[PATCH 08/13] mfd: sec: store hardware revision in sec_pmic_dev and add S2MU005 support

Kaustabh Chakraborty posted 13 patches 2 months, 3 weeks ago
There is a newer version of this series
[PATCH 08/13] mfd: sec: store hardware revision in sec_pmic_dev and add S2MU005 support
Posted by Kaustabh Chakraborty 2 months, 3 weeks ago
The device revision matters in cases when in some PMICs, the correct
register offsets very in different revisions. Instead of just debug
printing the value, store it in the driver data struct.

Unlike other devices, S2MU005 has its hardware revision ID in register
offset 0x73. Allow handling different devices and add support for S2MU005.

Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
 drivers/mfd/sec-common.c         | 30 ++++++++++++++++++++++++------
 include/linux/mfd/samsung/core.h |  3 +++
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/sec-common.c b/drivers/mfd/sec-common.c
index 4c5f4dc2905b..f51c53e7a164 100644
--- a/drivers/mfd/sec-common.c
+++ b/drivers/mfd/sec-common.c
@@ -16,6 +16,7 @@
 #include <linux/mfd/samsung/irq.h>
 #include <linux/mfd/samsung/s2mps11.h>
 #include <linux/mfd/samsung/s2mps13.h>
+#include <linux/mfd/samsung/s2mu005.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pm.h>
@@ -86,17 +87,34 @@ static const struct mfd_cell s2mu005_devs[] = {
 	MFD_CELL_OF("s2mu005-rgb", NULL, NULL, 0, 0, "samsung,s2mu005-rgb"),
 };
 
-static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
+static void sec_pmic_store_rev(struct sec_pmic_dev *sec_pmic)
 {
-	unsigned int val;
+	unsigned int reg, mask, shift;
 
 	/* For s2mpg1x, the revision is in a different regmap */
 	if (sec_pmic->device_type == S2MPG10)
 		return;
 
-	/* For each device type, the REG_ID is always the first register */
-	if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val))
-		dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", val);
+	switch (sec_pmic->device_type) {
+	case S2MU005:
+		reg = S2MU005_REG_ID;
+		mask = S2MU005_ID_MASK;
+		shift = S2MU005_ID_SHIFT;
+		break;
+	default:
+		/* For other device types, the REG_ID is always the first register. */
+		reg = S2MPS11_REG_ID;
+		mask = ~0;
+		shift = 0;
+	}
+
+	if (!regmap_read(sec_pmic->regmap_pmic, reg, &sec_pmic->revision))
+		return;
+
+	sec_pmic->revision &= mask;
+	sec_pmic->revision >>= shift;
+
+	dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", sec_pmic->revision);
 }
 
 static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic)
@@ -236,7 +254,7 @@ int sec_pmic_probe(struct device *dev, int device_type, unsigned int irq,
 		return ret;
 
 	sec_pmic_configure(sec_pmic);
-	sec_pmic_dump_rev(sec_pmic);
+	sec_pmic_store_rev(sec_pmic);
 
 	return ret;
 }
diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h
index fc07f7944dcd..ccd1bfa15b85 100644
--- a/include/linux/mfd/samsung/core.h
+++ b/include/linux/mfd/samsung/core.h
@@ -63,6 +63,7 @@ enum sec_device_type {
  * @irq_base:		Base IRQ number for device, required for IRQs
  * @irq:		Generic IRQ number for device
  * @irq_data:		Runtime data structure for IRQ controller
+ * @revision:		Revision number of the device
  * @wakeup:		Whether or not this is a wakeup device
  */
 struct sec_pmic_dev {
@@ -74,6 +75,8 @@ struct sec_pmic_dev {
 	int device_type;
 	int irq;
 	struct regmap_irq_chip_data *irq_data[MAX_IRQ_CHIPS];
+
+	unsigned int revision;
 };
 
 struct sec_platform_data {

-- 
2.51.2
Re: [PATCH 08/13] mfd: sec: store hardware revision in sec_pmic_dev and add S2MU005 support
Posted by André Draszik 2 months, 3 weeks ago
On Fri, 2025-11-14 at 00:35 +0530, Kaustabh Chakraborty wrote:
> The device revision matters in cases when in some PMICs, the correct
> register offsets very in different revisions. Instead of just debug
> printing the value, store it in the driver data struct.
> 
> Unlike other devices, S2MU005 has its hardware revision ID in register
> offset 0x73. Allow handling different devices and add support for S2MU005.
> 
> Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
> ---
>  drivers/mfd/sec-common.c         | 30 ++++++++++++++++++++++++------
>  include/linux/mfd/samsung/core.h |  3 +++
>  2 files changed, 27 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mfd/sec-common.c b/drivers/mfd/sec-common.c
> index 4c5f4dc2905b..f51c53e7a164 100644
> --- a/drivers/mfd/sec-common.c
> +++ b/drivers/mfd/sec-common.c
> @@ -16,6 +16,7 @@
>  #include <linux/mfd/samsung/irq.h>
>  #include <linux/mfd/samsung/s2mps11.h>
>  #include <linux/mfd/samsung/s2mps13.h>
> +#include <linux/mfd/samsung/s2mu005.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/pm.h>
> @@ -86,17 +87,34 @@ static const struct mfd_cell s2mu005_devs[] = {
>  	MFD_CELL_OF("s2mu005-rgb", NULL, NULL, 0, 0, "samsung,s2mu005-rgb"),
>  };
>  
> -static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
> +static void sec_pmic_store_rev(struct sec_pmic_dev *sec_pmic)
>  {
> -	unsigned int val;
> +	unsigned int reg, mask, shift;
>  
>  	/* For s2mpg1x, the revision is in a different regmap */
>  	if (sec_pmic->device_type == S2MPG10)
>  		return;
>  
> -	/* For each device type, the REG_ID is always the first register */
> -	if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val))
> -		dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", val);
> +	switch (sec_pmic->device_type) {
> +	case S2MU005:
> +		reg = S2MU005_REG_ID;
> +		mask = S2MU005_ID_MASK;
> +		shift = S2MU005_ID_SHIFT;
> +		break;
> +	default:
> +		/* For other device types, the REG_ID is always the first register. */
> +		reg = S2MPS11_REG_ID;
> +		mask = ~0;
> +		shift = 0;
> +	}
> +
> +	if (!regmap_read(sec_pmic->regmap_pmic, reg, &sec_pmic->revision))
> +		return;

You should probably propagate the error up to the caller here.

Cheers,
Andre'

> +
> +	sec_pmic->revision &= mask;
> +	sec_pmic->revision >>= shift;
> +
> +	dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", sec_pmic->revision);
>  }
>  
>  static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic)
> @@ -236,7 +254,7 @@ int sec_pmic_probe(struct device *dev, int device_type, unsigned int irq,
>  		return ret;
>  
>  	sec_pmic_configure(sec_pmic);
> -	sec_pmic_dump_rev(sec_pmic);
> +	sec_pmic_store_rev(sec_pmic);
>  
>  	return ret;
>  }
> diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h
> index fc07f7944dcd..ccd1bfa15b85 100644
> --- a/include/linux/mfd/samsung/core.h
> +++ b/include/linux/mfd/samsung/core.h
> @@ -63,6 +63,7 @@ enum sec_device_type {
>   * @irq_base:		Base IRQ number for device, required for IRQs
>   * @irq:		Generic IRQ number for device
>   * @irq_data:		Runtime data structure for IRQ controller
> + * @revision:		Revision number of the device
>   * @wakeup:		Whether or not this is a wakeup device
>   */
>  struct sec_pmic_dev {
> @@ -74,6 +75,8 @@ struct sec_pmic_dev {
>  	int device_type;
>  	int irq;
>  	struct regmap_irq_chip_data *irq_data[MAX_IRQ_CHIPS];
> +
> +	unsigned int revision;
>  };
>  
>  struct sec_platform_data {