summaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c133
-rw-r--r--drivers/iio/dac/ad7303.c4
-rw-r--r--drivers/iio/industrialio-trigger.c2
-rw-r--r--drivers/iio/inkern.c2
-rw-r--r--drivers/iio/pressure/st_pressure_core.c6
5 files changed, 110 insertions, 37 deletions
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index 5f9a7e7d3135..0ad208a69c29 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -22,13 +22,18 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/iio/iio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/iio/machine.h>
+#include <linux/iio/driver.h>
#include <linux/mfd/ti_am335x_tscadc.h>
-#include <linux/platform_data/ti_am335x_adc.h>
struct tiadc_device {
struct ti_tscadc_dev *mfd_tscadc;
int channels;
+ u8 channel_line[8];
+ u8 channel_step[8];
};
static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
@@ -42,10 +47,20 @@ static void tiadc_writel(struct tiadc_device *adc, unsigned int reg,
writel(val, adc->mfd_tscadc->tscadc_base + reg);
}
+static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
+{
+ u32 step_en;
+
+ step_en = ((1 << adc_dev->channels) - 1);
+ step_en <<= TOTAL_STEPS - adc_dev->channels + 1;
+ return step_en;
+}
+
static void tiadc_step_config(struct tiadc_device *adc_dev)
{
unsigned int stepconfig;
- int i, channels = 0, steps;
+ int i, steps;
+ u32 step_en;
/*
* There are 16 configurable steps and 8 analog input
@@ -58,43 +73,63 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
*/
steps = TOTAL_STEPS - adc_dev->channels;
- channels = TOTAL_CHANNELS - adc_dev->channels;
-
stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
- for (i = (steps + 1); i <= TOTAL_STEPS; i++) {
- tiadc_writel(adc_dev, REG_STEPCONFIG(i),
- stepconfig | STEPCONFIG_INP(channels));
- tiadc_writel(adc_dev, REG_STEPDELAY(i),
+ for (i = 0; i < adc_dev->channels; i++) {
+ int chan;
+
+ chan = adc_dev->channel_line[i];
+ tiadc_writel(adc_dev, REG_STEPCONFIG(steps),
+ stepconfig | STEPCONFIG_INP(chan));
+ tiadc_writel(adc_dev, REG_STEPDELAY(steps),
STEPCONFIG_OPENDLY);
- channels++;
+ adc_dev->channel_step[i] = steps;
+ steps++;
}
- tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB);
+ step_en = get_adc_step_mask(adc_dev);
+ am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
}
+static const char * const chan_name_ain[] = {
+ "AIN0",
+ "AIN1",
+ "AIN2",
+ "AIN3",
+ "AIN4",
+ "AIN5",
+ "AIN6",
+ "AIN7",
+};
+
static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
{
+ struct tiadc_device *adc_dev = iio_priv(indio_dev);
struct iio_chan_spec *chan_array;
+ struct iio_chan_spec *chan;
int i;
indio_dev->num_channels = channels;
- chan_array = kcalloc(indio_dev->num_channels,
+ chan_array = kcalloc(channels,
sizeof(struct iio_chan_spec), GFP_KERNEL);
-
if (chan_array == NULL)
return -ENOMEM;
- for (i = 0; i < (indio_dev->num_channels); i++) {
- struct iio_chan_spec *chan = chan_array + i;
+ chan = chan_array;
+ for (i = 0; i < channels; i++, chan++) {
+
chan->type = IIO_VOLTAGE;
chan->indexed = 1;
- chan->channel = i;
+ chan->channel = adc_dev->channel_line[i];
chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
+ chan->datasheet_name = chan_name_ain[chan->channel];
+ chan->scan_type.sign = 'u';
+ chan->scan_type.realbits = 12;
+ chan->scan_type.storagebits = 32;
}
indio_dev->channels = chan_array;
- return indio_dev->num_channels;
+ return 0;
}
static void tiadc_channels_remove(struct iio_dev *indio_dev)
@@ -108,7 +143,9 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
{
struct tiadc_device *adc_dev = iio_priv(indio_dev);
int i;
- unsigned int fifo1count, readx1;
+ unsigned int fifo1count, read;
+ u32 step = UINT_MAX;
+ bool found = false;
/*
* When the sub-system is first enabled,
@@ -121,32 +158,47 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
* Hence we need to flush out this data.
*/
+ for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
+ if (chan->channel == adc_dev->channel_line[i]) {
+ step = adc_dev->channel_step[i];
+ break;
+ }
+ }
+ if (WARN_ON_ONCE(step == UINT_MAX))
+ return -EINVAL;
+
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
for (i = 0; i < fifo1count; i++) {
- readx1 = tiadc_readl(adc_dev, REG_FIFO1);
- if (i == chan->channel)
- *val = readx1 & 0xfff;
+ read = tiadc_readl(adc_dev, REG_FIFO1);
+ if (read >> 16 == step) {
+ *val = read & 0xfff;
+ found = true;
+ }
}
- tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB);
-
+ am335x_tsc_se_update(adc_dev->mfd_tscadc);
+ if (found == false)
+ return -EBUSY;
return IIO_VAL_INT;
}
static const struct iio_info tiadc_info = {
.read_raw = &tiadc_read_raw,
+ .driver_module = THIS_MODULE,
};
static int tiadc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
struct tiadc_device *adc_dev;
- struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
- struct mfd_tscadc_board *pdata;
+ struct device_node *node = pdev->dev.of_node;
+ struct property *prop;
+ const __be32 *cur;
int err;
+ u32 val;
+ int channels = 0;
- pdata = tscadc_dev->dev->platform_data;
- if (!pdata || !pdata->adc_init) {
- dev_err(&pdev->dev, "Could not find platform data\n");
+ if (!node) {
+ dev_err(&pdev->dev, "Could not find valid DT data.\n");
return -EINVAL;
}
@@ -158,8 +210,13 @@ static int tiadc_probe(struct platform_device *pdev)
}
adc_dev = iio_priv(indio_dev);
- adc_dev->mfd_tscadc = tscadc_dev;
- adc_dev->channels = pdata->adc_init->adc_channels;
+ adc_dev->mfd_tscadc = ti_tscadc_dev_get(pdev);
+
+ of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
+ adc_dev->channel_line[channels] = val;
+ channels++;
+ }
+ adc_dev->channels = channels;
indio_dev->dev.parent = &pdev->dev;
indio_dev->name = dev_name(&pdev->dev);
@@ -191,10 +248,15 @@ err_ret:
static int tiadc_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct tiadc_device *adc_dev = iio_priv(indio_dev);
+ u32 step_en;
iio_device_unregister(indio_dev);
tiadc_channels_remove(indio_dev);
+ step_en = get_adc_step_mask(adc_dev);
+ am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en);
+
iio_device_free(indio_dev);
return 0;
@@ -205,9 +267,10 @@ static int tiadc_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct tiadc_device *adc_dev = iio_priv(indio_dev);
- struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
+ struct ti_tscadc_dev *tscadc_dev;
unsigned int idle;
+ tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
if (!device_may_wakeup(tscadc_dev->dev)) {
idle = tiadc_readl(adc_dev, REG_CTRL);
idle &= ~(CNTRLREG_TSCSSENB);
@@ -243,16 +306,22 @@ static const struct dev_pm_ops tiadc_pm_ops = {
#define TIADC_PM_OPS NULL
#endif
+static const struct of_device_id ti_adc_dt_ids[] = {
+ { .compatible = "ti,am3359-adc", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ti_adc_dt_ids);
+
static struct platform_driver tiadc_driver = {
.driver = {
- .name = "tiadc",
+ .name = "TI-am335x-adc",
.owner = THIS_MODULE,
.pm = TIADC_PM_OPS,
+ .of_match_table = of_match_ptr(ti_adc_dt_ids),
},
.probe = tiadc_probe,
.remove = tiadc_remove,
};
-
module_platform_driver(tiadc_driver);
MODULE_DESCRIPTION("TI ADC controller driver");
diff --git a/drivers/iio/dac/ad7303.c b/drivers/iio/dac/ad7303.c
index 85aeef60dc5f..d546f50f9258 100644
--- a/drivers/iio/dac/ad7303.c
+++ b/drivers/iio/dac/ad7303.c
@@ -235,8 +235,10 @@ static int ad7303_probe(struct spi_device *spi)
if (ext_ref) {
st->vref_reg = regulator_get(&spi->dev, "REF");
- if (IS_ERR(st->vref_reg))
+ if (IS_ERR(st->vref_reg)) {
+ ret = PTR_ERR(st->vref_reg);
goto err_disable_vdd_reg;
+ }
ret = regulator_enable(st->vref_reg);
if (ret)
diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c
index 4d6c7d84e155..ea8a4146620d 100644
--- a/drivers/iio/industrialio-trigger.c
+++ b/drivers/iio/industrialio-trigger.c
@@ -104,7 +104,7 @@ void iio_trigger_unregister(struct iio_trigger *trig_info)
ida_simple_remove(&iio_trigger_ida, trig_info->id);
/* Possible issue in here */
- device_unregister(&trig_info->dev);
+ device_del(&trig_info->dev);
}
EXPORT_SYMBOL(iio_trigger_unregister);
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 98ddc323add0..0cf5f8e06cfc 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -451,7 +451,7 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
int ret;
ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_OFFSET);
- if (ret == 0)
+ if (ret >= 0)
raw64 += offset;
scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index 9c343b40665e..3ffbc56917b4 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -28,7 +28,9 @@
#include <linux/iio/common/st_sensors.h>
#include "st_pressure.h"
-#define ST_PRESS_MBAR_TO_KPASCAL(x) (x * 10)
+#define ST_PRESS_LSB_PER_MBAR 4096UL
+#define ST_PRESS_KPASCAL_NANO_SCALE (100000000UL / \
+ ST_PRESS_LSB_PER_MBAR)
#define ST_PRESS_NUMBER_DATA_CHANNELS 1
/* DEFAULT VALUE FOR SENSORS */
@@ -51,8 +53,8 @@
#define ST_PRESS_1_FS_ADDR 0x23
#define ST_PRESS_1_FS_MASK 0x30
#define ST_PRESS_1_FS_AVL_1260_VAL 0x00
-#define ST_PRESS_1_FS_AVL_1260_GAIN ST_PRESS_MBAR_TO_KPASCAL(244141)
#define ST_PRESS_1_FS_AVL_TEMP_GAIN 2083000
+#define ST_PRESS_1_FS_AVL_1260_GAIN ST_PRESS_KPASCAL_NANO_SCALE
#define ST_PRESS_1_BDU_ADDR 0x20
#define ST_PRESS_1_BDU_MASK 0x04
#define ST_PRESS_1_DRDY_IRQ_ADDR 0x22