Skip to content

Commit

Permalink
platform/x86: x86-android-tablets: Add Lenovo Yoga Tab 3 (YT3-X90F) c…
Browse files Browse the repository at this point in the history
…harger + fuel-gauge data

[ Upstream commit b6c14ff ]

The Lenovo Yoga Tab 3 (YT3-X90F) is an Intel Cherry Trail based tablet
which ships with Android as Factory OS. Its DSDT contains a bunch of I2C
devices which are not actually there, causing various resource conflicts.
Use acpi_quirk_skip_i2c_client_enumeration() to not enumerate these.

The YT3-X90F has quite a bit of exotic hardware, this adds initial
support by manually instantiating the i2c-clients for the 2 charger +
2 fuel-gauge chips used for the 2 batteries.

Support for other parts of the hw will be added by follow-up patches.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20221127182458.104528-1-hdegoede@redhat.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
jwrdegoede authored and gregkh committed Jan 7, 2023
1 parent 5a2798e commit c693355
Showing 1 changed file with 134 additions and 1 deletion.
135 changes: 134 additions & 1 deletion drivers/platform/x86/x86-android-tablets.c
Expand Up @@ -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
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -1327,6 +1451,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 = {
Expand Down

0 comments on commit c693355

Please sign in to comment.