mbox series

[v4,resend,00/20] power-suppy/i2c/extcon: Fix charger setup on Xiaomi Mi Pad 2 and Lenovo Yogabook

Message ID 20220130204557.15662-1-hdegoede@redhat.com
Headers show
Series power-suppy/i2c/extcon: Fix charger setup on Xiaomi Mi Pad 2 and Lenovo Yogabook | expand

Message

Hans de Goede Jan. 30, 2022, 8:45 p.m. UTC
Hi Sebastian,

Here is a resend of v4 of my patch series to fix the charger setup on
Xiaomi Mi Pad 2 and Lenovo Yogabook devices, as well as fix host/device
mode switching.

I'm resending this because this has not made it into 5.17, this resend has
been rebased on top of 5.17-rc1.

Since patches 14-20 rely on the power-supply changes from patch 1-13 and
since they all touch files which generally do not see much changes, the
intention is for this entire series to be merged through your (Sebastian's)
linux-power-supply tree. Patches 14-20 all have ackes from the relevant
subsystem maintainers for merging them through the linux-power-supply tree.

###

For more details on this series, here is some info from the v2
cover-letter:

So far almost all the kernel code surrounding the Cherry Trail Whiskey Cove
PMIC has been developed on the GPD win / pocket devices and it has various
assumption based on that. In the mean time I've learned (and gotten access
to) about 2 more designs and none of the 3 now known designs use a single
standard setup for the charger, fuel-gauge and other chips surrounding the
PMIC / charging+data USB port:

1. The GPD Win and GPD Pocket mini-laptops, these are really 2 models
but the Pocket re-uses the GPD Win's design in a different housing:

The WC PMIC is connected to a TI BQ24292i charger, paired with
a Maxim MAX17047 fuelgauge + a FUSB302 USB Type-C Controller +
a PI3USB30532 USB switch, for a fully functional Type-C port.

2. The Xiaomi Mi Pad 2:

The WC PMIC is connected to a TI BQ25890 charger, paired with
a TI BQ27520 fuelgauge, using the TI BQ25890 for BC1.2 charger type
detection, for a USB-2 only Type-C port without PD.

3. The Lenovo Yoga Book YB1-X90 / Lenovo Yoga Book YB1-X91 series:

The WC PMIC is connected to a TI BQ25892 charger, paired with
a TI BQ27542 fuelgauge, using the WC PMIC for BC1.2 charger type
detection and using the BQ25892's Mediatek Pump Express+ (1.0)


Unlike what is normal on X86 this diversity in designs is not handled /
abstracted away by the ACPI tables.

This series takes care of making sure that charging and device/host mode
switching also works on the Xiaomi Mi Pad 2 and the Lenovo Yogabook.

Patches  1-13: Prepare the bq25890 power_supply driver to fully support
               the Mi Pad 2 and the Yogabook. Note this includes a new
               version of 2 bq25890 patches send earlier by Yauhen Kharuzhy
Patch 14:      Adds the intel_cht_wc_get_model() helper
Patch 15:      Uses this intel_cht_wc_get_model() value to instantiate an
               i2c-client with the right type and properties for the charger
               IC used on the board (instead of harcoding the GPD values)
Patches 16-20: Modify the extcon code to provide charger-detection results
               to the charger driver and to take care of the Vbus boost
               regulator control (for host-mode) and device/host mode
               switching

I've tried to keep the power_supply patches as generic as possible while
focussing some of the special handling these boards need in the
WC PMIC MFD and cell drivers, which will only get loaded on these boards.

Regards,

Hans

p.s.

Sebastian, I also have another power-supply series pending
for merging into -next:
https://lore.kernel.org/linux-pm/20220106110608.66231-1-hdegoede@redhat.com/


Hans de Goede (17):
  power: supply: core: Refactor
    power_supply_set_input_current_limit_from_supplier()
  power: supply: bq25890: Add a bq25890_rw_init_data() helper
  power: supply: bq25890: Add support to skip reset at probe() /
    remove()
  power: supply: bq25890: Add support to read back the settings from the
    chip
  power: supply: bq25890: Enable charging on boards where we skip reset
  power: supply: bq25890: Drop dev->platform_data == NULL check
  power: supply: bq25890: Add bq25890_set_otg_cfg() helper
  power: supply: bq25890: Add support for registering the Vbus boost
    converter as a regulator
  power: supply: bq25890: On the bq25892 set the IINLIM based on
    external charger detection
  power: supply: bq25890: Use the devm_regmap_field_bulk_alloc() helper
  mfd: intel_soc_pmic_chtwc: Add cht_wc_model data to struct
    intel_soc_pmic
  i2c: cht-wc: Make charger i2c-client instantiation board/device-model
    specific
  extcon: intel-cht-wc: Use new cht_wc_model intel_soc_pmic field
  extcon: intel-cht-wc: Support devs with Micro-B / USB-2 only Type-C
    connectors
  extcon: intel-cht-wc: Refactor cht_wc_extcon_get_charger()
  extcon: intel-cht-wc: Add support for registering a power_supply
    class-device
  extcon: intel-cht-wc: Report RID_A for ACA adapters

Yauhen Kharuzhy (3):
  power: supply: bq25890: Rename IILIM field to IINLIM
  power: supply: bq25890: Reduce reported CONSTANT_CHARGE_CURRENT_MAX
    for low temperatures
  power: supply: bq25890: Support higher charging voltages through Pump
    Express+ protocol

 drivers/extcon/Kconfig                   |   2 +
 drivers/extcon/extcon-intel-cht-wc.c     | 240 ++++++++++++--
 drivers/i2c/busses/i2c-cht-wc.c          | 120 +++++--
 drivers/mfd/intel_soc_pmic_chtwc.c       |  40 +++
 drivers/power/supply/bq24190_charger.c   |  10 +-
 drivers/power/supply/bq25890_charger.c   | 396 ++++++++++++++++++-----
 drivers/power/supply/power_supply_core.c |  57 ++--
 include/linux/mfd/intel_soc_pmic.h       |   8 +
 include/linux/power/bq25890_charger.h    |  15 +
 include/linux/power_supply.h             |   5 +-
 10 files changed, 742 insertions(+), 151 deletions(-)
 create mode 100644 include/linux/power/bq25890_charger.h

Comments

Andy Shevchenko Jan. 31, 2022, 1:50 p.m. UTC | #1
On Sun, Jan 30, 2022 at 09:45:52PM +0100, Hans de Goede wrote:
> The i2c-controller on the Cherry Trail - Whiskey Cove PMIC is special
> in that it is always connected to the I2C charger IC of the board on
> which the PMIC is used; and the charger IC is not described in ACPI,
> so the i2c-cht-wc code needs to instantiate an i2c-client for it itself.
> 
> So far this was hardcoded to instantiate an i2c-client for the
> bq24292i, with all properties, etc. set to match how this charger
> is used on the GPD win and GPD pocket devices.
> 
> There is a rudimentary check to make sure the ACPI tables are at least
> somewhat as expected, but this is far from accurate, leading to
> a wrong i2c-client being instantiated for the charger on some boards.
> 
> Switch to the new DMI based intel_cht_wc_get_model() helper which is
> exported by the MFD driver for the CHT Whiskey Cove PMIC to help PMIC
> cell drivers like the i2c-cht-wc code reliably detect which board
> they are running on.
> 
> And add board_info for the charger ICs as found on the other 2 known
> boards with a Whisky Cove PMIC.
> 
> This has been tested on all 3 known boards.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

> Acked-by: Wolfram Sang <wsa@kernel.org>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> Changes in v3:
> - Add Wolfram's Ack for taking this upstream through another tree
>   then the i2c tree
> - Some minor tweaks / spelling fixes based on Andy's review
> ---
>  drivers/i2c/busses/i2c-cht-wc.c | 120 +++++++++++++++++++++++++++-----
>  1 file changed, 102 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c
> index 1cf68f85b2e1..54e909f9eab6 100644
> --- a/drivers/i2c/busses/i2c-cht-wc.c
> +++ b/drivers/i2c/busses/i2c-cht-wc.c
> @@ -18,6 +18,7 @@
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
>  #include <linux/power/bq24190_charger.h>
> +#include <linux/power/bq25890_charger.h>
>  #include <linux/slab.h>
>  
>  #define CHT_WC_I2C_CTRL			0x5e24
> @@ -270,6 +271,7 @@ static const struct irq_chip cht_wc_i2c_irq_chip = {
>  	.name			= "cht_wc_ext_chrg_irq_chip",
>  };
>  
> +/********** GPD Win / Pocket charger IC settings **********/
>  static const char * const bq24190_suppliers[] = {
>  	"tcpm-source-psy-i2c-fusb302" };
>  
> @@ -304,17 +306,92 @@ static struct bq24190_platform_data bq24190_pdata = {
>  	.regulator_init_data = &bq24190_vbus_init_data,
>  };
>  
> +static struct i2c_board_info gpd_win_board_info = {
> +	.type = "bq24190",
> +	.addr = 0x6b,
> +	.dev_name = "bq24190",
> +	.swnode = &bq24190_node,
> +	.platform_data = &bq24190_pdata,
> +};
> +
> +/********** Xiaomi Mi Pad 2 charger IC settings  **********/
> +static struct regulator_consumer_supply bq2589x_vbus_consumer = {
> +	.supply = "vbus",
> +	.dev_name = "cht_wcove_pwrsrc",
> +};
> +
> +static const struct regulator_init_data bq2589x_vbus_init_data = {
> +	.constraints = {
> +		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
> +	},
> +	.consumer_supplies = &bq2589x_vbus_consumer,
> +	.num_consumer_supplies = 1,
> +};
> +
> +static struct bq25890_platform_data bq2589x_pdata = {
> +	.regulator_init_data = &bq2589x_vbus_init_data,
> +};
> +
> +static const struct property_entry xiaomi_mipad2_props[] = {
> +	PROPERTY_ENTRY_BOOL("linux,skip-reset"),
> +	PROPERTY_ENTRY_BOOL("linux,read-back-settings"),
> +	{ }
> +};
> +
> +static const struct software_node xiaomi_mipad2_node = {
> +	.properties = xiaomi_mipad2_props,
> +};
> +
> +static struct i2c_board_info xiaomi_mipad2_board_info = {
> +	.type = "bq25890",
> +	.addr = 0x6a,
> +	.dev_name = "bq25890",
> +	.swnode = &xiaomi_mipad2_node,
> +	.platform_data = &bq2589x_pdata,
> +};
> +
> +/********** Lenovo Yogabook YB1-X90F/-X91F/-X91L charger settings **********/
> +static const char * const lenovo_yb1_bq25892_suppliers[] = { "cht_wcove_pwrsrc" };
> +
> +static const struct property_entry lenovo_yb1_bq25892_props[] = {
> +	PROPERTY_ENTRY_STRING_ARRAY("supplied-from",
> +				    lenovo_yb1_bq25892_suppliers),
> +	PROPERTY_ENTRY_U32("linux,pump-express-vbus-max", 12000000),
> +	PROPERTY_ENTRY_BOOL("linux,skip-reset"),
> +	/*
> +	 * The firmware sets everything to the defaults, which leads to a
> +	 * somewhat low charge-current of 2048mA and worse to a battery-voltage
> +	 * of 4.2V instead of 4.35V (when booted without a charger connected).
> +	 * Use our own values instead of "linux,read-back-settings" to fix this.
> +	 */
> +	PROPERTY_ENTRY_U32("ti,charge-current", 4224000),
> +	PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
> +	PROPERTY_ENTRY_U32("ti,termination-current", 256000),
> +	PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
> +	PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3500000),
> +	PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
> +	PROPERTY_ENTRY_U32("ti,boost-max-current", 1400000),
> +	PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
> +	{ }
> +};
> +
> +static const struct software_node lenovo_yb1_bq25892_node = {
> +	.properties = lenovo_yb1_bq25892_props,
> +};
> +
> +static struct i2c_board_info lenovo_yogabook1_board_info = {
> +	.type = "bq25892",
> +	.addr = 0x6b,
> +	.dev_name = "bq25892",
> +	.swnode = &lenovo_yb1_bq25892_node,
> +	.platform_data = &bq2589x_pdata,
> +};
> +
>  static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
>  {
>  	struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
> +	struct i2c_board_info *board_info = NULL;
>  	struct cht_wc_i2c_adap *adap;
> -	struct i2c_board_info board_info = {
> -		.type = "bq24190",
> -		.addr = 0x6b,
> -		.dev_name = "bq24190",
> -		.swnode = &bq24190_node,
> -		.platform_data = &bq24190_pdata,
> -	};
>  	int ret, reg, irq;
>  
>  	irq = platform_get_irq(pdev, 0);
> @@ -379,17 +456,24 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto remove_irq_domain;
>  
> -	/*
> -	 * Normally the Whiskey Cove PMIC is paired with a TI bq24292i charger,
> -	 * connected to this i2c bus, and a max17047 fuel-gauge and a fusb302
> -	 * USB Type-C controller connected to another i2c bus. In this setup
> -	 * the max17047 and fusb302 devices are enumerated through an INT33FE
> -	 * ACPI device. If this device is present register an i2c-client for
> -	 * the TI bq24292i charger.
> -	 */
> -	if (acpi_dev_present("INT33FE", NULL, -1)) {
> -		board_info.irq = adap->client_irq;
> -		adap->client = i2c_new_client_device(&adap->adapter, &board_info);
> +	switch (pmic->cht_wc_model) {
> +	case INTEL_CHT_WC_GPD_WIN_POCKET:
> +		board_info = &gpd_win_board_info;
> +		break;
> +	case INTEL_CHT_WC_XIAOMI_MIPAD2:
> +		board_info = &xiaomi_mipad2_board_info;
> +		break;
> +	case INTEL_CHT_WC_LENOVO_YOGABOOK1:
> +		board_info = &lenovo_yogabook1_board_info;
> +		break;
> +	default:
> +		dev_warn(&pdev->dev, "Unknown model, not instantiating charger device\n");
> +		break;
> +	}
> +
> +	if (board_info) {
> +		board_info->irq = adap->client_irq;
> +		adap->client = i2c_new_client_device(&adap->adapter, board_info);
>  		if (IS_ERR(adap->client)) {
>  			ret = PTR_ERR(adap->client);
>  			goto del_adapter;
> -- 
> 2.33.1
>
Andy Shevchenko Jan. 31, 2022, 1:56 p.m. UTC | #2
On Sun, Jan 30, 2022 at 09:45:55PM +0100, Hans de Goede wrote:
> This is a preparation patch for adding support for registering
> a power_supply class device.
> 
> Setting usbsrc to "CHT_WC_USBSRC_TYPE_SDP << CHT_WC_USBSRC_TYPE_SHIFT"
> will make the following switch-case return EXTCON_CHG_USB_SDP
> just as before, so there is no functional change.

...

> -		return EXTCON_CHG_USB_SDP; /* Save fallback */

> +		/* Save fallback */

I see it's in the previous code, but what does it mean?
I would read it as "Safe fallback", bit I have no clue.
Hans de Goede Jan. 31, 2022, 3:22 p.m. UTC | #3
Hi,

On 1/31/22 14:56, Andy Shevchenko wrote:
> On Sun, Jan 30, 2022 at 09:45:55PM +0100, Hans de Goede wrote:
>> This is a preparation patch for adding support for registering
>> a power_supply class device.
>>
>> Setting usbsrc to "CHT_WC_USBSRC_TYPE_SDP << CHT_WC_USBSRC_TYPE_SHIFT"
>> will make the following switch-case return EXTCON_CHG_USB_SDP
>> just as before, so there is no functional change.
> 
> ...
> 
>> -		return EXTCON_CHG_USB_SDP; /* Save fallback */
> 
>> +		/* Save fallback */
> 
> I see it's in the previous code, but what does it mean?
> I would read it as "Safe fallback", bit I have no clue.

Ah yes that should be safe not save, sorry will fix for v5.

Regards,

Hans