x86-android-tablets.c (42916B)
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/pm.h> 31#include <linux/power/bq24190_charger.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 */ 44enum 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 51struct 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 60static int gpiochip_find_match_label(struct gpio_chip *gc, void *data) 61{ 62 return gc->label && !strcmp(gc->label, data); 63} 64 65static 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 86static 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 153struct 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 159struct 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 172struct 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 */ 188static const char * const tusb1211_chg_det_psy[] = { "tusb1211-charger-detect" }; 189static const char * const bq24190_psy[] = { "bq24190-charger" }; 190static const char * const bq25890_psy[] = { "bq25890-charger" }; 191 192static const struct property_entry fg_bq24190_supply_props[] = { 193 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy), 194 { } 195}; 196 197static const struct software_node fg_bq24190_supply_node = { 198 .properties = fg_bq24190_supply_props, 199}; 200 201static const struct property_entry fg_bq25890_supply_props[] = { 202 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_psy), 203 { } 204}; 205 206static 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. */ 211static 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 222static 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 */ 227static struct regulator_consumer_supply intel_int3496_consumer = { 228 .supply = "vbus", 229 .dev_name = "intel-int3496", 230}; 231 232static 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 241static struct bq24190_platform_data bq24190_pdata = { 242 .regulator_init_data = &bq24190_vbus_init_data, 243}; 244 245static 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 */ 252static 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 260static 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 */ 269static 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 279static 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 285static 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 299static 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 */ 314static const char * const asus_me176c_accel_mount_matrix[] = { 315 "-1", "0", "0", 316 "0", "1", "0", 317 "0", "0", "1" 318}; 319 320static const struct property_entry asus_me176c_accel_props[] = { 321 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_me176c_accel_mount_matrix), 322 { } 323}; 324 325static const struct software_node asus_me176c_accel_node = { 326 .properties = asus_me176c_accel_props, 327}; 328 329static 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 338static const struct software_node asus_me176c_bq24190_node = { 339 .properties = asus_me176c_bq24190_props, 340}; 341 342static 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 349static const struct software_node asus_me176c_ug3105_node = { 350 .properties = asus_me176c_ug3105_props, 351}; 352 353static 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 419static 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 428static 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 437static struct gpiod_lookup_table * const asus_me176c_gpios[] = { 438 &int3496_gpo2_pin22_gpios, 439 &asus_me176c_goodix_gpios, 440 NULL 441}; 442 443static 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 */ 458static const char * const asus_tf103c_accel_mount_matrix[] = { 459 "0", "-1", "0", 460 "-1", "0", "0", 461 "0", "0", "1" 462}; 463 464static const struct property_entry asus_tf103c_accel_props[] = { 465 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_tf103c_accel_mount_matrix), 466 { } 467}; 468 469static const struct software_node asus_tf103c_accel_node = { 470 .properties = asus_tf103c_accel_props, 471}; 472 473static const struct property_entry asus_tf103c_touchscreen_props[] = { 474 PROPERTY_ENTRY_STRING("compatible", "atmel,atmel_mxt_ts"), 475 { } 476}; 477 478static const struct software_node asus_tf103c_touchscreen_node = { 479 .properties = asus_tf103c_touchscreen_props, 480}; 481 482static 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 493static const struct software_node asus_tf103c_battery_node = { 494 .properties = asus_tf103c_battery_props, 495}; 496 497static 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 506static const struct software_node asus_tf103c_bq24190_node = { 507 .properties = asus_tf103c_bq24190_props, 508}; 509 510static 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 517static const struct software_node asus_tf103c_ug3105_node = { 518 .properties = asus_tf103c_ug3105_props, 519}; 520 521static 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 583static struct gpiod_lookup_table * const asus_tf103c_gpios[] = { 584 &int3496_gpo2_pin22_gpios, 585 NULL 586}; 587 588static 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 */ 605static 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 614static const struct software_node chuwi_hi8_gsl1680_node = { 615 .properties = chuwi_hi8_gsl1680_props, 616}; 617 618static const char * const chuwi_hi8_mount_matrix[] = { 619 "1", "0", "0", 620 "0", "-1", "0", 621 "0", "0", "1" 622}; 623 624static const struct property_entry chuwi_hi8_bma250e_props[] = { 625 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", chuwi_hi8_mount_matrix), 626 { } 627}; 628 629static const struct software_node chuwi_hi8_bma250e_node = { 630 .properties = chuwi_hi8_bma250e_props, 631}; 632 633static 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 666static 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 674static 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 700static 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 */ 705static 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 718static 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 */ 724static 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 732static 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() */ 737static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { }; 738 739static struct lp855x_platform_data lenovo_yoga_tab2_830_1050_lp8557_pdata = { 740 .device_control = 0x86, 741 .initial_brightness = 128, 742}; 743 744static 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 798static 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 809static 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 820static 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 826static int __init lenovo_yoga_tab2_830_1050_init(void); 827static void lenovo_yoga_tab2_830_1050_exit(void); 828 829static 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 */ 860static 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 */ 887static 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 891static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl; 892 893static int __init lenovo_yoga_tab2_830_1050_init_codec(void) 894{ 895 struct device *codec_dev; 896 struct pinctrl *pinctrl; 897 int ret; 898 899 codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, 900 LENOVO_YOGA_TAB2_830_1050_CODEC_NAME); 901 if (!codec_dev) { 902 pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME); 903 return -ENODEV; 904 } 905 906 ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1); 907 if (ret) 908 goto err_put_device; 909 910 pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk"); 911 if (IS_ERR(pinctrl)) { 912 ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n"); 913 goto err_unregister_mappings; 914 } 915 916 /* We're done with the codec_dev now */ 917 put_device(codec_dev); 918 919 lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl; 920 return 0; 921 922err_unregister_mappings: 923 pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map); 924err_put_device: 925 put_device(codec_dev); 926 return ret; 927} 928 929/* 930 * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off 931 * gets used as pm_power_off handler. This causes "poweroff" on these tablets 932 * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice* 933 * followed by a normal 3 second press to recover. Avoid this by doing an EFI 934 * poweroff instead. 935 */ 936static void lenovo_yoga_tab2_830_1050_power_off(void) 937{ 938 efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL); 939} 940 941static int __init lenovo_yoga_tab2_830_1050_init(void) 942{ 943 int ret; 944 945 ret = lenovo_yoga_tab2_830_1050_init_display(); 946 if (ret) 947 return ret; 948 949 ret = lenovo_yoga_tab2_830_1050_init_codec(); 950 if (ret) 951 return ret; 952 953 pm_power_off = lenovo_yoga_tab2_830_1050_power_off; 954 return 0; 955} 956 957static void lenovo_yoga_tab2_830_1050_exit(void) 958{ 959 pm_power_off = NULL; /* Just turn poweroff into halt on module unload */ 960 961 if (lenovo_yoga_tab2_830_1050_codec_pinctrl) { 962 pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl); 963 pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map); 964 } 965} 966 967/* Nextbook Ares 8 tablets have an Android factory img with everything hardcoded */ 968static const char * const nextbook_ares8_accel_mount_matrix[] = { 969 "0", "-1", "0", 970 "-1", "0", "0", 971 "0", "0", "1" 972}; 973 974static const struct property_entry nextbook_ares8_accel_props[] = { 975 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", nextbook_ares8_accel_mount_matrix), 976 { } 977}; 978 979static const struct software_node nextbook_ares8_accel_node = { 980 .properties = nextbook_ares8_accel_props, 981}; 982 983static const struct property_entry nextbook_ares8_touchscreen_props[] = { 984 PROPERTY_ENTRY_U32("touchscreen-size-x", 800), 985 PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), 986 { } 987}; 988 989static const struct software_node nextbook_ares8_touchscreen_node = { 990 .properties = nextbook_ares8_touchscreen_props, 991}; 992 993static const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst = { 994 { 995 /* Freescale MMA8653FC accel */ 996 .board_info = { 997 .type = "mma8653", 998 .addr = 0x1d, 999 .dev_name = "mma8653", 1000 .swnode = &nextbook_ares8_accel_node, 1001 }, 1002 .adapter_path = "\\_SB_.I2C3", 1003 }, { 1004 /* FT5416DQ9 touchscreen controller */ 1005 .board_info = { 1006 .type = "edt-ft5x06", 1007 .addr = 0x38, 1008 .dev_name = "ft5416", 1009 .swnode = &nextbook_ares8_touchscreen_node, 1010 }, 1011 .adapter_path = "\\_SB_.I2C4", 1012 .irq_data = { 1013 .type = X86_ACPI_IRQ_TYPE_GPIOINT, 1014 .chip = "INT33FC:02", 1015 .index = 3, 1016 .trigger = ACPI_EDGE_SENSITIVE, 1017 .polarity = ACPI_ACTIVE_LOW, 1018 }, 1019 }, 1020}; 1021 1022static struct gpiod_lookup_table nextbook_ares8_int3496_gpios = { 1023 .dev_id = "intel-int3496", 1024 .table = { 1025 GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_HIGH), 1026 GPIO_LOOKUP("INT33FC:02", 18, "id", GPIO_ACTIVE_HIGH), 1027 { } 1028 }, 1029}; 1030 1031static struct gpiod_lookup_table * const nextbook_ares8_gpios[] = { 1032 &nextbook_ares8_int3496_gpios, 1033 NULL 1034}; 1035 1036static const struct x86_dev_info nextbook_ares8_info __initconst = { 1037 .i2c_client_info = nextbook_ares8_i2c_clients, 1038 .i2c_client_count = ARRAY_SIZE(nextbook_ares8_i2c_clients), 1039 .pdev_info = int3496_pdevs, 1040 .pdev_count = ARRAY_SIZE(int3496_pdevs), 1041 .gpiod_lookup_tables = nextbook_ares8_gpios, 1042 .invalid_aei_gpiochip = "INT33FC:02", 1043}; 1044 1045/* 1046 * Whitelabel (sold as various brands) TM800A550L tablets. 1047 * These tablet's DSDT contains a whole bunch of bogus ACPI I2C devices 1048 * (removed through acpi_quirk_skip_i2c_client_enumeration()) and 1049 * the touchscreen fwnode has the wrong GPIOs. 1050 */ 1051static const char * const whitelabel_tm800a550l_accel_mount_matrix[] = { 1052 "-1", "0", "0", 1053 "0", "1", "0", 1054 "0", "0", "1" 1055}; 1056 1057static const struct property_entry whitelabel_tm800a550l_accel_props[] = { 1058 PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", whitelabel_tm800a550l_accel_mount_matrix), 1059 { } 1060}; 1061 1062static const struct software_node whitelabel_tm800a550l_accel_node = { 1063 .properties = whitelabel_tm800a550l_accel_props, 1064}; 1065 1066static const struct property_entry whitelabel_tm800a550l_goodix_props[] = { 1067 PROPERTY_ENTRY_STRING("firmware-name", "gt912-tm800a550l.fw"), 1068 PROPERTY_ENTRY_STRING("goodix,config-name", "gt912-tm800a550l.cfg"), 1069 PROPERTY_ENTRY_U32("goodix,main-clk", 54), 1070 { } 1071}; 1072 1073static const struct software_node whitelabel_tm800a550l_goodix_node = { 1074 .properties = whitelabel_tm800a550l_goodix_props, 1075}; 1076 1077static const struct x86_i2c_client_info whitelabel_tm800a550l_i2c_clients[] __initconst = { 1078 { 1079 /* goodix touchscreen */ 1080 .board_info = { 1081 .type = "GDIX1001:00", 1082 .addr = 0x14, 1083 .dev_name = "goodix_ts", 1084 .swnode = &whitelabel_tm800a550l_goodix_node, 1085 }, 1086 .adapter_path = "\\_SB_.I2C2", 1087 .irq_data = { 1088 .type = X86_ACPI_IRQ_TYPE_APIC, 1089 .index = 0x44, 1090 .trigger = ACPI_EDGE_SENSITIVE, 1091 .polarity = ACPI_ACTIVE_HIGH, 1092 }, 1093 }, { 1094 /* kxcj91008 accel */ 1095 .board_info = { 1096 .type = "kxcj91008", 1097 .addr = 0x0f, 1098 .dev_name = "kxcj91008", 1099 .swnode = &whitelabel_tm800a550l_accel_node, 1100 }, 1101 .adapter_path = "\\_SB_.I2C3", 1102 }, 1103}; 1104 1105static struct gpiod_lookup_table whitelabel_tm800a550l_goodix_gpios = { 1106 .dev_id = "i2c-goodix_ts", 1107 .table = { 1108 GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH), 1109 GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH), 1110 { } 1111 }, 1112}; 1113 1114static struct gpiod_lookup_table * const whitelabel_tm800a550l_gpios[] = { 1115 &whitelabel_tm800a550l_goodix_gpios, 1116 NULL 1117}; 1118 1119static const struct x86_dev_info whitelabel_tm800a550l_info __initconst = { 1120 .i2c_client_info = whitelabel_tm800a550l_i2c_clients, 1121 .i2c_client_count = ARRAY_SIZE(whitelabel_tm800a550l_i2c_clients), 1122 .gpiod_lookup_tables = whitelabel_tm800a550l_gpios, 1123}; 1124 1125/* 1126 * If the EFI bootloader is not Xiaomi's own signed Android loader, then the 1127 * Xiaomi Mi Pad 2 X86 tablet sets OSID in the DSDT to 1 (Windows), causing 1128 * a bunch of devices to be hidden. 1129 * 1130 * This takes care of instantiating the hidden devices manually. 1131 */ 1132static const struct x86_i2c_client_info xiaomi_mipad2_i2c_clients[] __initconst = { 1133 { 1134 /* BQ27520 fuel-gauge */ 1135 .board_info = { 1136 .type = "bq27520", 1137 .addr = 0x55, 1138 .dev_name = "bq27520", 1139 .swnode = &fg_bq25890_supply_node, 1140 }, 1141 .adapter_path = "\\_SB_.PCI0.I2C1", 1142 }, { 1143 /* KTD2026 RGB notification LED controller */ 1144 .board_info = { 1145 .type = "ktd2026", 1146 .addr = 0x30, 1147 .dev_name = "ktd2026", 1148 }, 1149 .adapter_path = "\\_SB_.PCI0.I2C3", 1150 }, 1151}; 1152 1153static const struct x86_dev_info xiaomi_mipad2_info __initconst = { 1154 .i2c_client_info = xiaomi_mipad2_i2c_clients, 1155 .i2c_client_count = ARRAY_SIZE(xiaomi_mipad2_i2c_clients), 1156}; 1157 1158static const struct dmi_system_id x86_android_tablet_ids[] __initconst = { 1159 { 1160 /* Asus MeMO Pad 7 ME176C */ 1161 .matches = { 1162 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1163 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"), 1164 }, 1165 .driver_data = (void *)&asus_me176c_info, 1166 }, 1167 { 1168 /* Asus TF103C */ 1169 .matches = { 1170 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1171 DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"), 1172 }, 1173 .driver_data = (void *)&asus_tf103c_info, 1174 }, 1175 { 1176 /* Chuwi Hi8 (CWI509) */ 1177 .matches = { 1178 DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"), 1179 DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"), 1180 DMI_MATCH(DMI_SYS_VENDOR, "ilife"), 1181 DMI_MATCH(DMI_PRODUCT_NAME, "S806"), 1182 }, 1183 .driver_data = (void *)&chuwi_hi8_info, 1184 }, 1185 { 1186 /* CZC P10T */ 1187 .ident = "CZC ODEON TPC-10 (\"P10T\")", 1188 .matches = { 1189 DMI_MATCH(DMI_SYS_VENDOR, "CZC"), 1190 DMI_MATCH(DMI_PRODUCT_NAME, "ODEON*TPC-10"), 1191 }, 1192 .driver_data = (void *)&czc_p10t, 1193 }, 1194 { 1195 /* CZC P10T variant */ 1196 .ident = "ViewSonic ViewPad 10", 1197 .matches = { 1198 DMI_MATCH(DMI_SYS_VENDOR, "ViewSonic"), 1199 DMI_MATCH(DMI_PRODUCT_NAME, "VPAD10"), 1200 }, 1201 .driver_data = (void *)&czc_p10t, 1202 }, 1203 { 1204 /* Lenovo Yoga Book X90F / X91F / X91L */ 1205 .matches = { 1206 /* Non exact match to match all versions */ 1207 DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"), 1208 }, 1209 .driver_data = (void *)&lenovo_yogabook_x9x_info, 1210 }, 1211 { 1212 /* 1213 * Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10" 1214 * Lenovo Yoga Tablet 2 use the same mainboard) 1215 */ 1216 .matches = { 1217 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."), 1218 DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"), 1219 DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"), 1220 /* Partial match on beginning of BIOS version */ 1221 DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"), 1222 }, 1223 .driver_data = (void *)&lenovo_yoga_tab2_830_1050_info, 1224 }, 1225 { 1226 /* Nextbook Ares 8 */ 1227 .matches = { 1228 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), 1229 DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"), 1230 }, 1231 .driver_data = (void *)&nextbook_ares8_info, 1232 }, 1233 { 1234 /* Whitelabel (sold as various brands) TM800A550L */ 1235 .matches = { 1236 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), 1237 DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), 1238 /* Above strings are too generic, also match on BIOS version */ 1239 DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"), 1240 }, 1241 .driver_data = (void *)&whitelabel_tm800a550l_info, 1242 }, 1243 { 1244 /* Xiaomi Mi Pad 2 */ 1245 .matches = { 1246 DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"), 1247 DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"), 1248 }, 1249 .driver_data = (void *)&xiaomi_mipad2_info, 1250 }, 1251 { } 1252}; 1253MODULE_DEVICE_TABLE(dmi, x86_android_tablet_ids); 1254 1255static int i2c_client_count; 1256static int pdev_count; 1257static int serdev_count; 1258static struct i2c_client **i2c_clients; 1259static struct platform_device **pdevs; 1260static struct serdev_device **serdevs; 1261static struct gpiod_lookup_table * const *gpiod_lookup_tables; 1262static const struct software_node *bat_swnode; 1263static void (*exit_handler)(void); 1264 1265static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info, 1266 int idx) 1267{ 1268 const struct x86_i2c_client_info *client_info = &dev_info->i2c_client_info[idx]; 1269 struct i2c_board_info board_info = client_info->board_info; 1270 struct i2c_adapter *adap; 1271 acpi_handle handle; 1272 acpi_status status; 1273 1274 board_info.irq = x86_acpi_irq_helper_get(&client_info->irq_data); 1275 if (board_info.irq < 0) 1276 return board_info.irq; 1277 1278 status = acpi_get_handle(NULL, client_info->adapter_path, &handle); 1279 if (ACPI_FAILURE(status)) { 1280 pr_err("Error could not get %s handle\n", client_info->adapter_path); 1281 return -ENODEV; 1282 } 1283 1284 adap = i2c_acpi_find_adapter_by_handle(handle); 1285 if (!adap) { 1286 pr_err("error could not get %s adapter\n", client_info->adapter_path); 1287 return -ENODEV; 1288 } 1289 1290 i2c_clients[idx] = i2c_new_client_device(adap, &board_info); 1291 put_device(&adap->dev); 1292 if (IS_ERR(i2c_clients[idx])) 1293 return dev_err_probe(&adap->dev, PTR_ERR(i2c_clients[idx]), 1294 "creating I2C-client %d\n", idx); 1295 1296 return 0; 1297} 1298 1299static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx) 1300{ 1301 struct acpi_device *ctrl_adev, *serdev_adev; 1302 struct serdev_device *serdev; 1303 struct device *ctrl_dev; 1304 int ret = -ENODEV; 1305 1306 ctrl_adev = acpi_dev_get_first_match_dev(info->ctrl_hid, info->ctrl_uid, -1); 1307 if (!ctrl_adev) { 1308 pr_err("error could not get %s/%s ctrl adev\n", 1309 info->ctrl_hid, info->ctrl_uid); 1310 return -ENODEV; 1311 } 1312 1313 serdev_adev = acpi_dev_get_first_match_dev(info->serdev_hid, NULL, -1); 1314 if (!serdev_adev) { 1315 pr_err("error could not get %s serdev adev\n", info->serdev_hid); 1316 goto put_ctrl_adev; 1317 } 1318 1319 /* get_first_physical_node() returns a weak ref, no need to put() it */ 1320 ctrl_dev = acpi_get_first_physical_node(ctrl_adev); 1321 if (!ctrl_dev) { 1322 pr_err("error could not get %s/%s ctrl physical dev\n", 1323 info->ctrl_hid, info->ctrl_uid); 1324 goto put_serdev_adev; 1325 } 1326 1327 /* ctrl_dev now points to the controller's parent, get the controller */ 1328 ctrl_dev = device_find_child_by_name(ctrl_dev, info->ctrl_devname); 1329 if (!ctrl_dev) { 1330 pr_err("error could not get %s/%s %s ctrl dev\n", 1331 info->ctrl_hid, info->ctrl_uid, info->ctrl_devname); 1332 goto put_serdev_adev; 1333 } 1334 1335 serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev)); 1336 if (!serdev) { 1337 ret = -ENOMEM; 1338 goto put_serdev_adev; 1339 } 1340 1341 ACPI_COMPANION_SET(&serdev->dev, serdev_adev); 1342 acpi_device_set_enumerated(serdev_adev); 1343 1344 ret = serdev_device_add(serdev); 1345 if (ret) { 1346 dev_err(&serdev->dev, "error %d adding serdev\n", ret); 1347 serdev_device_put(serdev); 1348 goto put_serdev_adev; 1349 } 1350 1351 serdevs[idx] = serdev; 1352 1353put_serdev_adev: 1354 acpi_dev_put(serdev_adev); 1355put_ctrl_adev: 1356 acpi_dev_put(ctrl_adev); 1357 return ret; 1358} 1359 1360static void x86_android_tablet_cleanup(void) 1361{ 1362 int i; 1363 1364 for (i = 0; i < serdev_count; i++) { 1365 if (serdevs[i]) 1366 serdev_device_remove(serdevs[i]); 1367 } 1368 1369 kfree(serdevs); 1370 1371 for (i = 0; i < pdev_count; i++) 1372 platform_device_unregister(pdevs[i]); 1373 1374 kfree(pdevs); 1375 1376 for (i = 0; i < i2c_client_count; i++) 1377 i2c_unregister_device(i2c_clients[i]); 1378 1379 kfree(i2c_clients); 1380 1381 if (exit_handler) 1382 exit_handler(); 1383 1384 for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++) 1385 gpiod_remove_lookup_table(gpiod_lookup_tables[i]); 1386 1387 software_node_unregister(bat_swnode); 1388} 1389 1390static __init int x86_android_tablet_init(void) 1391{ 1392 const struct x86_dev_info *dev_info; 1393 const struct dmi_system_id *id; 1394 struct gpio_chip *chip; 1395 int i, ret = 0; 1396 1397 id = dmi_first_match(x86_android_tablet_ids); 1398 if (!id) 1399 return -ENODEV; 1400 1401 dev_info = id->driver_data; 1402 1403 /* 1404 * The broken DSDTs on these devices often also include broken 1405 * _AEI (ACPI Event Interrupt) handlers, disable these. 1406 */ 1407 if (dev_info->invalid_aei_gpiochip) { 1408 chip = gpiochip_find(dev_info->invalid_aei_gpiochip, 1409 gpiochip_find_match_label); 1410 if (!chip) { 1411 pr_err("error cannot find GPIO chip %s\n", dev_info->invalid_aei_gpiochip); 1412 return -ENODEV; 1413 } 1414 acpi_gpiochip_free_interrupts(chip); 1415 } 1416 1417 /* 1418 * Since this runs from module_init() it cannot use -EPROBE_DEFER, 1419 * instead pre-load any modules which are listed as requirements. 1420 */ 1421 for (i = 0; dev_info->modules && dev_info->modules[i]; i++) 1422 request_module(dev_info->modules[i]); 1423 1424 bat_swnode = dev_info->bat_swnode; 1425 if (bat_swnode) { 1426 ret = software_node_register(bat_swnode); 1427 if (ret) 1428 return ret; 1429 } 1430 1431 gpiod_lookup_tables = dev_info->gpiod_lookup_tables; 1432 for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++) 1433 gpiod_add_lookup_table(gpiod_lookup_tables[i]); 1434 1435 if (dev_info->init) { 1436 ret = dev_info->init(); 1437 if (ret < 0) { 1438 x86_android_tablet_cleanup(); 1439 return ret; 1440 } 1441 exit_handler = dev_info->exit; 1442 } 1443 1444 i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL); 1445 if (!i2c_clients) { 1446 x86_android_tablet_cleanup(); 1447 return -ENOMEM; 1448 } 1449 1450 i2c_client_count = dev_info->i2c_client_count; 1451 for (i = 0; i < i2c_client_count; i++) { 1452 ret = x86_instantiate_i2c_client(dev_info, i); 1453 if (ret < 0) { 1454 x86_android_tablet_cleanup(); 1455 return ret; 1456 } 1457 } 1458 1459 pdevs = kcalloc(dev_info->pdev_count, sizeof(*pdevs), GFP_KERNEL); 1460 if (!pdevs) { 1461 x86_android_tablet_cleanup(); 1462 return -ENOMEM; 1463 } 1464 1465 pdev_count = dev_info->pdev_count; 1466 for (i = 0; i < pdev_count; i++) { 1467 pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]); 1468 if (IS_ERR(pdevs[i])) { 1469 x86_android_tablet_cleanup(); 1470 return PTR_ERR(pdevs[i]); 1471 } 1472 } 1473 1474 serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL); 1475 if (!serdevs) { 1476 x86_android_tablet_cleanup(); 1477 return -ENOMEM; 1478 } 1479 1480 serdev_count = dev_info->serdev_count; 1481 for (i = 0; i < serdev_count; i++) { 1482 ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i); 1483 if (ret < 0) { 1484 x86_android_tablet_cleanup(); 1485 return ret; 1486 } 1487 } 1488 1489 return 0; 1490} 1491 1492module_init(x86_android_tablet_init); 1493module_exit(x86_android_tablet_cleanup); 1494 1495MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 1496MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver"); 1497MODULE_LICENSE("GPL");