build/patch/kernel/archive/sunxi-6.2/patches.armbian/drv-iio-adc-sun4i-gpadc-iio-multible-sensors-support.patch

183 lines
6.4 KiB
Diff

From 34ac46e89ae9031cf99f998983c1889495de6eac Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Sun, 21 Jan 2018 22:26:50 +0100
Subject: [PATCH 016/153] drv:iio:adc:sun4i-gpadc-iio: multible sensors support
For adding newer sensor some basic rework of the code is necessary.
This patch reworks the driver to be able to handle more than one
thermal sensor. Newer SoC like the A80 have 4 thermal sensors.
Because of this the maximal sensor count value was set to 4.
The sensor_id value is set during sensor registration and is for each
registered sensor indiviual. This makes it able to differntiate the
sensors when the value is read from the register.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 33 +++++++++++++++++++++----------
include/linux/mfd/sun4i-gpadc.h | 6 ++++++
2 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index ec0e1ced5..e42b357e5 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -67,7 +67,7 @@ struct gpadc_data {
unsigned int tp_adc_select;
unsigned int (*adc_chan_select)(unsigned int chan);
unsigned int adc_chan_mask;
- unsigned int temp_data;
+ unsigned int temp_data[MAX_SENSOR_COUNT];
int (*sample_start)(struct sun4i_gpadc_iio *info);
int (*sample_end)(struct sun4i_gpadc_iio *info);
u32 ctrl0_map;
@@ -77,6 +77,7 @@ struct gpadc_data {
bool has_bus_clk;
bool has_bus_rst;
bool has_mod_clk;
+ int sensor_count;
};
static const struct gpadc_data sun4i_gpadc_data = {
@@ -86,9 +87,10 @@ static const struct gpadc_data sun4i_gpadc_data = {
.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,
+ .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+ .sensor_count = 1,
};
static const struct gpadc_data sun5i_gpadc_data = {
@@ -98,9 +100,10 @@ static const struct gpadc_data sun5i_gpadc_data = {
.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,
+ .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+ .sensor_count = 1,
};
static const struct gpadc_data sun6i_gpadc_data = {
@@ -110,18 +113,20 @@ static const struct gpadc_data sun6i_gpadc_data = {
.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,
+ .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+ .sensor_count = 1,
};
static const struct gpadc_data sun8i_a33_gpadc_data = {
.temp_offset = -1662,
.temp_scale = 162,
.tp_mode_en = SUN8I_A33_GPADC_CTRL1_CHOP_TEMP_EN,
- .temp_data = SUN4I_GPADC_TEMP_DATA,
+ .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+ .sensor_count = 1,
};
struct sun4i_gpadc_iio {
@@ -139,6 +144,7 @@ struct sun4i_gpadc_iio {
struct clk *bus_clk;
struct clk *mod_clk;
struct reset_control *reset;
+ int sensor_id;
/* prevents concurrent reads of temperature and ADC */
struct mutex mutex;
struct thermal_zone_device *tzd;
@@ -306,14 +312,15 @@ static int sun4i_gpadc_adc_read(struct iio_dev *indio_dev, int channel,
return sun4i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq);
}
-static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
+static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val,
+ int sensor)
{
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
if (info->no_irq) {
pm_runtime_get_sync(indio_dev->dev.parent);
- regmap_read(info->regmap, info->data->temp_data, val);
+ regmap_read(info->regmap, info->data->temp_data[sensor], val);
pm_runtime_mark_last_busy(indio_dev->dev.parent);
pm_runtime_put_autosuspend(indio_dev->dev.parent);
@@ -360,7 +367,7 @@ static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev,
ret = sun4i_gpadc_adc_read(indio_dev, chan->channel,
val);
else
- ret = sun4i_gpadc_temp_read(indio_dev, val);
+ ret = sun4i_gpadc_temp_read(indio_dev, val, 0);
if (ret)
return ret;
@@ -508,7 +515,7 @@ static int sun4i_gpadc_get_temp(struct thermal_zone_device *tz, int *temp)
struct sun4i_gpadc_iio *info = tz->devdata;
int val, scale, offset;
- if (sun4i_gpadc_temp_read(info->indio_dev, &val))
+ if (sun4i_gpadc_temp_read(info->indio_dev, &val, info->sensor_id))
return -ETIMEDOUT;
sun4i_gpadc_temp_scale(info->indio_dev, &scale);
@@ -748,7 +755,7 @@ static int sun4i_gpadc_probe(struct platform_device *pdev)
{
struct sun4i_gpadc_iio *info;
struct iio_dev *indio_dev;
- int ret;
+ int ret, i;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
if (!indio_dev)
@@ -783,6 +790,12 @@ static int sun4i_gpadc_probe(struct platform_device *pdev)
info->tzd = devm_thermal_of_zone_register(info->sensor_device,
0, info,
&sun4i_ts_tz_ops);
+ for (i = 0; i < info->data->sensor_count; i++) {
+ info->sensor_id = i;
+ info->tzd = devm_thermal_of_zone_register(
+ info->sensor_device,
+ i, info, &sun4i_ts_tz_ops);
+ }
/*
* Do not fail driver probing when failing to register in
* thermal because no thermal DT node is found.
diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h
index a7cd4c644..4b4415bf4 100644
--- a/include/linux/mfd/sun4i-gpadc.h
+++ b/include/linux/mfd/sun4i-gpadc.h
@@ -87,6 +87,10 @@
#define SUNXI_THS_CTRL0 0x00
#define SUNXI_THS_CTRL2 0x40
#define SUNXI_THS_FILTER 0x70
+#define SUNXI_THS_TDATA0 0x80
+#define SUNXI_THS_TDATA1 0x84
+#define SUNXI_THS_TDATA2 0x88
+#define SUNXI_THS_TDATA3 0x8c
#define SUNXI_THS_FILTER_EN BIT(2)
#define SUNXI_THS_FILTER_TYPE(x) (GENMASK(1, 0) & (x))
@@ -98,6 +102,8 @@
#define SUNXI_THS_TEMP_SENSE_EN2 BIT(2)
#define SUNXI_THS_TEMP_SENSE_EN3 BIT(3)
+#define MAX_SENSOR_COUNT 4
+
struct sun4i_gpadc_dev {
struct device *dev;
struct regmap *regmap;
--
2.35.3