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