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