xref: /linux/drivers/platform/x86/x86-android-tablets/lenovo.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
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/arizona/pdata.h>
16 #include <linux/mfd/arizona/registers.h>
17 #include <linux/mfd/intel_soc_pmic.h>
18 #include <linux/pinctrl/consumer.h>
19 #include <linux/pinctrl/machine.h>
20 #include <linux/platform_data/lp855x.h>
21 #include <linux/platform_device.h>
22 #include <linux/power/bq24190_charger.h>
23 #include <linux/reboot.h>
24 #include <linux/rmi.h>
25 #include <linux/spi/spi.h>
26 
27 #include "shared-psy-info.h"
28 #include "x86-android-tablets.h"
29 
30 /*
31  * Various Lenovo models use a TI LP8557 LED backlight controller with its PWM
32  * input connected to a PWM output coming from the LCD panel's controller.
33  * The Android kernels have a hack in the i915 driver to write a non-standard
34  * panel specific DSI register to set the duty-cycle of the LCD's PWM output.
35  *
36  * To avoid having to have a similar hack in the mainline kernel program the
37  * LP8557 to directly set the level and use the lp855x_bl driver for control.
38  *
39  * The LP8557 can either be configured to multiply its PWM input and
40  * the I2C register set level (requiring both to be at 100% for 100% output);
41  * or to only take the I2C register set level into account.
42  *
43  * Multiplying the 2 levels is useful because this will turn off the backlight
44  * when the panel goes off and turns off its PWM output.
45  *
46  * But on some models the panel's PWM output defaults to a duty-cycle of
47  * much less then 100%, severely limiting max brightness. In this case
48  * the LP8557 should be configured to only take the I2C register into
49  * account and the i915 driver must turn off the panel and the backlight
50  * separately using e.g. VBT MIPI sequences to turn off the backlight.
51  */
52 static struct lp855x_platform_data lenovo_lp8557_pwm_and_reg_pdata = {
53 	.device_control = 0x86,
54 	.initial_brightness = 128,
55 };
56 
57 static struct lp855x_platform_data lenovo_lp8557_reg_only_pdata = {
58 	.device_control = 0x85,
59 	.initial_brightness = 128,
60 };
61 
62 /* Lenovo Yoga Book X90F / X90L's Android factory image has everything hardcoded */
63 
64 static const struct property_entry lenovo_yb1_x90_wacom_props[] = {
65 	PROPERTY_ENTRY_U32("hid-descr-addr", 0x0001),
66 	PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 150),
67 	{ }
68 };
69 
70 static const struct software_node lenovo_yb1_x90_wacom_node = {
71 	.properties = lenovo_yb1_x90_wacom_props,
72 };
73 
74 /*
75  * The HiDeep IST940E touchscreen comes up in I2C-HID mode. The native protocol
76  * reports ABS_MT_PRESSURE and ABS_MT_TOUCH_MAJOR which are not reported in HID
77  * mode, so using native mode is preferred.
78  * It could alternatively be used in HID mode by changing the properties to:
79  *	PROPERTY_ENTRY_U32("hid-descr-addr", 0x0020),
80  *	PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
81  * and changing board_info.type to "hid-over-i2c".
82  */
83 static const struct property_entry lenovo_yb1_x90_hideep_ts_props[] = {
84 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1200),
85 	PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
86 	PROPERTY_ENTRY_U32("touchscreen-max-pressure", 16384),
87 	PROPERTY_ENTRY_BOOL("hideep,force-native-protocol"),
88 	{ }
89 };
90 
91 static const struct software_node lenovo_yb1_x90_hideep_ts_node = {
92 	.properties = lenovo_yb1_x90_hideep_ts_props,
93 };
94 
95 static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst = {
96 	{
97 		/* BQ27542 fuel-gauge */
98 		.board_info = {
99 			.type = "bq27542",
100 			.addr = 0x55,
101 			.dev_name = "bq27542",
102 			.swnode = &fg_bq25890_supply_node,
103 		},
104 		.adapter_path = "\\_SB_.PCI0.I2C1",
105 	}, {
106 		/* Goodix Touchscreen in keyboard half */
107 		.board_info = {
108 			.type = "GDIX1001:00",
109 			.addr = 0x14,
110 			.dev_name = "goodix_ts",
111 		},
112 		.adapter_path = "\\_SB_.PCI0.I2C2",
113 		.irq_data = {
114 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
115 			.chip = "INT33FF:01",
116 			.index = 56,
117 			.trigger = ACPI_EDGE_SENSITIVE,
118 			.polarity = ACPI_ACTIVE_LOW,
119 			.con_id = "goodix_ts_irq",
120 			.free_gpio = true,
121 		},
122 	}, {
123 		/* Wacom Digitizer in keyboard half */
124 		.board_info = {
125 			.type = "hid-over-i2c",
126 			.addr = 0x09,
127 			.dev_name = "wacom",
128 			.swnode = &lenovo_yb1_x90_wacom_node,
129 		},
130 		.adapter_path = "\\_SB_.PCI0.I2C4",
131 		.irq_data = {
132 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
133 			.chip = "INT33FF:01",
134 			.index = 49,
135 			.trigger = ACPI_LEVEL_SENSITIVE,
136 			.polarity = ACPI_ACTIVE_LOW,
137 			.con_id = "wacom_irq",
138 		},
139 	}, {
140 		/* LP8557 Backlight controller */
141 		.board_info = {
142 			.type = "lp8557",
143 			.addr = 0x2c,
144 			.dev_name = "lp8557",
145 			.platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
146 		},
147 		.adapter_path = "\\_SB_.PCI0.I2C4",
148 	}, {
149 		/* HiDeep IST940E Touchscreen in display half */
150 		.board_info = {
151 			.type = "hideep_ts",
152 			.addr = 0x6c,
153 			.dev_name = "hideep_ts",
154 			.swnode = &lenovo_yb1_x90_hideep_ts_node,
155 		},
156 		.adapter_path = "\\_SB_.PCI0.I2C6",
157 		.irq_data = {
158 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
159 			.chip = "INT33FF:03",
160 			.index = 77,
161 			.trigger = ACPI_LEVEL_SENSITIVE,
162 			.polarity = ACPI_ACTIVE_LOW,
163 			.con_id = "hideep_ts_irq",
164 		},
165 	},
166 };
167 
168 static const struct platform_device_info lenovo_yb1_x90_pdevs[] __initconst = {
169 	{
170 		.name = "yogabook-touch-kbd-digitizer-switch",
171 		.id = PLATFORM_DEVID_NONE,
172 	},
173 };
174 
175 /*
176  * DSDT says UART path is "\\_SB.PCIO.URT1" with a letter 'O' instead of
177  * the number '0' add the link manually.
178  */
179 static const struct x86_serdev_info lenovo_yb1_x90_serdevs[] __initconst = {
180 	{
181 		.ctrl_hid = "8086228A",
182 		.ctrl_uid = "1",
183 		.ctrl_devname = "serial0",
184 		.serdev_hid = "BCM2E1A",
185 	},
186 };
187 
188 static const struct x86_gpio_button lenovo_yb1_x90_lid __initconst = {
189 	.button = {
190 		.code = SW_LID,
191 		.active_low = true,
192 		.desc = "lid_sw",
193 		.type = EV_SW,
194 		.wakeup = true,
195 		.debounce_interval = 50,
196 	},
197 	.chip = "INT33FF:02",
198 	.pin = 19,
199 };
200 
201 static struct gpiod_lookup_table lenovo_yb1_x90_goodix_gpios = {
202 	.dev_id = "i2c-goodix_ts",
203 	.table = {
204 		GPIO_LOOKUP("INT33FF:01", 53, "reset", GPIO_ACTIVE_HIGH),
205 		GPIO_LOOKUP("INT33FF:01", 56, "irq", GPIO_ACTIVE_HIGH),
206 		{ }
207 	},
208 };
209 
210 static struct gpiod_lookup_table lenovo_yb1_x90_hideep_gpios = {
211 	.dev_id = "i2c-hideep_ts",
212 	.table = {
213 		GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
214 		{ }
215 	},
216 };
217 
218 static struct gpiod_lookup_table lenovo_yb1_x90_wacom_gpios = {
219 	.dev_id = "i2c-wacom",
220 	.table = {
221 		GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_LOW),
222 		{ }
223 	},
224 };
225 
226 static struct gpiod_lookup_table * const lenovo_yb1_x90_gpios[] = {
227 	&lenovo_yb1_x90_hideep_gpios,
228 	&lenovo_yb1_x90_goodix_gpios,
229 	&lenovo_yb1_x90_wacom_gpios,
230 	NULL
231 };
232 
lenovo_yb1_x90_init(struct device * dev)233 static int __init lenovo_yb1_x90_init(struct device *dev)
234 {
235 	/* Enable the regulators used by the touchscreens */
236 
237 	/* Vprog3B 3.0V used by the goodix touchscreen in the keyboard half */
238 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
239 
240 	/* Vprog4D 3.0V used by the HiDeep touchscreen in the display half */
241 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9f, 0x02, 0xff);
242 
243 	/* Vprog5A 1.8V used by the HiDeep touchscreen in the display half */
244 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
245 
246 	/* Vprog5B 1.8V used by the goodix touchscreen in the keyboard half */
247 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa1, 0x02, 0xff);
248 
249 	return 0;
250 }
251 
252 const struct x86_dev_info lenovo_yogabook_x90_info __initconst = {
253 	.i2c_client_info = lenovo_yb1_x90_i2c_clients,
254 	.i2c_client_count = ARRAY_SIZE(lenovo_yb1_x90_i2c_clients),
255 	.pdev_info = lenovo_yb1_x90_pdevs,
256 	.pdev_count = ARRAY_SIZE(lenovo_yb1_x90_pdevs),
257 	.serdev_info = lenovo_yb1_x90_serdevs,
258 	.serdev_count = ARRAY_SIZE(lenovo_yb1_x90_serdevs),
259 	.gpio_button = &lenovo_yb1_x90_lid,
260 	.gpio_button_count = 1,
261 	.gpiod_lookup_tables = lenovo_yb1_x90_gpios,
262 	.init = lenovo_yb1_x90_init,
263 };
264 
265 /* Lenovo Yoga Book X91F/L Windows tablet needs manual instantiation of the fuel-gauge client */
266 static const struct x86_i2c_client_info lenovo_yogabook_x91_i2c_clients[] __initconst = {
267 	{
268 		/* BQ27542 fuel-gauge */
269 		.board_info = {
270 			.type = "bq27542",
271 			.addr = 0x55,
272 			.dev_name = "bq27542",
273 			.swnode = &fg_bq25890_supply_node,
274 		},
275 		.adapter_path = "\\_SB_.PCI0.I2C1",
276 	},
277 };
278 
279 const struct x86_dev_info lenovo_yogabook_x91_info __initconst = {
280 	.i2c_client_info = lenovo_yogabook_x91_i2c_clients,
281 	.i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x91_i2c_clients),
282 };
283 
284 /* Lenovo Yoga Tablet 2 1050F/L's Android factory image has everything hardcoded */
285 static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
286 	PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1),
287 	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
288 	PROPERTY_ENTRY_BOOL("omit-battery-class"),
289 	PROPERTY_ENTRY_BOOL("disable-reset"),
290 	{ }
291 };
292 
293 static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
294 	.properties = lenovo_yoga_tab2_830_1050_bq24190_props,
295 };
296 
297 static const struct x86_gpio_button lenovo_yoga_tab2_830_1050_lid __initconst = {
298 	.button = {
299 		.code = SW_LID,
300 		.active_low = true,
301 		.desc = "lid_sw",
302 		.type = EV_SW,
303 		.wakeup = true,
304 		.debounce_interval = 50,
305 	},
306 	.chip = "INT33FC:02",
307 	.pin = 26,
308 };
309 
310 /* This gets filled by lenovo_yoga_tab2_830_1050_init() */
311 static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
312 
313 static struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initdata = {
314 	{
315 		/*
316 		 * This must be the first entry because lenovo_yoga_tab2_830_1050_init()
317 		 * may update its swnode. LSM303DA accelerometer + magnetometer.
318 		 */
319 		.board_info = {
320 			.type = "lsm303d",
321 			.addr = 0x1d,
322 			.dev_name = "lsm303d",
323 		},
324 		.adapter_path = "\\_SB_.I2C5",
325 	}, {
326 		/* AL3320A ambient light sensor */
327 		.board_info = {
328 			.type = "al3320a",
329 			.addr = 0x1c,
330 			.dev_name = "al3320a",
331 		},
332 		.adapter_path = "\\_SB_.I2C5",
333 	}, {
334 		/* bq24292i battery charger */
335 		.board_info = {
336 			.type = "bq24190",
337 			.addr = 0x6b,
338 			.dev_name = "bq24292i",
339 			.swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
340 			.platform_data = &bq24190_pdata,
341 		},
342 		.adapter_path = "\\_SB_.I2C1",
343 		.irq_data = {
344 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
345 			.chip = "INT33FC:02",
346 			.index = 2,
347 			.trigger = ACPI_EDGE_SENSITIVE,
348 			.polarity = ACPI_ACTIVE_HIGH,
349 			.con_id = "bq24292i_irq",
350 		},
351 	}, {
352 		/* BQ27541 fuel-gauge */
353 		.board_info = {
354 			.type = "bq27541",
355 			.addr = 0x55,
356 			.dev_name = "bq27541",
357 			.swnode = &fg_bq24190_supply_node,
358 		},
359 		.adapter_path = "\\_SB_.I2C1",
360 	}, {
361 		/* Synaptics RMI touchscreen */
362 		.board_info = {
363 			.type = "rmi4_i2c",
364 			.addr = 0x38,
365 			.dev_name = "rmi4_i2c",
366 			.platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
367 		},
368 		.adapter_path = "\\_SB_.I2C6",
369 		.irq_data = {
370 			.type = X86_ACPI_IRQ_TYPE_APIC,
371 			.index = 0x45,
372 			.trigger = ACPI_EDGE_SENSITIVE,
373 			.polarity = ACPI_ACTIVE_HIGH,
374 		},
375 	}, {
376 		/* LP8557 Backlight controller */
377 		.board_info = {
378 			.type = "lp8557",
379 			.addr = 0x2c,
380 			.dev_name = "lp8557",
381 			.platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
382 		},
383 		.adapter_path = "\\_SB_.I2C3",
384 	},
385 };
386 
387 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
388 	.dev_id = "intel-int3496",
389 	.table = {
390 		GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
391 		GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
392 		{ }
393 	},
394 };
395 
396 #define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
397 
398 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = {
399 	.dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME,
400 	.table = {
401 		GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH),
402 		GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH),
403 		GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
404 		GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW),
405 		{ }
406 	},
407 };
408 
409 static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = {
410 	&lenovo_yoga_tab2_830_1050_int3496_gpios,
411 	&lenovo_yoga_tab2_830_1050_codec_gpios,
412 	NULL
413 };
414 
415 static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev);
416 static void lenovo_yoga_tab2_830_1050_exit(void);
417 
418 const struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initconst = {
419 	.i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
420 	.i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients),
421 	.pdev_info = int3496_pdevs,
422 	.pdev_count = 1,
423 	.gpio_button = &lenovo_yoga_tab2_830_1050_lid,
424 	.gpio_button_count = 1,
425 	.gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios,
426 	.bat_swnode = &generic_lipo_hv_4v35_battery_node,
427 	.modules = bq24190_modules,
428 	.init = lenovo_yoga_tab2_830_1050_init,
429 	.exit = lenovo_yoga_tab2_830_1050_exit,
430 };
431 
432 /*
433  * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
434  * mainboard, but the 830 uses a portrait LCD panel with a landscape touchscreen,
435  * requiring the touchscreen driver to adjust the touch-coords to match the LCD.
436  * And requiring the accelerometer to have a mount-matrix set to correct for
437  * the 90° rotation of the LCD vs the frame.
438  */
439 static const char * const lenovo_yoga_tab2_830_lms303d_mount_matrix[] = {
440 	"0", "1", "0",
441 	"-1", "0", "0",
442 	"0", "0", "1"
443 };
444 
445 static const struct property_entry lenovo_yoga_tab2_830_lms303d_props[] = {
446 	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_830_lms303d_mount_matrix),
447 	{ }
448 };
449 
450 static const struct software_node lenovo_yoga_tab2_830_lms303d_node = {
451 	.properties = lenovo_yoga_tab2_830_lms303d_props,
452 };
453 
lenovo_yoga_tab2_830_1050_init_touchscreen(void)454 static int __init lenovo_yoga_tab2_830_1050_init_touchscreen(void)
455 {
456 	struct gpio_desc *gpiod;
457 	int ret;
458 
459 	/* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
460 	ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, "yoga_bootstrap",
461 					   false, GPIOD_ASIS, &gpiod);
462 	if (ret)
463 		return ret;
464 
465 	ret = gpiod_get_value_cansleep(gpiod);
466 	if (ret) {
467 		pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
468 	} else {
469 		pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
470 		lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
471 		lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
472 		lenovo_yoga_tab2_830_1050_i2c_clients[0].board_info.swnode =
473 			&lenovo_yoga_tab2_830_lms303d_node;
474 	}
475 
476 	return 0;
477 }
478 
479 /* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
480 static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
481 	PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
482 			  "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
483 
484 static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
485 static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
486 
lenovo_yoga_tab2_830_1050_init_codec(void)487 static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
488 {
489 	struct device *codec_dev;
490 	struct pinctrl *pinctrl;
491 	int ret;
492 
493 	codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
494 					    LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
495 	if (!codec_dev) {
496 		pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
497 		return -ENODEV;
498 	}
499 
500 	ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
501 	if (ret)
502 		goto err_put_device;
503 
504 	pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
505 	if (IS_ERR(pinctrl)) {
506 		ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
507 		goto err_unregister_mappings;
508 	}
509 
510 	/* We're done with the codec_dev now */
511 	put_device(codec_dev);
512 
513 	lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
514 	return 0;
515 
516 err_unregister_mappings:
517 	pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
518 err_put_device:
519 	put_device(codec_dev);
520 	return ret;
521 }
522 
523 /*
524  * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off()
525  * gets used as pm_power_off handler. This causes "poweroff" on these tablets
526  * to hang hard. Requiring pressing the power button for 30 seconds *twice*
527  * followed by a normal 3 second press to recover. Avoid this by doing an EFI
528  * poweroff instead.
529  */
lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data * data)530 static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
531 {
532 	efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
533 
534 	return NOTIFY_DONE;
535 }
536 
lenovo_yoga_tab2_830_1050_init(struct device * dev)537 static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev)
538 {
539 	int ret;
540 
541 	ret = lenovo_yoga_tab2_830_1050_init_touchscreen();
542 	if (ret)
543 		return ret;
544 
545 	ret = lenovo_yoga_tab2_830_1050_init_codec();
546 	if (ret)
547 		return ret;
548 
549 	/* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off() */
550 	lenovo_yoga_tab2_830_1050_sys_off_handler =
551 		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
552 					 lenovo_yoga_tab2_830_1050_power_off, NULL);
553 	if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
554 		return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
555 
556 	return 0;
557 }
558 
lenovo_yoga_tab2_830_1050_exit(void)559 static void lenovo_yoga_tab2_830_1050_exit(void)
560 {
561 	unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
562 
563 	if (lenovo_yoga_tab2_830_1050_codec_pinctrl) {
564 		pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
565 		pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
566 	}
567 }
568 
569 /*
570  * Lenovo Yoga Tablet 2 Pro 1380F/L
571  *
572  * The Lenovo Yoga Tablet 2 Pro 1380F/L mostly has the same design as the 830F/L
573  * and the 1050F/L so this re-uses some of the handling for that from above.
574  */
575 static const char * const lc824206xa_chg_det_psy[] = { "lc824206xa-charger-detect" };
576 
577 static const struct property_entry lenovo_yoga_tab2_1380_bq24190_props[] = {
578 	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lc824206xa_chg_det_psy),
579 	PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
580 	PROPERTY_ENTRY_BOOL("omit-battery-class"),
581 	PROPERTY_ENTRY_BOOL("disable-reset"),
582 	{ }
583 };
584 
585 static const struct software_node lenovo_yoga_tab2_1380_bq24190_node = {
586 	.properties = lenovo_yoga_tab2_1380_bq24190_props,
587 };
588 
589 /* For enabling the bq24190 5V boost based on id-pin */
590 static struct regulator_consumer_supply lc824206xa_consumer = {
591 	.supply = "vbus",
592 	.dev_name = "i2c-lc824206xa",
593 };
594 
595 static const struct regulator_init_data lenovo_yoga_tab2_1380_bq24190_vbus_init_data = {
596 	.constraints = {
597 		.name = "bq24190_vbus",
598 		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
599 	},
600 	.consumer_supplies = &lc824206xa_consumer,
601 	.num_consumer_supplies = 1,
602 };
603 
604 struct bq24190_platform_data lenovo_yoga_tab2_1380_bq24190_pdata = {
605 	.regulator_init_data = &lenovo_yoga_tab2_1380_bq24190_vbus_init_data,
606 };
607 
608 static const struct property_entry lenovo_yoga_tab2_1380_lc824206xa_props[] = {
609 	PROPERTY_ENTRY_BOOL("onnn,enable-miclr-for-dcp"),
610 	{ }
611 };
612 
613 static const struct software_node lenovo_yoga_tab2_1380_lc824206xa_node = {
614 	.properties = lenovo_yoga_tab2_1380_lc824206xa_props,
615 };
616 
617 static const char * const lenovo_yoga_tab2_1380_lms303d_mount_matrix[] = {
618 	"0", "-1", "0",
619 	"-1", "0", "0",
620 	"0", "0", "1"
621 };
622 
623 static const struct property_entry lenovo_yoga_tab2_1380_lms303d_props[] = {
624 	PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_1380_lms303d_mount_matrix),
625 	{ }
626 };
627 
628 static const struct software_node lenovo_yoga_tab2_1380_lms303d_node = {
629 	.properties = lenovo_yoga_tab2_1380_lms303d_props,
630 };
631 
632 static const struct x86_i2c_client_info lenovo_yoga_tab2_1380_i2c_clients[] __initconst = {
633 	{
634 		/* BQ27541 fuel-gauge */
635 		.board_info = {
636 			.type = "bq27541",
637 			.addr = 0x55,
638 			.dev_name = "bq27541",
639 			.swnode = &fg_bq24190_supply_node,
640 		},
641 		.adapter_path = "\\_SB_.I2C1",
642 	}, {
643 		/* bq24292i battery charger */
644 		.board_info = {
645 			.type = "bq24190",
646 			.addr = 0x6b,
647 			.dev_name = "bq24292i",
648 			.swnode = &lenovo_yoga_tab2_1380_bq24190_node,
649 			.platform_data = &lenovo_yoga_tab2_1380_bq24190_pdata,
650 		},
651 		.adapter_path = "\\_SB_.I2C1",
652 		.irq_data = {
653 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
654 			.chip = "INT33FC:02",
655 			.index = 2,
656 			.trigger = ACPI_EDGE_SENSITIVE,
657 			.polarity = ACPI_ACTIVE_HIGH,
658 			.con_id = "bq24292i_irq",
659 		},
660 	}, {
661 		/* LP8557 Backlight controller */
662 		.board_info = {
663 			.type = "lp8557",
664 			.addr = 0x2c,
665 			.dev_name = "lp8557",
666 			.platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
667 		},
668 		.adapter_path = "\\_SB_.I2C3",
669 	}, {
670 		/* LC824206XA Micro USB Switch */
671 		.board_info = {
672 			.type = "lc824206xa",
673 			.addr = 0x48,
674 			.dev_name = "lc824206xa",
675 			.swnode = &lenovo_yoga_tab2_1380_lc824206xa_node,
676 		},
677 		.adapter_path = "\\_SB_.I2C3",
678 		.irq_data = {
679 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
680 			.chip = "INT33FC:02",
681 			.index = 1,
682 			.trigger = ACPI_LEVEL_SENSITIVE,
683 			.polarity = ACPI_ACTIVE_LOW,
684 			.con_id = "lc824206xa_irq",
685 		},
686 	}, {
687 		/* AL3320A ambient light sensor */
688 		.board_info = {
689 			.type = "al3320a",
690 			.addr = 0x1c,
691 			.dev_name = "al3320a",
692 		},
693 		.adapter_path = "\\_SB_.I2C5",
694 	}, {
695 		/* LSM303DA accelerometer + magnetometer */
696 		.board_info = {
697 			.type = "lsm303d",
698 			.addr = 0x1d,
699 			.dev_name = "lsm303d",
700 			.swnode = &lenovo_yoga_tab2_1380_lms303d_node,
701 		},
702 		.adapter_path = "\\_SB_.I2C5",
703 	}, {
704 		/* Synaptics RMI touchscreen */
705 		.board_info = {
706 			.type = "rmi4_i2c",
707 			.addr = 0x38,
708 			.dev_name = "rmi4_i2c",
709 			.platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
710 		},
711 		.adapter_path = "\\_SB_.I2C6",
712 		.irq_data = {
713 			.type = X86_ACPI_IRQ_TYPE_APIC,
714 			.index = 0x45,
715 			.trigger = ACPI_EDGE_SENSITIVE,
716 			.polarity = ACPI_ACTIVE_HIGH,
717 		},
718 	}
719 };
720 
721 static const struct platform_device_info lenovo_yoga_tab2_1380_pdevs[] __initconst = {
722 	{
723 		/* For the Tablet 2 Pro 1380's custom fast charging driver */
724 		.name = "lenovo-yoga-tab2-pro-1380-fastcharger",
725 		.id = PLATFORM_DEVID_NONE,
726 	},
727 };
728 
729 const char * const lenovo_yoga_tab2_1380_modules[] __initconst = {
730 	"bq24190_charger",            /* For the Vbus regulator for lc824206xa */
731 	NULL
732 };
733 
lenovo_yoga_tab2_1380_init(struct device * dev)734 static int __init lenovo_yoga_tab2_1380_init(struct device *dev)
735 {
736 	int ret;
737 
738 	/* To verify that the DMI matching works vs the 830 / 1050 models */
739 	pr_info("detected Lenovo Yoga Tablet 2 Pro 1380F/L\n");
740 
741 	ret = lenovo_yoga_tab2_830_1050_init_codec();
742 	if (ret)
743 		return ret;
744 
745 	/* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off() */
746 	lenovo_yoga_tab2_830_1050_sys_off_handler =
747 		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
748 					 lenovo_yoga_tab2_830_1050_power_off, NULL);
749 	if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
750 		return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
751 
752 	return 0;
753 }
754 
755 static struct gpiod_lookup_table lenovo_yoga_tab2_1380_fc_gpios = {
756 	.dev_id = "serial0-0",
757 	.table = {
758 		GPIO_LOOKUP("INT33FC:00", 57, "uart3_txd", GPIO_ACTIVE_HIGH),
759 		GPIO_LOOKUP("INT33FC:00", 61, "uart3_rxd", GPIO_ACTIVE_HIGH),
760 		{ }
761 	},
762 };
763 
764 static struct gpiod_lookup_table * const lenovo_yoga_tab2_1380_gpios[] = {
765 	&lenovo_yoga_tab2_830_1050_codec_gpios,
766 	&lenovo_yoga_tab2_1380_fc_gpios,
767 	NULL
768 };
769 
770 const struct x86_dev_info lenovo_yoga_tab2_1380_info __initconst = {
771 	.i2c_client_info = lenovo_yoga_tab2_1380_i2c_clients,
772 	.i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_i2c_clients),
773 	.pdev_info = lenovo_yoga_tab2_1380_pdevs,
774 	.pdev_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_pdevs),
775 	.gpio_button = &lenovo_yoga_tab2_830_1050_lid,
776 	.gpio_button_count = 1,
777 	.gpiod_lookup_tables = lenovo_yoga_tab2_1380_gpios,
778 	.bat_swnode = &generic_lipo_hv_4v35_battery_node,
779 	.modules = lenovo_yoga_tab2_1380_modules,
780 	.init = lenovo_yoga_tab2_1380_init,
781 	.exit = lenovo_yoga_tab2_830_1050_exit,
782 };
783 
784 /* Lenovo Yoga Tab 3 Pro YT3-X90F */
785 
786 /*
787  * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers,
788  * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c.
789  */
790 static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" };
791 static const char * const bq25890_1_psy[] = { "bq25890-charger-1" };
792 
793 static const struct property_entry fg_bq25890_1_supply_props[] = {
794 	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy),
795 	{ }
796 };
797 
798 static const struct software_node fg_bq25890_1_supply_node = {
799 	.properties = fg_bq25890_1_supply_props,
800 };
801 
802 /* bq25892 charger settings for the flat LiPo battery behind the screen */
803 static const struct property_entry lenovo_yt3_bq25892_0_props[] = {
804 	PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers),
805 	PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40),
806 	PROPERTY_ENTRY_BOOL("linux,skip-reset"),
807 	/* Values taken from Android Factory Image */
808 	PROPERTY_ENTRY_U32("ti,charge-current", 2048000),
809 	PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
810 	PROPERTY_ENTRY_U32("ti,termination-current", 128000),
811 	PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
812 	PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000),
813 	PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
814 	PROPERTY_ENTRY_U32("ti,boost-max-current", 500000),
815 	PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
816 	{ }
817 };
818 
819 static const struct software_node lenovo_yt3_bq25892_0_node = {
820 	.properties = lenovo_yt3_bq25892_0_props,
821 };
822 
823 static const struct property_entry lenovo_yt3_hideep_ts_props[] = {
824 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
825 	PROPERTY_ENTRY_U32("touchscreen-size-y", 2560),
826 	PROPERTY_ENTRY_U32("touchscreen-max-pressure", 255),
827 	{ }
828 };
829 
830 static const struct software_node lenovo_yt3_hideep_ts_node = {
831 	.properties = lenovo_yt3_hideep_ts_props,
832 };
833 
834 static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
835 	{
836 		/* bq27500 fuel-gauge for the flat LiPo battery behind the screen */
837 		.board_info = {
838 			.type = "bq27500",
839 			.addr = 0x55,
840 			.dev_name = "bq27500_0",
841 			.swnode = &fg_bq25890_supply_node,
842 		},
843 		.adapter_path = "\\_SB_.PCI0.I2C1",
844 	}, {
845 		/* bq25892 charger for the flat LiPo battery behind the screen */
846 		.board_info = {
847 			.type = "bq25892",
848 			.addr = 0x6b,
849 			.dev_name = "bq25892_0",
850 			.swnode = &lenovo_yt3_bq25892_0_node,
851 		},
852 		.adapter_path = "\\_SB_.PCI0.I2C1",
853 		.irq_data = {
854 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
855 			.chip = "INT33FF:01",
856 			.index = 5,
857 			.trigger = ACPI_EDGE_SENSITIVE,
858 			.polarity = ACPI_ACTIVE_LOW,
859 			.con_id = "bq25892_0_irq",
860 		},
861 	}, {
862 		/* bq27500 fuel-gauge for the round Li-ion cells in the hinge */
863 		.board_info = {
864 			.type = "bq27500",
865 			.addr = 0x55,
866 			.dev_name = "bq27500_1",
867 			.swnode = &fg_bq25890_1_supply_node,
868 		},
869 		.adapter_path = "\\_SB_.PCI0.I2C2",
870 	}, {
871 		/* HiDeep IST520E Touchscreen */
872 		.board_info = {
873 			.type = "hideep_ts",
874 			.addr = 0x6c,
875 			.dev_name = "hideep_ts",
876 			.swnode = &lenovo_yt3_hideep_ts_node,
877 		},
878 		.adapter_path = "\\_SB_.PCI0.I2C6",
879 		.irq_data = {
880 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
881 			.chip = "INT33FF:03",
882 			.index = 77,
883 			.trigger = ACPI_LEVEL_SENSITIVE,
884 			.polarity = ACPI_ACTIVE_LOW,
885 			.con_id = "hideep_ts_irq",
886 		},
887 	}, {
888 		/* LP8557 Backlight controller */
889 		.board_info = {
890 			.type = "lp8557",
891 			.addr = 0x2c,
892 			.dev_name = "lp8557",
893 			.platform_data = &lenovo_lp8557_reg_only_pdata,
894 		},
895 		.adapter_path = "\\_SB_.PCI0.I2C1",
896 	}
897 };
898 
899 /*
900  * The AOSP 3.5 mm Headset: Accessory Specification gives the following values:
901  * Function A Play/Pause:           0 ohm
902  * Function D Voice assistant:    135 ohm
903  * Function B Volume Up           240 ohm
904  * Function C Volume Down         470 ohm
905  * Minimum Mic DC resistance     1000 ohm
906  * Minimum Ear speaker impedance   16 ohm
907  * Note the first max value below must be less then the min. speaker impedance,
908  * to allow CTIA/OMTP detection to work. The other max values are the closest
909  * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.
910  */
911 static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
912 	{ .max =  11, .key = KEY_PLAYPAUSE },
913 	{ .max = 186, .key = KEY_VOICECOMMAND },
914 	{ .max = 348, .key = KEY_VOLUMEUP },
915 	{ .max = 752, .key = KEY_VOLUMEDOWN },
916 };
917 
918 /* YT3 WM5102 arizona_micd_config comes from Android kernel sources */
919 static struct arizona_micd_config lenovo_yt3_wm5102_micd_config[] = {
920 	{ 0, 1, 0 },
921 	{ ARIZONA_ACCDET_SRC, 2, 1 },
922 };
923 
924 static struct arizona_pdata lenovo_yt3_wm5102_pdata = {
925 	.irq_flags = IRQF_TRIGGER_LOW,
926 	.micd_detect_debounce = 200,
927 	.micd_ranges = arizona_micd_aosp_ranges,
928 	.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges),
929 	.hpdet_channel = ARIZONA_ACCDET_MODE_HPL,
930 
931 	/* Below settings come from Android kernel sources */
932 	.micd_bias_start_time = 1,
933 	.micd_rate = 6,
934 	.micd_configs = lenovo_yt3_wm5102_micd_config,
935 	.num_micd_configs = ARRAY_SIZE(lenovo_yt3_wm5102_micd_config),
936 	.micbias = {
937 		[0] = { /* MICBIAS1 */
938 			.mV = 2800,
939 			.ext_cap = 1,
940 			.discharge = 1,
941 			.soft_start = 0,
942 			.bypass = 0,
943 		},
944 		[1] = { /* MICBIAS2 */
945 			.mV = 2800,
946 			.ext_cap = 1,
947 			.discharge = 1,
948 			.soft_start = 0,
949 			.bypass = 0,
950 		},
951 		[2] = { /* MICBIAS2 */
952 			.mV = 2800,
953 			.ext_cap = 1,
954 			.discharge = 1,
955 			.soft_start = 0,
956 			.bypass = 0,
957 		},
958 	},
959 };
960 
961 static const struct x86_spi_dev_info lenovo_yt3_spi_devs[] __initconst = {
962 	{
963 		/* WM5102 codec */
964 		.board_info = {
965 			.modalias = "wm5102",
966 			.platform_data = &lenovo_yt3_wm5102_pdata,
967 			.max_speed_hz = 5000000,
968 		},
969 		.ctrl_path = "\\_SB_.PCI0.SPI1",
970 		.irq_data = {
971 			.type = X86_ACPI_IRQ_TYPE_GPIOINT,
972 			.chip = "INT33FF:00",
973 			.index = 91,
974 			.trigger = ACPI_LEVEL_SENSITIVE,
975 			.polarity = ACPI_ACTIVE_LOW,
976 			.con_id = "wm5102_irq",
977 		},
978 	}
979 };
980 
lenovo_yt3_init(struct device * dev)981 static int __init lenovo_yt3_init(struct device *dev)
982 {
983 	int ret;
984 
985 	/*
986 	 * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins
987 	 * connected to GPIOs, rather then having them hardwired to the correct
988 	 * values as is normally done.
989 	 *
990 	 * The bq25890_charger driver controls these through I2C, but this only
991 	 * works if not overridden by the pins. Set these pins here:
992 	 * 1. Set /CE to 1 to allow charging.
993 	 * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of
994 	 *    the main "bq25892_1" charger is used when necessary.
995 	 */
996 
997 	/* /CE pin */
998 	ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, "bq25892_0_ce",
999 					   true, GPIOD_OUT_HIGH, NULL);
1000 	if (ret < 0)
1001 		return ret;
1002 
1003 	/* OTG pin */
1004 	ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, "bq25892_0_otg",
1005 					   false, GPIOD_OUT_LOW, NULL);
1006 	if (ret < 0)
1007 		return ret;
1008 
1009 	/* Enable the regulators used by the touchscreen */
1010 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
1011 	intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
1012 
1013 	return 0;
1014 }
1015 
1016 static struct gpiod_lookup_table lenovo_yt3_hideep_gpios = {
1017 	.dev_id = "i2c-hideep_ts",
1018 	.table = {
1019 		GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
1020 		{ }
1021 	},
1022 };
1023 
1024 static struct gpiod_lookup_table lenovo_yt3_wm5102_gpios = {
1025 	.dev_id = "spi1.0",
1026 	.table = {
1027 		GPIO_LOOKUP("INT33FF:00", 75, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
1028 		GPIO_LOOKUP("INT33FF:00", 81, "wlf,ldoena", GPIO_ACTIVE_HIGH),
1029 		GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_HIGH),
1030 		GPIO_LOOKUP("arizona", 2, "wlf,micd-pol", GPIO_ACTIVE_HIGH),
1031 		{ }
1032 	},
1033 };
1034 
1035 static struct gpiod_lookup_table * const lenovo_yt3_gpios[] = {
1036 	&lenovo_yt3_hideep_gpios,
1037 	&lenovo_yt3_wm5102_gpios,
1038 	NULL
1039 };
1040 
1041 const struct x86_dev_info lenovo_yt3_info __initconst = {
1042 	.i2c_client_info = lenovo_yt3_i2c_clients,
1043 	.i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients),
1044 	.spi_dev_info = lenovo_yt3_spi_devs,
1045 	.spi_dev_count = ARRAY_SIZE(lenovo_yt3_spi_devs),
1046 	.gpiod_lookup_tables = lenovo_yt3_gpios,
1047 	.init = lenovo_yt3_init,
1048 };
1049