162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * DMI based code to deal with broken DSDTs on X86 tablets which ship with 462306a36Sopenharmony_ci * Android as (part of) the factory image. The factory kernels shipped on these 562306a36Sopenharmony_ci * devices typically have a bunch of things hardcoded, rather than specified 662306a36Sopenharmony_ci * in their DSDT. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com> 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/acpi.h> 1262306a36Sopenharmony_ci#include <linux/gpio/machine.h> 1362306a36Sopenharmony_ci#include <linux/input.h> 1462306a36Sopenharmony_ci#include <linux/platform_device.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "shared-psy-info.h" 1762306a36Sopenharmony_ci#include "x86-android-tablets.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/* Acer Iconia One 7 B1-750 has an Android factory img with everything hardcoded */ 2062306a36Sopenharmony_cistatic const char * const acer_b1_750_mount_matrix[] = { 2162306a36Sopenharmony_ci "-1", "0", "0", 2262306a36Sopenharmony_ci "0", "1", "0", 2362306a36Sopenharmony_ci "0", "0", "1" 2462306a36Sopenharmony_ci}; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistatic const struct property_entry acer_b1_750_bma250e_props[] = { 2762306a36Sopenharmony_ci PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", acer_b1_750_mount_matrix), 2862306a36Sopenharmony_ci { } 2962306a36Sopenharmony_ci}; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic const struct software_node acer_b1_750_bma250e_node = { 3262306a36Sopenharmony_ci .properties = acer_b1_750_bma250e_props, 3362306a36Sopenharmony_ci}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic const struct x86_i2c_client_info acer_b1_750_i2c_clients[] __initconst = { 3662306a36Sopenharmony_ci { 3762306a36Sopenharmony_ci /* Novatek NVT-ts touchscreen */ 3862306a36Sopenharmony_ci .board_info = { 3962306a36Sopenharmony_ci .type = "NVT-ts", 4062306a36Sopenharmony_ci .addr = 0x34, 4162306a36Sopenharmony_ci .dev_name = "NVT-ts", 4262306a36Sopenharmony_ci }, 4362306a36Sopenharmony_ci .adapter_path = "\\_SB_.I2C4", 4462306a36Sopenharmony_ci .irq_data = { 4562306a36Sopenharmony_ci .type = X86_ACPI_IRQ_TYPE_GPIOINT, 4662306a36Sopenharmony_ci .chip = "INT33FC:02", 4762306a36Sopenharmony_ci .index = 3, 4862306a36Sopenharmony_ci .trigger = ACPI_EDGE_SENSITIVE, 4962306a36Sopenharmony_ci .polarity = ACPI_ACTIVE_LOW, 5062306a36Sopenharmony_ci }, 5162306a36Sopenharmony_ci }, { 5262306a36Sopenharmony_ci /* BMA250E accelerometer */ 5362306a36Sopenharmony_ci .board_info = { 5462306a36Sopenharmony_ci .type = "bma250e", 5562306a36Sopenharmony_ci .addr = 0x18, 5662306a36Sopenharmony_ci .swnode = &acer_b1_750_bma250e_node, 5762306a36Sopenharmony_ci }, 5862306a36Sopenharmony_ci .adapter_path = "\\_SB_.I2C3", 5962306a36Sopenharmony_ci .irq_data = { 6062306a36Sopenharmony_ci .type = X86_ACPI_IRQ_TYPE_GPIOINT, 6162306a36Sopenharmony_ci .chip = "INT33FC:02", 6262306a36Sopenharmony_ci .index = 25, 6362306a36Sopenharmony_ci .trigger = ACPI_LEVEL_SENSITIVE, 6462306a36Sopenharmony_ci .polarity = ACPI_ACTIVE_HIGH, 6562306a36Sopenharmony_ci }, 6662306a36Sopenharmony_ci }, 6762306a36Sopenharmony_ci}; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic struct gpiod_lookup_table acer_b1_750_nvt_ts_gpios = { 7062306a36Sopenharmony_ci .dev_id = "i2c-NVT-ts", 7162306a36Sopenharmony_ci .table = { 7262306a36Sopenharmony_ci GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_LOW), 7362306a36Sopenharmony_ci { } 7462306a36Sopenharmony_ci }, 7562306a36Sopenharmony_ci}; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic struct gpiod_lookup_table * const acer_b1_750_gpios[] = { 7862306a36Sopenharmony_ci &acer_b1_750_nvt_ts_gpios, 7962306a36Sopenharmony_ci &int3496_reference_gpios, 8062306a36Sopenharmony_ci NULL 8162306a36Sopenharmony_ci}; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ciconst struct x86_dev_info acer_b1_750_info __initconst = { 8462306a36Sopenharmony_ci .i2c_client_info = acer_b1_750_i2c_clients, 8562306a36Sopenharmony_ci .i2c_client_count = ARRAY_SIZE(acer_b1_750_i2c_clients), 8662306a36Sopenharmony_ci .pdev_info = int3496_pdevs, 8762306a36Sopenharmony_ci .pdev_count = 1, 8862306a36Sopenharmony_ci .gpiod_lookup_tables = acer_b1_750_gpios, 8962306a36Sopenharmony_ci}; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci/* 9262306a36Sopenharmony_ci * Advantech MICA-071 9362306a36Sopenharmony_ci * This is a standard Windows tablet, but it has an extra "quick launch" button 9462306a36Sopenharmony_ci * which is not described in the ACPI tables in anyway. 9562306a36Sopenharmony_ci * Use the x86-android-tablets infra to create a gpio-button device for this. 9662306a36Sopenharmony_ci */ 9762306a36Sopenharmony_cistatic const struct x86_gpio_button advantech_mica_071_button __initconst = { 9862306a36Sopenharmony_ci .button = { 9962306a36Sopenharmony_ci .code = KEY_PROG1, 10062306a36Sopenharmony_ci .active_low = true, 10162306a36Sopenharmony_ci .desc = "prog1_key", 10262306a36Sopenharmony_ci .type = EV_KEY, 10362306a36Sopenharmony_ci .wakeup = false, 10462306a36Sopenharmony_ci .debounce_interval = 50, 10562306a36Sopenharmony_ci }, 10662306a36Sopenharmony_ci .chip = "INT33FC:00", 10762306a36Sopenharmony_ci .pin = 2, 10862306a36Sopenharmony_ci}; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ciconst struct x86_dev_info advantech_mica_071_info __initconst = { 11162306a36Sopenharmony_ci .gpio_button = &advantech_mica_071_button, 11262306a36Sopenharmony_ci .gpio_button_count = 1, 11362306a36Sopenharmony_ci}; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci/* 11662306a36Sopenharmony_ci * When booted with the BIOS set to Android mode the Chuwi Hi8 (CWI509) DSDT 11762306a36Sopenharmony_ci * contains a whole bunch of bogus ACPI I2C devices and is missing entries 11862306a36Sopenharmony_ci * for the touchscreen and the accelerometer. 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_cistatic const struct property_entry chuwi_hi8_gsl1680_props[] = { 12162306a36Sopenharmony_ci PROPERTY_ENTRY_U32("touchscreen-size-x", 1665), 12262306a36Sopenharmony_ci PROPERTY_ENTRY_U32("touchscreen-size-y", 1140), 12362306a36Sopenharmony_ci PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), 12462306a36Sopenharmony_ci PROPERTY_ENTRY_BOOL("silead,home-button"), 12562306a36Sopenharmony_ci PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi8.fw"), 12662306a36Sopenharmony_ci { } 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic const struct software_node chuwi_hi8_gsl1680_node = { 13062306a36Sopenharmony_ci .properties = chuwi_hi8_gsl1680_props, 13162306a36Sopenharmony_ci}; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistatic const char * const chuwi_hi8_mount_matrix[] = { 13462306a36Sopenharmony_ci "1", "0", "0", 13562306a36Sopenharmony_ci "0", "-1", "0", 13662306a36Sopenharmony_ci "0", "0", "1" 13762306a36Sopenharmony_ci}; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistatic const struct property_entry chuwi_hi8_bma250e_props[] = { 14062306a36Sopenharmony_ci PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", chuwi_hi8_mount_matrix), 14162306a36Sopenharmony_ci { } 14262306a36Sopenharmony_ci}; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_cistatic const struct software_node chuwi_hi8_bma250e_node = { 14562306a36Sopenharmony_ci .properties = chuwi_hi8_bma250e_props, 14662306a36Sopenharmony_ci}; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic const struct x86_i2c_client_info chuwi_hi8_i2c_clients[] __initconst = { 14962306a36Sopenharmony_ci { 15062306a36Sopenharmony_ci /* Silead touchscreen */ 15162306a36Sopenharmony_ci .board_info = { 15262306a36Sopenharmony_ci .type = "gsl1680", 15362306a36Sopenharmony_ci .addr = 0x40, 15462306a36Sopenharmony_ci .swnode = &chuwi_hi8_gsl1680_node, 15562306a36Sopenharmony_ci }, 15662306a36Sopenharmony_ci .adapter_path = "\\_SB_.I2C4", 15762306a36Sopenharmony_ci .irq_data = { 15862306a36Sopenharmony_ci .type = X86_ACPI_IRQ_TYPE_APIC, 15962306a36Sopenharmony_ci .index = 0x44, 16062306a36Sopenharmony_ci .trigger = ACPI_EDGE_SENSITIVE, 16162306a36Sopenharmony_ci .polarity = ACPI_ACTIVE_HIGH, 16262306a36Sopenharmony_ci }, 16362306a36Sopenharmony_ci }, { 16462306a36Sopenharmony_ci /* BMA250E accelerometer */ 16562306a36Sopenharmony_ci .board_info = { 16662306a36Sopenharmony_ci .type = "bma250e", 16762306a36Sopenharmony_ci .addr = 0x18, 16862306a36Sopenharmony_ci .swnode = &chuwi_hi8_bma250e_node, 16962306a36Sopenharmony_ci }, 17062306a36Sopenharmony_ci .adapter_path = "\\_SB_.I2C3", 17162306a36Sopenharmony_ci .irq_data = { 17262306a36Sopenharmony_ci .type = X86_ACPI_IRQ_TYPE_GPIOINT, 17362306a36Sopenharmony_ci .chip = "INT33FC:02", 17462306a36Sopenharmony_ci .index = 23, 17562306a36Sopenharmony_ci .trigger = ACPI_LEVEL_SENSITIVE, 17662306a36Sopenharmony_ci .polarity = ACPI_ACTIVE_HIGH, 17762306a36Sopenharmony_ci }, 17862306a36Sopenharmony_ci }, 17962306a36Sopenharmony_ci}; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cistatic int __init chuwi_hi8_init(void) 18262306a36Sopenharmony_ci{ 18362306a36Sopenharmony_ci /* 18462306a36Sopenharmony_ci * Avoid the acpi_unregister_gsi() call in x86_acpi_irq_helper_get() 18562306a36Sopenharmony_ci * breaking the touchscreen + logging various errors when the Windows 18662306a36Sopenharmony_ci * BIOS is used. 18762306a36Sopenharmony_ci */ 18862306a36Sopenharmony_ci if (acpi_dev_present("MSSL0001", NULL, 1)) 18962306a36Sopenharmony_ci return -ENODEV; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci return 0; 19262306a36Sopenharmony_ci} 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ciconst struct x86_dev_info chuwi_hi8_info __initconst = { 19562306a36Sopenharmony_ci .i2c_client_info = chuwi_hi8_i2c_clients, 19662306a36Sopenharmony_ci .i2c_client_count = ARRAY_SIZE(chuwi_hi8_i2c_clients), 19762306a36Sopenharmony_ci .init = chuwi_hi8_init, 19862306a36Sopenharmony_ci}; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci/* 20162306a36Sopenharmony_ci * Cyberbook T116 Android version 20262306a36Sopenharmony_ci * This comes in both Windows and Android versions and even on Android 20362306a36Sopenharmony_ci * the DSDT is mostly sane. This tablet has 2 extra general purpose buttons 20462306a36Sopenharmony_ci * in the button row with the power + volume-buttons labeled P and F. 20562306a36Sopenharmony_ci * Use the x86-android-tablets infra to create a gpio-button device for these. 20662306a36Sopenharmony_ci */ 20762306a36Sopenharmony_cistatic const struct x86_gpio_button cyberbook_t116_buttons[] __initconst = { 20862306a36Sopenharmony_ci { 20962306a36Sopenharmony_ci .button = { 21062306a36Sopenharmony_ci .code = KEY_PROG1, 21162306a36Sopenharmony_ci .active_low = true, 21262306a36Sopenharmony_ci .desc = "prog1_key", 21362306a36Sopenharmony_ci .type = EV_KEY, 21462306a36Sopenharmony_ci .wakeup = false, 21562306a36Sopenharmony_ci .debounce_interval = 50, 21662306a36Sopenharmony_ci }, 21762306a36Sopenharmony_ci .chip = "INT33FF:00", 21862306a36Sopenharmony_ci .pin = 30, 21962306a36Sopenharmony_ci }, 22062306a36Sopenharmony_ci { 22162306a36Sopenharmony_ci .button = { 22262306a36Sopenharmony_ci .code = KEY_PROG2, 22362306a36Sopenharmony_ci .active_low = true, 22462306a36Sopenharmony_ci .desc = "prog2_key", 22562306a36Sopenharmony_ci .type = EV_KEY, 22662306a36Sopenharmony_ci .wakeup = false, 22762306a36Sopenharmony_ci .debounce_interval = 50, 22862306a36Sopenharmony_ci }, 22962306a36Sopenharmony_ci .chip = "INT33FF:03", 23062306a36Sopenharmony_ci .pin = 48, 23162306a36Sopenharmony_ci }, 23262306a36Sopenharmony_ci}; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ciconst struct x86_dev_info cyberbook_t116_info __initconst = { 23562306a36Sopenharmony_ci .gpio_button = cyberbook_t116_buttons, 23662306a36Sopenharmony_ci .gpio_button_count = ARRAY_SIZE(cyberbook_t116_buttons), 23762306a36Sopenharmony_ci}; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci#define CZC_EC_EXTRA_PORT 0x68 24062306a36Sopenharmony_ci#define CZC_EC_ANDROID_KEYS 0x63 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_cistatic int __init czc_p10t_init(void) 24362306a36Sopenharmony_ci{ 24462306a36Sopenharmony_ci /* 24562306a36Sopenharmony_ci * The device boots up in "Windows 7" mode, when the home button sends a 24662306a36Sopenharmony_ci * Windows specific key sequence (Left Meta + D) and the second button 24762306a36Sopenharmony_ci * sends an unknown one while also toggling the Radio Kill Switch. 24862306a36Sopenharmony_ci * This is a surprising behavior when the second button is labeled "Back". 24962306a36Sopenharmony_ci * 25062306a36Sopenharmony_ci * The vendor-supplied Android-x86 build switches the device to a "Android" 25162306a36Sopenharmony_ci * mode by writing value 0x63 to the I/O port 0x68. This just seems to just 25262306a36Sopenharmony_ci * set bit 6 on address 0x96 in the EC region; switching the bit directly 25362306a36Sopenharmony_ci * seems to achieve the same result. It uses a "p10t_switcher" to do the 25462306a36Sopenharmony_ci * job. It doesn't seem to be able to do anything else, and no other use 25562306a36Sopenharmony_ci * of the port 0x68 is known. 25662306a36Sopenharmony_ci * 25762306a36Sopenharmony_ci * In the Android mode, the home button sends just a single scancode, 25862306a36Sopenharmony_ci * which can be handled in Linux userspace more reasonably and the back 25962306a36Sopenharmony_ci * button only sends a scancode without toggling the kill switch. 26062306a36Sopenharmony_ci * The scancode can then be mapped either to Back or RF Kill functionality 26162306a36Sopenharmony_ci * in userspace, depending on how the button is labeled on that particular 26262306a36Sopenharmony_ci * model. 26362306a36Sopenharmony_ci */ 26462306a36Sopenharmony_ci outb(CZC_EC_ANDROID_KEYS, CZC_EC_EXTRA_PORT); 26562306a36Sopenharmony_ci return 0; 26662306a36Sopenharmony_ci} 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ciconst struct x86_dev_info czc_p10t __initconst = { 26962306a36Sopenharmony_ci .init = czc_p10t_init, 27062306a36Sopenharmony_ci}; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci/* Medion Lifetab S10346 tablets have an Android factory img with everything hardcoded */ 27362306a36Sopenharmony_cistatic const char * const medion_lifetab_s10346_accel_mount_matrix[] = { 27462306a36Sopenharmony_ci "0", "1", "0", 27562306a36Sopenharmony_ci "1", "0", "0", 27662306a36Sopenharmony_ci "0", "0", "1" 27762306a36Sopenharmony_ci}; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_cistatic const struct property_entry medion_lifetab_s10346_accel_props[] = { 28062306a36Sopenharmony_ci PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", medion_lifetab_s10346_accel_mount_matrix), 28162306a36Sopenharmony_ci { } 28262306a36Sopenharmony_ci}; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_cistatic const struct software_node medion_lifetab_s10346_accel_node = { 28562306a36Sopenharmony_ci .properties = medion_lifetab_s10346_accel_props, 28662306a36Sopenharmony_ci}; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci/* Note the LCD panel is mounted upside down, this is correctly indicated in the VBT */ 28962306a36Sopenharmony_cistatic const struct property_entry medion_lifetab_s10346_touchscreen_props[] = { 29062306a36Sopenharmony_ci PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"), 29162306a36Sopenharmony_ci PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), 29262306a36Sopenharmony_ci { } 29362306a36Sopenharmony_ci}; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_cistatic const struct software_node medion_lifetab_s10346_touchscreen_node = { 29662306a36Sopenharmony_ci .properties = medion_lifetab_s10346_touchscreen_props, 29762306a36Sopenharmony_ci}; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_cistatic const struct x86_i2c_client_info medion_lifetab_s10346_i2c_clients[] __initconst = { 30062306a36Sopenharmony_ci { 30162306a36Sopenharmony_ci /* kxtj21009 accel */ 30262306a36Sopenharmony_ci .board_info = { 30362306a36Sopenharmony_ci .type = "kxtj21009", 30462306a36Sopenharmony_ci .addr = 0x0f, 30562306a36Sopenharmony_ci .dev_name = "kxtj21009", 30662306a36Sopenharmony_ci .swnode = &medion_lifetab_s10346_accel_node, 30762306a36Sopenharmony_ci }, 30862306a36Sopenharmony_ci .adapter_path = "\\_SB_.I2C3", 30962306a36Sopenharmony_ci .irq_data = { 31062306a36Sopenharmony_ci .type = X86_ACPI_IRQ_TYPE_GPIOINT, 31162306a36Sopenharmony_ci .chip = "INT33FC:02", 31262306a36Sopenharmony_ci .index = 23, 31362306a36Sopenharmony_ci .trigger = ACPI_EDGE_SENSITIVE, 31462306a36Sopenharmony_ci .polarity = ACPI_ACTIVE_HIGH, 31562306a36Sopenharmony_ci }, 31662306a36Sopenharmony_ci }, { 31762306a36Sopenharmony_ci /* goodix touchscreen */ 31862306a36Sopenharmony_ci .board_info = { 31962306a36Sopenharmony_ci .type = "GDIX1001:00", 32062306a36Sopenharmony_ci .addr = 0x14, 32162306a36Sopenharmony_ci .dev_name = "goodix_ts", 32262306a36Sopenharmony_ci .swnode = &medion_lifetab_s10346_touchscreen_node, 32362306a36Sopenharmony_ci }, 32462306a36Sopenharmony_ci .adapter_path = "\\_SB_.I2C4", 32562306a36Sopenharmony_ci .irq_data = { 32662306a36Sopenharmony_ci .type = X86_ACPI_IRQ_TYPE_APIC, 32762306a36Sopenharmony_ci .index = 0x44, 32862306a36Sopenharmony_ci .trigger = ACPI_EDGE_SENSITIVE, 32962306a36Sopenharmony_ci .polarity = ACPI_ACTIVE_LOW, 33062306a36Sopenharmony_ci }, 33162306a36Sopenharmony_ci }, 33262306a36Sopenharmony_ci}; 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_cistatic struct gpiod_lookup_table medion_lifetab_s10346_goodix_gpios = { 33562306a36Sopenharmony_ci .dev_id = "i2c-goodix_ts", 33662306a36Sopenharmony_ci .table = { 33762306a36Sopenharmony_ci GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH), 33862306a36Sopenharmony_ci GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH), 33962306a36Sopenharmony_ci { } 34062306a36Sopenharmony_ci }, 34162306a36Sopenharmony_ci}; 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_cistatic struct gpiod_lookup_table * const medion_lifetab_s10346_gpios[] = { 34462306a36Sopenharmony_ci &medion_lifetab_s10346_goodix_gpios, 34562306a36Sopenharmony_ci NULL 34662306a36Sopenharmony_ci}; 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ciconst struct x86_dev_info medion_lifetab_s10346_info __initconst = { 34962306a36Sopenharmony_ci .i2c_client_info = medion_lifetab_s10346_i2c_clients, 35062306a36Sopenharmony_ci .i2c_client_count = ARRAY_SIZE(medion_lifetab_s10346_i2c_clients), 35162306a36Sopenharmony_ci .gpiod_lookup_tables = medion_lifetab_s10346_gpios, 35262306a36Sopenharmony_ci}; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci/* Nextbook Ares 8 (BYT) tablets have an Android factory img with everything hardcoded */ 35562306a36Sopenharmony_cistatic const char * const nextbook_ares8_accel_mount_matrix[] = { 35662306a36Sopenharmony_ci "0", "-1", "0", 35762306a36Sopenharmony_ci "-1", "0", "0", 35862306a36Sopenharmony_ci "0", "0", "1" 35962306a36Sopenharmony_ci}; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_cistatic const struct property_entry nextbook_ares8_accel_props[] = { 36262306a36Sopenharmony_ci PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", nextbook_ares8_accel_mount_matrix), 36362306a36Sopenharmony_ci { } 36462306a36Sopenharmony_ci}; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_cistatic const struct software_node nextbook_ares8_accel_node = { 36762306a36Sopenharmony_ci .properties = nextbook_ares8_accel_props, 36862306a36Sopenharmony_ci}; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_cistatic const struct property_entry nextbook_ares8_touchscreen_props[] = { 37162306a36Sopenharmony_ci PROPERTY_ENTRY_U32("touchscreen-size-x", 800), 37262306a36Sopenharmony_ci PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), 37362306a36Sopenharmony_ci { } 37462306a36Sopenharmony_ci}; 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_cistatic const struct software_node nextbook_ares8_touchscreen_node = { 37762306a36Sopenharmony_ci .properties = nextbook_ares8_touchscreen_props, 37862306a36Sopenharmony_ci}; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_cistatic const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst = { 38162306a36Sopenharmony_ci { 38262306a36Sopenharmony_ci /* Freescale MMA8653FC accel */ 38362306a36Sopenharmony_ci .board_info = { 38462306a36Sopenharmony_ci .type = "mma8653", 38562306a36Sopenharmony_ci .addr = 0x1d, 38662306a36Sopenharmony_ci .dev_name = "mma8653", 38762306a36Sopenharmony_ci .swnode = &nextbook_ares8_accel_node, 38862306a36Sopenharmony_ci }, 38962306a36Sopenharmony_ci .adapter_path = "\\_SB_.I2C3", 39062306a36Sopenharmony_ci }, { 39162306a36Sopenharmony_ci /* FT5416DQ9 touchscreen controller */ 39262306a36Sopenharmony_ci .board_info = { 39362306a36Sopenharmony_ci .type = "edt-ft5x06", 39462306a36Sopenharmony_ci .addr = 0x38, 39562306a36Sopenharmony_ci .dev_name = "ft5416", 39662306a36Sopenharmony_ci .swnode = &nextbook_ares8_touchscreen_node, 39762306a36Sopenharmony_ci }, 39862306a36Sopenharmony_ci .adapter_path = "\\_SB_.I2C4", 39962306a36Sopenharmony_ci .irq_data = { 40062306a36Sopenharmony_ci .type = X86_ACPI_IRQ_TYPE_GPIOINT, 40162306a36Sopenharmony_ci .chip = "INT33FC:02", 40262306a36Sopenharmony_ci .index = 3, 40362306a36Sopenharmony_ci .trigger = ACPI_EDGE_SENSITIVE, 40462306a36Sopenharmony_ci .polarity = ACPI_ACTIVE_LOW, 40562306a36Sopenharmony_ci }, 40662306a36Sopenharmony_ci }, 40762306a36Sopenharmony_ci}; 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_cistatic struct gpiod_lookup_table * const nextbook_ares8_gpios[] = { 41062306a36Sopenharmony_ci &int3496_reference_gpios, 41162306a36Sopenharmony_ci NULL 41262306a36Sopenharmony_ci}; 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ciconst struct x86_dev_info nextbook_ares8_info __initconst = { 41562306a36Sopenharmony_ci .i2c_client_info = nextbook_ares8_i2c_clients, 41662306a36Sopenharmony_ci .i2c_client_count = ARRAY_SIZE(nextbook_ares8_i2c_clients), 41762306a36Sopenharmony_ci .pdev_info = int3496_pdevs, 41862306a36Sopenharmony_ci .pdev_count = 1, 41962306a36Sopenharmony_ci .gpiod_lookup_tables = nextbook_ares8_gpios, 42062306a36Sopenharmony_ci}; 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci/* Nextbook Ares 8A (CHT) tablets have an Android factory img with everything hardcoded */ 42362306a36Sopenharmony_cistatic const char * const nextbook_ares8a_accel_mount_matrix[] = { 42462306a36Sopenharmony_ci "1", "0", "0", 42562306a36Sopenharmony_ci "0", "-1", "0", 42662306a36Sopenharmony_ci "0", "0", "1" 42762306a36Sopenharmony_ci}; 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_cistatic const struct property_entry nextbook_ares8a_accel_props[] = { 43062306a36Sopenharmony_ci PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", nextbook_ares8a_accel_mount_matrix), 43162306a36Sopenharmony_ci { } 43262306a36Sopenharmony_ci}; 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_cistatic const struct software_node nextbook_ares8a_accel_node = { 43562306a36Sopenharmony_ci .properties = nextbook_ares8a_accel_props, 43662306a36Sopenharmony_ci}; 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_cistatic const struct x86_i2c_client_info nextbook_ares8a_i2c_clients[] __initconst = { 43962306a36Sopenharmony_ci { 44062306a36Sopenharmony_ci /* Freescale MMA8653FC accel */ 44162306a36Sopenharmony_ci .board_info = { 44262306a36Sopenharmony_ci .type = "mma8653", 44362306a36Sopenharmony_ci .addr = 0x1d, 44462306a36Sopenharmony_ci .dev_name = "mma8653", 44562306a36Sopenharmony_ci .swnode = &nextbook_ares8a_accel_node, 44662306a36Sopenharmony_ci }, 44762306a36Sopenharmony_ci .adapter_path = "\\_SB_.PCI0.I2C3", 44862306a36Sopenharmony_ci }, { 44962306a36Sopenharmony_ci /* FT5416DQ9 touchscreen controller */ 45062306a36Sopenharmony_ci .board_info = { 45162306a36Sopenharmony_ci .type = "edt-ft5x06", 45262306a36Sopenharmony_ci .addr = 0x38, 45362306a36Sopenharmony_ci .dev_name = "ft5416", 45462306a36Sopenharmony_ci .swnode = &nextbook_ares8_touchscreen_node, 45562306a36Sopenharmony_ci }, 45662306a36Sopenharmony_ci .adapter_path = "\\_SB_.PCI0.I2C6", 45762306a36Sopenharmony_ci .irq_data = { 45862306a36Sopenharmony_ci .type = X86_ACPI_IRQ_TYPE_GPIOINT, 45962306a36Sopenharmony_ci .chip = "INT33FF:01", 46062306a36Sopenharmony_ci .index = 17, 46162306a36Sopenharmony_ci .trigger = ACPI_EDGE_SENSITIVE, 46262306a36Sopenharmony_ci .polarity = ACPI_ACTIVE_LOW, 46362306a36Sopenharmony_ci }, 46462306a36Sopenharmony_ci }, 46562306a36Sopenharmony_ci}; 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_cistatic struct gpiod_lookup_table nextbook_ares8a_ft5416_gpios = { 46862306a36Sopenharmony_ci .dev_id = "i2c-ft5416", 46962306a36Sopenharmony_ci .table = { 47062306a36Sopenharmony_ci GPIO_LOOKUP("INT33FF:01", 25, "reset", GPIO_ACTIVE_LOW), 47162306a36Sopenharmony_ci { } 47262306a36Sopenharmony_ci }, 47362306a36Sopenharmony_ci}; 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_cistatic struct gpiod_lookup_table * const nextbook_ares8a_gpios[] = { 47662306a36Sopenharmony_ci &nextbook_ares8a_ft5416_gpios, 47762306a36Sopenharmony_ci NULL 47862306a36Sopenharmony_ci}; 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ciconst struct x86_dev_info nextbook_ares8a_info __initconst = { 48162306a36Sopenharmony_ci .i2c_client_info = nextbook_ares8a_i2c_clients, 48262306a36Sopenharmony_ci .i2c_client_count = ARRAY_SIZE(nextbook_ares8a_i2c_clients), 48362306a36Sopenharmony_ci .gpiod_lookup_tables = nextbook_ares8a_gpios, 48462306a36Sopenharmony_ci}; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci/* 48762306a36Sopenharmony_ci * Peaq C1010 48862306a36Sopenharmony_ci * This is a standard Windows tablet, but it has a special Dolby button. 48962306a36Sopenharmony_ci * This button has a WMI interface, but that is broken. Instead of trying to 49062306a36Sopenharmony_ci * use the broken WMI interface, instantiate a gpio_keys device for this. 49162306a36Sopenharmony_ci */ 49262306a36Sopenharmony_cistatic const struct x86_gpio_button peaq_c1010_button __initconst = { 49362306a36Sopenharmony_ci .button = { 49462306a36Sopenharmony_ci .code = KEY_SOUND, 49562306a36Sopenharmony_ci .active_low = true, 49662306a36Sopenharmony_ci .desc = "dolby_key", 49762306a36Sopenharmony_ci .type = EV_KEY, 49862306a36Sopenharmony_ci .wakeup = false, 49962306a36Sopenharmony_ci .debounce_interval = 50, 50062306a36Sopenharmony_ci }, 50162306a36Sopenharmony_ci .chip = "INT33FC:00", 50262306a36Sopenharmony_ci .pin = 3, 50362306a36Sopenharmony_ci}; 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ciconst struct x86_dev_info peaq_c1010_info __initconst = { 50662306a36Sopenharmony_ci .gpio_button = &peaq_c1010_button, 50762306a36Sopenharmony_ci .gpio_button_count = 1, 50862306a36Sopenharmony_ci /* 50962306a36Sopenharmony_ci * Move the ACPI event handler used by the broken WMI interface out of 51062306a36Sopenharmony_ci * the way. This is the only event handler on INT33FC:00. 51162306a36Sopenharmony_ci */ 51262306a36Sopenharmony_ci .invalid_aei_gpiochip = "INT33FC:00", 51362306a36Sopenharmony_ci}; 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci/* 51662306a36Sopenharmony_ci * Whitelabel (sold as various brands) TM800A550L tablets. 51762306a36Sopenharmony_ci * These tablet's DSDT contains a whole bunch of bogus ACPI I2C devices 51862306a36Sopenharmony_ci * (removed through acpi_quirk_skip_i2c_client_enumeration()) and 51962306a36Sopenharmony_ci * the touchscreen fwnode has the wrong GPIOs. 52062306a36Sopenharmony_ci */ 52162306a36Sopenharmony_cistatic const char * const whitelabel_tm800a550l_accel_mount_matrix[] = { 52262306a36Sopenharmony_ci "-1", "0", "0", 52362306a36Sopenharmony_ci "0", "1", "0", 52462306a36Sopenharmony_ci "0", "0", "1" 52562306a36Sopenharmony_ci}; 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_cistatic const struct property_entry whitelabel_tm800a550l_accel_props[] = { 52862306a36Sopenharmony_ci PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", whitelabel_tm800a550l_accel_mount_matrix), 52962306a36Sopenharmony_ci { } 53062306a36Sopenharmony_ci}; 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_cistatic const struct software_node whitelabel_tm800a550l_accel_node = { 53362306a36Sopenharmony_ci .properties = whitelabel_tm800a550l_accel_props, 53462306a36Sopenharmony_ci}; 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_cistatic const struct property_entry whitelabel_tm800a550l_goodix_props[] = { 53762306a36Sopenharmony_ci PROPERTY_ENTRY_STRING("firmware-name", "gt912-tm800a550l.fw"), 53862306a36Sopenharmony_ci PROPERTY_ENTRY_STRING("goodix,config-name", "gt912-tm800a550l.cfg"), 53962306a36Sopenharmony_ci PROPERTY_ENTRY_U32("goodix,main-clk", 54), 54062306a36Sopenharmony_ci { } 54162306a36Sopenharmony_ci}; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_cistatic const struct software_node whitelabel_tm800a550l_goodix_node = { 54462306a36Sopenharmony_ci .properties = whitelabel_tm800a550l_goodix_props, 54562306a36Sopenharmony_ci}; 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_cistatic const struct x86_i2c_client_info whitelabel_tm800a550l_i2c_clients[] __initconst = { 54862306a36Sopenharmony_ci { 54962306a36Sopenharmony_ci /* goodix touchscreen */ 55062306a36Sopenharmony_ci .board_info = { 55162306a36Sopenharmony_ci .type = "GDIX1001:00", 55262306a36Sopenharmony_ci .addr = 0x14, 55362306a36Sopenharmony_ci .dev_name = "goodix_ts", 55462306a36Sopenharmony_ci .swnode = &whitelabel_tm800a550l_goodix_node, 55562306a36Sopenharmony_ci }, 55662306a36Sopenharmony_ci .adapter_path = "\\_SB_.I2C2", 55762306a36Sopenharmony_ci .irq_data = { 55862306a36Sopenharmony_ci .type = X86_ACPI_IRQ_TYPE_APIC, 55962306a36Sopenharmony_ci .index = 0x44, 56062306a36Sopenharmony_ci .trigger = ACPI_EDGE_SENSITIVE, 56162306a36Sopenharmony_ci .polarity = ACPI_ACTIVE_HIGH, 56262306a36Sopenharmony_ci }, 56362306a36Sopenharmony_ci }, { 56462306a36Sopenharmony_ci /* kxcj91008 accel */ 56562306a36Sopenharmony_ci .board_info = { 56662306a36Sopenharmony_ci .type = "kxcj91008", 56762306a36Sopenharmony_ci .addr = 0x0f, 56862306a36Sopenharmony_ci .dev_name = "kxcj91008", 56962306a36Sopenharmony_ci .swnode = &whitelabel_tm800a550l_accel_node, 57062306a36Sopenharmony_ci }, 57162306a36Sopenharmony_ci .adapter_path = "\\_SB_.I2C3", 57262306a36Sopenharmony_ci }, 57362306a36Sopenharmony_ci}; 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_cistatic struct gpiod_lookup_table whitelabel_tm800a550l_goodix_gpios = { 57662306a36Sopenharmony_ci .dev_id = "i2c-goodix_ts", 57762306a36Sopenharmony_ci .table = { 57862306a36Sopenharmony_ci GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH), 57962306a36Sopenharmony_ci GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH), 58062306a36Sopenharmony_ci { } 58162306a36Sopenharmony_ci }, 58262306a36Sopenharmony_ci}; 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_cistatic struct gpiod_lookup_table * const whitelabel_tm800a550l_gpios[] = { 58562306a36Sopenharmony_ci &whitelabel_tm800a550l_goodix_gpios, 58662306a36Sopenharmony_ci NULL 58762306a36Sopenharmony_ci}; 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ciconst struct x86_dev_info whitelabel_tm800a550l_info __initconst = { 59062306a36Sopenharmony_ci .i2c_client_info = whitelabel_tm800a550l_i2c_clients, 59162306a36Sopenharmony_ci .i2c_client_count = ARRAY_SIZE(whitelabel_tm800a550l_i2c_clients), 59262306a36Sopenharmony_ci .gpiod_lookup_tables = whitelabel_tm800a550l_gpios, 59362306a36Sopenharmony_ci}; 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ci/* 59662306a36Sopenharmony_ci * If the EFI bootloader is not Xiaomi's own signed Android loader, then the 59762306a36Sopenharmony_ci * Xiaomi Mi Pad 2 X86 tablet sets OSID in the DSDT to 1 (Windows), causing 59862306a36Sopenharmony_ci * a bunch of devices to be hidden. 59962306a36Sopenharmony_ci * 60062306a36Sopenharmony_ci * This takes care of instantiating the hidden devices manually. 60162306a36Sopenharmony_ci */ 60262306a36Sopenharmony_cistatic const struct x86_i2c_client_info xiaomi_mipad2_i2c_clients[] __initconst = { 60362306a36Sopenharmony_ci { 60462306a36Sopenharmony_ci /* BQ27520 fuel-gauge */ 60562306a36Sopenharmony_ci .board_info = { 60662306a36Sopenharmony_ci .type = "bq27520", 60762306a36Sopenharmony_ci .addr = 0x55, 60862306a36Sopenharmony_ci .dev_name = "bq27520", 60962306a36Sopenharmony_ci .swnode = &fg_bq25890_supply_node, 61062306a36Sopenharmony_ci }, 61162306a36Sopenharmony_ci .adapter_path = "\\_SB_.PCI0.I2C1", 61262306a36Sopenharmony_ci }, { 61362306a36Sopenharmony_ci /* KTD2026 RGB notification LED controller */ 61462306a36Sopenharmony_ci .board_info = { 61562306a36Sopenharmony_ci .type = "ktd2026", 61662306a36Sopenharmony_ci .addr = 0x30, 61762306a36Sopenharmony_ci .dev_name = "ktd2026", 61862306a36Sopenharmony_ci }, 61962306a36Sopenharmony_ci .adapter_path = "\\_SB_.PCI0.I2C3", 62062306a36Sopenharmony_ci }, 62162306a36Sopenharmony_ci}; 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ciconst struct x86_dev_info xiaomi_mipad2_info __initconst = { 62462306a36Sopenharmony_ci .i2c_client_info = xiaomi_mipad2_i2c_clients, 62562306a36Sopenharmony_ci .i2c_client_count = ARRAY_SIZE(xiaomi_mipad2_i2c_clients), 62662306a36Sopenharmony_ci}; 627