1 // SPDX-License-Identifier: GPL-2.0-or-later
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
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
27 #include "shared-psy-info.h"
28 #include "x86-android-tablets.h"
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.
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.
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.
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.
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.
52 static struct lp855x_platform_data lenovo_lp8557_pwm_and_reg_pdata = {
53 .device_control = 0x86,
54 .initial_brightness = 128,
57 static struct lp855x_platform_data lenovo_lp8557_reg_only_pdata = {
58 .device_control = 0x85,
59 .initial_brightness = 128,
62 /* Lenovo Yoga Book X90F / X90L's Android factory img has everything hardcoded */
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),
70 static const struct software_node lenovo_yb1_x90_wacom_node = {
71 .properties = lenovo_yb1_x90_wacom_props,
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".
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"),
91 static const struct software_node lenovo_yb1_x90_hideep_ts_node = {
92 .properties = lenovo_yb1_x90_hideep_ts_props,
95 static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst = {
97 /* BQ27542 fuel-gauge */
101 .dev_name = "bq27542",
102 .swnode = &fg_bq25890_supply_node,
104 .adapter_path = "\\_SB_.PCI0.I2C1",
106 /* Goodix Touchscreen in keyboard half */
108 .type = "GDIX1001:00",
110 .dev_name = "goodix_ts",
112 .adapter_path = "\\_SB_.PCI0.I2C2",
114 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
115 .chip = "INT33FF:01",
117 .trigger = ACPI_EDGE_SENSITIVE,
118 .polarity = ACPI_ACTIVE_LOW,
119 .con_id = "goodix_ts_irq",
123 /* Wacom Digitizer in keyboard half */
125 .type = "hid-over-i2c",
128 .swnode = &lenovo_yb1_x90_wacom_node,
130 .adapter_path = "\\_SB_.PCI0.I2C4",
132 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
133 .chip = "INT33FF:01",
135 .trigger = ACPI_LEVEL_SENSITIVE,
136 .polarity = ACPI_ACTIVE_LOW,
137 .con_id = "wacom_irq",
140 /* LP8557 Backlight controller */
144 .dev_name = "lp8557",
145 .platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
147 .adapter_path = "\\_SB_.PCI0.I2C4",
149 /* HiDeep IST940E Touchscreen in display half */
153 .dev_name = "hideep_ts",
154 .swnode = &lenovo_yb1_x90_hideep_ts_node,
156 .adapter_path = "\\_SB_.PCI0.I2C6",
158 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
159 .chip = "INT33FF:03",
161 .trigger = ACPI_LEVEL_SENSITIVE,
162 .polarity = ACPI_ACTIVE_LOW,
163 .con_id = "hideep_ts_irq",
168 static const struct platform_device_info lenovo_yb1_x90_pdevs[] __initconst = {
170 .name = "yogabook-touch-kbd-digitizer-switch",
171 .id = PLATFORM_DEVID_NONE,
176 * DSDT says UART path is "\\_SB.PCIO.URT1" with a letter 'O' instead of
177 * the number '0' add the link manually.
179 static const struct x86_serdev_info lenovo_yb1_x90_serdevs[] __initconst = {
181 .ctrl_hid = "8086228A",
183 .ctrl_devname = "serial0",
184 .serdev_hid = "BCM2E1A",
188 static const struct x86_gpio_button lenovo_yb1_x90_lid __initconst = {
195 .debounce_interval = 50,
197 .chip = "INT33FF:02",
201 static struct gpiod_lookup_table lenovo_yb1_x90_goodix_gpios = {
202 .dev_id = "i2c-goodix_ts",
204 GPIO_LOOKUP("INT33FF:01", 53, "reset", GPIO_ACTIVE_HIGH),
205 GPIO_LOOKUP("INT33FF:01", 56, "irq", GPIO_ACTIVE_HIGH),
210 static struct gpiod_lookup_table lenovo_yb1_x90_hideep_gpios = {
211 .dev_id = "i2c-hideep_ts",
213 GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
218 static struct gpiod_lookup_table lenovo_yb1_x90_wacom_gpios = {
219 .dev_id = "i2c-wacom",
221 GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_LOW),
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,
233 static int __init lenovo_yb1_x90_init(struct device *dev)
235 /* Enable the regulators used by the touchscreens */
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);
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);
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);
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);
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,
265 /* Lenovo Yoga Book X91F/L Windows tablet needs manual instantiation of the fg client */
266 static const struct x86_i2c_client_info lenovo_yogabook_x91_i2c_clients[] __initconst = {
268 /* BQ27542 fuel-gauge */
272 .dev_name = "bq27542",
273 .swnode = &fg_bq25890_supply_node,
275 .adapter_path = "\\_SB_.PCI0.I2C1",
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),
284 /* Lenovo Yoga Tablet 2 1050F/L's Android factory img 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"),
293 static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
294 .properties = lenovo_yoga_tab2_830_1050_bq24190_props,
297 static const struct x86_gpio_button lenovo_yoga_tab2_830_1050_lid __initconst = {
304 .debounce_interval = 50,
306 .chip = "INT33FC:02",
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 = { };
313 static struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initdata = {
316 * This must be the first entry because lenovo_yoga_tab2_830_1050_init()
317 * may update its swnode. LSM303DA accelerometer + magnetometer.
322 .dev_name = "lsm303d",
324 .adapter_path = "\\_SB_.I2C5",
326 /* AL3320A ambient light sensor */
330 .dev_name = "al3320a",
332 .adapter_path = "\\_SB_.I2C5",
334 /* bq24292i battery charger */
338 .dev_name = "bq24292i",
339 .swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
340 .platform_data = &bq24190_pdata,
342 .adapter_path = "\\_SB_.I2C1",
344 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
345 .chip = "INT33FC:02",
347 .trigger = ACPI_EDGE_SENSITIVE,
348 .polarity = ACPI_ACTIVE_HIGH,
349 .con_id = "bq24292i_irq",
352 /* BQ27541 fuel-gauge */
356 .dev_name = "bq27541",
357 .swnode = &fg_bq24190_supply_node,
359 .adapter_path = "\\_SB_.I2C1",
361 /* Synaptics RMI touchscreen */
365 .dev_name = "rmi4_i2c",
366 .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
368 .adapter_path = "\\_SB_.I2C6",
370 .type = X86_ACPI_IRQ_TYPE_APIC,
372 .trigger = ACPI_EDGE_SENSITIVE,
373 .polarity = ACPI_ACTIVE_HIGH,
376 /* LP8557 Backlight controller */
380 .dev_name = "lp8557",
381 .platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
383 .adapter_path = "\\_SB_.I2C3",
387 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
388 .dev_id = "intel-int3496",
390 GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
391 GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
396 #define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
398 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = {
399 .dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME,
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),
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,
415 static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev);
416 static void lenovo_yoga_tab2_830_1050_exit(void);
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,
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,
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.
439 static const char * const lenovo_yoga_tab2_830_lms303d_mount_matrix[] = {
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),
450 static const struct software_node lenovo_yoga_tab2_830_lms303d_node = {
451 .properties = lenovo_yoga_tab2_830_lms303d_props,
454 static int __init lenovo_yoga_tab2_830_1050_init_touchscreen(void)
456 struct gpio_desc *gpiod;
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);
465 ret = gpiod_get_value_cansleep(gpiod);
467 pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
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;
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");
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;
487 static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
489 struct device *codec_dev;
490 struct pinctrl *pinctrl;
493 codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
494 LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
496 pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
500 ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
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;
510 /* We're done with the codec_dev now */
511 put_device(codec_dev);
513 lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
516 err_unregister_mappings:
517 pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
519 put_device(codec_dev);
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 powerbutton for 30 seconds *twice*
527 * followed by a normal 3 second press to recover. Avoid this by doing an EFI
530 static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
532 efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
537 static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev)
541 ret = lenovo_yoga_tab2_830_1050_init_touchscreen();
545 ret = lenovo_yoga_tab2_830_1050_init_codec();
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);
559 static void lenovo_yoga_tab2_830_1050_exit(void)
561 unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
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);
570 * Lenovo Yoga Tablet 2 Pro 1380F/L
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.
575 static const char * const lc824206xa_chg_det_psy[] = { "lc824206xa-charger-detect" };
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"),
585 static const struct software_node lenovo_yoga_tab2_1380_bq24190_node = {
586 .properties = lenovo_yoga_tab2_1380_bq24190_props,
589 /* For enabling the bq24190 5V boost based on id-pin */
590 static struct regulator_consumer_supply lc824206xa_consumer = {
592 .dev_name = "i2c-lc824206xa",
595 static const struct regulator_init_data lenovo_yoga_tab2_1380_bq24190_vbus_init_data = {
597 .name = "bq24190_vbus",
598 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
600 .consumer_supplies = &lc824206xa_consumer,
601 .num_consumer_supplies = 1,
604 struct bq24190_platform_data lenovo_yoga_tab2_1380_bq24190_pdata = {
605 .regulator_init_data = &lenovo_yoga_tab2_1380_bq24190_vbus_init_data,
608 static const struct property_entry lenovo_yoga_tab2_1380_lc824206xa_props[] = {
609 PROPERTY_ENTRY_BOOL("onnn,enable-miclr-for-dcp"),
613 static const struct software_node lenovo_yoga_tab2_1380_lc824206xa_node = {
614 .properties = lenovo_yoga_tab2_1380_lc824206xa_props,
617 static const char * const lenovo_yoga_tab2_1380_lms303d_mount_matrix[] = {
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),
628 static const struct software_node lenovo_yoga_tab2_1380_lms303d_node = {
629 .properties = lenovo_yoga_tab2_1380_lms303d_props,
632 static const struct x86_i2c_client_info lenovo_yoga_tab2_1380_i2c_clients[] __initconst = {
634 /* BQ27541 fuel-gauge */
638 .dev_name = "bq27541",
639 .swnode = &fg_bq24190_supply_node,
641 .adapter_path = "\\_SB_.I2C1",
643 /* bq24292i battery charger */
647 .dev_name = "bq24292i",
648 .swnode = &lenovo_yoga_tab2_1380_bq24190_node,
649 .platform_data = &lenovo_yoga_tab2_1380_bq24190_pdata,
651 .adapter_path = "\\_SB_.I2C1",
653 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
654 .chip = "INT33FC:02",
656 .trigger = ACPI_EDGE_SENSITIVE,
657 .polarity = ACPI_ACTIVE_HIGH,
658 .con_id = "bq24292i_irq",
661 /* LP8557 Backlight controller */
665 .dev_name = "lp8557",
666 .platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
668 .adapter_path = "\\_SB_.I2C3",
670 /* LC824206XA Micro USB Switch */
672 .type = "lc824206xa",
674 .dev_name = "lc824206xa",
675 .swnode = &lenovo_yoga_tab2_1380_lc824206xa_node,
677 .adapter_path = "\\_SB_.I2C3",
679 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
680 .chip = "INT33FC:02",
682 .trigger = ACPI_LEVEL_SENSITIVE,
683 .polarity = ACPI_ACTIVE_LOW,
684 .con_id = "lc824206xa_irq",
687 /* AL3320A ambient light sensor */
691 .dev_name = "al3320a",
693 .adapter_path = "\\_SB_.I2C5",
695 /* LSM303DA accelerometer + magnetometer */
699 .dev_name = "lsm303d",
700 .swnode = &lenovo_yoga_tab2_1380_lms303d_node,
702 .adapter_path = "\\_SB_.I2C5",
704 /* Synaptics RMI touchscreen */
708 .dev_name = "rmi4_i2c",
709 .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
711 .adapter_path = "\\_SB_.I2C6",
713 .type = X86_ACPI_IRQ_TYPE_APIC,
715 .trigger = ACPI_EDGE_SENSITIVE,
716 .polarity = ACPI_ACTIVE_HIGH,
721 static const struct platform_device_info lenovo_yoga_tab2_1380_pdevs[] __initconst = {
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,
729 const char * const lenovo_yoga_tab2_1380_modules[] __initconst = {
730 "bq24190_charger", /* For the Vbus regulator for lc824206xa */
734 static int __init lenovo_yoga_tab2_1380_init(struct device *dev)
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");
741 ret = lenovo_yoga_tab2_830_1050_init_codec();
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);
755 static struct gpiod_lookup_table lenovo_yoga_tab2_1380_fc_gpios = {
756 .dev_id = "serial0-0",
758 GPIO_LOOKUP("INT33FC:00", 57, "uart3_txd", GPIO_ACTIVE_HIGH),
759 GPIO_LOOKUP("INT33FC:00", 61, "uart3_rxd", GPIO_ACTIVE_HIGH),
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,
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,
784 /* Lenovo Yoga Tab 3 Pro YT3-X90F */
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.
790 static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" };
791 static const char * const bq25890_1_psy[] = { "bq25890-charger-1" };
793 static const struct property_entry fg_bq25890_1_supply_props[] = {
794 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy),
798 static const struct software_node fg_bq25890_1_supply_node = {
799 .properties = fg_bq25890_1_supply_props,
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"),
819 static const struct software_node lenovo_yt3_bq25892_0_node = {
820 .properties = lenovo_yt3_bq25892_0_props,
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),
830 static const struct software_node lenovo_yt3_hideep_ts_node = {
831 .properties = lenovo_yt3_hideep_ts_props,
834 static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
836 /* bq27500 fuel-gauge for the flat lipo battery behind the screen */
840 .dev_name = "bq27500_0",
841 .swnode = &fg_bq25890_supply_node,
843 .adapter_path = "\\_SB_.PCI0.I2C1",
845 /* bq25892 charger for the flat lipo battery behind the screen */
849 .dev_name = "bq25892_0",
850 .swnode = &lenovo_yt3_bq25892_0_node,
852 .adapter_path = "\\_SB_.PCI0.I2C1",
854 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
855 .chip = "INT33FF:01",
857 .trigger = ACPI_EDGE_SENSITIVE,
858 .polarity = ACPI_ACTIVE_LOW,
859 .con_id = "bq25892_0_irq",
862 /* bq27500 fuel-gauge for the round li-ion cells in the hinge */
866 .dev_name = "bq27500_1",
867 .swnode = &fg_bq25890_1_supply_node,
869 .adapter_path = "\\_SB_.PCI0.I2C2",
871 /* HiDeep IST520E Touchscreen */
875 .dev_name = "hideep_ts",
876 .swnode = &lenovo_yt3_hideep_ts_node,
878 .adapter_path = "\\_SB_.PCI0.I2C6",
880 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
881 .chip = "INT33FF:03",
883 .trigger = ACPI_LEVEL_SENSITIVE,
884 .polarity = ACPI_ACTIVE_LOW,
885 .con_id = "hideep_ts_irq",
888 /* LP8557 Backlight controller */
892 .dev_name = "lp8557",
893 .platform_data = &lenovo_lp8557_reg_only_pdata,
895 .adapter_path = "\\_SB_.PCI0.I2C1",
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.
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 },
918 /* YT3 WM5102 arizona_micd_config comes from Android kernel sources */
919 static struct arizona_micd_config lenovo_yt3_wm5102_micd_config[] = {
921 { ARIZONA_ACCDET_SRC, 2, 1 },
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,
931 /* Below settings come from Android kernel sources */
932 .micd_bias_start_time = 1,
934 .micd_configs = lenovo_yt3_wm5102_micd_config,
935 .num_micd_configs = ARRAY_SIZE(lenovo_yt3_wm5102_micd_config),
937 [0] = { /* MICBIAS1 */
944 [1] = { /* MICBIAS2 */
951 [2] = { /* MICBIAS2 */
961 static const struct x86_spi_dev_info lenovo_yt3_spi_devs[] __initconst = {
965 .modalias = "wm5102",
966 .platform_data = &lenovo_yt3_wm5102_pdata,
967 .max_speed_hz = 5000000,
969 .ctrl_path = "\\_SB_.PCI0.SPI1",
971 .type = X86_ACPI_IRQ_TYPE_GPIOINT,
972 .chip = "INT33FF:00",
974 .trigger = ACPI_LEVEL_SENSITIVE,
975 .polarity = ACPI_ACTIVE_LOW,
976 .con_id = "wm5102_irq",
981 static int __init lenovo_yt3_init(struct device *dev)
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.
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.
998 ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, "bq25892_0_ce",
999 true, GPIOD_OUT_HIGH, NULL);
1004 ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, "bq25892_0_otg",
1005 false, GPIOD_OUT_LOW, NULL);
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);
1016 static struct gpiod_lookup_table lenovo_yt3_hideep_gpios = {
1017 .dev_id = "i2c-hideep_ts",
1019 GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
1024 static struct gpiod_lookup_table lenovo_yt3_wm5102_gpios = {
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),
1035 static struct gpiod_lookup_table * const lenovo_yt3_gpios[] = {
1036 &lenovo_yt3_hideep_gpios,
1037 &lenovo_yt3_wm5102_gpios,
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,