1cc183ad4SHans de Goede // SPDX-License-Identifier: GPL-2.0-or-later
2cc183ad4SHans de Goede /*
3cc183ad4SHans de Goede  * DMI based code to deal with broken DSDTs on X86 tablets which ship with
4cc183ad4SHans de Goede  * Android as (part of) the factory image. The factory kernels shipped on these
5cc183ad4SHans de Goede  * devices typically have a bunch of things hardcoded, rather than specified
6cc183ad4SHans de Goede  * in their DSDT.
7cc183ad4SHans de Goede  *
8cc183ad4SHans de Goede  * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com>
9cc183ad4SHans de Goede  */
10cc183ad4SHans de Goede 
11cc183ad4SHans de Goede #include <linux/acpi.h>
12cc183ad4SHans de Goede #include <linux/gpio/machine.h>
13cc183ad4SHans de Goede #include <linux/input.h>
14cc183ad4SHans de Goede #include <linux/platform_device.h>
15cc183ad4SHans de Goede 
16cc183ad4SHans de Goede #include "shared-psy-info.h"
17cc183ad4SHans de Goede #include "x86-android-tablets.h"
18cc183ad4SHans de Goede 
19cc183ad4SHans de Goede /* Acer Iconia One 7 B1-750 has an Android factory img with everything hardcoded */
20cc183ad4SHans de Goede static const char * const acer_b1_750_mount_matrix[] = {
21cc183ad4SHans de Goede 	"-1", "0", "0",
22cc183ad4SHans de Goede 	"0", "1", "0",
23cc183ad4SHans de Goede 	"0", "0", "1"
24cc183ad4SHans de Goede };
25cc183ad4SHans de Goede 
26cc183ad4SHans de Goede static const struct property_entry acer_b1_750_bma250e_props[] = {
27cc183ad4SHans de Goede 	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", acer_b1_750_mount_matrix),
28cc183ad4SHans de Goede 	{ }
29cc183ad4SHans de Goede };
30cc183ad4SHans de Goede 
31cc183ad4SHans de Goede static const struct software_node acer_b1_750_bma250e_node = {
32cc183ad4SHans de Goede 	.properties = acer_b1_750_bma250e_props,
33cc183ad4SHans de Goede };
34cc183ad4SHans de Goede 
35cc183ad4SHans de Goede static const struct x86_i2c_client_info acer_b1_750_i2c_clients[] __initconst = {
36cc183ad4SHans de Goede 	{
37cc183ad4SHans de Goede 		/* Novatek NVT-ts touchscreen */
38cc183ad4SHans de Goede 		.board_info = {
39cc183ad4SHans de Goede 			.type = "NVT-ts",
40cc183ad4SHans de Goede 			.addr = 0x34,
41cc183ad4SHans de Goede 			.dev_name = "NVT-ts",
42cc183ad4SHans de Goede 		},
43cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.I2C4",
44cc183ad4SHans de Goede 		.irq_data = {
45cc183ad4SHans de Goede 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
46cc183ad4SHans de Goede 			.chip = "INT33FC:02",
47cc183ad4SHans de Goede 			.index = 3,
48cc183ad4SHans de Goede 			.trigger = ACPI_EDGE_SENSITIVE,
49cc183ad4SHans de Goede 			.polarity = ACPI_ACTIVE_LOW,
50cc183ad4SHans de Goede 		},
51cc183ad4SHans de Goede 	}, {
52cc183ad4SHans de Goede 		/* BMA250E accelerometer */
53cc183ad4SHans de Goede 		.board_info = {
54cc183ad4SHans de Goede 			.type = "bma250e",
55cc183ad4SHans de Goede 			.addr = 0x18,
56cc183ad4SHans de Goede 			.swnode = &acer_b1_750_bma250e_node,
57cc183ad4SHans de Goede 		},
58cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.I2C3",
59cc183ad4SHans de Goede 		.irq_data = {
60cc183ad4SHans de Goede 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
61cc183ad4SHans de Goede 			.chip = "INT33FC:02",
62cc183ad4SHans de Goede 			.index = 25,
63cc183ad4SHans de Goede 			.trigger = ACPI_LEVEL_SENSITIVE,
64cc183ad4SHans de Goede 			.polarity = ACPI_ACTIVE_HIGH,
65cc183ad4SHans de Goede 		},
66cc183ad4SHans de Goede 	},
67cc183ad4SHans de Goede };
68cc183ad4SHans de Goede 
69*bf9e4b5fSHans de Goede static struct gpiod_lookup_table acer_b1_750_nvt_ts_gpios = {
70cc183ad4SHans de Goede 	.dev_id = "i2c-NVT-ts",
71cc183ad4SHans de Goede 	.table = {
72cc183ad4SHans de Goede 		GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_LOW),
73cc183ad4SHans de Goede 		{ }
74cc183ad4SHans de Goede 	},
75cc183ad4SHans de Goede };
76cc183ad4SHans de Goede 
77cc183ad4SHans de Goede static struct gpiod_lookup_table * const acer_b1_750_gpios[] = {
78*bf9e4b5fSHans de Goede 	&acer_b1_750_nvt_ts_gpios,
79cc183ad4SHans de Goede 	&int3496_reference_gpios,
80cc183ad4SHans de Goede 	NULL
81cc183ad4SHans de Goede };
82cc183ad4SHans de Goede 
83cc183ad4SHans de Goede const struct x86_dev_info acer_b1_750_info __initconst = {
84cc183ad4SHans de Goede 	.i2c_client_info = acer_b1_750_i2c_clients,
85cc183ad4SHans de Goede 	.i2c_client_count = ARRAY_SIZE(acer_b1_750_i2c_clients),
86cc183ad4SHans de Goede 	.pdev_info = int3496_pdevs,
87cc183ad4SHans de Goede 	.pdev_count = 1,
88cc183ad4SHans de Goede 	.gpiod_lookup_tables = acer_b1_750_gpios,
89cc183ad4SHans de Goede };
90cc183ad4SHans de Goede 
91cc183ad4SHans de Goede /*
92cc183ad4SHans de Goede  * Advantech MICA-071
93cc183ad4SHans de Goede  * This is a standard Windows tablet, but it has an extra "quick launch" button
94cc183ad4SHans de Goede  * which is not described in the ACPI tables in anyway.
95cc183ad4SHans de Goede  * Use the x86-android-tablets infra to create a gpio-button device for this.
96cc183ad4SHans de Goede  */
976dc6c0c1SHans de Goede static const struct x86_gpio_button advantech_mica_071_button __initconst = {
98e2200d3fSHans de Goede 	.button = {
99cc183ad4SHans de Goede 		.code = KEY_PROG1,
100cc183ad4SHans de Goede 		.active_low = true,
101cc183ad4SHans de Goede 		.desc = "prog1_key",
102cc183ad4SHans de Goede 		.type = EV_KEY,
103cc183ad4SHans de Goede 		.wakeup = false,
104cc183ad4SHans de Goede 		.debounce_interval = 50,
105cc183ad4SHans de Goede 	},
106e2200d3fSHans de Goede 	.chip = "INT33FC:00",
107e2200d3fSHans de Goede 	.pin = 2,
108cc183ad4SHans de Goede };
109cc183ad4SHans de Goede 
110cc183ad4SHans de Goede const struct x86_dev_info advantech_mica_071_info __initconst = {
111e2200d3fSHans de Goede 	.gpio_button = &advantech_mica_071_button,
1126dc6c0c1SHans de Goede 	.gpio_button_count = 1,
113cc183ad4SHans de Goede };
114cc183ad4SHans de Goede 
115cc183ad4SHans de Goede /*
116cc183ad4SHans de Goede  * When booted with the BIOS set to Android mode the Chuwi Hi8 (CWI509) DSDT
117cc183ad4SHans de Goede  * contains a whole bunch of bogus ACPI I2C devices and is missing entries
118cc183ad4SHans de Goede  * for the touchscreen and the accelerometer.
119cc183ad4SHans de Goede  */
120cc183ad4SHans de Goede static const struct property_entry chuwi_hi8_gsl1680_props[] = {
121cc183ad4SHans de Goede 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
122cc183ad4SHans de Goede 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
123cc183ad4SHans de Goede 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
124cc183ad4SHans de Goede 	PROPERTY_ENTRY_BOOL("silead,home-button"),
125cc183ad4SHans de Goede 	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi8.fw"),
126cc183ad4SHans de Goede 	{ }
127cc183ad4SHans de Goede };
128cc183ad4SHans de Goede 
129cc183ad4SHans de Goede static const struct software_node chuwi_hi8_gsl1680_node = {
130cc183ad4SHans de Goede 	.properties = chuwi_hi8_gsl1680_props,
131cc183ad4SHans de Goede };
132cc183ad4SHans de Goede 
133cc183ad4SHans de Goede static const char * const chuwi_hi8_mount_matrix[] = {
134cc183ad4SHans de Goede 	"1", "0", "0",
135cc183ad4SHans de Goede 	"0", "-1", "0",
136cc183ad4SHans de Goede 	"0", "0", "1"
137cc183ad4SHans de Goede };
138cc183ad4SHans de Goede 
139cc183ad4SHans de Goede static const struct property_entry chuwi_hi8_bma250e_props[] = {
140cc183ad4SHans de Goede 	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", chuwi_hi8_mount_matrix),
141cc183ad4SHans de Goede 	{ }
142cc183ad4SHans de Goede };
143cc183ad4SHans de Goede 
144cc183ad4SHans de Goede static const struct software_node chuwi_hi8_bma250e_node = {
145cc183ad4SHans de Goede 	.properties = chuwi_hi8_bma250e_props,
146cc183ad4SHans de Goede };
147cc183ad4SHans de Goede 
148cc183ad4SHans de Goede static const struct x86_i2c_client_info chuwi_hi8_i2c_clients[] __initconst = {
149cc183ad4SHans de Goede 	{
150cc183ad4SHans de Goede 		/* Silead touchscreen */
151cc183ad4SHans de Goede 		.board_info = {
152cc183ad4SHans de Goede 			.type = "gsl1680",
153cc183ad4SHans de Goede 			.addr = 0x40,
154cc183ad4SHans de Goede 			.swnode = &chuwi_hi8_gsl1680_node,
155cc183ad4SHans de Goede 		},
156cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.I2C4",
157cc183ad4SHans de Goede 		.irq_data = {
158cc183ad4SHans de Goede 			.type = X86_ACPI_IRQ_TYPE_APIC,
159cc183ad4SHans de Goede 			.index = 0x44,
160cc183ad4SHans de Goede 			.trigger = ACPI_EDGE_SENSITIVE,
161cc183ad4SHans de Goede 			.polarity = ACPI_ACTIVE_HIGH,
162cc183ad4SHans de Goede 		},
163cc183ad4SHans de Goede 	}, {
164cc183ad4SHans de Goede 		/* BMA250E accelerometer */
165cc183ad4SHans de Goede 		.board_info = {
166cc183ad4SHans de Goede 			.type = "bma250e",
167cc183ad4SHans de Goede 			.addr = 0x18,
168cc183ad4SHans de Goede 			.swnode = &chuwi_hi8_bma250e_node,
169cc183ad4SHans de Goede 		},
170cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.I2C3",
171cc183ad4SHans de Goede 		.irq_data = {
172cc183ad4SHans de Goede 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
173cc183ad4SHans de Goede 			.chip = "INT33FC:02",
174cc183ad4SHans de Goede 			.index = 23,
175cc183ad4SHans de Goede 			.trigger = ACPI_LEVEL_SENSITIVE,
176cc183ad4SHans de Goede 			.polarity = ACPI_ACTIVE_HIGH,
177cc183ad4SHans de Goede 		},
178cc183ad4SHans de Goede 	},
179cc183ad4SHans de Goede };
180cc183ad4SHans de Goede 
chuwi_hi8_init(void)181cc183ad4SHans de Goede static int __init chuwi_hi8_init(void)
182cc183ad4SHans de Goede {
183cc183ad4SHans de Goede 	/*
184cc183ad4SHans de Goede 	 * Avoid the acpi_unregister_gsi() call in x86_acpi_irq_helper_get()
185cc183ad4SHans de Goede 	 * breaking the touchscreen + logging various errors when the Windows
186cc183ad4SHans de Goede 	 * BIOS is used.
187cc183ad4SHans de Goede 	 */
188cc183ad4SHans de Goede 	if (acpi_dev_present("MSSL0001", NULL, 1))
189cc183ad4SHans de Goede 		return -ENODEV;
190cc183ad4SHans de Goede 
191cc183ad4SHans de Goede 	return 0;
192cc183ad4SHans de Goede }
193cc183ad4SHans de Goede 
194cc183ad4SHans de Goede const struct x86_dev_info chuwi_hi8_info __initconst = {
195cc183ad4SHans de Goede 	.i2c_client_info = chuwi_hi8_i2c_clients,
196cc183ad4SHans de Goede 	.i2c_client_count = ARRAY_SIZE(chuwi_hi8_i2c_clients),
197cc183ad4SHans de Goede 	.init = chuwi_hi8_init,
198cc183ad4SHans de Goede };
199cc183ad4SHans de Goede 
20024f7b9a0SHans de Goede /*
20124f7b9a0SHans de Goede  * Cyberbook T116 Android version
20224f7b9a0SHans de Goede  * This comes in both Windows and Android versions and even on Android
20324f7b9a0SHans de Goede  * the DSDT is mostly sane. This tablet has 2 extra general purpose buttons
20424f7b9a0SHans de Goede  * in the button row with the power + volume-buttons labeled P and F.
20524f7b9a0SHans de Goede  * Use the x86-android-tablets infra to create a gpio-button device for these.
20624f7b9a0SHans de Goede  */
20724f7b9a0SHans de Goede static const struct x86_gpio_button cyberbook_t116_buttons[] __initconst = {
20824f7b9a0SHans de Goede 	{
20924f7b9a0SHans de Goede 		.button = {
21024f7b9a0SHans de Goede 			.code = KEY_PROG1,
21124f7b9a0SHans de Goede 			.active_low = true,
21224f7b9a0SHans de Goede 			.desc = "prog1_key",
21324f7b9a0SHans de Goede 			.type = EV_KEY,
21424f7b9a0SHans de Goede 			.wakeup = false,
21524f7b9a0SHans de Goede 			.debounce_interval = 50,
21624f7b9a0SHans de Goede 		},
21724f7b9a0SHans de Goede 		.chip = "INT33FF:00",
21824f7b9a0SHans de Goede 		.pin = 30,
21924f7b9a0SHans de Goede 	},
22024f7b9a0SHans de Goede 	{
22124f7b9a0SHans de Goede 		.button = {
22224f7b9a0SHans de Goede 			.code = KEY_PROG2,
22324f7b9a0SHans de Goede 			.active_low = true,
22424f7b9a0SHans de Goede 			.desc = "prog2_key",
22524f7b9a0SHans de Goede 			.type = EV_KEY,
22624f7b9a0SHans de Goede 			.wakeup = false,
22724f7b9a0SHans de Goede 			.debounce_interval = 50,
22824f7b9a0SHans de Goede 		},
22924f7b9a0SHans de Goede 		.chip = "INT33FF:03",
23024f7b9a0SHans de Goede 		.pin = 48,
23124f7b9a0SHans de Goede 	},
23224f7b9a0SHans de Goede };
23324f7b9a0SHans de Goede 
23424f7b9a0SHans de Goede const struct x86_dev_info cyberbook_t116_info __initconst = {
23524f7b9a0SHans de Goede 	.gpio_button = cyberbook_t116_buttons,
23624f7b9a0SHans de Goede 	.gpio_button_count = ARRAY_SIZE(cyberbook_t116_buttons),
23724f7b9a0SHans de Goede };
23824f7b9a0SHans de Goede 
239cc183ad4SHans de Goede #define CZC_EC_EXTRA_PORT	0x68
240cc183ad4SHans de Goede #define CZC_EC_ANDROID_KEYS	0x63
241cc183ad4SHans de Goede 
czc_p10t_init(void)242cc183ad4SHans de Goede static int __init czc_p10t_init(void)
243cc183ad4SHans de Goede {
244cc183ad4SHans de Goede 	/*
245cc183ad4SHans de Goede 	 * The device boots up in "Windows 7" mode, when the home button sends a
246cc183ad4SHans de Goede 	 * Windows specific key sequence (Left Meta + D) and the second button
247cc183ad4SHans de Goede 	 * sends an unknown one while also toggling the Radio Kill Switch.
248cc183ad4SHans de Goede 	 * This is a surprising behavior when the second button is labeled "Back".
249cc183ad4SHans de Goede 	 *
250cc183ad4SHans de Goede 	 * The vendor-supplied Android-x86 build switches the device to a "Android"
251cc183ad4SHans de Goede 	 * mode by writing value 0x63 to the I/O port 0x68. This just seems to just
252cc183ad4SHans de Goede 	 * set bit 6 on address 0x96 in the EC region; switching the bit directly
253cc183ad4SHans de Goede 	 * seems to achieve the same result. It uses a "p10t_switcher" to do the
254cc183ad4SHans de Goede 	 * job. It doesn't seem to be able to do anything else, and no other use
255cc183ad4SHans de Goede 	 * of the port 0x68 is known.
256cc183ad4SHans de Goede 	 *
257cc183ad4SHans de Goede 	 * In the Android mode, the home button sends just a single scancode,
258cc183ad4SHans de Goede 	 * which can be handled in Linux userspace more reasonably and the back
259cc183ad4SHans de Goede 	 * button only sends a scancode without toggling the kill switch.
260cc183ad4SHans de Goede 	 * The scancode can then be mapped either to Back or RF Kill functionality
261cc183ad4SHans de Goede 	 * in userspace, depending on how the button is labeled on that particular
262cc183ad4SHans de Goede 	 * model.
263cc183ad4SHans de Goede 	 */
264cc183ad4SHans de Goede 	outb(CZC_EC_ANDROID_KEYS, CZC_EC_EXTRA_PORT);
265cc183ad4SHans de Goede 	return 0;
266cc183ad4SHans de Goede }
267cc183ad4SHans de Goede 
268cc183ad4SHans de Goede const struct x86_dev_info czc_p10t __initconst = {
269cc183ad4SHans de Goede 	.init = czc_p10t_init,
270cc183ad4SHans de Goede };
271cc183ad4SHans de Goede 
272cc183ad4SHans de Goede /* Medion Lifetab S10346 tablets have an Android factory img with everything hardcoded */
273cc183ad4SHans de Goede static const char * const medion_lifetab_s10346_accel_mount_matrix[] = {
274cc183ad4SHans de Goede 	"0", "1", "0",
275cc183ad4SHans de Goede 	"1", "0", "0",
276cc183ad4SHans de Goede 	"0", "0", "1"
277cc183ad4SHans de Goede };
278cc183ad4SHans de Goede 
279cc183ad4SHans de Goede static const struct property_entry medion_lifetab_s10346_accel_props[] = {
280cc183ad4SHans de Goede 	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", medion_lifetab_s10346_accel_mount_matrix),
281cc183ad4SHans de Goede 	{ }
282cc183ad4SHans de Goede };
283cc183ad4SHans de Goede 
284cc183ad4SHans de Goede static const struct software_node medion_lifetab_s10346_accel_node = {
285cc183ad4SHans de Goede 	.properties = medion_lifetab_s10346_accel_props,
286cc183ad4SHans de Goede };
287cc183ad4SHans de Goede 
288cc183ad4SHans de Goede /* Note the LCD panel is mounted upside down, this is correctly indicated in the VBT */
289cc183ad4SHans de Goede static const struct property_entry medion_lifetab_s10346_touchscreen_props[] = {
290cc183ad4SHans de Goede 	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
291cc183ad4SHans de Goede 	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
292cc183ad4SHans de Goede 	{ }
293cc183ad4SHans de Goede };
294cc183ad4SHans de Goede 
295cc183ad4SHans de Goede static const struct software_node medion_lifetab_s10346_touchscreen_node = {
296cc183ad4SHans de Goede 	.properties = medion_lifetab_s10346_touchscreen_props,
297cc183ad4SHans de Goede };
298cc183ad4SHans de Goede 
299cc183ad4SHans de Goede static const struct x86_i2c_client_info medion_lifetab_s10346_i2c_clients[] __initconst = {
300cc183ad4SHans de Goede 	{
301cc183ad4SHans de Goede 		/* kxtj21009 accel */
302cc183ad4SHans de Goede 		.board_info = {
303cc183ad4SHans de Goede 			.type = "kxtj21009",
304cc183ad4SHans de Goede 			.addr = 0x0f,
305cc183ad4SHans de Goede 			.dev_name = "kxtj21009",
306cc183ad4SHans de Goede 			.swnode = &medion_lifetab_s10346_accel_node,
307cc183ad4SHans de Goede 		},
308cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.I2C3",
309cc183ad4SHans de Goede 		.irq_data = {
310cc183ad4SHans de Goede 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
311cc183ad4SHans de Goede 			.chip = "INT33FC:02",
312cc183ad4SHans de Goede 			.index = 23,
313cc183ad4SHans de Goede 			.trigger = ACPI_EDGE_SENSITIVE,
314cc183ad4SHans de Goede 			.polarity = ACPI_ACTIVE_HIGH,
315cc183ad4SHans de Goede 		},
316cc183ad4SHans de Goede 	}, {
317cc183ad4SHans de Goede 		/* goodix touchscreen */
318cc183ad4SHans de Goede 		.board_info = {
319cc183ad4SHans de Goede 			.type = "GDIX1001:00",
320cc183ad4SHans de Goede 			.addr = 0x14,
321cc183ad4SHans de Goede 			.dev_name = "goodix_ts",
322cc183ad4SHans de Goede 			.swnode = &medion_lifetab_s10346_touchscreen_node,
323cc183ad4SHans de Goede 		},
324cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.I2C4",
325cc183ad4SHans de Goede 		.irq_data = {
326cc183ad4SHans de Goede 			.type = X86_ACPI_IRQ_TYPE_APIC,
327cc183ad4SHans de Goede 			.index = 0x44,
328cc183ad4SHans de Goede 			.trigger = ACPI_EDGE_SENSITIVE,
329cc183ad4SHans de Goede 			.polarity = ACPI_ACTIVE_LOW,
330cc183ad4SHans de Goede 		},
331cc183ad4SHans de Goede 	},
332cc183ad4SHans de Goede };
333cc183ad4SHans de Goede 
334cc183ad4SHans de Goede static struct gpiod_lookup_table medion_lifetab_s10346_goodix_gpios = {
335cc183ad4SHans de Goede 	.dev_id = "i2c-goodix_ts",
336cc183ad4SHans de Goede 	.table = {
337cc183ad4SHans de Goede 		GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH),
338cc183ad4SHans de Goede 		GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH),
339cc183ad4SHans de Goede 		{ }
340cc183ad4SHans de Goede 	},
341cc183ad4SHans de Goede };
342cc183ad4SHans de Goede 
343cc183ad4SHans de Goede static struct gpiod_lookup_table * const medion_lifetab_s10346_gpios[] = {
344cc183ad4SHans de Goede 	&medion_lifetab_s10346_goodix_gpios,
345cc183ad4SHans de Goede 	NULL
346cc183ad4SHans de Goede };
347cc183ad4SHans de Goede 
348cc183ad4SHans de Goede const struct x86_dev_info medion_lifetab_s10346_info __initconst = {
349cc183ad4SHans de Goede 	.i2c_client_info = medion_lifetab_s10346_i2c_clients,
350cc183ad4SHans de Goede 	.i2c_client_count = ARRAY_SIZE(medion_lifetab_s10346_i2c_clients),
351cc183ad4SHans de Goede 	.gpiod_lookup_tables = medion_lifetab_s10346_gpios,
352cc183ad4SHans de Goede };
353cc183ad4SHans de Goede 
354c9105066SHans de Goede /* Nextbook Ares 8 (BYT) tablets have an Android factory img with everything hardcoded */
355cc183ad4SHans de Goede static const char * const nextbook_ares8_accel_mount_matrix[] = {
356cc183ad4SHans de Goede 	"0", "-1", "0",
357cc183ad4SHans de Goede 	"-1", "0", "0",
358cc183ad4SHans de Goede 	"0", "0", "1"
359cc183ad4SHans de Goede };
360cc183ad4SHans de Goede 
361cc183ad4SHans de Goede static const struct property_entry nextbook_ares8_accel_props[] = {
362cc183ad4SHans de Goede 	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", nextbook_ares8_accel_mount_matrix),
363cc183ad4SHans de Goede 	{ }
364cc183ad4SHans de Goede };
365cc183ad4SHans de Goede 
366cc183ad4SHans de Goede static const struct software_node nextbook_ares8_accel_node = {
367cc183ad4SHans de Goede 	.properties = nextbook_ares8_accel_props,
368cc183ad4SHans de Goede };
369cc183ad4SHans de Goede 
370cc183ad4SHans de Goede static const struct property_entry nextbook_ares8_touchscreen_props[] = {
371cc183ad4SHans de Goede 	PROPERTY_ENTRY_U32("touchscreen-size-x", 800),
372cc183ad4SHans de Goede 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
373cc183ad4SHans de Goede 	{ }
374cc183ad4SHans de Goede };
375cc183ad4SHans de Goede 
376cc183ad4SHans de Goede static const struct software_node nextbook_ares8_touchscreen_node = {
377cc183ad4SHans de Goede 	.properties = nextbook_ares8_touchscreen_props,
378cc183ad4SHans de Goede };
379cc183ad4SHans de Goede 
380cc183ad4SHans de Goede static const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst = {
381cc183ad4SHans de Goede 	{
382cc183ad4SHans de Goede 		/* Freescale MMA8653FC accel */
383cc183ad4SHans de Goede 		.board_info = {
384cc183ad4SHans de Goede 			.type = "mma8653",
385cc183ad4SHans de Goede 			.addr = 0x1d,
386cc183ad4SHans de Goede 			.dev_name = "mma8653",
387cc183ad4SHans de Goede 			.swnode = &nextbook_ares8_accel_node,
388cc183ad4SHans de Goede 		},
389cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.I2C3",
390cc183ad4SHans de Goede 	}, {
391cc183ad4SHans de Goede 		/* FT5416DQ9 touchscreen controller */
392cc183ad4SHans de Goede 		.board_info = {
393cc183ad4SHans de Goede 			.type = "edt-ft5x06",
394cc183ad4SHans de Goede 			.addr = 0x38,
395cc183ad4SHans de Goede 			.dev_name = "ft5416",
396cc183ad4SHans de Goede 			.swnode = &nextbook_ares8_touchscreen_node,
397cc183ad4SHans de Goede 		},
398cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.I2C4",
399cc183ad4SHans de Goede 		.irq_data = {
400cc183ad4SHans de Goede 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
401cc183ad4SHans de Goede 			.chip = "INT33FC:02",
402cc183ad4SHans de Goede 			.index = 3,
403cc183ad4SHans de Goede 			.trigger = ACPI_EDGE_SENSITIVE,
404cc183ad4SHans de Goede 			.polarity = ACPI_ACTIVE_LOW,
405cc183ad4SHans de Goede 		},
406cc183ad4SHans de Goede 	},
407cc183ad4SHans de Goede };
408cc183ad4SHans de Goede 
409cc183ad4SHans de Goede static struct gpiod_lookup_table * const nextbook_ares8_gpios[] = {
410cc183ad4SHans de Goede 	&int3496_reference_gpios,
411cc183ad4SHans de Goede 	NULL
412cc183ad4SHans de Goede };
413cc183ad4SHans de Goede 
414cc183ad4SHans de Goede const struct x86_dev_info nextbook_ares8_info __initconst = {
415cc183ad4SHans de Goede 	.i2c_client_info = nextbook_ares8_i2c_clients,
416cc183ad4SHans de Goede 	.i2c_client_count = ARRAY_SIZE(nextbook_ares8_i2c_clients),
417cc183ad4SHans de Goede 	.pdev_info = int3496_pdevs,
418cc183ad4SHans de Goede 	.pdev_count = 1,
419cc183ad4SHans de Goede 	.gpiod_lookup_tables = nextbook_ares8_gpios,
420cc183ad4SHans de Goede };
421cc183ad4SHans de Goede 
422c9105066SHans de Goede /* Nextbook Ares 8A (CHT) tablets have an Android factory img with everything hardcoded */
423c9105066SHans de Goede static const char * const nextbook_ares8a_accel_mount_matrix[] = {
424c9105066SHans de Goede 	"1", "0", "0",
425c9105066SHans de Goede 	"0", "-1", "0",
426c9105066SHans de Goede 	"0", "0", "1"
427c9105066SHans de Goede };
428c9105066SHans de Goede 
429c9105066SHans de Goede static const struct property_entry nextbook_ares8a_accel_props[] = {
430c9105066SHans de Goede 	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", nextbook_ares8a_accel_mount_matrix),
431c9105066SHans de Goede 	{ }
432c9105066SHans de Goede };
433c9105066SHans de Goede 
434c9105066SHans de Goede static const struct software_node nextbook_ares8a_accel_node = {
435c9105066SHans de Goede 	.properties = nextbook_ares8a_accel_props,
436c9105066SHans de Goede };
437c9105066SHans de Goede 
438c9105066SHans de Goede static const struct x86_i2c_client_info nextbook_ares8a_i2c_clients[] __initconst = {
439c9105066SHans de Goede 	{
440c9105066SHans de Goede 		/* Freescale MMA8653FC accel */
441c9105066SHans de Goede 		.board_info = {
442c9105066SHans de Goede 			.type = "mma8653",
443c9105066SHans de Goede 			.addr = 0x1d,
444c9105066SHans de Goede 			.dev_name = "mma8653",
445c9105066SHans de Goede 			.swnode = &nextbook_ares8a_accel_node,
446c9105066SHans de Goede 		},
447c9105066SHans de Goede 		.adapter_path = "\\_SB_.PCI0.I2C3",
448c9105066SHans de Goede 	}, {
449c9105066SHans de Goede 		/* FT5416DQ9 touchscreen controller */
450c9105066SHans de Goede 		.board_info = {
451c9105066SHans de Goede 			.type = "edt-ft5x06",
452c9105066SHans de Goede 			.addr = 0x38,
453c9105066SHans de Goede 			.dev_name = "ft5416",
454c9105066SHans de Goede 			.swnode = &nextbook_ares8_touchscreen_node,
455c9105066SHans de Goede 		},
456c9105066SHans de Goede 		.adapter_path = "\\_SB_.PCI0.I2C6",
457c9105066SHans de Goede 		.irq_data = {
458c9105066SHans de Goede 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
459c9105066SHans de Goede 			.chip = "INT33FF:01",
460c9105066SHans de Goede 			.index = 17,
461c9105066SHans de Goede 			.trigger = ACPI_EDGE_SENSITIVE,
462c9105066SHans de Goede 			.polarity = ACPI_ACTIVE_LOW,
463c9105066SHans de Goede 		},
464c9105066SHans de Goede 	},
465c9105066SHans de Goede };
466c9105066SHans de Goede 
467c9105066SHans de Goede static struct gpiod_lookup_table nextbook_ares8a_ft5416_gpios = {
468c9105066SHans de Goede 	.dev_id = "i2c-ft5416",
469c9105066SHans de Goede 	.table = {
470c9105066SHans de Goede 		GPIO_LOOKUP("INT33FF:01", 25, "reset", GPIO_ACTIVE_LOW),
471c9105066SHans de Goede 		{ }
472c9105066SHans de Goede 	},
473c9105066SHans de Goede };
474c9105066SHans de Goede 
475c9105066SHans de Goede static struct gpiod_lookup_table * const nextbook_ares8a_gpios[] = {
476c9105066SHans de Goede 	&nextbook_ares8a_ft5416_gpios,
477c9105066SHans de Goede 	NULL
478c9105066SHans de Goede };
479c9105066SHans de Goede 
480c9105066SHans de Goede const struct x86_dev_info nextbook_ares8a_info __initconst = {
481c9105066SHans de Goede 	.i2c_client_info = nextbook_ares8a_i2c_clients,
482c9105066SHans de Goede 	.i2c_client_count = ARRAY_SIZE(nextbook_ares8a_i2c_clients),
483c9105066SHans de Goede 	.gpiod_lookup_tables = nextbook_ares8a_gpios,
484c9105066SHans de Goede };
485c9105066SHans de Goede 
486cc183ad4SHans de Goede /*
487772cbba5SHans de Goede  * Peaq C1010
488772cbba5SHans de Goede  * This is a standard Windows tablet, but it has a special Dolby button.
489772cbba5SHans de Goede  * This button has a WMI interface, but that is broken. Instead of trying to
490772cbba5SHans de Goede  * use the broken WMI interface, instantiate a gpio_keys device for this.
491772cbba5SHans de Goede  */
4926dc6c0c1SHans de Goede static const struct x86_gpio_button peaq_c1010_button __initconst = {
493772cbba5SHans de Goede 	.button = {
494772cbba5SHans de Goede 		.code = KEY_SOUND,
495772cbba5SHans de Goede 		.active_low = true,
496772cbba5SHans de Goede 		.desc = "dolby_key",
497772cbba5SHans de Goede 		.type = EV_KEY,
498772cbba5SHans de Goede 		.wakeup = false,
499772cbba5SHans de Goede 		.debounce_interval = 50,
500772cbba5SHans de Goede 	},
501772cbba5SHans de Goede 	.chip = "INT33FC:00",
502772cbba5SHans de Goede 	.pin = 3,
503772cbba5SHans de Goede };
504772cbba5SHans de Goede 
505772cbba5SHans de Goede const struct x86_dev_info peaq_c1010_info __initconst = {
506772cbba5SHans de Goede 	.gpio_button = &peaq_c1010_button,
5076dc6c0c1SHans de Goede 	.gpio_button_count = 1,
508772cbba5SHans de Goede 	/*
509772cbba5SHans de Goede 	 * Move the ACPI event handler used by the broken WMI interface out of
510772cbba5SHans de Goede 	 * the way. This is the only event handler on INT33FC:00.
511772cbba5SHans de Goede 	 */
512772cbba5SHans de Goede 	.invalid_aei_gpiochip = "INT33FC:00",
513772cbba5SHans de Goede };
514772cbba5SHans de Goede 
515772cbba5SHans de Goede /*
516cc183ad4SHans de Goede  * Whitelabel (sold as various brands) TM800A550L tablets.
517cc183ad4SHans de Goede  * These tablet's DSDT contains a whole bunch of bogus ACPI I2C devices
518cc183ad4SHans de Goede  * (removed through acpi_quirk_skip_i2c_client_enumeration()) and
519cc183ad4SHans de Goede  * the touchscreen fwnode has the wrong GPIOs.
520cc183ad4SHans de Goede  */
521cc183ad4SHans de Goede static const char * const whitelabel_tm800a550l_accel_mount_matrix[] = {
522cc183ad4SHans de Goede 	"-1", "0", "0",
523cc183ad4SHans de Goede 	"0", "1", "0",
524cc183ad4SHans de Goede 	"0", "0", "1"
525cc183ad4SHans de Goede };
526cc183ad4SHans de Goede 
527cc183ad4SHans de Goede static const struct property_entry whitelabel_tm800a550l_accel_props[] = {
528cc183ad4SHans de Goede 	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", whitelabel_tm800a550l_accel_mount_matrix),
529cc183ad4SHans de Goede 	{ }
530cc183ad4SHans de Goede };
531cc183ad4SHans de Goede 
532cc183ad4SHans de Goede static const struct software_node whitelabel_tm800a550l_accel_node = {
533cc183ad4SHans de Goede 	.properties = whitelabel_tm800a550l_accel_props,
534cc183ad4SHans de Goede };
535cc183ad4SHans de Goede 
536cc183ad4SHans de Goede static const struct property_entry whitelabel_tm800a550l_goodix_props[] = {
537cc183ad4SHans de Goede 	PROPERTY_ENTRY_STRING("firmware-name", "gt912-tm800a550l.fw"),
538cc183ad4SHans de Goede 	PROPERTY_ENTRY_STRING("goodix,config-name", "gt912-tm800a550l.cfg"),
539cc183ad4SHans de Goede 	PROPERTY_ENTRY_U32("goodix,main-clk", 54),
540cc183ad4SHans de Goede 	{ }
541cc183ad4SHans de Goede };
542cc183ad4SHans de Goede 
543cc183ad4SHans de Goede static const struct software_node whitelabel_tm800a550l_goodix_node = {
544cc183ad4SHans de Goede 	.properties = whitelabel_tm800a550l_goodix_props,
545cc183ad4SHans de Goede };
546cc183ad4SHans de Goede 
547cc183ad4SHans de Goede static const struct x86_i2c_client_info whitelabel_tm800a550l_i2c_clients[] __initconst = {
548cc183ad4SHans de Goede 	{
549cc183ad4SHans de Goede 		/* goodix touchscreen */
550cc183ad4SHans de Goede 		.board_info = {
551cc183ad4SHans de Goede 			.type = "GDIX1001:00",
552cc183ad4SHans de Goede 			.addr = 0x14,
553cc183ad4SHans de Goede 			.dev_name = "goodix_ts",
554cc183ad4SHans de Goede 			.swnode = &whitelabel_tm800a550l_goodix_node,
555cc183ad4SHans de Goede 		},
556cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.I2C2",
557cc183ad4SHans de Goede 		.irq_data = {
558cc183ad4SHans de Goede 			.type = X86_ACPI_IRQ_TYPE_APIC,
559cc183ad4SHans de Goede 			.index = 0x44,
560cc183ad4SHans de Goede 			.trigger = ACPI_EDGE_SENSITIVE,
561cc183ad4SHans de Goede 			.polarity = ACPI_ACTIVE_HIGH,
562cc183ad4SHans de Goede 		},
563cc183ad4SHans de Goede 	}, {
564cc183ad4SHans de Goede 		/* kxcj91008 accel */
565cc183ad4SHans de Goede 		.board_info = {
566cc183ad4SHans de Goede 			.type = "kxcj91008",
567cc183ad4SHans de Goede 			.addr = 0x0f,
568cc183ad4SHans de Goede 			.dev_name = "kxcj91008",
569cc183ad4SHans de Goede 			.swnode = &whitelabel_tm800a550l_accel_node,
570cc183ad4SHans de Goede 		},
571cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.I2C3",
572cc183ad4SHans de Goede 	},
573cc183ad4SHans de Goede };
574cc183ad4SHans de Goede 
575cc183ad4SHans de Goede static struct gpiod_lookup_table whitelabel_tm800a550l_goodix_gpios = {
576cc183ad4SHans de Goede 	.dev_id = "i2c-goodix_ts",
577cc183ad4SHans de Goede 	.table = {
578cc183ad4SHans de Goede 		GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH),
579cc183ad4SHans de Goede 		GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH),
580cc183ad4SHans de Goede 		{ }
581cc183ad4SHans de Goede 	},
582cc183ad4SHans de Goede };
583cc183ad4SHans de Goede 
584cc183ad4SHans de Goede static struct gpiod_lookup_table * const whitelabel_tm800a550l_gpios[] = {
585cc183ad4SHans de Goede 	&whitelabel_tm800a550l_goodix_gpios,
586cc183ad4SHans de Goede 	NULL
587cc183ad4SHans de Goede };
588cc183ad4SHans de Goede 
589cc183ad4SHans de Goede const struct x86_dev_info whitelabel_tm800a550l_info __initconst = {
590cc183ad4SHans de Goede 	.i2c_client_info = whitelabel_tm800a550l_i2c_clients,
591cc183ad4SHans de Goede 	.i2c_client_count = ARRAY_SIZE(whitelabel_tm800a550l_i2c_clients),
592cc183ad4SHans de Goede 	.gpiod_lookup_tables = whitelabel_tm800a550l_gpios,
593cc183ad4SHans de Goede };
594cc183ad4SHans de Goede 
595cc183ad4SHans de Goede /*
596cc183ad4SHans de Goede  * If the EFI bootloader is not Xiaomi's own signed Android loader, then the
597cc183ad4SHans de Goede  * Xiaomi Mi Pad 2 X86 tablet sets OSID in the DSDT to 1 (Windows), causing
598cc183ad4SHans de Goede  * a bunch of devices to be hidden.
599cc183ad4SHans de Goede  *
600cc183ad4SHans de Goede  * This takes care of instantiating the hidden devices manually.
601cc183ad4SHans de Goede  */
602cc183ad4SHans de Goede static const struct x86_i2c_client_info xiaomi_mipad2_i2c_clients[] __initconst = {
603cc183ad4SHans de Goede 	{
604cc183ad4SHans de Goede 		/* BQ27520 fuel-gauge */
605cc183ad4SHans de Goede 		.board_info = {
606cc183ad4SHans de Goede 			.type = "bq27520",
607cc183ad4SHans de Goede 			.addr = 0x55,
608cc183ad4SHans de Goede 			.dev_name = "bq27520",
609cc183ad4SHans de Goede 			.swnode = &fg_bq25890_supply_node,
610cc183ad4SHans de Goede 		},
611cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.PCI0.I2C1",
612cc183ad4SHans de Goede 	}, {
613cc183ad4SHans de Goede 		/* KTD2026 RGB notification LED controller */
614cc183ad4SHans de Goede 		.board_info = {
615cc183ad4SHans de Goede 			.type = "ktd2026",
616cc183ad4SHans de Goede 			.addr = 0x30,
617cc183ad4SHans de Goede 			.dev_name = "ktd2026",
618cc183ad4SHans de Goede 		},
619cc183ad4SHans de Goede 		.adapter_path = "\\_SB_.PCI0.I2C3",
620cc183ad4SHans de Goede 	},
621cc183ad4SHans de Goede };
622cc183ad4SHans de Goede 
623cc183ad4SHans de Goede const struct x86_dev_info xiaomi_mipad2_info __initconst = {
624cc183ad4SHans de Goede 	.i2c_client_info = xiaomi_mipad2_i2c_clients,
625cc183ad4SHans de Goede 	.i2c_client_count = ARRAY_SIZE(xiaomi_mipad2_i2c_clients),
626cc183ad4SHans de Goede };
627