1 // SPDX-License-Identifier: GPL-2.0+
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/efi.h>
16 #include <linux/gpio_keys.h>
17 #include <linux/gpio/consumer.h>
18 #include <linux/gpio/driver.h>
19 #include <linux/gpio/machine.h>
20 #include <linux/i2c.h>
21 #include <linux/input.h>
22 #include <linux/irq.h>
23 #include <linux/irqdomain.h>
24 #include <linux/module.h>
25 #include <linux/mod_devicetable.h>
26 #include <linux/pinctrl/consumer.h>
27 #include <linux/pinctrl/machine.h>
28 #include <linux/platform_data/lp855x.h>
29 #include <linux/platform_device.h>
30 #include <linux/power/bq24190_charger.h>
31 #include <linux/reboot.h>
32 #include <linux/rmi.h>
33 #include <linux/serdev.h>
34 #include <linux/spi/spi.h>
35 #include <linux/string.h>
36 /* For gpio_get_desc() which is EXPORT_SYMBOL_GPL() */
37 #include "../../gpio/gpiolib.h"
38 #include "../../gpio/gpiolib-acpi.h"
41 * Helper code to get Linux IRQ numbers given a description of the IRQ source
42 * (either IOAPIC index, or GPIO chip name + pin-number).
44 enum x86_acpi_irq_type {
45 X86_ACPI_IRQ_TYPE_NONE,
46 X86_ACPI_IRQ_TYPE_APIC,
47 X86_ACPI_IRQ_TYPE_GPIOINT,
48 X86_ACPI_IRQ_TYPE_PMIC,
51 struct x86_acpi_irq_data {
52 char *chip; /* GPIO chip label (GPIOINT) or PMIC ACPI path (PMIC) */
53 enum x86_acpi_irq_type type;
54 enum irq_domain_bus_token domain;
56 int trigger; /* ACPI_EDGE_SENSITIVE / ACPI_LEVEL_SENSITIVE */
57 int polarity; /* ACPI_ACTIVE_HIGH / ACPI_ACTIVE_LOW / ACPI_ACTIVE_BOTH */
60 static int gpiochip_find_match_label(struct gpio_chip *gc, void *data)
62 return gc->label && !strcmp(gc->label, data);
65 static int x86_android_tablet_get_gpiod(char *label, int pin, struct gpio_desc **desc)
67 struct gpio_desc *gpiod;
68 struct gpio_chip *chip;
70 chip = gpiochip_find(label, gpiochip_find_match_label);
72 pr_err("error cannot find GPIO chip %s\n", label);
76 gpiod = gpiochip_get_desc(chip, pin);
78 pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), label, pin);
79 return PTR_ERR(gpiod);
86 static int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data)
88 struct irq_fwspec fwspec = { };
89 struct irq_domain *domain;
90 struct acpi_device *adev;
91 struct gpio_desc *gpiod;
92 unsigned int irq_type;
98 case X86_ACPI_IRQ_TYPE_APIC:
100 * The DSDT may already reference the GSI in a device skipped by
101 * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI
102 * to avoid EBUSY errors in this case.
104 acpi_unregister_gsi(data->index);
105 irq = acpi_register_gsi(NULL, data->index, data->trigger, data->polarity);
107 pr_err("error %d getting APIC IRQ %d\n", irq, data->index);
110 case X86_ACPI_IRQ_TYPE_GPIOINT:
111 /* Like acpi_dev_gpio_irq_get(), but without parsing ACPI resources */
112 ret = x86_android_tablet_get_gpiod(data->chip, data->index, &gpiod);
116 irq = gpiod_to_irq(gpiod);
118 pr_err("error %d getting IRQ %s %d\n", irq, data->chip, data->index);
122 irq_type = acpi_dev_get_irq_type(data->trigger, data->polarity);
123 if (irq_type != IRQ_TYPE_NONE && irq_type != irq_get_trigger_type(irq))
124 irq_set_irq_type(irq, irq_type);
127 case X86_ACPI_IRQ_TYPE_PMIC:
128 status = acpi_get_handle(NULL, data->chip, &handle);
129 if (ACPI_FAILURE(status)) {
130 pr_err("error could not get %s handle\n", data->chip);
134 adev = acpi_fetch_acpi_dev(handle);
136 pr_err("error could not get %s adev\n", data->chip);
140 fwspec.fwnode = acpi_fwnode_handle(adev);
141 domain = irq_find_matching_fwspec(&fwspec, data->domain);
143 pr_err("error could not find IRQ domain for %s\n", data->chip);
147 return irq_create_mapping(domain, data->index);
153 struct x86_i2c_client_info {
154 struct i2c_board_info board_info;
156 struct x86_acpi_irq_data irq_data;
159 struct x86_serdev_info {
160 const char *ctrl_hid;
161 const char *ctrl_uid;
162 const char *ctrl_devname;
164 * ATM the serdev core only supports of or ACPI matching; and sofar all
165 * Android x86 tablets DSDTs have usable serdev nodes, but sometimes
166 * under the wrong controller. So we just tie the existing serdev ACPI
167 * node to the right controller.
169 const char *serdev_hid;
172 struct x86_dev_info {
173 char *invalid_aei_gpiochip;
174 const char * const *modules;
175 const struct software_node *bat_swnode;
176 struct gpiod_lookup_table * const *gpiod_lookup_tables;
177 const struct x86_i2c_client_info *i2c_client_info;
178 const struct platform_device_info *pdev_info;
179 const struct x86_serdev_info *serdev_info;
180 int i2c_client_count;
187 /* Generic / shared charger / battery settings */
188 static const char * const tusb1211_chg_det_psy[] = { "tusb1211-charger-detect" };
189 static const char * const bq24190_psy[] = { "bq24190-charger" };
190 static const char * const bq25890_psy[] = { "bq25890-charger" };
192 static const struct property_entry fg_bq24190_supply_props[] = {
193 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
197 static const struct software_node fg_bq24190_supply_node = {
198 .properties = fg_bq24190_supply_props,
201 static const struct property_entry fg_bq25890_supply_props[] = {
202 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_psy),
206 static const struct software_node fg_bq25890_supply_node = {
207 .properties = fg_bq25890_supply_props,
210 /* LiPo HighVoltage (max 4.35V) settings used by most devs with a HV bat. */
211 static const struct property_entry generic_lipo_hv_4v35_battery_props[] = {
212 PROPERTY_ENTRY_STRING("compatible", "simple-battery"),
213 PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion"),
214 PROPERTY_ENTRY_U32("precharge-current-microamp", 256000),
215 PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000),
216 PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 1856000),
217 PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4352000),
218 PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000),
222 static const struct software_node generic_lipo_hv_4v35_battery_node = {
223 .properties = generic_lipo_hv_4v35_battery_props,
226 /* For enabling the bq24190 5V boost based on id-pin */
227 static struct regulator_consumer_supply intel_int3496_consumer = {
229 .dev_name = "intel-int3496",
232 static const struct regulator_init_data bq24190_vbus_init_data = {
234 .name = "bq24190_vbus",
235 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
237 .consumer_supplies = &intel_int3496_consumer,
238 .num_consumer_supplies = 1,
241 static struct bq24190_platform_data bq24190_pdata = {
242 .regulator_init_data = &bq24190_vbus_init_data,
245 static const char * const bq24190_modules[] __initconst = {
246 "intel_crystal_cove_charger", /* For the bq24190 IRQ */
247 "bq24190_charger", /* For the Vbus regulator for intel-int3496 */
251 /* Generic pdevs array and gpio-lookups for micro USB ID pin handling */
252 static const struct platform_device_info int3496_pdevs[] __initconst = {
254 /* For micro USB ID pin handling */
255 .name = "intel-int3496",
256 .id = PLATFORM_DEVID_NONE,
260 static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = {
261 .dev_id = "intel-int3496",
263 GPIO_LOOKUP("INT33FC:02", 22, "id", GPIO_ACTIVE_HIGH),
268 /* Asus ME176C and TF103C tablets shared data */
269 static struct gpio_keys_button asus_me176c_tf103c_lid = {
271 /* .gpio gets filled in by asus_me176c_tf103c_init() */
276 .debounce_interval = 50,
279 static const struct gpio_keys_platform_data asus_me176c_tf103c_lid_pdata __initconst = {
280 .buttons = &asus_me176c_tf103c_lid,
285 static const struct platform_device_info asus_me176c_tf103c_pdevs[] __initconst = {
288 .id = PLATFORM_DEVID_AUTO,
289 .data = &asus_me176c_tf103c_lid_pdata,
290 .size_data = sizeof(asus_me176c_tf103c_lid_pdata),
293 /* For micro USB ID pin handling */
294 .name = "intel-int3496",
295 .id = PLATFORM_DEVID_NONE,
299 static int __init asus_me176c_tf103c_init(void)
301 struct gpio_desc *gpiod;
304 ret = x86_android_tablet_get_gpiod("INT33FC:02", 12, &gpiod);
307 asus_me176c_tf103c_lid.gpio = desc_to_gpio(gpiod);
313 /* Asus ME176C tablets have an Android factory img with everything hardcoded */
314 static const char * const asus_me176c_accel_mount_matrix[] = {
320 static const struct property_entry asus_me176c_accel_props[] = {
321 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_me176c_accel_mount_matrix),
325 static const struct software_node asus_me176c_accel_node = {
326 .properties = asus_me176c_accel_props,
329 static const struct property_entry asus_me176c_bq24190_props[] = {
330 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
331 PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
332 PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000),
333 PROPERTY_ENTRY_BOOL("omit-battery-class"),
334 PROPERTY_ENTRY_BOOL("disable-reset"),
338 static const struct software_node asus_me176c_bq24190_node = {
339 .properties = asus_me176c_bq24190_props,
342 static const struct property_entry asus_me176c_ug3105_props[] = {
343 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
344 PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
345 PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 10000),
349 static const struct software_node asus_me176c_ug3105_node = {
350 .properties = asus_me176c_ug3105_props,
353 static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = {
355 /* bq24297 battery charger */
359 .dev_name = "bq24297",
360 .swnode = &asus_me176c_bq24190_node,
361 .platform_data = &bq24190_pdata,
363 .adapter_path = "\\_SB_.I2C1",
365 .type = X86_ACPI_IRQ_TYPE_PMIC,
366 .chip = "\\_SB_.I2C7.PMIC",
367 .domain = DOMAIN_BUS_WAKEUP,
371 /* ug3105 battery monitor */
375 .dev_name = "ug3105",
376 .swnode = &asus_me176c_ug3105_node,
378 .adapter_path = "\\_SB_.I2C1",
380 /* ak09911 compass */
384 .dev_name = "ak09911",
386 .adapter_path = "\\_SB_.I2C5",
388 /* kxtj21009 accel */
392 .dev_name = "kxtj21009",
393 .swnode = &asus_me176c_accel_node,
395 .adapter_path = "\\_SB_.I2C5",
397 .type = X86_ACPI_IRQ_TYPE_APIC,
399 .trigger = ACPI_EDGE_SENSITIVE,
400 .polarity = ACPI_ACTIVE_LOW,
403 /* goodix touchscreen */
405 .type = "GDIX1001:00",
407 .dev_name = "goodix_ts",
409 .adapter_path = "\\_SB_.I2C6",
411 .type = X86_ACPI_IRQ_TYPE_APIC,
413 .trigger = ACPI_EDGE_SENSITIVE,
414 .polarity = ACPI_ACTIVE_LOW,
419 static const struct x86_serdev_info asus_me176c_serdevs[] __initconst = {
421 .ctrl_hid = "80860F0A",
423 .ctrl_devname = "serial0",
424 .serdev_hid = "BCM2E3A",
428 static struct gpiod_lookup_table asus_me176c_goodix_gpios = {
429 .dev_id = "i2c-goodix_ts",
431 GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_HIGH),
432 GPIO_LOOKUP("INT33FC:02", 28, "irq", GPIO_ACTIVE_HIGH),
437 static struct gpiod_lookup_table * const asus_me176c_gpios[] = {
438 &int3496_gpo2_pin22_gpios,
439 &asus_me176c_goodix_gpios,
443 static const struct x86_dev_info asus_me176c_info __initconst = {
444 .i2c_client_info = asus_me176c_i2c_clients,
445 .i2c_client_count = ARRAY_SIZE(asus_me176c_i2c_clients),
446 .pdev_info = asus_me176c_tf103c_pdevs,
447 .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs),
448 .serdev_info = asus_me176c_serdevs,
449 .serdev_count = ARRAY_SIZE(asus_me176c_serdevs),
450 .gpiod_lookup_tables = asus_me176c_gpios,
451 .bat_swnode = &generic_lipo_hv_4v35_battery_node,
452 .modules = bq24190_modules,
453 .invalid_aei_gpiochip = "INT33FC:02",
454 .init = asus_me176c_tf103c_init,
457 /* Asus TF103C tablets have an Android factory img with everything hardcoded */
458 static const char * const asus_tf103c_accel_mount_matrix[] = {
464 static const struct property_entry asus_tf103c_accel_props[] = {
465 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_tf103c_accel_mount_matrix),
469 static const struct software_node asus_tf103c_accel_node = {
470 .properties = asus_tf103c_accel_props,
473 static const struct property_entry asus_tf103c_touchscreen_props[] = {
474 PROPERTY_ENTRY_STRING("compatible", "atmel,atmel_mxt_ts"),
478 static const struct software_node asus_tf103c_touchscreen_node = {
479 .properties = asus_tf103c_touchscreen_props,
482 static const struct property_entry asus_tf103c_battery_props[] = {
483 PROPERTY_ENTRY_STRING("compatible", "simple-battery"),
484 PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion-polymer"),
485 PROPERTY_ENTRY_U32("precharge-current-microamp", 256000),
486 PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000),
487 PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 2048000),
488 PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4208000),
489 PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000),
493 static const struct software_node asus_tf103c_battery_node = {
494 .properties = asus_tf103c_battery_props,
497 static const struct property_entry asus_tf103c_bq24190_props[] = {
498 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
499 PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node),
500 PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000),
501 PROPERTY_ENTRY_BOOL("omit-battery-class"),
502 PROPERTY_ENTRY_BOOL("disable-reset"),
506 static const struct software_node asus_tf103c_bq24190_node = {
507 .properties = asus_tf103c_bq24190_props,
510 static const struct property_entry asus_tf103c_ug3105_props[] = {
511 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
512 PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node),
513 PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 5000),
517 static const struct software_node asus_tf103c_ug3105_node = {
518 .properties = asus_tf103c_ug3105_props,
521 static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = {
523 /* bq24297 battery charger */
527 .dev_name = "bq24297",
528 .swnode = &asus_tf103c_bq24190_node,
529 .platform_data = &bq24190_pdata,
531 .adapter_path = "\\_SB_.I2C1",
533 .type = X86_ACPI_IRQ_TYPE_PMIC,
534 .chip = "\\_SB_.I2C7.PMIC",
535 .domain = DOMAIN_BUS_WAKEUP,
539 /* ug3105 battery monitor */
543 .dev_name = "ug3105",
544 .swnode = &asus_tf103c_ug3105_node,
546 .adapter_path = "\\_SB_.I2C1",
548 /* ak09911 compass */
552 .dev_name = "ak09911",
554 .adapter_path = "\\_SB_.I2C5",
556 /* kxtj21009 accel */
560 .dev_name = "kxtj21009",
561 .swnode = &asus_tf103c_accel_node,
563 .adapter_path = "\\_SB_.I2C5",
565 /* atmel touchscreen */
567 .type = "atmel_mxt_ts",
569 .dev_name = "atmel_mxt_ts",
570 .swnode = &asus_tf103c_touchscreen_node,
572 .adapter_path = "\\_SB_.I2C6",
574 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
575 .chip = "INT33FC:02",
577 .trigger = ACPI_EDGE_SENSITIVE,
578 .polarity = ACPI_ACTIVE_LOW,
583 static struct gpiod_lookup_table * const asus_tf103c_gpios[] = {
584 &int3496_gpo2_pin22_gpios,
588 static const struct x86_dev_info asus_tf103c_info __initconst = {
589 .i2c_client_info = asus_tf103c_i2c_clients,
590 .i2c_client_count = ARRAY_SIZE(asus_tf103c_i2c_clients),
591 .pdev_info = asus_me176c_tf103c_pdevs,
592 .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs),
593 .gpiod_lookup_tables = asus_tf103c_gpios,
594 .bat_swnode = &asus_tf103c_battery_node,
595 .modules = bq24190_modules,
596 .invalid_aei_gpiochip = "INT33FC:02",
597 .init = asus_me176c_tf103c_init,
601 * When booted with the BIOS set to Android mode the Chuwi Hi8 (CWI509) DSDT
602 * contains a whole bunch of bogus ACPI I2C devices and is missing entries
603 * for the touchscreen and the accelerometer.
605 static const struct property_entry chuwi_hi8_gsl1680_props[] = {
606 PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
607 PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
608 PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
609 PROPERTY_ENTRY_BOOL("silead,home-button"),
610 PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi8.fw"),
614 static const struct software_node chuwi_hi8_gsl1680_node = {
615 .properties = chuwi_hi8_gsl1680_props,
618 static const char * const chuwi_hi8_mount_matrix[] = {
624 static const struct property_entry chuwi_hi8_bma250e_props[] = {
625 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", chuwi_hi8_mount_matrix),
629 static const struct software_node chuwi_hi8_bma250e_node = {
630 .properties = chuwi_hi8_bma250e_props,
633 static const struct x86_i2c_client_info chuwi_hi8_i2c_clients[] __initconst = {
635 /* Silead touchscreen */
639 .swnode = &chuwi_hi8_gsl1680_node,
641 .adapter_path = "\\_SB_.I2C4",
643 .type = X86_ACPI_IRQ_TYPE_APIC,
645 .trigger = ACPI_EDGE_SENSITIVE,
646 .polarity = ACPI_ACTIVE_HIGH,
649 /* BMA250E accelerometer */
653 .swnode = &chuwi_hi8_bma250e_node,
655 .adapter_path = "\\_SB_.I2C3",
657 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
658 .chip = "INT33FC:02",
660 .trigger = ACPI_LEVEL_SENSITIVE,
661 .polarity = ACPI_ACTIVE_HIGH,
666 static int __init chuwi_hi8_init(void)
669 * Avoid the acpi_unregister_gsi() call in x86_acpi_irq_helper_get()
670 * breaking the touchscreen + logging various errors when the Windows
673 if (acpi_dev_present("MSSL0001", NULL, 1))
679 static const struct x86_dev_info chuwi_hi8_info __initconst = {
680 .i2c_client_info = chuwi_hi8_i2c_clients,
681 .i2c_client_count = ARRAY_SIZE(chuwi_hi8_i2c_clients),
682 .init = chuwi_hi8_init,
685 #define CZC_EC_EXTRA_PORT 0x68
686 #define CZC_EC_ANDROID_KEYS 0x63
688 static int __init czc_p10t_init(void)
691 * The device boots up in "Windows 7" mode, when the home button sends a
692 * Windows specific key sequence (Left Meta + D) and the second button
693 * sends an unknown one while also toggling the Radio Kill Switch.
694 * This is a surprising behavior when the second button is labeled "Back".
696 * The vendor-supplied Android-x86 build switches the device to a "Android"
697 * mode by writing value 0x63 to the I/O port 0x68. This just seems to just
698 * set bit 6 on address 0x96 in the EC region; switching the bit directly
699 * seems to achieve the same result. It uses a "p10t_switcher" to do the
700 * job. It doesn't seem to be able to do anything else, and no other use
701 * of the port 0x68 is known.
703 * In the Android mode, the home button sends just a single scancode,
704 * which can be handled in Linux userspace more reasonably and the back
705 * button only sends a scancode without toggling the kill switch.
706 * The scancode can then be mapped either to Back or RF Kill functionality
707 * in userspace, depending on how the button is labeled on that particular
710 outb(CZC_EC_ANDROID_KEYS, CZC_EC_EXTRA_PORT);
714 static const struct x86_dev_info czc_p10t __initconst = {
715 .init = czc_p10t_init,
718 /* Lenovo Yoga Book X90F / X91F / X91L need manual instantiation of the fg client */
719 static const struct x86_i2c_client_info lenovo_yogabook_x9x_i2c_clients[] __initconst = {
721 /* BQ27542 fuel-gauge */
725 .dev_name = "bq27542",
726 .swnode = &fg_bq25890_supply_node,
728 .adapter_path = "\\_SB_.PCI0.I2C1",
732 static const struct x86_dev_info lenovo_yogabook_x9x_info __initconst = {
733 .i2c_client_info = lenovo_yogabook_x9x_i2c_clients,
734 .i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x9x_i2c_clients),
737 /* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */
738 static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
739 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
740 PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
741 PROPERTY_ENTRY_BOOL("omit-battery-class"),
742 PROPERTY_ENTRY_BOOL("disable-reset"),
746 static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
747 .properties = lenovo_yoga_tab2_830_1050_bq24190_props,
750 /* This gets filled by lenovo_yoga_tab2_830_1050_init() */
751 static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
753 static struct lp855x_platform_data lenovo_yoga_tab2_830_1050_lp8557_pdata = {
754 .device_control = 0x86,
755 .initial_brightness = 128,
758 static const struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initconst = {
760 /* bq24292i battery charger */
764 .dev_name = "bq24292i",
765 .swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
766 .platform_data = &bq24190_pdata,
768 .adapter_path = "\\_SB_.I2C1",
770 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
771 .chip = "INT33FC:02",
773 .trigger = ACPI_EDGE_SENSITIVE,
774 .polarity = ACPI_ACTIVE_HIGH,
777 /* BQ27541 fuel-gauge */
781 .dev_name = "bq27541",
782 .swnode = &fg_bq24190_supply_node,
784 .adapter_path = "\\_SB_.I2C1",
786 /* Synaptics RMI touchscreen */
790 .dev_name = "rmi4_i2c",
791 .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
793 .adapter_path = "\\_SB_.I2C6",
795 .type = X86_ACPI_IRQ_TYPE_APIC,
797 .trigger = ACPI_EDGE_SENSITIVE,
798 .polarity = ACPI_ACTIVE_HIGH,
801 /* LP8557 Backlight controller */
805 .dev_name = "lp8557",
806 .platform_data = &lenovo_yoga_tab2_830_1050_lp8557_pdata,
808 .adapter_path = "\\_SB_.I2C3",
812 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
813 .dev_id = "intel-int3496",
815 GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
816 GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
821 #define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
823 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = {
824 .dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME,
826 GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH),
827 GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH),
828 GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
829 GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW),
834 static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = {
835 &lenovo_yoga_tab2_830_1050_int3496_gpios,
836 &lenovo_yoga_tab2_830_1050_codec_gpios,
840 static int __init lenovo_yoga_tab2_830_1050_init(void);
841 static void lenovo_yoga_tab2_830_1050_exit(void);
843 static struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initdata = {
844 .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
845 /* i2c_client_count gets set by lenovo_yoga_tab2_830_1050_init() */
846 .pdev_info = int3496_pdevs,
847 .pdev_count = ARRAY_SIZE(int3496_pdevs),
848 .gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios,
849 .bat_swnode = &generic_lipo_hv_4v35_battery_node,
850 .modules = bq24190_modules,
851 .invalid_aei_gpiochip = "INT33FC:02",
852 .init = lenovo_yoga_tab2_830_1050_init,
853 .exit = lenovo_yoga_tab2_830_1050_exit,
857 * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
858 * mainboard, but they need some different treatment related to the display:
859 * 1. The 830 uses a portrait LCD panel with a landscape touchscreen, requiring
860 * the touchscreen driver to adjust the touch-coords to match the LCD.
861 * 2. Both use an TI LP8557 LED backlight controller. On the 1050 the LP8557's
862 * PWM input is connected to the PMIC's PWM output and everything works fine
863 * with the defaults programmed into the LP8557 by the BIOS.
864 * But on the 830 the LP8557's PWM input is connected to a PWM output coming
865 * from the LCD panel's controller. The Android code has a hack in the i915
866 * driver to write the non-standard DSI reg 0x9f with the desired backlight
867 * level to set the duty-cycle of the LCD's PWM output.
869 * To avoid having to have a similar hack in the mainline kernel the LP8557
870 * entry in lenovo_yoga_tab2_830_1050_i2c_clients instead just programs the
871 * LP8557 to directly set the level, ignoring the PWM input. This means that
872 * the LP8557 i2c_client should only be instantiated on the 830.
874 static int __init lenovo_yoga_tab2_830_1050_init_display(void)
876 struct gpio_desc *gpiod;
879 /* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
880 ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, &gpiod);
884 ret = gpiod_get_value_cansleep(gpiod);
886 pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
887 lenovo_yoga_tab2_830_1050_info.i2c_client_count =
888 ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients) - 1;
890 pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
891 lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
892 lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
893 lenovo_yoga_tab2_830_1050_info.i2c_client_count =
894 ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients);
900 /* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
901 static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
902 PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
903 "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
905 static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
906 static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
908 static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
910 struct device *codec_dev;
911 struct pinctrl *pinctrl;
914 codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
915 LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
917 pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
921 ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
925 pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
926 if (IS_ERR(pinctrl)) {
927 ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
928 goto err_unregister_mappings;
931 /* We're done with the codec_dev now */
932 put_device(codec_dev);
934 lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
937 err_unregister_mappings:
938 pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
940 put_device(codec_dev);
945 * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off
946 * gets used as pm_power_off handler. This causes "poweroff" on these tablets
947 * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice*
948 * followed by a normal 3 second press to recover. Avoid this by doing an EFI
951 static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
953 efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
958 static int __init lenovo_yoga_tab2_830_1050_init(void)
962 ret = lenovo_yoga_tab2_830_1050_init_display();
966 ret = lenovo_yoga_tab2_830_1050_init_codec();
970 /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */
971 lenovo_yoga_tab2_830_1050_sys_off_handler =
972 register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
973 lenovo_yoga_tab2_830_1050_power_off, NULL);
974 if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
975 return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
980 static void lenovo_yoga_tab2_830_1050_exit(void)
982 unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
984 if (lenovo_yoga_tab2_830_1050_codec_pinctrl) {
985 pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
986 pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
990 /* Nextbook Ares 8 tablets have an Android factory img with everything hardcoded */
991 static const char * const nextbook_ares8_accel_mount_matrix[] = {
997 static const struct property_entry nextbook_ares8_accel_props[] = {
998 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", nextbook_ares8_accel_mount_matrix),
1002 static const struct software_node nextbook_ares8_accel_node = {
1003 .properties = nextbook_ares8_accel_props,
1006 static const struct property_entry nextbook_ares8_touchscreen_props[] = {
1007 PROPERTY_ENTRY_U32("touchscreen-size-x", 800),
1008 PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
1012 static const struct software_node nextbook_ares8_touchscreen_node = {
1013 .properties = nextbook_ares8_touchscreen_props,
1016 static const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst = {
1018 /* Freescale MMA8653FC accel */
1022 .dev_name = "mma8653",
1023 .swnode = &nextbook_ares8_accel_node,
1025 .adapter_path = "\\_SB_.I2C3",
1027 /* FT5416DQ9 touchscreen controller */
1029 .type = "edt-ft5x06",
1031 .dev_name = "ft5416",
1032 .swnode = &nextbook_ares8_touchscreen_node,
1034 .adapter_path = "\\_SB_.I2C4",
1036 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
1037 .chip = "INT33FC:02",
1039 .trigger = ACPI_EDGE_SENSITIVE,
1040 .polarity = ACPI_ACTIVE_LOW,
1045 static struct gpiod_lookup_table nextbook_ares8_int3496_gpios = {
1046 .dev_id = "intel-int3496",
1048 GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_HIGH),
1049 GPIO_LOOKUP("INT33FC:02", 18, "id", GPIO_ACTIVE_HIGH),
1054 static struct gpiod_lookup_table * const nextbook_ares8_gpios[] = {
1055 &nextbook_ares8_int3496_gpios,
1059 static const struct x86_dev_info nextbook_ares8_info __initconst = {
1060 .i2c_client_info = nextbook_ares8_i2c_clients,
1061 .i2c_client_count = ARRAY_SIZE(nextbook_ares8_i2c_clients),
1062 .pdev_info = int3496_pdevs,
1063 .pdev_count = ARRAY_SIZE(int3496_pdevs),
1064 .gpiod_lookup_tables = nextbook_ares8_gpios,
1065 .invalid_aei_gpiochip = "INT33FC:02",
1069 * Whitelabel (sold as various brands) TM800A550L tablets.
1070 * These tablet's DSDT contains a whole bunch of bogus ACPI I2C devices
1071 * (removed through acpi_quirk_skip_i2c_client_enumeration()) and
1072 * the touchscreen fwnode has the wrong GPIOs.
1074 static const char * const whitelabel_tm800a550l_accel_mount_matrix[] = {
1080 static const struct property_entry whitelabel_tm800a550l_accel_props[] = {
1081 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", whitelabel_tm800a550l_accel_mount_matrix),
1085 static const struct software_node whitelabel_tm800a550l_accel_node = {
1086 .properties = whitelabel_tm800a550l_accel_props,
1089 static const struct property_entry whitelabel_tm800a550l_goodix_props[] = {
1090 PROPERTY_ENTRY_STRING("firmware-name", "gt912-tm800a550l.fw"),
1091 PROPERTY_ENTRY_STRING("goodix,config-name", "gt912-tm800a550l.cfg"),
1092 PROPERTY_ENTRY_U32("goodix,main-clk", 54),
1096 static const struct software_node whitelabel_tm800a550l_goodix_node = {
1097 .properties = whitelabel_tm800a550l_goodix_props,
1100 static const struct x86_i2c_client_info whitelabel_tm800a550l_i2c_clients[] __initconst = {
1102 /* goodix touchscreen */
1104 .type = "GDIX1001:00",
1106 .dev_name = "goodix_ts",
1107 .swnode = &whitelabel_tm800a550l_goodix_node,
1109 .adapter_path = "\\_SB_.I2C2",
1111 .type = X86_ACPI_IRQ_TYPE_APIC,
1113 .trigger = ACPI_EDGE_SENSITIVE,
1114 .polarity = ACPI_ACTIVE_HIGH,
1117 /* kxcj91008 accel */
1119 .type = "kxcj91008",
1121 .dev_name = "kxcj91008",
1122 .swnode = &whitelabel_tm800a550l_accel_node,
1124 .adapter_path = "\\_SB_.I2C3",
1128 static struct gpiod_lookup_table whitelabel_tm800a550l_goodix_gpios = {
1129 .dev_id = "i2c-goodix_ts",
1131 GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH),
1132 GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH),
1137 static struct gpiod_lookup_table * const whitelabel_tm800a550l_gpios[] = {
1138 &whitelabel_tm800a550l_goodix_gpios,
1142 static const struct x86_dev_info whitelabel_tm800a550l_info __initconst = {
1143 .i2c_client_info = whitelabel_tm800a550l_i2c_clients,
1144 .i2c_client_count = ARRAY_SIZE(whitelabel_tm800a550l_i2c_clients),
1145 .gpiod_lookup_tables = whitelabel_tm800a550l_gpios,
1149 * If the EFI bootloader is not Xiaomi's own signed Android loader, then the
1150 * Xiaomi Mi Pad 2 X86 tablet sets OSID in the DSDT to 1 (Windows), causing
1151 * a bunch of devices to be hidden.
1153 * This takes care of instantiating the hidden devices manually.
1155 static const struct x86_i2c_client_info xiaomi_mipad2_i2c_clients[] __initconst = {
1157 /* BQ27520 fuel-gauge */
1161 .dev_name = "bq27520",
1162 .swnode = &fg_bq25890_supply_node,
1164 .adapter_path = "\\_SB_.PCI0.I2C1",
1166 /* KTD2026 RGB notification LED controller */
1170 .dev_name = "ktd2026",
1172 .adapter_path = "\\_SB_.PCI0.I2C3",
1176 static const struct x86_dev_info xiaomi_mipad2_info __initconst = {
1177 .i2c_client_info = xiaomi_mipad2_i2c_clients,
1178 .i2c_client_count = ARRAY_SIZE(xiaomi_mipad2_i2c_clients),
1181 static const struct dmi_system_id x86_android_tablet_ids[] __initconst = {
1183 /* Asus MeMO Pad 7 ME176C */
1185 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
1186 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"),
1188 .driver_data = (void *)&asus_me176c_info,
1193 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
1194 DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
1196 .driver_data = (void *)&asus_tf103c_info,
1199 /* Chuwi Hi8 (CWI509) */
1201 DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
1202 DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"),
1203 DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
1204 DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
1206 .driver_data = (void *)&chuwi_hi8_info,
1210 .ident = "CZC ODEON TPC-10 (\"P10T\")",
1212 DMI_MATCH(DMI_SYS_VENDOR, "CZC"),
1213 DMI_MATCH(DMI_PRODUCT_NAME, "ODEON*TPC-10"),
1215 .driver_data = (void *)&czc_p10t,
1218 /* CZC P10T variant */
1219 .ident = "ViewSonic ViewPad 10",
1221 DMI_MATCH(DMI_SYS_VENDOR, "ViewSonic"),
1222 DMI_MATCH(DMI_PRODUCT_NAME, "VPAD10"),
1224 .driver_data = (void *)&czc_p10t,
1227 /* Lenovo Yoga Book X90F / X91F / X91L */
1229 /* Non exact match to match all versions */
1230 DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
1232 .driver_data = (void *)&lenovo_yogabook_x9x_info,
1236 * Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10"
1237 * Lenovo Yoga Tablet 2 use the same mainboard)
1240 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
1241 DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
1242 DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
1243 /* Partial match on beginning of BIOS version */
1244 DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
1246 .driver_data = (void *)&lenovo_yoga_tab2_830_1050_info,
1249 /* Nextbook Ares 8 */
1251 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
1252 DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"),
1254 .driver_data = (void *)&nextbook_ares8_info,
1257 /* Whitelabel (sold as various brands) TM800A550L */
1259 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1260 DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1261 /* Above strings are too generic, also match on BIOS version */
1262 DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"),
1264 .driver_data = (void *)&whitelabel_tm800a550l_info,
1267 /* Xiaomi Mi Pad 2 */
1269 DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
1270 DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
1272 .driver_data = (void *)&xiaomi_mipad2_info,
1276 MODULE_DEVICE_TABLE(dmi, x86_android_tablet_ids);
1278 static int i2c_client_count;
1279 static int pdev_count;
1280 static int serdev_count;
1281 static struct i2c_client **i2c_clients;
1282 static struct platform_device **pdevs;
1283 static struct serdev_device **serdevs;
1284 static struct gpiod_lookup_table * const *gpiod_lookup_tables;
1285 static const struct software_node *bat_swnode;
1286 static void (*exit_handler)(void);
1288 static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info,
1291 const struct x86_i2c_client_info *client_info = &dev_info->i2c_client_info[idx];
1292 struct i2c_board_info board_info = client_info->board_info;
1293 struct i2c_adapter *adap;
1297 board_info.irq = x86_acpi_irq_helper_get(&client_info->irq_data);
1298 if (board_info.irq < 0)
1299 return board_info.irq;
1301 status = acpi_get_handle(NULL, client_info->adapter_path, &handle);
1302 if (ACPI_FAILURE(status)) {
1303 pr_err("Error could not get %s handle\n", client_info->adapter_path);
1307 adap = i2c_acpi_find_adapter_by_handle(handle);
1309 pr_err("error could not get %s adapter\n", client_info->adapter_path);
1313 i2c_clients[idx] = i2c_new_client_device(adap, &board_info);
1314 put_device(&adap->dev);
1315 if (IS_ERR(i2c_clients[idx]))
1316 return dev_err_probe(&adap->dev, PTR_ERR(i2c_clients[idx]),
1317 "creating I2C-client %d\n", idx);
1322 static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx)
1324 struct acpi_device *ctrl_adev, *serdev_adev;
1325 struct serdev_device *serdev;
1326 struct device *ctrl_dev;
1329 ctrl_adev = acpi_dev_get_first_match_dev(info->ctrl_hid, info->ctrl_uid, -1);
1331 pr_err("error could not get %s/%s ctrl adev\n",
1332 info->ctrl_hid, info->ctrl_uid);
1336 serdev_adev = acpi_dev_get_first_match_dev(info->serdev_hid, NULL, -1);
1338 pr_err("error could not get %s serdev adev\n", info->serdev_hid);
1342 /* get_first_physical_node() returns a weak ref, no need to put() it */
1343 ctrl_dev = acpi_get_first_physical_node(ctrl_adev);
1345 pr_err("error could not get %s/%s ctrl physical dev\n",
1346 info->ctrl_hid, info->ctrl_uid);
1347 goto put_serdev_adev;
1350 /* ctrl_dev now points to the controller's parent, get the controller */
1351 ctrl_dev = device_find_child_by_name(ctrl_dev, info->ctrl_devname);
1353 pr_err("error could not get %s/%s %s ctrl dev\n",
1354 info->ctrl_hid, info->ctrl_uid, info->ctrl_devname);
1355 goto put_serdev_adev;
1358 serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev));
1361 goto put_serdev_adev;
1364 ACPI_COMPANION_SET(&serdev->dev, serdev_adev);
1365 acpi_device_set_enumerated(serdev_adev);
1367 ret = serdev_device_add(serdev);
1369 dev_err(&serdev->dev, "error %d adding serdev\n", ret);
1370 serdev_device_put(serdev);
1371 goto put_serdev_adev;
1374 serdevs[idx] = serdev;
1377 acpi_dev_put(serdev_adev);
1379 acpi_dev_put(ctrl_adev);
1383 static void x86_android_tablet_cleanup(void)
1387 for (i = 0; i < serdev_count; i++) {
1389 serdev_device_remove(serdevs[i]);
1394 for (i = 0; i < pdev_count; i++)
1395 platform_device_unregister(pdevs[i]);
1399 for (i = 0; i < i2c_client_count; i++)
1400 i2c_unregister_device(i2c_clients[i]);
1407 for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++)
1408 gpiod_remove_lookup_table(gpiod_lookup_tables[i]);
1410 software_node_unregister(bat_swnode);
1413 static __init int x86_android_tablet_init(void)
1415 const struct x86_dev_info *dev_info;
1416 const struct dmi_system_id *id;
1417 struct gpio_chip *chip;
1420 id = dmi_first_match(x86_android_tablet_ids);
1424 dev_info = id->driver_data;
1427 * The broken DSDTs on these devices often also include broken
1428 * _AEI (ACPI Event Interrupt) handlers, disable these.
1430 if (dev_info->invalid_aei_gpiochip) {
1431 chip = gpiochip_find(dev_info->invalid_aei_gpiochip,
1432 gpiochip_find_match_label);
1434 pr_err("error cannot find GPIO chip %s\n", dev_info->invalid_aei_gpiochip);
1437 acpi_gpiochip_free_interrupts(chip);
1441 * Since this runs from module_init() it cannot use -EPROBE_DEFER,
1442 * instead pre-load any modules which are listed as requirements.
1444 for (i = 0; dev_info->modules && dev_info->modules[i]; i++)
1445 request_module(dev_info->modules[i]);
1447 bat_swnode = dev_info->bat_swnode;
1449 ret = software_node_register(bat_swnode);
1454 gpiod_lookup_tables = dev_info->gpiod_lookup_tables;
1455 for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++)
1456 gpiod_add_lookup_table(gpiod_lookup_tables[i]);
1458 if (dev_info->init) {
1459 ret = dev_info->init();
1461 x86_android_tablet_cleanup();
1464 exit_handler = dev_info->exit;
1467 i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL);
1469 x86_android_tablet_cleanup();
1473 i2c_client_count = dev_info->i2c_client_count;
1474 for (i = 0; i < i2c_client_count; i++) {
1475 ret = x86_instantiate_i2c_client(dev_info, i);
1477 x86_android_tablet_cleanup();
1482 pdevs = kcalloc(dev_info->pdev_count, sizeof(*pdevs), GFP_KERNEL);
1484 x86_android_tablet_cleanup();
1488 pdev_count = dev_info->pdev_count;
1489 for (i = 0; i < pdev_count; i++) {
1490 pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]);
1491 if (IS_ERR(pdevs[i])) {
1492 x86_android_tablet_cleanup();
1493 return PTR_ERR(pdevs[i]);
1497 serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL);
1499 x86_android_tablet_cleanup();
1503 serdev_count = dev_info->serdev_count;
1504 for (i = 0; i < serdev_count; i++) {
1505 ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i);
1507 x86_android_tablet_cleanup();
1515 module_init(x86_android_tablet_init);
1516 module_exit(x86_android_tablet_cleanup);
1519 MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver");
1520 MODULE_LICENSE("GPL");