Thermals: use sunxi's GP-ADC to read SoC temp
takes 21, 23, 24, 25 from "safe-needs-more-inspection" and 22 from "unresolved" to (re-) activate Sunxi's SoC temp sensor.
This commit is contained in:
parent
033c18581c
commit
87af831187
@ -0,0 +1,30 @@
|
||||
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
|
||||
index 81d4c39e414a..41769bc6a429 100644
|
||||
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
|
||||
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
|
||||
@@ -88,7 +88,7 @@ static const struct gpadc_data sun6i_gpadc_data = {
|
||||
static const struct gpadc_data sun8i_a33_gpadc_data = {
|
||||
.temp_offset = -1662,
|
||||
.temp_scale = 162,
|
||||
- .tp_mode_en = SUN8I_GPADC_CTRL1_CHOP_TEMP_EN,
|
||||
+ .tp_mode_en = SUN8I_A23_GPADC_CTRL1_CHOP_TEMP_EN,
|
||||
};
|
||||
|
||||
struct sun4i_gpadc_iio {
|
||||
diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h
|
||||
index 139872c2e0fe..d31d962bb7d8 100644
|
||||
--- a/include/linux/mfd/sun4i-gpadc.h
|
||||
+++ b/include/linux/mfd/sun4i-gpadc.h
|
||||
@@ -38,9 +38,9 @@
|
||||
#define SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(x) (GENMASK(3, 0) & BIT(x))
|
||||
#define SUN6I_GPADC_CTRL1_ADC_CHAN_MASK GENMASK(3, 0)
|
||||
|
||||
-/* TP_CTRL1 bits for sun8i SoCs */
|
||||
-#define SUN8I_GPADC_CTRL1_CHOP_TEMP_EN BIT(8)
|
||||
-#define SUN8I_GPADC_CTRL1_GPADC_CALI_EN BIT(7)
|
||||
+/* TP_CTRL1 bits for sun8i A23/A33 SoCs */
|
||||
+#define SUN8I_A23_GPADC_CTRL1_CHOP_TEMP_EN BIT(8)
|
||||
+#define SUN8I_A23_GPADC_CTRL1_GPADC_CALI_EN BIT(7)
|
||||
|
||||
#define SUN4I_GPADC_CTRL2 0x08
|
||||
|
||||
@ -0,0 +1,392 @@
|
||||
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
|
||||
index 75cb089..d7089b7 100644
|
||||
--- a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
|
||||
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
|
||||
@@ -22,6 +22,7 @@
|
||||
* shutdown for not being used.
|
||||
*/
|
||||
|
||||
+#include <linux/clk.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
@@ -31,6 +32,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
+#include <linux/reset.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
@@ -49,6 +51,8 @@ static unsigned int sun6i_gpadc_chan_select(unsigned int chan)
|
||||
return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
|
||||
}
|
||||
|
||||
+struct sun4i_gpadc_iio;
|
||||
+
|
||||
struct gpadc_data {
|
||||
int temp_offset;
|
||||
int temp_scale;
|
||||
@@ -56,39 +60,12 @@ struct gpadc_data {
|
||||
unsigned int tp_adc_select;
|
||||
unsigned int (*adc_chan_select)(unsigned int chan);
|
||||
unsigned int adc_chan_mask;
|
||||
-};
|
||||
-
|
||||
-static const struct gpadc_data sun4i_gpadc_data = {
|
||||
- .temp_offset = -1932,
|
||||
- .temp_scale = 133,
|
||||
- .tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
|
||||
- .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
|
||||
- .adc_chan_select = &sun4i_gpadc_chan_select,
|
||||
- .adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
|
||||
-};
|
||||
-
|
||||
-static const struct gpadc_data sun5i_gpadc_data = {
|
||||
- .temp_offset = -1447,
|
||||
- .temp_scale = 100,
|
||||
- .tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
|
||||
- .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
|
||||
- .adc_chan_select = &sun4i_gpadc_chan_select,
|
||||
- .adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
|
||||
-};
|
||||
-
|
||||
-static const struct gpadc_data sun6i_gpadc_data = {
|
||||
- .temp_offset = -1623,
|
||||
- .temp_scale = 167,
|
||||
- .tp_mode_en = SUN6I_GPADC_CTRL1_TP_MODE_EN,
|
||||
- .tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
|
||||
- .adc_chan_select = &sun6i_gpadc_chan_select,
|
||||
- .adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
|
||||
-};
|
||||
-
|
||||
-static const struct gpadc_data sun8i_a33_gpadc_data = {
|
||||
- .temp_offset = -1662,
|
||||
- .temp_scale = 162,
|
||||
- .tp_mode_en = SUN8I_A23_GPADC_CTRL1_CHOP_TEMP_EN,
|
||||
+ unsigned int temp_data;
|
||||
+ int (*sample_start)(struct sun4i_gpadc_iio *info);
|
||||
+ int (*sample_end)(struct sun4i_gpadc_iio *info);
|
||||
+ bool has_bus_clk;
|
||||
+ bool has_bus_rst;
|
||||
+ bool has_mod_clk;
|
||||
};
|
||||
|
||||
struct sun4i_gpadc_iio {
|
||||
@@ -103,6 +80,9 @@ struct sun4i_gpadc_iio {
|
||||
atomic_t ignore_temp_data_irq;
|
||||
const struct gpadc_data *data;
|
||||
bool no_irq;
|
||||
+ struct clk *ths_bus_clk;
|
||||
+ struct clk *mod_clk;
|
||||
+ struct reset_control *reset;
|
||||
/* prevents concurrent reads of temperature and ADC */
|
||||
struct mutex mutex;
|
||||
struct thermal_zone_device *tzd;
|
||||
@@ -277,7 +257,7 @@ static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
|
||||
if (info->no_irq) {
|
||||
pm_runtime_get_sync(indio_dev->dev.parent);
|
||||
|
||||
- regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val);
|
||||
+ regmap_read(info->regmap, info->data->temp_data, val);
|
||||
|
||||
pm_runtime_mark_last_busy(indio_dev->dev.parent);
|
||||
pm_runtime_put_autosuspend(indio_dev->dev.parent);
|
||||
@@ -385,10 +365,8 @@ out:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
-static int sun4i_gpadc_runtime_suspend(struct device *dev)
|
||||
+static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info)
|
||||
{
|
||||
- struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
|
||||
-
|
||||
/* Disable the ADC on IP */
|
||||
regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0);
|
||||
/* Disable temperature sensor on IP */
|
||||
@@ -397,10 +375,23 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int sun4i_gpadc_runtime_resume(struct device *dev)
|
||||
+static int sun8i_h3_gpadc_sample_end(struct sun4i_gpadc_iio *info)
|
||||
+{
|
||||
+ /* Disable temperature sensor */
|
||||
+ regmap_write(info->regmap, SUN8I_H3_GPADC_CTRL2, 0);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sun4i_gpadc_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
|
||||
|
||||
+ return info->data->sample_end(info);
|
||||
+}
|
||||
+
|
||||
+static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info)
|
||||
+{
|
||||
/* clkin = 6MHz */
|
||||
regmap_write(info->regmap, SUN4I_GPADC_CTRL0,
|
||||
SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) |
|
||||
@@ -418,6 +409,29 @@ static int sun4i_gpadc_runtime_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int sun8i_h3_gpadc_sample_start(struct sun4i_gpadc_iio *info)
|
||||
+{
|
||||
+ regmap_write(info->regmap, SUN8I_H3_GPADC_CTRL2,
|
||||
+ SUN8I_H3_GPADC_CTRL2_TEMP_SENSE_EN |
|
||||
+ SUN8I_H3_GPADC_CTRL2_T_ACQ1(31));
|
||||
+ regmap_write(info->regmap, SUN4I_GPADC_CTRL0,
|
||||
+ SUN4I_GPADC_CTRL0_T_ACQ(31));
|
||||
+ regmap_write(info->regmap, SUN8I_H3_GPADC_CTRL3,
|
||||
+ SUN4I_GPADC_CTRL3_FILTER_EN |
|
||||
+ SUN4I_GPADC_CTRL3_FILTER_TYPE(1));
|
||||
+ regmap_write(info->regmap, SUN8I_H3_GPADC_INTC,
|
||||
+ SUN8I_H3_GPADC_INTC_TEMP_PERIOD(800));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int sun4i_gpadc_runtime_resume(struct device *dev)
|
||||
+{
|
||||
+ struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
|
||||
+
|
||||
+ return info->data->sample_start(info);
|
||||
+}
|
||||
+
|
||||
static int sun4i_gpadc_get_temp(void *data, int *temp)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = data;
|
||||
@@ -492,11 +506,78 @@ static int sun4i_irq_init(struct platform_device *pdev, const char *name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const struct gpadc_data sun4i_gpadc_data = {
|
||||
+ .temp_offset = -1932,
|
||||
+ .temp_scale = 133,
|
||||
+ .tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
|
||||
+ .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
|
||||
+ .adc_chan_select = &sun4i_gpadc_chan_select,
|
||||
+ .adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
|
||||
+ .temp_data = SUN4I_GPADC_TEMP_DATA,
|
||||
+ .sample_start = sun4i_gpadc_sample_start,
|
||||
+ .sample_end = sun4i_gpadc_sample_end,
|
||||
+};
|
||||
+
|
||||
+static const struct gpadc_data sun5i_gpadc_data = {
|
||||
+ .temp_offset = -1447,
|
||||
+ .temp_scale = 100,
|
||||
+ .tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
|
||||
+ .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
|
||||
+ .adc_chan_select = &sun4i_gpadc_chan_select,
|
||||
+ .adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
|
||||
+ .temp_data = SUN4I_GPADC_TEMP_DATA,
|
||||
+ .sample_start = sun4i_gpadc_sample_start,
|
||||
+ .sample_end = sun4i_gpadc_sample_end,
|
||||
+};
|
||||
+
|
||||
+static const struct gpadc_data sun6i_gpadc_data = {
|
||||
+ .temp_offset = -1623,
|
||||
+ .temp_scale = 167,
|
||||
+ .tp_mode_en = SUN6I_GPADC_CTRL1_TP_MODE_EN,
|
||||
+ .tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
|
||||
+ .adc_chan_select = &sun6i_gpadc_chan_select,
|
||||
+ .adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
|
||||
+ .temp_data = SUN4I_GPADC_TEMP_DATA,
|
||||
+ .sample_start = sun4i_gpadc_sample_start,
|
||||
+ .sample_end = sun4i_gpadc_sample_end,
|
||||
+};
|
||||
+
|
||||
+static const struct gpadc_data sun8i_a33_gpadc_data = {
|
||||
+ .temp_offset = -1662,
|
||||
+ .temp_scale = 162,
|
||||
+ .tp_mode_en = SUN8I_A23_GPADC_CTRL1_CHOP_TEMP_EN,
|
||||
+ .temp_data = SUN4I_GPADC_TEMP_DATA,
|
||||
+ .sample_start = sun4i_gpadc_sample_start,
|
||||
+ .sample_end = sun4i_gpadc_sample_end,
|
||||
+};
|
||||
+
|
||||
+static const struct gpadc_data sun8i_h3_gpadc_data = {
|
||||
+ /*
|
||||
+ * The original formula on the datasheet seems to be wrong.
|
||||
+ * These factors are calculated based on the formula in the BSP
|
||||
+ * kernel, which is originally Tem = 217 - (T / 8.253), in which Tem
|
||||
+ * is the temperature in Celsius degree and T is the raw value
|
||||
+ * from the sensor.
|
||||
+ */
|
||||
+ .temp_offset = -1791,
|
||||
+ .temp_scale = -121,
|
||||
+ .temp_data = SUN8I_H3_GPADC_TEMP_DATA,
|
||||
+ .sample_start = sun8i_h3_gpadc_sample_start,
|
||||
+ .sample_end = sun8i_h3_gpadc_sample_end,
|
||||
+ .has_bus_clk = true,
|
||||
+ .has_bus_rst = true,
|
||||
+ .has_mod_clk = true,
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id sun4i_gpadc_of_id[] = {
|
||||
{
|
||||
.compatible = "allwinner,sun8i-a33-ths",
|
||||
.data = &sun8i_a33_gpadc_data,
|
||||
},
|
||||
+ {
|
||||
+ .compatible = "allwinner,sun8i-h3-ths",
|
||||
+ .data = &sun8i_h3_gpadc_data,
|
||||
+ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
@@ -529,10 +610,72 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ if (info->data->has_bus_rst) {
|
||||
+ info->reset = devm_reset_control_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(info->reset)) {
|
||||
+ ret = PTR_ERR(info->reset);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = reset_control_deassert(info->reset);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (info->data->has_bus_clk) {
|
||||
+ info->ths_bus_clk = devm_clk_get(&pdev->dev, "bus");
|
||||
+ if (IS_ERR(info->ths_bus_clk)) {
|
||||
+ ret = PTR_ERR(info->ths_bus_clk);
|
||||
+ goto assert_reset;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(info->ths_bus_clk);
|
||||
+ if (ret)
|
||||
+ goto assert_reset;
|
||||
+ }
|
||||
+
|
||||
+ if (info->data->has_mod_clk) {
|
||||
+ info->mod_clk = devm_clk_get(&pdev->dev, "mod");
|
||||
+ if (IS_ERR(info->mod_clk)) {
|
||||
+ ret = PTR_ERR(info->mod_clk);
|
||||
+ goto disable_bus_clk;
|
||||
+ }
|
||||
+
|
||||
+ /* Running at 6MHz */
|
||||
+ ret = clk_set_rate(info->mod_clk, 6000000);
|
||||
+ if (ret)
|
||||
+ goto disable_bus_clk;
|
||||
+
|
||||
+ ret = clk_prepare_enable(info->mod_clk);
|
||||
+ if (ret)
|
||||
+ goto disable_bus_clk;
|
||||
+ }
|
||||
+
|
||||
if (IS_ENABLED(CONFIG_THERMAL_OF))
|
||||
info->sensor_device = &pdev->dev;
|
||||
|
||||
+ if (IS_ERR(info->tzd)) {
|
||||
+ dev_err(&pdev->dev, "could not register thermal sensor: %ld\n",
|
||||
+ PTR_ERR(info->tzd));
|
||||
+ ret = PTR_ERR(info->tzd);
|
||||
+ goto disable_mod_clk;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
+
|
||||
+disable_mod_clk:
|
||||
+ if (info->data->has_mod_clk)
|
||||
+ clk_disable_unprepare(info->mod_clk);
|
||||
+
|
||||
+disable_bus_clk:
|
||||
+ if (info->data->has_bus_clk)
|
||||
+ clk_disable_unprepare(info->ths_bus_clk);
|
||||
+
|
||||
+assert_reset:
|
||||
+ if (info->data->has_bus_rst)
|
||||
+ reset_control_assert(info->reset);
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_probe_mfd(struct platform_device *pdev,
|
||||
@@ -698,6 +841,15 @@ static int sun4i_gpadc_remove(struct platform_device *pdev)
|
||||
if (!info->no_irq)
|
||||
iio_map_array_unregister(indio_dev);
|
||||
|
||||
+ if (info->data->has_mod_clk)
|
||||
+ clk_disable_unprepare(info->mod_clk);
|
||||
+
|
||||
+ if (info->data->has_bus_clk)
|
||||
+ clk_disable_unprepare(info->ths_bus_clk);
|
||||
+
|
||||
+ if (info->data->has_bus_rst)
|
||||
+ reset_control_assert(info->reset);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd2/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd2/sun4i-gpadc.h
|
||||
index d31d962..f794a29 100644
|
||||
--- a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd2/sun4i-gpadc.h
|
||||
+++ b/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd2/sun4i-gpadc.h
|
||||
@@ -42,6 +42,9 @@
|
||||
#define SUN8I_A23_GPADC_CTRL1_CHOP_TEMP_EN BIT(8)
|
||||
#define SUN8I_A23_GPADC_CTRL1_GPADC_CALI_EN BIT(7)
|
||||
|
||||
+/* TP_CTRL1 bits for SoCs after H3 */
|
||||
+#define SUN8I_H3_GPADC_CTRL1_GPADC_CALI_EN BIT(17)
|
||||
+
|
||||
#define SUN4I_GPADC_CTRL2 0x08
|
||||
|
||||
#define SUN4I_GPADC_CTRL2_TP_SENSITIVE_ADJUST(x) ((GENMASK(3, 0) & (x)) << 28)
|
||||
@@ -49,7 +52,17 @@
|
||||
#define SUN4I_GPADC_CTRL2_PRE_MEA_EN BIT(24)
|
||||
#define SUN4I_GPADC_CTRL2_PRE_MEA_THRE_CNT(x) (GENMASK(23, 0) & (x))
|
||||
|
||||
+#define SUN8I_H3_GPADC_CTRL2 0x40
|
||||
+
|
||||
+#define SUN8I_H3_GPADC_CTRL2_TEMP_SENSE_EN BIT(0)
|
||||
+#define SUN8I_H3_GPADC_CTRL2_T_ACQ1(x) ((GENMASK(15, 0) * (x)) << 16)
|
||||
+
|
||||
#define SUN4I_GPADC_CTRL3 0x0c
|
||||
+/*
|
||||
+ * This register is named "Average filter Control Register" in H3 Datasheet,
|
||||
+ * but the register's definition is the same as the old CTRL3 register.
|
||||
+ */
|
||||
+#define SUN8I_H3_GPADC_CTRL3 0x70
|
||||
|
||||
#define SUN4I_GPADC_CTRL3_FILTER_EN BIT(2)
|
||||
#define SUN4I_GPADC_CTRL3_FILTER_TYPE(x) (GENMASK(1, 0) & (x))
|
||||
@@ -71,6 +84,13 @@
|
||||
#define SUN4I_GPADC_INT_FIFOC_TP_UP_IRQ_EN BIT(1)
|
||||
#define SUN4I_GPADC_INT_FIFOC_TP_DOWN_IRQ_EN BIT(0)
|
||||
|
||||
+#define SUN8I_H3_GPADC_INTC 0x44
|
||||
+
|
||||
+#define SUN8I_H3_GPADC_INTC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12)
|
||||
+#define SUN8I_H3_GPADC_INTC_TEMP_DATA BIT(8)
|
||||
+#define SUN8I_H3_GPADC_INTC_TEMP_SHUT BIT(4)
|
||||
+#define SUN8I_H3_GPADC_INTC_TEMP_ALARM BIT(0)
|
||||
+
|
||||
#define SUN4I_GPADC_INT_FIFOS 0x14
|
||||
|
||||
#define SUN4I_GPADC_INT_FIFOS_TEMP_DATA_PENDING BIT(18)
|
||||
@@ -80,9 +100,16 @@
|
||||
#define SUN4I_GPADC_INT_FIFOS_TP_UP_PENDING BIT(1)
|
||||
#define SUN4I_GPADC_INT_FIFOS_TP_DOWN_PENDING BIT(0)
|
||||
|
||||
+#define SUN8I_H3_GPADC_INTS 0x44
|
||||
+
|
||||
+#define SUN8I_H3_GPADC_INTS_TEMP_DATA BIT(8)
|
||||
+#define SUN8I_H3_GPADC_INTS_TEMP_SHUT BIT(4)
|
||||
+#define SUN8I_H3_GPADC_INTS_TEMP_ALARM BIT(0)
|
||||
+
|
||||
#define SUN4I_GPADC_CDAT 0x1c
|
||||
#define SUN4I_GPADC_TEMP_DATA 0x20
|
||||
#define SUN4I_GPADC_DATA 0x24
|
||||
+#define SUN8I_H3_GPADC_TEMP_DATA 0x80
|
||||
|
||||
#define SUN4I_GPADC_IRQ_FIFO_DATA 0
|
||||
#define SUN4I_GPADC_IRQ_TEMP_DATA 1
|
||||
@ -0,0 +1,28 @@
|
||||
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
index a0cee17fe44b..efe3a8e4f2af 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
@@ -108,6 +108,23 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ iio-hwmon {
|
||||
+ compatible = "iio-hwmon";
|
||||
+ io-channels = <&ths>;
|
||||
+ };
|
||||
+
|
||||
+ soc {
|
||||
+ ths: thermal-sensor@1c25000 {
|
||||
+ compatible = "allwinner,sun8i-h3-ths";
|
||||
+ reg = <0x01c25000 0x100>;
|
||||
+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>;
|
||||
+ clock-names = "bus", "mod";
|
||||
+ resets = <&ccu RST_BUS_THS>;
|
||||
+ #thermal-sensor-cells = <0>;
|
||||
+ #io-channel-cells = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
timer {
|
||||
compatible = "arm,armv7-timer";
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
|
||||
@ -0,0 +1,93 @@
|
||||
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
index b36f9f423..0ad8e3e80 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
@@ -41,6 +41,7 @@
|
||||
*/
|
||||
|
||||
#include "sunxi-h3-h5.dtsi"
|
||||
+#include <dt-bindings/thermal/thermal.h>
|
||||
|
||||
/ {
|
||||
cpus {
|
||||
@@ -72,6 +73,80 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ thermal-zones {
|
||||
+ cpu-thermal {
|
||||
+ /* milliseconds */
|
||||
+ polling-delay-passive = <250>;
|
||||
+ polling-delay = <1000>;
|
||||
+ thermal-sensors = <&ths>;
|
||||
+
|
||||
+ trips {
|
||||
+ cpu_warm: cpu_warm {
|
||||
+ temperature = <65000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+
|
||||
+ cpu_hot_pre: cpu_hot_pre {
|
||||
+ temperature = <70000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+
|
||||
+ cpu_hot: cpu_hot {
|
||||
+ temperature = <75000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+
|
||||
+ cpu_very_hot_pre: cpu_very_hot_pre {
|
||||
+ temperature = <85000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+
|
||||
+ cpu_very_hot: cpu_very_hot {
|
||||
+ temperature = <90000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+
|
||||
+ cpu_crit: cpu_crit {
|
||||
+ temperature = <105000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cooling-maps {
|
||||
+ cpu_warm_limit_cpu {
|
||||
+ trip = <&cpu_warm>;
|
||||
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT 2>;
|
||||
+ };
|
||||
+
|
||||
+ cpu_hot_pre_limit_cpu {
|
||||
+ trip = <&cpu_hot_pre>;
|
||||
+ cooling-device = <&cpu0 2 3>;
|
||||
+ };
|
||||
+
|
||||
+ cpu_hot_limit_cpu {
|
||||
+ trip = <&cpu_hot>;
|
||||
+ cooling-device = <&cpu0 3 4>;
|
||||
+ };
|
||||
+
|
||||
+ cpu_very_hot_pre_limit_cpu {
|
||||
+ trip = <&cpu_very_hot>;
|
||||
+ cooling-device = <&cpu0 5 6>;
|
||||
+ };
|
||||
+
|
||||
+ cpu_very_hot_limit_cpu {
|
||||
+ trip = <&cpu_very_hot>;
|
||||
+ cooling-device = <&cpu0 7 THERMAL_NO_LIMIT>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
timer {
|
||||
compatible = "arm,armv7-timer";
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
|
||||
@ -0,0 +1,34 @@
|
||||
From e42ea77a5f2b389eed2c9004eab80bf6589ebf5a Mon Sep 17 00:00:00 2001
|
||||
From: Icenowy Zheng <icenowy@aosc.io>
|
||||
Date: Tue, 1 Aug 2017 23:42:12 +0800
|
||||
Subject: [PATCH] iio: adc: sun4i-gpadc: workaroud bogus THS raw value 0
|
||||
readout
|
||||
|
||||
When booting the system, the THS may read out a bogus false value which
|
||||
is raw value 0.
|
||||
|
||||
On H3 it represents a extremely high temperature and can shutdown the
|
||||
system immediately.
|
||||
|
||||
Workaround it by make it return -EINVAL when the raw value is 0 (which
|
||||
is unlikely to happen).
|
||||
|
||||
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
|
||||
---
|
||||
drivers/iio/adc/sun4i-gpadc-iio.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
|
||||
index f378ca0bc0b30..a89dcb6fba4ec 100644
|
||||
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
|
||||
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
|
||||
@@ -262,6 +262,9 @@ static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
|
||||
pm_runtime_mark_last_busy(indio_dev->dev.parent);
|
||||
pm_runtime_put_autosuspend(indio_dev->dev.parent);
|
||||
|
||||
+ if (!*val)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user