183 lines
6.4 KiB
Diff
183 lines
6.4 KiB
Diff
From 852e4474fc2d17b1fa2c085fb2b1100e7b7e65e0 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/158] 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
|
|
|