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