linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/5] thermal/drivers: airoha: Add support for AN7583
@ 2025-11-06 22:59 Christian Marangi
  2025-11-06 22:59 ` [PATCH v3 1/5] thermal/drivers: airoha: Convert to regmap API Christian Marangi
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Christian Marangi @ 2025-11-06 22:59 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm

This small series implement all the required changes to
support Airoha AN7583 Thermal Sensor.

The SoC dropped the Monitor subsystem and only provide
temperature reading. Some generalization was required
to at least save the common code with also the help of
reg field API.

Changes v3:
- Property use chip-scu for thermal sensor
Changes v2:
- Update DT schema patch to implement dedicated schema

Christian Marangi (5):
  thermal/drivers: airoha: Convert to regmap API
  thermal/drivers: airoha: Generalize probe function
  thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux
    function
  dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC
  thermal/drivers: airoha: Add support for AN7583 Thermal Sensor

 .../bindings/arm/airoha,en7581-chip-scu.yaml  |  14 +
 drivers/thermal/airoha_thermal.c              | 368 +++++++++++++++---
 2 files changed, 318 insertions(+), 64 deletions(-)

-- 
2.51.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 1/5] thermal/drivers: airoha: Convert to regmap API
  2025-11-06 22:59 [PATCH v3 0/5] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
@ 2025-11-06 22:59 ` Christian Marangi
  2025-11-06 22:59 ` [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function Christian Marangi
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Christian Marangi @ 2025-11-06 22:59 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm

In preparation for support of Airoha AN7583, convert the driver to
regmap API. This is needed as Airoha AN7583 will be based on syscon
regmap.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/thermal/airoha_thermal.c | 72 +++++++++++++++++++-------------
 1 file changed, 42 insertions(+), 30 deletions(-)

diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
index b9fd6bfc88e5..01ed49a4887e 100644
--- a/drivers/thermal/airoha_thermal.c
+++ b/drivers/thermal/airoha_thermal.c
@@ -194,7 +194,7 @@
 #define AIROHA_MAX_SAMPLES			6
 
 struct airoha_thermal_priv {
-	void __iomem *base;
+	struct regmap *map;
 	struct regmap *chip_scu;
 	struct resource scu_adc_res;
 
@@ -265,8 +265,8 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
 			       RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
 
 		/* We offset the high temp of 1°C to trigger correct event */
-		writel(TEMP_TO_RAW(priv, high) >> 4,
-		       priv->base + EN7581_TEMPOFFSETH);
+		regmap_write(priv->map, EN7581_TEMPOFFSETH,
+			     TEMP_TO_RAW(priv, high) >> 4);
 
 		enable_monitor = true;
 	}
@@ -277,15 +277,15 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
 			      RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
 
 		/* We offset the low temp of 1°C to trigger correct event */
-		writel(TEMP_TO_RAW(priv, low) >> 4,
-		       priv->base + EN7581_TEMPOFFSETL);
+		regmap_write(priv->map, EN7581_TEMPOFFSETL,
+			     TEMP_TO_RAW(priv, high) >> 4);
 
 		enable_monitor = true;
 	}
 
 	/* Enable sensor 0 monitor after trip are set */
 	if (enable_monitor)
-		writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0);
+		regmap_write(priv->map, EN7581_TEMPMONCTL0, EN7581_SENSE0_EN);
 
 	return 0;
 }
@@ -302,7 +302,7 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
 	bool update = false;
 	u32 status;
 
-	status = readl(priv->base + EN7581_TEMPMONINTSTS);
+	regmap_read(priv->map, EN7581_TEMPMONINTSTS, &status);
 	switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) {
 	case EN7581_HOFSINTSTS0:
 		event = THERMAL_TRIP_VIOLATED;
@@ -318,7 +318,7 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
 	}
 
 	/* Reset Interrupt */
-	writel(status, priv->base + EN7581_TEMPMONINTSTS);
+	regmap_write(priv->map, EN7581_TEMPMONINTSTS, status);
 
 	if (update)
 		thermal_zone_device_update(priv->tz, event);
@@ -336,11 +336,11 @@ static void airoha_thermal_setup_adc_val(struct device *dev,
 	/* sleep 10 ms for ADC to enable */
 	usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
 
-	efuse_calib_info = readl(priv->base + EN7581_EFUSE_TEMP_OFFSET_REG);
+	regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
 	if (efuse_calib_info) {
 		priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info);
 		/* Different slope are applied if the sensor is used for CPU or for package */
-		cpu_sensor = readl(priv->base + EN7581_EFUSE_TEMP_CPU_SENSOR_REG);
+		regmap_read(priv->map, EN7581_EFUSE_TEMP_CPU_SENSOR_REG, &cpu_sensor);
 		if (cpu_sensor) {
 			priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT;
 			priv->init_temp = EN7581_INIT_TEMP_FTK_X10;
@@ -359,8 +359,8 @@ static void airoha_thermal_setup_adc_val(struct device *dev,
 static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 {
 	/* Set measure mode */
-	writel(FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4),
-	       priv->base + EN7581_TEMPMSRCTL0);
+	regmap_write(priv->map, EN7581_TEMPMSRCTL0,
+		     FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4));
 
 	/*
 	 * Configure ADC valid reading addr
@@ -375,15 +375,15 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 	 * We set valid instead of volt as we don't enable valid/volt
 	 * split reading and AHB read valid addr in such case.
 	 */
-	writel(priv->scu_adc_res.start + EN7581_DOUT_TADC,
-	       priv->base + EN7581_TEMPADCVALIDADDR);
+	regmap_write(priv->map, EN7581_TEMPADCVALIDADDR,
+		     priv->scu_adc_res.start + EN7581_DOUT_TADC);
 
 	/*
 	 * Configure valid bit on a fake value of bit 16. The ADC outputs
 	 * max of 2 bytes for voltage.
 	 */
-	writel(FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16),
-	       priv->base + EN7581_TEMPADCVALIDMASK);
+	regmap_write(priv->map, EN7581_TEMPADCVALIDMASK,
+		     FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16));
 
 	/*
 	 * AHB supports max 12 bytes for ADC voltage. Shift the read
@@ -391,40 +391,52 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 	 * in the order of half a °C and is acceptable in the context
 	 * of triggering interrupt in critical condition.
 	 */
-	writel(FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4),
-	       priv->base + EN7581_TEMPADCVOLTAGESHIFT);
+	regmap_write(priv->map, EN7581_TEMPADCVOLTAGESHIFT,
+		     FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4));
 
 	/* BUS clock is 300MHz counting unit is 3 * 68.64 * 256 = 52.715us */
-	writel(FIELD_PREP(EN7581_PERIOD_UNIT, 3),
-	       priv->base + EN7581_TEMPMONCTL1);
+	regmap_write(priv->map, EN7581_TEMPMONCTL1,
+		     FIELD_PREP(EN7581_PERIOD_UNIT, 3));
 
 	/*
 	 * filt interval is 1 * 52.715us = 52.715us,
 	 * sen interval is 379 * 52.715us = 19.97ms
 	 */
-	writel(FIELD_PREP(EN7581_FILT_INTERVAL, 1) |
-	       FIELD_PREP(EN7581_FILT_INTERVAL, 379),
-	       priv->base + EN7581_TEMPMONCTL2);
+	regmap_write(priv->map, EN7581_TEMPMONCTL2,
+		     FIELD_PREP(EN7581_FILT_INTERVAL, 1) |
+		     FIELD_PREP(EN7581_FILT_INTERVAL, 379));
 
 	/* AHB poll is set to 146 * 68.64 = 10.02us */
-	writel(FIELD_PREP(EN7581_ADC_POLL_INTVL, 146),
-	       priv->base + EN7581_TEMPAHBPOLL);
+	regmap_write(priv->map, EN7581_TEMPAHBPOLL,
+		     FIELD_PREP(EN7581_ADC_POLL_INTVL, 146));
 }
 
+static const struct regmap_config airoha_thermal_regmap_config = {
+	.reg_bits		= 32,
+	.reg_stride		= 4,
+	.val_bits		= 32,
+};
+
 static int airoha_thermal_probe(struct platform_device *pdev)
 {
 	struct airoha_thermal_priv *priv;
 	struct device_node *chip_scu_np;
 	struct device *dev = &pdev->dev;
+	void __iomem *base;
 	int irq, ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
-	priv->base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(priv->base))
-		return PTR_ERR(priv->base);
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	priv->map = devm_regmap_init_mmio(dev, base,
+					  &airoha_thermal_regmap_config);
+	if (IS_ERR(priv->map))
+		return PTR_ERR(priv->map);
 
 	chip_scu_np = of_parse_phandle(dev->of_node, "airoha,chip-scu", 0);
 	if (!chip_scu_np)
@@ -462,8 +474,8 @@ static int airoha_thermal_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, priv);
 
 	/* Enable LOW and HIGH interrupt */
-	writel(EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0,
-	       priv->base + EN7581_TEMPMONINT);
+	regmap_write(priv->map, EN7581_TEMPMONINT,
+		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
 
 	return 0;
 }
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function
  2025-11-06 22:59 [PATCH v3 0/5] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
  2025-11-06 22:59 ` [PATCH v3 1/5] thermal/drivers: airoha: Convert to regmap API Christian Marangi
@ 2025-11-06 22:59 ` Christian Marangi
  2025-11-25 17:16   ` Daniel Lezcano
  2025-11-25 17:41   ` Daniel Lezcano
  2025-11-06 22:59 ` [PATCH v3 3/5] thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux function Christian Marangi
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 12+ messages in thread
From: Christian Marangi @ 2025-11-06 22:59 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm

In preparation for support of Airoha AN7583, generalize the probe
function to address for the 2 SoC differece.

Implement a match_data struct where it's possible to define a more
specific probe and post_probe function and specific thermal ops and
pllrg protect value.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++--------
 1 file changed, 75 insertions(+), 27 deletions(-)

diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
index 01ed49a4887e..864a01fd8fd8 100644
--- a/drivers/thermal/airoha_thermal.c
+++ b/drivers/thermal/airoha_thermal.c
@@ -198,12 +198,23 @@ struct airoha_thermal_priv {
 	struct regmap *chip_scu;
 	struct resource scu_adc_res;
 
+	u32 pllrg_protect;
+
 	struct thermal_zone_device *tz;
 	int init_temp;
 	int default_slope;
 	int default_offset;
 };
 
+struct airoha_thermal_soc_data {
+	u32 pllrg_protect;
+
+	const struct thermal_zone_device_ops *thdev_ops;
+	int (*probe)(struct platform_device *pdev,
+		     struct airoha_thermal_priv *priv);
+	int (*post_probe)(struct platform_device *pdev);
+};
+
 static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
 {
 	u32 val;
@@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
 	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
 
 	/* Give access to thermal regs */
-	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
+	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
+		     priv->pllrg_protect);
 	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
 	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
 
@@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
 }
 
-static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
+static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
 {
 	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
 	int min_value, max_value, avg_value, value;
@@ -253,7 +265,7 @@ static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
 	return 0;
 }
 
-static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
+static int en7581_thermal_set_trips(struct thermal_zone_device *tz, int low,
 				    int high)
 {
 	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
@@ -290,12 +302,12 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
 	return 0;
 }
 
-static const struct thermal_zone_device_ops thdev_ops = {
-	.get_temp = airoha_thermal_get_temp,
-	.set_trips = airoha_thermal_set_trips,
+static const struct thermal_zone_device_ops en7581_thdev_ops = {
+	.get_temp = en7581_thermal_get_temp,
+	.set_trips = en7581_thermal_set_trips,
 };
 
-static irqreturn_t airoha_thermal_irq(int irq, void *data)
+static irqreturn_t en7581_thermal_irq(int irq, void *data)
 {
 	struct airoha_thermal_priv *priv = data;
 	enum thermal_notify_event event;
@@ -326,7 +338,7 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static void airoha_thermal_setup_adc_val(struct device *dev,
+static void en7581_thermal_setup_adc_val(struct device *dev,
 					 struct airoha_thermal_priv *priv)
 {
 	u32 efuse_calib_info, cpu_sensor;
@@ -356,7 +368,7 @@ static void airoha_thermal_setup_adc_val(struct device *dev,
 	}
 }
 
-static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
+static void en7581_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 {
 	/* Set measure mode */
 	regmap_write(priv->map, EN7581_TEMPMSRCTL0,
@@ -411,30 +423,26 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 		     FIELD_PREP(EN7581_ADC_POLL_INTVL, 146));
 }
 
-static const struct regmap_config airoha_thermal_regmap_config = {
+static const struct regmap_config en7581_thermal_regmap_config = {
 	.reg_bits		= 32,
 	.reg_stride		= 4,
 	.val_bits		= 32,
 };
 
-static int airoha_thermal_probe(struct platform_device *pdev)
+static int en7581_thermal_probe(struct platform_device *pdev,
+				struct airoha_thermal_priv *priv)
 {
-	struct airoha_thermal_priv *priv;
 	struct device_node *chip_scu_np;
 	struct device *dev = &pdev->dev;
 	void __iomem *base;
 	int irq, ret;
 
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
 	priv->map = devm_regmap_init_mmio(dev, base,
-					  &airoha_thermal_regmap_config);
+					  &en7581_thermal_regmap_config);
 	if (IS_ERR(priv->map))
 		return PTR_ERR(priv->map);
 
@@ -454,18 +462,55 @@ static int airoha_thermal_probe(struct platform_device *pdev)
 		return irq;
 
 	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
-					airoha_thermal_irq, IRQF_ONESHOT,
+					en7581_thermal_irq, IRQF_ONESHOT,
 					pdev->name, priv);
 	if (ret) {
 		dev_err(dev, "Can't get interrupt working.\n");
 		return ret;
 	}
 
-	airoha_thermal_setup_monitor(priv);
-	airoha_thermal_setup_adc_val(dev, priv);
+	en7581_thermal_setup_monitor(priv);
+	en7581_thermal_setup_adc_val(dev, priv);
+
+	return 0;
+}
+
+static int en7581_thermal_post_probe(struct platform_device *pdev)
+{
+	struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
+
+	/* Enable LOW and HIGH interrupt (if supported) */
+	regmap_write(priv->map, EN7581_TEMPMONINT,
+		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
+
+	return 0;
+}
+
+static int airoha_thermal_probe(struct platform_device *pdev)
+{
+	const struct airoha_thermal_soc_data *soc_data;
+	struct airoha_thermal_priv *priv;
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	soc_data = device_get_match_data(dev);
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->pllrg_protect = soc_data->pllrg_protect;
+
+	if (!soc_data->probe)
+		return -EINVAL;
+
+	ret = soc_data->probe(pdev, priv);
+	if (ret)
+		return ret;
 
 	/* register of thermal sensor and get info from DT */
-	priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops);
+	priv->tz = devm_thermal_of_zone_register(dev, 0, priv,
+						 soc_data->thdev_ops);
 	if (IS_ERR(priv->tz)) {
 		dev_err(dev, "register thermal zone sensor failed\n");
 		return PTR_ERR(priv->tz);
@@ -473,15 +518,18 @@ static int airoha_thermal_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, priv);
 
-	/* Enable LOW and HIGH interrupt */
-	regmap_write(priv->map, EN7581_TEMPMONINT,
-		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
-
-	return 0;
+	return soc_data->post_probe ? soc_data->post_probe(pdev) : 0;
 }
 
+static const struct airoha_thermal_soc_data en7581_data = {
+	.pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
+	.thdev_ops = &en7581_thdev_ops,
+	.probe = &en7581_thermal_probe,
+	.post_probe = &en7581_thermal_post_probe,
+};
+
 static const struct of_device_id airoha_thermal_match[] = {
-	{ .compatible = "airoha,en7581-thermal" },
+	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, airoha_thermal_match);
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 3/5] thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux function
  2025-11-06 22:59 [PATCH v3 0/5] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
  2025-11-06 22:59 ` [PATCH v3 1/5] thermal/drivers: airoha: Convert to regmap API Christian Marangi
  2025-11-06 22:59 ` [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function Christian Marangi
@ 2025-11-06 22:59 ` Christian Marangi
  2025-11-25 21:20   ` Daniel Lezcano
  2025-11-06 22:59 ` [PATCH v3 4/5] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC Christian Marangi
  2025-11-06 22:59 ` [PATCH v3 5/5] thermal/drivers: airoha: Add support for AN7583 Thermal Sensor Christian Marangi
  4 siblings, 1 reply; 12+ messages in thread
From: Christian Marangi @ 2025-11-06 22:59 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm

In preparation for support of Airoha AN7583, generalize
get_thermal_ADC() and set_thermal_mux() with the use of reg_field API.

This is to account the same logic between the current supported SoC and
the new one but with different register address.

While at it also further improve some comments and move sleep inside the
set_thermal_mux function.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/thermal/airoha_thermal.c | 54 +++++++++++++++++++++++++-------
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
index 864a01fd8fd8..a062922cb116 100644
--- a/drivers/thermal/airoha_thermal.c
+++ b/drivers/thermal/airoha_thermal.c
@@ -193,9 +193,18 @@
 
 #define AIROHA_MAX_SAMPLES			6
 
+enum airoha_thermal_chip_scu_field {
+	AIROHA_THERMAL_DOUT_TADC,
+	AIROHA_THERMAL_MUX_TADC,
+
+	/* keep last */
+	AIROHA_THERMAL_FIELD_MAX,
+};
+
 struct airoha_thermal_priv {
 	struct regmap *map;
 	struct regmap *chip_scu;
+	struct regmap_field *chip_scu_fields[AIROHA_THERMAL_FIELD_MAX];
 	struct resource scu_adc_res;
 
 	u32 pllrg_protect;
@@ -219,22 +228,29 @@ static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
 {
 	u32 val;
 
-	regmap_read(priv->chip_scu, EN7581_DOUT_TADC, &val);
-	return FIELD_GET(EN7581_DOUT_TADC_MASK, val);
+	regmap_field_read(priv->chip_scu_fields[AIROHA_THERMAL_DOUT_TADC],
+			  &val);
+	return val;
 }
 
-static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
+static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv,
+				   int tdac_idx)
 {
-	u32 adc_mux, pllrg;
+	u32 pllrg;
 
 	/* Save PLLRG current value */
 	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
 
-	/* Give access to thermal regs */
+	/* Give access to Thermal regs */
 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
 		     priv->pllrg_protect);
-	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
-	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
+
+	/* Configure Thermal ADC mux to tdac_idx */
+	regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
+			   tdac_idx);
+
+	/* Sleep 10 ms for Thermal ADC to enable */
+	usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
 
 	/* Restore PLLRG value on exit */
 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
@@ -343,10 +359,8 @@ static void en7581_thermal_setup_adc_val(struct device *dev,
 {
 	u32 efuse_calib_info, cpu_sensor;
 
-	/* Setup thermal sensor to ADC mode and setup the mux to DIODE1 */
-	airoha_init_thermal_ADC_mode(priv);
-	/* sleep 10 ms for ADC to enable */
-	usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
+	/* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */
+	airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1);
 
 	regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
 	if (efuse_calib_info) {
@@ -429,13 +443,18 @@ static const struct regmap_config en7581_thermal_regmap_config = {
 	.val_bits		= 32,
 };
 
+static const struct reg_field en7581_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = {
+	[AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(EN7581_DOUT_TADC, 0, 15),
+	[AIROHA_THERMAL_MUX_TADC] = REG_FIELD(EN7581_PWD_TADC, 1, 3),
+};
+
 static int en7581_thermal_probe(struct platform_device *pdev,
 				struct airoha_thermal_priv *priv)
 {
 	struct device_node *chip_scu_np;
 	struct device *dev = &pdev->dev;
 	void __iomem *base;
-	int irq, ret;
+	int i, irq, ret;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
@@ -454,6 +473,17 @@ static int en7581_thermal_probe(struct platform_device *pdev,
 	if (IS_ERR(priv->chip_scu))
 		return PTR_ERR(priv->chip_scu);
 
+	for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
+		struct regmap_field *field;
+
+		field = devm_regmap_field_alloc(dev, priv->chip_scu,
+						en7581_chip_scu_fields[i]);
+		if (IS_ERR(field))
+			return PTR_ERR(field);
+
+		priv->chip_scu_fields[i] = field;
+	}
+
 	of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res);
 	of_node_put(chip_scu_np);
 
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 4/5] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC
  2025-11-06 22:59 [PATCH v3 0/5] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
                   ` (2 preceding siblings ...)
  2025-11-06 22:59 ` [PATCH v3 3/5] thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux function Christian Marangi
@ 2025-11-06 22:59 ` Christian Marangi
  2025-11-07  7:45   ` Krzysztof Kozlowski
  2025-11-06 22:59 ` [PATCH v3 5/5] thermal/drivers: airoha: Add support for AN7583 Thermal Sensor Christian Marangi
  4 siblings, 1 reply; 12+ messages in thread
From: Christian Marangi @ 2025-11-06 22:59 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm

Document support for Airoha AN7583 chip-scu node.

This is similar to Airoha EN7581 with the addition of the presence of
thermal sensor in addition to controlling HW PIN and other miscellaneous
pheriperals.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 .../bindings/arm/airoha,en7581-chip-scu.yaml       | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
index 67c449d804c2..0d042fb90a78 100644
--- a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
+++ b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
@@ -18,16 +18,30 @@ properties:
   compatible:
     items:
       - enum:
+          - airoha,an7583-chip-scu
           - airoha,en7581-chip-scu
       - const: syscon
 
   reg:
     maxItems: 1
 
+  '#thermal-sensor-cells':
+    const: 0
+
 required:
   - compatible
   - reg
 
+if:
+  properties:
+    compatible:
+      contains:
+        const: airoha,en7581-chip-scu
+
+then:
+  properties:
+    '#thermal-sensor-cells': false
+
 additionalProperties: false
 
 examples:
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 5/5] thermal/drivers: airoha: Add support for AN7583 Thermal Sensor
  2025-11-06 22:59 [PATCH v3 0/5] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
                   ` (3 preceding siblings ...)
  2025-11-06 22:59 ` [PATCH v3 4/5] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC Christian Marangi
@ 2025-11-06 22:59 ` Christian Marangi
  4 siblings, 0 replies; 12+ messages in thread
From: Christian Marangi @ 2025-11-06 22:59 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm

Add support for Airoha AN7583 Thermal driver. This apply similar logic
on how to read the temperature but totally drop support for the
PTP_THERMAL subsystem. PTP_THERMAL subsystem was a way to trigger trip
point from hardware by configuring how to read the temperature
internally.

This subsystem has been totally removed from Airoha AN7583 permitting
only to read the temperature.

The SoC support up to 3 sensor but the original driver always read the
BGA sensor hence it's currently implemented reading only this specific
sensor. Reference and values for the other 2 sensor are defined for
further implementation if confirmed working.

set_thermal_mux() is extended to also address muxing the sensor as
AN7583 use a different way to read the temperature from 3 different
diode. The EN7581 code is updated to account for these changes.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/thermal/airoha_thermal.c | 158 ++++++++++++++++++++++++++++++-
 1 file changed, 154 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
index a062922cb116..c190b696d3a8 100644
--- a/drivers/thermal/airoha_thermal.c
+++ b/drivers/thermal/airoha_thermal.c
@@ -18,6 +18,12 @@
 #define EN7581_DOUT_TADC			0x2f8
 #define   EN7581_DOUT_TADC_MASK			GENMASK(15, 0)
 
+#define AN7583_MUX_SENSOR			0x2a0
+#define   AN7583_LOAD_ADJ			GENMASK(3, 2)
+#define AN7583_MUX_TADC				0x2e4
+#define   AN7583_MUX_TADC_MASK			GENMASK(3, 1)
+#define AN7583_DOUT_TADC			0x2f0
+
 /* PTP_THERMAL regs */
 #define EN7581_TEMPMONCTL0			0x800
 #define   EN7581_SENSE3_EN			BIT(3)
@@ -181,6 +187,11 @@
 #define EN7581_SCU_THERMAL_PROTECT_KEY		0x12
 #define EN7581_SCU_THERMAL_MUX_DIODE1		0x7
 
+#define AN7583_SCU_THERMAL_PROTECT_KEY		0x80
+#define AN7583_NUM_SENSOR			3
+
+#define AIROHA_THERMAL_NO_MUX_SENSOR		-1
+
 /* Convert temp to raw value as read from ADC	((((temp / 100) - init) * slope) / 1000) + offset */
 #define TEMP_TO_RAW(priv, temp)			((((((temp) / 100) - (priv)->init_temp) * \
 						  (priv)->default_slope) / 1000) + \
@@ -193,8 +204,39 @@
 
 #define AIROHA_MAX_SAMPLES			6
 
+/*
+ * AN7583 supports all these ADC mux but the original driver
+ * always checked temp with the AN7583_BGP_TEMP_SENSOR.
+ * Assume using the other sensor temperature is invalid and
+ * always read from AN7583_BGP_TEMP_SENSOR.
+ *
+ * On top of this it's defined that AN7583 supports 3
+ * sensor: AN7583_BGP_TEMP_SENSOR, AN7583_GBE_TEMP_SENSOR,
+ * AN7583_CPU_TEMP_SENSOR.
+ *
+ * Provide the ADC mux for reference.
+ */
+enum an7583_thermal_adc_mux {
+	AN7583_BGP_TEMP_SENSOR,
+	AN7583_PAD_AVS,
+	AN7583_CORE_POWER,
+	AN7583_AVSDAC_OUT,
+	AN7583_VCM,
+	AN7583_GBE_TEMP_SENSOR,
+	AN7583_CPU_TEMP_SENSOR,
+
+	AN7583_ADC_MUX_MAX,
+};
+
+enum an7583_thermal_diode_mux {
+	AN7583_D0_TADC,
+	AN7583_ZERO_TADC,
+	AN7583_D1_TADC,
+};
+
 enum airoha_thermal_chip_scu_field {
 	AIROHA_THERMAL_DOUT_TADC,
+	AIROHA_THERMAL_MUX_SENSOR,
 	AIROHA_THERMAL_MUX_TADC,
 
 	/* keep last */
@@ -208,6 +250,7 @@ struct airoha_thermal_priv {
 	struct resource scu_adc_res;
 
 	u32 pllrg_protect;
+	int current_adc;
 
 	struct thermal_zone_device *tz;
 	int init_temp;
@@ -224,6 +267,24 @@ struct airoha_thermal_soc_data {
 	int (*post_probe)(struct platform_device *pdev);
 };
 
+static const unsigned int an7583_thermal_coeff[AN7583_ADC_MUX_MAX] = {
+	[AN7583_BGP_TEMP_SENSOR] = 973,
+	[AN7583_GBE_TEMP_SENSOR] = 995,
+	[AN7583_CPU_TEMP_SENSOR] = 1035,
+};
+
+static const unsigned int an7583_thermal_slope[AN7583_ADC_MUX_MAX] = {
+	[AN7583_BGP_TEMP_SENSOR] = 7440,
+	[AN7583_GBE_TEMP_SENSOR] = 7620,
+	[AN7583_CPU_TEMP_SENSOR] = 8390,
+};
+
+static const unsigned int an7583_thermal_offset[AN7583_ADC_MUX_MAX] = {
+	[AN7583_BGP_TEMP_SENSOR] = 294,
+	[AN7583_GBE_TEMP_SENSOR] = 298,
+	[AN7583_CPU_TEMP_SENSOR] = 344,
+};
+
 static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
 {
 	u32 val;
@@ -234,7 +295,7 @@ static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
 }
 
 static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv,
-				   int tdac_idx)
+				   int tdac_idx, int sensor_idx)
 {
 	u32 pllrg;
 
@@ -245,9 +306,20 @@ static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv,
 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
 		     priv->pllrg_protect);
 
+	/*
+	 * Configure Thermal Sensor mux to sensor_idx.
+	 * (if not supported, sensor_idx is AIROHA_THERMAL_NO_MUX_SENSOR)
+	 */
+	if (sensor_idx != AIROHA_THERMAL_NO_MUX_SENSOR)
+		regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_SENSOR],
+				   sensor_idx);
+
 	/* Configure Thermal ADC mux to tdac_idx */
-	regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
-			   tdac_idx);
+	if (priv->current_adc != tdac_idx) {
+		regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
+				   tdac_idx);
+		priv->current_adc = tdac_idx;
+	}
 
 	/* Sleep 10 ms for Thermal ADC to enable */
 	usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
@@ -360,7 +432,8 @@ static void en7581_thermal_setup_adc_val(struct device *dev,
 	u32 efuse_calib_info, cpu_sensor;
 
 	/* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */
-	airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1);
+	airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1,
+			       AIROHA_THERMAL_NO_MUX_SENSOR);
 
 	regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
 	if (efuse_calib_info) {
@@ -476,6 +549,10 @@ static int en7581_thermal_probe(struct platform_device *pdev,
 	for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
 		struct regmap_field *field;
 
+		/* Skip registering MUX_SENSOR field as not supported */
+		if (i == AIROHA_THERMAL_MUX_SENSOR)
+			continue;
+
 		field = devm_regmap_field_alloc(dev, priv->chip_scu,
 						en7581_chip_scu_fields[i]);
 		if (IS_ERR(field))
@@ -516,6 +593,71 @@ static int en7581_thermal_post_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int an7583_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
+{
+	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
+	int sensor_idx;
+	int delta_diode, delta_gain;
+	int coeff, slope, offset;
+
+	int diode_zero, diode_d0, diode_d1;
+
+	/* Always read sensor AN7583_BGP_TEMP_SENSOR */
+	sensor_idx = AN7583_BGP_TEMP_SENSOR;
+
+	coeff = an7583_thermal_coeff[sensor_idx];
+	slope = an7583_thermal_slope[sensor_idx];
+	offset = an7583_thermal_offset[sensor_idx];
+
+	airoha_set_thermal_mux(priv, sensor_idx, AN7583_ZERO_TADC);
+	diode_zero = airoha_get_thermal_ADC(priv);
+	airoha_set_thermal_mux(priv, sensor_idx, AN7583_D0_TADC);
+	diode_d0 = airoha_get_thermal_ADC(priv);
+	airoha_set_thermal_mux(priv, sensor_idx, AN7583_D1_TADC);
+	diode_d1 = airoha_get_thermal_ADC(priv);
+
+	delta_diode = diode_d1 - diode_d0;
+	delta_gain = (delta_diode * coeff) / 100 + (diode_zero - diode_d1);
+	*temp = (slope * delta_diode * 10) / delta_gain - offset * 10;
+	*temp *= 100;
+
+	return 0;
+}
+
+static const struct thermal_zone_device_ops an7583_tz_ops = {
+	.get_temp = an7583_thermal_get_temp,
+};
+
+static const struct reg_field an7583_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = {
+	[AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(AN7583_DOUT_TADC, 0, 31),
+	[AIROHA_THERMAL_MUX_TADC] = REG_FIELD(AN7583_MUX_TADC, 1, 3),
+	[AIROHA_THERMAL_MUX_SENSOR] = REG_FIELD(AN7583_MUX_SENSOR, 2, 3),
+};
+
+static int an7583_thermal_probe(struct platform_device *pdev,
+				struct airoha_thermal_priv *priv)
+{
+	struct device *dev = &pdev->dev;
+	int i;
+
+	priv->chip_scu = device_node_to_regmap(dev->of_node);
+	if (IS_ERR(priv->map))
+		return PTR_ERR(priv->map);
+
+	for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
+		struct regmap_field *field;
+
+		field = devm_regmap_field_alloc(dev, priv->chip_scu,
+						an7583_chip_scu_fields[i]);
+		if (IS_ERR(field))
+			return PTR_ERR(field);
+
+		priv->chip_scu_fields[i] = field;
+	}
+
+	return 0;
+}
+
 static int airoha_thermal_probe(struct platform_device *pdev)
 {
 	const struct airoha_thermal_soc_data *soc_data;
@@ -530,6 +672,7 @@ static int airoha_thermal_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	priv->pllrg_protect = soc_data->pllrg_protect;
+	priv->current_adc = -1;
 
 	if (!soc_data->probe)
 		return -EINVAL;
@@ -558,8 +701,15 @@ static const struct airoha_thermal_soc_data en7581_data = {
 	.post_probe = &en7581_thermal_post_probe,
 };
 
+static const struct airoha_thermal_soc_data an7583_data = {
+	.pllrg_protect = AN7583_SCU_THERMAL_PROTECT_KEY,
+	.thdev_ops = &an7583_tz_ops,
+	.probe = &an7583_thermal_probe,
+};
+
 static const struct of_device_id airoha_thermal_match[] = {
 	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
+	{ .compatible = "airoha,an7583-chip-scu", .data = &an7583_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, airoha_thermal_match);
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 4/5] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC
  2025-11-06 22:59 ` [PATCH v3 4/5] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC Christian Marangi
@ 2025-11-07  7:45   ` Krzysztof Kozlowski
  2025-11-07  8:53     ` Krzysztof Kozlowski
  0 siblings, 1 reply; 12+ messages in thread
From: Krzysztof Kozlowski @ 2025-11-07  7:45 UTC (permalink / raw)
  To: Christian Marangi
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Lorenzo Bianconi,
	devicetree, linux-kernel, linux-pm

On Thu, Nov 06, 2025 at 11:59:13PM +0100, Christian Marangi wrote:
> Document support for Airoha AN7583 chip-scu node.
> 
> This is similar to Airoha EN7581 with the addition of the presence of
> thermal sensor in addition to controlling HW PIN and other miscellaneous
> pheriperals.
> 
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
>  .../bindings/arm/airoha,en7581-chip-scu.yaml       | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
> index 67c449d804c2..0d042fb90a78 100644
> --- a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
> +++ b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
> @@ -18,16 +18,30 @@ properties:
>    compatible:
>      items:
>        - enum:
> +          - airoha,an7583-chip-scu

Again, random order.

>            - airoha,en7581-chip-scu
>        - const: syscon

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 4/5] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC
  2025-11-07  7:45   ` Krzysztof Kozlowski
@ 2025-11-07  8:53     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2025-11-07  8:53 UTC (permalink / raw)
  To: Christian Marangi
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Lorenzo Bianconi,
	devicetree, linux-kernel, linux-pm

On 07/11/2025 08:45, Krzysztof Kozlowski wrote:
> On Thu, Nov 06, 2025 at 11:59:13PM +0100, Christian Marangi wrote:
>> Document support for Airoha AN7583 chip-scu node.
>>
>> This is similar to Airoha EN7581 with the addition of the presence of
>> thermal sensor in addition to controlling HW PIN and other miscellaneous
>> pheriperals.
>>
>> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
>> ---
>>  .../bindings/arm/airoha,en7581-chip-scu.yaml       | 14 ++++++++++++++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
>> index 67c449d804c2..0d042fb90a78 100644
>> --- a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
>> +++ b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
>> @@ -18,16 +18,30 @@ properties:
>>    compatible:
>>      items:
>>        - enum:
>> +          - airoha,an7583-chip-scu
> 
> Again, random order.

D'oh! That's a correct order. Missed a/e difference.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function
  2025-11-06 22:59 ` [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function Christian Marangi
@ 2025-11-25 17:16   ` Daniel Lezcano
  2025-11-25 17:24     ` Christian Marangi
  2025-11-25 17:41   ` Daniel Lezcano
  1 sibling, 1 reply; 12+ messages in thread
From: Daniel Lezcano @ 2025-11-25 17:16 UTC (permalink / raw)
  To: Christian Marangi, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Lorenzo Bianconi,
	devicetree, linux-kernel, linux-pm

On 11/6/25 23:59, Christian Marangi wrote:
> In preparation for support of Airoha AN7583, generalize the probe
> function to address for the 2 SoC differece.
> 
> Implement a match_data struct where it's possible to define a more
> specific probe and post_probe function and specific thermal ops and
> pllrg protect value.
> 
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
>   drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++--------
>   1 file changed, 75 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
> index 01ed49a4887e..864a01fd8fd8 100644
> --- a/drivers/thermal/airoha_thermal.c
> +++ b/drivers/thermal/airoha_thermal.c
> @@ -198,12 +198,23 @@ struct airoha_thermal_priv {
>   	struct regmap *chip_scu;
>   	struct resource scu_adc_res;
>   
> +	u32 pllrg_protect;
> +
>   	struct thermal_zone_device *tz;
>   	int init_temp;
>   	int default_slope;
>   	int default_offset;
>   };
>   
> +struct airoha_thermal_soc_data {
> +	u32 pllrg_protect;
> +
> +	const struct thermal_zone_device_ops *thdev_ops;
> +	int (*probe)(struct platform_device *pdev,
> +		     struct airoha_thermal_priv *priv);
> +	int (*post_probe)(struct platform_device *pdev);

What the post-probe provides compared to calling the corresponding code 
in the probe function ?

> +};
> +
>   static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
>   {
>   	u32 val;
> @@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
>   	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
>   
>   	/* Give access to thermal regs */
> -	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
> +	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
> +		     priv->pllrg_protect);
>   	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
>   	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
>   
> @@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
>   	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
>   }
>   
> -static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
> +static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)

Please provide a separate patch before where s/airoha/en7581/

[ ... ]
> +static int en7581_thermal_post_probe(struct platform_device *pdev)
> +{
> +	struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
> +
> +	/* Enable LOW and HIGH interrupt (if supported) */

Why "(if supported)" ?

> +	regmap_write(priv->map, EN7581_TEMPMONINT,
> +		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
> +
> +	return 0;
> +}
> +
> +static int airoha_thermal_probe(struct platform_device *pdev)
> +{
> +	const struct airoha_thermal_soc_data *soc_data;
> +	struct airoha_thermal_priv *priv;
> +	struct device *dev = &pdev->dev;
> +	int ret;
> +
> +	soc_data = device_get_match_data(dev);
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->pllrg_protect = soc_data->pllrg_protect;
> +
> +	if (!soc_data->probe)
> +		return -EINVAL;

Shall the driver check its own code ?
> +	ret = soc_data->probe(pdev, priv);
> +	if (ret)

[ ... ]
> +static const struct airoha_thermal_soc_data en7581_data = {
> +	.pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
> +	.thdev_ops = &en7581_thdev_ops,
> +	.probe = &en7581_thermal_probe,
> +	.post_probe = &en7581_thermal_post_probe,
	.probe = en7581_thermal_probe,
	.post_probe = en7581_thermal_post_probe,

> +};
> +
>   static const struct of_device_id airoha_thermal_match[] = {
> -	{ .compatible = "airoha,en7581-thermal" },
> +	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
>   	{},
>   };
>   MODULE_DEVICE_TABLE(of, airoha_thermal_match);


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function
  2025-11-25 17:16   ` Daniel Lezcano
@ 2025-11-25 17:24     ` Christian Marangi
  0 siblings, 0 replies; 12+ messages in thread
From: Christian Marangi @ 2025-11-25 17:24 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Zhang Rui, Lukasz Luba, Lorenzo Bianconi, devicetree,
	linux-kernel, linux-pm

On Tue, Nov 25, 2025 at 06:16:29PM +0100, Daniel Lezcano wrote:
> On 11/6/25 23:59, Christian Marangi wrote:
> > In preparation for support of Airoha AN7583, generalize the probe
> > function to address for the 2 SoC differece.
> > 
> > Implement a match_data struct where it's possible to define a more
> > specific probe and post_probe function and specific thermal ops and
> > pllrg protect value.
> > 
> > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > ---
> >   drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++--------
> >   1 file changed, 75 insertions(+), 27 deletions(-)
> > 
> > diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
> > index 01ed49a4887e..864a01fd8fd8 100644
> > --- a/drivers/thermal/airoha_thermal.c
> > +++ b/drivers/thermal/airoha_thermal.c
> > @@ -198,12 +198,23 @@ struct airoha_thermal_priv {
> >   	struct regmap *chip_scu;
> >   	struct resource scu_adc_res;
> > +	u32 pllrg_protect;
> > +
> >   	struct thermal_zone_device *tz;
> >   	int init_temp;
> >   	int default_slope;
> >   	int default_offset;
> >   };
> > +struct airoha_thermal_soc_data {
> > +	u32 pllrg_protect;
> > +
> > +	const struct thermal_zone_device_ops *thdev_ops;
> > +	int (*probe)(struct platform_device *pdev,
> > +		     struct airoha_thermal_priv *priv);
> > +	int (*post_probe)(struct platform_device *pdev);
> 
> What the post-probe provides compared to calling the corresponding code in
> the probe function ?
>

Hi Daniel,

the usage would be to do those operation that should be done AFTER the
thermal zone are registered. In this specific case, to enable the
interrupt.

(they can't be enabled before as they will fire up immediately due to
wrong configuration of trip point)

I can also limit enabling the interrupt to AN7581 by checking the
compatible. I probably went too much with the modular approach.

> > +};
> > +
> >   static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
> >   {
> >   	u32 val;
> > @@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
> >   	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
> >   	/* Give access to thermal regs */
> > -	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
> > +	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
> > +		     priv->pllrg_protect);
> >   	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
> >   	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
> > @@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
> >   	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
> >   }
> > -static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
> > +static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
> 
> Please provide a separate patch before where s/airoha/en7581/
> 

Ok no problem.

> [ ... ]
> > +static int en7581_thermal_post_probe(struct platform_device *pdev)
> > +{
> > +	struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
> > +
> > +	/* Enable LOW and HIGH interrupt (if supported) */
> 
> Why "(if supported)" ?
> 

Airoha AN7583 won't support this. But I understand this is confusing
since this function is specific to AN7581.

> > +	regmap_write(priv->map, EN7581_TEMPMONINT,
> > +		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
> > +
> > +	return 0;
> > +}
> > +
> > +static int airoha_thermal_probe(struct platform_device *pdev)
> > +{
> > +	const struct airoha_thermal_soc_data *soc_data;
> > +	struct airoha_thermal_priv *priv;
> > +	struct device *dev = &pdev->dev;
> > +	int ret;
> > +
> > +	soc_data = device_get_match_data(dev);
> > +
> > +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	priv->pllrg_protect = soc_data->pllrg_protect;
> > +
> > +	if (!soc_data->probe)
> > +		return -EINVAL;
> 
> Shall the driver check its own code ?
> > +	ret = soc_data->probe(pdev, priv);
> > +	if (ret)
> 

Well it's expected to be always present so I guess I can drop this.

> [ ... ]
> > +static const struct airoha_thermal_soc_data en7581_data = {
> > +	.pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
> > +	.thdev_ops = &en7581_thdev_ops,
> > +	.probe = &en7581_thermal_probe,
> > +	.post_probe = &en7581_thermal_post_probe,
> 	.probe = en7581_thermal_probe,
> 	.post_probe = en7581_thermal_post_probe,
> 
> > +};
> > +
> >   static const struct of_device_id airoha_thermal_match[] = {
> > -	{ .compatible = "airoha,en7581-thermal" },
> > +	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
> >   	{},
> >   };
> >   MODULE_DEVICE_TABLE(of, airoha_thermal_match);
> 
> 
> -- 
> <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
> 
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog

-- 
	Ansuel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function
  2025-11-06 22:59 ` [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function Christian Marangi
  2025-11-25 17:16   ` Daniel Lezcano
@ 2025-11-25 17:41   ` Daniel Lezcano
  1 sibling, 0 replies; 12+ messages in thread
From: Daniel Lezcano @ 2025-11-25 17:41 UTC (permalink / raw)
  To: Christian Marangi, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Lorenzo Bianconi,
	devicetree, linux-kernel, linux-pm

On 11/6/25 23:59, Christian Marangi wrote:
> In preparation for support of Airoha AN7583, generalize the probe
> function to address for the 2 SoC differece.
> 
> Implement a match_data struct where it's possible to define a more
> specific probe and post_probe function and specific thermal ops and
> pllrg protect value.
> 
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
>   drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++--------
>   1 file changed, 75 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
> index 01ed49a4887e..864a01fd8fd8 100644
> --- a/drivers/thermal/airoha_thermal.c
> +++ b/drivers/thermal/airoha_thermal.c
> @@ -198,12 +198,23 @@ struct airoha_thermal_priv {
>   	struct regmap *chip_scu;
>   	struct resource scu_adc_res;
>   
> +	u32 pllrg_protect;
> +
>   	struct thermal_zone_device *tz;
>   	int init_temp;
>   	int default_slope;
>   	int default_offset;
>   };
>   
> +struct airoha_thermal_soc_data {
> +	u32 pllrg_protect;
> +
> +	const struct thermal_zone_device_ops *thdev_ops;
> +	int (*probe)(struct platform_device *pdev,
> +		     struct airoha_thermal_priv *priv);
> +	int (*post_probe)(struct platform_device *pdev);
> +};
> +
>   static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
>   {
>   	u32 val;
> @@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
>   	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
>   
>   	/* Give access to thermal regs */
> -	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
> +	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
> +		     priv->pllrg_protect);
>   	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
>   	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
>   
> @@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
>   	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
>   }
>   
> -static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
> +static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
>   {
>   	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
>   	int min_value, max_value, avg_value, value;
> @@ -253,7 +265,7 @@ static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
>   	return 0;
>   }
>   
> -static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
> +static int en7581_thermal_set_trips(struct thermal_zone_device *tz, int low,
>   				    int high)
>   {
>   	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
> @@ -290,12 +302,12 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
>   	return 0;
>   }
>   
> -static const struct thermal_zone_device_ops thdev_ops = {
> -	.get_temp = airoha_thermal_get_temp,
> -	.set_trips = airoha_thermal_set_trips,
> +static const struct thermal_zone_device_ops en7581_thdev_ops = {
> +	.get_temp = en7581_thermal_get_temp,
> +	.set_trips = en7581_thermal_set_trips,
>   };
>   
> -static irqreturn_t airoha_thermal_irq(int irq, void *data)
> +static irqreturn_t en7581_thermal_irq(int irq, void *data)
>   {
>   	struct airoha_thermal_priv *priv = data;
>   	enum thermal_notify_event event;
> @@ -326,7 +338,7 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
>   	return IRQ_HANDLED;
>   }
>   
> -static void airoha_thermal_setup_adc_val(struct device *dev,
> +static void en7581_thermal_setup_adc_val(struct device *dev,
>   					 struct airoha_thermal_priv *priv)
>   {
>   	u32 efuse_calib_info, cpu_sensor;
> @@ -356,7 +368,7 @@ static void airoha_thermal_setup_adc_val(struct device *dev,
>   	}
>   }
>   
> -static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
> +static void en7581_thermal_setup_monitor(struct airoha_thermal_priv *priv)
>   {
>   	/* Set measure mode */
>   	regmap_write(priv->map, EN7581_TEMPMSRCTL0,
> @@ -411,30 +423,26 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
>   		     FIELD_PREP(EN7581_ADC_POLL_INTVL, 146));
>   }
>   
> -static const struct regmap_config airoha_thermal_regmap_config = {
> +static const struct regmap_config en7581_thermal_regmap_config = {
>   	.reg_bits		= 32,
>   	.reg_stride		= 4,
>   	.val_bits		= 32,
>   };
>   
> -static int airoha_thermal_probe(struct platform_device *pdev)
> +static int en7581_thermal_probe(struct platform_device *pdev,
> +				struct airoha_thermal_priv *priv)
>   {
> -	struct airoha_thermal_priv *priv;
>   	struct device_node *chip_scu_np;
>   	struct device *dev = &pdev->dev;
>   	void __iomem *base;
>   	int irq, ret;
>   
> -	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> -	if (!priv)
> -		return -ENOMEM;
> -
>   	base = devm_platform_ioremap_resource(pdev, 0);
>   	if (IS_ERR(base))
>   		return PTR_ERR(base);
>   
>   	priv->map = devm_regmap_init_mmio(dev, base,
> -					  &airoha_thermal_regmap_config);
> +					  &en7581_thermal_regmap_config);
>   	if (IS_ERR(priv->map))
>   		return PTR_ERR(priv->map);
>   
> @@ -454,18 +462,55 @@ static int airoha_thermal_probe(struct platform_device *pdev)
>   		return irq;
>   
>   	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
> -					airoha_thermal_irq, IRQF_ONESHOT,
> +					en7581_thermal_irq, IRQF_ONESHOT,
>   					pdev->name, priv);
>   	if (ret) {
>   		dev_err(dev, "Can't get interrupt working.\n");
>   		return ret;
>   	}
>   
> -	airoha_thermal_setup_monitor(priv);
> -	airoha_thermal_setup_adc_val(dev, priv);
> +	en7581_thermal_setup_monitor(priv);
> +	en7581_thermal_setup_adc_val(dev, priv);
> +
> +	return 0;
> +}
> +
> +static int en7581_thermal_post_probe(struct platform_device *pdev)
> +{
> +	struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
> +
> +	/* Enable LOW and HIGH interrupt (if supported) */
> +	regmap_write(priv->map, EN7581_TEMPMONINT,
> +		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
> +
> +	return 0;
> +}
> +
> +static int airoha_thermal_probe(struct platform_device *pdev)
> +{
> +	const struct airoha_thermal_soc_data *soc_data;
> +	struct airoha_thermal_priv *priv;
> +	struct device *dev = &pdev->dev;
> +	int ret;
> +
> +	soc_data = device_get_match_data(dev);
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->pllrg_protect = soc_data->pllrg_protect;
> +
> +	if (!soc_data->probe)
> +		return -EINVAL;
> +
> +	ret = soc_data->probe(pdev, priv);
> +	if (ret)
> +		return ret;
>   
>   	/* register of thermal sensor and get info from DT */
> -	priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops);
> +	priv->tz = devm_thermal_of_zone_register(dev, 0, priv,
> +						 soc_data->thdev_ops);

I suggest to move devm_thermal_of_zone_register() in the platform 
specific probe function, directly pass the corresponding ops.

That will allow to get rid of the post_probe() and the thdev_ops field 
in the airoha_thermal_soc_data structure.

	devm_thermal_of_zone_register(dev, 0, priv, &en7581_thdev_ops);


>   	if (IS_ERR(priv->tz)) {
>   		dev_err(dev, "register thermal zone sensor failed\n");
>   		return PTR_ERR(priv->tz);
> @@ -473,15 +518,18 @@ static int airoha_thermal_probe(struct platform_device *pdev)
>   
>   	platform_set_drvdata(pdev, priv);
>   
> -	/* Enable LOW and HIGH interrupt */
> -	regmap_write(priv->map, EN7581_TEMPMONINT,
> -		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
> -
> -	return 0;
> +	return soc_data->post_probe ? soc_data->post_probe(pdev) : 0;
>   }
>   
> +static const struct airoha_thermal_soc_data en7581_data = {
> +	.pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
> +	.thdev_ops = &en7581_thdev_ops,
> +	.probe = &en7581_thermal_probe,
> +	.post_probe = &en7581_thermal_post_probe,
> +};
> +
>   static const struct of_device_id airoha_thermal_match[] = {
> -	{ .compatible = "airoha,en7581-thermal" },
> +	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
>   	{},
>   };
>   MODULE_DEVICE_TABLE(of, airoha_thermal_match);


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/5] thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux function
  2025-11-06 22:59 ` [PATCH v3 3/5] thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux function Christian Marangi
@ 2025-11-25 21:20   ` Daniel Lezcano
  0 siblings, 0 replies; 12+ messages in thread
From: Daniel Lezcano @ 2025-11-25 21:20 UTC (permalink / raw)
  To: Christian Marangi, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Lorenzo Bianconi,
	devicetree, linux-kernel, linux-pm

On 11/6/25 23:59, Christian Marangi wrote:
> In preparation for support of Airoha AN7583, generalize
> get_thermal_ADC() and set_thermal_mux() with the use of reg_field API.
> 
> This is to account the same logic between the current supported SoC and
> the new one but with different register address.
> 
> While at it also further improve some comments and move sleep inside the
> set_thermal_mux function.
> 
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
>   drivers/thermal/airoha_thermal.c | 54 +++++++++++++++++++++++++-------
>   1 file changed, 42 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
> index 864a01fd8fd8..a062922cb116 100644
> --- a/drivers/thermal/airoha_thermal.c
> +++ b/drivers/thermal/airoha_thermal.c
> @@ -193,9 +193,18 @@
>   
>   #define AIROHA_MAX_SAMPLES			6
>   
> +enum airoha_thermal_chip_scu_field {
> +	AIROHA_THERMAL_DOUT_TADC,
> +	AIROHA_THERMAL_MUX_TADC,
> +
> +	/* keep last */
> +	AIROHA_THERMAL_FIELD_MAX,

nit: if last, no comma :)
nit2: naming is not consistent

> +};
> +
>   struct airoha_thermal_priv {
>   	struct regmap *map;
>   	struct regmap *chip_scu;
> +	struct regmap_field *chip_scu_fields[AIROHA_THERMAL_FIELD_MAX];
>   	struct resource scu_adc_res;
>   
>   	u32 pllrg_protect;
> @@ -219,22 +228,29 @@ static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
>   {
>   	u32 val;
>   
> -	regmap_read(priv->chip_scu, EN7581_DOUT_TADC, &val);
> -	return FIELD_GET(EN7581_DOUT_TADC_MASK, val);
> +	regmap_field_read(priv->chip_scu_fields[AIROHA_THERMAL_DOUT_TADC],
> +			  &val);
> +	return val;
>   }
>   
> -static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
> +static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv,
> +				   int tdac_idx)
>   {
> -	u32 adc_mux, pllrg;
> +	u32 pllrg;
>   
>   	/* Save PLLRG current value */
>   	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
>   
> -	/* Give access to thermal regs */
> +	/* Give access to Thermal regs */
>   	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
>   		     priv->pllrg_protect);
> -	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
> -	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
> +
> +	/* Configure Thermal ADC mux to tdac_idx */
> +	regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
> +			   tdac_idx);
> +
> +	/* Sleep 10 ms for Thermal ADC to enable */
> +	usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);

10ms ? It is a lot no ?
>   	/* Restore PLLRG value on exit */
>   	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
> @@ -343,10 +359,8 @@ static void en7581_thermal_setup_adc_val(struct device *dev,
>   {
>   	u32 efuse_calib_info, cpu_sensor;
>   
> -	/* Setup thermal sensor to ADC mode and setup the mux to DIODE1 */
> -	airoha_init_thermal_ADC_mode(priv);
> -	/* sleep 10 ms for ADC to enable */
> -	usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
> +	/* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */
> +	airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1);
>   
>   	regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
>   	if (efuse_calib_info) {
> @@ -429,13 +443,18 @@ static const struct regmap_config en7581_thermal_regmap_config = {
>   	.val_bits		= 32,
>   };
>   
> +static const struct reg_field en7581_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = {
> +	[AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(EN7581_DOUT_TADC, 0, 15),
> +	[AIROHA_THERMAL_MUX_TADC] = REG_FIELD(EN7581_PWD_TADC, 1, 3),
> +};
> +
>   static int en7581_thermal_probe(struct platform_device *pdev,
>   				struct airoha_thermal_priv *priv)
>   {
>   	struct device_node *chip_scu_np;
>   	struct device *dev = &pdev->dev;
>   	void __iomem *base;
> -	int irq, ret;
> +	int i, irq, ret;
>   
>   	base = devm_platform_ioremap_resource(pdev, 0);
>   	if (IS_ERR(base))
> @@ -454,6 +473,17 @@ static int en7581_thermal_probe(struct platform_device *pdev,
>   	if (IS_ERR(priv->chip_scu))
>   		return PTR_ERR(priv->chip_scu);
>   
> +	for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
> +		struct regmap_field *field;
> +
> +		field = devm_regmap_field_alloc(dev, priv->chip_scu,
> +						en7581_chip_scu_fields[i]);
> +		if (IS_ERR(field))
> +			return PTR_ERR(field);
> +
> +		priv->chip_scu_fields[i] = field;
> +	}
> +
>   	of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res);
>   	of_node_put(chip_scu_np);
>   


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-11-25 21:20 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-06 22:59 [PATCH v3 0/5] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
2025-11-06 22:59 ` [PATCH v3 1/5] thermal/drivers: airoha: Convert to regmap API Christian Marangi
2025-11-06 22:59 ` [PATCH v3 2/5] thermal/drivers: airoha: Generalize probe function Christian Marangi
2025-11-25 17:16   ` Daniel Lezcano
2025-11-25 17:24     ` Christian Marangi
2025-11-25 17:41   ` Daniel Lezcano
2025-11-06 22:59 ` [PATCH v3 3/5] thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux function Christian Marangi
2025-11-25 21:20   ` Daniel Lezcano
2025-11-06 22:59 ` [PATCH v3 4/5] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC Christian Marangi
2025-11-07  7:45   ` Krzysztof Kozlowski
2025-11-07  8:53     ` Krzysztof Kozlowski
2025-11-06 22:59 ` [PATCH v3 5/5] thermal/drivers: airoha: Add support for AN7583 Thermal Sensor Christian Marangi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).