diff mbox series

[v4,14/20] mfd: intel_soc_pmic_chtwc: Add cht_wc_model data to struct intel_soc_pmic

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

Commit Message

Hans de Goede Dec. 6, 2021, 9:33 a.m. UTC
Tablet / laptop designs using an Intel Cherry Trail x86 main SoC with
an Intel Whiskey Cove PMIC do not use a single standard setup for
the charger, fuel-gauge and other chips surrounding the PMIC /
charging+data USB port.

Unlike what is normal on x86 this diversity in designs is not handled
by the ACPI tables. On 2 of the 3 known designs there are no standard
(PNP0C0A) ACPI battery devices and on the 3th design the ACPI battery
device does not work under Linux due to it requiring non-standard
and undocumented ACPI behavior.

So to make things work under Linux we use native charger and fuel-gauge
drivers on these devices, re-using the native drivers used on ARM boards
with the same charger / fuel-gauge ICs.

This requires various MFD-cell drivers for the CHT-WC PMIC cells to
know which model they are exactly running on so that they can e.g.
instantiate an I2C-client for the right model charger-IC (the charger
is connected to an I2C-controller which is part of the PMIC).

Rather then duplicating DMI-id matching to check which model we are
running on in each MFD-cell driver, add a check for this to the
shared drivers/mfd/intel_soc_pmic_chtwc.c code by using a
DMI table for all 3 known models:

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)
support to enable charging with up to 12V through a micro-USB port.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v4:
- Put '{' and comment of DMI entries on separate lines (requested by Lee)
- Drop comment on terminating empty entry in DMI table

Changes in v3:
- Store the model in struct intel_soc_pmic instead of adding a helper
  function to retreive it

Changes in v2:
- New patch in v2 of this patch-set
---
 drivers/mfd/intel_soc_pmic_chtwc.c | 40 ++++++++++++++++++++++++++++++
 include/linux/mfd/intel_soc_pmic.h |  8 ++++++
 2 files changed, 48 insertions(+)

Comments

Andy Shevchenko Dec. 6, 2021, 7:55 p.m. UTC | #1
On Mon, Dec 6, 2021 at 11:35 AM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Tablet / laptop designs using an Intel Cherry Trail x86 main SoC with
> an Intel Whiskey Cove PMIC do not use a single standard setup for
> the charger, fuel-gauge and other chips surrounding the PMIC /
> charging+data USB port.
>
> Unlike what is normal on x86 this diversity in designs is not handled
> by the ACPI tables. On 2 of the 3 known designs there are no standard
> (PNP0C0A) ACPI battery devices and on the 3th design the ACPI battery
> device does not work under Linux due to it requiring non-standard
> and undocumented ACPI behavior.
>
> So to make things work under Linux we use native charger and fuel-gauge
> drivers on these devices, re-using the native drivers used on ARM boards
> with the same charger / fuel-gauge ICs.
>
> This requires various MFD-cell drivers for the CHT-WC PMIC cells to
> know which model they are exactly running on so that they can e.g.
> instantiate an I2C-client for the right model charger-IC (the charger
> is connected to an I2C-controller which is part of the PMIC).
>
> Rather then duplicating DMI-id matching to check which model we are
> running on in each MFD-cell driver, add a check for this to the
> shared drivers/mfd/intel_soc_pmic_chtwc.c code by using a
> DMI table for all 3 known models:
>
> 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)
> support to enable charging with up to 12V through a micro-USB port.

...

> +enum intel_cht_wc_models {
> +       INTEL_CHT_WC_UNKNOWN,
> +       INTEL_CHT_WC_GPD_WIN_POCKET,
> +       INTEL_CHT_WC_XIAOMI_MIPAD2,
> +       INTEL_CHT_WC_LENOVO_YOGABOOK1,
> +};

...

> +       enum intel_cht_wc_models cht_wc_model;

I'm wondering what will you do when something similar will be needed
for another PMIC?

I see possible solutions to eliminate additional churn:
- make just one enum for all models (can be done now, can be renamed later)
- make a union if we have such situation

because I wouldn't like to have another field for each possible
variant of PMIC in the generic structure.

Hence the question, does it make sense to just name it (enum and
member) less cht_wc oriented?
Andy Shevchenko Dec. 6, 2021, 10:04 p.m. UTC | #2
On Mon, Dec 6, 2021 at 11:46 PM Hans de Goede <hdegoede@redhat.com> wrote:
> On 12/6/21 20:55, Andy Shevchenko wrote:
> > On Mon, Dec 6, 2021 at 11:35 AM Hans de Goede <hdegoede@redhat.com> wrote:
> >>
> >> Tablet / laptop designs using an Intel Cherry Trail x86 main SoC with
> >> an Intel Whiskey Cove PMIC do not use a single standard setup for
> >> the charger, fuel-gauge and other chips surrounding the PMIC /
> >> charging+data USB port.
> >>
> >> Unlike what is normal on x86 this diversity in designs is not handled
> >> by the ACPI tables. On 2 of the 3 known designs there are no standard
> >> (PNP0C0A) ACPI battery devices and on the 3th design the ACPI battery
> >> device does not work under Linux due to it requiring non-standard
> >> and undocumented ACPI behavior.
> >>
> >> So to make things work under Linux we use native charger and fuel-gauge
> >> drivers on these devices, re-using the native drivers used on ARM boards
> >> with the same charger / fuel-gauge ICs.
> >>
> >> This requires various MFD-cell drivers for the CHT-WC PMIC cells to
> >> know which model they are exactly running on so that they can e.g.
> >> instantiate an I2C-client for the right model charger-IC (the charger
> >> is connected to an I2C-controller which is part of the PMIC).
> >>
> >> Rather then duplicating DMI-id matching to check which model we are
> >> running on in each MFD-cell driver, add a check for this to the
> >> shared drivers/mfd/intel_soc_pmic_chtwc.c code by using a
> >> DMI table for all 3 known models:
> >>
> >> 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)
> >> support to enable charging with up to 12V through a micro-USB port.
> >
> > ...
> >
> >> +enum intel_cht_wc_models {
> >> +       INTEL_CHT_WC_UNKNOWN,
> >> +       INTEL_CHT_WC_GPD_WIN_POCKET,
> >> +       INTEL_CHT_WC_XIAOMI_MIPAD2,
> >> +       INTEL_CHT_WC_LENOVO_YOGABOOK1,
> >> +};
> >
> > ...
> >
> >> +       enum intel_cht_wc_models cht_wc_model;
> >
> > I'm wondering what will you do when something similar will be needed
> > for another PMIC?
> >
> > I see possible solutions to eliminate additional churn:
> > - make just one enum for all models (can be done now, can be renamed later)
> > - make a union if we have such situation
> >
> > because I wouldn't like to have another field for each possible
> > variant of PMIC in the generic structure.
> >
> > Hence the question, does it make sense to just name it (enum and
> > member) less cht_wc oriented?
>
> I agree that renaming these to make them generic makes sense if we get a
> second user (which I doubt, but you never know). For now I would like to
> keep this as is though, this is a big series and I would like to avoid
> to respin it just for this and we can always rename this later.
>
> If I need to do a v5 anyways though, then I'll do the rename for v5.

Yeah, either way:
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Lee Jones Dec. 17, 2021, 10:09 a.m. UTC | #3
On Mon, 06 Dec 2021, Hans de Goede wrote:

> Tablet / laptop designs using an Intel Cherry Trail x86 main SoC with
> an Intel Whiskey Cove PMIC do not use a single standard setup for
> the charger, fuel-gauge and other chips surrounding the PMIC /
> charging+data USB port.
> 
> Unlike what is normal on x86 this diversity in designs is not handled
> by the ACPI tables. On 2 of the 3 known designs there are no standard
> (PNP0C0A) ACPI battery devices and on the 3th design the ACPI battery
> device does not work under Linux due to it requiring non-standard
> and undocumented ACPI behavior.
> 
> So to make things work under Linux we use native charger and fuel-gauge
> drivers on these devices, re-using the native drivers used on ARM boards
> with the same charger / fuel-gauge ICs.
> 
> This requires various MFD-cell drivers for the CHT-WC PMIC cells to
> know which model they are exactly running on so that they can e.g.
> instantiate an I2C-client for the right model charger-IC (the charger
> is connected to an I2C-controller which is part of the PMIC).
> 
> Rather then duplicating DMI-id matching to check which model we are
> running on in each MFD-cell driver, add a check for this to the
> shared drivers/mfd/intel_soc_pmic_chtwc.c code by using a
> DMI table for all 3 known models:
> 
> 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)
> support to enable charging with up to 12V through a micro-USB port.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> Changes in v4:
> - Put '{' and comment of DMI entries on separate lines (requested by Lee)
> - Drop comment on terminating empty entry in DMI table
> 
> Changes in v3:
> - Store the model in struct intel_soc_pmic instead of adding a helper
>   function to retreive it
> 
> Changes in v2:
> - New patch in v2 of this patch-set
> ---
>  drivers/mfd/intel_soc_pmic_chtwc.c | 40 ++++++++++++++++++++++++++++++
>  include/linux/mfd/intel_soc_pmic.h |  8 ++++++
>  2 files changed, 48 insertions(+)

Acked-by: Lee Jones <lee.jones@linaro.org>
diff mbox series

Patch

diff --git a/drivers/mfd/intel_soc_pmic_chtwc.c b/drivers/mfd/intel_soc_pmic_chtwc.c
index 49c5f71664bc..4eab191e053a 100644
--- a/drivers/mfd/intel_soc_pmic_chtwc.c
+++ b/drivers/mfd/intel_soc_pmic_chtwc.c
@@ -10,6 +10,7 @@ 
 
 #include <linux/acpi.h>
 #include <linux/delay.h>
+#include <linux/dmi.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
@@ -134,9 +135,44 @@  static const struct regmap_irq_chip cht_wc_regmap_irq_chip = {
 	.num_regs = 1,
 };
 
+static const struct dmi_system_id cht_wc_model_dmi_ids[] = {
+	{
+		/* GPD win / GPD pocket mini laptops */
+		.driver_data = (void *)(long)INTEL_CHT_WC_GPD_WIN_POCKET,
+		/*
+		 * This DMI match may not seem unique, but it is. In the 67000+
+		 * DMI decode dumps from linux-hardware.org only 116 have
+		 * board_vendor set to "AMI Corporation" and of those 116 only
+		 * the GPD win's and pocket's board_name is "Default string".
+		 */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
+			DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
+		},
+	}, {
+		/* Xiaomi Mi Pad 2 */
+		.driver_data = (void *)(long)INTEL_CHT_WC_XIAOMI_MIPAD2,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
+		},
+	}, {
+		/* Lenovo Yoga Book X90F / X91F / X91L */
+		.driver_data = (void *)(long)INTEL_CHT_WC_LENOVO_YOGABOOK1,
+		.matches = {
+			/* Non exact match to match all versions */
+			DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
+		},
+	},
+	{ }
+};
+
 static int cht_wc_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
+	const struct dmi_system_id *id;
 	struct intel_soc_pmic *pmic;
 	acpi_status status;
 	unsigned long long hrv;
@@ -160,6 +196,10 @@  static int cht_wc_probe(struct i2c_client *client)
 	if (!pmic)
 		return -ENOMEM;
 
+	id = dmi_first_match(cht_wc_model_dmi_ids);
+	if (id)
+		pmic->cht_wc_model = (long)id->driver_data;
+
 	pmic->irq = client->irq;
 	pmic->dev = dev;
 	i2c_set_clientdata(client, pmic);
diff --git a/include/linux/mfd/intel_soc_pmic.h b/include/linux/mfd/intel_soc_pmic.h
index 6a88e34cb955..945bde1fe55c 100644
--- a/include/linux/mfd/intel_soc_pmic.h
+++ b/include/linux/mfd/intel_soc_pmic.h
@@ -13,6 +13,13 @@ 
 
 #include <linux/regmap.h>
 
+enum intel_cht_wc_models {
+	INTEL_CHT_WC_UNKNOWN,
+	INTEL_CHT_WC_GPD_WIN_POCKET,
+	INTEL_CHT_WC_XIAOMI_MIPAD2,
+	INTEL_CHT_WC_LENOVO_YOGABOOK1,
+};
+
 /**
  * struct intel_soc_pmic - Intel SoC PMIC data
  * @irq: Master interrupt number of the parent PMIC device
@@ -39,6 +46,7 @@  struct intel_soc_pmic {
 	struct regmap_irq_chip_data *irq_chip_data_crit;
 	struct device *dev;
 	struct intel_scu_ipc_dev *scu;
+	enum intel_cht_wc_models cht_wc_model;
 };
 
 int intel_soc_pmic_exec_mipi_pmic_seq_element(u16 i2c_address, u32 reg_address,