Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * DMI based code to deal with broken DSDTs on X86 tablets which ship with
0004  * Android as (part of) the factory image. The factory kernels shipped on these
0005  * devices typically have a bunch of things hardcoded, rather than specified
0006  * in their DSDT.
0007  *
0008  * Copyright (C) 2021 Hans de Goede <hdegoede@redhat.com>
0009  */
0010 
0011 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0012 
0013 #include <linux/acpi.h>
0014 #include <linux/dmi.h>
0015 #include <linux/efi.h>
0016 #include <linux/gpio_keys.h>
0017 #include <linux/gpio/consumer.h>
0018 #include <linux/gpio/driver.h>
0019 #include <linux/gpio/machine.h>
0020 #include <linux/i2c.h>
0021 #include <linux/input.h>
0022 #include <linux/irq.h>
0023 #include <linux/irqdomain.h>
0024 #include <linux/module.h>
0025 #include <linux/mod_devicetable.h>
0026 #include <linux/pinctrl/consumer.h>
0027 #include <linux/pinctrl/machine.h>
0028 #include <linux/platform_data/lp855x.h>
0029 #include <linux/platform_device.h>
0030 #include <linux/power/bq24190_charger.h>
0031 #include <linux/reboot.h>
0032 #include <linux/rmi.h>
0033 #include <linux/serdev.h>
0034 #include <linux/spi/spi.h>
0035 #include <linux/string.h>
0036 /* For gpio_get_desc() which is EXPORT_SYMBOL_GPL() */
0037 #include "../../gpio/gpiolib.h"
0038 #include "../../gpio/gpiolib-acpi.h"
0039 
0040 /*
0041  * Helper code to get Linux IRQ numbers given a description of the IRQ source
0042  * (either IOAPIC index, or GPIO chip name + pin-number).
0043  */
0044 enum x86_acpi_irq_type {
0045     X86_ACPI_IRQ_TYPE_NONE,
0046     X86_ACPI_IRQ_TYPE_APIC,
0047     X86_ACPI_IRQ_TYPE_GPIOINT,
0048     X86_ACPI_IRQ_TYPE_PMIC,
0049 };
0050 
0051 struct x86_acpi_irq_data {
0052     char *chip;   /* GPIO chip label (GPIOINT) or PMIC ACPI path (PMIC) */
0053     enum x86_acpi_irq_type type;
0054     enum irq_domain_bus_token domain;
0055     int index;
0056     int trigger;  /* ACPI_EDGE_SENSITIVE / ACPI_LEVEL_SENSITIVE */
0057     int polarity; /* ACPI_ACTIVE_HIGH / ACPI_ACTIVE_LOW / ACPI_ACTIVE_BOTH */
0058 };
0059 
0060 static int gpiochip_find_match_label(struct gpio_chip *gc, void *data)
0061 {
0062     return gc->label && !strcmp(gc->label, data);
0063 }
0064 
0065 static int x86_android_tablet_get_gpiod(char *label, int pin, struct gpio_desc **desc)
0066 {
0067     struct gpio_desc *gpiod;
0068     struct gpio_chip *chip;
0069 
0070     chip = gpiochip_find(label, gpiochip_find_match_label);
0071     if (!chip) {
0072         pr_err("error cannot find GPIO chip %s\n", label);
0073         return -ENODEV;
0074     }
0075 
0076     gpiod = gpiochip_get_desc(chip, pin);
0077     if (IS_ERR(gpiod)) {
0078         pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), label, pin);
0079         return PTR_ERR(gpiod);
0080     }
0081 
0082     *desc = gpiod;
0083     return 0;
0084 }
0085 
0086 static int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data)
0087 {
0088     struct irq_fwspec fwspec = { };
0089     struct irq_domain *domain;
0090     struct acpi_device *adev;
0091     struct gpio_desc *gpiod;
0092     unsigned int irq_type;
0093     acpi_handle handle;
0094     acpi_status status;
0095     int irq, ret;
0096 
0097     switch (data->type) {
0098     case X86_ACPI_IRQ_TYPE_APIC:
0099         /*
0100          * The DSDT may already reference the GSI in a device skipped by
0101          * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI
0102          * to avoid EBUSY errors in this case.
0103          */
0104         acpi_unregister_gsi(data->index);
0105         irq = acpi_register_gsi(NULL, data->index, data->trigger, data->polarity);
0106         if (irq < 0)
0107             pr_err("error %d getting APIC IRQ %d\n", irq, data->index);
0108 
0109         return irq;
0110     case X86_ACPI_IRQ_TYPE_GPIOINT:
0111         /* Like acpi_dev_gpio_irq_get(), but without parsing ACPI resources */
0112         ret = x86_android_tablet_get_gpiod(data->chip, data->index, &gpiod);
0113         if (ret)
0114             return ret;
0115 
0116         irq = gpiod_to_irq(gpiod);
0117         if (irq < 0) {
0118             pr_err("error %d getting IRQ %s %d\n", irq, data->chip, data->index);
0119             return irq;
0120         }
0121 
0122         irq_type = acpi_dev_get_irq_type(data->trigger, data->polarity);
0123         if (irq_type != IRQ_TYPE_NONE && irq_type != irq_get_trigger_type(irq))
0124             irq_set_irq_type(irq, irq_type);
0125 
0126         return irq;
0127     case X86_ACPI_IRQ_TYPE_PMIC:
0128         status = acpi_get_handle(NULL, data->chip, &handle);
0129         if (ACPI_FAILURE(status)) {
0130             pr_err("error could not get %s handle\n", data->chip);
0131             return -ENODEV;
0132         }
0133 
0134         adev = acpi_fetch_acpi_dev(handle);
0135         if (!adev) {
0136             pr_err("error could not get %s adev\n", data->chip);
0137             return -ENODEV;
0138         }
0139 
0140         fwspec.fwnode = acpi_fwnode_handle(adev);
0141         domain = irq_find_matching_fwspec(&fwspec, data->domain);
0142         if (!domain) {
0143             pr_err("error could not find IRQ domain for %s\n", data->chip);
0144             return -ENODEV;
0145         }
0146 
0147         return irq_create_mapping(domain, data->index);
0148     default:
0149         return 0;
0150     }
0151 }
0152 
0153 struct x86_i2c_client_info {
0154     struct i2c_board_info board_info;
0155     char *adapter_path;
0156     struct x86_acpi_irq_data irq_data;
0157 };
0158 
0159 struct x86_serdev_info {
0160     const char *ctrl_hid;
0161     const char *ctrl_uid;
0162     const char *ctrl_devname;
0163     /*
0164      * ATM the serdev core only supports of or ACPI matching; and sofar all
0165      * Android x86 tablets DSDTs have usable serdev nodes, but sometimes
0166      * under the wrong controller. So we just tie the existing serdev ACPI
0167      * node to the right controller.
0168      */
0169     const char *serdev_hid;
0170 };
0171 
0172 struct x86_dev_info {
0173     char *invalid_aei_gpiochip;
0174     const char * const *modules;
0175     const struct software_node *bat_swnode;
0176     struct gpiod_lookup_table * const *gpiod_lookup_tables;
0177     const struct x86_i2c_client_info *i2c_client_info;
0178     const struct platform_device_info *pdev_info;
0179     const struct x86_serdev_info *serdev_info;
0180     int i2c_client_count;
0181     int pdev_count;
0182     int serdev_count;
0183     int (*init)(void);
0184     void (*exit)(void);
0185 };
0186 
0187 /* Generic / shared charger / battery settings */
0188 static const char * const tusb1211_chg_det_psy[] = { "tusb1211-charger-detect" };
0189 static const char * const bq24190_psy[] = { "bq24190-charger" };
0190 static const char * const bq25890_psy[] = { "bq25890-charger" };
0191 
0192 static const struct property_entry fg_bq24190_supply_props[] = {
0193     PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
0194     { }
0195 };
0196 
0197 static const struct software_node fg_bq24190_supply_node = {
0198     .properties = fg_bq24190_supply_props,
0199 };
0200 
0201 static const struct property_entry fg_bq25890_supply_props[] = {
0202     PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_psy),
0203     { }
0204 };
0205 
0206 static const struct software_node fg_bq25890_supply_node = {
0207     .properties = fg_bq25890_supply_props,
0208 };
0209 
0210 /* LiPo HighVoltage (max 4.35V) settings used by most devs with a HV bat. */
0211 static const struct property_entry generic_lipo_hv_4v35_battery_props[] = {
0212     PROPERTY_ENTRY_STRING("compatible", "simple-battery"),
0213     PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion"),
0214     PROPERTY_ENTRY_U32("precharge-current-microamp", 256000),
0215     PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000),
0216     PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 1856000),
0217     PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4352000),
0218     PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000),
0219     { }
0220 };
0221 
0222 static const struct software_node generic_lipo_hv_4v35_battery_node = {
0223     .properties = generic_lipo_hv_4v35_battery_props,
0224 };
0225 
0226 /* For enabling the bq24190 5V boost based on id-pin */
0227 static struct regulator_consumer_supply intel_int3496_consumer = {
0228     .supply = "vbus",
0229     .dev_name = "intel-int3496",
0230 };
0231 
0232 static const struct regulator_init_data bq24190_vbus_init_data = {
0233     .constraints = {
0234         .name = "bq24190_vbus",
0235         .valid_ops_mask = REGULATOR_CHANGE_STATUS,
0236     },
0237     .consumer_supplies = &intel_int3496_consumer,
0238     .num_consumer_supplies = 1,
0239 };
0240 
0241 static struct bq24190_platform_data bq24190_pdata = {
0242     .regulator_init_data = &bq24190_vbus_init_data,
0243 };
0244 
0245 static const char * const bq24190_modules[] __initconst = {
0246     "intel_crystal_cove_charger", /* For the bq24190 IRQ */
0247     "bq24190_charger",            /* For the Vbus regulator for intel-int3496 */
0248     NULL
0249 };
0250 
0251 /* Generic pdevs array and gpio-lookups for micro USB ID pin handling */
0252 static const struct platform_device_info int3496_pdevs[] __initconst = {
0253     {
0254         /* For micro USB ID pin handling */
0255         .name = "intel-int3496",
0256         .id = PLATFORM_DEVID_NONE,
0257     },
0258 };
0259 
0260 static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = {
0261     .dev_id = "intel-int3496",
0262     .table = {
0263         GPIO_LOOKUP("INT33FC:02", 22, "id", GPIO_ACTIVE_HIGH),
0264         { }
0265     },
0266 };
0267 
0268 /* Asus ME176C and TF103C tablets shared data */
0269 static struct gpio_keys_button asus_me176c_tf103c_lid = {
0270     .code = SW_LID,
0271     /* .gpio gets filled in by asus_me176c_tf103c_init() */
0272     .active_low = true,
0273     .desc = "lid_sw",
0274     .type = EV_SW,
0275     .wakeup = true,
0276     .debounce_interval = 50,
0277 };
0278 
0279 static const struct gpio_keys_platform_data asus_me176c_tf103c_lid_pdata __initconst = {
0280     .buttons = &asus_me176c_tf103c_lid,
0281     .nbuttons = 1,
0282     .name = "lid_sw",
0283 };
0284 
0285 static const struct platform_device_info asus_me176c_tf103c_pdevs[] __initconst = {
0286     {
0287         .name = "gpio-keys",
0288         .id = PLATFORM_DEVID_AUTO,
0289         .data = &asus_me176c_tf103c_lid_pdata,
0290         .size_data = sizeof(asus_me176c_tf103c_lid_pdata),
0291     },
0292     {
0293         /* For micro USB ID pin handling */
0294         .name = "intel-int3496",
0295         .id = PLATFORM_DEVID_NONE,
0296     },
0297 };
0298 
0299 static int __init asus_me176c_tf103c_init(void)
0300 {
0301     struct gpio_desc *gpiod;
0302     int ret;
0303 
0304     ret = x86_android_tablet_get_gpiod("INT33FC:02", 12, &gpiod);
0305     if (ret < 0)
0306         return ret;
0307     asus_me176c_tf103c_lid.gpio = desc_to_gpio(gpiod);
0308 
0309     return 0;
0310 }
0311 
0312 
0313 /* Asus ME176C tablets have an Android factory img with everything hardcoded */
0314 static const char * const asus_me176c_accel_mount_matrix[] = {
0315     "-1", "0", "0",
0316     "0", "1", "0",
0317     "0", "0", "1"
0318 };
0319 
0320 static const struct property_entry asus_me176c_accel_props[] = {
0321     PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_me176c_accel_mount_matrix),
0322     { }
0323 };
0324 
0325 static const struct software_node asus_me176c_accel_node = {
0326     .properties = asus_me176c_accel_props,
0327 };
0328 
0329 static const struct property_entry asus_me176c_bq24190_props[] = {
0330     PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
0331     PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
0332     PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000),
0333     PROPERTY_ENTRY_BOOL("omit-battery-class"),
0334     PROPERTY_ENTRY_BOOL("disable-reset"),
0335     { }
0336 };
0337 
0338 static const struct software_node asus_me176c_bq24190_node = {
0339     .properties = asus_me176c_bq24190_props,
0340 };
0341 
0342 static const struct property_entry asus_me176c_ug3105_props[] = {
0343     PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
0344     PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
0345     PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 10000),
0346     { }
0347 };
0348 
0349 static const struct software_node asus_me176c_ug3105_node = {
0350     .properties = asus_me176c_ug3105_props,
0351 };
0352 
0353 static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = {
0354     {
0355         /* bq24297 battery charger */
0356         .board_info = {
0357             .type = "bq24190",
0358             .addr = 0x6b,
0359             .dev_name = "bq24297",
0360             .swnode = &asus_me176c_bq24190_node,
0361             .platform_data = &bq24190_pdata,
0362         },
0363         .adapter_path = "\\_SB_.I2C1",
0364         .irq_data = {
0365             .type = X86_ACPI_IRQ_TYPE_PMIC,
0366             .chip = "\\_SB_.I2C7.PMIC",
0367             .domain = DOMAIN_BUS_WAKEUP,
0368             .index = 0,
0369         },
0370     }, {
0371         /* ug3105 battery monitor */
0372         .board_info = {
0373             .type = "ug3105",
0374             .addr = 0x70,
0375             .dev_name = "ug3105",
0376             .swnode = &asus_me176c_ug3105_node,
0377         },
0378         .adapter_path = "\\_SB_.I2C1",
0379     }, {
0380         /* ak09911 compass */
0381         .board_info = {
0382             .type = "ak09911",
0383             .addr = 0x0c,
0384             .dev_name = "ak09911",
0385         },
0386         .adapter_path = "\\_SB_.I2C5",
0387     }, {
0388         /* kxtj21009 accel */
0389         .board_info = {
0390             .type = "kxtj21009",
0391             .addr = 0x0f,
0392             .dev_name = "kxtj21009",
0393             .swnode = &asus_me176c_accel_node,
0394         },
0395         .adapter_path = "\\_SB_.I2C5",
0396         .irq_data = {
0397             .type = X86_ACPI_IRQ_TYPE_APIC,
0398             .index = 0x44,
0399             .trigger = ACPI_EDGE_SENSITIVE,
0400             .polarity = ACPI_ACTIVE_LOW,
0401         },
0402     }, {
0403         /* goodix touchscreen */
0404         .board_info = {
0405             .type = "GDIX1001:00",
0406             .addr = 0x14,
0407             .dev_name = "goodix_ts",
0408         },
0409         .adapter_path = "\\_SB_.I2C6",
0410         .irq_data = {
0411             .type = X86_ACPI_IRQ_TYPE_APIC,
0412             .index = 0x45,
0413             .trigger = ACPI_EDGE_SENSITIVE,
0414             .polarity = ACPI_ACTIVE_LOW,
0415         },
0416     },
0417 };
0418 
0419 static const struct x86_serdev_info asus_me176c_serdevs[] __initconst = {
0420     {
0421         .ctrl_hid = "80860F0A",
0422         .ctrl_uid = "2",
0423         .ctrl_devname = "serial0",
0424         .serdev_hid = "BCM2E3A",
0425     },
0426 };
0427 
0428 static struct gpiod_lookup_table asus_me176c_goodix_gpios = {
0429     .dev_id = "i2c-goodix_ts",
0430     .table = {
0431         GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_HIGH),
0432         GPIO_LOOKUP("INT33FC:02", 28, "irq", GPIO_ACTIVE_HIGH),
0433         { }
0434     },
0435 };
0436 
0437 static struct gpiod_lookup_table * const asus_me176c_gpios[] = {
0438     &int3496_gpo2_pin22_gpios,
0439     &asus_me176c_goodix_gpios,
0440     NULL
0441 };
0442 
0443 static const struct x86_dev_info asus_me176c_info __initconst = {
0444     .i2c_client_info = asus_me176c_i2c_clients,
0445     .i2c_client_count = ARRAY_SIZE(asus_me176c_i2c_clients),
0446     .pdev_info = asus_me176c_tf103c_pdevs,
0447     .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs),
0448     .serdev_info = asus_me176c_serdevs,
0449     .serdev_count = ARRAY_SIZE(asus_me176c_serdevs),
0450     .gpiod_lookup_tables = asus_me176c_gpios,
0451     .bat_swnode = &generic_lipo_hv_4v35_battery_node,
0452     .modules = bq24190_modules,
0453     .invalid_aei_gpiochip = "INT33FC:02",
0454     .init = asus_me176c_tf103c_init,
0455 };
0456 
0457 /* Asus TF103C tablets have an Android factory img with everything hardcoded */
0458 static const char * const asus_tf103c_accel_mount_matrix[] = {
0459     "0", "-1", "0",
0460     "-1", "0", "0",
0461     "0", "0", "1"
0462 };
0463 
0464 static const struct property_entry asus_tf103c_accel_props[] = {
0465     PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_tf103c_accel_mount_matrix),
0466     { }
0467 };
0468 
0469 static const struct software_node asus_tf103c_accel_node = {
0470     .properties = asus_tf103c_accel_props,
0471 };
0472 
0473 static const struct property_entry asus_tf103c_touchscreen_props[] = {
0474     PROPERTY_ENTRY_STRING("compatible", "atmel,atmel_mxt_ts"),
0475     { }
0476 };
0477 
0478 static const struct software_node asus_tf103c_touchscreen_node = {
0479     .properties = asus_tf103c_touchscreen_props,
0480 };
0481 
0482 static const struct property_entry asus_tf103c_battery_props[] = {
0483     PROPERTY_ENTRY_STRING("compatible", "simple-battery"),
0484     PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion-polymer"),
0485     PROPERTY_ENTRY_U32("precharge-current-microamp", 256000),
0486     PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000),
0487     PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 2048000),
0488     PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4208000),
0489     PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000),
0490     { }
0491 };
0492 
0493 static const struct software_node asus_tf103c_battery_node = {
0494     .properties = asus_tf103c_battery_props,
0495 };
0496 
0497 static const struct property_entry asus_tf103c_bq24190_props[] = {
0498     PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
0499     PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node),
0500     PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000),
0501     PROPERTY_ENTRY_BOOL("omit-battery-class"),
0502     PROPERTY_ENTRY_BOOL("disable-reset"),
0503     { }
0504 };
0505 
0506 static const struct software_node asus_tf103c_bq24190_node = {
0507     .properties = asus_tf103c_bq24190_props,
0508 };
0509 
0510 static const struct property_entry asus_tf103c_ug3105_props[] = {
0511     PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
0512     PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node),
0513     PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 5000),
0514     { }
0515 };
0516 
0517 static const struct software_node asus_tf103c_ug3105_node = {
0518     .properties = asus_tf103c_ug3105_props,
0519 };
0520 
0521 static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = {
0522     {
0523         /* bq24297 battery charger */
0524         .board_info = {
0525             .type = "bq24190",
0526             .addr = 0x6b,
0527             .dev_name = "bq24297",
0528             .swnode = &asus_tf103c_bq24190_node,
0529             .platform_data = &bq24190_pdata,
0530         },
0531         .adapter_path = "\\_SB_.I2C1",
0532         .irq_data = {
0533             .type = X86_ACPI_IRQ_TYPE_PMIC,
0534             .chip = "\\_SB_.I2C7.PMIC",
0535             .domain = DOMAIN_BUS_WAKEUP,
0536             .index = 0,
0537         },
0538     }, {
0539         /* ug3105 battery monitor */
0540         .board_info = {
0541             .type = "ug3105",
0542             .addr = 0x70,
0543             .dev_name = "ug3105",
0544             .swnode = &asus_tf103c_ug3105_node,
0545         },
0546         .adapter_path = "\\_SB_.I2C1",
0547     }, {
0548         /* ak09911 compass */
0549         .board_info = {
0550             .type = "ak09911",
0551             .addr = 0x0c,
0552             .dev_name = "ak09911",
0553         },
0554         .adapter_path = "\\_SB_.I2C5",
0555     }, {
0556         /* kxtj21009 accel */
0557         .board_info = {
0558             .type = "kxtj21009",
0559             .addr = 0x0f,
0560             .dev_name = "kxtj21009",
0561             .swnode = &asus_tf103c_accel_node,
0562         },
0563         .adapter_path = "\\_SB_.I2C5",
0564     }, {
0565         /* atmel touchscreen */
0566         .board_info = {
0567             .type = "atmel_mxt_ts",
0568             .addr = 0x4a,
0569             .dev_name = "atmel_mxt_ts",
0570             .swnode = &asus_tf103c_touchscreen_node,
0571         },
0572         .adapter_path = "\\_SB_.I2C6",
0573         .irq_data = {
0574             .type = X86_ACPI_IRQ_TYPE_GPIOINT,
0575             .chip = "INT33FC:02",
0576             .index = 28,
0577             .trigger = ACPI_EDGE_SENSITIVE,
0578             .polarity = ACPI_ACTIVE_LOW,
0579         },
0580     },
0581 };
0582 
0583 static struct gpiod_lookup_table * const asus_tf103c_gpios[] = {
0584     &int3496_gpo2_pin22_gpios,
0585     NULL
0586 };
0587 
0588 static const struct x86_dev_info asus_tf103c_info __initconst = {
0589     .i2c_client_info = asus_tf103c_i2c_clients,
0590     .i2c_client_count = ARRAY_SIZE(asus_tf103c_i2c_clients),
0591     .pdev_info = asus_me176c_tf103c_pdevs,
0592     .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs),
0593     .gpiod_lookup_tables = asus_tf103c_gpios,
0594     .bat_swnode = &asus_tf103c_battery_node,
0595     .modules = bq24190_modules,
0596     .invalid_aei_gpiochip = "INT33FC:02",
0597     .init = asus_me176c_tf103c_init,
0598 };
0599 
0600 /*
0601  * When booted with the BIOS set to Android mode the Chuwi Hi8 (CWI509) DSDT
0602  * contains a whole bunch of bogus ACPI I2C devices and is missing entries
0603  * for the touchscreen and the accelerometer.
0604  */
0605 static const struct property_entry chuwi_hi8_gsl1680_props[] = {
0606     PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
0607     PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
0608     PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
0609     PROPERTY_ENTRY_BOOL("silead,home-button"),
0610     PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi8.fw"),
0611     { }
0612 };
0613 
0614 static const struct software_node chuwi_hi8_gsl1680_node = {
0615     .properties = chuwi_hi8_gsl1680_props,
0616 };
0617 
0618 static const char * const chuwi_hi8_mount_matrix[] = {
0619     "1", "0", "0",
0620     "0", "-1", "0",
0621     "0", "0", "1"
0622 };
0623 
0624 static const struct property_entry chuwi_hi8_bma250e_props[] = {
0625     PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", chuwi_hi8_mount_matrix),
0626     { }
0627 };
0628 
0629 static const struct software_node chuwi_hi8_bma250e_node = {
0630     .properties = chuwi_hi8_bma250e_props,
0631 };
0632 
0633 static const struct x86_i2c_client_info chuwi_hi8_i2c_clients[] __initconst = {
0634     {
0635         /* Silead touchscreen */
0636         .board_info = {
0637             .type = "gsl1680",
0638             .addr = 0x40,
0639             .swnode = &chuwi_hi8_gsl1680_node,
0640         },
0641         .adapter_path = "\\_SB_.I2C4",
0642         .irq_data = {
0643             .type = X86_ACPI_IRQ_TYPE_APIC,
0644             .index = 0x44,
0645             .trigger = ACPI_EDGE_SENSITIVE,
0646             .polarity = ACPI_ACTIVE_HIGH,
0647         },
0648     }, {
0649         /* BMA250E accelerometer */
0650         .board_info = {
0651             .type = "bma250e",
0652             .addr = 0x18,
0653             .swnode = &chuwi_hi8_bma250e_node,
0654         },
0655         .adapter_path = "\\_SB_.I2C3",
0656         .irq_data = {
0657             .type = X86_ACPI_IRQ_TYPE_GPIOINT,
0658             .chip = "INT33FC:02",
0659             .index = 23,
0660             .trigger = ACPI_LEVEL_SENSITIVE,
0661             .polarity = ACPI_ACTIVE_HIGH,
0662         },
0663     },
0664 };
0665 
0666 static int __init chuwi_hi8_init(void)
0667 {
0668     /*
0669      * Avoid the acpi_unregister_gsi() call in x86_acpi_irq_helper_get()
0670      * breaking the touchscreen + logging various errors when the Windows
0671      * BIOS is used.
0672      */
0673     if (acpi_dev_present("MSSL0001", NULL, 1))
0674         return -ENODEV;
0675 
0676     return 0;
0677 }
0678 
0679 static const struct x86_dev_info chuwi_hi8_info __initconst = {
0680     .i2c_client_info = chuwi_hi8_i2c_clients,
0681     .i2c_client_count = ARRAY_SIZE(chuwi_hi8_i2c_clients),
0682     .init = chuwi_hi8_init,
0683 };
0684 
0685 #define CZC_EC_EXTRA_PORT   0x68
0686 #define CZC_EC_ANDROID_KEYS 0x63
0687 
0688 static int __init czc_p10t_init(void)
0689 {
0690     /*
0691      * The device boots up in "Windows 7" mode, when the home button sends a
0692      * Windows specific key sequence (Left Meta + D) and the second button
0693      * sends an unknown one while also toggling the Radio Kill Switch.
0694      * This is a surprising behavior when the second button is labeled "Back".
0695      *
0696      * The vendor-supplied Android-x86 build switches the device to a "Android"
0697      * mode by writing value 0x63 to the I/O port 0x68. This just seems to just
0698      * set bit 6 on address 0x96 in the EC region; switching the bit directly
0699      * seems to achieve the same result. It uses a "p10t_switcher" to do the
0700      * job. It doesn't seem to be able to do anything else, and no other use
0701      * of the port 0x68 is known.
0702      *
0703      * In the Android mode, the home button sends just a single scancode,
0704      * which can be handled in Linux userspace more reasonably and the back
0705      * button only sends a scancode without toggling the kill switch.
0706      * The scancode can then be mapped either to Back or RF Kill functionality
0707      * in userspace, depending on how the button is labeled on that particular
0708      * model.
0709      */
0710     outb(CZC_EC_ANDROID_KEYS, CZC_EC_EXTRA_PORT);
0711     return 0;
0712 }
0713 
0714 static const struct x86_dev_info czc_p10t __initconst = {
0715     .init = czc_p10t_init,
0716 };
0717 
0718 /* Lenovo Yoga Book X90F / X91F / X91L need manual instantiation of the fg client */
0719 static const struct x86_i2c_client_info lenovo_yogabook_x9x_i2c_clients[] __initconst = {
0720     {
0721         /* BQ27542 fuel-gauge */
0722         .board_info = {
0723             .type = "bq27542",
0724             .addr = 0x55,
0725             .dev_name = "bq27542",
0726             .swnode = &fg_bq25890_supply_node,
0727         },
0728         .adapter_path = "\\_SB_.PCI0.I2C1",
0729     },
0730 };
0731 
0732 static const struct x86_dev_info lenovo_yogabook_x9x_info __initconst = {
0733     .i2c_client_info = lenovo_yogabook_x9x_i2c_clients,
0734     .i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x9x_i2c_clients),
0735 };
0736 
0737 /* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */
0738 static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
0739     PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
0740     PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
0741     PROPERTY_ENTRY_BOOL("omit-battery-class"),
0742     PROPERTY_ENTRY_BOOL("disable-reset"),
0743     { }
0744 };
0745 
0746 static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
0747     .properties = lenovo_yoga_tab2_830_1050_bq24190_props,
0748 };
0749 
0750 /* This gets filled by lenovo_yoga_tab2_830_1050_init() */
0751 static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
0752 
0753 static struct lp855x_platform_data lenovo_yoga_tab2_830_1050_lp8557_pdata = {
0754     .device_control = 0x86,
0755     .initial_brightness = 128,
0756 };
0757 
0758 static const struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initconst = {
0759     {
0760         /* bq24292i battery charger */
0761         .board_info = {
0762             .type = "bq24190",
0763             .addr = 0x6b,
0764             .dev_name = "bq24292i",
0765             .swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
0766             .platform_data = &bq24190_pdata,
0767         },
0768         .adapter_path = "\\_SB_.I2C1",
0769         .irq_data = {
0770             .type = X86_ACPI_IRQ_TYPE_GPIOINT,
0771             .chip = "INT33FC:02",
0772             .index = 2,
0773             .trigger = ACPI_EDGE_SENSITIVE,
0774             .polarity = ACPI_ACTIVE_HIGH,
0775         },
0776     }, {
0777         /* BQ27541 fuel-gauge */
0778         .board_info = {
0779             .type = "bq27541",
0780             .addr = 0x55,
0781             .dev_name = "bq27541",
0782             .swnode = &fg_bq24190_supply_node,
0783         },
0784         .adapter_path = "\\_SB_.I2C1",
0785     }, {
0786         /* Synaptics RMI touchscreen */
0787         .board_info = {
0788             .type = "rmi4_i2c",
0789             .addr = 0x38,
0790             .dev_name = "rmi4_i2c",
0791             .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
0792         },
0793         .adapter_path = "\\_SB_.I2C6",
0794         .irq_data = {
0795             .type = X86_ACPI_IRQ_TYPE_APIC,
0796             .index = 0x45,
0797             .trigger = ACPI_EDGE_SENSITIVE,
0798             .polarity = ACPI_ACTIVE_HIGH,
0799         },
0800     }, {
0801         /* LP8557 Backlight controller */
0802         .board_info = {
0803             .type = "lp8557",
0804             .addr = 0x2c,
0805             .dev_name = "lp8557",
0806             .platform_data = &lenovo_yoga_tab2_830_1050_lp8557_pdata,
0807         },
0808         .adapter_path = "\\_SB_.I2C3",
0809     },
0810 };
0811 
0812 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
0813     .dev_id = "intel-int3496",
0814     .table = {
0815         GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
0816         GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
0817         { }
0818     },
0819 };
0820 
0821 #define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
0822 
0823 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = {
0824     .dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME,
0825     .table = {
0826         GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH),
0827         GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH),
0828         GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
0829         GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW),
0830         { }
0831     },
0832 };
0833 
0834 static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = {
0835     &lenovo_yoga_tab2_830_1050_int3496_gpios,
0836     &lenovo_yoga_tab2_830_1050_codec_gpios,
0837     NULL
0838 };
0839 
0840 static int __init lenovo_yoga_tab2_830_1050_init(void);
0841 static void lenovo_yoga_tab2_830_1050_exit(void);
0842 
0843 static struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initdata = {
0844     .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
0845     /* i2c_client_count gets set by lenovo_yoga_tab2_830_1050_init() */
0846     .pdev_info = int3496_pdevs,
0847     .pdev_count = ARRAY_SIZE(int3496_pdevs),
0848     .gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios,
0849     .bat_swnode = &generic_lipo_hv_4v35_battery_node,
0850     .modules = bq24190_modules,
0851     .invalid_aei_gpiochip = "INT33FC:02",
0852     .init = lenovo_yoga_tab2_830_1050_init,
0853     .exit = lenovo_yoga_tab2_830_1050_exit,
0854 };
0855 
0856 /*
0857  * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
0858  * mainboard, but they need some different treatment related to the display:
0859  * 1. The 830 uses a portrait LCD panel with a landscape touchscreen, requiring
0860  *    the touchscreen driver to adjust the touch-coords to match the LCD.
0861  * 2. Both use an TI LP8557 LED backlight controller. On the 1050 the LP8557's
0862  *    PWM input is connected to the PMIC's PWM output and everything works fine
0863  *    with the defaults programmed into the LP8557 by the BIOS.
0864  *    But on the 830 the LP8557's PWM input is connected to a PWM output coming
0865  *    from the LCD panel's controller. The Android code has a hack in the i915
0866  *    driver to write the non-standard DSI reg 0x9f with the desired backlight
0867  *    level to set the duty-cycle of the LCD's PWM output.
0868  *
0869  *    To avoid having to have a similar hack in the mainline kernel the LP8557
0870  *    entry in lenovo_yoga_tab2_830_1050_i2c_clients instead just programs the
0871  *    LP8557 to directly set the level, ignoring the PWM input. This means that
0872  *    the LP8557 i2c_client should only be instantiated on the 830.
0873  */
0874 static int __init lenovo_yoga_tab2_830_1050_init_display(void)
0875 {
0876     struct gpio_desc *gpiod;
0877     int ret;
0878 
0879     /* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
0880     ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, &gpiod);
0881     if (ret)
0882         return ret;
0883 
0884     ret = gpiod_get_value_cansleep(gpiod);
0885     if (ret) {
0886         pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
0887         lenovo_yoga_tab2_830_1050_info.i2c_client_count =
0888             ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients) - 1;
0889     } else {
0890         pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
0891         lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
0892         lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
0893         lenovo_yoga_tab2_830_1050_info.i2c_client_count =
0894             ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients);
0895     }
0896 
0897     return 0;
0898 }
0899 
0900 /* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
0901 static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
0902     PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
0903               "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
0904 
0905 static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
0906 static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
0907 
0908 static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
0909 {
0910     struct device *codec_dev;
0911     struct pinctrl *pinctrl;
0912     int ret;
0913 
0914     codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
0915                         LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
0916     if (!codec_dev) {
0917         pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
0918         return -ENODEV;
0919     }
0920 
0921     ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
0922     if (ret)
0923         goto err_put_device;
0924 
0925     pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
0926     if (IS_ERR(pinctrl)) {
0927         ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
0928         goto err_unregister_mappings;
0929     }
0930 
0931     /* We're done with the codec_dev now */
0932     put_device(codec_dev);
0933 
0934     lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
0935     return 0;
0936 
0937 err_unregister_mappings:
0938     pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
0939 err_put_device:
0940     put_device(codec_dev);
0941     return ret;
0942 }
0943 
0944 /*
0945  * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off
0946  * gets used as pm_power_off handler. This causes "poweroff" on these tablets
0947  * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice*
0948  * followed by a normal 3 second press to recover. Avoid this by doing an EFI
0949  * poweroff instead.
0950  */
0951 static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
0952 {
0953     efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
0954 
0955     return NOTIFY_DONE;
0956 }
0957 
0958 static int __init lenovo_yoga_tab2_830_1050_init(void)
0959 {
0960     int ret;
0961 
0962     ret = lenovo_yoga_tab2_830_1050_init_display();
0963     if (ret)
0964         return ret;
0965 
0966     ret = lenovo_yoga_tab2_830_1050_init_codec();
0967     if (ret)
0968         return ret;
0969 
0970     /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */
0971     lenovo_yoga_tab2_830_1050_sys_off_handler =
0972         register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
0973                      lenovo_yoga_tab2_830_1050_power_off, NULL);
0974     if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
0975         return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
0976 
0977     return 0;
0978 }
0979 
0980 static void lenovo_yoga_tab2_830_1050_exit(void)
0981 {
0982     unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
0983 
0984     if (lenovo_yoga_tab2_830_1050_codec_pinctrl) {
0985         pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
0986         pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
0987     }
0988 }
0989 
0990 /* Nextbook Ares 8 tablets have an Android factory img with everything hardcoded */
0991 static const char * const nextbook_ares8_accel_mount_matrix[] = {
0992     "0", "-1", "0",
0993     "-1", "0", "0",
0994     "0", "0", "1"
0995 };
0996 
0997 static const struct property_entry nextbook_ares8_accel_props[] = {
0998     PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", nextbook_ares8_accel_mount_matrix),
0999     { }
1000 };
1001 
1002 static const struct software_node nextbook_ares8_accel_node = {
1003     .properties = nextbook_ares8_accel_props,
1004 };
1005 
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),
1009     { }
1010 };
1011 
1012 static const struct software_node nextbook_ares8_touchscreen_node = {
1013     .properties = nextbook_ares8_touchscreen_props,
1014 };
1015 
1016 static const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst = {
1017     {
1018         /* Freescale MMA8653FC accel */
1019         .board_info = {
1020             .type = "mma8653",
1021             .addr = 0x1d,
1022             .dev_name = "mma8653",
1023             .swnode = &nextbook_ares8_accel_node,
1024         },
1025         .adapter_path = "\\_SB_.I2C3",
1026     }, {
1027         /* FT5416DQ9 touchscreen controller */
1028         .board_info = {
1029             .type = "edt-ft5x06",
1030             .addr = 0x38,
1031             .dev_name = "ft5416",
1032             .swnode = &nextbook_ares8_touchscreen_node,
1033         },
1034         .adapter_path = "\\_SB_.I2C4",
1035         .irq_data = {
1036             .type = X86_ACPI_IRQ_TYPE_GPIOINT,
1037             .chip = "INT33FC:02",
1038             .index = 3,
1039             .trigger = ACPI_EDGE_SENSITIVE,
1040             .polarity = ACPI_ACTIVE_LOW,
1041         },
1042     },
1043 };
1044 
1045 static struct gpiod_lookup_table nextbook_ares8_int3496_gpios = {
1046     .dev_id = "intel-int3496",
1047     .table = {
1048         GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_HIGH),
1049         GPIO_LOOKUP("INT33FC:02", 18, "id", GPIO_ACTIVE_HIGH),
1050         { }
1051     },
1052 };
1053 
1054 static struct gpiod_lookup_table * const nextbook_ares8_gpios[] = {
1055     &nextbook_ares8_int3496_gpios,
1056     NULL
1057 };
1058 
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",
1066 };
1067 
1068 /*
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.
1073  */
1074 static const char * const whitelabel_tm800a550l_accel_mount_matrix[] = {
1075     "-1", "0", "0",
1076     "0", "1", "0",
1077     "0", "0", "1"
1078 };
1079 
1080 static const struct property_entry whitelabel_tm800a550l_accel_props[] = {
1081     PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", whitelabel_tm800a550l_accel_mount_matrix),
1082     { }
1083 };
1084 
1085 static const struct software_node whitelabel_tm800a550l_accel_node = {
1086     .properties = whitelabel_tm800a550l_accel_props,
1087 };
1088 
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),
1093     { }
1094 };
1095 
1096 static const struct software_node whitelabel_tm800a550l_goodix_node = {
1097     .properties = whitelabel_tm800a550l_goodix_props,
1098 };
1099 
1100 static const struct x86_i2c_client_info whitelabel_tm800a550l_i2c_clients[] __initconst = {
1101     {
1102         /* goodix touchscreen */
1103         .board_info = {
1104             .type = "GDIX1001:00",
1105             .addr = 0x14,
1106             .dev_name = "goodix_ts",
1107             .swnode = &whitelabel_tm800a550l_goodix_node,
1108         },
1109         .adapter_path = "\\_SB_.I2C2",
1110         .irq_data = {
1111             .type = X86_ACPI_IRQ_TYPE_APIC,
1112             .index = 0x44,
1113             .trigger = ACPI_EDGE_SENSITIVE,
1114             .polarity = ACPI_ACTIVE_HIGH,
1115         },
1116     }, {
1117         /* kxcj91008 accel */
1118         .board_info = {
1119             .type = "kxcj91008",
1120             .addr = 0x0f,
1121             .dev_name = "kxcj91008",
1122             .swnode = &whitelabel_tm800a550l_accel_node,
1123         },
1124         .adapter_path = "\\_SB_.I2C3",
1125     },
1126 };
1127 
1128 static struct gpiod_lookup_table whitelabel_tm800a550l_goodix_gpios = {
1129     .dev_id = "i2c-goodix_ts",
1130     .table = {
1131         GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH),
1132         GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH),
1133         { }
1134     },
1135 };
1136 
1137 static struct gpiod_lookup_table * const whitelabel_tm800a550l_gpios[] = {
1138     &whitelabel_tm800a550l_goodix_gpios,
1139     NULL
1140 };
1141 
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,
1146 };
1147 
1148 /*
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.
1152  *
1153  * This takes care of instantiating the hidden devices manually.
1154  */
1155 static const struct x86_i2c_client_info xiaomi_mipad2_i2c_clients[] __initconst = {
1156     {
1157         /* BQ27520 fuel-gauge */
1158         .board_info = {
1159             .type = "bq27520",
1160             .addr = 0x55,
1161             .dev_name = "bq27520",
1162             .swnode = &fg_bq25890_supply_node,
1163         },
1164         .adapter_path = "\\_SB_.PCI0.I2C1",
1165     }, {
1166         /* KTD2026 RGB notification LED controller */
1167         .board_info = {
1168             .type = "ktd2026",
1169             .addr = 0x30,
1170             .dev_name = "ktd2026",
1171         },
1172         .adapter_path = "\\_SB_.PCI0.I2C3",
1173     },
1174 };
1175 
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),
1179 };
1180 
1181 static const struct dmi_system_id x86_android_tablet_ids[] __initconst = {
1182     {
1183         /* Asus MeMO Pad 7 ME176C */
1184         .matches = {
1185             DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
1186             DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"),
1187         },
1188         .driver_data = (void *)&asus_me176c_info,
1189     },
1190     {
1191         /* Asus TF103C */
1192         .matches = {
1193             DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
1194             DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
1195         },
1196         .driver_data = (void *)&asus_tf103c_info,
1197     },
1198     {
1199         /* Chuwi Hi8 (CWI509) */
1200         .matches = {
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"),
1205         },
1206         .driver_data = (void *)&chuwi_hi8_info,
1207     },
1208     {
1209         /* CZC P10T */
1210         .ident = "CZC ODEON TPC-10 (\"P10T\")",
1211         .matches = {
1212             DMI_MATCH(DMI_SYS_VENDOR, "CZC"),
1213             DMI_MATCH(DMI_PRODUCT_NAME, "ODEON*TPC-10"),
1214         },
1215         .driver_data = (void *)&czc_p10t,
1216     },
1217     {
1218         /* CZC P10T variant */
1219         .ident = "ViewSonic ViewPad 10",
1220         .matches = {
1221             DMI_MATCH(DMI_SYS_VENDOR, "ViewSonic"),
1222             DMI_MATCH(DMI_PRODUCT_NAME, "VPAD10"),
1223         },
1224         .driver_data = (void *)&czc_p10t,
1225     },
1226     {
1227         /* Lenovo Yoga Book X90F / X91F / X91L */
1228         .matches = {
1229             /* Non exact match to match all versions */
1230             DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
1231         },
1232         .driver_data = (void *)&lenovo_yogabook_x9x_info,
1233     },
1234     {
1235         /*
1236          * Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10"
1237          * Lenovo Yoga Tablet 2 use the same mainboard)
1238          */
1239         .matches = {
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"),
1245         },
1246         .driver_data = (void *)&lenovo_yoga_tab2_830_1050_info,
1247     },
1248     {
1249         /* Nextbook Ares 8 */
1250         .matches = {
1251             DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
1252             DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"),
1253         },
1254         .driver_data = (void *)&nextbook_ares8_info,
1255     },
1256     {
1257         /* Whitelabel (sold as various brands) TM800A550L */
1258         .matches = {
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"),
1263         },
1264         .driver_data = (void *)&whitelabel_tm800a550l_info,
1265     },
1266     {
1267         /* Xiaomi Mi Pad 2 */
1268         .matches = {
1269             DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
1270             DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
1271         },
1272         .driver_data = (void *)&xiaomi_mipad2_info,
1273     },
1274     { }
1275 };
1276 MODULE_DEVICE_TABLE(dmi, x86_android_tablet_ids);
1277 
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);
1287 
1288 static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info,
1289                          int idx)
1290 {
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;
1294     acpi_handle handle;
1295     acpi_status status;
1296 
1297     board_info.irq = x86_acpi_irq_helper_get(&client_info->irq_data);
1298     if (board_info.irq < 0)
1299         return board_info.irq;
1300 
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);
1304         return -ENODEV;
1305     }
1306 
1307     adap = i2c_acpi_find_adapter_by_handle(handle);
1308     if (!adap) {
1309         pr_err("error could not get %s adapter\n", client_info->adapter_path);
1310         return -ENODEV;
1311     }
1312 
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);
1318 
1319     return 0;
1320 }
1321 
1322 static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx)
1323 {
1324     struct acpi_device *ctrl_adev, *serdev_adev;
1325     struct serdev_device *serdev;
1326     struct device *ctrl_dev;
1327     int ret = -ENODEV;
1328 
1329     ctrl_adev = acpi_dev_get_first_match_dev(info->ctrl_hid, info->ctrl_uid, -1);
1330     if (!ctrl_adev) {
1331         pr_err("error could not get %s/%s ctrl adev\n",
1332                info->ctrl_hid, info->ctrl_uid);
1333         return -ENODEV;
1334     }
1335 
1336     serdev_adev = acpi_dev_get_first_match_dev(info->serdev_hid, NULL, -1);
1337     if (!serdev_adev) {
1338         pr_err("error could not get %s serdev adev\n", info->serdev_hid);
1339         goto put_ctrl_adev;
1340     }
1341 
1342     /* get_first_physical_node() returns a weak ref, no need to put() it */
1343     ctrl_dev = acpi_get_first_physical_node(ctrl_adev);
1344     if (!ctrl_dev)  {
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;
1348     }
1349 
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);
1352     if (!ctrl_dev) {
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;
1356     }
1357 
1358     serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev));
1359     if (!serdev) {
1360         ret = -ENOMEM;
1361         goto put_serdev_adev;
1362     }
1363 
1364     ACPI_COMPANION_SET(&serdev->dev, serdev_adev);
1365     acpi_device_set_enumerated(serdev_adev);
1366 
1367     ret = serdev_device_add(serdev);
1368     if (ret) {
1369         dev_err(&serdev->dev, "error %d adding serdev\n", ret);
1370         serdev_device_put(serdev);
1371         goto put_serdev_adev;
1372     }
1373 
1374     serdevs[idx] = serdev;
1375 
1376 put_serdev_adev:
1377     acpi_dev_put(serdev_adev);
1378 put_ctrl_adev:
1379     acpi_dev_put(ctrl_adev);
1380     return ret;
1381 }
1382 
1383 static void x86_android_tablet_cleanup(void)
1384 {
1385     int i;
1386 
1387     for (i = 0; i < serdev_count; i++) {
1388         if (serdevs[i])
1389             serdev_device_remove(serdevs[i]);
1390     }
1391 
1392     kfree(serdevs);
1393 
1394     for (i = 0; i < pdev_count; i++)
1395         platform_device_unregister(pdevs[i]);
1396 
1397     kfree(pdevs);
1398 
1399     for (i = 0; i < i2c_client_count; i++)
1400         i2c_unregister_device(i2c_clients[i]);
1401 
1402     kfree(i2c_clients);
1403 
1404     if (exit_handler)
1405         exit_handler();
1406 
1407     for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++)
1408         gpiod_remove_lookup_table(gpiod_lookup_tables[i]);
1409 
1410     software_node_unregister(bat_swnode);
1411 }
1412 
1413 static __init int x86_android_tablet_init(void)
1414 {
1415     const struct x86_dev_info *dev_info;
1416     const struct dmi_system_id *id;
1417     struct gpio_chip *chip;
1418     int i, ret = 0;
1419 
1420     id = dmi_first_match(x86_android_tablet_ids);
1421     if (!id)
1422         return -ENODEV;
1423 
1424     dev_info = id->driver_data;
1425 
1426     /*
1427      * The broken DSDTs on these devices often also include broken
1428      * _AEI (ACPI Event Interrupt) handlers, disable these.
1429      */
1430     if (dev_info->invalid_aei_gpiochip) {
1431         chip = gpiochip_find(dev_info->invalid_aei_gpiochip,
1432                      gpiochip_find_match_label);
1433         if (!chip) {
1434             pr_err("error cannot find GPIO chip %s\n", dev_info->invalid_aei_gpiochip);
1435             return -ENODEV;
1436         }
1437         acpi_gpiochip_free_interrupts(chip);
1438     }
1439 
1440     /*
1441      * Since this runs from module_init() it cannot use -EPROBE_DEFER,
1442      * instead pre-load any modules which are listed as requirements.
1443      */
1444     for (i = 0; dev_info->modules && dev_info->modules[i]; i++)
1445         request_module(dev_info->modules[i]);
1446 
1447     bat_swnode = dev_info->bat_swnode;
1448     if (bat_swnode) {
1449         ret = software_node_register(bat_swnode);
1450         if (ret)
1451             return ret;
1452     }
1453 
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]);
1457 
1458     if (dev_info->init) {
1459         ret = dev_info->init();
1460         if (ret < 0) {
1461             x86_android_tablet_cleanup();
1462             return ret;
1463         }
1464         exit_handler = dev_info->exit;
1465     }
1466 
1467     i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL);
1468     if (!i2c_clients) {
1469         x86_android_tablet_cleanup();
1470         return -ENOMEM;
1471     }
1472 
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);
1476         if (ret < 0) {
1477             x86_android_tablet_cleanup();
1478             return ret;
1479         }
1480     }
1481 
1482     pdevs = kcalloc(dev_info->pdev_count, sizeof(*pdevs), GFP_KERNEL);
1483     if (!pdevs) {
1484         x86_android_tablet_cleanup();
1485         return -ENOMEM;
1486     }
1487 
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]);
1494         }
1495     }
1496 
1497     serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL);
1498     if (!serdevs) {
1499         x86_android_tablet_cleanup();
1500         return -ENOMEM;
1501     }
1502 
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);
1506         if (ret < 0) {
1507             x86_android_tablet_cleanup();
1508             return ret;
1509         }
1510     }
1511 
1512     return 0;
1513 }
1514 
1515 module_init(x86_android_tablet_init);
1516 module_exit(x86_android_tablet_cleanup);
1517 
1518 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
1519 MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver");
1520 MODULE_LICENSE("GPL");