xref: /linux/drivers/platform/x86/x86-android-tablets/asus.c (revision 9669b2499ea377764f8320dd562dd6cd4ea80a5d)
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 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 image 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 accelerometer */
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.acpi.hid = "80860F0A",
149 		.ctrl.acpi.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 	.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 image 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_bq24190_props[] = {
210 	PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1),
211 	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_4v2_battery_node),
212 	PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000),
213 	PROPERTY_ENTRY_BOOL("omit-battery-class"),
214 	PROPERTY_ENTRY_BOOL("disable-reset"),
215 	{ }
216 };
217 
218 static const struct software_node asus_tf103c_bq24190_node = {
219 	.properties = asus_tf103c_bq24190_props,
220 };
221 
222 static const struct property_entry asus_tf103c_ug3105_props[] = {
223 	PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", bq24190_psy, 1),
224 	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_4v2_battery_node),
225 	PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 5000),
226 	{ }
227 };
228 
229 static const struct software_node asus_tf103c_ug3105_node = {
230 	.properties = asus_tf103c_ug3105_props,
231 };
232 
233 static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = {
234 	{
235 		/* bq24297 battery charger */
236 		.board_info = {
237 			.type = "bq24190",
238 			.addr = 0x6b,
239 			.dev_name = "bq24297",
240 			.swnode = &asus_tf103c_bq24190_node,
241 			.platform_data = &bq24190_pdata,
242 		},
243 		.adapter_path = "\\_SB_.I2C1",
244 		.irq_data = {
245 			.type = X86_ACPI_IRQ_TYPE_PMIC,
246 			.chip = "\\_SB_.I2C7.PMIC",
247 			.domain = DOMAIN_BUS_WAKEUP,
248 			.index = 0,
249 		},
250 	}, {
251 		/* ug3105 battery monitor */
252 		.board_info = {
253 			.type = "ug3105",
254 			.addr = 0x70,
255 			.dev_name = "ug3105",
256 			.swnode = &asus_tf103c_ug3105_node,
257 		},
258 		.adapter_path = "\\_SB_.I2C1",
259 	}, {
260 		/* ak09911 compass */
261 		.board_info = {
262 			.type = "ak09911",
263 			.addr = 0x0c,
264 			.dev_name = "ak09911",
265 		},
266 		.adapter_path = "\\_SB_.I2C5",
267 	}, {
268 		/* kxtj21009 accelerometer */
269 		.board_info = {
270 			.type = "kxtj21009",
271 			.addr = 0x0f,
272 			.dev_name = "kxtj21009",
273 			.swnode = &asus_tf103c_accel_node,
274 		},
275 		.adapter_path = "\\_SB_.I2C5",
276 	}, {
277 		/* atmel touchscreen */
278 		.board_info = {
279 			.type = "atmel_mxt_ts",
280 			.addr = 0x4a,
281 			.dev_name = "atmel_mxt_ts",
282 			.swnode = &asus_tf103c_touchscreen_node,
283 		},
284 		.adapter_path = "\\_SB_.I2C6",
285 		.irq_data = {
286 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
287 			.chip = "INT33FC:02",
288 			.index = 28,
289 			.trigger = ACPI_EDGE_SENSITIVE,
290 			.polarity = ACPI_ACTIVE_LOW,
291 			.con_id = "atmel_mxt_ts_irq",
292 		},
293 	},
294 };
295 
296 static struct gpiod_lookup_table * const asus_tf103c_gpios[] = {
297 	&int3496_gpo2_pin22_gpios,
298 	NULL
299 };
300 
301 const struct x86_dev_info asus_tf103c_info __initconst = {
302 	.i2c_client_info = asus_tf103c_i2c_clients,
303 	.i2c_client_count = ARRAY_SIZE(asus_tf103c_i2c_clients),
304 	.pdev_info = int3496_pdevs,
305 	.pdev_count = 1,
306 	.gpio_button = &asus_me176c_tf103c_lid,
307 	.gpio_button_count = 1,
308 	.gpiod_lookup_tables = asus_tf103c_gpios,
309 	.bat_swnode = &generic_lipo_4v2_battery_node,
310 	.modules = bq24190_modules,
311 };
312