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