This is a patch series for thermal driver for Sunplus SoC.
Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates
many peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and
etc.) into a single chip. It is designed for industrial control.
Refer to:
https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
https://tibbo.com/store/plus1.html
Li-hao Kuo (2):
thermal: Add thermal driver for Sunplus
dt-bindings:thermal: Add Sunplus schema
.../bindings/thermal/sunplus,thermal.yaml | 43 +++++++
MAINTAINERS | 7 ++
drivers/thermal/Kconfig | 10 ++
drivers/thermal/Makefile | 1 +
drivers/thermal/sunplus_thermal.c | 135 +++++++++++++++++++++
5 files changed, 196 insertions(+)
create mode 100644 Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
create mode 100644 drivers/thermal/sunplus_thermal.c
--
2.7.4
Add thermal driver for Sunplus.
Signed-off-by: Li-hao Kuo <[email protected]>
---
Changes in v8:
- Modify yaml file.
modify the setting compatible
- Change yaml file name.
- Modify driver.
mosdify and simply the nvmem setting and remove valiable
MAINTAINERS | 6 ++
drivers/thermal/Kconfig | 10 +++
drivers/thermal/Makefile | 1 +
drivers/thermal/sunplus_thermal.c | 135 ++++++++++++++++++++++++++++++++++++++
4 files changed, 152 insertions(+)
create mode 100644 drivers/thermal/sunplus_thermal.c
diff --git a/MAINTAINERS b/MAINTAINERS
index edc96cd..82143ff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18896,6 +18896,12 @@ S: Maintained
F: Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml
F: drivers/spi/spi-sunplus-sp7021.c
+SUNPLUS THERMAL DRIVER
+M: Li-hao Kuo <[email protected]>
+L: [email protected]
+S: Maintained
+F: drivers/thermal/sunplus_thermal.c
+
SUNPLUS UART DRIVER
M: Hammer Hsieh <[email protected]>
S: Maintained
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 0e5cc94..595f507 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -504,4 +504,14 @@ config KHADAS_MCU_FAN_THERMAL
If you say yes here you get support for the FAN controlled
by the Microcontroller found on the Khadas VIM boards.
+config SUNPLUS_THERMAL
+ tristate "Sunplus thermal drivers"
+ depends on SOC_SP7021 || COMPILE_TEST
+ help
+ This the Sunplus SP7021 thermal driver, which supports the primitive
+ temperature sensor embedded in Sunplus SP7021 SoC.
+
+ If you have a Sunplus SP7021 platform say Y here and enable this option
+ to have support for thermal management
+
endif
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index f0c36a1..38a76f9 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -61,3 +61,4 @@ obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o
obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o
obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL) += khadas_mcu_fan.o
+obj-$(CONFIG_SUNPLUS_THERMAL) += sunplus_thermal.o
diff --git a/drivers/thermal/sunplus_thermal.c b/drivers/thermal/sunplus_thermal.c
new file mode 100644
index 0000000..d4e22fc
--- /dev/null
+++ b/drivers/thermal/sunplus_thermal.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Sunplus Inc.
+ * Author: Li-hao Kuo <[email protected]>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/thermal.h>
+
+#define ENABLE_THERMAL BIT(31)
+#define SP_THERMAL_MASK GENMASK(10, 0)
+
+#define TEMP_RATE 608
+#define TEMP_BASE 3500
+#define TEMP_OTP_BASE 1518
+
+#define SP_THERMAL_CTL0_REG 0x0000
+#define SP_THERMAL_STS0_REG 0x0030
+
+/* common data structures */
+struct sp_thermal_data {
+ struct thermal_zone_device *pcb_tz;
+ void __iomem *regs;
+ int *otp_temp0;
+};
+
+static int sunplus_get_otp_temp_coef(struct sp_thermal_data *sp_data, struct device *dev)
+{
+ struct nvmem_cell *cell;
+ ssize_t otp_l;
+
+ cell = nvmem_cell_get(dev, "calib");
+ if (IS_ERR(cell))
+ return PTR_ERR(cell);
+
+ sp_data->otp_temp0 = nvmem_cell_read(cell, &otp_l);
+ nvmem_cell_put(cell);
+
+ if (*sp_data->otp_temp0 == 0)
+ *sp_data->otp_temp0 = TEMP_OTP_BASE;
+
+ return 0;
+}
+
+/*
+ * There is a thermal sensor instance for SUNPLUS Soc
+ * T_CODE is the ADC of the thermal sensor
+ * T_CODE : 11 digits in total
+ * When remanufacturing, the 35 degree T_CODE will be read and stored in nvcell.
+ * otp_temp0 is the 35 degree T_CODE obtained from nvcell
+ * The function will get 35 degree T_CODE for thermal calibration.
+ * TEMP_RATE is the SUNPLUS thermal temperature slope.
+ */
+
+static int sp_thermal_get_sensor_temp(void *data, int *temp)
+{
+ struct sp_thermal_data *sp_data = data;
+ int t_code;
+
+ t_code = readl(sp_data->regs + SP_THERMAL_STS0_REG);
+ t_code = FIELD_GET(SP_THERMAL_MASK, t_code);
+ *temp = ((*sp_data->otp_temp0 - t_code) * 10000 / TEMP_RATE) + TEMP_BASE;
+ *temp *= 10;
+ return 0;
+}
+
+static const struct thermal_zone_of_device_ops sp_of_thermal_ops = {
+ .get_temp = sp_thermal_get_sensor_temp,
+};
+
+static int sunplus_thermal_probe(struct platform_device *pdev)
+{
+ struct sp_thermal_data *sp_data;
+ int ret;
+
+ sp_data = devm_kzalloc(&pdev->dev, sizeof(*sp_data), GFP_KERNEL);
+ if (!sp_data)
+ return -ENOMEM;
+
+ sp_data->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(sp_data->regs)) {
+ dev_err(&pdev->dev, "resource get fail\n");
+ return PTR_ERR(sp_data->regs);
+ }
+
+ writel(ENABLE_THERMAL, sp_data->regs + SP_THERMAL_CTL0_REG);
+
+ platform_set_drvdata(pdev, sp_data);
+ ret = sunplus_get_otp_temp_coef(sp_data, &pdev->dev);
+ if (ret)
+ return ret;
+
+ sp_data->pcb_tz = devm_thermal_zone_of_sensor_register(&pdev->dev,
+ 0,
+ sp_data, &sp_of_thermal_ops);
+ if (IS_ERR_OR_NULL(sp_data->pcb_tz))
+ return PTR_ERR(sp_data->pcb_tz);
+
+ return ret;
+}
+
+static int sunplus_thermal_remove(struct platform_device *pdev)
+{
+ struct sp_thermal_data *sp_data = platform_get_drvdata(pdev);
+
+ thermal_zone_device_unregister(sp_data->pcb_tz);
+ return 0;
+}
+
+static const struct of_device_id of_sunplus_thermal_ids[] = {
+ { .compatible = "sunplus,thermal" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, of_sunplus_thermal_ids);
+
+static struct platform_driver sunplus_thermal_driver = {
+ .probe = sunplus_thermal_probe,
+ .remove = sunplus_thermal_remove,
+ .driver = {
+ .name = "sunplus-thermal",
+ .of_match_table = of_sunplus_thermal_ids,
+ },
+};
+module_platform_driver(sunplus_thermal_driver);
+
+MODULE_AUTHOR("Li-hao Kuo <[email protected]>");
+MODULE_DESCRIPTION("Thermal driver for sunplus SoC");
+MODULE_LICENSE("GPL");
--
2.7.4
Add bindings for Sunplus thermal driver
Signed-off-by: Li-hao Kuo <[email protected]>
---
Changes in v8:
- Modify yaml file.
modify the setting compatible
- Change yaml file name.
- Modify driver.
mosdify and simply the nvmem setting and remove valiable
.../bindings/thermal/sunplus,thermal.yaml | 43 ++++++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 44 insertions(+)
create mode 100644 Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
diff --git a/Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml b/Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
new file mode 100644
index 0000000..1ecf6f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/sunplus,thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus Thermal controller
+
+maintainers:
+ - Li-hao Kuo <[email protected]>
+
+properties:
+ compatible:
+ enum:
+ - sunplus,thermal
+
+ reg:
+ maxItems: 1
+
+ nvmem-cells:
+ maxItems: 1
+
+ nvmem-cell-names:
+ const: calib
+
+required:
+ - compatible
+ - reg
+ - nvmem-cells
+ - nvmem-cell-names
+
+additionalProperties: false
+
+examples:
+ - |
+ thermal@9c000280 {
+ compatible = "sunplus,thermal";
+ reg = <0x9c000280 0xc>;
+ nvmem-cells = <&calib>;
+ nvmem-cell-names = "calib";
+ };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 82143ff..ff49023 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18900,6 +18900,7 @@ SUNPLUS THERMAL DRIVER
M: Li-hao Kuo <[email protected]>
L: [email protected]
S: Maintained
+F: Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
F: drivers/thermal/sunplus_thermal.c
SUNPLUS UART DRIVER
--
2.7.4
Hi,
Le 03/05/2022 à 04:13, Li-hao Kuo a écrit :
> Add thermal driver for Sunplus.
>
> Signed-off-by: Li-hao Kuo <[email protected]>
> ---
> Changes in v8:
> - Modify yaml file.
> modify the setting compatible
> - Change yaml file name.
> - Modify driver.
> mosdify and simply the nvmem setting and remove valiable
>
> MAINTAINERS | 6 ++
> drivers/thermal/Kconfig | 10 +++
> drivers/thermal/Makefile | 1 +
> drivers/thermal/sunplus_thermal.c | 135 ++++++++++++++++++++++++++++++++++++++
> 4 files changed, 152 insertions(+)
> create mode 100644 drivers/thermal/sunplus_thermal.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index edc96cd..82143ff 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -18896,6 +18896,12 @@ S: Maintained
> F: Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml
> F: drivers/spi/spi-sunplus-sp7021.c
>
> +SUNPLUS THERMAL DRIVER
> +M: Li-hao Kuo <[email protected]>
> +L: [email protected]
> +S: Maintained
> +F: drivers/thermal/sunplus_thermal.c
> +
> SUNPLUS UART DRIVER
> M: Hammer Hsieh <[email protected]>
> S: Maintained
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index 0e5cc94..595f507 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -504,4 +504,14 @@ config KHADAS_MCU_FAN_THERMAL
> If you say yes here you get support for the FAN controlled
> by the Microcontroller found on the Khadas VIM boards.
>
> +config SUNPLUS_THERMAL
> + tristate "Sunplus thermal drivers"
> + depends on SOC_SP7021 || COMPILE_TEST
> + help
> + This the Sunplus SP7021 thermal driver, which supports the primitive
> + temperature sensor embedded in Sunplus SP7021 SoC.
> +
> + If you have a Sunplus SP7021 platform say Y here and enable this option
> + to have support for thermal management
> +
> endif
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index f0c36a1..38a76f9 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -61,3 +61,4 @@ obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
> obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o
> obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o
> obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL) += khadas_mcu_fan.o
> +obj-$(CONFIG_SUNPLUS_THERMAL) += sunplus_thermal.o
> diff --git a/drivers/thermal/sunplus_thermal.c b/drivers/thermal/sunplus_thermal.c
> new file mode 100644
> index 0000000..d4e22fc
> --- /dev/null
> +++ b/drivers/thermal/sunplus_thermal.c
> @@ -0,0 +1,135 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) Sunplus Inc.
> + * Author: Li-hao Kuo <[email protected]>
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset.h>
> +#include <linux/thermal.h>
> +
> +#define ENABLE_THERMAL BIT(31)
> +#define SP_THERMAL_MASK GENMASK(10, 0)
> +
> +#define TEMP_RATE 608
> +#define TEMP_BASE 3500
> +#define TEMP_OTP_BASE 1518
> +
> +#define SP_THERMAL_CTL0_REG 0x0000
> +#define SP_THERMAL_STS0_REG 0x0030
> +
> +/* common data structures */
> +struct sp_thermal_data {
> + struct thermal_zone_device *pcb_tz;
> + void __iomem *regs;
> + int *otp_temp0;
> +};
> +
> +static int sunplus_get_otp_temp_coef(struct sp_thermal_data *sp_data, struct device *dev)
> +{
> + struct nvmem_cell *cell;
> + ssize_t otp_l;
> +
> + cell = nvmem_cell_get(dev, "calib");
> + if (IS_ERR(cell))
> + return PTR_ERR(cell);
> +
> + sp_data->otp_temp0 = nvmem_cell_read(cell, &otp_l);
> + nvmem_cell_put(cell);
> +
> + if (*sp_data->otp_temp0 == 0)
> + *sp_data->otp_temp0 = TEMP_OTP_BASE;
> +
> + return 0;
> +}
> +
> +/*
> + * There is a thermal sensor instance for SUNPLUS Soc
> + * T_CODE is the ADC of the thermal sensor
> + * T_CODE : 11 digits in total
> + * When remanufacturing, the 35 degree T_CODE will be read and stored in nvcell.
> + * otp_temp0 is the 35 degree T_CODE obtained from nvcell
> + * The function will get 35 degree T_CODE for thermal calibration.
> + * TEMP_RATE is the SUNPLUS thermal temperature slope.
> + */
> +
> +static int sp_thermal_get_sensor_temp(void *data, int *temp)
> +{
> + struct sp_thermal_data *sp_data = data;
> + int t_code;
> +
> + t_code = readl(sp_data->regs + SP_THERMAL_STS0_REG);
> + t_code = FIELD_GET(SP_THERMAL_MASK, t_code);
> + *temp = ((*sp_data->otp_temp0 - t_code) * 10000 / TEMP_RATE) + TEMP_BASE;
> + *temp *= 10;
> + return 0;
> +}
> +
> +static const struct thermal_zone_of_device_ops sp_of_thermal_ops = {
> + .get_temp = sp_thermal_get_sensor_temp,
> +};
> +
> +static int sunplus_thermal_probe(struct platform_device *pdev)
> +{
> + struct sp_thermal_data *sp_data;
> + int ret;
> +
> + sp_data = devm_kzalloc(&pdev->dev, sizeof(*sp_data), GFP_KERNEL);
> + if (!sp_data)
> + return -ENOMEM;
> +
> + sp_data->regs = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(sp_data->regs)) {
> + dev_err(&pdev->dev, "resource get fail\n");
> + return PTR_ERR(sp_data->regs);
> + }
> +
> + writel(ENABLE_THERMAL, sp_data->regs + SP_THERMAL_CTL0_REG);
> +
> + platform_set_drvdata(pdev, sp_data);
> + ret = sunplus_get_otp_temp_coef(sp_data, &pdev->dev);
> + if (ret)
> + return ret;
> +
> + sp_data->pcb_tz = devm_thermal_zone_of_sensor_register(&pdev->dev,
> + 0,
> + sp_data, &sp_of_thermal_ops);
sp_data->pcb_tz is the result of devm_thermal_zone_of_sensor_register()
and devm_ functions usually don't need any clean-up. It is done
automagically by the kernel itself.
> + if (IS_ERR_OR_NULL(sp_data->pcb_tz))
> + return PTR_ERR(sp_data->pcb_tz);
> +
> + return ret;
> +}
> +
> +static int sunplus_thermal_remove(struct platform_device *pdev)
> +{
> + struct sp_thermal_data *sp_data = platform_get_drvdata(pdev);
> +
> + thermal_zone_device_unregister(sp_data->pcb_tz);
But here it is unregistered.
1) I would have expected that no unregister function is needed.
2) Should one be there, based on naming,
thermal_zone_of_sensor_unregister() would look more consistent.
I know nothing about the thermal API, so don't take this comment too
seriously. It just look odd to me when I gave it a look.
Just my 2c,
CJ
> + return 0;
> +}
> +
> +static const struct of_device_id of_sunplus_thermal_ids[] = {
> + { .compatible = "sunplus,thermal" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, of_sunplus_thermal_ids);
> +
> +static struct platform_driver sunplus_thermal_driver = {
> + .probe = sunplus_thermal_probe,
> + .remove = sunplus_thermal_remove,
> + .driver = {
> + .name = "sunplus-thermal",
> + .of_match_table = of_sunplus_thermal_ids,
> + },
> +};
> +module_platform_driver(sunplus_thermal_driver);
> +
> +MODULE_AUTHOR("Li-hao Kuo <[email protected]>");
> +MODULE_DESCRIPTION("Thermal driver for sunplus SoC");
> +MODULE_LICENSE("GPL");
On 03/05/2022 04:13, Li-hao Kuo wrote:
> Add bindings for Sunplus thermal driver
>
> Signed-off-by: Li-hao Kuo <[email protected]>
> ---
> Changes in v8:
> - Modify yaml file.
> modify the setting compatible
> - Change yaml file name.
> - Modify driver.
> mosdify and simply the nvmem setting and remove valiable
>
> .../bindings/thermal/sunplus,thermal.yaml | 43 ++++++++++++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 44 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
>
> diff --git a/Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml b/Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
> new file mode 100644
> index 0000000..1ecf6f6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
> @@ -0,0 +1,43 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright (C) Sunplus Co., Ltd.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/thermal/sunplus,thermal.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Sunplus Thermal controller
> +
> +maintainers:
> + - Li-hao Kuo <[email protected]>
> +
> +properties:
> + compatible:
> + enum:
> + - sunplus,thermal
This is a very surprising change and was never requested by me or other
reviewers. It is also not correct. Previous compatible was correct.
Best regards,
Krzysztof
Hi,
below, some additional nitpick.
CJ
Le 03/05/2022 à 04:13, Li-hao Kuo a écrit :
> Add thermal driver for Sunplus.
>
> Signed-off-by: Li-hao Kuo <[email protected]>
> ---
> Changes in v8:
> - Modify yaml file.
> modify the setting compatible
> - Change yaml file name.
> - Modify driver.
> mosdify and simply the nvmem setting and remove valiable
>
> MAINTAINERS | 6 ++
> drivers/thermal/Kconfig | 10 +++
> drivers/thermal/Makefile | 1 +
> drivers/thermal/sunplus_thermal.c | 135 ++++++++++++++++++++++++++++++++++++++
> 4 files changed, 152 insertions(+)
> create mode 100644 drivers/thermal/sunplus_thermal.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index edc96cd..82143ff 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -18896,6 +18896,12 @@ S: Maintained
> F: Documentation/devicetree/bindings/spi/spi-sunplus-sp7021.yaml
> F: drivers/spi/spi-sunplus-sp7021.c
>
> +SUNPLUS THERMAL DRIVER
> +M: Li-hao Kuo <[email protected]>
> +L: [email protected]
> +S: Maintained
> +F: drivers/thermal/sunplus_thermal.c
> +
> SUNPLUS UART DRIVER
> M: Hammer Hsieh <[email protected]>
> S: Maintained
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index 0e5cc94..595f507 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -504,4 +504,14 @@ config KHADAS_MCU_FAN_THERMAL
> If you say yes here you get support for the FAN controlled
> by the Microcontroller found on the Khadas VIM boards.
>
> +config SUNPLUS_THERMAL
> + tristate "Sunplus thermal drivers"
> + depends on SOC_SP7021 || COMPILE_TEST
> + help
> + This the Sunplus SP7021 thermal driver, which supports the primitive
Missing word?
This *enables* the... ?
> + temperature sensor embedded in Sunplus SP7021 SoC.
> +
> + If you have a Sunplus SP7021 platform say Y here and enable this option
> + to have support for thermal management
> +
> endif
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index f0c36a1..38a76f9 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -61,3 +61,4 @@ obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
> obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o
> obj-$(CONFIG_SPRD_THERMAL) += sprd_thermal.o
> obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL) += khadas_mcu_fan.o
> +obj-$(CONFIG_SUNPLUS_THERMAL) += sunplus_thermal.o
> diff --git a/drivers/thermal/sunplus_thermal.c b/drivers/thermal/sunplus_thermal.c
> new file mode 100644
> index 0000000..d4e22fc
> --- /dev/null
> +++ b/drivers/thermal/sunplus_thermal.c
> @@ -0,0 +1,135 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) Sunplus Inc.
> + * Author: Li-hao Kuo <[email protected]>
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset.h>
> +#include <linux/thermal.h>
> +
> +#define ENABLE_THERMAL BIT(31)
> +#define SP_THERMAL_MASK GENMASK(10, 0)
> +
> +#define TEMP_RATE 608
> +#define TEMP_BASE 3500
> +#define TEMP_OTP_BASE 1518
> +
> +#define SP_THERMAL_CTL0_REG 0x0000
> +#define SP_THERMAL_STS0_REG 0x0030
> +
> +/* common data structures */
> +struct sp_thermal_data {
> + struct thermal_zone_device *pcb_tz;
> + void __iomem *regs;
> + int *otp_temp0;
> +};
> +
> +static int sunplus_get_otp_temp_coef(struct sp_thermal_data *sp_data, struct device *dev)
> +{
> + struct nvmem_cell *cell;
> + ssize_t otp_l;
> +
> + cell = nvmem_cell_get(dev, "calib");
> + if (IS_ERR(cell))
> + return PTR_ERR(cell);
> +
> + sp_data->otp_temp0 = nvmem_cell_read(cell, &otp_l);
> + nvmem_cell_put(cell);
> +
> + if (*sp_data->otp_temp0 == 0)
> + *sp_data->otp_temp0 = TEMP_OTP_BASE;
> +
> + return 0;
> +}
> +
> +/*
> + * There is a thermal sensor instance for SUNPLUS Soc
I don't know what is the best, but if you want to be consistent, other
places are about Sunplus, not SUNPLUS.
> + * T_CODE is the ADC of the thermal sensor
> + * T_CODE : 11 digits in total
> + * When remanufacturing, the 35 degree T_CODE will be read and stored in nvcell.
> + * otp_temp0 is the 35 degree T_CODE obtained from nvcell
> + * The function will get 35 degree T_CODE for thermal calibration.
> + * TEMP_RATE is the SUNPLUS thermal temperature slope.
Same here.
> + */
> +
> +static int sp_thermal_get_sensor_temp(void *data, int *temp)
> +{
> + struct sp_thermal_data *sp_data = data;
> + int t_code;
> +
> + t_code = readl(sp_data->regs + SP_THERMAL_STS0_REG);
> + t_code = FIELD_GET(SP_THERMAL_MASK, t_code);
> + *temp = ((*sp_data->otp_temp0 - t_code) * 10000 / TEMP_RATE) + TEMP_BASE;
> + *temp *= 10;
> + return 0;
> +}
> +
> +static const struct thermal_zone_of_device_ops sp_of_thermal_ops = {
> + .get_temp = sp_thermal_get_sensor_temp,
> +};
> +
> +static int sunplus_thermal_probe(struct platform_device *pdev)
> +{
> + struct sp_thermal_data *sp_data;
> + int ret;
> +
> + sp_data = devm_kzalloc(&pdev->dev, sizeof(*sp_data), GFP_KERNEL);
> + if (!sp_data)
> + return -ENOMEM;
> +
> + sp_data->regs = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(sp_data->regs)) {
> + dev_err(&pdev->dev, "resource get fail\n");
> + return PTR_ERR(sp_data->regs);
> + }
> +
> + writel(ENABLE_THERMAL, sp_data->regs + SP_THERMAL_CTL0_REG);
> +
> + platform_set_drvdata(pdev, sp_data);
> + ret = sunplus_get_otp_temp_coef(sp_data, &pdev->dev);
> + if (ret)
> + return ret;
> +
> + sp_data->pcb_tz = devm_thermal_zone_of_sensor_register(&pdev->dev,
> + 0,
> + sp_data, &sp_of_thermal_ops);
> + if (IS_ERR_OR_NULL(sp_data->pcb_tz))
I don't think that devm_thermal_zone_of_sensor_register() can return NULL.
> + return PTR_ERR(sp_data->pcb_tz);
> +
> + return ret;
> +}
> +
> +static int sunplus_thermal_remove(struct platform_device *pdev)
> +{
> + struct sp_thermal_data *sp_data = platform_get_drvdata(pdev);
> +
> + thermal_zone_device_unregister(sp_data->pcb_tz);
> + return 0;
> +}
> +
> +static const struct of_device_id of_sunplus_thermal_ids[] = {
> + { .compatible = "sunplus,thermal" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, of_sunplus_thermal_ids);
> +
> +static struct platform_driver sunplus_thermal_driver = {
> + .probe = sunplus_thermal_probe,
> + .remove = sunplus_thermal_remove,
> + .driver = {
> + .name = "sunplus-thermal",
> + .of_match_table = of_sunplus_thermal_ids,
> + },
The }, should be aligned on .driver (1 less tabulation)
> +};
> +module_platform_driver(sunplus_thermal_driver);
> +
> +MODULE_AUTHOR("Li-hao Kuo <[email protected]>");
> +MODULE_DESCRIPTION("Thermal driver for sunplus SoC");
Other places are about Sunplus, not sunplus
> +MODULE_LICENSE("GPL");
On Tue, May 03, 2022 at 10:13:08AM +0800, Li-hao Kuo wrote:
> Add bindings for Sunplus thermal driver
>
> Signed-off-by: Li-hao Kuo <[email protected]>
> ---
> Changes in v8:
> - Modify yaml file.
> modify the setting compatible
> - Change yaml file name.
> - Modify driver.
> mosdify and simply the nvmem setting and remove valiable
>
> .../bindings/thermal/sunplus,thermal.yaml | 43 ++++++++++++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 44 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
>
> diff --git a/Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml b/Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
> new file mode 100644
> index 0000000..1ecf6f6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
> @@ -0,0 +1,43 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright (C) Sunplus Co., Ltd.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/thermal/sunplus,thermal.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Sunplus Thermal controller
> +
> +maintainers:
> + - Li-hao Kuo <[email protected]>
> +
> +properties:
> + compatible:
> + enum:
> + - sunplus,thermal
I don't think is is what was suggested. This must be SoC specific.
> +
> + reg:
> + maxItems: 1
> +
> + nvmem-cells:
> + maxItems: 1
> +
> + nvmem-cell-names:
> + const: calib
> +
> +required:
> + - compatible
> + - reg
> + - nvmem-cells
> + - nvmem-cell-names
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + thermal@9c000280 {
> + compatible = "sunplus,thermal";
> + reg = <0x9c000280 0xc>;
> + nvmem-cells = <&calib>;
> + nvmem-cell-names = "calib";
> + };
> +...
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 82143ff..ff49023 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -18900,6 +18900,7 @@ SUNPLUS THERMAL DRIVER
> M: Li-hao Kuo <[email protected]>
> L: [email protected]
> S: Maintained
> +F: Documentation/devicetree/bindings/thermal/sunplus,thermal.yaml
> F: drivers/thermal/sunplus_thermal.c
>
> SUNPLUS UART DRIVER
> --
> 2.7.4
>
>