xref: /linux/drivers/platform/x86/x86-android-tablets/lenovo.c (revision f6154d8babbb8a98f0d3ea325aafae2e33bfd8be)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Board info for Lenovo 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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 
13 #include <linux/efi.h>
14 #include <linux/gpio/machine.h>
15 #include <linux/mfd/intel_soc_pmic.h>
16 #include <linux/pinctrl/consumer.h>
17 #include <linux/pinctrl/machine.h>
18 #include <linux/platform_data/lp855x.h>
19 #include <linux/platform_device.h>
20 #include <linux/reboot.h>
21 #include <linux/rmi.h>
22 #include <linux/spi/spi.h>
23 
24 #include "shared-psy-info.h"
25 #include "x86-android-tablets.h"
26 
27 /*
28  * Various Lenovo models use a TI LP8557 LED backlight controller with its PWM
29  * input connected to a PWM output coming from the LCD panel's controller.
30  * The Android kernels have a hack in the i915 driver to write a non-standard
31  * panel specific DSI register to set the duty-cycle of the LCD's PWM output.
32  *
33  * To avoid having to have a similar hack in the mainline kernel program the
34  * LP8557 to directly set the level and use the lp855x_bl driver for control.
35  */
36 static struct lp855x_platform_data lenovo_lp8557_pdata = {
37 	.device_control = 0x86,
38 	.initial_brightness = 128,
39 };
40 
41 /* Lenovo Yoga Book X90F / X90L's Android factory img has everything hardcoded */
42 
43 static const struct property_entry lenovo_yb1_x90_wacom_props[] = {
44 	PROPERTY_ENTRY_U32("hid-descr-addr", 0x0001),
45 	PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 150),
46 	{ }
47 };
48 
49 static const struct software_node lenovo_yb1_x90_wacom_node = {
50 	.properties = lenovo_yb1_x90_wacom_props,
51 };
52 
53 /*
54  * The HiDeep IST940E touchscreen comes up in I2C-HID mode. The native protocol
55  * reports ABS_MT_PRESSURE and ABS_MT_TOUCH_MAJOR which are not reported in HID
56  * mode, so using native mode is preferred.
57  * It could alternatively be used in HID mode by changing the properties to:
58  *	PROPERTY_ENTRY_U32("hid-descr-addr", 0x0020),
59  *	PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
60  * and changing board_info.type to "hid-over-i2c".
61  */
62 static const struct property_entry lenovo_yb1_x90_hideep_ts_props[] = {
63 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1200),
64 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
65 	PROPERTY_ENTRY_U32("touchscreen-max-pressure", 16384),
66 	PROPERTY_ENTRY_BOOL("hideep,force-native-protocol"),
67 	{ }
68 };
69 
70 static const struct software_node lenovo_yb1_x90_hideep_ts_node = {
71 	.properties = lenovo_yb1_x90_hideep_ts_props,
72 };
73 
74 static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst = {
75 	{
76 		/* BQ27542 fuel-gauge */
77 		.board_info = {
78 			.type = "bq27542",
79 			.addr = 0x55,
80 			.dev_name = "bq27542",
81 			.swnode = &fg_bq25890_supply_node,
82 		},
83 		.adapter_path = "\\_SB_.PCI0.I2C1",
84 	}, {
85 		/* Goodix Touchscreen in keyboard half */
86 		.board_info = {
87 			.type = "GDIX1001:00",
88 			.addr = 0x14,
89 			.dev_name = "goodix_ts",
90 		},
91 		.adapter_path = "\\_SB_.PCI0.I2C2",
92 		.irq_data = {
93 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
94 			.chip = "INT33FF:01",
95 			.index = 56,
96 			.trigger = ACPI_EDGE_SENSITIVE,
97 			.polarity = ACPI_ACTIVE_LOW,
98 			.con_id = "goodix_ts_irq",
99 		},
100 	}, {
101 		/* Wacom Digitizer in keyboard half */
102 		.board_info = {
103 			.type = "hid-over-i2c",
104 			.addr = 0x09,
105 			.dev_name = "wacom",
106 			.swnode = &lenovo_yb1_x90_wacom_node,
107 		},
108 		.adapter_path = "\\_SB_.PCI0.I2C4",
109 		.irq_data = {
110 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
111 			.chip = "INT33FF:01",
112 			.index = 49,
113 			.trigger = ACPI_LEVEL_SENSITIVE,
114 			.polarity = ACPI_ACTIVE_LOW,
115 			.con_id = "wacom_irq",
116 		},
117 	}, {
118 		/* LP8557 Backlight controller */
119 		.board_info = {
120 			.type = "lp8557",
121 			.addr = 0x2c,
122 			.dev_name = "lp8557",
123 			.platform_data = &lenovo_lp8557_pdata,
124 		},
125 		.adapter_path = "\\_SB_.PCI0.I2C4",
126 	}, {
127 		/* HiDeep IST940E Touchscreen in display half */
128 		.board_info = {
129 			.type = "hideep_ts",
130 			.addr = 0x6c,
131 			.dev_name = "hideep_ts",
132 			.swnode = &lenovo_yb1_x90_hideep_ts_node,
133 		},
134 		.adapter_path = "\\_SB_.PCI0.I2C6",
135 		.irq_data = {
136 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
137 			.chip = "INT33FF:03",
138 			.index = 77,
139 			.trigger = ACPI_LEVEL_SENSITIVE,
140 			.polarity = ACPI_ACTIVE_LOW,
141 			.con_id = "hideep_ts_irq",
142 		},
143 	},
144 };
145 
146 static const struct platform_device_info lenovo_yb1_x90_pdevs[] __initconst = {
147 	{
148 		.name = "yogabook-touch-kbd-digitizer-switch",
149 		.id = PLATFORM_DEVID_NONE,
150 	},
151 };
152 
153 /*
154  * DSDT says UART path is "\\_SB.PCIO.URT1" with a letter 'O' instead of
155  * the number '0' add the link manually.
156  */
157 static const struct x86_serdev_info lenovo_yb1_x90_serdevs[] __initconst = {
158 	{
159 		.ctrl_hid = "8086228A",
160 		.ctrl_uid = "1",
161 		.ctrl_devname = "serial0",
162 		.serdev_hid = "BCM2E1A",
163 	},
164 };
165 
166 static const struct x86_gpio_button lenovo_yb1_x90_lid __initconst = {
167 	.button = {
168 		.code = SW_LID,
169 		.active_low = true,
170 		.desc = "lid_sw",
171 		.type = EV_SW,
172 		.wakeup = true,
173 		.debounce_interval = 50,
174 	},
175 	.chip = "INT33FF:02",
176 	.pin = 19,
177 };
178 
179 static struct gpiod_lookup_table lenovo_yb1_x90_goodix_gpios = {
180 	.dev_id = "i2c-goodix_ts",
181 	.table = {
182 		GPIO_LOOKUP("INT33FF:01", 53, "reset", GPIO_ACTIVE_HIGH),
183 		GPIO_LOOKUP("INT33FF:01", 56, "irq", GPIO_ACTIVE_HIGH),
184 		{ }
185 	},
186 };
187 
188 static struct gpiod_lookup_table lenovo_yb1_x90_hideep_gpios = {
189 	.dev_id = "i2c-hideep_ts",
190 	.table = {
191 		GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
192 		{ }
193 	},
194 };
195 
196 static struct gpiod_lookup_table lenovo_yb1_x90_wacom_gpios = {
197 	.dev_id = "i2c-wacom",
198 	.table = {
199 		GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_LOW),
200 		{ }
201 	},
202 };
203 
204 static struct gpiod_lookup_table * const lenovo_yb1_x90_gpios[] = {
205 	&lenovo_yb1_x90_hideep_gpios,
206 	&lenovo_yb1_x90_goodix_gpios,
207 	&lenovo_yb1_x90_wacom_gpios,
208 	NULL
209 };
210 
211 static int __init lenovo_yb1_x90_init(void)
212 {
213 	/* Enable the regulators used by the touchscreens */
214 
215 	/* Vprog3B 3.0V used by the goodix touchscreen in the keyboard half */
216 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
217 
218 	/* Vprog4D 3.0V used by the HiDeep touchscreen in the display half */
219 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9f, 0x02, 0xff);
220 
221 	/* Vprog5A 1.8V used by the HiDeep touchscreen in the display half */
222 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
223 
224 	/* Vprog5B 1.8V used by the goodix touchscreen in the keyboard half */
225 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa1, 0x02, 0xff);
226 
227 	return 0;
228 }
229 
230 const struct x86_dev_info lenovo_yogabook_x90_info __initconst = {
231 	.i2c_client_info = lenovo_yb1_x90_i2c_clients,
232 	.i2c_client_count = ARRAY_SIZE(lenovo_yb1_x90_i2c_clients),
233 	.pdev_info = lenovo_yb1_x90_pdevs,
234 	.pdev_count = ARRAY_SIZE(lenovo_yb1_x90_pdevs),
235 	.serdev_info = lenovo_yb1_x90_serdevs,
236 	.serdev_count = ARRAY_SIZE(lenovo_yb1_x90_serdevs),
237 	.gpio_button = &lenovo_yb1_x90_lid,
238 	.gpio_button_count = 1,
239 	.gpiod_lookup_tables = lenovo_yb1_x90_gpios,
240 	.init = lenovo_yb1_x90_init,
241 };
242 
243 /* Lenovo Yoga Book X91F/L Windows tablet needs manual instantiation of the fg client */
244 static const struct x86_i2c_client_info lenovo_yogabook_x91_i2c_clients[] __initconst = {
245 	{
246 		/* BQ27542 fuel-gauge */
247 		.board_info = {
248 			.type = "bq27542",
249 			.addr = 0x55,
250 			.dev_name = "bq27542",
251 			.swnode = &fg_bq25890_supply_node,
252 		},
253 		.adapter_path = "\\_SB_.PCI0.I2C1",
254 	},
255 };
256 
257 const struct x86_dev_info lenovo_yogabook_x91_info __initconst = {
258 	.i2c_client_info = lenovo_yogabook_x91_i2c_clients,
259 	.i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x91_i2c_clients),
260 };
261 
262 /* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */
263 static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
264 	PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1),
265 	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
266 	PROPERTY_ENTRY_BOOL("omit-battery-class"),
267 	PROPERTY_ENTRY_BOOL("disable-reset"),
268 	{ }
269 };
270 
271 static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
272 	.properties = lenovo_yoga_tab2_830_1050_bq24190_props,
273 };
274 
275 static const struct x86_gpio_button lenovo_yoga_tab2_830_1050_lid __initconst = {
276 	.button = {
277 		.code = SW_LID,
278 		.active_low = true,
279 		.desc = "lid_sw",
280 		.type = EV_SW,
281 		.wakeup = true,
282 		.debounce_interval = 50,
283 	},
284 	.chip = "INT33FC:02",
285 	.pin = 26,
286 };
287 
288 /* This gets filled by lenovo_yoga_tab2_830_1050_init() */
289 static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
290 
291 static struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initdata = {
292 	{
293 		/*
294 		 * This must be the first entry because lenovo_yoga_tab2_830_1050_init()
295 		 * may update its swnode. LSM303DA accelerometer + magnetometer.
296 		 */
297 		.board_info = {
298 			.type = "lsm303d",
299 			.addr = 0x1d,
300 			.dev_name = "lsm303d",
301 		},
302 		.adapter_path = "\\_SB_.I2C5",
303 	}, {
304 		/* AL3320A ambient light sensor */
305 		.board_info = {
306 			.type = "al3320a",
307 			.addr = 0x1c,
308 			.dev_name = "al3320a",
309 		},
310 		.adapter_path = "\\_SB_.I2C5",
311 	}, {
312 		/* bq24292i battery charger */
313 		.board_info = {
314 			.type = "bq24190",
315 			.addr = 0x6b,
316 			.dev_name = "bq24292i",
317 			.swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
318 			.platform_data = &bq24190_pdata,
319 		},
320 		.adapter_path = "\\_SB_.I2C1",
321 		.irq_data = {
322 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
323 			.chip = "INT33FC:02",
324 			.index = 2,
325 			.trigger = ACPI_EDGE_SENSITIVE,
326 			.polarity = ACPI_ACTIVE_HIGH,
327 			.con_id = "bq24292i_irq",
328 		},
329 	}, {
330 		/* BQ27541 fuel-gauge */
331 		.board_info = {
332 			.type = "bq27541",
333 			.addr = 0x55,
334 			.dev_name = "bq27541",
335 			.swnode = &fg_bq24190_supply_node,
336 		},
337 		.adapter_path = "\\_SB_.I2C1",
338 	}, {
339 		/* Synaptics RMI touchscreen */
340 		.board_info = {
341 			.type = "rmi4_i2c",
342 			.addr = 0x38,
343 			.dev_name = "rmi4_i2c",
344 			.platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
345 		},
346 		.adapter_path = "\\_SB_.I2C6",
347 		.irq_data = {
348 			.type = X86_ACPI_IRQ_TYPE_APIC,
349 			.index = 0x45,
350 			.trigger = ACPI_EDGE_SENSITIVE,
351 			.polarity = ACPI_ACTIVE_HIGH,
352 		},
353 	}, {
354 		/* LP8557 Backlight controller */
355 		.board_info = {
356 			.type = "lp8557",
357 			.addr = 0x2c,
358 			.dev_name = "lp8557",
359 			.platform_data = &lenovo_lp8557_pdata,
360 		},
361 		.adapter_path = "\\_SB_.I2C3",
362 	},
363 };
364 
365 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
366 	.dev_id = "intel-int3496",
367 	.table = {
368 		GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
369 		GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
370 		{ }
371 	},
372 };
373 
374 #define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
375 
376 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = {
377 	.dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME,
378 	.table = {
379 		GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH),
380 		GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH),
381 		GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
382 		GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW),
383 		{ }
384 	},
385 };
386 
387 static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = {
388 	&lenovo_yoga_tab2_830_1050_int3496_gpios,
389 	&lenovo_yoga_tab2_830_1050_codec_gpios,
390 	NULL
391 };
392 
393 static int __init lenovo_yoga_tab2_830_1050_init(void);
394 static void lenovo_yoga_tab2_830_1050_exit(void);
395 
396 const struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initconst = {
397 	.i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
398 	.i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients),
399 	.pdev_info = int3496_pdevs,
400 	.pdev_count = 1,
401 	.gpio_button = &lenovo_yoga_tab2_830_1050_lid,
402 	.gpio_button_count = 1,
403 	.gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios,
404 	.bat_swnode = &generic_lipo_hv_4v35_battery_node,
405 	.modules = bq24190_modules,
406 	.init = lenovo_yoga_tab2_830_1050_init,
407 	.exit = lenovo_yoga_tab2_830_1050_exit,
408 };
409 
410 /*
411  * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
412  * mainboard, but the 830 uses a portrait LCD panel with a landscape touchscreen,
413  * requiring the touchscreen driver to adjust the touch-coords to match the LCD.
414  * And requiring the accelerometer to have a mount-matrix set to correct for
415  * the 90° rotation of the LCD vs the frame.
416  */
417 static const char * const lenovo_yoga_tab2_830_lms303d_mount_matrix[] = {
418 	"0", "1", "0",
419 	"-1", "0", "0",
420 	"0", "0", "1"
421 };
422 
423 static const struct property_entry lenovo_yoga_tab2_830_lms303d_props[] = {
424 	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_830_lms303d_mount_matrix),
425 	{ }
426 };
427 
428 static const struct software_node lenovo_yoga_tab2_830_lms303d_node = {
429 	.properties = lenovo_yoga_tab2_830_lms303d_props,
430 };
431 
432 static int __init lenovo_yoga_tab2_830_1050_init_touchscreen(void)
433 {
434 	struct gpio_desc *gpiod;
435 	int ret;
436 
437 	/* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
438 	ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, "yoga_bootstrap",
439 					   false, GPIOD_ASIS, &gpiod);
440 	if (ret)
441 		return ret;
442 
443 	ret = gpiod_get_value_cansleep(gpiod);
444 	if (ret) {
445 		pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
446 	} else {
447 		pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
448 		lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
449 		lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
450 		lenovo_yoga_tab2_830_1050_i2c_clients[0].board_info.swnode =
451 			&lenovo_yoga_tab2_830_lms303d_node;
452 	}
453 
454 	return 0;
455 }
456 
457 /* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
458 static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
459 	PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
460 			  "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
461 
462 static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
463 static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
464 
465 static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
466 {
467 	struct device *codec_dev;
468 	struct pinctrl *pinctrl;
469 	int ret;
470 
471 	codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
472 					    LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
473 	if (!codec_dev) {
474 		pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
475 		return -ENODEV;
476 	}
477 
478 	ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
479 	if (ret)
480 		goto err_put_device;
481 
482 	pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
483 	if (IS_ERR(pinctrl)) {
484 		ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
485 		goto err_unregister_mappings;
486 	}
487 
488 	/* We're done with the codec_dev now */
489 	put_device(codec_dev);
490 
491 	lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
492 	return 0;
493 
494 err_unregister_mappings:
495 	pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
496 err_put_device:
497 	put_device(codec_dev);
498 	return ret;
499 }
500 
501 /*
502  * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off
503  * gets used as pm_power_off handler. This causes "poweroff" on these tablets
504  * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice*
505  * followed by a normal 3 second press to recover. Avoid this by doing an EFI
506  * poweroff instead.
507  */
508 static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
509 {
510 	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
511 
512 	return NOTIFY_DONE;
513 }
514 
515 static int __init lenovo_yoga_tab2_830_1050_init(void)
516 {
517 	int ret;
518 
519 	ret = lenovo_yoga_tab2_830_1050_init_touchscreen();
520 	if (ret)
521 		return ret;
522 
523 	ret = lenovo_yoga_tab2_830_1050_init_codec();
524 	if (ret)
525 		return ret;
526 
527 	/* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */
528 	lenovo_yoga_tab2_830_1050_sys_off_handler =
529 		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
530 					 lenovo_yoga_tab2_830_1050_power_off, NULL);
531 	if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
532 		return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
533 
534 	return 0;
535 }
536 
537 static void lenovo_yoga_tab2_830_1050_exit(void)
538 {
539 	unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
540 
541 	if (lenovo_yoga_tab2_830_1050_codec_pinctrl) {
542 		pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
543 		pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
544 	}
545 }
546 
547 /* Lenovo Yoga Tab 3 Pro YT3-X90F */
548 
549 /*
550  * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers,
551  * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c.
552  */
553 static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" };
554 static const char * const bq25890_1_psy[] = { "bq25890-charger-1" };
555 
556 static const struct property_entry fg_bq25890_1_supply_props[] = {
557 	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy),
558 	{ }
559 };
560 
561 static const struct software_node fg_bq25890_1_supply_node = {
562 	.properties = fg_bq25890_1_supply_props,
563 };
564 
565 /* bq25892 charger settings for the flat lipo battery behind the screen */
566 static const struct property_entry lenovo_yt3_bq25892_0_props[] = {
567 	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers),
568 	PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40),
569 	PROPERTY_ENTRY_BOOL("linux,skip-reset"),
570 	/* Values taken from Android Factory Image */
571 	PROPERTY_ENTRY_U32("ti,charge-current", 2048000),
572 	PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
573 	PROPERTY_ENTRY_U32("ti,termination-current", 128000),
574 	PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
575 	PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000),
576 	PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
577 	PROPERTY_ENTRY_U32("ti,boost-max-current", 500000),
578 	PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
579 	{ }
580 };
581 
582 static const struct software_node lenovo_yt3_bq25892_0_node = {
583 	.properties = lenovo_yt3_bq25892_0_props,
584 };
585 
586 static const struct property_entry lenovo_yt3_hideep_ts_props[] = {
587 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
588 	PROPERTY_ENTRY_U32("touchscreen-size-y", 2560),
589 	PROPERTY_ENTRY_U32("touchscreen-max-pressure", 255),
590 	{ }
591 };
592 
593 static const struct software_node lenovo_yt3_hideep_ts_node = {
594 	.properties = lenovo_yt3_hideep_ts_props,
595 };
596 
597 static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
598 	{
599 		/* bq27500 fuel-gauge for the flat lipo battery behind the screen */
600 		.board_info = {
601 			.type = "bq27500",
602 			.addr = 0x55,
603 			.dev_name = "bq27500_0",
604 			.swnode = &fg_bq25890_supply_node,
605 		},
606 		.adapter_path = "\\_SB_.PCI0.I2C1",
607 	}, {
608 		/* bq25892 charger for the flat lipo battery behind the screen */
609 		.board_info = {
610 			.type = "bq25892",
611 			.addr = 0x6b,
612 			.dev_name = "bq25892_0",
613 			.swnode = &lenovo_yt3_bq25892_0_node,
614 		},
615 		.adapter_path = "\\_SB_.PCI0.I2C1",
616 		.irq_data = {
617 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
618 			.chip = "INT33FF:01",
619 			.index = 5,
620 			.trigger = ACPI_EDGE_SENSITIVE,
621 			.polarity = ACPI_ACTIVE_LOW,
622 			.con_id = "bq25892_0_irq",
623 		},
624 	}, {
625 		/* bq27500 fuel-gauge for the round li-ion cells in the hinge */
626 		.board_info = {
627 			.type = "bq27500",
628 			.addr = 0x55,
629 			.dev_name = "bq27500_1",
630 			.swnode = &fg_bq25890_1_supply_node,
631 		},
632 		.adapter_path = "\\_SB_.PCI0.I2C2",
633 	}, {
634 		/* HiDeep IST520E Touchscreen */
635 		.board_info = {
636 			.type = "hideep_ts",
637 			.addr = 0x6c,
638 			.dev_name = "hideep_ts",
639 			.swnode = &lenovo_yt3_hideep_ts_node,
640 		},
641 		.adapter_path = "\\_SB_.PCI0.I2C6",
642 		.irq_data = {
643 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
644 			.chip = "INT33FF:03",
645 			.index = 77,
646 			.trigger = ACPI_LEVEL_SENSITIVE,
647 			.polarity = ACPI_ACTIVE_LOW,
648 			.con_id = "hideep_ts_irq",
649 		},
650 	}, {
651 		/* LP8557 Backlight controller */
652 		.board_info = {
653 			.type = "lp8557",
654 			.addr = 0x2c,
655 			.dev_name = "lp8557",
656 			.platform_data = &lenovo_lp8557_pdata,
657 		},
658 		.adapter_path = "\\_SB_.PCI0.I2C1",
659 	}
660 };
661 
662 static int __init lenovo_yt3_init(void)
663 {
664 	int ret;
665 
666 	/*
667 	 * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins
668 	 * connected to GPIOs, rather then having them hardwired to the correct
669 	 * values as is normally done.
670 	 *
671 	 * The bq25890_charger driver controls these through I2C, but this only
672 	 * works if not overridden by the pins. Set these pins here:
673 	 * 1. Set /CE to 1 to allow charging.
674 	 * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of
675 	 *    the main "bq25892_1" charger is used when necessary.
676 	 */
677 
678 	/* /CE pin */
679 	ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, "bq25892_0_ce",
680 					   true, GPIOD_OUT_HIGH, NULL);
681 	if (ret < 0)
682 		return ret;
683 
684 	/* OTG pin */
685 	ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, "bq25892_0_otg",
686 					   false, GPIOD_OUT_LOW, NULL);
687 	if (ret < 0)
688 		return ret;
689 
690 	/* Enable the regulators used by the touchscreen */
691 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
692 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
693 
694 	return 0;
695 }
696 
697 static struct gpiod_lookup_table lenovo_yt3_hideep_gpios = {
698 	.dev_id = "i2c-hideep_ts",
699 	.table = {
700 		GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
701 		{ }
702 	},
703 };
704 
705 static struct gpiod_lookup_table * const lenovo_yt3_gpios[] = {
706 	&lenovo_yt3_hideep_gpios,
707 	NULL
708 };
709 
710 const struct x86_dev_info lenovo_yt3_info __initconst = {
711 	.i2c_client_info = lenovo_yt3_i2c_clients,
712 	.i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients),
713 	.gpiod_lookup_tables = lenovo_yt3_gpios,
714 	.init = lenovo_yt3_init,
715 };
716