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