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