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