1049 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Board info for Lenovo X86 tablets which ship with Android as the factory image4 * and which have broken DSDT tables. The factory kernels shipped on these5 * devices typically have a bunch of things hardcoded, rather than specified6 * in their DSDT.7 *8 * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com>9 */10 11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt12 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 PWM32 * 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-standard34 * 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 the37 * 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 and40 * 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 backlight44 * 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 of47 * much less then 100%, severely limiting max brightness. In this case48 * the LP8557 should be configured to only take the I2C register into49 * account and the i915 driver must turn off the panel and the backlight50 * separately using e.g. VBT MIPI sequences to turn off the backlight.51 */52static struct lp855x_platform_data lenovo_lp8557_pwm_and_reg_pdata = {53 .device_control = 0x86,54 .initial_brightness = 128,55};56 57static 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 64static 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 70static 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 protocol76 * reports ABS_MT_PRESSURE and ABS_MT_TOUCH_MAJOR which are not reported in HID77 * 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 */83static 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 91static const struct software_node lenovo_yb1_x90_hideep_ts_node = {92 .properties = lenovo_yb1_x90_hideep_ts_props,93};94 95static 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 168static 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 of177 * the number '0' add the link manually.178 */179static 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 188static 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 201static 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 210static 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 218static 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 226static 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 NULL231};232 233static 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 252const 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 */266static 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 279const 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 */285static 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 293static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {294 .properties = lenovo_yoga_tab2_830_1050_bq24190_props,295};296 297static 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() */311static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };312 313static 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 387static 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 398static 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 409static 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 NULL413};414 415static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev);416static void lenovo_yoga_tab2_830_1050_exit(void);417 418const 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 same434 * 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 for437 * the 90° rotation of the LCD vs the frame.438 */439static const char * const lenovo_yoga_tab2_830_lms303d_mount_matrix[] = {440 "0", "1", "0",441 "-1", "0", "0",442 "0", "0", "1"443};444 445static 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 450static const struct software_node lenovo_yoga_tab2_830_lms303d_node = {451 .properties = lenovo_yoga_tab2_830_lms303d_props,452};453 454static 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 */480static 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 484static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;485static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;486 487static 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 516err_unregister_mappings:517 pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);518err_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 tablets526 * 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 EFI528 * poweroff instead.529 */530static 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 537static 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 559static 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/L571 *572 * The Lenovo Yoga Tablet 2 Pro 1380F/L mostly has the same design as the 830F/L573 * and the 1050F/L so this re-uses some of the handling for that from above.574 */575static const char * const lc824206xa_chg_det_psy[] = { "lc824206xa-charger-detect" };576 577static 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 585static 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 */590static struct regulator_consumer_supply lc824206xa_consumer = {591 .supply = "vbus",592 .dev_name = "i2c-lc824206xa",593};594 595static 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 604struct bq24190_platform_data lenovo_yoga_tab2_1380_bq24190_pdata = {605 .regulator_init_data = &lenovo_yoga_tab2_1380_bq24190_vbus_init_data,606};607 608static const struct property_entry lenovo_yoga_tab2_1380_lc824206xa_props[] = {609 PROPERTY_ENTRY_BOOL("onnn,enable-miclr-for-dcp"),610 { }611};612 613static const struct software_node lenovo_yoga_tab2_1380_lc824206xa_node = {614 .properties = lenovo_yoga_tab2_1380_lc824206xa_props,615};616 617static const char * const lenovo_yoga_tab2_1380_lms303d_mount_matrix[] = {618 "0", "-1", "0",619 "-1", "0", "0",620 "0", "0", "1"621};622 623static 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 628static const struct software_node lenovo_yoga_tab2_1380_lms303d_node = {629 .properties = lenovo_yoga_tab2_1380_lms303d_props,630};631 632static 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 721static 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 729const char * const lenovo_yoga_tab2_1380_modules[] __initconst = {730 "bq24190_charger", /* For the Vbus regulator for lc824206xa */731 NULL732};733 734static 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 755static 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 764static 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 NULL768};769 770const 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 */790static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" };791static const char * const bq25890_1_psy[] = { "bq25890-charger-1" };792 793static const struct property_entry fg_bq25890_1_supply_props[] = {794 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy),795 { }796};797 798static 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 */803static 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 819static const struct software_node lenovo_yt3_bq25892_0_node = {820 .properties = lenovo_yt3_bq25892_0_props,821};822 823static 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 830static const struct software_node lenovo_yt3_hideep_ts_node = {831 .properties = lenovo_yt3_hideep_ts_props,832};833 834static 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 ohm902 * Function D Voice assistant: 135 ohm903 * Function B Volume Up 240 ohm904 * Function C Volume Down 470 ohm905 * Minimum Mic DC resistance 1000 ohm906 * Minimum Ear speaker impedance 16 ohm907 * 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 closest909 * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.910 */911static 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 */919static struct arizona_micd_config lenovo_yt3_wm5102_micd_config[] = {920 { 0, 1, 0 },921 { ARIZONA_ACCDET_SRC, 2, 1 },922};923 924static 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 961static 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 981static 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 pins987 * connected to GPIOs, rather then having them hardwired to the correct988 * values as is normally done.989 *990 * The bq25890_charger driver controls these through I2C, but this only991 * 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 of994 * 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 1016static 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 1024static 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 1035static struct gpiod_lookup_table * const lenovo_yt3_gpios[] = {1036 &lenovo_yt3_hideep_gpios,1037 &lenovo_yt3_wm5102_gpios,1038 NULL1039};1040 1041const 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