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
8 * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com>
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 image 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 fuel-gauge 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 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"),
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 power button 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
,