1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Board info for Asus X86 tablets which ship with Android as the factory image
4 * and which have broken DSDT tables. The factory kernels shipped on these
5 * devices typically have a bunch of things hardcoded, rather than specified
6 * in their DSDT.
7 *
8 * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com>
9 */
10
11#include <linux/gpio/machine.h>
12#include <linux/input.h>
13#include <linux/platform_device.h>
14
15#include "shared-psy-info.h"
16#include "x86-android-tablets.h"
17
18/* Asus ME176C and TF103C tablets shared data */
19static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = {
20	.dev_id = "intel-int3496",
21	.table = {
22		GPIO_LOOKUP("INT33FC:02", 22, "id", GPIO_ACTIVE_HIGH),
23		{ }
24	},
25};
26
27static const struct x86_gpio_button asus_me176c_tf103c_lid __initconst = {
28	.button = {
29		.code = SW_LID,
30		.active_low = true,
31		.desc = "lid_sw",
32		.type = EV_SW,
33		.wakeup = true,
34		.debounce_interval = 50,
35	},
36	.chip = "INT33FC:02",
37	.pin = 12,
38};
39
40/* Asus ME176C tablets have an Android factory img with everything hardcoded */
41static const char * const asus_me176c_accel_mount_matrix[] = {
42	"-1", "0", "0",
43	"0", "1", "0",
44	"0", "0", "1"
45};
46
47static const struct property_entry asus_me176c_accel_props[] = {
48	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_me176c_accel_mount_matrix),
49	{ }
50};
51
52static const struct software_node asus_me176c_accel_node = {
53	.properties = asus_me176c_accel_props,
54};
55
56static const struct property_entry asus_me176c_bq24190_props[] = {
57	PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1),
58	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
59	PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000),
60	PROPERTY_ENTRY_BOOL("omit-battery-class"),
61	PROPERTY_ENTRY_BOOL("disable-reset"),
62	{ }
63};
64
65static const struct software_node asus_me176c_bq24190_node = {
66	.properties = asus_me176c_bq24190_props,
67};
68
69static const struct property_entry asus_me176c_ug3105_props[] = {
70	PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", bq24190_psy, 1),
71	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
72	PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 10000),
73	{ }
74};
75
76static const struct software_node asus_me176c_ug3105_node = {
77	.properties = asus_me176c_ug3105_props,
78};
79
80static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = {
81	{
82		/* bq24297 battery charger */
83		.board_info = {
84			.type = "bq24190",
85			.addr = 0x6b,
86			.dev_name = "bq24297",
87			.swnode = &asus_me176c_bq24190_node,
88			.platform_data = &bq24190_pdata,
89		},
90		.adapter_path = "\\_SB_.I2C1",
91		.irq_data = {
92			.type = X86_ACPI_IRQ_TYPE_PMIC,
93			.chip = "\\_SB_.I2C7.PMIC",
94			.domain = DOMAIN_BUS_WAKEUP,
95			.index = 0,
96		},
97	}, {
98		/* ug3105 battery monitor */
99		.board_info = {
100			.type = "ug3105",
101			.addr = 0x70,
102			.dev_name = "ug3105",
103			.swnode = &asus_me176c_ug3105_node,
104		},
105		.adapter_path = "\\_SB_.I2C1",
106	}, {
107		/* ak09911 compass */
108		.board_info = {
109			.type = "ak09911",
110			.addr = 0x0c,
111			.dev_name = "ak09911",
112		},
113		.adapter_path = "\\_SB_.I2C5",
114	}, {
115		/* kxtj21009 accel */
116		.board_info = {
117			.type = "kxtj21009",
118			.addr = 0x0f,
119			.dev_name = "kxtj21009",
120			.swnode = &asus_me176c_accel_node,
121		},
122		.adapter_path = "\\_SB_.I2C5",
123		.irq_data = {
124			.type = X86_ACPI_IRQ_TYPE_APIC,
125			.index = 0x44,
126			.trigger = ACPI_EDGE_SENSITIVE,
127			.polarity = ACPI_ACTIVE_LOW,
128		},
129	}, {
130		/* goodix touchscreen */
131		.board_info = {
132			.type = "GDIX1001:00",
133			.addr = 0x14,
134			.dev_name = "goodix_ts",
135		},
136		.adapter_path = "\\_SB_.I2C6",
137		.irq_data = {
138			.type = X86_ACPI_IRQ_TYPE_APIC,
139			.index = 0x45,
140			.trigger = ACPI_EDGE_SENSITIVE,
141			.polarity = ACPI_ACTIVE_LOW,
142		},
143	},
144};
145
146static const struct x86_serdev_info asus_me176c_serdevs[] __initconst = {
147	{
148		.ctrl_hid = "80860F0A",
149		.ctrl_uid = "2",
150		.ctrl_devname = "serial0",
151		.serdev_hid = "BCM2E3A",
152	},
153};
154
155static struct gpiod_lookup_table asus_me176c_goodix_gpios = {
156	.dev_id = "i2c-goodix_ts",
157	.table = {
158		GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_HIGH),
159		GPIO_LOOKUP("INT33FC:02", 28, "irq", GPIO_ACTIVE_HIGH),
160		{ }
161	},
162};
163
164static struct gpiod_lookup_table * const asus_me176c_gpios[] = {
165	&int3496_gpo2_pin22_gpios,
166	&asus_me176c_goodix_gpios,
167	NULL
168};
169
170const struct x86_dev_info asus_me176c_info __initconst = {
171	.i2c_client_info = asus_me176c_i2c_clients,
172	.i2c_client_count = ARRAY_SIZE(asus_me176c_i2c_clients),
173	.pdev_info = int3496_pdevs,
174	.pdev_count = 1,
175	.serdev_info = asus_me176c_serdevs,
176	.serdev_count = ARRAY_SIZE(asus_me176c_serdevs),
177	.gpio_button = &asus_me176c_tf103c_lid,
178	.gpio_button_count = 1,
179	.gpiod_lookup_tables = asus_me176c_gpios,
180	.bat_swnode = &generic_lipo_hv_4v35_battery_node,
181	.modules = bq24190_modules,
182};
183
184/* Asus TF103C tablets have an Android factory img with everything hardcoded */
185static const char * const asus_tf103c_accel_mount_matrix[] = {
186	"0", "-1", "0",
187	"-1", "0", "0",
188	"0", "0", "1"
189};
190
191static const struct property_entry asus_tf103c_accel_props[] = {
192	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_tf103c_accel_mount_matrix),
193	{ }
194};
195
196static const struct software_node asus_tf103c_accel_node = {
197	.properties = asus_tf103c_accel_props,
198};
199
200static const struct property_entry asus_tf103c_touchscreen_props[] = {
201	PROPERTY_ENTRY_STRING("compatible", "atmel,atmel_mxt_ts"),
202	{ }
203};
204
205static const struct software_node asus_tf103c_touchscreen_node = {
206	.properties = asus_tf103c_touchscreen_props,
207};
208
209static const struct property_entry asus_tf103c_battery_props[] = {
210	PROPERTY_ENTRY_STRING("compatible", "simple-battery"),
211	PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion-polymer"),
212	PROPERTY_ENTRY_U32("precharge-current-microamp", 256000),
213	PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000),
214	PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 2048000),
215	PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4208000),
216	PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000),
217	{ }
218};
219
220static const struct software_node asus_tf103c_battery_node = {
221	.properties = asus_tf103c_battery_props,
222};
223
224static const struct property_entry asus_tf103c_bq24190_props[] = {
225	PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1),
226	PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node),
227	PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000),
228	PROPERTY_ENTRY_BOOL("omit-battery-class"),
229	PROPERTY_ENTRY_BOOL("disable-reset"),
230	{ }
231};
232
233static const struct software_node asus_tf103c_bq24190_node = {
234	.properties = asus_tf103c_bq24190_props,
235};
236
237static const struct property_entry asus_tf103c_ug3105_props[] = {
238	PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", bq24190_psy, 1),
239	PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node),
240	PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 5000),
241	{ }
242};
243
244static const struct software_node asus_tf103c_ug3105_node = {
245	.properties = asus_tf103c_ug3105_props,
246};
247
248static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = {
249	{
250		/* bq24297 battery charger */
251		.board_info = {
252			.type = "bq24190",
253			.addr = 0x6b,
254			.dev_name = "bq24297",
255			.swnode = &asus_tf103c_bq24190_node,
256			.platform_data = &bq24190_pdata,
257		},
258		.adapter_path = "\\_SB_.I2C1",
259		.irq_data = {
260			.type = X86_ACPI_IRQ_TYPE_PMIC,
261			.chip = "\\_SB_.I2C7.PMIC",
262			.domain = DOMAIN_BUS_WAKEUP,
263			.index = 0,
264		},
265	}, {
266		/* ug3105 battery monitor */
267		.board_info = {
268			.type = "ug3105",
269			.addr = 0x70,
270			.dev_name = "ug3105",
271			.swnode = &asus_tf103c_ug3105_node,
272		},
273		.adapter_path = "\\_SB_.I2C1",
274	}, {
275		/* ak09911 compass */
276		.board_info = {
277			.type = "ak09911",
278			.addr = 0x0c,
279			.dev_name = "ak09911",
280		},
281		.adapter_path = "\\_SB_.I2C5",
282	}, {
283		/* kxtj21009 accel */
284		.board_info = {
285			.type = "kxtj21009",
286			.addr = 0x0f,
287			.dev_name = "kxtj21009",
288			.swnode = &asus_tf103c_accel_node,
289		},
290		.adapter_path = "\\_SB_.I2C5",
291	}, {
292		/* atmel touchscreen */
293		.board_info = {
294			.type = "atmel_mxt_ts",
295			.addr = 0x4a,
296			.dev_name = "atmel_mxt_ts",
297			.swnode = &asus_tf103c_touchscreen_node,
298		},
299		.adapter_path = "\\_SB_.I2C6",
300		.irq_data = {
301			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
302			.chip = "INT33FC:02",
303			.index = 28,
304			.trigger = ACPI_EDGE_SENSITIVE,
305			.polarity = ACPI_ACTIVE_LOW,
306		},
307	},
308};
309
310static struct gpiod_lookup_table * const asus_tf103c_gpios[] = {
311	&int3496_gpo2_pin22_gpios,
312	NULL
313};
314
315const struct x86_dev_info asus_tf103c_info __initconst = {
316	.i2c_client_info = asus_tf103c_i2c_clients,
317	.i2c_client_count = ARRAY_SIZE(asus_tf103c_i2c_clients),
318	.pdev_info = int3496_pdevs,
319	.pdev_count = 1,
320	.gpio_button = &asus_me176c_tf103c_lid,
321	.gpio_button_count = 1,
322	.gpiod_lookup_tables = asus_tf103c_gpios,
323	.bat_swnode = &asus_tf103c_battery_node,
324	.modules = bq24190_modules,
325};
326