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 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 | .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 */ |
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 | .con_id = "atmel_mxt_ts_irq" , |
307 | }, |
308 | }, |
309 | }; |
310 | |
311 | static struct gpiod_lookup_table * const asus_tf103c_gpios[] = { |
312 | &int3496_gpo2_pin22_gpios, |
313 | NULL |
314 | }; |
315 | |
316 | const 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 | |