diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/platform/x86/x86-android-tablets.c | 135 |
1 files changed, 134 insertions, 1 deletions
diff --git a/drivers/platform/x86/x86-android-tablets.c b/drivers/platform/x86/x86-android-tablets.c index f04e06eeb958..bbfae1395e18 100644 --- a/drivers/platform/x86/x86-android-tablets.c +++ b/drivers/platform/x86/x86-android-tablets.c @@ -5,7 +5,7 @@ * devices typically have a bunch of things hardcoded, rather than specified * in their DSDT. * - * Copyright (C) 2021 Hans de Goede <hdegoede@redhat.com> + * Copyright (C) 2021-2022 Hans de Goede <hdegoede@redhat.com> */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -987,6 +987,130 @@ static void lenovo_yoga_tab2_830_1050_exit(void) } } +/* Lenovo Yoga Tab 3 Pro YT3-X90F */ + +/* + * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers, + * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c. + */ +static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" }; +static const char * const bq25890_1_psy[] = { "bq25890-charger-1" }; + +static const struct property_entry fg_bq25890_1_supply_props[] = { + PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy), + { } +}; + +static const struct software_node fg_bq25890_1_supply_node = { + .properties = fg_bq25890_1_supply_props, +}; + +/* bq25892 charger settings for the flat lipo battery behind the screen */ +static const struct property_entry lenovo_yt3_bq25892_0_props[] = { + PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers), + PROPERTY_ENTRY_STRING("linux,power-supply-name", "bq25892-second-chrg"), + PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40), + PROPERTY_ENTRY_BOOL("linux,skip-reset"), + /* Values taken from Android Factory Image */ + PROPERTY_ENTRY_U32("ti,charge-current", 2048000), + PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000), + PROPERTY_ENTRY_U32("ti,termination-current", 128000), + PROPERTY_ENTRY_U32("ti,precharge-current", 128000), + PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000), + PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000), + PROPERTY_ENTRY_U32("ti,boost-max-current", 500000), + PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"), + { } +}; + +static const struct software_node lenovo_yt3_bq25892_0_node = { + .properties = lenovo_yt3_bq25892_0_props, +}; + +static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = { + { + /* bq27500 fuel-gauge for the flat lipo battery behind the screen */ + .board_info = { + .type = "bq27500", + .addr = 0x55, + .dev_name = "bq27500_0", + .swnode = &fg_bq25890_supply_node, + }, + .adapter_path = "\\_SB_.PCI0.I2C1", + }, { + /* bq25892 charger for the flat lipo battery behind the screen */ + .board_info = { + .type = "bq25892", + .addr = 0x6b, + .dev_name = "bq25892_0", + .swnode = &lenovo_yt3_bq25892_0_node, + }, + .adapter_path = "\\_SB_.PCI0.I2C1", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_GPIOINT, + .chip = "INT33FF:01", + .index = 5, + .trigger = ACPI_EDGE_SENSITIVE, + .polarity = ACPI_ACTIVE_LOW, + }, + }, { + /* bq27500 fuel-gauge for the round li-ion cells in the hinge */ + .board_info = { + .type = "bq27500", + .addr = 0x55, + .dev_name = "bq27500_1", + .swnode = &fg_bq25890_1_supply_node, + }, + .adapter_path = "\\_SB_.PCI0.I2C2", + } +}; + +static int __init lenovo_yt3_init(void) +{ + struct gpio_desc *gpiod; + int ret; + + /* + * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins + * connected to GPIOs, rather then having them hardwired to the correct + * values as is normally done. + * + * The bq25890_charger driver controls these through I2C, but this only + * works if not overridden by the pins. Set these pins here: + * 1. Set /CE to 0 to allow charging. + * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of + * the main "bq25892_1" charger is used when necessary. + */ + + /* /CE pin */ + ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, &gpiod); + if (ret < 0) + return ret; + + /* + * The gpio_desc returned by x86_android_tablet_get_gpiod() is a "raw" + * gpio_desc, that is there is no way to pass lookup-flags like + * GPIO_ACTIVE_LOW. Set the GPIO to 0 here to enable charging since + * the /CE pin is active-low, but not marked as such in the gpio_desc. + */ + gpiod_set_value(gpiod, 0); + + /* OTG pin */ + ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, &gpiod); + if (ret < 0) + return ret; + + gpiod_set_value(gpiod, 0); + + return 0; +} + +static const struct x86_dev_info lenovo_yt3_info __initconst = { + .i2c_client_info = lenovo_yt3_i2c_clients, + .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients), + .init = lenovo_yt3_init, +}; + /* Medion Lifetab S10346 tablets have an Android factory img with everything hardcoded */ static const char * const medion_lifetab_s10346_accel_mount_matrix[] = { "0", "1", "0", @@ -1328,6 +1452,15 @@ static const struct dmi_system_id x86_android_tablet_ids[] __initconst = { .driver_data = (void *)&lenovo_yoga_tab2_830_1050_info, }, { + /* Lenovo Yoga Tab 3 Pro YT3-X90F */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), + }, + .driver_data = (void *)&lenovo_yt3_info, + }, + { /* Medion Lifetab S10346 */ .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), |