
Since the Armbian sources refer to linux 4.19.76 as being linux-mainline, all the patches from linux-4.19 were moved to linux-mainline_4.19 and the linux_4.19.76 recipes was named accordingly. This patch makes 4.19.76 as default version for linux Signed-off-by: Vicentiu Galanopulo <vicentiu@balena.io>
498 lines
15 KiB
Diff
498 lines
15 KiB
Diff
From 9da4c28e6a7963f67e2ca05098683445a1571538 Mon Sep 17 00:00:00 2001
|
|
From: Ondrej Jirman <megous@megous.com>
|
|
Date: Tue, 14 Nov 2017 17:15:54 +0100
|
|
Subject: [PATCH 05/82] thermal: sun8i: Add support for A83T thermal sensors
|
|
|
|
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
|
---
|
|
drivers/thermal/sun8i_ths.c | 371 ++++++++++++++++++++++++++----------
|
|
1 file changed, 274 insertions(+), 97 deletions(-)
|
|
|
|
diff --git a/drivers/thermal/sun8i_ths.c b/drivers/thermal/sun8i_ths.c
|
|
index cfe7d1073b8c..2fda940da4cc 100644
|
|
--- a/drivers/thermal/sun8i_ths.c
|
|
+++ b/drivers/thermal/sun8i_ths.c
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
- * Thermal sensor driver for Allwinner H3 SoC
|
|
+ * Thermal sensor driver for Allwinner SUN8I SoC
|
|
*
|
|
* Copyright (C) 2016 Ondřej Jirman
|
|
* Based on the work of Josef Gajdusek <atx@atx.name>
|
|
@@ -26,79 +26,174 @@
|
|
#include <linux/thermal.h>
|
|
#include <linux/printk.h>
|
|
|
|
-#define THS_H3_CTRL0 0x00
|
|
-#define THS_H3_CTRL2 0x40
|
|
-#define THS_H3_INT_CTRL 0x44
|
|
-#define THS_H3_STAT 0x48
|
|
-#define THS_H3_FILTER 0x70
|
|
-#define THS_H3_CDATA 0x74
|
|
-#define THS_H3_DATA 0x80
|
|
-
|
|
-#define THS_H3_CTRL0_SENSOR_ACQ0(x) (x)
|
|
-#define THS_H3_CTRL2_SENSE_EN BIT(0)
|
|
-#define THS_H3_CTRL2_SENSOR_ACQ1(x) ((x) << 16)
|
|
-#define THS_H3_INT_CTRL_DATA_IRQ_EN BIT(8)
|
|
-#define THS_H3_INT_CTRL_THERMAL_PER(x) ((x) << 12)
|
|
-#define THS_H3_STAT_DATA_IRQ_STS BIT(8)
|
|
-#define THS_H3_FILTER_TYPE(x) ((x) << 0)
|
|
-#define THS_H3_FILTER_EN BIT(2)
|
|
-
|
|
-#define THS_H3_CLK_IN 40000000 /* Hz */
|
|
-#define THS_H3_DATA_PERIOD 330 /* ms */
|
|
-
|
|
-#define THS_H3_FILTER_TYPE_VALUE 2 /* average over 2^(n+1) samples */
|
|
-#define THS_H3_FILTER_DIV (1 << (THS_H3_FILTER_TYPE_VALUE + 1))
|
|
-#define THS_H3_INT_CTRL_THERMAL_PER_VALUE \
|
|
- (THS_H3_DATA_PERIOD * (THS_H3_CLK_IN / 1000) / THS_H3_FILTER_DIV / 4096 - 1)
|
|
-#define THS_H3_CTRL0_SENSOR_ACQ0_VALUE 0x3f /* 16us */
|
|
-#define THS_H3_CTRL2_SENSOR_ACQ1_VALUE 0x3f
|
|
+#define THS_SUN8I_CTRL0 0x00
|
|
+#define THS_SUN8I_CTRL2 0x40
|
|
+#define THS_SUN8I_INT_CTRL 0x44
|
|
+#define THS_SUN8I_STAT 0x48
|
|
+#define THS_SUN8I_FILTER 0x70
|
|
+#define THS_SUN8I_CDATA01 0x74
|
|
+#define THS_SUN8I_CDATA2 0x78
|
|
+#define THS_SUN8I_DATA0 0x80
|
|
+#define THS_SUN8I_DATA1 0x84
|
|
+#define THS_SUN8I_DATA2 0x88
|
|
+
|
|
+#define THS_SUN8I_CTRL0_SENSOR_ACQ0(x) (x)
|
|
+#define THS_SUN8I_CTRL2_SENSE_EN0 BIT(0)
|
|
+#define THS_SUN8I_CTRL2_SENSE_EN1 BIT(1)
|
|
+#define THS_SUN8I_CTRL2_SENSE_EN2 BIT(2)
|
|
+#define THS_SUN8I_CTRL2_SENSOR_ACQ1(x) ((x) << 16)
|
|
+#define THS_SUN8I_INT_CTRL_DATA0_IRQ_EN BIT(8)
|
|
+#define THS_SUN8I_INT_CTRL_DATA1_IRQ_EN BIT(9)
|
|
+#define THS_SUN8I_INT_CTRL_DATA2_IRQ_EN BIT(10)
|
|
+#define THS_SUN8I_INT_CTRL_THERMAL_PER(x) ((x) << 12)
|
|
+#define THS_SUN8I_STAT_DATA0_IRQ_STS BIT(8)
|
|
+#define THS_SUN8I_STAT_DATA1_IRQ_STS BIT(9)
|
|
+#define THS_SUN8I_STAT_DATA2_IRQ_STS BIT(10)
|
|
+#define THS_SUN8I_STAT_CLEAR 0x777
|
|
+#define THS_SUN8I_FILTER_TYPE(x) ((x) << 0)
|
|
+#define THS_SUN8I_FILTER_EN BIT(2)
|
|
+
|
|
+#define THS_SUN8I_CLK_IN 40000000 /* Hz */
|
|
+#define THS_SUN8I_DATA_PERIOD 330 /* ms */
|
|
+#define THS_SUN8I_FILTER_TYPE_VALUE 2 /* average over 2^(n+1) samples */
|
|
+
|
|
+//XXX: this formula doesn't work for A83T very well
|
|
+//XXX: A83T is getting slower readings out of this (1s interval?)
|
|
+//perhaps configure this in sun8i_ths_desc
|
|
+#define THS_SUN8I_FILTER_DIV (1 << (THS_SUN8I_FILTER_TYPE_VALUE + 1))
|
|
+#define THS_SUN8I_INT_CTRL_THERMAL_PER_VALUE \
|
|
+ (THS_SUN8I_DATA_PERIOD * (THS_SUN8I_CLK_IN / 1000) / \
|
|
+ THS_SUN8I_FILTER_DIV / 4096 - 1)
|
|
+
|
|
+#define THS_SUN8I_CTRL0_SENSOR_ACQ0_VALUE 0x3f /* 16us */
|
|
+#define THS_SUN8I_CTRL2_SENSOR_ACQ1_VALUE 0x3f
|
|
+
|
|
+#define SUN8I_THS_MAX_TZDS 3
|
|
+
|
|
+struct sun8i_ths_sensor_desc {
|
|
+ u32 data_int_en;
|
|
+ u32 data_int_flag;
|
|
+ u32 data_offset;
|
|
+ u32 sense_en;
|
|
+};
|
|
+
|
|
+struct sun8i_ths_desc {
|
|
+ int num_sensors;
|
|
+ struct sun8i_ths_sensor_desc *sensors;
|
|
+ int (*calc_temp)(u32 reg_val);
|
|
+ bool has_cal1;
|
|
+};
|
|
+
|
|
+struct sun8i_ths_tzd {
|
|
+ struct sun8i_ths_data *data;
|
|
+ struct thermal_zone_device *tzd;
|
|
+ u32 temp;
|
|
+};
|
|
|
|
struct sun8i_ths_data {
|
|
+ struct device *dev;
|
|
struct reset_control *reset;
|
|
struct clk *clk;
|
|
struct clk *busclk;
|
|
void __iomem *regs;
|
|
- struct thermal_zone_device *tzd;
|
|
- u32 temp;
|
|
+ void __iomem *cal_regs;
|
|
+ struct sun8i_ths_desc *desc;
|
|
+ struct sun8i_ths_tzd tzds[SUN8I_THS_MAX_TZDS];
|
|
};
|
|
|
|
+static int sun8i_ths_calc_temp_h3(u32 reg_val)
|
|
+{
|
|
+ uint64_t temp = (uint64_t)reg_val * 1000000ll;
|
|
+
|
|
+ do_div(temp, 8253);
|
|
+
|
|
+ return 217000 - (int)temp;
|
|
+}
|
|
+
|
|
+static int sun8i_ths_calc_temp_a83t(u32 reg_val)
|
|
+{
|
|
+ uint64_t temp = (uint64_t)reg_val * 1000000ll;
|
|
+
|
|
+ do_div(temp, 14186);
|
|
+
|
|
+ return 192000 - (int)temp;
|
|
+}
|
|
+
|
|
static int sun8i_ths_get_temp(void *_data, int *out)
|
|
{
|
|
- struct sun8i_ths_data *data = _data;
|
|
+ struct sun8i_ths_tzd *tzd = _data;
|
|
+ struct sun8i_ths_data *data = tzd->data;
|
|
|
|
- if (data->temp == 0)
|
|
+ if (tzd->temp == 0)
|
|
return -EBUSY;
|
|
|
|
- /* Formula and parameters from the Allwinner 3.4 kernel */
|
|
- *out = 217000 - (int)((data->temp * 1000000) / 8253);
|
|
+ *out = data->desc->calc_temp(tzd->temp);
|
|
return 0;
|
|
}
|
|
|
|
static irqreturn_t sun8i_ths_irq_thread(int irq, void *_data)
|
|
{
|
|
struct sun8i_ths_data *data = _data;
|
|
-
|
|
- writel(THS_H3_STAT_DATA_IRQ_STS, data->regs + THS_H3_STAT);
|
|
-
|
|
- data->temp = readl(data->regs + THS_H3_DATA);
|
|
- if (data->temp)
|
|
- thermal_zone_device_update(data->tzd, THERMAL_EVENT_TEMP_SAMPLE);
|
|
+ struct sun8i_ths_tzd *tzd;
|
|
+ struct sun8i_ths_sensor_desc *zdesc;
|
|
+ int i;
|
|
+ u32 status;
|
|
+
|
|
+ status = readl(data->regs + THS_SUN8I_STAT);
|
|
+ writel(THS_SUN8I_STAT_CLEAR, data->regs + THS_SUN8I_STAT);
|
|
+
|
|
+ for (i = 0; i < data->desc->num_sensors; i++) {
|
|
+ tzd = &data->tzds[i];
|
|
+ zdesc = &data->desc->sensors[i];
|
|
+
|
|
+ if (status & zdesc->data_int_flag) {
|
|
+ tzd->temp = readl(data->regs + zdesc->data_offset);
|
|
+ if (tzd->temp)
|
|
+ thermal_zone_device_update(tzd->tzd,
|
|
+ THERMAL_EVENT_TEMP_SAMPLE);
|
|
+ }
|
|
+ }
|
|
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
-static void sun8i_ths_h3_init(struct sun8i_ths_data *data)
|
|
+static void sun8i_ths_init(struct sun8i_ths_data *data)
|
|
{
|
|
- writel(THS_H3_CTRL0_SENSOR_ACQ0(THS_H3_CTRL0_SENSOR_ACQ0_VALUE),
|
|
- data->regs + THS_H3_CTRL0);
|
|
- writel(THS_H3_FILTER_EN | THS_H3_FILTER_TYPE(THS_H3_FILTER_TYPE_VALUE),
|
|
- data->regs + THS_H3_FILTER);
|
|
- writel(THS_H3_CTRL2_SENSOR_ACQ1(THS_H3_CTRL2_SENSOR_ACQ1_VALUE) |
|
|
- THS_H3_CTRL2_SENSE_EN,
|
|
- data->regs + THS_H3_CTRL2);
|
|
- writel(THS_H3_INT_CTRL_THERMAL_PER(THS_H3_INT_CTRL_THERMAL_PER_VALUE) |
|
|
- THS_H3_INT_CTRL_DATA_IRQ_EN,
|
|
- data->regs + THS_H3_INT_CTRL);
|
|
+ int i;
|
|
+ u32 int_ctrl = 0;
|
|
+ u32 ctrl2 = 0;
|
|
+
|
|
+ writel(THS_SUN8I_CTRL0_SENSOR_ACQ0(THS_SUN8I_CTRL0_SENSOR_ACQ0_VALUE),
|
|
+ data->regs + THS_SUN8I_CTRL0);
|
|
+ writel(THS_SUN8I_FILTER_EN | THS_SUN8I_FILTER_TYPE(THS_SUN8I_FILTER_TYPE_VALUE),
|
|
+ data->regs + THS_SUN8I_FILTER);
|
|
+
|
|
+ ctrl2 |= THS_SUN8I_CTRL2_SENSOR_ACQ1(THS_SUN8I_CTRL2_SENSOR_ACQ1_VALUE);
|
|
+ int_ctrl |= THS_SUN8I_INT_CTRL_THERMAL_PER(THS_SUN8I_INT_CTRL_THERMAL_PER_VALUE);
|
|
+
|
|
+ for (i = 0; i < data->desc->num_sensors; i++) {
|
|
+ ctrl2 |= data->desc->sensors[i].sense_en;
|
|
+ int_ctrl |= data->desc->sensors[i].data_int_en;
|
|
+ }
|
|
+
|
|
+ if (data->cal_regs) {
|
|
+ u32 cal0, cal1;
|
|
+
|
|
+ cal0 = readl(data->cal_regs);
|
|
+ if (cal0)
|
|
+ writel(cal0, data->regs + THS_SUN8I_CDATA01);
|
|
+
|
|
+ if (data->desc->has_cal1) {
|
|
+ cal1 = readl(data->cal_regs + 4);
|
|
+ if (cal1)
|
|
+ writel(cal1, data->regs + THS_SUN8I_CDATA2);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ writel(ctrl2, data->regs + THS_SUN8I_CTRL2);
|
|
+
|
|
+ /* enable interrupts */
|
|
+ writel(int_ctrl, data->regs + THS_SUN8I_INT_CTRL);
|
|
}
|
|
|
|
static const struct thermal_zone_of_device_ops sun8i_ths_thermal_ops = {
|
|
@@ -108,100 +203,135 @@ static const struct thermal_zone_of_device_ops sun8i_ths_thermal_ops = {
|
|
static int sun8i_ths_probe(struct platform_device *pdev)
|
|
{
|
|
struct sun8i_ths_data *data;
|
|
+ struct device *dev = &pdev->dev;
|
|
struct resource *res;
|
|
- int ret;
|
|
- int irq;
|
|
+ int ret, irq, i;
|
|
|
|
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
|
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
|
if (!data)
|
|
return -ENOMEM;
|
|
|
|
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
+ data->desc = (struct sun8i_ths_desc *)of_device_get_match_data(dev);
|
|
+ if (data->desc == NULL)
|
|
+ return -EINVAL;
|
|
+
|
|
+ data->dev = dev;
|
|
+ platform_set_drvdata(pdev, data);
|
|
+
|
|
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ths");
|
|
if (!res) {
|
|
- dev_err(&pdev->dev, "no memory resources defined\n");
|
|
+ dev_err(dev, "no memory resources defined\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
- data->regs = devm_ioremap_resource(&pdev->dev, res);
|
|
+ data->regs = devm_ioremap_resource(dev, res);
|
|
if (IS_ERR(data->regs)) {
|
|
ret = PTR_ERR(data->regs);
|
|
- dev_err(&pdev->dev, "failed to ioremap THS registers: %d\n", ret);
|
|
+ dev_err(dev, "failed to ioremap THS registers: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
+ /*XXX: use SRAM device in the future, instead of direct access to regs */
|
|
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "calibration");
|
|
+ if (res) {
|
|
+ data->cal_regs = devm_ioremap_resource(dev, res);
|
|
+ if (IS_ERR(data->cal_regs)) {
|
|
+ ret = PTR_ERR(data->cal_regs);
|
|
+ dev_err(dev, "failed to ioremap calibration SRAM: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+
|
|
irq = platform_get_irq(pdev, 0);
|
|
if (irq < 0) {
|
|
- dev_err(&pdev->dev, "failed to get IRQ: %d\n", irq);
|
|
+ dev_err(dev, "failed to get IRQ: %d\n", irq);
|
|
return irq;
|
|
}
|
|
|
|
- ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
|
+ ret = devm_request_threaded_irq(dev, irq, NULL,
|
|
sun8i_ths_irq_thread, IRQF_ONESHOT,
|
|
- dev_name(&pdev->dev), data);
|
|
+ dev_name(dev), data);
|
|
if (ret)
|
|
return ret;
|
|
|
|
- data->busclk = devm_clk_get(&pdev->dev, "ahb");
|
|
+ data->busclk = devm_clk_get(dev, "ahb");
|
|
if (IS_ERR(data->busclk)) {
|
|
ret = PTR_ERR(data->busclk);
|
|
- dev_err(&pdev->dev, "failed to get ahb clk: %d\n", ret);
|
|
- return ret;
|
|
+ if (ret != -ENOENT) {
|
|
+ dev_err(dev, "failed to get ahb clk: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ data->busclk = NULL;
|
|
}
|
|
|
|
- data->clk = devm_clk_get(&pdev->dev, "ths");
|
|
+ data->clk = devm_clk_get(dev, "ths");
|
|
if (IS_ERR(data->clk)) {
|
|
ret = PTR_ERR(data->clk);
|
|
- dev_err(&pdev->dev, "failed to get ths clk: %d\n", ret);
|
|
- return ret;
|
|
+ if (ret != -ENOENT) {
|
|
+ dev_err(dev, "failed to get ths clk: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ data->clk = NULL;
|
|
}
|
|
|
|
- data->reset = devm_reset_control_get(&pdev->dev, "ahb");
|
|
+ data->reset = devm_reset_control_get_optional(dev, "ahb");
|
|
if (IS_ERR(data->reset)) {
|
|
ret = PTR_ERR(data->reset);
|
|
- dev_err(&pdev->dev, "failed to get reset: %d\n", ret);
|
|
+ dev_err(dev, "failed to get reset: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = reset_control_deassert(data->reset);
|
|
if (ret) {
|
|
- dev_err(&pdev->dev, "reset deassert failed: %d\n", ret);
|
|
+ dev_err(dev, "reset deassert failed: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
- ret = clk_prepare_enable(data->busclk);
|
|
- if (ret) {
|
|
- dev_err(&pdev->dev, "failed to enable bus clk: %d\n", ret);
|
|
- goto err_assert_reset;
|
|
+ if (data->busclk) {
|
|
+ ret = clk_prepare_enable(data->busclk);
|
|
+ if (ret) {
|
|
+ dev_err(dev, "failed to enable bus clk: %d\n", ret);
|
|
+ goto err_assert_reset;
|
|
+ }
|
|
}
|
|
|
|
- ret = clk_prepare_enable(data->clk);
|
|
- if (ret) {
|
|
- dev_err(&pdev->dev, "failed to enable ths clk: %d\n", ret);
|
|
- goto err_disable_bus;
|
|
- }
|
|
+ if (data->clk) {
|
|
+ ret = clk_prepare_enable(data->clk);
|
|
+ if (ret) {
|
|
+ dev_err(dev, "failed to enable ths clk: %d\n", ret);
|
|
+ goto err_disable_bus;
|
|
+ }
|
|
|
|
- ret = clk_set_rate(data->clk, THS_H3_CLK_IN);
|
|
- if (ret)
|
|
- goto err_disable_ths;
|
|
-
|
|
- data->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, data,
|
|
- &sun8i_ths_thermal_ops);
|
|
- if (IS_ERR(data->tzd)) {
|
|
- ret = PTR_ERR(data->tzd);
|
|
- dev_err(&pdev->dev, "failed to register thermal zone: %d\n",
|
|
- ret);
|
|
- goto err_disable_ths;
|
|
+ ret = clk_set_rate(data->clk, THS_SUN8I_CLK_IN);
|
|
+ if (ret)
|
|
+ goto err_disable_ths;
|
|
}
|
|
|
|
- sun8i_ths_h3_init(data);
|
|
+ for (i = 0; i < data->desc->num_sensors; i++) {
|
|
+ data->tzds[i].data = data;
|
|
+ data->tzds[i].tzd =
|
|
+ devm_thermal_zone_of_sensor_register(dev, i,
|
|
+ &data->tzds[i],
|
|
+ &sun8i_ths_thermal_ops);
|
|
+ if (IS_ERR(data->tzds[i].tzd)) {
|
|
+ ret = PTR_ERR(data->tzds[i].tzd);
|
|
+ dev_err(dev,
|
|
+ "failed to register thermal zone: %d\n", ret);
|
|
+ goto err_disable_ths;
|
|
+ }
|
|
+ }
|
|
|
|
- platform_set_drvdata(pdev, data);
|
|
+ sun8i_ths_init(data);
|
|
return 0;
|
|
|
|
err_disable_ths:
|
|
- clk_disable_unprepare(data->clk);
|
|
+ if (data->clk)
|
|
+ clk_disable_unprepare(data->clk);
|
|
err_disable_bus:
|
|
- clk_disable_unprepare(data->busclk);
|
|
+ if (data->busclk)
|
|
+ clk_disable_unprepare(data->busclk);
|
|
err_assert_reset:
|
|
reset_control_assert(data->reset);
|
|
return ret;
|
|
@@ -212,13 +342,60 @@ static int sun8i_ths_remove(struct platform_device *pdev)
|
|
struct sun8i_ths_data *data = platform_get_drvdata(pdev);
|
|
|
|
reset_control_assert(data->reset);
|
|
- clk_disable_unprepare(data->clk);
|
|
- clk_disable_unprepare(data->busclk);
|
|
+ if (data->clk)
|
|
+ clk_disable_unprepare(data->clk);
|
|
+ if (data->busclk)
|
|
+ clk_disable_unprepare(data->busclk);
|
|
return 0;
|
|
}
|
|
|
|
+struct sun8i_ths_sensor_desc sun8i_ths_h3_sensors[] = {
|
|
+ {
|
|
+ .data_int_en = THS_SUN8I_INT_CTRL_DATA0_IRQ_EN,
|
|
+ .data_int_flag = THS_SUN8I_STAT_DATA0_IRQ_STS,
|
|
+ .data_offset = THS_SUN8I_DATA0,
|
|
+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN0,
|
|
+ },
|
|
+};
|
|
+
|
|
+struct sun8i_ths_sensor_desc sun8i_ths_a83t_sensors[] = {
|
|
+ {
|
|
+ .data_int_en = THS_SUN8I_INT_CTRL_DATA0_IRQ_EN,
|
|
+ .data_int_flag = THS_SUN8I_STAT_DATA0_IRQ_STS,
|
|
+ .data_offset = THS_SUN8I_DATA0,
|
|
+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN0,
|
|
+ },
|
|
+ {
|
|
+ .data_int_en = THS_SUN8I_INT_CTRL_DATA1_IRQ_EN,
|
|
+ .data_int_flag = THS_SUN8I_STAT_DATA1_IRQ_STS,
|
|
+ .data_offset = THS_SUN8I_DATA1,
|
|
+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN1,
|
|
+ },
|
|
+ {
|
|
+ .data_int_en = THS_SUN8I_INT_CTRL_DATA2_IRQ_EN,
|
|
+ .data_int_flag = THS_SUN8I_STAT_DATA2_IRQ_STS,
|
|
+ .data_offset = THS_SUN8I_DATA2,
|
|
+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN2,
|
|
+ },
|
|
+};
|
|
+
|
|
+static const struct sun8i_ths_desc sun8i_ths_h3_desc = {
|
|
+ .num_sensors = ARRAY_SIZE(sun8i_ths_h3_sensors),
|
|
+ .sensors = sun8i_ths_h3_sensors,
|
|
+ .calc_temp = sun8i_ths_calc_temp_h3,
|
|
+ .has_cal1 = false,
|
|
+};
|
|
+
|
|
+static const struct sun8i_ths_desc sun8i_ths_a83t_desc = {
|
|
+ .num_sensors = ARRAY_SIZE(sun8i_ths_a83t_sensors),
|
|
+ .sensors = sun8i_ths_a83t_sensors,
|
|
+ .calc_temp = sun8i_ths_calc_temp_a83t,
|
|
+ .has_cal1 = true,
|
|
+};
|
|
+
|
|
static const struct of_device_id sun8i_ths_id_table[] = {
|
|
- { .compatible = "allwinner,sun8i-h3-ths", },
|
|
+ { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_ths_h3_desc },
|
|
+ { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_ths_a83t_desc },
|
|
{ /* sentinel */ },
|
|
};
|
|
MODULE_DEVICE_TABLE(of, sun8i_ths_id_table);
|
|
@@ -235,5 +412,5 @@ static struct platform_driver sun8i_ths_driver = {
|
|
module_platform_driver(sun8i_ths_driver);
|
|
|
|
MODULE_AUTHOR("Ondřej Jirman <megous@megous.com>");
|
|
-MODULE_DESCRIPTION("Thermal sensor driver for Allwinner H3 SoC");
|
|
+MODULE_DESCRIPTION("Thermal sensor driver for Allwinner SUN8I SoCs");
|
|
MODULE_LICENSE("GPL v2");
|
|
--
|
|
2.20.1
|
|
|