1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * DMI based code to deal with broken DSDTs on X86 tablets which ship with
4 * Android as (part of) the factory image. The factory kernels shipped on these
5 * devices typically have a bunch of things hardcoded, rather than specified
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 #include <linux/acpi.h>
14 #include <linux/dmi.h>
15 #include <linux/gpio/driver.h>
16 #include <linux/gpio/machine.h>
17 #include <linux/irq.h>
18 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/serdev.h>
21 #include <linux/string.h>
23 #include "x86-android-tablets.h"
24 /* For gpiochip_get_desc() which is EXPORT_SYMBOL_GPL() */
25 #include "../../../gpio/gpiolib.h"
26 #include "../../../gpio/gpiolib-acpi.h"
28 static int gpiochip_find_match_label(struct gpio_chip *gc, void *data)
30 return gc->label && !strcmp(gc->label, data);
33 int x86_android_tablet_get_gpiod(const char *label, int pin, struct gpio_desc **desc)
35 struct gpio_desc *gpiod;
36 struct gpio_chip *chip;
38 chip = gpiochip_find((void *)label, gpiochip_find_match_label);
40 pr_err("error cannot find GPIO chip %s\n", label);
44 gpiod = gpiochip_get_desc(chip, pin);
46 pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), label, pin);
47 return PTR_ERR(gpiod);
54 int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data)
56 struct irq_fwspec fwspec = { };
57 struct irq_domain *domain;
58 struct acpi_device *adev;
59 struct gpio_desc *gpiod;
60 unsigned int irq_type;
66 case X86_ACPI_IRQ_TYPE_APIC:
68 * The DSDT may already reference the GSI in a device skipped by
69 * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI
70 * to avoid EBUSY errors in this case.
72 acpi_unregister_gsi(data->index);
73 irq = acpi_register_gsi(NULL, data->index, data->trigger, data->polarity);
75 pr_err("error %d getting APIC IRQ %d\n", irq, data->index);
78 case X86_ACPI_IRQ_TYPE_GPIOINT:
79 /* Like acpi_dev_gpio_irq_get(), but without parsing ACPI resources */
80 ret = x86_android_tablet_get_gpiod(data->chip, data->index, &gpiod);
84 irq = gpiod_to_irq(gpiod);
86 pr_err("error %d getting IRQ %s %d\n", irq, data->chip, data->index);
90 irq_type = acpi_dev_get_irq_type(data->trigger, data->polarity);
91 if (irq_type != IRQ_TYPE_NONE && irq_type != irq_get_trigger_type(irq))
92 irq_set_irq_type(irq, irq_type);
95 case X86_ACPI_IRQ_TYPE_PMIC:
96 status = acpi_get_handle(NULL, data->chip, &handle);
97 if (ACPI_FAILURE(status)) {
98 pr_err("error could not get %s handle\n", data->chip);
102 adev = acpi_fetch_acpi_dev(handle);
104 pr_err("error could not get %s adev\n", data->chip);
108 fwspec.fwnode = acpi_fwnode_handle(adev);
109 domain = irq_find_matching_fwspec(&fwspec, data->domain);
111 pr_err("error could not find IRQ domain for %s\n", data->chip);
115 return irq_create_mapping(domain, data->index);
121 static int i2c_client_count;
122 static int pdev_count;
123 static int serdev_count;
124 static struct i2c_client **i2c_clients;
125 static struct platform_device **pdevs;
126 static struct serdev_device **serdevs;
127 static struct gpiod_lookup_table * const *gpiod_lookup_tables;
128 static const struct software_node *bat_swnode;
129 static void (*exit_handler)(void);
131 static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info,
134 const struct x86_i2c_client_info *client_info = &dev_info->i2c_client_info[idx];
135 struct i2c_board_info board_info = client_info->board_info;
136 struct i2c_adapter *adap;
140 board_info.irq = x86_acpi_irq_helper_get(&client_info->irq_data);
141 if (board_info.irq < 0)
142 return board_info.irq;
144 status = acpi_get_handle(NULL, client_info->adapter_path, &handle);
145 if (ACPI_FAILURE(status)) {
146 pr_err("Error could not get %s handle\n", client_info->adapter_path);
150 adap = i2c_acpi_find_adapter_by_handle(handle);
152 pr_err("error could not get %s adapter\n", client_info->adapter_path);
156 i2c_clients[idx] = i2c_new_client_device(adap, &board_info);
157 put_device(&adap->dev);
158 if (IS_ERR(i2c_clients[idx]))
159 return dev_err_probe(&adap->dev, PTR_ERR(i2c_clients[idx]),
160 "creating I2C-client %d\n", idx);
165 static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx)
167 struct acpi_device *ctrl_adev, *serdev_adev;
168 struct serdev_device *serdev;
169 struct device *ctrl_dev;
172 ctrl_adev = acpi_dev_get_first_match_dev(info->ctrl_hid, info->ctrl_uid, -1);
174 pr_err("error could not get %s/%s ctrl adev\n",
175 info->ctrl_hid, info->ctrl_uid);
179 serdev_adev = acpi_dev_get_first_match_dev(info->serdev_hid, NULL, -1);
181 pr_err("error could not get %s serdev adev\n", info->serdev_hid);
185 /* get_first_physical_node() returns a weak ref, no need to put() it */
186 ctrl_dev = acpi_get_first_physical_node(ctrl_adev);
188 pr_err("error could not get %s/%s ctrl physical dev\n",
189 info->ctrl_hid, info->ctrl_uid);
190 goto put_serdev_adev;
193 /* ctrl_dev now points to the controller's parent, get the controller */
194 ctrl_dev = device_find_child_by_name(ctrl_dev, info->ctrl_devname);
196 pr_err("error could not get %s/%s %s ctrl dev\n",
197 info->ctrl_hid, info->ctrl_uid, info->ctrl_devname);
198 goto put_serdev_adev;
201 serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev));
204 goto put_serdev_adev;
207 ACPI_COMPANION_SET(&serdev->dev, serdev_adev);
208 acpi_device_set_enumerated(serdev_adev);
210 ret = serdev_device_add(serdev);
212 dev_err(&serdev->dev, "error %d adding serdev\n", ret);
213 serdev_device_put(serdev);
214 goto put_serdev_adev;
217 serdevs[idx] = serdev;
220 acpi_dev_put(serdev_adev);
222 acpi_dev_put(ctrl_adev);
226 static void x86_android_tablet_cleanup(void)
230 for (i = 0; i < serdev_count; i++) {
232 serdev_device_remove(serdevs[i]);
237 for (i = 0; i < pdev_count; i++)
238 platform_device_unregister(pdevs[i]);
242 for (i = 0; i < i2c_client_count; i++)
243 i2c_unregister_device(i2c_clients[i]);
250 for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++)
251 gpiod_remove_lookup_table(gpiod_lookup_tables[i]);
253 software_node_unregister(bat_swnode);
256 static __init int x86_android_tablet_init(void)
258 const struct x86_dev_info *dev_info;
259 const struct dmi_system_id *id;
260 struct gpio_chip *chip;
263 id = dmi_first_match(x86_android_tablet_ids);
267 dev_info = id->driver_data;
270 * The broken DSDTs on these devices often also include broken
271 * _AEI (ACPI Event Interrupt) handlers, disable these.
273 if (dev_info->invalid_aei_gpiochip) {
274 chip = gpiochip_find(dev_info->invalid_aei_gpiochip,
275 gpiochip_find_match_label);
277 pr_err("error cannot find GPIO chip %s\n", dev_info->invalid_aei_gpiochip);
280 acpi_gpiochip_free_interrupts(chip);
284 * Since this runs from module_init() it cannot use -EPROBE_DEFER,
285 * instead pre-load any modules which are listed as requirements.
287 for (i = 0; dev_info->modules && dev_info->modules[i]; i++)
288 request_module(dev_info->modules[i]);
290 bat_swnode = dev_info->bat_swnode;
292 ret = software_node_register(bat_swnode);
297 gpiod_lookup_tables = dev_info->gpiod_lookup_tables;
298 for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++)
299 gpiod_add_lookup_table(gpiod_lookup_tables[i]);
301 if (dev_info->init) {
302 ret = dev_info->init();
304 x86_android_tablet_cleanup();
307 exit_handler = dev_info->exit;
310 i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL);
312 x86_android_tablet_cleanup();
316 i2c_client_count = dev_info->i2c_client_count;
317 for (i = 0; i < i2c_client_count; i++) {
318 ret = x86_instantiate_i2c_client(dev_info, i);
320 x86_android_tablet_cleanup();
325 /* + 1 to make space for (optional) gpio_keys_button pdev */
326 pdevs = kcalloc(dev_info->pdev_count + 1, sizeof(*pdevs), GFP_KERNEL);
328 x86_android_tablet_cleanup();
332 pdev_count = dev_info->pdev_count;
333 for (i = 0; i < pdev_count; i++) {
334 pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]);
335 if (IS_ERR(pdevs[i])) {
336 x86_android_tablet_cleanup();
337 return PTR_ERR(pdevs[i]);
341 serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL);
343 x86_android_tablet_cleanup();
347 serdev_count = dev_info->serdev_count;
348 for (i = 0; i < serdev_count; i++) {
349 ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i);
351 x86_android_tablet_cleanup();
356 if (dev_info->gpio_button) {
357 struct gpio_keys_platform_data pdata = {
358 .buttons = &dev_info->gpio_button->button,
361 struct gpio_desc *gpiod;
363 /* Get GPIO for the gpio-button */
364 ret = x86_android_tablet_get_gpiod(dev_info->gpio_button->chip,
365 dev_info->gpio_button->pin, &gpiod);
367 x86_android_tablet_cleanup();
371 dev_info->gpio_button->button.gpio = desc_to_gpio(gpiod);
373 pdevs[pdev_count] = platform_device_register_data(NULL, "gpio-keys",
375 &pdata, sizeof(pdata));
376 if (IS_ERR(pdevs[pdev_count])) {
377 x86_android_tablet_cleanup();
378 return PTR_ERR(pdevs[pdev_count]);
386 module_init(x86_android_tablet_init);
387 module_exit(x86_android_tablet_cleanup);
390 MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver");
391 MODULE_LICENSE("GPL");