Merge tag 'x86_vmware_for_v6.0_rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / platform / x86 / x86-android-tablets.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
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
6  * in their DSDT.
7  *
8  * Copyright (C) 2021 Hans de Goede <hdegoede@redhat.com>
9  */
10
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12
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"
39
40 /*
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).
43  */
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,
49 };
50
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;
55         int index;
56         int trigger;  /* ACPI_EDGE_SENSITIVE / ACPI_LEVEL_SENSITIVE */
57         int polarity; /* ACPI_ACTIVE_HIGH / ACPI_ACTIVE_LOW / ACPI_ACTIVE_BOTH */
58 };
59
60 static int gpiochip_find_match_label(struct gpio_chip *gc, void *data)
61 {
62         return gc->label && !strcmp(gc->label, data);
63 }
64
65 static int x86_android_tablet_get_gpiod(char *label, int pin, struct gpio_desc **desc)
66 {
67         struct gpio_desc *gpiod;
68         struct gpio_chip *chip;
69
70         chip = gpiochip_find(label, gpiochip_find_match_label);
71         if (!chip) {
72                 pr_err("error cannot find GPIO chip %s\n", label);
73                 return -ENODEV;
74         }
75
76         gpiod = gpiochip_get_desc(chip, pin);
77         if (IS_ERR(gpiod)) {
78                 pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), label, pin);
79                 return PTR_ERR(gpiod);
80         }
81
82         *desc = gpiod;
83         return 0;
84 }
85
86 static int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data)
87 {
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;
93         acpi_handle handle;
94         acpi_status status;
95         int irq, ret;
96
97         switch (data->type) {
98         case X86_ACPI_IRQ_TYPE_APIC:
99                 /*
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.
103                  */
104                 acpi_unregister_gsi(data->index);
105                 irq = acpi_register_gsi(NULL, data->index, data->trigger, data->polarity);
106                 if (irq < 0)
107                         pr_err("error %d getting APIC IRQ %d\n", irq, data->index);
108
109                 return irq;
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);
113                 if (ret)
114                         return ret;
115
116                 irq = gpiod_to_irq(gpiod);
117                 if (irq < 0) {
118                         pr_err("error %d getting IRQ %s %d\n", irq, data->chip, data->index);
119                         return irq;
120                 }
121
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);
125
126                 return irq;
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);
131                         return -ENODEV;
132                 }
133
134                 adev = acpi_fetch_acpi_dev(handle);
135                 if (!adev) {
136                         pr_err("error could not get %s adev\n", data->chip);
137                         return -ENODEV;
138                 }
139
140                 fwspec.fwnode = acpi_fwnode_handle(adev);
141                 domain = irq_find_matching_fwspec(&fwspec, data->domain);
142                 if (!domain) {
143                         pr_err("error could not find IRQ domain for %s\n", data->chip);
144                         return -ENODEV;
145                 }
146
147                 return irq_create_mapping(domain, data->index);
148         default:
149                 return 0;
150         }
151 }
152
153 struct x86_i2c_client_info {
154         struct i2c_board_info board_info;
155         char *adapter_path;
156         struct x86_acpi_irq_data irq_data;
157 };
158
159 struct x86_serdev_info {
160         const char *ctrl_hid;
161         const char *ctrl_uid;
162         const char *ctrl_devname;
163         /*
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.
168          */
169         const char *serdev_hid;
170 };
171
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;
181         int pdev_count;
182         int serdev_count;
183         int (*init)(void);
184         void (*exit)(void);
185 };
186
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" };
191
192 static const struct property_entry fg_bq24190_supply_props[] = {
193         PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy),
194         { }
195 };
196
197 static const struct software_node fg_bq24190_supply_node = {
198         .properties = fg_bq24190_supply_props,
199 };
200
201 static const struct property_entry fg_bq25890_supply_props[] = {
202         PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_psy),
203         { }
204 };
205
206 static const struct software_node fg_bq25890_supply_node = {
207         .properties = fg_bq25890_supply_props,
208 };
209
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),
219         { }
220 };
221
222 static const struct software_node generic_lipo_hv_4v35_battery_node = {
223         .properties = generic_lipo_hv_4v35_battery_props,
224 };
225
226 /* For enabling the bq24190 5V boost based on id-pin */
227 static struct regulator_consumer_supply intel_int3496_consumer = {
228         .supply = "vbus",
229         .dev_name = "intel-int3496",
230 };
231
232 static const struct regulator_init_data bq24190_vbus_init_data = {
233         .constraints = {
234                 .name = "bq24190_vbus",
235                 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
236         },
237         .consumer_supplies = &intel_int3496_consumer,
238         .num_consumer_supplies = 1,
239 };
240
241 static struct bq24190_platform_data bq24190_pdata = {
242         .regulator_init_data = &bq24190_vbus_init_data,
243 };
244
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 */
248         NULL
249 };
250
251 /* Generic pdevs array and gpio-lookups for micro USB ID pin handling */
252 static const struct platform_device_info int3496_pdevs[] __initconst = {
253         {
254                 /* For micro USB ID pin handling */
255                 .name = "intel-int3496",
256                 .id = PLATFORM_DEVID_NONE,
257         },
258 };
259
260 static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = {
261         .dev_id = "intel-int3496",
262         .table = {
263                 GPIO_LOOKUP("INT33FC:02", 22, "id", GPIO_ACTIVE_HIGH),
264                 { }
265         },
266 };
267
268 /* Asus ME176C and TF103C tablets shared data */
269 static struct gpio_keys_button asus_me176c_tf103c_lid = {
270         .code = SW_LID,
271         /* .gpio gets filled in by asus_me176c_tf103c_init() */
272         .active_low = true,
273         .desc = "lid_sw",
274         .type = EV_SW,
275         .wakeup = true,
276         .debounce_interval = 50,
277 };
278
279 static const struct gpio_keys_platform_data asus_me176c_tf103c_lid_pdata __initconst = {
280         .buttons = &asus_me176c_tf103c_lid,
281         .nbuttons = 1,
282         .name = "lid_sw",
283 };
284
285 static const struct platform_device_info asus_me176c_tf103c_pdevs[] __initconst = {
286         {
287                 .name = "gpio-keys",
288                 .id = PLATFORM_DEVID_AUTO,
289                 .data = &asus_me176c_tf103c_lid_pdata,
290                 .size_data = sizeof(asus_me176c_tf103c_lid_pdata),
291         },
292         {
293                 /* For micro USB ID pin handling */
294                 .name = "intel-int3496",
295                 .id = PLATFORM_DEVID_NONE,
296         },
297 };
298
299 static int __init asus_me176c_tf103c_init(void)
300 {
301         struct gpio_desc *gpiod;
302         int ret;
303
304         ret = x86_android_tablet_get_gpiod("INT33FC:02", 12, &gpiod);
305         if (ret < 0)
306                 return ret;
307         asus_me176c_tf103c_lid.gpio = desc_to_gpio(gpiod);
308
309         return 0;
310 }
311
312
313 /* Asus ME176C tablets have an Android factory img with everything hardcoded */
314 static const char * const asus_me176c_accel_mount_matrix[] = {
315         "-1", "0", "0",
316         "0", "1", "0",
317         "0", "0", "1"
318 };
319
320 static const struct property_entry asus_me176c_accel_props[] = {
321         PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_me176c_accel_mount_matrix),
322         { }
323 };
324
325 static const struct software_node asus_me176c_accel_node = {
326         .properties = asus_me176c_accel_props,
327 };
328
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"),
335         { }
336 };
337
338 static const struct software_node asus_me176c_bq24190_node = {
339         .properties = asus_me176c_bq24190_props,
340 };
341
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),
346         { }
347 };
348
349 static const struct software_node asus_me176c_ug3105_node = {
350         .properties = asus_me176c_ug3105_props,
351 };
352
353 static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = {
354         {
355                 /* bq24297 battery charger */
356                 .board_info = {
357                         .type = "bq24190",
358                         .addr = 0x6b,
359                         .dev_name = "bq24297",
360                         .swnode = &asus_me176c_bq24190_node,
361                         .platform_data = &bq24190_pdata,
362                 },
363                 .adapter_path = "\\_SB_.I2C1",
364                 .irq_data = {
365                         .type = X86_ACPI_IRQ_TYPE_PMIC,
366                         .chip = "\\_SB_.I2C7.PMIC",
367                         .domain = DOMAIN_BUS_WAKEUP,
368                         .index = 0,
369                 },
370         }, {
371                 /* ug3105 battery monitor */
372                 .board_info = {
373                         .type = "ug3105",
374                         .addr = 0x70,
375                         .dev_name = "ug3105",
376                         .swnode = &asus_me176c_ug3105_node,
377                 },
378                 .adapter_path = "\\_SB_.I2C1",
379         }, {
380                 /* ak09911 compass */
381                 .board_info = {
382                         .type = "ak09911",
383                         .addr = 0x0c,
384                         .dev_name = "ak09911",
385                 },
386                 .adapter_path = "\\_SB_.I2C5",
387         }, {
388                 /* kxtj21009 accel */
389                 .board_info = {
390                         .type = "kxtj21009",
391                         .addr = 0x0f,
392                         .dev_name = "kxtj21009",
393                         .swnode = &asus_me176c_accel_node,
394                 },
395                 .adapter_path = "\\_SB_.I2C5",
396                 .irq_data = {
397                         .type = X86_ACPI_IRQ_TYPE_APIC,
398                         .index = 0x44,
399                         .trigger = ACPI_EDGE_SENSITIVE,
400                         .polarity = ACPI_ACTIVE_LOW,
401                 },
402         }, {
403                 /* goodix touchscreen */
404                 .board_info = {
405                         .type = "GDIX1001:00",
406                         .addr = 0x14,
407                         .dev_name = "goodix_ts",
408                 },
409                 .adapter_path = "\\_SB_.I2C6",
410                 .irq_data = {
411                         .type = X86_ACPI_IRQ_TYPE_APIC,
412                         .index = 0x45,
413                         .trigger = ACPI_EDGE_SENSITIVE,
414                         .polarity = ACPI_ACTIVE_LOW,
415                 },
416         },
417 };
418
419 static const struct x86_serdev_info asus_me176c_serdevs[] __initconst = {
420         {
421                 .ctrl_hid = "80860F0A",
422                 .ctrl_uid = "2",
423                 .ctrl_devname = "serial0",
424                 .serdev_hid = "BCM2E3A",
425         },
426 };
427
428 static struct gpiod_lookup_table asus_me176c_goodix_gpios = {
429         .dev_id = "i2c-goodix_ts",
430         .table = {
431                 GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_HIGH),
432                 GPIO_LOOKUP("INT33FC:02", 28, "irq", GPIO_ACTIVE_HIGH),
433                 { }
434         },
435 };
436
437 static struct gpiod_lookup_table * const asus_me176c_gpios[] = {
438         &int3496_gpo2_pin22_gpios,
439         &asus_me176c_goodix_gpios,
440         NULL
441 };
442
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,
455 };
456
457 /* Asus TF103C tablets have an Android factory img with everything hardcoded */
458 static const char * const asus_tf103c_accel_mount_matrix[] = {
459         "0", "-1", "0",
460         "-1", "0", "0",
461         "0", "0", "1"
462 };
463
464 static const struct property_entry asus_tf103c_accel_props[] = {
465         PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_tf103c_accel_mount_matrix),
466         { }
467 };
468
469 static const struct software_node asus_tf103c_accel_node = {
470         .properties = asus_tf103c_accel_props,
471 };
472
473 static const struct property_entry asus_tf103c_touchscreen_props[] = {
474         PROPERTY_ENTRY_STRING("compatible", "atmel,atmel_mxt_ts"),
475         { }
476 };
477
478 static const struct software_node asus_tf103c_touchscreen_node = {
479         .properties = asus_tf103c_touchscreen_props,
480 };
481
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),
490         { }
491 };
492
493 static const struct software_node asus_tf103c_battery_node = {
494         .properties = asus_tf103c_battery_props,
495 };
496
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"),
503         { }
504 };
505
506 static const struct software_node asus_tf103c_bq24190_node = {
507         .properties = asus_tf103c_bq24190_props,
508 };
509
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),
514         { }
515 };
516
517 static const struct software_node asus_tf103c_ug3105_node = {
518         .properties = asus_tf103c_ug3105_props,
519 };
520
521 static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = {
522         {
523                 /* bq24297 battery charger */
524                 .board_info = {
525                         .type = "bq24190",
526                         .addr = 0x6b,
527                         .dev_name = "bq24297",
528                         .swnode = &asus_tf103c_bq24190_node,
529                         .platform_data = &bq24190_pdata,
530                 },
531                 .adapter_path = "\\_SB_.I2C1",
532                 .irq_data = {
533                         .type = X86_ACPI_IRQ_TYPE_PMIC,
534                         .chip = "\\_SB_.I2C7.PMIC",
535                         .domain = DOMAIN_BUS_WAKEUP,
536                         .index = 0,
537                 },
538         }, {
539                 /* ug3105 battery monitor */
540                 .board_info = {
541                         .type = "ug3105",
542                         .addr = 0x70,
543                         .dev_name = "ug3105",
544                         .swnode = &asus_tf103c_ug3105_node,
545                 },
546                 .adapter_path = "\\_SB_.I2C1",
547         }, {
548                 /* ak09911 compass */
549                 .board_info = {
550                         .type = "ak09911",
551                         .addr = 0x0c,
552                         .dev_name = "ak09911",
553                 },
554                 .adapter_path = "\\_SB_.I2C5",
555         }, {
556                 /* kxtj21009 accel */
557                 .board_info = {
558                         .type = "kxtj21009",
559                         .addr = 0x0f,
560                         .dev_name = "kxtj21009",
561                         .swnode = &asus_tf103c_accel_node,
562                 },
563                 .adapter_path = "\\_SB_.I2C5",
564         }, {
565                 /* atmel touchscreen */
566                 .board_info = {
567                         .type = "atmel_mxt_ts",
568                         .addr = 0x4a,
569                         .dev_name = "atmel_mxt_ts",
570                         .swnode = &asus_tf103c_touchscreen_node,
571                 },
572                 .adapter_path = "\\_SB_.I2C6",
573                 .irq_data = {
574                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
575                         .chip = "INT33FC:02",
576                         .index = 28,
577                         .trigger = ACPI_EDGE_SENSITIVE,
578                         .polarity = ACPI_ACTIVE_LOW,
579                 },
580         },
581 };
582
583 static struct gpiod_lookup_table * const asus_tf103c_gpios[] = {
584         &int3496_gpo2_pin22_gpios,
585         NULL
586 };
587
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,
598 };
599
600 /*
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.
604  */
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"),
611         { }
612 };
613
614 static const struct software_node chuwi_hi8_gsl1680_node = {
615         .properties = chuwi_hi8_gsl1680_props,
616 };
617
618 static const char * const chuwi_hi8_mount_matrix[] = {
619         "1", "0", "0",
620         "0", "-1", "0",
621         "0", "0", "1"
622 };
623
624 static const struct property_entry chuwi_hi8_bma250e_props[] = {
625         PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", chuwi_hi8_mount_matrix),
626         { }
627 };
628
629 static const struct software_node chuwi_hi8_bma250e_node = {
630         .properties = chuwi_hi8_bma250e_props,
631 };
632
633 static const struct x86_i2c_client_info chuwi_hi8_i2c_clients[] __initconst = {
634         {
635                 /* Silead touchscreen */
636                 .board_info = {
637                         .type = "gsl1680",
638                         .addr = 0x40,
639                         .swnode = &chuwi_hi8_gsl1680_node,
640                 },
641                 .adapter_path = "\\_SB_.I2C4",
642                 .irq_data = {
643                         .type = X86_ACPI_IRQ_TYPE_APIC,
644                         .index = 0x44,
645                         .trigger = ACPI_EDGE_SENSITIVE,
646                         .polarity = ACPI_ACTIVE_HIGH,
647                 },
648         }, {
649                 /* BMA250E accelerometer */
650                 .board_info = {
651                         .type = "bma250e",
652                         .addr = 0x18,
653                         .swnode = &chuwi_hi8_bma250e_node,
654                 },
655                 .adapter_path = "\\_SB_.I2C3",
656                 .irq_data = {
657                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
658                         .chip = "INT33FC:02",
659                         .index = 23,
660                         .trigger = ACPI_LEVEL_SENSITIVE,
661                         .polarity = ACPI_ACTIVE_HIGH,
662                 },
663         },
664 };
665
666 static const struct x86_dev_info chuwi_hi8_info __initconst = {
667         .i2c_client_info = chuwi_hi8_i2c_clients,
668         .i2c_client_count = ARRAY_SIZE(chuwi_hi8_i2c_clients),
669 };
670
671 #define CZC_EC_EXTRA_PORT       0x68
672 #define CZC_EC_ANDROID_KEYS     0x63
673
674 static int __init czc_p10t_init(void)
675 {
676         /*
677          * The device boots up in "Windows 7" mode, when the home button sends a
678          * Windows specific key sequence (Left Meta + D) and the second button
679          * sends an unknown one while also toggling the Radio Kill Switch.
680          * This is a surprising behavior when the second button is labeled "Back".
681          *
682          * The vendor-supplied Android-x86 build switches the device to a "Android"
683          * mode by writing value 0x63 to the I/O port 0x68. This just seems to just
684          * set bit 6 on address 0x96 in the EC region; switching the bit directly
685          * seems to achieve the same result. It uses a "p10t_switcher" to do the
686          * job. It doesn't seem to be able to do anything else, and no other use
687          * of the port 0x68 is known.
688          *
689          * In the Android mode, the home button sends just a single scancode,
690          * which can be handled in Linux userspace more reasonably and the back
691          * button only sends a scancode without toggling the kill switch.
692          * The scancode can then be mapped either to Back or RF Kill functionality
693          * in userspace, depending on how the button is labeled on that particular
694          * model.
695          */
696         outb(CZC_EC_ANDROID_KEYS, CZC_EC_EXTRA_PORT);
697         return 0;
698 }
699
700 static const struct x86_dev_info czc_p10t __initconst = {
701         .init = czc_p10t_init,
702 };
703
704 /* Lenovo Yoga Book X90F / X91F / X91L need manual instantiation of the fg client */
705 static const struct x86_i2c_client_info lenovo_yogabook_x9x_i2c_clients[] __initconst = {
706         {
707                 /* BQ27542 fuel-gauge */
708                 .board_info = {
709                         .type = "bq27542",
710                         .addr = 0x55,
711                         .dev_name = "bq27542",
712                         .swnode = &fg_bq25890_supply_node,
713                 },
714                 .adapter_path = "\\_SB_.PCI0.I2C1",
715         },
716 };
717
718 static const struct x86_dev_info lenovo_yogabook_x9x_info __initconst = {
719         .i2c_client_info = lenovo_yogabook_x9x_i2c_clients,
720         .i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x9x_i2c_clients),
721 };
722
723 /* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */
724 static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
725         PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy),
726         PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
727         PROPERTY_ENTRY_BOOL("omit-battery-class"),
728         PROPERTY_ENTRY_BOOL("disable-reset"),
729         { }
730 };
731
732 static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
733         .properties = lenovo_yoga_tab2_830_1050_bq24190_props,
734 };
735
736 /* This gets filled by lenovo_yoga_tab2_830_1050_init() */
737 static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
738
739 static struct lp855x_platform_data lenovo_yoga_tab2_830_1050_lp8557_pdata = {
740         .device_control = 0x86,
741         .initial_brightness = 128,
742 };
743
744 static const struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initconst = {
745         {
746                 /* bq24292i battery charger */
747                 .board_info = {
748                         .type = "bq24190",
749                         .addr = 0x6b,
750                         .dev_name = "bq24292i",
751                         .swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
752                         .platform_data = &bq24190_pdata,
753                 },
754                 .adapter_path = "\\_SB_.I2C1",
755                 .irq_data = {
756                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
757                         .chip = "INT33FC:02",
758                         .index = 2,
759                         .trigger = ACPI_EDGE_SENSITIVE,
760                         .polarity = ACPI_ACTIVE_HIGH,
761                 },
762         }, {
763                 /* BQ27541 fuel-gauge */
764                 .board_info = {
765                         .type = "bq27541",
766                         .addr = 0x55,
767                         .dev_name = "bq27541",
768                         .swnode = &fg_bq24190_supply_node,
769                 },
770                 .adapter_path = "\\_SB_.I2C1",
771         }, {
772                 /* Synaptics RMI touchscreen */
773                 .board_info = {
774                         .type = "rmi4_i2c",
775                         .addr = 0x38,
776                         .dev_name = "rmi4_i2c",
777                         .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
778                 },
779                 .adapter_path = "\\_SB_.I2C6",
780                 .irq_data = {
781                         .type = X86_ACPI_IRQ_TYPE_APIC,
782                         .index = 0x45,
783                         .trigger = ACPI_EDGE_SENSITIVE,
784                         .polarity = ACPI_ACTIVE_HIGH,
785                 },
786         }, {
787                 /* LP8557 Backlight controller */
788                 .board_info = {
789                         .type = "lp8557",
790                         .addr = 0x2c,
791                         .dev_name = "lp8557",
792                         .platform_data = &lenovo_yoga_tab2_830_1050_lp8557_pdata,
793                 },
794                 .adapter_path = "\\_SB_.I2C3",
795         },
796 };
797
798 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
799         .dev_id = "intel-int3496",
800         .table = {
801                 GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
802                 GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
803                 { }
804         },
805 };
806
807 #define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
808
809 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = {
810         .dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME,
811         .table = {
812                 GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH),
813                 GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH),
814                 GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
815                 GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW),
816                 { }
817         },
818 };
819
820 static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = {
821         &lenovo_yoga_tab2_830_1050_int3496_gpios,
822         &lenovo_yoga_tab2_830_1050_codec_gpios,
823         NULL
824 };
825
826 static int __init lenovo_yoga_tab2_830_1050_init(void);
827 static void lenovo_yoga_tab2_830_1050_exit(void);
828
829 static struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initdata = {
830         .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
831         /* i2c_client_count gets set by lenovo_yoga_tab2_830_1050_init() */
832         .pdev_info = int3496_pdevs,
833         .pdev_count = ARRAY_SIZE(int3496_pdevs),
834         .gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios,
835         .bat_swnode = &generic_lipo_hv_4v35_battery_node,
836         .modules = bq24190_modules,
837         .invalid_aei_gpiochip = "INT33FC:02",
838         .init = lenovo_yoga_tab2_830_1050_init,
839         .exit = lenovo_yoga_tab2_830_1050_exit,
840 };
841
842 /*
843  * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
844  * mainboard, but they need some different treatment related to the display:
845  * 1. The 830 uses a portrait LCD panel with a landscape touchscreen, requiring
846  *    the touchscreen driver to adjust the touch-coords to match the LCD.
847  * 2. Both use an TI LP8557 LED backlight controller. On the 1050 the LP8557's
848  *    PWM input is connected to the PMIC's PWM output and everything works fine
849  *    with the defaults programmed into the LP8557 by the BIOS.
850  *    But on the 830 the LP8557's PWM input is connected to a PWM output coming
851  *    from the LCD panel's controller. The Android code has a hack in the i915
852  *    driver to write the non-standard DSI reg 0x9f with the desired backlight
853  *    level to set the duty-cycle of the LCD's PWM output.
854  *
855  *    To avoid having to have a similar hack in the mainline kernel the LP8557
856  *    entry in lenovo_yoga_tab2_830_1050_i2c_clients instead just programs the
857  *    LP8557 to directly set the level, ignoring the PWM input. This means that
858  *    the LP8557 i2c_client should only be instantiated on the 830.
859  */
860 static int __init lenovo_yoga_tab2_830_1050_init_display(void)
861 {
862         struct gpio_desc *gpiod;
863         int ret;
864
865         /* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
866         ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, &gpiod);
867         if (ret)
868                 return ret;
869
870         ret = gpiod_get_value_cansleep(gpiod);
871         if (ret) {
872                 pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
873                 lenovo_yoga_tab2_830_1050_info.i2c_client_count =
874                         ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients) - 1;
875         } else {
876                 pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
877                 lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
878                 lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
879                 lenovo_yoga_tab2_830_1050_info.i2c_client_count =
880                         ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients);
881         }
882
883         return 0;
884 }
885
886 /* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
887 static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
888         PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
889                           "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
890
891 static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
892 static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
893
894 static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
895 {
896         struct device *codec_dev;
897         struct pinctrl *pinctrl;
898         int ret;
899
900         codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
901                                             LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
902         if (!codec_dev) {
903                 pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
904                 return -ENODEV;
905         }
906
907         ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
908         if (ret)
909                 goto err_put_device;
910
911         pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
912         if (IS_ERR(pinctrl)) {
913                 ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
914                 goto err_unregister_mappings;
915         }
916
917         /* We're done with the codec_dev now */
918         put_device(codec_dev);
919
920         lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
921         return 0;
922
923 err_unregister_mappings:
924         pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
925 err_put_device:
926         put_device(codec_dev);
927         return ret;
928 }
929
930 /*
931  * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off
932  * gets used as pm_power_off handler. This causes "poweroff" on these tablets
933  * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice*
934  * followed by a normal 3 second press to recover. Avoid this by doing an EFI
935  * poweroff instead.
936  */
937 static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
938 {
939         efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
940
941         return NOTIFY_DONE;
942 }
943
944 static int __init lenovo_yoga_tab2_830_1050_init(void)
945 {
946         int ret;
947
948         ret = lenovo_yoga_tab2_830_1050_init_display();
949         if (ret)
950                 return ret;
951
952         ret = lenovo_yoga_tab2_830_1050_init_codec();
953         if (ret)
954                 return ret;
955
956         /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */
957         lenovo_yoga_tab2_830_1050_sys_off_handler =
958                 register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
959                                          lenovo_yoga_tab2_830_1050_power_off, NULL);
960         if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
961                 return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
962
963         return 0;
964 }
965
966 static void lenovo_yoga_tab2_830_1050_exit(void)
967 {
968         unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
969
970         if (lenovo_yoga_tab2_830_1050_codec_pinctrl) {
971                 pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
972                 pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
973         }
974 }
975
976 /* Nextbook Ares 8 tablets have an Android factory img with everything hardcoded */
977 static const char * const nextbook_ares8_accel_mount_matrix[] = {
978         "0", "-1", "0",
979         "-1", "0", "0",
980         "0", "0", "1"
981 };
982
983 static const struct property_entry nextbook_ares8_accel_props[] = {
984         PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", nextbook_ares8_accel_mount_matrix),
985         { }
986 };
987
988 static const struct software_node nextbook_ares8_accel_node = {
989         .properties = nextbook_ares8_accel_props,
990 };
991
992 static const struct property_entry nextbook_ares8_touchscreen_props[] = {
993         PROPERTY_ENTRY_U32("touchscreen-size-x", 800),
994         PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
995         { }
996 };
997
998 static const struct software_node nextbook_ares8_touchscreen_node = {
999         .properties = nextbook_ares8_touchscreen_props,
1000 };
1001
1002 static const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst = {
1003         {
1004                 /* Freescale MMA8653FC accel */
1005                 .board_info = {
1006                         .type = "mma8653",
1007                         .addr = 0x1d,
1008                         .dev_name = "mma8653",
1009                         .swnode = &nextbook_ares8_accel_node,
1010                 },
1011                 .adapter_path = "\\_SB_.I2C3",
1012         }, {
1013                 /* FT5416DQ9 touchscreen controller */
1014                 .board_info = {
1015                         .type = "edt-ft5x06",
1016                         .addr = 0x38,
1017                         .dev_name = "ft5416",
1018                         .swnode = &nextbook_ares8_touchscreen_node,
1019                 },
1020                 .adapter_path = "\\_SB_.I2C4",
1021                 .irq_data = {
1022                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
1023                         .chip = "INT33FC:02",
1024                         .index = 3,
1025                         .trigger = ACPI_EDGE_SENSITIVE,
1026                         .polarity = ACPI_ACTIVE_LOW,
1027                 },
1028         },
1029 };
1030
1031 static struct gpiod_lookup_table nextbook_ares8_int3496_gpios = {
1032         .dev_id = "intel-int3496",
1033         .table = {
1034                 GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_HIGH),
1035                 GPIO_LOOKUP("INT33FC:02", 18, "id", GPIO_ACTIVE_HIGH),
1036                 { }
1037         },
1038 };
1039
1040 static struct gpiod_lookup_table * const nextbook_ares8_gpios[] = {
1041         &nextbook_ares8_int3496_gpios,
1042         NULL
1043 };
1044
1045 static const struct x86_dev_info nextbook_ares8_info __initconst = {
1046         .i2c_client_info = nextbook_ares8_i2c_clients,
1047         .i2c_client_count = ARRAY_SIZE(nextbook_ares8_i2c_clients),
1048         .pdev_info = int3496_pdevs,
1049         .pdev_count = ARRAY_SIZE(int3496_pdevs),
1050         .gpiod_lookup_tables = nextbook_ares8_gpios,
1051         .invalid_aei_gpiochip = "INT33FC:02",
1052 };
1053
1054 /*
1055  * Whitelabel (sold as various brands) TM800A550L tablets.
1056  * These tablet's DSDT contains a whole bunch of bogus ACPI I2C devices
1057  * (removed through acpi_quirk_skip_i2c_client_enumeration()) and
1058  * the touchscreen fwnode has the wrong GPIOs.
1059  */
1060 static const char * const whitelabel_tm800a550l_accel_mount_matrix[] = {
1061         "-1", "0", "0",
1062         "0", "1", "0",
1063         "0", "0", "1"
1064 };
1065
1066 static const struct property_entry whitelabel_tm800a550l_accel_props[] = {
1067         PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", whitelabel_tm800a550l_accel_mount_matrix),
1068         { }
1069 };
1070
1071 static const struct software_node whitelabel_tm800a550l_accel_node = {
1072         .properties = whitelabel_tm800a550l_accel_props,
1073 };
1074
1075 static const struct property_entry whitelabel_tm800a550l_goodix_props[] = {
1076         PROPERTY_ENTRY_STRING("firmware-name", "gt912-tm800a550l.fw"),
1077         PROPERTY_ENTRY_STRING("goodix,config-name", "gt912-tm800a550l.cfg"),
1078         PROPERTY_ENTRY_U32("goodix,main-clk", 54),
1079         { }
1080 };
1081
1082 static const struct software_node whitelabel_tm800a550l_goodix_node = {
1083         .properties = whitelabel_tm800a550l_goodix_props,
1084 };
1085
1086 static const struct x86_i2c_client_info whitelabel_tm800a550l_i2c_clients[] __initconst = {
1087         {
1088                 /* goodix touchscreen */
1089                 .board_info = {
1090                         .type = "GDIX1001:00",
1091                         .addr = 0x14,
1092                         .dev_name = "goodix_ts",
1093                         .swnode = &whitelabel_tm800a550l_goodix_node,
1094                 },
1095                 .adapter_path = "\\_SB_.I2C2",
1096                 .irq_data = {
1097                         .type = X86_ACPI_IRQ_TYPE_APIC,
1098                         .index = 0x44,
1099                         .trigger = ACPI_EDGE_SENSITIVE,
1100                         .polarity = ACPI_ACTIVE_HIGH,
1101                 },
1102         }, {
1103                 /* kxcj91008 accel */
1104                 .board_info = {
1105                         .type = "kxcj91008",
1106                         .addr = 0x0f,
1107                         .dev_name = "kxcj91008",
1108                         .swnode = &whitelabel_tm800a550l_accel_node,
1109                 },
1110                 .adapter_path = "\\_SB_.I2C3",
1111         },
1112 };
1113
1114 static struct gpiod_lookup_table whitelabel_tm800a550l_goodix_gpios = {
1115         .dev_id = "i2c-goodix_ts",
1116         .table = {
1117                 GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH),
1118                 GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH),
1119                 { }
1120         },
1121 };
1122
1123 static struct gpiod_lookup_table * const whitelabel_tm800a550l_gpios[] = {
1124         &whitelabel_tm800a550l_goodix_gpios,
1125         NULL
1126 };
1127
1128 static const struct x86_dev_info whitelabel_tm800a550l_info __initconst = {
1129         .i2c_client_info = whitelabel_tm800a550l_i2c_clients,
1130         .i2c_client_count = ARRAY_SIZE(whitelabel_tm800a550l_i2c_clients),
1131         .gpiod_lookup_tables = whitelabel_tm800a550l_gpios,
1132 };
1133
1134 /*
1135  * If the EFI bootloader is not Xiaomi's own signed Android loader, then the
1136  * Xiaomi Mi Pad 2 X86 tablet sets OSID in the DSDT to 1 (Windows), causing
1137  * a bunch of devices to be hidden.
1138  *
1139  * This takes care of instantiating the hidden devices manually.
1140  */
1141 static const struct x86_i2c_client_info xiaomi_mipad2_i2c_clients[] __initconst = {
1142         {
1143                 /* BQ27520 fuel-gauge */
1144                 .board_info = {
1145                         .type = "bq27520",
1146                         .addr = 0x55,
1147                         .dev_name = "bq27520",
1148                         .swnode = &fg_bq25890_supply_node,
1149                 },
1150                 .adapter_path = "\\_SB_.PCI0.I2C1",
1151         }, {
1152                 /* KTD2026 RGB notification LED controller */
1153                 .board_info = {
1154                         .type = "ktd2026",
1155                         .addr = 0x30,
1156                         .dev_name = "ktd2026",
1157                 },
1158                 .adapter_path = "\\_SB_.PCI0.I2C3",
1159         },
1160 };
1161
1162 static const struct x86_dev_info xiaomi_mipad2_info __initconst = {
1163         .i2c_client_info = xiaomi_mipad2_i2c_clients,
1164         .i2c_client_count = ARRAY_SIZE(xiaomi_mipad2_i2c_clients),
1165 };
1166
1167 static const struct dmi_system_id x86_android_tablet_ids[] __initconst = {
1168         {
1169                 /* Asus MeMO Pad 7 ME176C */
1170                 .matches = {
1171                         DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
1172                         DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"),
1173                 },
1174                 .driver_data = (void *)&asus_me176c_info,
1175         },
1176         {
1177                 /* Asus TF103C */
1178                 .matches = {
1179                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
1180                         DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
1181                 },
1182                 .driver_data = (void *)&asus_tf103c_info,
1183         },
1184         {
1185                 /* Chuwi Hi8 (CWI509) */
1186                 .matches = {
1187                         DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
1188                         DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"),
1189                         DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
1190                         DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
1191                 },
1192                 .driver_data = (void *)&chuwi_hi8_info,
1193         },
1194         {
1195                 /* CZC P10T */
1196                 .ident = "CZC ODEON TPC-10 (\"P10T\")",
1197                 .matches = {
1198                         DMI_MATCH(DMI_SYS_VENDOR, "CZC"),
1199                         DMI_MATCH(DMI_PRODUCT_NAME, "ODEON*TPC-10"),
1200                 },
1201                 .driver_data = (void *)&czc_p10t,
1202         },
1203         {
1204                 /* CZC P10T variant */
1205                 .ident = "ViewSonic ViewPad 10",
1206                 .matches = {
1207                         DMI_MATCH(DMI_SYS_VENDOR, "ViewSonic"),
1208                         DMI_MATCH(DMI_PRODUCT_NAME, "VPAD10"),
1209                 },
1210                 .driver_data = (void *)&czc_p10t,
1211         },
1212         {
1213                 /* Lenovo Yoga Book X90F / X91F / X91L */
1214                 .matches = {
1215                         /* Non exact match to match all versions */
1216                         DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
1217                 },
1218                 .driver_data = (void *)&lenovo_yogabook_x9x_info,
1219         },
1220         {
1221                 /*
1222                  * Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10"
1223                  * Lenovo Yoga Tablet 2 use the same mainboard)
1224                  */
1225                 .matches = {
1226                         DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
1227                         DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
1228                         DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
1229                         /* Partial match on beginning of BIOS version */
1230                         DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
1231                 },
1232                 .driver_data = (void *)&lenovo_yoga_tab2_830_1050_info,
1233         },
1234         {
1235                 /* Nextbook Ares 8 */
1236                 .matches = {
1237                         DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
1238                         DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"),
1239                 },
1240                 .driver_data = (void *)&nextbook_ares8_info,
1241         },
1242         {
1243                 /* Whitelabel (sold as various brands) TM800A550L */
1244                 .matches = {
1245                         DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1246                         DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1247                         /* Above strings are too generic, also match on BIOS version */
1248                         DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"),
1249                 },
1250                 .driver_data = (void *)&whitelabel_tm800a550l_info,
1251         },
1252         {
1253                 /* Xiaomi Mi Pad 2 */
1254                 .matches = {
1255                         DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
1256                         DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
1257                 },
1258                 .driver_data = (void *)&xiaomi_mipad2_info,
1259         },
1260         { }
1261 };
1262 MODULE_DEVICE_TABLE(dmi, x86_android_tablet_ids);
1263
1264 static int i2c_client_count;
1265 static int pdev_count;
1266 static int serdev_count;
1267 static struct i2c_client **i2c_clients;
1268 static struct platform_device **pdevs;
1269 static struct serdev_device **serdevs;
1270 static struct gpiod_lookup_table * const *gpiod_lookup_tables;
1271 static const struct software_node *bat_swnode;
1272 static void (*exit_handler)(void);
1273
1274 static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info,
1275                                              int idx)
1276 {
1277         const struct x86_i2c_client_info *client_info = &dev_info->i2c_client_info[idx];
1278         struct i2c_board_info board_info = client_info->board_info;
1279         struct i2c_adapter *adap;
1280         acpi_handle handle;
1281         acpi_status status;
1282
1283         board_info.irq = x86_acpi_irq_helper_get(&client_info->irq_data);
1284         if (board_info.irq < 0)
1285                 return board_info.irq;
1286
1287         status = acpi_get_handle(NULL, client_info->adapter_path, &handle);
1288         if (ACPI_FAILURE(status)) {
1289                 pr_err("Error could not get %s handle\n", client_info->adapter_path);
1290                 return -ENODEV;
1291         }
1292
1293         adap = i2c_acpi_find_adapter_by_handle(handle);
1294         if (!adap) {
1295                 pr_err("error could not get %s adapter\n", client_info->adapter_path);
1296                 return -ENODEV;
1297         }
1298
1299         i2c_clients[idx] = i2c_new_client_device(adap, &board_info);
1300         put_device(&adap->dev);
1301         if (IS_ERR(i2c_clients[idx]))
1302                 return dev_err_probe(&adap->dev, PTR_ERR(i2c_clients[idx]),
1303                                       "creating I2C-client %d\n", idx);
1304
1305         return 0;
1306 }
1307
1308 static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx)
1309 {
1310         struct acpi_device *ctrl_adev, *serdev_adev;
1311         struct serdev_device *serdev;
1312         struct device *ctrl_dev;
1313         int ret = -ENODEV;
1314
1315         ctrl_adev = acpi_dev_get_first_match_dev(info->ctrl_hid, info->ctrl_uid, -1);
1316         if (!ctrl_adev) {
1317                 pr_err("error could not get %s/%s ctrl adev\n",
1318                        info->ctrl_hid, info->ctrl_uid);
1319                 return -ENODEV;
1320         }
1321
1322         serdev_adev = acpi_dev_get_first_match_dev(info->serdev_hid, NULL, -1);
1323         if (!serdev_adev) {
1324                 pr_err("error could not get %s serdev adev\n", info->serdev_hid);
1325                 goto put_ctrl_adev;
1326         }
1327
1328         /* get_first_physical_node() returns a weak ref, no need to put() it */
1329         ctrl_dev = acpi_get_first_physical_node(ctrl_adev);
1330         if (!ctrl_dev)  {
1331                 pr_err("error could not get %s/%s ctrl physical dev\n",
1332                        info->ctrl_hid, info->ctrl_uid);
1333                 goto put_serdev_adev;
1334         }
1335
1336         /* ctrl_dev now points to the controller's parent, get the controller */
1337         ctrl_dev = device_find_child_by_name(ctrl_dev, info->ctrl_devname);
1338         if (!ctrl_dev) {
1339                 pr_err("error could not get %s/%s %s ctrl dev\n",
1340                        info->ctrl_hid, info->ctrl_uid, info->ctrl_devname);
1341                 goto put_serdev_adev;
1342         }
1343
1344         serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev));
1345         if (!serdev) {
1346                 ret = -ENOMEM;
1347                 goto put_serdev_adev;
1348         }
1349
1350         ACPI_COMPANION_SET(&serdev->dev, serdev_adev);
1351         acpi_device_set_enumerated(serdev_adev);
1352
1353         ret = serdev_device_add(serdev);
1354         if (ret) {
1355                 dev_err(&serdev->dev, "error %d adding serdev\n", ret);
1356                 serdev_device_put(serdev);
1357                 goto put_serdev_adev;
1358         }
1359
1360         serdevs[idx] = serdev;
1361
1362 put_serdev_adev:
1363         acpi_dev_put(serdev_adev);
1364 put_ctrl_adev:
1365         acpi_dev_put(ctrl_adev);
1366         return ret;
1367 }
1368
1369 static void x86_android_tablet_cleanup(void)
1370 {
1371         int i;
1372
1373         for (i = 0; i < serdev_count; i++) {
1374                 if (serdevs[i])
1375                         serdev_device_remove(serdevs[i]);
1376         }
1377
1378         kfree(serdevs);
1379
1380         for (i = 0; i < pdev_count; i++)
1381                 platform_device_unregister(pdevs[i]);
1382
1383         kfree(pdevs);
1384
1385         for (i = 0; i < i2c_client_count; i++)
1386                 i2c_unregister_device(i2c_clients[i]);
1387
1388         kfree(i2c_clients);
1389
1390         if (exit_handler)
1391                 exit_handler();
1392
1393         for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++)
1394                 gpiod_remove_lookup_table(gpiod_lookup_tables[i]);
1395
1396         software_node_unregister(bat_swnode);
1397 }
1398
1399 static __init int x86_android_tablet_init(void)
1400 {
1401         const struct x86_dev_info *dev_info;
1402         const struct dmi_system_id *id;
1403         struct gpio_chip *chip;
1404         int i, ret = 0;
1405
1406         id = dmi_first_match(x86_android_tablet_ids);
1407         if (!id)
1408                 return -ENODEV;
1409
1410         dev_info = id->driver_data;
1411
1412         /*
1413          * The broken DSDTs on these devices often also include broken
1414          * _AEI (ACPI Event Interrupt) handlers, disable these.
1415          */
1416         if (dev_info->invalid_aei_gpiochip) {
1417                 chip = gpiochip_find(dev_info->invalid_aei_gpiochip,
1418                                      gpiochip_find_match_label);
1419                 if (!chip) {
1420                         pr_err("error cannot find GPIO chip %s\n", dev_info->invalid_aei_gpiochip);
1421                         return -ENODEV;
1422                 }
1423                 acpi_gpiochip_free_interrupts(chip);
1424         }
1425
1426         /*
1427          * Since this runs from module_init() it cannot use -EPROBE_DEFER,
1428          * instead pre-load any modules which are listed as requirements.
1429          */
1430         for (i = 0; dev_info->modules && dev_info->modules[i]; i++)
1431                 request_module(dev_info->modules[i]);
1432
1433         bat_swnode = dev_info->bat_swnode;
1434         if (bat_swnode) {
1435                 ret = software_node_register(bat_swnode);
1436                 if (ret)
1437                         return ret;
1438         }
1439
1440         gpiod_lookup_tables = dev_info->gpiod_lookup_tables;
1441         for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++)
1442                 gpiod_add_lookup_table(gpiod_lookup_tables[i]);
1443
1444         if (dev_info->init) {
1445                 ret = dev_info->init();
1446                 if (ret < 0) {
1447                         x86_android_tablet_cleanup();
1448                         return ret;
1449                 }
1450                 exit_handler = dev_info->exit;
1451         }
1452
1453         i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL);
1454         if (!i2c_clients) {
1455                 x86_android_tablet_cleanup();
1456                 return -ENOMEM;
1457         }
1458
1459         i2c_client_count = dev_info->i2c_client_count;
1460         for (i = 0; i < i2c_client_count; i++) {
1461                 ret = x86_instantiate_i2c_client(dev_info, i);
1462                 if (ret < 0) {
1463                         x86_android_tablet_cleanup();
1464                         return ret;
1465                 }
1466         }
1467
1468         pdevs = kcalloc(dev_info->pdev_count, sizeof(*pdevs), GFP_KERNEL);
1469         if (!pdevs) {
1470                 x86_android_tablet_cleanup();
1471                 return -ENOMEM;
1472         }
1473
1474         pdev_count = dev_info->pdev_count;
1475         for (i = 0; i < pdev_count; i++) {
1476                 pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]);
1477                 if (IS_ERR(pdevs[i])) {
1478                         x86_android_tablet_cleanup();
1479                         return PTR_ERR(pdevs[i]);
1480                 }
1481         }
1482
1483         serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL);
1484         if (!serdevs) {
1485                 x86_android_tablet_cleanup();
1486                 return -ENOMEM;
1487         }
1488
1489         serdev_count = dev_info->serdev_count;
1490         for (i = 0; i < serdev_count; i++) {
1491                 ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i);
1492                 if (ret < 0) {
1493                         x86_android_tablet_cleanup();
1494                         return ret;
1495                 }
1496         }
1497
1498         return 0;
1499 }
1500
1501 module_init(x86_android_tablet_init);
1502 module_exit(x86_android_tablet_cleanup);
1503
1504 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
1505 MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver");
1506 MODULE_LICENSE("GPL");