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 */
19 static 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 
27 static struct x86_gpio_button asus_me176c_tf103c_lid = {
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 */
41 static const char * const asus_me176c_accel_mount_matrix[] = {
42 	"-1", "0", "0",
43 	"0", "1", "0",
44 	"0", "0", "1"
45 };
46 
47 static const struct property_entry asus_me176c_accel_props[] = {
48 	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_me176c_accel_mount_matrix),
49 	{ }
50 };
51 
52 static const struct software_node asus_me176c_accel_node = {
53 	.properties = asus_me176c_accel_props,
54 };
55 
56 static 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 
65 static const struct software_node asus_me176c_bq24190_node = {
66 	.properties = asus_me176c_bq24190_props,
67 };
68 
69 static 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 
76 static const struct software_node asus_me176c_ug3105_node = {
77 	.properties = asus_me176c_ug3105_props,
78 };
79 
80 static 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 
146 static 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 
155 static 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 
164 static struct gpiod_lookup_table * const asus_me176c_gpios[] = {
165 	&int3496_gpo2_pin22_gpios,
166 	&asus_me176c_goodix_gpios,
167 	NULL
168 };
169 
170 const 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 	.gpiod_lookup_tables = asus_me176c_gpios,
179 	.bat_swnode = &generic_lipo_hv_4v35_battery_node,
180 	.modules = bq24190_modules,
181 	.invalid_aei_gpiochip = "INT33FC:02",
182 };
183 
184 /* Asus TF103C tablets have an Android factory img with everything hardcoded */
185 static const char * const asus_tf103c_accel_mount_matrix[] = {
186 	"0", "-1", "0",
187 	"-1", "0", "0",
188 	"0", "0", "1"
189 };
190 
191 static const struct property_entry asus_tf103c_accel_props[] = {
192 	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_tf103c_accel_mount_matrix),
193 	{ }
194 };
195 
196 static const struct software_node asus_tf103c_accel_node = {
197 	.properties = asus_tf103c_accel_props,
198 };
199 
200 static const struct property_entry asus_tf103c_touchscreen_props[] = {
201 	PROPERTY_ENTRY_STRING("compatible", "atmel,atmel_mxt_ts"),
202 	{ }
203 };
204 
205 static const struct software_node asus_tf103c_touchscreen_node = {
206 	.properties = asus_tf103c_touchscreen_props,
207 };
208 
209 static 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 
220 static const struct software_node asus_tf103c_battery_node = {
221 	.properties = asus_tf103c_battery_props,
222 };
223 
224 static 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 
233 static const struct software_node asus_tf103c_bq24190_node = {
234 	.properties = asus_tf103c_bq24190_props,
235 };
236 
237 static 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 
244 static const struct software_node asus_tf103c_ug3105_node = {
245 	.properties = asus_tf103c_ug3105_props,
246 };
247 
248 static 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 
310 static struct gpiod_lookup_table * const asus_tf103c_gpios[] = {
311 	&int3496_gpo2_pin22_gpios,
312 	NULL
313 };
314 
315 const 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 	.gpiod_lookup_tables = asus_tf103c_gpios,
322 	.bat_swnode = &asus_tf103c_battery_node,
323 	.modules = bq24190_modules,
324 	.invalid_aei_gpiochip = "INT33FC:02",
325 };
326