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 .con_id = "atmel_mxt_ts_irq",
307 },
308 },
309};
310
311static struct gpiod_lookup_table * const asus_tf103c_gpios[] = {
312 &int3496_gpo2_pin22_gpios,
313 NULL
314};
315
316const struct x86_dev_info asus_tf103c_info __initconst = {
317 .i2c_client_info = asus_tf103c_i2c_clients,
318 .i2c_client_count = ARRAY_SIZE(asus_tf103c_i2c_clients),
319 .pdev_info = int3496_pdevs,
320 .pdev_count = 1,
321 .gpio_button = &asus_me176c_tf103c_lid,
322 .gpio_button_count = 1,
323 .gpiod_lookup_tables = asus_tf103c_gpios,
324 .bat_swnode = &asus_tf103c_battery_node,
325 .modules = bq24190_modules,
326};
327

source code of linux/drivers/platform/x86/x86-android-tablets/asus.c