summaryrefslogtreecommitdiff
path: root/drivers/staging/iio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r--drivers/staging/iio/Documentation/iio_utils.h2
-rw-r--r--drivers/staging/iio/TODO11
-rw-r--r--drivers/staging/iio/accel/adis16220_core.c6
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_core.c66
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c14
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c66
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c19
-rw-r--r--drivers/staging/iio/adc/Kconfig8
-rw-r--r--drivers/staging/iio/adc/ad7192.c15
-rw-r--r--drivers/staging/iio/adc/ad7280a.c21
-rw-r--r--drivers/staging/iio/adc/ad7291.c246
-rw-r--r--drivers/staging/iio/adc/ad7606.h2
-rw-r--r--drivers/staging/iio/adc/ad7606_core.c35
-rw-r--r--drivers/staging/iio/adc/ad7606_ring.c8
-rw-r--r--drivers/staging/iio/adc/ad7780.c37
-rw-r--r--drivers/staging/iio/adc/ad7816.c59
-rw-r--r--drivers/staging/iio/adc/ad799x.h16
-rw-r--r--drivers/staging/iio/adc/ad799x_core.c297
-rw-r--r--drivers/staging/iio/adc/ad799x_ring.c10
-rw-r--r--drivers/staging/iio/adc/lpc32xx_adc.c51
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c998
-rw-r--r--drivers/staging/iio/adc/spear_adc.c12
-rw-r--r--drivers/staging/iio/addac/adt7316-i2c.c3
-rw-r--r--drivers/staging/iio/addac/adt7316-spi.c3
-rw-r--r--drivers/staging/iio/addac/adt7316.c86
-rw-r--r--drivers/staging/iio/cdc/ad7150.c165
-rw-r--r--drivers/staging/iio/cdc/ad7746.c13
-rw-r--r--drivers/staging/iio/frequency/ad5930.c16
-rw-r--r--drivers/staging/iio/frequency/ad9832.c36
-rw-r--r--drivers/staging/iio/frequency/ad9834.c33
-rw-r--r--drivers/staging/iio/frequency/ad9850.c16
-rw-r--r--drivers/staging/iio/frequency/ad9852.c62
-rw-r--r--drivers/staging/iio/frequency/ad9910.c98
-rw-r--r--drivers/staging/iio/frequency/ad9951.c43
-rw-r--r--drivers/staging/iio/iio_simple_dummy.c49
-rw-r--r--drivers/staging/iio/iio_simple_dummy.h22
-rw-r--r--drivers/staging/iio/iio_simple_dummy_buffer.c17
-rw-r--r--drivers/staging/iio/iio_simple_dummy_events.c49
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c44
-rw-r--r--drivers/staging/iio/light/isl29018.c18
-rw-r--r--drivers/staging/iio/light/tsl2583.c48
-rw-r--r--drivers/staging/iio/light/tsl2x7x_core.c168
-rw-r--r--drivers/staging/iio/magnetometer/Kconfig2
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843.c669
-rw-r--r--drivers/staging/iio/meter/ade7753.c34
-rw-r--r--drivers/staging/iio/meter/ade7754.c34
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c32
-rw-r--r--drivers/staging/iio/meter/ade7758_ring.c18
-rw-r--r--drivers/staging/iio/meter/ade7759.c33
-rw-r--r--drivers/staging/iio/meter/ade7854-i2c.c4
-rw-r--r--drivers/staging/iio/meter/ade7854-spi.c4
-rw-r--r--drivers/staging/iio/meter/ade7854.c22
-rw-r--r--drivers/staging/iio/resolver/ad2s1200.c28
-rw-r--r--drivers/staging/iio/resolver/ad2s1210.c34
-rw-r--r--drivers/staging/iio/resolver/ad2s90.c16
-rw-r--r--drivers/staging/iio/trigger/iio-trig-bfin-timer.c25
-rw-r--r--drivers/staging/iio/trigger/iio-trig-periodic-rtc.c4
57 files changed, 2015 insertions, 1932 deletions
diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h
index 35154d6..cf32ae0 100644
--- a/drivers/staging/iio/Documentation/iio_utils.h
+++ b/drivers/staging/iio/Documentation/iio_utils.h
@@ -502,7 +502,7 @@ inline int find_type_by_name(const char *name, const char *type)
inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify)
{
- int ret = 0;
+ int ret;
FILE *sysfsfp;
int test;
char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO
index c22a0ed..04c2326 100644
--- a/drivers/staging/iio/TODO
+++ b/drivers/staging/iio/TODO
@@ -13,17 +13,6 @@ Would be nice
3) Expand device set. Lots of other maxim adc's have very
similar interfaces.
-MXS LRADC driver:
-This is a classic MFD device as it combines the following subdevices
- - touchscreen controller (input subsystem related device)
- - general purpose ADC channels
- - battery voltage monitor (power subsystem related device)
- - die temperature monitor (thermal management)
-
-At least the battery voltage and die temperature feature is required in-kernel
-by a driver of the SoC's battery charging unit to avoid any damage to the
-silicon and the battery.
-
TSL2561
Would be nice
1) Open question of userspace vs kernel space balance when
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index 4c9364b..5c28961 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -102,6 +102,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
int addr)
{
struct adis16220_state *st = iio_priv(indio_dev);
+ struct spi_message msg;
struct spi_transfer xfers[] = {
{
.tx_buf = st->tx,
@@ -146,7 +147,10 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
}
xfers[1].len = count;
- ret = spi_sync_transfer(st->adis.spi, xfers, ARRAY_SIZE(xfers));
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfers[0], &msg);
+ spi_message_add_tail(&xfers[1], &msg);
+ ret = spi_sync(st->adis.spi, &msg);
if (ret) {
mutex_unlock(&st->buf_lock);
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 735c0a3..bb852dc 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -190,26 +190,15 @@ static u8 lis3l02dq_axis_map[3][3] = {
};
static int lis3l02dq_read_thresh(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int *val, int *val2)
+ u64 e,
+ int *val)
{
- int ret;
-
- ret = lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
- if (ret)
- return ret;
- return IIO_VAL_INT;
+ return lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
}
static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int val, int val2)
+ u64 event_code,
+ int val)
{
u16 value = val;
return lis3l02dq_spi_write_reg_s16(indio_dev,
@@ -514,19 +503,9 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
return IRQ_HANDLED;
}
-static const struct iio_event_spec lis3l02dq_event[] = {
- {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_RISING,
- .mask_separate = BIT(IIO_EV_INFO_ENABLE),
- .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
- }, {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_FALLING,
- .mask_separate = BIT(IIO_EV_INFO_ENABLE),
- .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
- }
-};
+#define LIS3L02DQ_EVENT_MASK \
+ (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
#define LIS3L02DQ_CHAN(index, mod) \
{ \
@@ -544,8 +523,7 @@ static const struct iio_event_spec lis3l02dq_event[] = {
.realbits = 12, \
.storagebits = 16, \
}, \
- .event_spec = lis3l02dq_event, \
- .num_event_specs = ARRAY_SIZE(lis3l02dq_event), \
+ .event_mask = LIS3L02DQ_EVENT_MASK, \
}
static const struct iio_chan_spec lis3l02dq_channels[] = {
@@ -557,14 +535,14 @@ static const struct iio_chan_spec lis3l02dq_channels[] = {
static int lis3l02dq_read_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir)
+ u64 event_code)
{
u8 val;
int ret;
- u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
+ u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
+ (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+ IIO_EV_DIR_RISING)));
ret = lis3l02dq_spi_read_reg_8(indio_dev,
LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
&val);
@@ -609,16 +587,16 @@ error_ret:
}
static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
+ u64 event_code,
int state)
{
int ret = 0;
u8 val, control;
u8 currentlyset;
bool changed = false;
- u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
+ u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
+ (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+ IIO_EV_DIR_RISING)));
mutex_lock(&indio_dev->mlock);
/* read current control */
@@ -676,10 +654,10 @@ static const struct attribute_group lis3l02dq_attribute_group = {
static const struct iio_info lis3l02dq_info = {
.read_raw = &lis3l02dq_read_raw,
.write_raw = &lis3l02dq_write_raw,
- .read_event_value_new = &lis3l02dq_read_thresh,
- .write_event_value_new = &lis3l02dq_write_thresh,
- .write_event_config_new = &lis3l02dq_write_event_config,
- .read_event_config_new = &lis3l02dq_read_event_config,
+ .read_event_value = &lis3l02dq_read_thresh,
+ .write_event_value = &lis3l02dq_write_thresh,
+ .write_event_config = &lis3l02dq_write_event_config,
+ .read_event_config = &lis3l02dq_read_event_config,
.driver_module = THIS_MODULE,
.attrs = &lis3l02dq_attribute_group,
};
@@ -716,7 +694,7 @@ static int lis3l02dq_probe(struct spi_device *spi)
lis3l02dq_channels,
ARRAY_SIZE(lis3l02dq_channels));
if (ret) {
- dev_err(&spi->dev, "failed to initialize the buffer\n");
+ printk(KERN_ERR "failed to initialize the buffer\n");
goto error_unreg_buffer_funcs;
}
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 79cefe0..5b8f0f6 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -111,7 +111,7 @@ static int lis3l02dq_get_buffer_element(struct iio_dev *indio_dev,
u8 *buf)
{
int ret, i;
- u8 *rx_array;
+ u8 *rx_array ;
s16 *data = (s16 *)buf;
int scan_count = bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength);
@@ -146,7 +146,11 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
len = lis3l02dq_get_buffer_element(indio_dev, data);
- iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
+ /* Guaranteed to be aligned with 8 byte boundary */
+ if (indio_dev->scan_timestamp)
+ *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
+ = pf->timestamp;
+ iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data);
done:
@@ -260,7 +264,8 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
else
break;
if (i == 5)
- pr_info("Failed to clear the interrupt for lis3l02dq\n");
+ printk(KERN_INFO
+ "Failed to clear the interrupt for lis3l02dq\n");
/* irq reenabled so success! */
return 0;
@@ -382,6 +387,7 @@ error_ret:
}
static const struct iio_buffer_setup_ops lis3l02dq_buffer_setup_ops = {
+ .preenable = &iio_sw_buffer_preenable,
.postenable = &lis3l02dq_buffer_postenable,
.predisable = &lis3l02dq_buffer_predisable,
};
@@ -395,7 +401,7 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
if (!buffer)
return -ENOMEM;
- iio_device_attach_buffer(indio_dev, buffer);
+ indio_dev->buffer = buffer;
buffer->scan_timestamp = true;
indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops;
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index c49e6ef..48a25ba 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -419,11 +419,8 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR,
static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0);
-static const struct iio_event_spec sca3000_event = {
- .type = IIO_EV_TYPE_MAG,
- .dir = IIO_EV_DIR_RISING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
-};
+#define SCA3000_EVENT_MASK \
+ (IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING))
#define SCA3000_CHAN(index, mod) \
{ \
@@ -440,8 +437,7 @@ static const struct iio_event_spec sca3000_event = {
.storagebits = 16, \
.shift = 5, \
}, \
- .event_spec = &sca3000_event, \
- .num_event_specs = 1, \
+ .event_mask = SCA3000_EVENT_MASK, \
}
static const struct iio_chan_spec sca3000_channels[] = {
@@ -628,9 +624,9 @@ static ssize_t sca3000_set_frequency(struct device *dev,
struct sca3000_state *st = iio_priv(indio_dev);
int ret, base_freq = 0;
int ctrlval;
- int val;
+ long val;
- ret = kstrtoint(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
return ret;
@@ -707,15 +703,12 @@ static IIO_CONST_ATTR_TEMP_OFFSET("-214.6");
* sca3000_read_thresh() - query of a threshold
**/
static int sca3000_read_thresh(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int *val, int *val2)
+ u64 e,
+ int *val)
{
int ret, i;
struct sca3000_state *st = iio_priv(indio_dev);
- int num = chan->channel2;
+ int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
mutex_lock(&st->lock);
ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]);
mutex_unlock(&st->lock);
@@ -731,21 +724,18 @@ static int sca3000_read_thresh(struct iio_dev *indio_dev,
ARRAY_SIZE(st->info->mot_det_mult_xz))
*val += st->info->mot_det_mult_xz[i];
- return IIO_VAL_INT;
+ return 0;
}
/**
* sca3000_write_thresh() control of threshold
**/
static int sca3000_write_thresh(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int val, int val2)
+ u64 e,
+ int val)
{
struct sca3000_state *st = iio_priv(indio_dev);
- int num = chan->channel2;
+ int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
int ret;
int i;
u8 nonlinear = 0;
@@ -876,14 +866,12 @@ done:
* sca3000_read_event_config() what events are enabled
**/
static int sca3000_read_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir)
+ u64 e)
{
struct sca3000_state *st = iio_priv(indio_dev);
int ret;
u8 protect_mask = 0x03;
- int num = chan->channel2;
+ int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
/* read current value of mode register */
mutex_lock(&st->lock);
@@ -943,12 +931,12 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct sca3000_state *st = iio_priv(indio_dev);
- u8 val;
+ long val;
int ret;
u8 protect_mask = SCA3000_FREE_FALL_DETECT;
mutex_lock(&st->lock);
- ret = kstrtou8(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
@@ -981,15 +969,13 @@ error_ret:
* this mode is disabled. Currently normal mode is assumed.
**/
static int sca3000_write_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
+ u64 e,
int state)
{
struct sca3000_state *st = iio_priv(indio_dev);
int ret, ctrlval;
u8 protect_mask = 0x03;
- int num = chan->channel2;
+ int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
mutex_lock(&st->lock);
/* First read the motion detector config to find out if
@@ -1126,20 +1112,20 @@ static const struct iio_info sca3000_info = {
.attrs = &sca3000_attribute_group,
.read_raw = &sca3000_read_raw,
.event_attrs = &sca3000_event_attribute_group,
- .read_event_value_new = &sca3000_read_thresh,
- .write_event_value_new = &sca3000_write_thresh,
- .read_event_config_new = &sca3000_read_event_config,
- .write_event_config_new = &sca3000_write_event_config,
+ .read_event_value = &sca3000_read_thresh,
+ .write_event_value = &sca3000_write_thresh,
+ .read_event_config = &sca3000_read_event_config,
+ .write_event_config = &sca3000_write_event_config,
.driver_module = THIS_MODULE,
};
static const struct iio_info sca3000_info_with_temp = {
.attrs = &sca3000_attribute_group_with_temp,
.read_raw = &sca3000_read_raw,
- .read_event_value_new = &sca3000_read_thresh,
- .write_event_value_new = &sca3000_write_thresh,
- .read_event_config_new = &sca3000_read_event_config,
- .write_event_config_new = &sca3000_write_event_config,
+ .read_event_value = &sca3000_read_thresh,
+ .write_event_value = &sca3000_write_thresh,
+ .read_event_config = &sca3000_read_event_config,
+ .write_event_config = &sca3000_write_event_config,
.driver_module = THIS_MODULE,
};
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index ea0af6d..3e5e860 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -177,11 +177,11 @@ static ssize_t sca3000_set_ring_int(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct sca3000_state *st = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- u8 val;
+ long val;
int ret;
mutex_lock(&st->lock);
- ret = kstrtou8(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
@@ -252,7 +252,7 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
struct iio_buffer *buf;
struct iio_hw_buffer *ring;
- ring = kzalloc(sizeof(*ring), GFP_KERNEL);
+ ring = kzalloc(sizeof *ring, GFP_KERNEL);
if (!ring)
return NULL;
@@ -265,7 +265,7 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
return buf;
}
-static void sca3000_ring_release(struct iio_buffer *r)
+static inline void sca3000_rb_free(struct iio_buffer *r)
{
kfree(iio_to_hw_buf(r));
}
@@ -274,28 +274,23 @@ static const struct iio_buffer_access_funcs sca3000_ring_access_funcs = {
.read_first_n = &sca3000_read_first_n_hw_rb,
.get_length = &sca3000_ring_get_length,
.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum,
- .release = sca3000_ring_release,
};
int sca3000_configure_ring(struct iio_dev *indio_dev)
{
- struct iio_buffer *buffer;
-
- buffer = sca3000_rb_allocate(indio_dev);
- if (buffer == NULL)
+ indio_dev->buffer = sca3000_rb_allocate(indio_dev);
+ if (indio_dev->buffer == NULL)
return -ENOMEM;
indio_dev->modes |= INDIO_BUFFER_HARDWARE;
indio_dev->buffer->access = &sca3000_ring_access_funcs;
- iio_device_attach_buffer(indio_dev, buffer);
-
return 0;
}
void sca3000_unconfigure_ring(struct iio_dev *indio_dev)
{
- iio_buffer_put(indio_dev->buffer);
+ sca3000_rb_free(indio_dev->buffer);
}
static inline
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index e3d6430..cabc7a3 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -102,7 +102,7 @@ config AD7280
config LPC32XX_ADC
tristate "NXP LPC32XX ADC"
- depends on ARCH_LPC32XX || COMPILE_TEST
+ depends on ARCH_LPC32XX
help
Say yes here to build support for the integrated ADC inside the
LPC32XX SoC. Note that this feature uses the same hardware as the
@@ -113,9 +113,7 @@ config LPC32XX_ADC
config MXS_LRADC
tristate "Freescale i.MX23/i.MX28 LRADC"
- depends on ARCH_MXS || COMPILE_TEST
- depends on INPUT
- select STMP_DEVICE
+ depends on ARCH_MXS
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
@@ -127,7 +125,7 @@ config MXS_LRADC
config SPEAR_ADC
tristate "ST SPEAr ADC"
- depends on PLAT_SPEAR || COMPILE_TEST
+ depends on PLAT_SPEAR
help
Say yes here to build support for the integrated ADC inside the
ST SPEAr SoC. Provides direct access via sysfs.
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 83bb44b..3283e28 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -623,17 +623,17 @@ static int ad7192_probe(struct spi_device *spi)
return -ENODEV;
}
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->reg = devm_regulator_get(&spi->dev, "vcc");
+ st->reg = regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- return ret;
+ goto error_put_reg;
voltage_uv = regulator_get_voltage(st->reg);
}
@@ -677,6 +677,11 @@ error_remove_trigger:
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
+error_put_reg:
+ if (!IS_ERR(st->reg))
+ regulator_put(st->reg);
+
+ iio_device_free(indio_dev);
return ret;
}
@@ -689,8 +694,10 @@ static int ad7192_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ad_sd_cleanup_buffer_and_trigger(indio_dev);
- if (!IS_ERR(st->reg))
+ if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
+ regulator_put(st->reg);
+ }
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c
index 8209fa5..c19618b 100644
--- a/drivers/staging/iio/adc/ad7280a.c
+++ b/drivers/staging/iio/adc/ad7280a.c
@@ -783,6 +783,7 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad7280_state *st = iio_priv(indio_dev);
+ unsigned int scale_uv;
int ret;
switch (m) {
@@ -803,12 +804,13 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
if ((chan->address & 0xFF) <= AD7280A_CELL_VOLTAGE_6)
- *val = 4000;
+ scale_uv = (4000 * 1000) >> AD7280A_BITS;
else
- *val = 5000;
+ scale_uv = (5000 * 1000) >> AD7280A_BITS;
- *val2 = AD7280A_BITS;
- return IIO_VAL_FRACTIONAL_LOG2;
+ *val = scale_uv / 1000;
+ *val2 = (scale_uv % 1000) * 1000;
+ return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
}
@@ -833,9 +835,8 @@ static int ad7280_probe(struct spi_device *spi)
int ret;
const unsigned short tACQ_ns[4] = {465, 1010, 1460, 1890};
const unsigned short nAVG[4] = {1, 2, 4, 8};
- struct iio_dev *indio_dev;
+ struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -859,7 +860,7 @@ static int ad7280_probe(struct spi_device *spi)
ret = ad7280_chain_setup(st);
if (ret < 0)
- return ret;
+ goto error_free_device;
st->slave_num = ret;
st->scan_cnt = (st->slave_num + 1) * AD7280A_NUM_CH;
@@ -890,7 +891,7 @@ static int ad7280_probe(struct spi_device *spi)
ret = ad7280_channel_init(st);
if (ret < 0)
- return ret;
+ goto error_free_device;
indio_dev->num_channels = ret;
indio_dev->channels = st->channels;
@@ -939,6 +940,9 @@ error_free_attr:
error_free_channels:
kfree(st->channels);
+error_free_device:
+ iio_device_free(indio_dev);
+
return ret;
}
@@ -956,6 +960,7 @@ static int ad7280_remove(struct spi_device *spi)
kfree(st->channels);
kfree(st->iio_attr);
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
index d13f8ae..a2e61c2 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -164,14 +164,97 @@ static irqreturn_t ad7291_event_handler(int irq, void *private)
return IRQ_HANDLED;
}
-static unsigned int ad7291_threshold_reg(const struct iio_chan_spec *chan,
- enum iio_event_direction dir, enum iio_event_info info)
+static inline ssize_t ad7291_show_hyst(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct ad7291_chip_info *chip = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ u16 data;
+ int ret;
+
+ ret = ad7291_i2c_read(chip, this_attr->address, &data);
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%d\n", data & AD7291_VALUE_MASK);
+}
+
+static inline ssize_t ad7291_set_hyst(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct ad7291_chip_info *chip = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ u16 data;
+ int ret;
+
+ ret = kstrtou16(buf, 10, &data);
+
+ if (ret < 0)
+ return ret;
+ if (data > AD7291_VALUE_MASK)
+ return -EINVAL;
+
+ ret = ad7291_i2c_write(chip, this_attr->address, data);
+ if (ret < 0)
+ return ret;
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(in_temp0_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad7291_show_hyst, ad7291_set_hyst,
+ AD7291_HYST(8));
+static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(0));
+static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(1));
+static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(2));
+static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(3));
+static IIO_DEVICE_ATTR(in_voltage4_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(4));
+static IIO_DEVICE_ATTR(in_voltage5_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(5));
+static IIO_DEVICE_ATTR(in_voltage6_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(6));
+static IIO_DEVICE_ATTR(in_voltage7_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(7));
+
+static struct attribute *ad7291_event_attributes[] = {
+ &iio_dev_attr_in_temp0_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage4_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage5_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage6_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage7_thresh_both_hyst_raw.dev_attr.attr,
+ NULL,
+};
+
+static unsigned int ad7291_threshold_reg(u64 event_code)
{
unsigned int offset;
- switch (chan->type) {
+ switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
case IIO_VOLTAGE:
- offset = chan->channel;
+ offset = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
break;
case IIO_TEMP:
offset = 8;
@@ -180,78 +263,69 @@ static unsigned int ad7291_threshold_reg(const struct iio_chan_spec *chan,
return 0;
}
- switch (info) {
- case IIO_EV_INFO_VALUE:
- if (dir == IIO_EV_DIR_FALLING)
- return AD7291_DATA_HIGH(offset);
- else
- return AD7291_DATA_LOW(offset);
- case IIO_EV_INFO_HYSTERESIS:
- return AD7291_HYST(offset);
- default:
- break;
- }
- return 0;
+ if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
+ return AD7291_DATA_LOW(offset);
+ else
+ return AD7291_DATA_HIGH(offset);
}
static int ad7291_read_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int *val, int *val2)
+ u64 event_code,
+ int *val)
{
struct ad7291_chip_info *chip = iio_priv(indio_dev);
int ret;
u16 uval;
- ret = ad7291_i2c_read(chip, ad7291_threshold_reg(chan, dir, info),
- &uval);
+ ret = ad7291_i2c_read(chip, ad7291_threshold_reg(event_code), &uval);
if (ret < 0)
return ret;
- if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE)
+ switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+ case IIO_VOLTAGE:
*val = uval & AD7291_VALUE_MASK;
-
- else
+ return 0;
+ case IIO_TEMP:
*val = sign_extend32(uval, 11);
-
- return IIO_VAL_INT;
+ return 0;
+ default:
+ return -EINVAL;
+ };
}
static int ad7291_write_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int val, int val2)
+ u64 event_code,
+ int val)
{
struct ad7291_chip_info *chip = iio_priv(indio_dev);
- if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE) {
+ switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+ case IIO_VOLTAGE:
if (val > AD7291_VALUE_MASK || val < 0)
return -EINVAL;
- } else {
+ break;
+ case IIO_TEMP:
if (val > 2047 || val < -2048)
return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
}
- return ad7291_i2c_write(chip, ad7291_threshold_reg(chan, dir, info),
- val);
+ return ad7291_i2c_write(chip, ad7291_threshold_reg(event_code), val);
}
static int ad7291_read_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir)
+ u64 event_code)
{
struct ad7291_chip_info *chip = iio_priv(indio_dev);
/* To be enabled the channel must simply be on. If any are enabled
we are in continuous sampling mode */
- switch (chan->type) {
+ switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
case IIO_VOLTAGE:
- if (chip->c_mask & (1 << (15 - chan->channel)))
+ if (chip->c_mask &
+ (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))
return 1;
else
return 0;
@@ -265,14 +339,11 @@ static int ad7291_read_event_config(struct iio_dev *indio_dev,
}
static int ad7291_write_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
+ u64 event_code,
int state)
{
int ret = 0;
struct ad7291_chip_info *chip = iio_priv(indio_dev);
- unsigned int mask;
u16 regval;
mutex_lock(&chip->state_lock);
@@ -283,14 +354,16 @@ static int ad7291_write_event_config(struct iio_dev *indio_dev,
* Possible to disable temp as well but that makes single read tricky.
*/
- mask = BIT(15 - chan->channel);
-
- switch (chan->type) {
+ switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
case IIO_VOLTAGE:
- if ((!state) && (chip->c_mask & mask))
- chip->c_mask &= ~mask;
- else if (state && (!(chip->c_mask & mask)))
- chip->c_mask |= mask;
+ if ((!state) && (chip->c_mask & (1 << (15 -
+ IIO_EVENT_CODE_EXTRACT_CHAN(event_code)))))
+ chip->c_mask &= ~(1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
+ (event_code)));
+ else if (state && (!(chip->c_mask & (1 << (15 -
+ IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))))
+ chip->c_mask |= (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
+ (event_code)));
else
break;
@@ -400,24 +473,6 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
}
}
-static const struct iio_event_spec ad7291_events[] = {
- {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_RISING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
- BIT(IIO_EV_INFO_ENABLE),
- }, {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_FALLING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
- BIT(IIO_EV_INFO_ENABLE),
- }, {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_EITHER,
- .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
- },
-};
-
#define AD7291_VOLTAGE_CHAN(_chan) \
{ \
.type = IIO_VOLTAGE, \
@@ -425,8 +480,8 @@ static const struct iio_event_spec ad7291_events[] = {
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.indexed = 1, \
.channel = _chan, \
- .event_spec = ad7291_events, \
- .num_event_specs = ARRAY_SIZE(ad7291_events), \
+ .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) \
}
static const struct iio_chan_spec ad7291_channels[] = {
@@ -445,17 +500,23 @@ static const struct iio_chan_spec ad7291_channels[] = {
BIT(IIO_CHAN_INFO_SCALE),
.indexed = 1,
.channel = 0,
- .event_spec = ad7291_events,
- .num_event_specs = ARRAY_SIZE(ad7291_events),
+ .event_mask =
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)
}
};
+static struct attribute_group ad7291_event_attribute_group = {
+ .attrs = ad7291_event_attributes,
+};
+
static const struct iio_info ad7291_info = {
.read_raw = &ad7291_read_raw,
- .read_event_config_new = &ad7291_read_event_config,
- .write_event_config_new = &ad7291_write_event_config,
- .read_event_value_new = &ad7291_read_event_value,
- .write_event_value_new = &ad7291_write_event_value,
+ .read_event_config = &ad7291_read_event_config,
+ .write_event_config = &ad7291_write_event_config,
+ .read_event_value = &ad7291_read_event_value,
+ .write_event_value = &ad7291_write_event_value,
+ .event_attrs = &ad7291_event_attribute_group,
.driver_module = THIS_MODULE,
};
@@ -467,19 +528,21 @@ static int ad7291_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
int ret = 0;
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
- if (!indio_dev)
- return -ENOMEM;
+ indio_dev = iio_device_alloc(sizeof(*chip));
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
chip = iio_priv(indio_dev);
if (pdata && pdata->use_external_ref) {
- chip->reg = devm_regulator_get(&client->dev, "vref");
+ chip->reg = regulator_get(&client->dev, "vref");
if (IS_ERR(chip->reg))
- return ret;
+ goto error_free;
ret = regulator_enable(chip->reg);
if (ret)
- return ret;
+ goto error_put_reg;
}
mutex_init(&chip->state_lock);
@@ -538,7 +601,12 @@ error_unreg_irq:
error_disable_reg:
if (chip->reg)
regulator_disable(chip->reg);
-
+error_put_reg:
+ if (chip->reg)
+ regulator_put(chip->reg);
+error_free:
+ iio_device_free(indio_dev);
+error_ret:
return ret;
}
@@ -552,8 +620,12 @@ static int ad7291_remove(struct i2c_client *client)
if (client->irq)
free_irq(client->irq, indio_dev);
- if (chip->reg)
+ if (chip->reg) {
regulator_disable(chip->reg);
+ regulator_put(chip->reg);
+ }
+
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h
index 93c7299..9221a74 100644
--- a/drivers/staging/iio/adc/ad7606.h
+++ b/drivers/staging/iio/adc/ad7606.h
@@ -42,7 +42,7 @@ struct ad7606_platform_data {
/**
* struct ad7606_chip_info - chip specifc information
- * @name: identification string for chip
+ * @name: indentification string for chip
* @int_vref_mv: the internal reference voltage
* @channels: channel specification
* @num_channels: number of channels
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index 2083673..72868ce 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -85,6 +85,7 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
{
int ret;
struct ad7606_state *st = iio_priv(indio_dev);
+ unsigned int scale_uv;
switch (m) {
case IIO_CHAN_INFO_RAW:
@@ -100,9 +101,11 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
*val = (short) ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = st->range * 2;
- *val2 = st->chip_info->channels[0].scan_type.realbits;
- return IIO_VAL_FRACTIONAL_LOG2;
+ scale_uv = (st->range * 1000 * 2)
+ >> st->chip_info->channels[0].scan_type.realbits;
+ *val = scale_uv / 1000;
+ *val2 = (scale_uv % 1000) * 1000;
+ return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
}
@@ -422,7 +425,8 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
struct ad7606_state *st = iio_priv(indio_dev);
if (iio_buffer_enabled(indio_dev)) {
- schedule_work(&st->poll_work);
+ if (!work_pending(&st->poll_work))
+ schedule_work(&st->poll_work);
} else {
st->done = true;
wake_up_interruptible(&st->wq_data_avail);
@@ -462,11 +466,12 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
struct ad7606_platform_data *pdata = dev->platform_data;
struct ad7606_state *st;
int ret;
- struct iio_dev *indio_dev;
+ struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
- indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
- if (!indio_dev)
- return ERR_PTR(-ENOMEM);
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
st = iio_priv(indio_dev);
@@ -484,11 +489,11 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
st->oversampling = pdata->default_os;
}
- st->reg = devm_regulator_get(dev, "vcc");
+ st->reg = regulator_get(dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- return ERR_PTR(ret);
+ goto error_put_reg;
}
st->pdata = pdata;
@@ -549,6 +554,11 @@ error_free_gpios:
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
+error_put_reg:
+ if (!IS_ERR(st->reg))
+ regulator_put(st->reg);
+ iio_device_free(indio_dev);
+error_ret:
return ERR_PTR(ret);
}
@@ -560,10 +570,13 @@ int ad7606_remove(struct iio_dev *indio_dev, int irq)
ad7606_ring_cleanup(indio_dev);
free_irq(irq, indio_dev);
- if (!IS_ERR(st->reg))
+ if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
+ regulator_put(st->reg);
+ }
ad7606_free_gpios(st);
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index 3bf174c..2b25cb0 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -46,6 +46,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
struct ad7606_state *st = container_of(work_s, struct ad7606_state,
poll_work);
struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ s64 time_ns;
__u8 *buf;
int ret;
@@ -77,7 +78,12 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
goto done;
}
- iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns());
+ time_ns = iio_get_time_ns();
+
+ if (indio_dev->scan_timestamp)
+ *((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns;
+
+ iio_push_to_buffers(indio_dev, buf);
done:
gpio_set_value(st->pdata->gpio_convst, 0);
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c
index 273add3..e1f8860 100644
--- a/drivers/staging/iio/adc/ad7780.c
+++ b/drivers/staging/iio/adc/ad7780.c
@@ -90,14 +90,17 @@ static int ad7780_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad7780_state *st = iio_priv(indio_dev);
+ unsigned long scale_uv;
switch (m) {
case IIO_CHAN_INFO_RAW:
return ad_sigma_delta_single_conversion(indio_dev, chan, val);
case IIO_CHAN_INFO_SCALE:
- *val = st->int_vref_mv * st->gain;
- *val2 = chan->scan_type.realbits - 1;
- return IIO_VAL_FRACTIONAL_LOG2;
+ scale_uv = (st->int_vref_mv * 100000 * st->gain)
+ >> (chan->scan_type.realbits - 1);
+ *val = scale_uv / 100000;
+ *val2 = (scale_uv % 100000) * 10;
+ return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_OFFSET:
*val -= (1 << (chan->scan_type.realbits - 1));
return IIO_VAL_INT;
@@ -168,7 +171,7 @@ static int ad7780_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
int ret, voltage_uv = 0;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -177,11 +180,11 @@ static int ad7780_probe(struct spi_device *spi)
ad_sd_init(&st->sd, indio_dev, spi, &ad7780_sigma_delta_info);
- st->reg = devm_regulator_get(&spi->dev, "vcc");
+ st->reg = regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- return ret;
+ goto error_put_reg;
voltage_uv = regulator_get_voltage(st->reg);
}
@@ -207,8 +210,8 @@ static int ad7780_probe(struct spi_device *spi)
if (pdata && gpio_is_valid(pdata->gpio_pdrst)) {
- ret = devm_gpio_request_one(&spi->dev, pdata->gpio_pdrst,
- GPIOF_OUT_INIT_LOW, "AD7780 /PDRST");
+ ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW,
+ "AD7780 /PDRST");
if (ret) {
dev_err(&spi->dev, "failed to request GPIO PDRST\n");
goto error_disable_reg;
@@ -220,7 +223,7 @@ static int ad7780_probe(struct spi_device *spi)
ret = ad_sd_setup_buffer_and_trigger(indio_dev);
if (ret)
- goto error_disable_reg;
+ goto error_free_gpio;
ret = iio_device_register(indio_dev);
if (ret)
@@ -230,9 +233,17 @@ static int ad7780_probe(struct spi_device *spi)
error_cleanup_buffer_and_trigger:
ad_sd_cleanup_buffer_and_trigger(indio_dev);
+error_free_gpio:
+ if (pdata && gpio_is_valid(pdata->gpio_pdrst))
+ gpio_free(pdata->gpio_pdrst);
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
+error_put_reg:
+ if (!IS_ERR(st->reg))
+ regulator_put(st->reg);
+
+ iio_device_free(indio_dev);
return ret;
}
@@ -245,8 +256,14 @@ static int ad7780_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ad_sd_cleanup_buffer_and_trigger(indio_dev);
- if (!IS_ERR(st->reg))
+ if (gpio_is_valid(st->powerdown_gpio))
+ gpio_free(st->powerdown_gpio);
+
+ if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
+ regulator_put(st->reg);
+ }
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index 9f48e5c..8470036 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -356,9 +356,11 @@ static int ad7816_probe(struct spi_device *spi_dev)
return -EINVAL;
}
- indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip));
- if (!indio_dev)
- return -ENOMEM;
+ indio_dev = iio_device_alloc(sizeof(*chip));
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
chip = iio_priv(indio_dev);
/* this is only used for device removal purposes */
dev_set_drvdata(&spi_dev->dev, indio_dev);
@@ -370,28 +372,25 @@ static int ad7816_probe(struct spi_device *spi_dev)
chip->convert_pin = pins[1];
chip->busy_pin = pins[2];
- ret = devm_gpio_request(&spi_dev->dev, chip->rdwr_pin,
- spi_get_device_id(spi_dev)->name);
+ ret = gpio_request(chip->rdwr_pin, spi_get_device_id(spi_dev)->name);
if (ret) {
dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n",
chip->rdwr_pin);
- return ret;
+ goto error_free_device;
}
gpio_direction_input(chip->rdwr_pin);
- ret = devm_gpio_request(&spi_dev->dev, chip->convert_pin,
- spi_get_device_id(spi_dev)->name);
+ ret = gpio_request(chip->convert_pin, spi_get_device_id(spi_dev)->name);
if (ret) {
dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n",
chip->convert_pin);
- return ret;
+ goto error_free_gpio_rdwr;
}
gpio_direction_input(chip->convert_pin);
- ret = devm_gpio_request(&spi_dev->dev, chip->busy_pin,
- spi_get_device_id(spi_dev)->name);
+ ret = gpio_request(chip->busy_pin, spi_get_device_id(spi_dev)->name);
if (ret) {
dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
chip->busy_pin);
- return ret;
+ goto error_free_gpio_convert;
}
gpio_direction_input(chip->busy_pin);
@@ -402,31 +401,51 @@ static int ad7816_probe(struct spi_device *spi_dev)
if (spi_dev->irq) {
/* Only low trigger is supported in ad7816/7/8 */
- ret = devm_request_threaded_irq(&spi_dev->dev, spi_dev->irq,
- NULL,
- &ad7816_event_handler,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- indio_dev->name,
- indio_dev);
+ ret = request_threaded_irq(spi_dev->irq,
+ NULL,
+ &ad7816_event_handler,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ indio_dev->name,
+ indio_dev);
if (ret)
- return ret;
+ goto error_free_gpio;
}
ret = iio_device_register(indio_dev);
if (ret)
- return ret;
+ goto error_free_irq;
dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
indio_dev->name);
return 0;
+error_free_irq:
+ free_irq(spi_dev->irq, indio_dev);
+error_free_gpio:
+ gpio_free(chip->busy_pin);
+error_free_gpio_convert:
+ gpio_free(chip->convert_pin);
+error_free_gpio_rdwr:
+ gpio_free(chip->rdwr_pin);
+error_free_device:
+ iio_device_free(indio_dev);
+error_ret:
+ return ret;
}
static int ad7816_remove(struct spi_device *spi_dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev);
+ struct ad7816_chip_info *chip = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
+ dev_set_drvdata(&spi_dev->dev, NULL);
+ if (spi_dev->irq)
+ free_irq(spi_dev->irq, indio_dev);
+ gpio_free(chip->busy_pin);
+ gpio_free(chip->convert_pin);
+ gpio_free(chip->rdwr_pin);
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h
index a591aa6..b51680c 100644
--- a/drivers/staging/iio/adc/ad799x.h
+++ b/drivers/staging/iio/adc/ad799x.h
@@ -36,10 +36,18 @@
#define AD7998_ALERT_STAT_REG 0x1
#define AD7998_CONF_REG 0x2
#define AD7998_CYCLE_TMR_REG 0x3
-
-#define AD7998_DATALOW_REG(x) ((x) * 3 + 0x4)
-#define AD7998_DATAHIGH_REG(x) ((x) * 3 + 0x5)
-#define AD7998_HYST_REG(x) ((x) * 3 + 0x6)
+#define AD7998_DATALOW_CH1_REG 0x4
+#define AD7998_DATAHIGH_CH1_REG 0x5
+#define AD7998_HYST_CH1_REG 0x6
+#define AD7998_DATALOW_CH2_REG 0x7
+#define AD7998_DATAHIGH_CH2_REG 0x8
+#define AD7998_HYST_CH2_REG 0x9
+#define AD7998_DATALOW_CH3_REG 0xA
+#define AD7998_DATAHIGH_CH3_REG 0xB
+#define AD7998_HYST_CH3_REG 0xC
+#define AD7998_DATALOW_CH4_REG 0xD
+#define AD7998_DATAHIGH_CH4_REG 0xE
+#define AD7998_HYST_CH4_REG 0xF
#define AD7998_CYC_MASK 0x7
#define AD7998_CYC_DIS 0x0
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index 9428be8..2b2049c 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -163,6 +163,7 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
{
int ret;
struct ad799x_state *st = iio_priv(indio_dev);
+ unsigned int scale_uv;
switch (m) {
case IIO_CHAN_INFO_RAW:
@@ -179,9 +180,10 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
RES_MASK(chan->scan_type.realbits);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = st->int_vref_mv;
- *val2 = chan->scan_type.realbits;
- return IIO_VAL_FRACTIONAL_LOG2;
+ scale_uv = (st->int_vref_mv * 1000) >> chan->scan_type.realbits;
+ *val = scale_uv / 1000;
+ *val2 = (scale_uv % 1000) * 1000;
+ return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
}
@@ -252,70 +254,98 @@ error_ret_mutex:
}
static int ad799x_read_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir)
+ u64 event_code)
{
return 1;
}
-static unsigned int ad799x_threshold_reg(const struct iio_chan_spec *chan,
- enum iio_event_direction dir,
- enum iio_event_info info)
-{
- switch (info) {
- case IIO_EV_INFO_VALUE:
- if (dir == IIO_EV_DIR_FALLING)
- return AD7998_DATALOW_REG(chan->channel);
- else
- return AD7998_DATAHIGH_REG(chan->channel);
- case IIO_EV_INFO_HYSTERESIS:
- return AD7998_HYST_REG(chan->channel);
- default:
- return -EINVAL;
- }
-
- return 0;
-}
+static const u8 ad799x_threshold_addresses[][2] = {
+ { AD7998_DATALOW_CH1_REG, AD7998_DATAHIGH_CH1_REG },
+ { AD7998_DATALOW_CH2_REG, AD7998_DATAHIGH_CH2_REG },
+ { AD7998_DATALOW_CH3_REG, AD7998_DATAHIGH_CH3_REG },
+ { AD7998_DATALOW_CH4_REG, AD7998_DATAHIGH_CH4_REG },
+};
static int ad799x_write_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int val, int val2)
+ u64 event_code,
+ int val)
{
int ret;
struct ad799x_state *st = iio_priv(indio_dev);
+ int direction = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+ IIO_EV_DIR_FALLING);
+ int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
mutex_lock(&indio_dev->mlock);
- ret = ad799x_i2c_write16(st, ad799x_threshold_reg(chan, dir, info),
- val);
+ ret = ad799x_i2c_write16(st,
+ ad799x_threshold_addresses[number][direction],
+ val);
mutex_unlock(&indio_dev->mlock);
return ret;
}
static int ad799x_read_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int *val, int *val2)
+ u64 event_code,
+ int *val)
{
int ret;
struct ad799x_state *st = iio_priv(indio_dev);
+ int direction = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+ IIO_EV_DIR_FALLING);
+ int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
u16 valin;
mutex_lock(&indio_dev->mlock);
- ret = ad799x_i2c_read16(st, ad799x_threshold_reg(chan, dir, info),
- &valin);
+ ret = ad799x_i2c_read16(st,
+ ad799x_threshold_addresses[number][direction],
+ &valin);
mutex_unlock(&indio_dev->mlock);
if (ret < 0)
return ret;
*val = valin;
- return IIO_VAL_INT;
+ return 0;
+}
+
+static ssize_t ad799x_read_channel_config(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct ad799x_state *st = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+ int ret;
+ u16 val;
+ ret = ad799x_i2c_read16(st, this_attr->address, &val);
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t ad799x_write_channel_config(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct ad799x_state *st = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+ long val;
+ int ret;
+
+ ret = kstrtol(buf, 10, &val);
+ if (ret)
+ return ret;
+
+ mutex_lock(&indio_dev->mlock);
+ ret = ad799x_i2c_write16(st, this_attr->address, val);
+ mutex_unlock(&indio_dev->mlock);
+
+ return ret ? ret : len;
}
static irqreturn_t ad799x_event_handler(int irq, void *private)
@@ -353,19 +383,60 @@ done:
return IRQ_HANDLED;
}
+static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad799x_read_channel_config,
+ ad799x_write_channel_config,
+ AD7998_HYST_CH1_REG);
+
+static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad799x_read_channel_config,
+ ad799x_write_channel_config,
+ AD7998_HYST_CH2_REG);
+
+static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad799x_read_channel_config,
+ ad799x_write_channel_config,
+ AD7998_HYST_CH3_REG);
+
+static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
+ S_IRUGO | S_IWUSR,
+ ad799x_read_channel_config,
+ ad799x_write_channel_config,
+ AD7998_HYST_CH4_REG);
+
static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
ad799x_read_frequency,
ad799x_write_frequency);
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("15625 7812 3906 1953 976 488 244 0");
-static struct attribute *ad799x_event_attributes[] = {
+static struct attribute *ad7993_4_7_8_event_attributes[] = {
+ &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_sampling_frequency.dev_attr.attr,
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ad7993_4_7_8_event_attrs_group = {
+ .attrs = ad7993_4_7_8_event_attributes,
+ .name = "events",
+};
+
+static struct attribute *ad7992_event_attributes[] = {
+ &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
+ &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
NULL,
};
-static struct attribute_group ad799x_event_attrs_group = {
- .attrs = ad799x_event_attributes,
+static struct attribute_group ad7992_event_attrs_group = {
+ .attrs = ad7992_event_attributes,
.name = "events",
};
@@ -374,35 +445,29 @@ static const struct iio_info ad7991_info = {
.driver_module = THIS_MODULE,
};
+static const struct iio_info ad7992_info = {
+ .read_raw = &ad799x_read_raw,
+ .event_attrs = &ad7992_event_attrs_group,
+ .read_event_config = &ad799x_read_event_config,
+ .read_event_value = &ad799x_read_event_value,
+ .write_event_value = &ad799x_write_event_value,
+ .driver_module = THIS_MODULE,
+};
+
static const struct iio_info ad7993_4_7_8_info = {
.read_raw = &ad799x_read_raw,
- .event_attrs = &ad799x_event_attrs_group,
- .read_event_config_new = &ad799x_read_event_config,
- .read_event_value_new = &ad799x_read_event_value,
- .write_event_value_new = &ad799x_write_event_value,
+ .event_attrs = &ad7993_4_7_8_event_attrs_group,
+ .read_event_config = &ad799x_read_event_config,
+ .read_event_value = &ad799x_read_event_value,
+ .write_event_value = &ad799x_write_event_value,
.driver_module = THIS_MODULE,
.update_scan_mode = ad7997_8_update_scan_mode,
};
-static const struct iio_event_spec ad799x_events[] = {
- {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_RISING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
- BIT(IIO_EV_INFO_ENABLE),
- }, {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_FALLING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE),
- BIT(IIO_EV_INFO_ENABLE),
- }, {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_EITHER,
- .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
- },
-};
+#define AD799X_EV_MASK (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
-#define _AD799X_CHANNEL(_index, _realbits, _ev_spec, _num_ev_spec) { \
+#define AD799X_CHANNEL(_index, _realbits, _evmask) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (_index), \
@@ -410,24 +475,16 @@ static const struct iio_event_spec ad799x_events[] = {
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.scan_index = (_index), \
.scan_type = IIO_ST('u', _realbits, 16, 12 - (_realbits)), \
- .event_spec = _ev_spec, \
- .num_event_specs = _num_ev_spec, \
+ .event_mask = (_evmask), \
}
-#define AD799X_CHANNEL(_index, _realbits) \
- _AD799X_CHANNEL(_index, _realbits, NULL, 0)
-
-#define AD799X_CHANNEL_WITH_EVENTS(_index, _realbits) \
- _AD799X_CHANNEL(_index, _realbits, ad799x_events, \
- ARRAY_SIZE(ad799x_events))
-
static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
[ad7991] = {
.channel = {
- AD799X_CHANNEL(0, 12),
- AD799X_CHANNEL(1, 12),
- AD799X_CHANNEL(2, 12),
- AD799X_CHANNEL(3, 12),
+ AD799X_CHANNEL(0, 12, 0),
+ AD799X_CHANNEL(1, 12, 0),
+ AD799X_CHANNEL(2, 12, 0),
+ AD799X_CHANNEL(3, 12, 0),
IIO_CHAN_SOFT_TIMESTAMP(4),
},
.num_channels = 5,
@@ -435,10 +492,10 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
},
[ad7995] = {
.channel = {
- AD799X_CHANNEL(0, 10),
- AD799X_CHANNEL(1, 10),
- AD799X_CHANNEL(2, 10),
- AD799X_CHANNEL(3, 10),
+ AD799X_CHANNEL(0, 10, 0),
+ AD799X_CHANNEL(1, 10, 0),
+ AD799X_CHANNEL(2, 10, 0),
+ AD799X_CHANNEL(3, 10, 0),
IIO_CHAN_SOFT_TIMESTAMP(4),
},
.num_channels = 5,
@@ -446,10 +503,10 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
},
[ad7999] = {
.channel = {
- AD799X_CHANNEL(0, 8),
- AD799X_CHANNEL(1, 8),
- AD799X_CHANNEL(2, 8),
- AD799X_CHANNEL(3, 8),
+ AD799X_CHANNEL(0, 8, 0),
+ AD799X_CHANNEL(1, 8, 0),
+ AD799X_CHANNEL(2, 8, 0),
+ AD799X_CHANNEL(3, 8, 0),
IIO_CHAN_SOFT_TIMESTAMP(4),
},
.num_channels = 5,
@@ -457,20 +514,20 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
},
[ad7992] = {
.channel = {
- AD799X_CHANNEL_WITH_EVENTS(0, 12),
- AD799X_CHANNEL_WITH_EVENTS(1, 12),
+ AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
+ AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
IIO_CHAN_SOFT_TIMESTAMP(3),
},
.num_channels = 3,
.default_config = AD7998_ALERT_EN,
- .info = &ad7993_4_7_8_info,
+ .info = &ad7992_info,
},
[ad7993] = {
.channel = {
- AD799X_CHANNEL_WITH_EVENTS(0, 10),
- AD799X_CHANNEL_WITH_EVENTS(1, 10),
- AD799X_CHANNEL_WITH_EVENTS(2, 10),
- AD799X_CHANNEL_WITH_EVENTS(3, 10),
+ AD799X_CHANNEL(0, 10, AD799X_EV_MASK),
+ AD799X_CHANNEL(1, 10, AD799X_EV_MASK),
+ AD799X_CHANNEL(2, 10, AD799X_EV_MASK),
+ AD799X_CHANNEL(3, 10, AD799X_EV_MASK),
IIO_CHAN_SOFT_TIMESTAMP(4),
},
.num_channels = 5,
@@ -479,10 +536,10 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
},
[ad7994] = {
.channel = {
- AD799X_CHANNEL_WITH_EVENTS(0, 12),
- AD799X_CHANNEL_WITH_EVENTS(1, 12),
- AD799X_CHANNEL_WITH_EVENTS(2, 12),
- AD799X_CHANNEL_WITH_EVENTS(3, 12),
+ AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
+ AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
+ AD799X_CHANNEL(2, 12, AD799X_EV_MASK),
+ AD799X_CHANNEL(3, 12, AD799X_EV_MASK),
IIO_CHAN_SOFT_TIMESTAMP(4),
},
.num_channels = 5,
@@ -491,14 +548,14 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
},
[ad7997] = {
.channel = {
- AD799X_CHANNEL_WITH_EVENTS(0, 10),
- AD799X_CHANNEL_WITH_EVENTS(1, 10),
- AD799X_CHANNEL_WITH_EVENTS(2, 10),
- AD799X_CHANNEL_WITH_EVENTS(3, 10),
- AD799X_CHANNEL(4, 10),
- AD799X_CHANNEL(5, 10),
- AD799X_CHANNEL(6, 10),
- AD799X_CHANNEL(7, 10),
+ AD799X_CHANNEL(0, 10, AD799X_EV_MASK),
+ AD799X_CHANNEL(1, 10, AD799X_EV_MASK),
+ AD799X_CHANNEL(2, 10, AD799X_EV_MASK),
+ AD799X_CHANNEL(3, 10, AD799X_EV_MASK),
+ AD799X_CHANNEL(4, 10, 0),
+ AD799X_CHANNEL(5, 10, 0),
+ AD799X_CHANNEL(6, 10, 0),
+ AD799X_CHANNEL(7, 10, 0),
IIO_CHAN_SOFT_TIMESTAMP(8),
},
.num_channels = 9,
@@ -507,14 +564,14 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
},
[ad7998] = {
.channel = {
- AD799X_CHANNEL_WITH_EVENTS(0, 12),
- AD799X_CHANNEL_WITH_EVENTS(1, 12),
- AD799X_CHANNEL_WITH_EVENTS(2, 12),
- AD799X_CHANNEL_WITH_EVENTS(3, 12),
- AD799X_CHANNEL(4, 12),
- AD799X_CHANNEL(5, 12),
- AD799X_CHANNEL(6, 12),
- AD799X_CHANNEL(7, 12),
+ AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
+ AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
+ AD799X_CHANNEL(2, 12, AD799X_EV_MASK),
+ AD799X_CHANNEL(3, 12, AD799X_EV_MASK),
+ AD799X_CHANNEL(4, 12, 0),
+ AD799X_CHANNEL(5, 12, 0),
+ AD799X_CHANNEL(6, 12, 0),
+ AD799X_CHANNEL(7, 12, 0),
IIO_CHAN_SOFT_TIMESTAMP(8),
},
.num_channels = 9,
@@ -529,9 +586,8 @@ static int ad799x_probe(struct i2c_client *client,
int ret;
struct ad799x_platform_data *pdata = client->dev.platform_data;
struct ad799x_state *st;
- struct iio_dev *indio_dev;
+ struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -550,11 +606,11 @@ static int ad799x_probe(struct i2c_client *client,
st->int_vref_mv = pdata->vref_mv;
- st->reg = devm_regulator_get(&client->dev, "vcc");
+ st->reg = regulator_get(&client->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- return ret;
+ goto error_put_reg;
}
st->client = client;
@@ -594,6 +650,10 @@ error_cleanup_ring:
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
+error_put_reg:
+ if (!IS_ERR(st->reg))
+ regulator_put(st->reg);
+ iio_device_free(indio_dev);
return ret;
}
@@ -608,9 +668,12 @@ static int ad799x_remove(struct i2c_client *client)
free_irq(client->irq, indio_dev);
ad799x_ring_cleanup(indio_dev);
- if (!IS_ERR(st->reg))
+ if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
+ regulator_put(st->reg);
+ }
kfree(st->rx_buf);
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index 0ff6c03..c2ebae1 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -35,6 +35,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad799x_state *st = iio_priv(indio_dev);
+ s64 time_ns;
int b_sent;
u8 cmd;
@@ -64,8 +65,13 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
if (b_sent < 0)
goto out;
- iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
- iio_get_time_ns());
+ time_ns = iio_get_time_ns();
+
+ if (indio_dev->scan_timestamp)
+ memcpy(st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
+ &time_ns, sizeof(time_ns));
+
+ iio_push_to_buffers(indio_dev, st->rx_buf);
out:
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c
index ef0a21d..9a4bb09 100644
--- a/drivers/staging/iio/adc/lpc32xx_adc.c
+++ b/drivers/staging/iio/adc/lpc32xx_adc.c
@@ -137,39 +137,43 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "failed to get platform I/O memory\n");
- return -EBUSY;
+ retval = -EBUSY;
+ goto errout1;
}
- iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
- if (!iodev)
- return -ENOMEM;
+ iodev = iio_device_alloc(sizeof(struct lpc32xx_adc_info));
+ if (!iodev) {
+ dev_err(&pdev->dev, "failed allocating iio device\n");
+ retval = -ENOMEM;
+ goto errout1;
+ }
info = iio_priv(iodev);
- info->adc_base = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
+ info->adc_base = ioremap(res->start, resource_size(res));
if (!info->adc_base) {
dev_err(&pdev->dev, "failed mapping memory\n");
- return -EBUSY;
+ retval = -EBUSY;
+ goto errout2;
}
- info->clk = devm_clk_get(&pdev->dev, NULL);
+ info->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(info->clk)) {
dev_err(&pdev->dev, "failed getting clock\n");
- return PTR_ERR(info->clk);
+ goto errout3;
}
irq = platform_get_irq(pdev, 0);
- if (irq <= 0) {
+ if ((irq < 0) || (irq >= NR_IRQS)) {
dev_err(&pdev->dev, "failed getting interrupt resource\n");
- return -EINVAL;
+ retval = -EINVAL;
+ goto errout4;
}
- retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
- MOD_NAME, info);
+ retval = request_irq(irq, lpc32xx_adc_isr, 0, MOD_NAME, info);
if (retval < 0) {
dev_err(&pdev->dev, "failed requesting interrupt\n");
- return retval;
+ goto errout4;
}
platform_set_drvdata(pdev, iodev);
@@ -185,18 +189,35 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
retval = iio_device_register(iodev);
if (retval)
- return retval;
+ goto errout5;
dev_info(&pdev->dev, "LPC32XX ADC driver loaded, IRQ %d\n", irq);
return 0;
+
+errout5:
+ free_irq(irq, info);
+errout4:
+ clk_put(info->clk);
+errout3:
+ iounmap(info->adc_base);
+errout2:
+ iio_device_free(iodev);
+errout1:
+ return retval;
}
static int lpc32xx_adc_remove(struct platform_device *pdev)
{
struct iio_dev *iodev = platform_get_drvdata(pdev);
+ struct lpc32xx_adc_info *info = iio_priv(iodev);
+ int irq = platform_get_irq(pdev, 0);
iio_device_unregister(iodev);
+ free_irq(irq, info);
+ clk_put(info->clk);
+ iounmap(info->adc_base);
+ iio_device_free(iodev);
return 0;
}
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index e2dd783..a08c173 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -35,7 +35,6 @@
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/input.h>
-#include <linux/clk.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
@@ -130,24 +129,11 @@ enum mxs_lradc_ts {
MXS_LRADC_TOUCHSCREEN_5WIRE,
};
-/*
- * Touchscreen handling
- */
-enum lradc_ts_plate {
- LRADC_TOUCH = 0,
- LRADC_SAMPLE_X,
- LRADC_SAMPLE_Y,
- LRADC_SAMPLE_PRESSURE,
- LRADC_SAMPLE_VALID,
-};
-
struct mxs_lradc {
struct device *dev;
void __iomem *base;
int irq[13];
- struct clk *clk;
-
uint32_t *buffer;
struct iio_trigger *trig;
@@ -183,63 +169,32 @@ struct mxs_lradc {
#define CHAN_MASK_TOUCHSCREEN_4WIRE (0xf << 2)
#define CHAN_MASK_TOUCHSCREEN_5WIRE (0x1f << 2)
enum mxs_lradc_ts use_touchscreen;
+ bool stop_touchscreen;
bool use_touchbutton;
struct input_dev *ts_input;
-
- enum mxs_lradc_id soc;
- enum lradc_ts_plate cur_plate; /* statemachine */
- bool ts_valid;
- unsigned ts_x_pos;
- unsigned ts_y_pos;
- unsigned ts_pressure;
-
- /* handle touchscreen's physical behaviour */
- /* samples per coordinate */
- unsigned over_sample_cnt;
- /* time clocks between samples */
- unsigned over_sample_delay;
- /* time in clocks to wait after the plates where switched */
- unsigned settling_delay;
+ struct work_struct ts_work;
};
#define LRADC_CTRL0 0x00
-# define LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE (1 << 23)
-# define LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE (1 << 22)
-# define LRADC_CTRL0_MX28_YNNSW /* YM */ (1 << 21)
-# define LRADC_CTRL0_MX28_YPNSW /* YP */ (1 << 20)
-# define LRADC_CTRL0_MX28_YPPSW /* YP */ (1 << 19)
-# define LRADC_CTRL0_MX28_XNNSW /* XM */ (1 << 18)
-# define LRADC_CTRL0_MX28_XNPSW /* XM */ (1 << 17)
-# define LRADC_CTRL0_MX28_XPPSW /* XP */ (1 << 16)
-
-# define LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE (1 << 20)
-# define LRADC_CTRL0_MX23_YM (1 << 19)
-# define LRADC_CTRL0_MX23_XM (1 << 18)
-# define LRADC_CTRL0_MX23_YP (1 << 17)
-# define LRADC_CTRL0_MX23_XP (1 << 16)
-
-# define LRADC_CTRL0_MX28_PLATE_MASK \
- (LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE | \
- LRADC_CTRL0_MX28_YNNSW | LRADC_CTRL0_MX28_YPNSW | \
- LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW | \
- LRADC_CTRL0_MX28_XNPSW | LRADC_CTRL0_MX28_XPPSW)
-
-# define LRADC_CTRL0_MX23_PLATE_MASK \
- (LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE | \
- LRADC_CTRL0_MX23_YM | LRADC_CTRL0_MX23_XM | \
- LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XP)
+#define LRADC_CTRL0_TOUCH_DETECT_ENABLE (1 << 23)
+#define LRADC_CTRL0_TOUCH_SCREEN_TYPE (1 << 22)
+#define LRADC_CTRL0_YNNSW /* YM */ (1 << 21)
+#define LRADC_CTRL0_YPNSW /* YP */ (1 << 20)
+#define LRADC_CTRL0_YPPSW /* YP */ (1 << 19)
+#define LRADC_CTRL0_XNNSW /* XM */ (1 << 18)
+#define LRADC_CTRL0_XNPSW /* XM */ (1 << 17)
+#define LRADC_CTRL0_XPPSW /* XP */ (1 << 16)
+#define LRADC_CTRL0_PLATE_MASK (0x3f << 16)
#define LRADC_CTRL1 0x10
#define LRADC_CTRL1_TOUCH_DETECT_IRQ_EN (1 << 24)
#define LRADC_CTRL1_LRADC_IRQ_EN(n) (1 << ((n) + 16))
-#define LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK (0x1fff << 16)
-#define LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK (0x01ff << 16)
+#define LRADC_CTRL1_LRADC_IRQ_EN_MASK (0x1fff << 16)
#define LRADC_CTRL1_LRADC_IRQ_EN_OFFSET 16
#define LRADC_CTRL1_TOUCH_DETECT_IRQ (1 << 8)
#define LRADC_CTRL1_LRADC_IRQ(n) (1 << (n))
-#define LRADC_CTRL1_MX28_LRADC_IRQ_MASK 0x1fff
-#define LRADC_CTRL1_MX23_LRADC_IRQ_MASK 0x01ff
+#define LRADC_CTRL1_LRADC_IRQ_MASK 0x1fff
#define LRADC_CTRL1_LRADC_IRQ_OFFSET 0
#define LRADC_CTRL2 0x20
@@ -252,33 +207,19 @@ struct mxs_lradc {
#define LRADC_CH_ACCUMULATE (1 << 29)
#define LRADC_CH_NUM_SAMPLES_MASK (0x1f << 24)
#define LRADC_CH_NUM_SAMPLES_OFFSET 24
-#define LRADC_CH_NUM_SAMPLES(x) \
- ((x) << LRADC_CH_NUM_SAMPLES_OFFSET)
#define LRADC_CH_VALUE_MASK 0x3ffff
#define LRADC_CH_VALUE_OFFSET 0
#define LRADC_DELAY(n) (0xd0 + (0x10 * (n)))
#define LRADC_DELAY_TRIGGER_LRADCS_MASK (0xff << 24)
#define LRADC_DELAY_TRIGGER_LRADCS_OFFSET 24
-#define LRADC_DELAY_TRIGGER(x) \
- (((x) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) & \
- LRADC_DELAY_TRIGGER_LRADCS_MASK)
#define LRADC_DELAY_KICK (1 << 20)
#define LRADC_DELAY_TRIGGER_DELAYS_MASK (0xf << 16)
#define LRADC_DELAY_TRIGGER_DELAYS_OFFSET 16
-#define LRADC_DELAY_TRIGGER_DELAYS(x) \
- (((x) << LRADC_DELAY_TRIGGER_DELAYS_OFFSET) & \
- LRADC_DELAY_TRIGGER_DELAYS_MASK)
#define LRADC_DELAY_LOOP_COUNT_MASK (0x1f << 11)
#define LRADC_DELAY_LOOP_COUNT_OFFSET 11
-#define LRADC_DELAY_LOOP(x) \
- (((x) << LRADC_DELAY_LOOP_COUNT_OFFSET) & \
- LRADC_DELAY_LOOP_COUNT_MASK)
#define LRADC_DELAY_DELAY_MASK 0x7ff
#define LRADC_DELAY_DELAY_OFFSET 0
-#define LRADC_DELAY_DELAY(x) \
- (((x) << LRADC_DELAY_DELAY_OFFSET) & \
- LRADC_DELAY_DELAY_MASK)
#define LRADC_CTRL4 0x140
#define LRADC_CTRL4_LRADCSELECT_MASK(n) (0xf << ((n) * 4))
@@ -287,475 +228,6 @@ struct mxs_lradc {
#define LRADC_RESOLUTION 12
#define LRADC_SINGLE_SAMPLE_MASK ((1 << LRADC_RESOLUTION) - 1)
-static void mxs_lradc_reg_set(struct mxs_lradc *lradc, u32 val, u32 reg)
-{
- writel(val, lradc->base + reg + STMP_OFFSET_REG_SET);
-}
-
-static void mxs_lradc_reg_clear(struct mxs_lradc *lradc, u32 val, u32 reg)
-{
- writel(val, lradc->base + reg + STMP_OFFSET_REG_CLR);
-}
-
-static void mxs_lradc_reg_wrt(struct mxs_lradc *lradc, u32 val, u32 reg)
-{
- writel(val, lradc->base + reg);
-}
-
-static u32 mxs_lradc_plate_mask(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL0_MX23_PLATE_MASK;
- else
- return LRADC_CTRL0_MX28_PLATE_MASK;
-}
-
-static u32 mxs_lradc_irq_en_mask(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK;
- else
- return LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK;
-}
-
-static u32 mxs_lradc_irq_mask(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL1_MX23_LRADC_IRQ_MASK;
- else
- return LRADC_CTRL1_MX28_LRADC_IRQ_MASK;
-}
-
-static u32 mxs_lradc_touch_detect_bit(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE;
- else
- return LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE;
-}
-
-static u32 mxs_lradc_drive_x_plate(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL0_MX23_XP | LRADC_CTRL0_MX23_XM;
- else
- return LRADC_CTRL0_MX28_XPPSW | LRADC_CTRL0_MX28_XNNSW;
-}
-
-static u32 mxs_lradc_drive_y_plate(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_YM;
- else
- return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_YNNSW;
-}
-
-static u32 mxs_lradc_drive_pressure(struct mxs_lradc *lradc)
-{
- if (lradc->soc == IMX23_LRADC)
- return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XM;
- else
- return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW;
-}
-
-static bool mxs_lradc_check_touch_event(struct mxs_lradc *lradc)
-{
- return !!(readl(lradc->base + LRADC_STATUS) &
- LRADC_STATUS_TOUCH_DETECT_RAW);
-}
-
-static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
-{
- /*
- * prepare for oversampling conversion
- *
- * from the datasheet:
- * "The ACCUMULATE bit in the appropriate channel register
- * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
- * otherwise, the IRQs will not fire."
- */
- mxs_lradc_reg_wrt(lradc, LRADC_CH_ACCUMULATE |
- LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1),
- LRADC_CH(ch));
-
- /* from the datasheet:
- * "Software must clear this register in preparation for a
- * multi-cycle accumulation.
- */
- mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch));
-
- /* prepare the delay/loop unit according to the oversampling count */
- mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch) |
- LRADC_DELAY_TRIGGER_DELAYS(0) |
- LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
- LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
- LRADC_DELAY(3));
-
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
- LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
- LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
-
- /* wake us again, when the complete conversion is done */
- mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch), LRADC_CTRL1);
- /*
- * after changing the touchscreen plates setting
- * the signals need some initial time to settle. Start the
- * SoC's delay unit and start the conversion later
- * and automatically.
- */
- mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
- LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */
- LRADC_DELAY_KICK |
- LRADC_DELAY_DELAY(lradc->settling_delay),
- LRADC_DELAY(2));
-}
-
-/*
- * Pressure detection is special:
- * We want to do both required measurements for the pressure detection in
- * one turn. Use the hardware features to chain both conversions and let the
- * hardware report one interrupt if both conversions are done
- */
-static void mxs_lradc_setup_ts_pressure(struct mxs_lradc *lradc, unsigned ch1,
- unsigned ch2)
-{
- u32 reg;
-
- /*
- * prepare for oversampling conversion
- *
- * from the datasheet:
- * "The ACCUMULATE bit in the appropriate channel register
- * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
- * otherwise, the IRQs will not fire."
- */
- reg = LRADC_CH_ACCUMULATE |
- LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1);
- mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch1));
- mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch2));
-
- /* from the datasheet:
- * "Software must clear this register in preparation for a
- * multi-cycle accumulation.
- */
- mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch1));
- mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch2));
-
- /* prepare the delay/loop unit according to the oversampling count */
- mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch1) |
- LRADC_DELAY_TRIGGER(1 << ch2) | /* start both channels */
- LRADC_DELAY_TRIGGER_DELAYS(0) |
- LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
- LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
- LRADC_DELAY(3));
-
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
- LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
- LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
-
- /* wake us again, when the conversions are done */
- mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch2), LRADC_CTRL1);
- /*
- * after changing the touchscreen plates setting
- * the signals need some initial time to settle. Start the
- * SoC's delay unit and start the conversion later
- * and automatically.
- */
- mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
- LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */
- LRADC_DELAY_KICK |
- LRADC_DELAY_DELAY(lradc->settling_delay), LRADC_DELAY(2));
-}
-
-static unsigned mxs_lradc_read_raw_channel(struct mxs_lradc *lradc,
- unsigned channel)
-{
- u32 reg;
- unsigned num_samples, val;
-
- reg = readl(lradc->base + LRADC_CH(channel));
- if (reg & LRADC_CH_ACCUMULATE)
- num_samples = lradc->over_sample_cnt;
- else
- num_samples = 1;
-
- val = (reg & LRADC_CH_VALUE_MASK) >> LRADC_CH_VALUE_OFFSET;
- return val / num_samples;
-}
-
-static unsigned mxs_lradc_read_ts_pressure(struct mxs_lradc *lradc,
- unsigned ch1, unsigned ch2)
-{
- u32 reg, mask;
- unsigned pressure, m1, m2;
-
- mask = LRADC_CTRL1_LRADC_IRQ(ch1) | LRADC_CTRL1_LRADC_IRQ(ch2);
- reg = readl(lradc->base + LRADC_CTRL1) & mask;
-
- while (reg != mask) {
- reg = readl(lradc->base + LRADC_CTRL1) & mask;
- dev_dbg(lradc->dev, "One channel is still busy: %X\n", reg);
- }
-
- m1 = mxs_lradc_read_raw_channel(lradc, ch1);
- m2 = mxs_lradc_read_raw_channel(lradc, ch2);
-
- if (m2 == 0) {
- dev_warn(lradc->dev, "Cannot calculate pressure\n");
- return 1 << (LRADC_RESOLUTION - 1);
- }
-
- /* simply scale the value from 0 ... max ADC resolution */
- pressure = m1;
- pressure *= (1 << LRADC_RESOLUTION);
- pressure /= m2;
-
- dev_dbg(lradc->dev, "Pressure = %u\n", pressure);
- return pressure;
-}
-
-#define TS_CH_XP 2
-#define TS_CH_YP 3
-#define TS_CH_XM 4
-#define TS_CH_YM 5
-
-static int mxs_lradc_read_ts_channel(struct mxs_lradc *lradc)
-{
- u32 reg;
- int val;
-
- reg = readl(lradc->base + LRADC_CTRL1);
-
- /* only channels 3 to 5 are of interest here */
- if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YP)) {
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YP) |
- LRADC_CTRL1_LRADC_IRQ(TS_CH_YP), LRADC_CTRL1);
- val = mxs_lradc_read_raw_channel(lradc, TS_CH_YP);
- } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_XM)) {
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_XM) |
- LRADC_CTRL1_LRADC_IRQ(TS_CH_XM), LRADC_CTRL1);
- val = mxs_lradc_read_raw_channel(lradc, TS_CH_XM);
- } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YM)) {
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YM) |
- LRADC_CTRL1_LRADC_IRQ(TS_CH_YM), LRADC_CTRL1);
- val = mxs_lradc_read_raw_channel(lradc, TS_CH_YM);
- } else {
- return -EIO;
- }
-
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
-
- return val;
-}
-
-/*
- * YP(open)--+-------------+
- * | |--+
- * | | |
- * YM(-)--+-------------+ |
- * +--------------+
- * | |
- * XP(weak+) XM(open)
- *
- * "weak+" means 200k Ohm VDDIO
- * (-) means GND
- */
-static void mxs_lradc_setup_touch_detection(struct mxs_lradc *lradc)
-{
- /*
- * In order to detect a touch event the 'touch detect enable' bit
- * enables:
- * - a weak pullup to the X+ connector
- * - a strong ground at the Y- connector
- */
- mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
- mxs_lradc_reg_set(lradc, mxs_lradc_touch_detect_bit(lradc),
- LRADC_CTRL0);
-}
-
-/*
- * YP(meas)--+-------------+
- * | |--+
- * | | |
- * YM(open)--+-------------+ |
- * +--------------+
- * | |
- * XP(+) XM(-)
- *
- * (+) means here 1.85 V
- * (-) means here GND
- */
-static void mxs_lradc_prepare_x_pos(struct mxs_lradc *lradc)
-{
- mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
- mxs_lradc_reg_set(lradc, mxs_lradc_drive_x_plate(lradc), LRADC_CTRL0);
-
- lradc->cur_plate = LRADC_SAMPLE_X;
- mxs_lradc_setup_ts_channel(lradc, TS_CH_YP);
-}
-
-/*
- * YP(+)--+-------------+
- * | |--+
- * | | |
- * YM(-)--+-------------+ |
- * +--------------+
- * | |
- * XP(open) XM(meas)
- *
- * (+) means here 1.85 V
- * (-) means here GND
- */
-static void mxs_lradc_prepare_y_pos(struct mxs_lradc *lradc)
-{
- mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
- mxs_lradc_reg_set(lradc, mxs_lradc_drive_y_plate(lradc), LRADC_CTRL0);
-
- lradc->cur_plate = LRADC_SAMPLE_Y;
- mxs_lradc_setup_ts_channel(lradc, TS_CH_XM);
-}
-
-/*
- * YP(+)--+-------------+
- * | |--+
- * | | |
- * YM(meas)--+-------------+ |
- * +--------------+
- * | |
- * XP(meas) XM(-)
- *
- * (+) means here 1.85 V
- * (-) means here GND
- */
-static void mxs_lradc_prepare_pressure(struct mxs_lradc *lradc)
-{
- mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
- mxs_lradc_reg_set(lradc, mxs_lradc_drive_pressure(lradc), LRADC_CTRL0);
-
- lradc->cur_plate = LRADC_SAMPLE_PRESSURE;
- mxs_lradc_setup_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
-}
-
-static void mxs_lradc_enable_touch_detection(struct mxs_lradc *lradc)
-{
- mxs_lradc_setup_touch_detection(lradc);
-
- lradc->cur_plate = LRADC_TOUCH;
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ |
- LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
- mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
-}
-
-static void mxs_lradc_report_ts_event(struct mxs_lradc *lradc)
-{
- input_report_abs(lradc->ts_input, ABS_X, lradc->ts_x_pos);
- input_report_abs(lradc->ts_input, ABS_Y, lradc->ts_y_pos);
- input_report_abs(lradc->ts_input, ABS_PRESSURE, lradc->ts_pressure);
- input_report_key(lradc->ts_input, BTN_TOUCH, 1);
- input_sync(lradc->ts_input);
-}
-
-static void mxs_lradc_complete_touch_event(struct mxs_lradc *lradc)
-{
- mxs_lradc_setup_touch_detection(lradc);
- lradc->cur_plate = LRADC_SAMPLE_VALID;
- /*
- * start a dummy conversion to burn time to settle the signals
- * note: we are not interested in the conversion's value
- */
- mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(5));
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
- mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(5), LRADC_CTRL1);
- mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << 5) |
- LRADC_DELAY_KICK | LRADC_DELAY_DELAY(10), /* waste 5 ms */
- LRADC_DELAY(2));
-}
-
-/*
- * in order to avoid false measurements, report only samples where
- * the surface is still touched after the position measurement
- */
-static void mxs_lradc_finish_touch_event(struct mxs_lradc *lradc, bool valid)
-{
- /* if it is still touched, report the sample */
- if (valid && mxs_lradc_check_touch_event(lradc)) {
- lradc->ts_valid = true;
- mxs_lradc_report_ts_event(lradc);
- }
-
- /* if it is even still touched, continue with the next measurement */
- if (mxs_lradc_check_touch_event(lradc)) {
- mxs_lradc_prepare_y_pos(lradc);
- return;
- }
-
- if (lradc->ts_valid) {
- /* signal the release */
- lradc->ts_valid = false;
- input_report_key(lradc->ts_input, BTN_TOUCH, 0);
- input_sync(lradc->ts_input);
- }
-
- /* if it is released, wait for the next touch via IRQ */
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1);
- mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
-}
-
-/* touchscreen's state machine */
-static void mxs_lradc_handle_touch(struct mxs_lradc *lradc)
-{
- int val;
-
- switch (lradc->cur_plate) {
- case LRADC_TOUCH:
- /*
- * start with the Y-pos, because it uses nearly the same plate
- * settings like the touch detection
- */
- if (mxs_lradc_check_touch_event(lradc)) {
- mxs_lradc_reg_clear(lradc,
- LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
- LRADC_CTRL1);
- mxs_lradc_prepare_y_pos(lradc);
- }
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ,
- LRADC_CTRL1);
- return;
-
- case LRADC_SAMPLE_Y:
- val = mxs_lradc_read_ts_channel(lradc);
- if (val < 0) {
- mxs_lradc_enable_touch_detection(lradc); /* re-start */
- return;
- }
- lradc->ts_y_pos = val;
- mxs_lradc_prepare_x_pos(lradc);
- return;
-
- case LRADC_SAMPLE_X:
- val = mxs_lradc_read_ts_channel(lradc);
- if (val < 0) {
- mxs_lradc_enable_touch_detection(lradc); /* re-start */
- return;
- }
- lradc->ts_x_pos = val;
- mxs_lradc_prepare_pressure(lradc);
- return;
-
- case LRADC_SAMPLE_PRESSURE:
- lradc->ts_pressure =
- mxs_lradc_read_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
- mxs_lradc_complete_touch_event(lradc);
- return;
-
- case LRADC_SAMPLE_VALID:
- val = mxs_lradc_read_ts_channel(lradc); /* ignore the value */
- mxs_lradc_finish_touch_event(lradc, 1);
- break;
- }
-}
-
/*
* Raw I/O operations
*/
@@ -783,27 +255,28 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
if (!ret)
return -EBUSY;
- reinit_completion(&lradc->completion);
+ INIT_COMPLETION(lradc->completion);
/*
* No buffered operation in progress, map the channel and trigger it.
* Virtual channel 0 is always used here as the others are always not
* used if doing raw sampling.
*/
- if (lradc->soc == IMX28_LRADC)
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
- LRADC_CTRL1);
- mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
+ writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
/* Clean the slot's previous content, then set new one. */
- mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(0), LRADC_CTRL4);
- mxs_lradc_reg_set(lradc, chan->channel, LRADC_CTRL4);
+ writel(LRADC_CTRL4_LRADCSELECT_MASK(0),
+ lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
+ writel(chan->channel, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
- mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(0));
+ writel(0, lradc->base + LRADC_CH(0));
/* Enable the IRQ and start sampling the channel. */
- mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
- mxs_lradc_reg_set(lradc, 1 << 0, LRADC_CTRL0);
+ writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
+ writel(1 << 0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
/* Wait for completion on the channel, 1 second max. */
ret = wait_for_completion_killable_timeout(&lradc->completion, HZ);
@@ -817,7 +290,8 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
ret = IIO_VAL_INT;
err:
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
+ writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
mutex_unlock(&lradc->lock);
@@ -829,33 +303,220 @@ static const struct iio_info mxs_lradc_iio_info = {
.read_raw = mxs_lradc_read_raw,
};
-static int mxs_lradc_ts_open(struct input_dev *dev)
+/*
+ * Touchscreen handling
+ */
+enum lradc_ts_plate {
+ LRADC_SAMPLE_X,
+ LRADC_SAMPLE_Y,
+ LRADC_SAMPLE_PRESSURE,
+};
+
+static int mxs_lradc_ts_touched(struct mxs_lradc *lradc)
{
- struct mxs_lradc *lradc = input_get_drvdata(dev);
+ uint32_t reg;
- /* Enable the touch-detect circuitry. */
- mxs_lradc_enable_touch_detection(lradc);
+ /* Enable touch detection. */
+ writel(LRADC_CTRL0_PLATE_MASK,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+ writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
- return 0;
+ msleep(LRADC_TS_SAMPLE_DELAY_MS);
+
+ reg = readl(lradc->base + LRADC_STATUS);
+
+ return reg & LRADC_STATUS_TOUCH_DETECT_RAW;
}
-static void mxs_lradc_disable_ts(struct mxs_lradc *lradc)
+static int32_t mxs_lradc_ts_sample(struct mxs_lradc *lradc,
+ enum lradc_ts_plate plate, int change)
{
- /* stop all interrupts from firing */
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
- LRADC_CTRL1_LRADC_IRQ_EN(2) | LRADC_CTRL1_LRADC_IRQ_EN(3) |
- LRADC_CTRL1_LRADC_IRQ_EN(4) | LRADC_CTRL1_LRADC_IRQ_EN(5),
- LRADC_CTRL1);
+ unsigned long delay, jiff;
+ uint32_t reg, ctrl0 = 0, chan = 0;
+ /* The touchscreen always uses CTRL4 slot #7. */
+ const uint8_t slot = 7;
+ uint32_t val;
- /* Power-down touchscreen touch-detect circuitry. */
- mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+ /*
+ * There are three correct configurations of the controller sampling
+ * the touchscreen, each of these configuration provides different
+ * information from the touchscreen.
+ *
+ * The following table describes the sampling configurations:
+ * +-------------+-------+-------+-------+
+ * | Wire \ Axis | X | Y | Z |
+ * +---------------------+-------+-------+
+ * | X+ (CH2) | HI | TS | TS |
+ * +-------------+-------+-------+-------+
+ * | X- (CH4) | LO | SH | HI |
+ * +-------------+-------+-------+-------+
+ * | Y+ (CH3) | SH | HI | HI |
+ * +-------------+-------+-------+-------+
+ * | Y- (CH5) | TS | LO | SH |
+ * +-------------+-------+-------+-------+
+ *
+ * HI ... strong '1' ; LO ... strong '0'
+ * SH ... sample here ; TS ... tri-state
+ *
+ * There are a few other ways of obtaining the Z coordinate
+ * (aka. pressure), but the one in the table seems to be the
+ * most reliable one.
+ */
+ switch (plate) {
+ case LRADC_SAMPLE_X:
+ ctrl0 = LRADC_CTRL0_XPPSW | LRADC_CTRL0_XNNSW;
+ chan = 3;
+ break;
+ case LRADC_SAMPLE_Y:
+ ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_YNNSW;
+ chan = 4;
+ break;
+ case LRADC_SAMPLE_PRESSURE:
+ ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_XNNSW;
+ chan = 5;
+ break;
+ }
+
+ if (change) {
+ writel(LRADC_CTRL0_PLATE_MASK,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+ writel(ctrl0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+
+ writel(LRADC_CTRL4_LRADCSELECT_MASK(slot),
+ lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
+ writel(chan << LRADC_CTRL4_LRADCSELECT_OFFSET(slot),
+ lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
+ }
+
+ writel(0xffffffff, lradc->base + LRADC_CH(slot) + STMP_OFFSET_REG_CLR);
+ writel(1 << slot, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+
+ delay = jiffies + msecs_to_jiffies(LRADC_TS_SAMPLE_DELAY_MS);
+ do {
+ jiff = jiffies;
+ reg = readl_relaxed(lradc->base + LRADC_CTRL1);
+ if (reg & LRADC_CTRL1_LRADC_IRQ(slot))
+ break;
+ } while (time_before(jiff, delay));
+
+ writel(LRADC_CTRL1_LRADC_IRQ(slot),
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+
+ if (time_after_eq(jiff, delay))
+ return -ETIMEDOUT;
+
+ val = readl(lradc->base + LRADC_CH(slot));
+ val &= LRADC_CH_VALUE_MASK;
+
+ return val;
+}
+
+static int32_t mxs_lradc_ts_sample_filter(struct mxs_lradc *lradc,
+ enum lradc_ts_plate plate)
+{
+ int32_t val, tot = 0;
+ int i;
+
+ val = mxs_lradc_ts_sample(lradc, plate, 1);
+
+ /* Delay a bit so the touchscreen is stable. */
+ mdelay(2);
+
+ for (i = 0; i < LRADC_TS_SAMPLE_AMOUNT; i++) {
+ val = mxs_lradc_ts_sample(lradc, plate, 0);
+ tot += val;
+ }
+
+ return tot / LRADC_TS_SAMPLE_AMOUNT;
+}
+
+static void mxs_lradc_ts_work(struct work_struct *ts_work)
+{
+ struct mxs_lradc *lradc = container_of(ts_work,
+ struct mxs_lradc, ts_work);
+ int val_x, val_y, val_p;
+ bool valid = false;
+
+ while (mxs_lradc_ts_touched(lradc)) {
+ /* Disable touch detector so we can sample the touchscreen. */
+ writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+
+ if (likely(valid)) {
+ input_report_abs(lradc->ts_input, ABS_X, val_x);
+ input_report_abs(lradc->ts_input, ABS_Y, val_y);
+ input_report_abs(lradc->ts_input, ABS_PRESSURE, val_p);
+ input_report_key(lradc->ts_input, BTN_TOUCH, 1);
+ input_sync(lradc->ts_input);
+ }
+
+ valid = false;
+
+ val_x = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_X);
+ if (val_x < 0)
+ continue;
+ val_y = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_Y);
+ if (val_y < 0)
+ continue;
+ val_p = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_PRESSURE);
+ if (val_p < 0)
+ continue;
+
+ valid = true;
+ }
+
+ input_report_abs(lradc->ts_input, ABS_PRESSURE, 0);
+ input_report_key(lradc->ts_input, BTN_TOUCH, 0);
+ input_sync(lradc->ts_input);
+
+ /* Do not restart the TS IRQ if the driver is shutting down. */
+ if (lradc->stop_touchscreen)
+ return;
+
+ /* Restart the touchscreen interrupts. */
+ writel(LRADC_CTRL1_TOUCH_DETECT_IRQ,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
+}
+
+static int mxs_lradc_ts_open(struct input_dev *dev)
+{
+ struct mxs_lradc *lradc = input_get_drvdata(dev);
+
+ /* The touchscreen is starting. */
+ lradc->stop_touchscreen = false;
+
+ /* Enable the touch-detect circuitry. */
+ writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+
+ /* Enable the touch-detect IRQ. */
+ writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
+
+ return 0;
}
static void mxs_lradc_ts_close(struct input_dev *dev)
{
struct mxs_lradc *lradc = input_get_drvdata(dev);
- mxs_lradc_disable_ts(lradc);
+ /* Indicate the touchscreen is stopping. */
+ lradc->stop_touchscreen = true;
+ mb();
+
+ /* Wait until touchscreen thread finishes any possible remnants. */
+ cancel_work_sync(&lradc->ts_work);
+
+ /* Disable touchscreen touch-detect IRQ. */
+ writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+
+ /* Power-down touchscreen touch-detect circuitry. */
+ writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
}
static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
@@ -868,8 +529,10 @@ static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
return 0;
input = input_allocate_device();
- if (!input)
+ if (!input) {
+ dev_err(dev, "Failed to allocate TS device!\n");
return -ENOMEM;
+ }
input->name = DRIVER_NAME;
input->id.bustype = BUS_HOST;
@@ -899,7 +562,8 @@ static void mxs_lradc_ts_unregister(struct mxs_lradc *lradc)
if (!lradc->use_touchscreen)
return;
- mxs_lradc_disable_ts(lradc);
+ cancel_work_sync(&lradc->ts_work);
+
input_unregister_device(lradc->ts_input);
}
@@ -912,24 +576,31 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
struct mxs_lradc *lradc = iio_priv(iio);
unsigned long reg = readl(lradc->base + LRADC_CTRL1);
const uint32_t ts_irq_mask =
- LRADC_CTRL1_TOUCH_DETECT_IRQ |
- LRADC_CTRL1_LRADC_IRQ(2) |
- LRADC_CTRL1_LRADC_IRQ(3) |
- LRADC_CTRL1_LRADC_IRQ(4) |
- LRADC_CTRL1_LRADC_IRQ(5);
+ LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
+ LRADC_CTRL1_TOUCH_DETECT_IRQ;
- if (!(reg & mxs_lradc_irq_mask(lradc)))
+ if (!(reg & LRADC_CTRL1_LRADC_IRQ_MASK))
return IRQ_NONE;
- if (lradc->use_touchscreen && (reg & ts_irq_mask))
- mxs_lradc_handle_touch(lradc);
+ /*
+ * Touchscreen IRQ handling code has priority and therefore
+ * is placed here. In case touchscreen IRQ arrives, disable
+ * it ASAP
+ */
+ if (reg & LRADC_CTRL1_TOUCH_DETECT_IRQ) {
+ writel(ts_irq_mask,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ if (!lradc->stop_touchscreen)
+ schedule_work(&lradc->ts_work);
+ }
if (iio_buffer_enabled(iio))
iio_trigger_poll(iio->trig, iio_get_time_ns());
else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
complete(&lradc->completion);
- mxs_lradc_reg_clear(lradc, reg & mxs_lradc_irq_mask(lradc), LRADC_CTRL1);
+ writel(reg & LRADC_CTRL1_LRADC_IRQ_MASK,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
return IRQ_HANDLED;
}
@@ -948,13 +619,19 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
for_each_set_bit(i, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
lradc->buffer[j] = readl(lradc->base + LRADC_CH(j));
- mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(j));
+ writel(chan_value, lradc->base + LRADC_CH(j));
lradc->buffer[j] &= LRADC_CH_VALUE_MASK;
lradc->buffer[j] /= LRADC_DELAY_TIMER_LOOP;
j++;
}
- iio_push_to_buffers_with_timestamp(iio, lradc->buffer, pf->timestamp);
+ if (iio->scan_timestamp) {
+ s64 *timestamp = (s64 *)((u8 *)lradc->buffer +
+ ALIGN(j, sizeof(s64)));
+ *timestamp = pf->timestamp;
+ }
+
+ iio_push_to_buffers(iio, (u8 *)lradc->buffer);
iio_trigger_notify_done(iio->trig);
@@ -967,7 +644,7 @@ static int mxs_lradc_configure_trigger(struct iio_trigger *trig, bool state)
struct mxs_lradc *lradc = iio_priv(iio);
const uint32_t st = state ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR;
- mxs_lradc_reg_wrt(lradc, LRADC_DELAY_KICK, LRADC_DELAY(0) + st);
+ writel(LRADC_DELAY_KICK, lradc->base + LRADC_DELAY(0) + st);
return 0;
}
@@ -1039,30 +716,38 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
goto err_mem;
}
- if (lradc->soc == IMX28_LRADC)
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
- LRADC_CTRL1);
- mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
+ ret = iio_sw_buffer_preenable(iio);
+ if (ret < 0)
+ goto err_buf;
+
+ writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+ writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs);
ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs);
- mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(ofs));
+ writel(chan_value, lradc->base + LRADC_CH(ofs));
bitmap_set(&enable, ofs, 1);
ofs++;
}
- mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
- LRADC_DELAY_KICK, LRADC_DELAY(0));
- mxs_lradc_reg_clear(lradc, ctrl4_clr, LRADC_CTRL4);
- mxs_lradc_reg_set(lradc, ctrl4_set, LRADC_CTRL4);
- mxs_lradc_reg_set(lradc, ctrl1_irq, LRADC_CTRL1);
- mxs_lradc_reg_set(lradc, enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
- LRADC_DELAY(0));
+ writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
+ lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
+
+ writel(ctrl4_clr, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
+ writel(ctrl4_set, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
+
+ writel(ctrl1_irq, lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
+
+ writel(enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
+ lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_SET);
return 0;
+err_buf:
+ kfree(lradc->buffer);
err_mem:
mutex_unlock(&lradc->lock);
return ret;
@@ -1072,13 +757,12 @@ static int mxs_lradc_buffer_postdisable(struct iio_dev *iio)
{
struct mxs_lradc *lradc = iio_priv(iio);
- mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
- LRADC_DELAY_KICK, LRADC_DELAY(0));
+ writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
+ lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
- mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
- if (lradc->soc == IMX28_LRADC)
- mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
- LRADC_CTRL1);
+ writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+ writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
kfree(lradc->buffer);
mutex_unlock(&lradc->lock);
@@ -1173,25 +857,24 @@ static int mxs_lradc_hw_init(struct mxs_lradc *lradc)
return ret;
/* Configure DELAY CHANNEL 0 for generic ADC sampling. */
- mxs_lradc_reg_wrt(lradc, adc_cfg, LRADC_DELAY(0));
+ writel(adc_cfg, lradc->base + LRADC_DELAY(0));
/* Disable remaining DELAY CHANNELs */
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(1));
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
+ writel(0, lradc->base + LRADC_DELAY(1));
+ writel(0, lradc->base + LRADC_DELAY(2));
+ writel(0, lradc->base + LRADC_DELAY(3));
/* Configure the touchscreen type */
- if (lradc->soc == IMX28_LRADC) {
- mxs_lradc_reg_clear(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
- LRADC_CTRL0);
+ writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
- if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE)
- mxs_lradc_reg_set(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
- LRADC_CTRL0);
+ if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE) {
+ writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE,
+ lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
}
/* Start internal temperature sensing. */
- mxs_lradc_reg_wrt(lradc, 0, LRADC_CTRL2);
+ writel(0, lradc->base + LRADC_CTRL2);
return 0;
}
@@ -1200,10 +883,11 @@ static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
{
int i;
- mxs_lradc_reg_clear(lradc, mxs_lradc_irq_en_mask(lradc), LRADC_CTRL1);
+ writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
+ lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++)
- mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(i));
+ writel(0, lradc->base + LRADC_DELAY(i));
}
static const struct of_device_id mxs_lradc_dt_ids[] = {
@@ -1213,52 +897,6 @@ static const struct of_device_id mxs_lradc_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids);
-static int mxs_lradc_probe_touchscreen(struct mxs_lradc *lradc,
- struct device_node *lradc_node)
-{
- int ret;
- u32 ts_wires = 0, adapt;
-
- ret = of_property_read_u32(lradc_node, "fsl,lradc-touchscreen-wires",
- &ts_wires);
- if (ret)
- return -ENODEV; /* touchscreen feature disabled */
-
- switch (ts_wires) {
- case 4:
- lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
- break;
- case 5:
- if (lradc->soc == IMX28_LRADC) {
- lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
- break;
- }
- /* fall through an error message for i.MX23 */
- default:
- dev_err(lradc->dev,
- "Unsupported number of touchscreen wires (%d)\n",
- ts_wires);
- return -EINVAL;
- }
-
- lradc->over_sample_cnt = 4;
- ret = of_property_read_u32(lradc_node, "fsl,ave-ctrl", &adapt);
- if (ret == 0)
- lradc->over_sample_cnt = adapt;
-
- lradc->over_sample_delay = 2;
- ret = of_property_read_u32(lradc_node, "fsl,ave-delay", &adapt);
- if (ret == 0)
- lradc->over_sample_delay = adapt;
-
- lradc->settling_delay = 10;
- ret = of_property_read_u32(lradc_node, "fsl,settling", &adapt);
- if (ret == 0)
- lradc->settling_delay = adapt;
-
- return 0;
-}
-
static int mxs_lradc_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
@@ -1270,7 +908,8 @@ static int mxs_lradc_probe(struct platform_device *pdev)
struct mxs_lradc *lradc;
struct iio_dev *iio;
struct resource *iores;
- int ret = 0, touch_ret;
+ uint32_t ts_wires = 0;
+ int ret = 0;
int i;
/* Allocate the IIO device. */
@@ -1281,7 +920,6 @@ static int mxs_lradc_probe(struct platform_device *pdev)
}
lradc = iio_priv(iio);
- lradc->soc = (enum mxs_lradc_id)of_id->data;
/* Grab the memory area */
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1290,18 +928,20 @@ static int mxs_lradc_probe(struct platform_device *pdev)
if (IS_ERR(lradc->base))
return PTR_ERR(lradc->base);
- lradc->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(lradc->clk)) {
- dev_err(dev, "Failed to get the delay unit clock\n");
- return PTR_ERR(lradc->clk);
- }
- ret = clk_prepare_enable(lradc->clk);
- if (ret != 0) {
- dev_err(dev, "Failed to enable the delay unit clock\n");
- return ret;
- }
+ INIT_WORK(&lradc->ts_work, mxs_lradc_ts_work);
- touch_ret = mxs_lradc_probe_touchscreen(lradc, node);
+ /* Check if touchscreen is enabled in DT. */
+ ret = of_property_read_u32(node, "fsl,lradc-touchscreen-wires",
+ &ts_wires);
+ if (ret)
+ dev_info(dev, "Touchscreen not enabled.\n");
+ else if (ts_wires == 4)
+ lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
+ else if (ts_wires == 5)
+ lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
+ else
+ dev_warn(dev, "Unsupported number of touchscreen wires (%d)\n",
+ ts_wires);
/* Grab all IRQ sources */
for (i = 0; i < of_cfg->irq_count; i++) {
@@ -1345,11 +985,9 @@ static int mxs_lradc_probe(struct platform_device *pdev)
goto err_dev;
/* Register the touchscreen input device. */
- if (touch_ret == 0) {
- ret = mxs_lradc_ts_register(lradc);
- if (ret)
- goto err_ts_register;
- }
+ ret = mxs_lradc_ts_register(lradc);
+ if (ret)
+ goto err_dev;
/* Register IIO device. */
ret = iio_device_register(iio);
@@ -1362,8 +1000,6 @@ static int mxs_lradc_probe(struct platform_device *pdev)
err_ts:
mxs_lradc_ts_unregister(lradc);
-err_ts_register:
- mxs_lradc_hw_stop(lradc);
err_dev:
mxs_lradc_trigger_remove(iio);
err_trig:
@@ -1376,13 +1012,14 @@ static int mxs_lradc_remove(struct platform_device *pdev)
struct iio_dev *iio = platform_get_drvdata(pdev);
struct mxs_lradc *lradc = iio_priv(iio);
- iio_device_unregister(iio);
mxs_lradc_ts_unregister(lradc);
+
mxs_lradc_hw_stop(lradc);
- mxs_lradc_trigger_remove(iio);
+
+ iio_device_unregister(iio);
iio_triggered_buffer_cleanup(iio);
+ mxs_lradc_trigger_remove(iio);
- clk_disable_unprepare(lradc->clk);
return 0;
}
@@ -1401,4 +1038,3 @@ module_platform_driver(mxs_lradc_driver);
MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
MODULE_DESCRIPTION("Freescale i.MX28 LRADC driver");
MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c
index 970d9ed..20f2d55 100644
--- a/drivers/staging/iio/adc/spear_adc.c
+++ b/drivers/staging/iio/adc/spear_adc.c
@@ -146,6 +146,7 @@ static int spear_read_raw(struct iio_dev *indio_dev,
long mask)
{
struct spear_adc_info *info = iio_priv(indio_dev);
+ u32 scale_mv;
u32 status;
switch (mask) {
@@ -167,9 +168,10 @@ static int spear_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = info->vref_external;
- *val2 = DATA_BITS;
- return IIO_VAL_FRACTIONAL_LOG2;
+ scale_mv = (info->vref_external * 1000) >> DATA_BITS;
+ *val = scale_mv / 1000;
+ *val2 = (scale_mv % 1000) * 1000;
+ return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
@@ -318,7 +320,7 @@ static int spear_adc_probe(struct platform_device *pdev)
return -ENOMEM;
}
info->adc_base_spear3xx =
- (struct adc_regs_spear3xx __iomem *)info->adc_base_spear6xx;
+ (struct adc_regs_spear3xx *)info->adc_base_spear6xx;
info->clk = clk_get(dev, NULL);
if (IS_ERR(info->clk)) {
@@ -333,7 +335,7 @@ static int spear_adc_probe(struct platform_device *pdev)
}
irq = platform_get_irq(pdev, 0);
- if (irq <= 0) {
+ if ((irq < 0) || (irq >= NR_IRQS)) {
dev_err(dev, "failed getting interrupt resource\n");
ret = -EINVAL;
goto errout3;
diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c
index 0feea55..ce7d91c 100644
--- a/drivers/staging/iio/addac/adt7316-i2c.c
+++ b/drivers/staging/iio/addac/adt7316-i2c.c
@@ -138,5 +138,6 @@ static struct i2c_driver adt7316_driver = {
module_i2c_driver(adt7316_driver);
MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and ADT7516/7/8 digital temperature sensor, ADC and DAC");
+MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and"
+ "ADT7516/7/8 digital temperature sensor, ADC and DAC");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c
index 7f4f0a8..0db8ef5 100644
--- a/drivers/staging/iio/addac/adt7316-spi.c
+++ b/drivers/staging/iio/addac/adt7316-spi.c
@@ -146,5 +146,6 @@ static struct spi_driver adt7316_driver = {
module_spi_driver(adt7316_driver);
MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and ADT7516/7/9 digital temperature sensor, ADC and DAC");
+MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and"
+ "ADT7516/7/9 digital temperature sensor, ADC and DAC");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index 80266e8..1e13568 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -412,13 +412,13 @@ static ssize_t adt7316_store_ad_channel(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
u8 config2;
- u8 data;
+ unsigned long data = 0;
int ret;
if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
return -EPERM;
- ret = kstrtou8(buf, 10, &data);
+ ret = strict_strtoul(buf, 10, &data);
if (ret)
return -EINVAL;
@@ -823,10 +823,10 @@ static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
u8 dac_config;
- u8 data;
+ unsigned long data = 0;
int ret;
- ret = kstrtou8(buf, 16, &data);
+ ret = strict_strtoul(buf, 16, &data);
if (ret || data > ADT7316_DA_2VREF_CH_MASK)
return -EINVAL;
@@ -878,13 +878,13 @@ static ssize_t adt7316_store_DAC_update_mode(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
u8 dac_config;
- u8 data;
+ unsigned long data;
int ret;
if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
return -EPERM;
- ret = kstrtou8(buf, 10, &data);
+ ret = strict_strtoul(buf, 10, &data);
if (ret || data > ADT7316_DA_EN_MODE_MASK)
return -EINVAL;
@@ -933,7 +933,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
u8 ldac_config;
- u8 data;
+ unsigned long data;
int ret;
if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) {
@@ -941,7 +941,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev,
ADT7316_DA_EN_MODE_LDAC)
return -EPERM;
- ret = kstrtou8(buf, 16, &data);
+ ret = strict_strtoul(buf, 16, &data);
if (ret || data > ADT7316_LDAC_EN_DA_MASK)
return -EINVAL;
@@ -1079,11 +1079,11 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
u8 ldac_config;
- u8 data;
+ unsigned long data;
int ret;
if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
- ret = kstrtou8(buf, 16, &data);
+ ret = strict_strtoul(buf, 16, &data);
if (ret || data > 3)
return -EINVAL;
@@ -1093,7 +1093,7 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
else if (data & 0x2)
ldac_config |= ADT7516_DAC_CD_IN_VREF;
} else {
- ret = kstrtou8(buf, 16, &data);
+ ret = strict_strtoul(buf, 16, &data);
if (ret)
return -EINVAL;
@@ -1281,11 +1281,11 @@ static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip,
static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip,
int offset_addr, const char *buf, size_t len)
{
- int data;
+ long data;
u8 val;
int ret;
- ret = kstrtoint(buf, 10, &data);
+ ret = strict_strtol(buf, 10, &data);
if (ret || data > 127 || data < -128)
return -EINVAL;
@@ -1442,7 +1442,7 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
int channel, const char *buf, size_t len)
{
u8 msb, lsb, offset;
- u16 data;
+ unsigned long data;
int ret;
if (channel >= ADT7316_DA_MSB_DATA_REGS ||
@@ -1454,7 +1454,7 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
offset = chip->dac_bits - 8;
- ret = kstrtou16(buf, 10, &data);
+ ret = strict_strtoul(buf, 10, &data);
if (ret || data >= (1 << chip->dac_bits))
return -EINVAL;
@@ -1830,11 +1830,11 @@ static ssize_t adt7316_set_int_mask(struct device *dev,
{
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- u16 data;
+ unsigned long data;
int ret;
u8 mask;
- ret = kstrtou16(buf, 16, &data);
+ ret = strict_strtoul(buf, 16, &data);
if (ret || data >= ADT7316_VDD_INT_MASK + 1)
return -EINVAL;
@@ -1901,7 +1901,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
struct iio_dev *dev_info = dev_to_iio_dev(dev);
struct adt7316_chip_info *chip = iio_priv(dev_info);
- int data;
+ long data;
u8 val;
int ret;
@@ -1909,7 +1909,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
this_attr->address > ADT7316_EX_TEMP_LOW)
return -EPERM;
- ret = kstrtoint(buf, 10, &data);
+ ret = strict_strtol(buf, 10, &data);
if (ret)
return -EINVAL;
@@ -2106,9 +2106,11 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
unsigned short *adt7316_platform_data = dev->platform_data;
int ret = 0;
- indio_dev = devm_iio_device_alloc(dev, sizeof(*chip));
- if (!indio_dev)
- return -ENOMEM;
+ indio_dev = iio_device_alloc(sizeof(*chip));
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
chip = iio_priv(indio_dev);
/* this is only used for device removal purposes */
dev_set_drvdata(dev, indio_dev);
@@ -2144,44 +2146,58 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
if (adt7316_platform_data[0])
chip->bus.irq_flags = adt7316_platform_data[0];
- ret = devm_request_threaded_irq(dev, chip->bus.irq,
- NULL,
- &adt7316_event_handler,
- chip->bus.irq_flags |
- IRQF_ONESHOT,
- indio_dev->name,
- indio_dev);
+ ret = request_threaded_irq(chip->bus.irq,
+ NULL,
+ &adt7316_event_handler,
+ chip->bus.irq_flags | IRQF_ONESHOT,
+ indio_dev->name,
+ indio_dev);
if (ret)
- return ret;
+ goto error_free_dev;
if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
chip->config1 |= ADT7316_INT_POLARITY;
}
ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1);
- if (ret)
- return -EIO;
+ if (ret) {
+ ret = -EIO;
+ goto error_unreg_irq;
+ }
ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, chip->config3);
- if (ret)
- return -EIO;
+ if (ret) {
+ ret = -EIO;
+ goto error_unreg_irq;
+ }
ret = iio_device_register(indio_dev);
if (ret)
- return ret;
+ goto error_unreg_irq;
dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
indio_dev->name);
return 0;
+
+error_unreg_irq:
+ free_irq(chip->bus.irq, indio_dev);
+error_free_dev:
+ iio_device_free(indio_dev);
+error_ret:
+ return ret;
}
EXPORT_SYMBOL(adt7316_probe);
int adt7316_remove(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct adt7316_chip_info *chip = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
+ if (chip->bus.irq)
+ free_irq(chip->bus.irq, indio_dev);
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c
index 7e7f989..f4a0341 100644
--- a/drivers/staging/iio/cdc/ad7150.c
+++ b/drivers/staging/iio/cdc/ad7150.c
@@ -123,14 +123,14 @@ static int ad7150_read_raw(struct iio_dev *indio_dev,
}
}
-static int ad7150_read_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan, enum iio_event_type type,
- enum iio_event_direction dir)
+static int ad7150_read_event_config(struct iio_dev *indio_dev, u64 event_code)
{
int ret;
u8 threshtype;
bool adaptive;
struct ad7150_chip_info *chip = iio_priv(indio_dev);
+ int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+ IIO_EV_DIR_RISING);
ret = i2c_smbus_read_byte_data(chip->client, AD7150_CFG);
if (ret < 0)
@@ -139,47 +139,42 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev,
threshtype = (ret >> 5) & 0x03;
adaptive = !!(ret & 0x80);
- switch (type) {
+ switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
case IIO_EV_TYPE_MAG_ADAPTIVE:
- if (dir == IIO_EV_DIR_RISING)
+ if (rising)
return adaptive && (threshtype == 0x1);
else
return adaptive && (threshtype == 0x0);
case IIO_EV_TYPE_THRESH_ADAPTIVE:
- if (dir == IIO_EV_DIR_RISING)
+ if (rising)
return adaptive && (threshtype == 0x3);
else
return adaptive && (threshtype == 0x2);
case IIO_EV_TYPE_THRESH:
- if (dir == IIO_EV_DIR_RISING)
+ if (rising)
return !adaptive && (threshtype == 0x1);
else
return !adaptive && (threshtype == 0x0);
- default:
- break;
}
return -EINVAL;
}
/* lock should be held */
-static int ad7150_write_event_params(struct iio_dev *indio_dev,
- unsigned int chan, enum iio_event_type type,
- enum iio_event_direction dir)
+static int ad7150_write_event_params(struct iio_dev *indio_dev, u64 event_code)
{
int ret;
u16 value;
u8 sens, timeout;
struct ad7150_chip_info *chip = iio_priv(indio_dev);
- int rising = (dir == IIO_EV_DIR_RISING);
- u64 event_code;
-
- event_code = IIO_UNMOD_EVENT_CODE(IIO_CAPACITANCE, chan, type, dir);
+ int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
+ int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+ IIO_EV_DIR_RISING);
if (event_code != chip->current_event)
return 0;
- switch (type) {
+ switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
/* Note completely different from the adaptive versions */
case IIO_EV_TYPE_THRESH:
value = chip->threshold[rising][chan];
@@ -216,20 +211,18 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev,
}
static int ad7150_write_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan, enum iio_event_type type,
- enum iio_event_direction dir, int state)
+ u64 event_code, int state)
{
u8 thresh_type, cfg, adaptive;
int ret;
struct ad7150_chip_info *chip = iio_priv(indio_dev);
- int rising = (dir == IIO_EV_DIR_RISING);
- u64 event_code;
+ int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+ IIO_EV_DIR_RISING);
/* Something must always be turned on */
if (state == 0)
return -EINVAL;
- event_code = IIO_UNMOD_EVENT_CODE(chan->type, chan->channel, type, dir);
if (event_code == chip->current_event)
return 0;
mutex_lock(&chip->state_lock);
@@ -239,7 +232,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev,
cfg = ret & ~((0x03 << 5) | (0x1 << 7));
- switch (type) {
+ switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
case IIO_EV_TYPE_MAG_ADAPTIVE:
adaptive = 1;
if (rising)
@@ -275,7 +268,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev,
chip->current_event = event_code;
/* update control attributes */
- ret = ad7150_write_event_params(indio_dev, chan->channel, type, dir);
+ ret = ad7150_write_event_params(indio_dev, event_code);
error_ret:
mutex_unlock(&chip->state_lock);
@@ -283,52 +276,53 @@ error_ret:
}
static int ad7150_read_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int *val, int *val2)
+ u64 event_code,
+ int *val)
{
+ int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
struct ad7150_chip_info *chip = iio_priv(indio_dev);
- int rising = (dir == IIO_EV_DIR_RISING);
+ int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+ IIO_EV_DIR_RISING);
/* Complex register sharing going on here */
- switch (type) {
+ switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
case IIO_EV_TYPE_MAG_ADAPTIVE:
- *val = chip->mag_sensitivity[rising][chan->channel];
- return IIO_VAL_INT;
+ *val = chip->mag_sensitivity[rising][chan];
+ return 0;
+
case IIO_EV_TYPE_THRESH_ADAPTIVE:
- *val = chip->thresh_sensitivity[rising][chan->channel];
- return IIO_VAL_INT;
+ *val = chip->thresh_sensitivity[rising][chan];
+ return 0;
+
case IIO_EV_TYPE_THRESH:
- *val = chip->threshold[rising][chan->channel];
- return IIO_VAL_INT;
+ *val = chip->threshold[rising][chan];
+ return 0;
+
default:
return -EINVAL;
- }
+ };
}
static int ad7150_write_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int val, int val2)
+ u64 event_code,
+ int val)
{
int ret;
struct ad7150_chip_info *chip = iio_priv(indio_dev);
- int rising = (dir == IIO_EV_DIR_RISING);
+ int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
+ int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+ IIO_EV_DIR_RISING);
mutex_lock(&chip->state_lock);
- switch (type) {
+ switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
case IIO_EV_TYPE_MAG_ADAPTIVE:
- chip->mag_sensitivity[rising][chan->channel] = val;
+ chip->mag_sensitivity[rising][chan] = val;
break;
case IIO_EV_TYPE_THRESH_ADAPTIVE:
- chip->thresh_sensitivity[rising][chan->channel] = val;
+ chip->thresh_sensitivity[rising][chan] = val;
break;
case IIO_EV_TYPE_THRESH:
- chip->threshold[rising][chan->channel] = val;
+ chip->threshold[rising][chan] = val;
break;
default:
ret = -EINVAL;
@@ -336,7 +330,7 @@ static int ad7150_write_event_value(struct iio_dev *indio_dev,
}
/* write back if active */
- ret = ad7150_write_event_params(indio_dev, chan->channel, type, dir);
+ ret = ad7150_write_event_params(indio_dev, event_code);
error_ret:
mutex_unlock(&chip->state_lock);
@@ -380,22 +374,17 @@ static ssize_t ad7150_store_timeout(struct device *dev,
struct ad7150_chip_info *chip = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int chan = IIO_EVENT_CODE_EXTRACT_CHAN(this_attr->address);
- enum iio_event_direction dir;
- enum iio_event_type type;
- int rising;
+ int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address) ==
+ IIO_EV_DIR_RISING);
u8 data;
int ret;
- type = IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address);
- dir = IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address);
- rising = (dir == IIO_EV_DIR_RISING);
-
ret = kstrtou8(buf, 10, &data);
if (ret < 0)
return ret;
mutex_lock(&chip->state_lock);
- switch (type) {
+ switch (IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address)) {
case IIO_EV_TYPE_MAG_ADAPTIVE:
chip->mag_timeout[rising][chan] = data;
break;
@@ -407,7 +396,7 @@ static ssize_t ad7150_store_timeout(struct device *dev,
goto error_ret;
}
- ret = ad7150_write_event_params(indio_dev, chan, type, dir);
+ ret = ad7150_write_event_params(indio_dev, this_attr->address);
error_ret:
mutex_unlock(&chip->state_lock);
@@ -435,40 +424,6 @@ static AD7150_TIMEOUT(0, thresh_adaptive, falling, THRESH_ADAPTIVE, FALLING);
static AD7150_TIMEOUT(1, thresh_adaptive, rising, THRESH_ADAPTIVE, RISING);
static AD7150_TIMEOUT(1, thresh_adaptive, falling, THRESH_ADAPTIVE, FALLING);
-static const struct iio_event_spec ad7150_events[] = {
- {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_RISING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
- BIT(IIO_EV_INFO_ENABLE),
- }, {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_FALLING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
- BIT(IIO_EV_INFO_ENABLE),
- }, {
- .type = IIO_EV_TYPE_THRESH_ADAPTIVE,
- .dir = IIO_EV_DIR_RISING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
- BIT(IIO_EV_INFO_ENABLE),
- }, {
- .type = IIO_EV_TYPE_THRESH_ADAPTIVE,
- .dir = IIO_EV_DIR_FALLING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
- BIT(IIO_EV_INFO_ENABLE),
- }, {
- .type = IIO_EV_TYPE_MAG_ADAPTIVE,
- .dir = IIO_EV_DIR_RISING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
- BIT(IIO_EV_INFO_ENABLE),
- }, {
- .type = IIO_EV_TYPE_MAG_ADAPTIVE,
- .dir = IIO_EV_DIR_FALLING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
- BIT(IIO_EV_INFO_ENABLE),
- },
-};
-
static const struct iio_chan_spec ad7150_channels[] = {
{
.type = IIO_CAPACITANCE,
@@ -476,16 +431,26 @@ static const struct iio_chan_spec ad7150_channels[] = {
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_AVERAGE_RAW),
- .event_spec = ad7150_events,
- .num_event_specs = ARRAY_SIZE(ad7150_events),
+ .event_mask =
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_RISING) |
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_FALLING) |
+ IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_RISING) |
+ IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_FALLING)
}, {
.type = IIO_CAPACITANCE,
.indexed = 1,
.channel = 1,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_AVERAGE_RAW),
- .event_spec = ad7150_events,
- .num_event_specs = ARRAY_SIZE(ad7150_events),
+ .event_mask =
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_RISING) |
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_FALLING) |
+ IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_RISING) |
+ IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_FALLING)
},
};
@@ -576,10 +541,10 @@ static const struct iio_info ad7150_info = {
.event_attrs = &ad7150_event_attribute_group,
.driver_module = THIS_MODULE,
.read_raw = &ad7150_read_raw,
- .read_event_config_new = &ad7150_read_event_config,
- .write_event_config_new = &ad7150_write_event_config,
- .read_event_value_new = &ad7150_read_event_value,
- .write_event_value_new = &ad7150_write_event_value,
+ .read_event_config = &ad7150_read_event_config,
+ .write_event_config = &ad7150_write_event_config,
+ .read_event_value = &ad7150_read_event_value,
+ .write_event_value = &ad7150_write_event_value,
};
/*
diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c
index 862d68d..75a533b 100644
--- a/drivers/staging/iio/cdc/ad7746.c
+++ b/drivers/staging/iio/cdc/ad7746.c
@@ -656,21 +656,20 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
switch (chan->type) {
case IIO_CAPACITANCE:
/* 8.192pf / 2^24 */
- *val = 0;
*val2 = 488;
- ret = IIO_VAL_INT_PLUS_NANO;
+ *val = 0;
break;
case IIO_VOLTAGE:
/* 1170mV / 2^23 */
- *val = 1170;
- *val2 = 23;
- ret = IIO_VAL_FRACTIONAL_LOG2;
+ *val2 = 139475;
+ *val = 0;
break;
default:
- ret = -EINVAL;
- break;
+ ret = -EINVAL;
+ goto out;
}
+ ret = IIO_VAL_INT_PLUS_NANO;
break;
default:
ret = -EINVAL;
diff --git a/drivers/staging/iio/frequency/ad5930.c b/drivers/staging/iio/frequency/ad5930.c
index a4aeee6..69e90e9 100644
--- a/drivers/staging/iio/frequency/ad5930.c
+++ b/drivers/staging/iio/frequency/ad5930.c
@@ -94,9 +94,11 @@ static int ad5930_probe(struct spi_device *spi)
struct iio_dev *idev;
int ret = 0;
- idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!idev)
- return -ENOMEM;
+ idev = iio_device_alloc(sizeof(*st));
+ if (idev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
spi_set_drvdata(spi, idev);
st = iio_priv(idev);
@@ -108,18 +110,24 @@ static int ad5930_probe(struct spi_device *spi)
ret = iio_device_register(idev);
if (ret)
- return ret;
+ goto error_free_dev;
spi->max_speed_hz = 2000000;
spi->mode = SPI_MODE_3;
spi->bits_per_word = 16;
spi_setup(spi);
return 0;
+
+error_free_dev:
+ iio_device_free(idev);
+error_ret:
+ return ret;
}
static int ad5930_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
+ iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c
index c7d0307..4e18380 100644
--- a/drivers/staging/iio/frequency/ad9832.c
+++ b/drivers/staging/iio/frequency/ad9832.c
@@ -81,9 +81,9 @@ static ssize_t ad9832_write(struct device *dev,
struct ad9832_state *st = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- unsigned long val;
+ long val;
- ret = kstrtoul(buf, 10, &val);
+ ret = strict_strtoul(buf, 10, &val);
if (ret)
goto error_ret;
@@ -214,14 +214,14 @@ static int ad9832_probe(struct spi_device *spi)
return -ENODEV;
}
- reg = devm_regulator_get(&spi->dev, "vcc");
+ reg = regulator_get(&spi->dev, "vcc");
if (!IS_ERR(reg)) {
ret = regulator_enable(reg);
if (ret)
- return ret;
+ goto error_put_reg;
}
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_disable_reg;
@@ -279,42 +279,47 @@ static int ad9832_probe(struct spi_device *spi)
ret = spi_sync(st->spi, &st->msg);
if (ret) {
dev_err(&spi->dev, "device init failed\n");
- goto error_disable_reg;
+ goto error_free_device;
}
ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
return 0;
+error_free_device:
+ iio_device_free(indio_dev);
error_disable_reg:
if (!IS_ERR(reg))
regulator_disable(reg);
+error_put_reg:
+ if (!IS_ERR(reg))
+ regulator_put(reg);
return ret;
}
@@ -325,8 +330,11 @@ static int ad9832_remove(struct spi_device *spi)
struct ad9832_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- if (!IS_ERR(st->reg))
+ if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
+ regulator_put(st->reg);
+ }
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c
index 86cda61..5cba3c0 100644
--- a/drivers/staging/iio/frequency/ad9834.c
+++ b/drivers/staging/iio/frequency/ad9834.c
@@ -70,9 +70,9 @@ static ssize_t ad9834_write(struct device *dev,
struct ad9834_state *st = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- unsigned long val;
+ long val;
- ret = kstrtoul(buf, 10, &val);
+ ret = strict_strtoul(buf, 10, &val);
if (ret)
goto error_ret;
@@ -327,14 +327,14 @@ static int ad9834_probe(struct spi_device *spi)
return -ENODEV;
}
- reg = devm_regulator_get(&spi->dev, "vcc");
+ reg = regulator_get(&spi->dev, "vcc");
if (!IS_ERR(reg)) {
ret = regulator_enable(reg);
if (ret)
- return ret;
+ goto error_put_reg;
}
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_disable_reg;
@@ -388,35 +388,39 @@ static int ad9834_probe(struct spi_device *spi)
ret = spi_sync(st->spi, &st->msg);
if (ret) {
dev_err(&spi->dev, "device init failed\n");
- goto error_disable_reg;
+ goto error_free_device;
}
ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
ret = iio_device_register(indio_dev);
if (ret)
- goto error_disable_reg;
+ goto error_free_device;
return 0;
+error_free_device:
+ iio_device_free(indio_dev);
error_disable_reg:
if (!IS_ERR(reg))
regulator_disable(reg);
-
+error_put_reg:
+ if (!IS_ERR(reg))
+ regulator_put(reg);
return ret;
}
@@ -426,8 +430,11 @@ static int ad9834_remove(struct spi_device *spi)
struct ad9834_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- if (!IS_ERR(st->reg))
+ if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
+ regulator_put(st->reg);
+ }
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9850.c b/drivers/staging/iio/frequency/ad9850.c
index af877ff..01a8a93 100644
--- a/drivers/staging/iio/frequency/ad9850.c
+++ b/drivers/staging/iio/frequency/ad9850.c
@@ -80,9 +80,11 @@ static int ad9850_probe(struct spi_device *spi)
struct iio_dev *idev;
int ret = 0;
- idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!idev)
- return -ENOMEM;
+ idev = iio_device_alloc(sizeof(*st));
+ if (idev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
spi_set_drvdata(spi, idev);
st = iio_priv(idev);
mutex_init(&st->lock);
@@ -94,18 +96,24 @@ static int ad9850_probe(struct spi_device *spi)
ret = iio_device_register(idev);
if (ret)
- return ret;
+ goto error_free_dev;
spi->max_speed_hz = 2000000;
spi->mode = SPI_MODE_3;
spi->bits_per_word = 16;
spi_setup(spi);
return 0;
+
+error_free_dev:
+ iio_device_free(idev);
+error_ret:
+ return ret;
}
static int ad9850_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
+ iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9852.c b/drivers/staging/iio/frequency/ad9852.c
index 11e4367..1344031 100644
--- a/drivers/staging/iio/frequency/ad9852.c
+++ b/drivers/staging/iio/frequency/ad9852.c
@@ -67,6 +67,7 @@ static ssize_t ad9852_set_parameter(struct device *dev,
const char *buf,
size_t len)
{
+ struct spi_message msg;
struct spi_transfer xfer;
int ret;
struct ad9852_config *config = (struct ad9852_config *)buf;
@@ -77,77 +78,99 @@ static ssize_t ad9852_set_parameter(struct device *dev,
xfer.tx_buf = &config->phajst0[0];
mutex_lock(&st->lock);
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 3;
xfer.tx_buf = &config->phajst1[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 6;
xfer.tx_buf = &config->fretun1[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 6;
xfer.tx_buf = &config->fretun2[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 6;
xfer.tx_buf = &config->dltafre[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->updtclk[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 4;
xfer.tx_buf = &config->ramprat[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->control[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 3;
xfer.tx_buf = &config->outpskm[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 2;
xfer.tx_buf = &config->outpskr[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 3;
xfer.tx_buf = &config->daccntl[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
error_ret:
@@ -206,9 +229,11 @@ static int ad9852_probe(struct spi_device *spi)
struct iio_dev *idev;
int ret = 0;
- idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!idev)
- return -ENOMEM;
+ idev = iio_device_alloc(sizeof(*st));
+ if (idev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
st = iio_priv(idev);
spi_set_drvdata(spi, idev);
mutex_init(&st->lock);
@@ -220,7 +245,7 @@ static int ad9852_probe(struct spi_device *spi)
ret = iio_device_register(idev);
if (ret)
- return ret;
+ goto error_free_dev;
spi->max_speed_hz = 2000000;
spi->mode = SPI_MODE_3;
spi->bits_per_word = 8;
@@ -228,11 +253,18 @@ static int ad9852_probe(struct spi_device *spi)
ad9852_init(st);
return 0;
+
+error_free_dev:
+ iio_device_free(idev);
+
+error_ret:
+ return ret;
}
static int ad9852_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
+ iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9910.c b/drivers/staging/iio/frequency/ad9910.c
index 755e048..e48f874 100644
--- a/drivers/staging/iio/frequency/ad9910.c
+++ b/drivers/staging/iio/frequency/ad9910.c
@@ -119,6 +119,7 @@ static ssize_t ad9910_set_parameter(struct device *dev,
const char *buf,
size_t len)
{
+ struct spi_message msg;
struct spi_transfer xfer;
int ret;
struct ad9910_config *config = (struct ad9910_config *)buf;
@@ -129,118 +130,152 @@ static ssize_t ad9910_set_parameter(struct device *dev,
xfer.tx_buf = &config->auxdac[0];
mutex_lock(&st->lock);
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->ioupd[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->ftw[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 3;
xfer.tx_buf = &config->pow[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->asf[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->multc[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->dig_rampl[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->dig_ramps[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->dig_rampr[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep0[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep1[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep2[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep3[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep4[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep5[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep6[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 9;
xfer.tx_buf = &config->sin_tonep7[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
error_ret:
@@ -253,6 +288,7 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0);
static void ad9910_init(struct ad9910_state *st)
{
+ struct spi_message msg;
struct spi_transfer xfer;
int ret;
u8 cfr[5];
@@ -268,7 +304,9 @@ static void ad9910_init(struct ad9910_state *st)
xfer.len = 5;
xfer.tx_buf = &cfr;
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
@@ -281,7 +319,9 @@ static void ad9910_init(struct ad9910_state *st)
xfer.len = 5;
xfer.tx_buf = &cfr;
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
@@ -294,7 +334,9 @@ static void ad9910_init(struct ad9910_state *st)
xfer.len = 5;
xfer.tx_buf = &cfr;
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
@@ -325,9 +367,11 @@ static int ad9910_probe(struct spi_device *spi)
struct iio_dev *idev;
int ret = 0;
- idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!idev)
- return -ENOMEM;
+ idev = iio_device_alloc(sizeof(*st));
+ if (idev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
spi_set_drvdata(spi, idev);
st = iio_priv(idev);
mutex_init(&st->lock);
@@ -339,18 +383,24 @@ static int ad9910_probe(struct spi_device *spi)
ret = iio_device_register(idev);
if (ret)
- return ret;
+ goto error_free_dev;
spi->max_speed_hz = 2000000;
spi->mode = SPI_MODE_3;
spi->bits_per_word = 8;
spi_setup(spi);
ad9910_init(st);
return 0;
+
+error_free_dev:
+ iio_device_free(idev);
+error_ret:
+ return ret;
}
static int ad9910_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
+ iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/frequency/ad9951.c b/drivers/staging/iio/frequency/ad9951.c
index 5e8990a..8234e3c 100644
--- a/drivers/staging/iio/frequency/ad9951.c
+++ b/drivers/staging/iio/frequency/ad9951.c
@@ -60,6 +60,7 @@ static ssize_t ad9951_set_parameter(struct device *dev,
const char *buf,
size_t len)
{
+ struct spi_message msg;
struct spi_transfer xfer;
int ret;
struct ad9951_config *config = (struct ad9951_config *)buf;
@@ -70,28 +71,36 @@ static ssize_t ad9951_set_parameter(struct device *dev,
xfer.tx_buf = &config->asf[0];
mutex_lock(&st->lock);
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 2;
xfer.tx_buf = &config->arr[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 5;
xfer.tx_buf = &config->ftw0[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
xfer.len = 3;
xfer.tx_buf = &config->ftw1[0];
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
error_ret:
@@ -104,6 +113,7 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0);
static void ad9951_init(struct ad9951_state *st)
{
+ struct spi_message msg;
struct spi_transfer xfer;
int ret;
u8 cfr[5];
@@ -119,7 +129,9 @@ static void ad9951_init(struct ad9951_state *st)
xfer.len = 5;
xfer.tx_buf = &cfr;
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
@@ -131,7 +143,9 @@ static void ad9951_init(struct ad9951_state *st)
xfer.len = 4;
xfer.tx_buf = &cfr;
- ret = spi_sync_transfer(st->sdev, &xfer, 1);
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+ ret = spi_sync(st->sdev, &msg);
if (ret)
goto error_ret;
@@ -162,9 +176,11 @@ static int ad9951_probe(struct spi_device *spi)
struct iio_dev *idev;
int ret = 0;
- idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!idev)
- return -ENOMEM;
+ idev = iio_device_alloc(sizeof(*st));
+ if (idev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
spi_set_drvdata(spi, idev);
st = iio_priv(idev);
mutex_init(&st->lock);
@@ -177,18 +193,25 @@ static int ad9951_probe(struct spi_device *spi)
ret = iio_device_register(idev);
if (ret)
- return ret;
+ goto error_free_dev;
spi->max_speed_hz = 2000000;
spi->mode = SPI_MODE_3;
spi->bits_per_word = 8;
spi_setup(spi);
ad9951_init(st);
return 0;
+
+error_free_dev:
+ iio_device_free(idev);
+
+error_ret:
+ return ret;
}
static int ad9951_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
+ iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index 1fac989..0e8e02a 100644
--- a/drivers/staging/iio/iio_simple_dummy.c
+++ b/drivers/staging/iio/iio_simple_dummy.c
@@ -57,20 +57,6 @@ static const struct iio_dummy_accel_calibscale dummy_scales[] = {
{ 733, 13, 0x9 }, /* 733.000013 */
};
-#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-
-/*
- * simple event - triggered when value rises above
- * a threshold
- */
-static const struct iio_event_spec iio_dummy_event = {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_RISING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
-};
-
-#endif
-
/*
* iio_dummy_channels - Description of available channels
*
@@ -104,11 +90,6 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
* when converting to standard units (microvolts)
*/
BIT(IIO_CHAN_INFO_SCALE),
- /*
- * sampling_frequency
- * The frequency in Hz at which the channels are sampled
- */
- .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
/* The ordering of elements in the buffer via an enum */
.scan_index = voltage0,
.scan_type = { /* Description of storage in buffer */
@@ -118,8 +99,12 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
.shift = 0, /* zero shift */
},
#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
- .event_spec = &iio_dummy_event,
- .num_event_specs = 1,
+ /*
+ * simple event - triggered when value rises above
+ * a threshold
+ */
+ .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH,
+ IIO_EV_DIR_RISING),
#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
},
/* Differential ADC channel in_voltage1-voltage2_raw etc*/
@@ -145,10 +130,6 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
* input channels of type IIO_VOLTAGE.
*/
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
- /*
- * sampling_frequency
- * The frequency in Hz at which the channels are sampled
- */
.scan_index = diffvoltage1m2,
.scan_type = { /* Description of storage in buffer */
.sign = 's', /* signed */
@@ -166,7 +147,6 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
.channel2 = 4,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
- .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.scan_index = diffvoltage3m4,
.scan_type = {
.sign = 's',
@@ -193,7 +173,6 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
*/
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS),
- .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.scan_index = accelx,
.scan_type = { /* Description of storage in buffer */
.sign = 's', /* signed */
@@ -293,11 +272,6 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
*val2 = st->accel_calibscale->val2;
ret = IIO_VAL_INT_PLUS_MICRO;
break;
- case IIO_CHAN_INFO_SAMP_FREQ:
- *val = 3;
- *val2 = 33;
- ret = IIO_VAL_INT_PLUS_NANO;
- break;
default:
break;
}
@@ -370,10 +344,10 @@ static const struct iio_info iio_dummy_info = {
.read_raw = &iio_dummy_read_raw,
.write_raw = &iio_dummy_write_raw,
#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
- .read_event_config_new = &iio_simple_dummy_read_event_config,
- .write_event_config_new = &iio_simple_dummy_write_event_config,
- .read_event_value_new = &iio_simple_dummy_read_event_value,
- .write_event_value_new = &iio_simple_dummy_write_event_value,
+ .read_event_config = &iio_simple_dummy_read_event_config,
+ .write_event_config = &iio_simple_dummy_write_event_config,
+ .read_event_value = &iio_simple_dummy_read_event_value,
+ .write_event_value = &iio_simple_dummy_write_event_value,
#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
};
@@ -480,8 +454,7 @@ static int iio_dummy_probe(int index)
* buffer, but avoid the output channel being registered by reducing the
* number of channels by 1.
*/
- ret = iio_simple_dummy_configure_buffer(indio_dev,
- iio_dummy_channels, 5);
+ ret = iio_simple_dummy_configure_buffer(indio_dev, iio_dummy_channels, 5);
if (ret < 0)
goto error_unregister_events;
diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/staging/iio/iio_simple_dummy.h
index b126196..c9e8702 100644
--- a/drivers/staging/iio/iio_simple_dummy.h
+++ b/drivers/staging/iio/iio_simple_dummy.h
@@ -45,29 +45,19 @@ struct iio_dummy_state {
struct iio_dev;
int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir);
+ u64 event_code);
int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
+ u64 event_code,
int state);
int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info, int *val,
- int *val2);
+ u64 event_code,
+ int *val);
int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info, int val,
- int val2);
+ u64 event_code,
+ int val);
int iio_simple_dummy_events_register(struct iio_dev *indio_dev);
int iio_simple_dummy_events_unregister(struct iio_dev *indio_dev);
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index 46c134b..72f400c 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -82,8 +82,11 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
len += 2;
}
}
-
- iio_push_to_buffers_with_timestamp(indio_dev, data, iio_get_time_ns());
+ /* Store the timestamp at an 8 byte aligned offset */
+ if (indio_dev->scan_timestamp)
+ *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
+ = iio_get_time_ns();
+ iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data);
@@ -99,6 +102,14 @@ done:
static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = {
/*
+ * iio_sw_buffer_preenable:
+ * Generic function for equal sized ring elements + 64 bit timestamp
+ * Assumes that any combination of channels can be enabled.
+ * Typically replaced to implement restrictions on what combinations
+ * can be captured (hardware scan modes).
+ */
+ .preenable = &iio_sw_buffer_preenable,
+ /*
* iio_triggered_buffer_postenable:
* Generic function that simply attaches the pollfunc to the trigger.
* Replace this to mess with hardware state before we attach the
@@ -127,7 +138,7 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
goto error_ret;
}
- iio_device_attach_buffer(indio_dev, buffer);
+ indio_dev->buffer = buffer;
/* Enable timestamps by default */
buffer->scan_timestamp = true;
diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/staging/iio/iio_simple_dummy_events.c
index 812ebd0..317b774 100644
--- a/drivers/staging/iio/iio_simple_dummy_events.c
+++ b/drivers/staging/iio/iio_simple_dummy_events.c
@@ -23,17 +23,13 @@
/**
* iio_simple_dummy_read_event_config() - is event enabled?
* @indio_dev: the device instance data
- * @chan: channel for the event whose state is being queried
- * @type: type of the event whose state is being queried
- * @dir: direction of the vent whose state is being queried
+ * @event_code: event code of the event being queried
*
* This function would normally query the relevant registers or a cache to
* discover if the event generation is enabled on the device.
*/
int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir)
+ u64 event_code)
{
struct iio_dummy_state *st = iio_priv(indio_dev);
@@ -43,9 +39,7 @@ int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
/**
* iio_simple_dummy_write_event_config() - set whether event is enabled
* @indio_dev: the device instance data
- * @chan: channel for the event whose state is being set
- * @type: type of the event whose state is being set
- * @dir: direction of the vent whose state is being set
+ * @event_code: event code of event being enabled/disabled
* @state: whether to enable or disable the device.
*
* This function would normally set the relevant registers on the devices
@@ -53,9 +47,7 @@ int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
* value.
*/
int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
+ u64 event_code,
int state)
{
struct iio_dummy_state *st = iio_priv(indio_dev);
@@ -64,11 +56,12 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
* Deliberately over the top code splitting to illustrate
* how this is done when multiple events exist.
*/
- switch (chan->type) {
+ switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
case IIO_VOLTAGE:
- switch (type) {
+ switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
case IIO_EV_TYPE_THRESH:
- if (dir == IIO_EV_DIR_RISING)
+ if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+ IIO_EV_DIR_RISING)
st->event_en = state;
else
return -EINVAL;
@@ -86,10 +79,7 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
/**
* iio_simple_dummy_read_event_value() - get value associated with event
* @indio_dev: device instance specific data
- * @chan: channel for the event whose value is being read
- * @type: type of the event whose value is being read
- * @dir: direction of the vent whose value is being read
- * @info: info type of the event whose value is being read
+ * @event_code: event code for the event whose value is being queried
* @val: value for the event code.
*
* Many devices provide a large set of events of which only a subset may
@@ -99,34 +89,25 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
* the enabled event is changed.
*/
int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int *val, int *val2)
+ u64 event_code,
+ int *val)
{
struct iio_dummy_state *st = iio_priv(indio_dev);
*val = st->event_val;
- return IIO_VAL_INT;
+ return 0;
}
/**
* iio_simple_dummy_write_event_value() - set value associate with event
* @indio_dev: device instance specific data
- * @chan: channel for the event whose value is being set
- * @type: type of the event whose value is being set
- * @dir: direction of the vent whose value is being set
- * @info: info type of the event whose value is being set
+ * @event_code: event code for the event whose value is being set
* @val: the value to be set.
*/
int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int val, int val2)
+ u64 event_code,
+ int val)
{
struct iio_dummy_state *st = iio_priv(indio_dev);
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 0a4298b..6330af6 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -323,10 +323,10 @@ static ssize_t ad5933_store_frequency(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad5933_state *st = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- unsigned long val;
+ long val;
int ret;
- ret = kstrtoul(buf, 10, &val);
+ ret = strict_strtoul(buf, 10, &val);
if (ret)
return ret;
@@ -400,12 +400,12 @@ static ssize_t ad5933_store(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad5933_state *st = iio_priv(indio_dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- u16 val;
+ long val;
int i, ret = 0;
unsigned short dat;
if (this_attr->address != AD5933_IN_PGA_GAIN) {
- ret = kstrtou16(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
return ret;
}
@@ -434,7 +434,7 @@ static ssize_t ad5933_store(struct device *dev,
ret = ad5933_cmd(st, 0);
break;
case AD5933_OUT_SETTLING_CYCLES:
- val = clamp(val, (u16)0, (u16)0x7FF);
+ val = clamp(val, 0L, 0x7FFL);
st->settling_cycles = val;
/* 2x, 4x handling, see datasheet */
@@ -448,7 +448,7 @@ static ssize_t ad5933_store(struct device *dev,
AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat);
break;
case AD5933_FREQ_POINTS:
- val = clamp(val, (u16)0, (u16)511);
+ val = clamp(val, 0L, 511L);
st->freq_points = val;
dat = cpu_to_be16(val);
@@ -574,6 +574,10 @@ static int ad5933_ring_preenable(struct iio_dev *indio_dev)
if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
+ ret = iio_sw_buffer_preenable(indio_dev);
+ if (ret < 0)
+ return ret;
+
ret = ad5933_reset(st);
if (ret < 0)
return ret;
@@ -626,14 +630,10 @@ static const struct iio_buffer_setup_ops ad5933_ring_setup_ops = {
static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
{
- struct iio_buffer *buffer;
-
- buffer = iio_kfifo_allocate(indio_dev);
- if (buffer)
+ indio_dev->buffer = iio_kfifo_allocate(indio_dev);
+ if (!indio_dev->buffer)
return -ENOMEM;
- iio_device_attach_buffer(indio_dev, buffer);
-
/* Ring buffer functions - here trigger setup related */
indio_dev->setup_ops = &ad5933_ring_setup_ops;
@@ -676,7 +676,7 @@ static void ad5933_work(struct work_struct *work)
} else {
buf[0] = be16_to_cpu(buf[0]);
}
- iio_push_to_buffers(indio_dev, buf);
+ iio_push_to_buffers(indio_dev, (u8 *)buf);
} else {
/* no data available - try again later */
schedule_delayed_work(&st->work, st->poll_time_jiffies);
@@ -703,9 +703,7 @@ static int ad5933_probe(struct i2c_client *client,
int ret, voltage_uv = 0;
struct ad5933_platform_data *pdata = client->dev.platform_data;
struct ad5933_state *st;
- struct iio_dev *indio_dev;
-
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
+ struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@@ -718,11 +716,11 @@ static int ad5933_probe(struct i2c_client *client,
else
st->pdata = pdata;
- st->reg = devm_regulator_get(&client->dev, "vcc");
+ st->reg = regulator_get(&client->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
- return ret;
+ goto error_put_reg;
voltage_uv = regulator_get_voltage(st->reg);
}
@@ -780,6 +778,11 @@ error_unreg_ring:
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
+error_put_reg:
+ if (!IS_ERR(st->reg))
+ regulator_put(st->reg);
+
+ iio_device_free(indio_dev);
return ret;
}
@@ -792,8 +795,11 @@ static int ad5933_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
iio_buffer_unregister(indio_dev);
iio_kfifo_free(indio_dev->buffer);
- if (!IS_ERR(st->reg))
+ if (!IS_ERR(st->reg)) {
regulator_disable(st->reg);
+ regulator_put(st->reg);
+ }
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
index 488e690..e4998e4 100644
--- a/drivers/staging/iio/light/isl29018.c
+++ b/drivers/staging/iio/light/isl29018.c
@@ -240,7 +240,7 @@ static ssize_t store_range(struct device *dev,
unsigned long lval;
unsigned int new_range;
- if (kstrtoul(buf, 10, &lval))
+ if (strict_strtoul(buf, 10, &lval))
return -EINVAL;
if (!(lval == 1000UL || lval == 4000UL ||
@@ -279,18 +279,18 @@ static ssize_t store_resolution(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct isl29018_chip *chip = iio_priv(indio_dev);
int status;
- unsigned int val;
+ unsigned long lval;
unsigned int new_adc_bit;
- if (kstrtouint(buf, 10, &val))
+ if (strict_strtoul(buf, 10, &lval))
return -EINVAL;
- if (!(val == 4 || val == 8 || val == 12 || val == 16)) {
+ if (!(lval == 4 || lval == 8 || lval == 12 || lval == 16)) {
dev_err(dev, "The resolution is not supported\n");
return -EINVAL;
}
mutex_lock(&chip->lock);
- status = isl29018_set_resolution(chip, val, &new_adc_bit);
+ status = isl29018_set_resolution(chip, lval, &new_adc_bit);
if (status < 0) {
mutex_unlock(&chip->lock);
dev_err(dev, "Error in setting resolution\n");
@@ -319,11 +319,11 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct isl29018_chip *chip = iio_priv(indio_dev);
- int val;
+ unsigned long lval;
- if (kstrtoint(buf, 10, &val))
+ if (strict_strtoul(buf, 10, &lval))
return -EINVAL;
- if (!(val == 0 || val == 1)) {
+ if (!(lval == 0UL || lval == 1UL)) {
dev_err(dev, "The mode is not supported\n");
return -EINVAL;
}
@@ -331,7 +331,7 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
/* get the "proximity scheme" i.e. if the chip does on chip
infrared suppression (1 means perform on chip suppression) */
mutex_lock(&chip->lock);
- chip->prox_scheme = val;
+ chip->prox_scheme = (int)lval;
mutex_unlock(&chip->lock);
return count;
diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c
index f8c6595..b377dd3 100644
--- a/drivers/staging/iio/light/tsl2583.c
+++ b/drivers/staging/iio/light/tsl2583.c
@@ -493,9 +493,9 @@ static ssize_t taos_power_state_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- int value;
+ unsigned long value;
- if (kstrtoint(buf, 0, &value))
+ if (strict_strtoul(buf, 0, &value))
return -EINVAL;
if (value == 0)
@@ -536,9 +536,9 @@ static ssize_t taos_gain_store(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
- int value;
+ unsigned long value;
- if (kstrtoint(buf, 0, &value))
+ if (strict_strtoul(buf, 0, &value))
return -EINVAL;
switch (value) {
@@ -582,9 +582,9 @@ static ssize_t taos_als_time_store(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
- int value;
+ unsigned long value;
- if (kstrtoint(buf, 0, &value))
+ if (strict_strtoul(buf, 0, &value))
return -EINVAL;
if ((value < 50) || (value > 650))
@@ -619,9 +619,9 @@ static ssize_t taos_als_trim_store(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
- int value;
+ unsigned long value;
- if (kstrtoint(buf, 0, &value))
+ if (strict_strtoul(buf, 0, &value))
return -EINVAL;
if (value)
@@ -644,9 +644,9 @@ static ssize_t taos_als_cal_target_store(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tsl2583_chip *chip = iio_priv(indio_dev);
- int value;
+ unsigned long value;
- if (kstrtoint(buf, 0, &value))
+ if (strict_strtoul(buf, 0, &value))
return -EINVAL;
if (value)
@@ -671,9 +671,9 @@ static ssize_t taos_do_calibrate(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- int value;
+ unsigned long value;
- if (kstrtoint(buf, 0, &value))
+ if (strict_strtoul(buf, 0, &value))
return -EINVAL;
if (value == 1)
@@ -815,9 +815,12 @@ static int taos_probe(struct i2c_client *clientp,
return -EOPNOTSUPP;
}
- indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
- if (!indio_dev)
- return -ENOMEM;
+ indio_dev = iio_device_alloc(sizeof(*chip));
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ dev_err(&clientp->dev, "iio allocation failed\n");
+ goto fail1;
+ }
chip = iio_priv(indio_dev);
chip->client = clientp;
i2c_set_clientdata(clientp, indio_dev);
@@ -832,14 +835,14 @@ static int taos_probe(struct i2c_client *clientp,
if (ret < 0) {
dev_err(&clientp->dev, "i2c_smbus_write_bytes() to cmd "
"reg failed in taos_probe(), err = %d\n", ret);
- return ret;
+ goto fail2;
}
ret = i2c_smbus_read_byte(clientp);
if (ret < 0) {
dev_err(&clientp->dev, "i2c_smbus_read_byte from "
"reg failed in taos_probe(), err = %d\n", ret);
- return ret;
+ goto fail2;
}
buf[i] = ret;
}
@@ -847,14 +850,14 @@ static int taos_probe(struct i2c_client *clientp,
if (!taos_tsl258x_device(buf)) {
dev_info(&clientp->dev, "i2c device found but does not match "
"expected id in taos_probe()\n");
- return -EINVAL;
+ goto fail2;
}
ret = i2c_smbus_write_byte(clientp, (TSL258X_CMD_REG | TSL258X_CNTRL));
if (ret < 0) {
dev_err(&clientp->dev, "i2c_smbus_write_byte() to cmd reg "
"failed in taos_probe(), err = %d\n", ret);
- return ret;
+ goto fail2;
}
indio_dev->info = &tsl2583_info;
@@ -864,7 +867,7 @@ static int taos_probe(struct i2c_client *clientp,
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(&clientp->dev, "iio registration failed\n");
- return ret;
+ goto fail2;
}
/* Load up the V2 defaults (these are hard coded defaults for now) */
@@ -875,6 +878,10 @@ static int taos_probe(struct i2c_client *clientp,
dev_info(&clientp->dev, "Light sensor found.\n");
return 0;
+fail1:
+ iio_device_free(indio_dev);
+fail2:
+ return ret;
}
#ifdef CONFIG_PM_SLEEP
@@ -919,6 +926,7 @@ static SIMPLE_DEV_PM_OPS(taos_pm_ops, taos_suspend, taos_resume);
static int taos_remove(struct i2c_client *client)
{
iio_device_unregister(i2c_get_clientdata(client));
+ iio_device_free(i2c_get_clientdata(client));
return 0;
}
diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c
index 1880502..c99f890 100644
--- a/drivers/staging/iio/light/tsl2x7x_core.c
+++ b/drivers/staging/iio/light/tsl2x7x_core.c
@@ -124,6 +124,11 @@
#define TSL2X7X_mA13 0xD0
#define TSL2X7X_MAX_TIMER_CNT (0xFF)
+/*Common device IIO EventMask */
+#define TSL2X7X_EVENT_MASK \
+ (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
+ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)),
+
#define TSL2X7X_MIN_ITIME 3
/* TAOS txx2x7x Device family members */
@@ -545,7 +550,7 @@ prox_poll_err:
static void tsl2x7x_defaults(struct tsl2X7X_chip *chip)
{
/* If Operational settings defined elsewhere.. */
- if (chip->pdata && chip->pdata->platform_default_settings)
+ if (chip->pdata && chip->pdata->platform_default_settings != 0)
memcpy(&(chip->tsl2x7x_settings),
chip->pdata->platform_default_settings,
sizeof(tsl2x7x_default_settings));
@@ -946,6 +951,7 @@ static ssize_t tsl2x7x_gain_available_show(struct device *dev,
case tsl2771:
case tmd2771:
return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 128");
+ break;
}
return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120");
@@ -1217,14 +1223,12 @@ static ssize_t tsl2x7x_do_prox_calibrate(struct device *dev,
}
static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir)
+ u64 event_code)
{
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
int ret;
- if (chan->type == IIO_INTENSITY)
+ if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY)
ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x10);
else
ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x20);
@@ -1233,14 +1237,12 @@ static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
}
static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
+ u64 event_code,
int val)
{
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
- if (chan->type == IIO_INTENSITY) {
+ if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
if (val)
chip->tsl2x7x_settings.interrupts_en |= 0x10;
else
@@ -1258,16 +1260,13 @@ static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
}
static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int val, int val2)
+ u64 event_code,
+ int val)
{
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
- if (chan->type == IIO_INTENSITY) {
- switch (dir) {
+ if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
+ switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
case IIO_EV_DIR_RISING:
chip->tsl2x7x_settings.als_thresh_high = val;
break;
@@ -1278,7 +1277,7 @@ static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
return -EINVAL;
}
} else {
- switch (dir) {
+ switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
case IIO_EV_DIR_RISING:
chip->tsl2x7x_settings.prox_thres_high = val;
break;
@@ -1296,16 +1295,13 @@ static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
}
static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
- const struct iio_chan_spec *chan,
- enum iio_event_type type,
- enum iio_event_direction dir,
- enum iio_event_info info,
- int *val, int *val2)
+ u64 event_code,
+ int *val)
{
struct tsl2X7X_chip *chip = iio_priv(indio_dev);
- if (chan->type == IIO_INTENSITY) {
- switch (dir) {
+ if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
+ switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
case IIO_EV_DIR_RISING:
*val = chip->tsl2x7x_settings.als_thresh_high;
break;
@@ -1316,7 +1312,7 @@ static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
return -EINVAL;
}
} else {
- switch (dir) {
+ switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
case IIO_EV_DIR_RISING:
*val = chip->tsl2x7x_settings.prox_thres_high;
break;
@@ -1328,7 +1324,7 @@ static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
}
}
- return IIO_VAL_INT;
+ return 0;
}
static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
@@ -1350,6 +1346,7 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
break;
default:
return -EINVAL;
+ break;
}
break;
case IIO_CHAN_INFO_RAW:
@@ -1369,6 +1366,7 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
break;
default:
return -EINVAL;
+ break;
}
break;
case IIO_CHAN_INFO_CALIBSCALE:
@@ -1421,6 +1419,7 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
case tsl2772:
case tmd2772:
return -EINVAL;
+ break;
}
chip->tsl2x7x_settings.als_gain = 3;
break;
@@ -1432,6 +1431,7 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
case tsl2771:
case tmd2771:
return -EINVAL;
+ break;
}
chip->tsl2x7x_settings.als_gain = 3;
break;
@@ -1508,15 +1508,18 @@ static int tsl2x7x_device_id(unsigned char *id, int target)
case tsl2671:
case tsl2771:
return ((*id & 0xf0) == TRITON_ID);
+ break;
case tmd2671:
case tmd2771:
return ((*id & 0xf0) == HALIBUT_ID);
+ break;
case tsl2572:
case tsl2672:
case tmd2672:
case tsl2772:
case tmd2772:
return ((*id & 0xf0) == SWORDFISH_ID);
+ break;
}
return -EINVAL;
@@ -1672,10 +1675,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
.driver_module = THIS_MODULE,
.read_raw = &tsl2x7x_read_raw,
.write_raw = &tsl2x7x_write_raw,
- .read_event_value_new = &tsl2x7x_read_thresh,
- .write_event_value_new = &tsl2x7x_write_thresh,
- .read_event_config_new = &tsl2x7x_read_interrupt_config,
- .write_event_config_new = &tsl2x7x_write_interrupt_config,
+ .read_event_value = &tsl2x7x_read_thresh,
+ .write_event_value = &tsl2x7x_write_thresh,
+ .read_event_config = &tsl2x7x_read_interrupt_config,
+ .write_event_config = &tsl2x7x_write_interrupt_config,
},
[PRX] = {
.attrs = &tsl2X7X_device_attr_group_tbl[PRX],
@@ -1683,10 +1686,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
.driver_module = THIS_MODULE,
.read_raw = &tsl2x7x_read_raw,
.write_raw = &tsl2x7x_write_raw,
- .read_event_value_new = &tsl2x7x_read_thresh,
- .write_event_value_new = &tsl2x7x_write_thresh,
- .read_event_config_new = &tsl2x7x_read_interrupt_config,
- .write_event_config_new = &tsl2x7x_write_interrupt_config,
+ .read_event_value = &tsl2x7x_read_thresh,
+ .write_event_value = &tsl2x7x_write_thresh,
+ .read_event_config = &tsl2x7x_read_interrupt_config,
+ .write_event_config = &tsl2x7x_write_interrupt_config,
},
[ALSPRX] = {
.attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX],
@@ -1694,10 +1697,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
.driver_module = THIS_MODULE,
.read_raw = &tsl2x7x_read_raw,
.write_raw = &tsl2x7x_write_raw,
- .read_event_value_new = &tsl2x7x_read_thresh,
- .write_event_value_new = &tsl2x7x_write_thresh,
- .read_event_config_new = &tsl2x7x_read_interrupt_config,
- .write_event_config_new = &tsl2x7x_write_interrupt_config,
+ .read_event_value = &tsl2x7x_read_thresh,
+ .write_event_value = &tsl2x7x_write_thresh,
+ .read_event_config = &tsl2x7x_read_interrupt_config,
+ .write_event_config = &tsl2x7x_write_interrupt_config,
},
[PRX2] = {
.attrs = &tsl2X7X_device_attr_group_tbl[PRX2],
@@ -1705,10 +1708,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
.driver_module = THIS_MODULE,
.read_raw = &tsl2x7x_read_raw,
.write_raw = &tsl2x7x_write_raw,
- .read_event_value_new = &tsl2x7x_read_thresh,
- .write_event_value_new = &tsl2x7x_write_thresh,
- .read_event_config_new = &tsl2x7x_read_interrupt_config,
- .write_event_config_new = &tsl2x7x_write_interrupt_config,
+ .read_event_value = &tsl2x7x_read_thresh,
+ .write_event_value = &tsl2x7x_write_thresh,
+ .read_event_config = &tsl2x7x_read_interrupt_config,
+ .write_event_config = &tsl2x7x_write_interrupt_config,
},
[ALSPRX2] = {
.attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX2],
@@ -1716,24 +1719,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
.driver_module = THIS_MODULE,
.read_raw = &tsl2x7x_read_raw,
.write_raw = &tsl2x7x_write_raw,
- .read_event_value_new = &tsl2x7x_read_thresh,
- .write_event_value_new = &tsl2x7x_write_thresh,
- .read_event_config_new = &tsl2x7x_read_interrupt_config,
- .write_event_config_new = &tsl2x7x_write_interrupt_config,
- },
-};
-
-static const struct iio_event_spec tsl2x7x_events[] = {
- {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_RISING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
- BIT(IIO_EV_INFO_ENABLE),
- }, {
- .type = IIO_EV_TYPE_THRESH,
- .dir = IIO_EV_DIR_FALLING,
- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
- BIT(IIO_EV_INFO_ENABLE),
+ .read_event_value = &tsl2x7x_read_thresh,
+ .write_event_value = &tsl2x7x_write_thresh,
+ .read_event_config = &tsl2x7x_read_interrupt_config,
+ .write_event_config = &tsl2x7x_write_interrupt_config,
},
};
@@ -1752,8 +1741,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS),
- .event_spec = tsl2x7x_events,
- .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+ .event_mask = TSL2X7X_EVENT_MASK
}, {
.type = IIO_INTENSITY,
.indexed = 1,
@@ -1770,8 +1758,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.indexed = 1,
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- .event_spec = tsl2x7x_events,
- .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+ .event_mask = TSL2X7X_EVENT_MASK
},
},
.chan_table_elements = 1,
@@ -1791,8 +1778,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS),
- .event_spec = tsl2x7x_events,
- .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+ .event_mask = TSL2X7X_EVENT_MASK
}, {
.type = IIO_INTENSITY,
.indexed = 1,
@@ -1803,8 +1789,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.indexed = 1,
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- .event_spec = tsl2x7x_events,
- .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+ .event_mask = TSL2X7X_EVENT_MASK
},
},
.chan_table_elements = 4,
@@ -1818,8 +1803,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE),
- .event_spec = tsl2x7x_events,
- .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+ .event_mask = TSL2X7X_EVENT_MASK
},
},
.chan_table_elements = 1,
@@ -1839,8 +1823,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE) |
BIT(IIO_CHAN_INFO_CALIBBIAS),
- .event_spec = tsl2x7x_events,
- .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+ .event_mask = TSL2X7X_EVENT_MASK
}, {
.type = IIO_INTENSITY,
.indexed = 1,
@@ -1852,8 +1835,7 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBSCALE),
- .event_spec = tsl2x7x_events,
- .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
+ .event_mask = TSL2X7X_EVENT_MASK
},
},
.chan_table_elements = 4,
@@ -1869,7 +1851,7 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
struct iio_dev *indio_dev;
struct tsl2X7X_chip *chip;
- indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
+ indio_dev = iio_device_alloc(sizeof(*chip));
if (!indio_dev)
return -ENOMEM;
@@ -1880,21 +1862,22 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
ret = tsl2x7x_i2c_read(chip->client,
TSL2X7X_CHIPID, &device_id);
if (ret < 0)
- return ret;
+ goto fail1;
if ((!tsl2x7x_device_id(&device_id, id->driver_data)) ||
(tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) {
dev_info(&chip->client->dev,
"%s: i2c device found does not match expected id\n",
__func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto fail1;
}
ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
if (ret < 0) {
dev_err(&clientp->dev, "%s: write to cmd reg failed. err = %d\n",
__func__, ret);
- return ret;
+ goto fail1;
}
/* ALS and PROX functions can be invoked via user space poll
@@ -1916,17 +1899,16 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
indio_dev->num_channels = chip->chip_info->chan_table_elements;
if (clientp->irq) {
- ret = devm_request_threaded_irq(&clientp->dev, clientp->irq,
- NULL,
- &tsl2x7x_event_handler,
- IRQF_TRIGGER_RISING |
- IRQF_ONESHOT,
- "TSL2X7X_event",
- indio_dev);
+ ret = request_threaded_irq(clientp->irq,
+ NULL,
+ &tsl2x7x_event_handler,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ "TSL2X7X_event",
+ indio_dev);
if (ret) {
dev_err(&clientp->dev,
"%s: irq request failed", __func__);
- return ret;
+ goto fail1;
}
}
@@ -1939,12 +1921,20 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
if (ret) {
dev_err(&clientp->dev,
"%s: iio registration failed\n", __func__);
- return ret;
+ goto fail2;
}
dev_info(&clientp->dev, "%s Light sensor found.\n", id->name);
return 0;
+
+fail2:
+ if (clientp->irq)
+ free_irq(clientp->irq, indio_dev);
+fail1:
+ iio_device_free(indio_dev);
+
+ return ret;
}
static int tsl2x7x_suspend(struct device *dev)
@@ -1990,6 +1980,10 @@ static int tsl2x7x_remove(struct i2c_client *client)
tsl2x7x_chip_off(indio_dev);
iio_device_unregister(indio_dev);
+ if (client->irq)
+ free_irq(client->irq, indio_dev);
+
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig
index 34634da..a3ea69e 100644
--- a/drivers/staging/iio/magnetometer/Kconfig
+++ b/drivers/staging/iio/magnetometer/Kconfig
@@ -6,8 +6,6 @@ menu "Magnetometer sensors"
config SENSORS_HMC5843
tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer"
depends on I2C
- select IIO_BUFFER
- select IIO_TRIGGERED_BUFFER
help
Say Y here to add support for the Honeywell HMC5843, HMC5883 and
HMC5883L 3-Axis Magnetometer (digital compass).
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index 99421f9..c3f3f53 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -23,17 +23,23 @@
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/triggered_buffer.h>
#include <linux/delay.h>
#define HMC5843_CONFIG_REG_A 0x00
#define HMC5843_CONFIG_REG_B 0x01
#define HMC5843_MODE_REG 0x02
-#define HMC5843_DATA_OUT_MSB_REGS 0x03
+#define HMC5843_DATA_OUT_X_MSB_REG 0x03
+#define HMC5843_DATA_OUT_X_LSB_REG 0x04
+#define HMC5843_DATA_OUT_Y_MSB_REG 0x05
+#define HMC5843_DATA_OUT_Y_LSB_REG 0x06
+#define HMC5843_DATA_OUT_Z_MSB_REG 0x07
+#define HMC5843_DATA_OUT_Z_LSB_REG 0x08
+/* Beware: Y and Z are exchanged on HMC5883 */
+#define HMC5883_DATA_OUT_Z_MSB_REG 0x05
+#define HMC5883_DATA_OUT_Z_LSB_REG 0x06
+#define HMC5883_DATA_OUT_Y_MSB_REG 0x07
+#define HMC5883_DATA_OUT_Y_LSB_REG 0x08
#define HMC5843_STATUS_REG 0x09
-#define HMC5843_ID_REG 0x0a
enum hmc5843_ids {
HMC5843_ID,
@@ -48,13 +54,19 @@ enum hmc5843_ids {
*/
#define HMC5843_RANGE_GAIN_OFFSET 0x05
#define HMC5843_RANGE_GAIN_DEFAULT 0x01
-#define HMC5843_RANGE_GAINS 8
+#define HMC5843_RANGE_GAIN_MAX 0x07
-/* Device status */
+/*
+ * Device status
+ */
#define HMC5843_DATA_READY 0x01
#define HMC5843_DATA_OUTPUT_LOCK 0x02
+/* Does not exist on HMC5883, not used */
+#define HMC5843_VOLTAGE_REGULATOR_ENABLED 0x04
-/* Mode register configuration */
+/*
+ * Mode register configuration
+ */
#define HMC5843_MODE_CONVERSION_CONTINUOUS 0x00
#define HMC5843_MODE_CONVERSION_SINGLE 0x01
#define HMC5843_MODE_IDLE 0x02
@@ -66,29 +78,80 @@ enum hmc5843_ids {
* HMC5883: Typical data output rate
*/
#define HMC5843_RATE_OFFSET 0x02
-#define HMC5843_RATE_DEFAULT 0x04
-#define HMC5843_RATES 7
+#define HMC5843_RATE_BITMASK 0x1C
+#define HMC5843_RATE_NOT_USED 0x07
-/* Device measurement configuration */
+/*
+ * Device measurement configuration
+ */
#define HMC5843_MEAS_CONF_NORMAL 0x00
#define HMC5843_MEAS_CONF_POSITIVE_BIAS 0x01
#define HMC5843_MEAS_CONF_NEGATIVE_BIAS 0x02
+#define HMC5843_MEAS_CONF_NOT_USED 0x03
#define HMC5843_MEAS_CONF_MASK 0x03
-/* Scaling factors: 10000000/Gain */
-static const int hmc5843_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
+/*
+ * Scaling factors: 10000000/Gain
+ */
+static const int hmc5843_regval_to_nanoscale[] = {
6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
};
-static const int hmc5883_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
+static const int hmc5883_regval_to_nanoscale[] = {
7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
};
-static const int hmc5883l_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
+static const int hmc5883l_regval_to_nanoscale[] = {
7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
};
/*
+ * From the HMC5843 datasheet:
+ * Value | Sensor input field range (Ga) | Gain (counts/milli-Gauss)
+ * 0 | (+-)0.7 | 1620
+ * 1 | (+-)1.0 | 1300
+ * 2 | (+-)1.5 | 970
+ * 3 | (+-)2.0 | 780
+ * 4 | (+-)3.2 | 530
+ * 5 | (+-)3.8 | 460
+ * 6 | (+-)4.5 | 390
+ * 7 | (+-)6.5 | 280
+ *
+ * From the HMC5883 datasheet:
+ * Value | Recommended sensor field range (Ga) | Gain (counts/Gauss)
+ * 0 | (+-)0.9 | 1280
+ * 1 | (+-)1.2 | 1024
+ * 2 | (+-)1.9 | 768
+ * 3 | (+-)2.5 | 614
+ * 4 | (+-)4.0 | 415
+ * 5 | (+-)4.6 | 361
+ * 6 | (+-)5.5 | 307
+ * 7 | (+-)7.9 | 219
+ *
+ * From the HMC5883L datasheet:
+ * Value | Recommended sensor field range (Ga) | Gain (LSB/Gauss)
+ * 0 | (+-)0.88 | 1370
+ * 1 | (+-)1.3 | 1090
+ * 2 | (+-)1.9 | 820
+ * 3 | (+-)2.5 | 660
+ * 4 | (+-)4.0 | 440
+ * 5 | (+-)4.7 | 390
+ * 6 | (+-)5.6 | 330
+ * 7 | (+-)8.1 | 230
+ */
+static const int hmc5843_regval_to_input_field_mga[] = {
+ 700, 1000, 1500, 2000, 3200, 3800, 4500, 6500
+};
+
+static const int hmc5883_regval_to_input_field_mga[] = {
+ 900, 1200, 1900, 2500, 4000, 4600, 5500, 7900
+};
+
+static const int hmc5883l_regval_to_input_field_mga[] = {
+ 880, 1300, 1900, 2500, 4000, 4700, 5600, 8100
+};
+
+/*
* From the datasheet:
* Value | HMC5843 | HMC5883/HMC5883L
* | Data output rate (Hz) | Data output rate (Hz)
@@ -101,95 +164,142 @@ static const int hmc5883l_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
* 6 | 50 | 75
* 7 | Not used | Not used
*/
-static const int hmc5843_regval_to_samp_freq[7][2] = {
- {0, 500000}, {1, 0}, {2, 0}, {5, 0}, {10, 0}, {20, 0}, {50, 0}
+static const char * const hmc5843_regval_to_sample_freq[] = {
+ "0.5", "1", "2", "5", "10", "20", "50",
};
-static const int hmc5883_regval_to_samp_freq[7][2] = {
- {0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
- {75, 0}
+static const char * const hmc5883_regval_to_sample_freq[] = {
+ "0.75", "1.5", "3", "7.5", "15", "30", "75",
};
/* Describe chip variants */
struct hmc5843_chip_info {
const struct iio_chan_spec *channels;
- const int (*regval_to_samp_freq)[2];
+ const char * const *regval_to_sample_freq;
+ const int *regval_to_input_field_mga;
const int *regval_to_nanoscale;
};
/* Each client has this additional data */
struct hmc5843_data {
- struct i2c_client *client;
struct mutex lock;
u8 rate;
u8 meas_conf;
u8 operating_mode;
u8 range;
const struct hmc5843_chip_info *variant;
- __be16 buffer[8]; /* 3x 16-bit channels + padding + 64-bit timestamp */
};
/* The lower two bits contain the current conversion mode */
-static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
+static s32 hmc5843_configure(struct i2c_client *client,
+ u8 operating_mode)
{
- int ret;
-
- mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_MODE_REG,
+ return i2c_smbus_write_byte_data(client,
+ HMC5843_MODE_REG,
operating_mode & HMC5843_MODE_MASK);
- if (ret >= 0)
- data->operating_mode = operating_mode;
- mutex_unlock(&data->lock);
-
- return ret;
}
-static int hmc5843_wait_measurement(struct hmc5843_data *data)
+/* Return the measurement value from the specified channel */
+static int hmc5843_read_measurement(struct iio_dev *indio_dev,
+ int address,
+ int *val)
{
+ struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+ struct hmc5843_data *data = iio_priv(indio_dev);
s32 result;
int tries = 150;
+ mutex_lock(&data->lock);
while (tries-- > 0) {
- result = i2c_smbus_read_byte_data(data->client,
+ result = i2c_smbus_read_byte_data(client,
HMC5843_STATUS_REG);
- if (result < 0)
- return result;
if (result & HMC5843_DATA_READY)
break;
msleep(20);
}
if (tries < 0) {
- dev_err(&data->client->dev, "data not ready\n");
+ dev_err(&client->dev, "data not ready\n");
+ mutex_unlock(&data->lock);
return -EIO;
}
- return 0;
+ result = i2c_smbus_read_word_swapped(client, address);
+ mutex_unlock(&data->lock);
+ if (result < 0)
+ return -EINVAL;
+
+ *val = sign_extend32(result, 15);
+ return IIO_VAL_INT;
}
-/* Return the measurement value from the specified channel */
-static int hmc5843_read_measurement(struct hmc5843_data *data,
- int idx, int *val)
+/*
+ * From the datasheet:
+ * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
+ * device continuously performs conversions and places the result in
+ * the data register.
+ *
+ * 1 - Single-Conversion Mode : Device performs a single measurement,
+ * sets RDY high and returns to sleep mode.
+ *
+ * 2 - Idle Mode : Device is placed in idle mode.
+ *
+ * 3 - Sleep Mode : Device is placed in sleep mode.
+ *
+ */
+static ssize_t hmc5843_show_operating_mode(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- s32 result;
- __be16 values[3];
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct hmc5843_data *data = iio_priv(indio_dev);
+ return sprintf(buf, "%d\n", data->operating_mode);
+}
+
+static ssize_t hmc5843_set_operating_mode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+ struct hmc5843_data *data = iio_priv(indio_dev);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ unsigned long operating_mode = 0;
+ s32 status;
+ int error;
mutex_lock(&data->lock);
- result = hmc5843_wait_measurement(data);
- if (result < 0) {
- mutex_unlock(&data->lock);
- return result;
+ error = kstrtoul(buf, 10, &operating_mode);
+ if (error) {
+ count = error;
+ goto exit;
+ }
+ dev_dbg(dev, "set conversion mode to %lu\n", operating_mode);
+ if (operating_mode > HMC5843_MODE_SLEEP) {
+ count = -EINVAL;
+ goto exit;
}
- result = i2c_smbus_read_i2c_block_data(data->client,
- HMC5843_DATA_OUT_MSB_REGS, sizeof(values), (u8 *) values);
- mutex_unlock(&data->lock);
- if (result < 0)
- return -EINVAL;
- *val = sign_extend32(be16_to_cpu(values[idx]), 15);
- return IIO_VAL_INT;
+ status = i2c_smbus_write_byte_data(client, this_attr->address,
+ operating_mode);
+ if (status) {
+ count = -EINVAL;
+ goto exit;
+ }
+ data->operating_mode = operating_mode;
+
+exit:
+ mutex_unlock(&data->lock);
+ return count;
}
+static IIO_DEVICE_ATTR(operating_mode,
+ S_IWUSR | S_IRUGO,
+ hmc5843_show_operating_mode,
+ hmc5843_set_operating_mode,
+ HMC5843_MODE_REG);
+
/*
* API for setting the measurement configuration to
* Normal, Positive bias and Negative bias
@@ -208,26 +318,23 @@ static int hmc5843_read_measurement(struct hmc5843_data *data,
* and BN.
*
*/
-static s32 hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
+static s32 hmc5843_set_meas_conf(struct i2c_client *client,
+ u8 meas_conf)
{
- int ret;
-
- mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
- (meas_conf & HMC5843_MEAS_CONF_MASK) |
- (data->rate << HMC5843_RATE_OFFSET));
- if (ret >= 0)
- data->meas_conf = meas_conf;
- mutex_unlock(&data->lock);
-
- return ret;
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct hmc5843_data *data = iio_priv(indio_dev);
+ u8 reg_val;
+ reg_val = (meas_conf & HMC5843_MEAS_CONF_MASK) |
+ (data->rate << HMC5843_RATE_OFFSET);
+ return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
}
static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct hmc5843_data *data = iio_priv(indio_dev);
return sprintf(buf, "%d\n", data->meas_conf);
}
@@ -236,19 +343,29 @@ static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
const char *buf,
size_t count)
{
- struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+ struct hmc5843_data *data = iio_priv(indio_dev);
unsigned long meas_conf = 0;
- int ret;
+ int error;
- ret = kstrtoul(buf, 10, &meas_conf);
- if (ret)
- return ret;
- if (meas_conf >= HMC5843_MEAS_CONF_MASK)
+ error = kstrtoul(buf, 10, &meas_conf);
+ if (error)
+ return error;
+ if (meas_conf >= HMC5843_MEAS_CONF_NOT_USED)
return -EINVAL;
- ret = hmc5843_set_meas_conf(data, meas_conf);
+ mutex_lock(&data->lock);
+ dev_dbg(dev, "set measurement configuration to %lu\n", meas_conf);
+ if (hmc5843_set_meas_conf(client, meas_conf)) {
+ count = -EINVAL;
+ goto exit;
+ }
+ data->meas_conf = meas_conf;
- return (ret < 0) ? ret : count;
+exit:
+ mutex_unlock(&data->lock);
+ return count;
}
static IIO_DEVICE_ATTR(meas_conf,
@@ -257,221 +374,211 @@ static IIO_DEVICE_ATTR(meas_conf,
hmc5843_set_measurement_configuration,
0);
-static ssize_t hmc5843_show_samp_freq_avail(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t hmc5843_show_sampling_frequencies_available(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
- size_t len = 0;
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct hmc5843_data *data = iio_priv(indio_dev);
+ ssize_t total_n = 0;
int i;
- for (i = 0; i < HMC5843_RATES; i++)
- len += scnprintf(buf + len, PAGE_SIZE - len,
- "%d.%d ", data->variant->regval_to_samp_freq[i][0],
- data->variant->regval_to_samp_freq[i][1]);
-
+ for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
+ ssize_t n = sprintf(buf, "%s ", data->variant->regval_to_sample_freq[i]);
+ buf += n;
+ total_n += n;
+ }
/* replace trailing space by newline */
- buf[len - 1] = '\n';
+ buf[-1] = '\n';
- return len;
+ return total_n;
}
-static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_samp_freq_avail);
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_sampling_frequencies_available);
-static int hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)
+static s32 hmc5843_set_rate(struct i2c_client *client,
+ u8 rate)
{
- int ret;
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct hmc5843_data *data = iio_priv(indio_dev);
+ u8 reg_val;
- mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
- data->meas_conf | (rate << HMC5843_RATE_OFFSET));
- if (ret >= 0)
- data->rate = rate;
- mutex_unlock(&data->lock);
+ if (rate >= HMC5843_RATE_NOT_USED) {
+ dev_err(&client->dev,
+ "data output rate is not supported\n");
+ return -EINVAL;
+ }
- return ret;
+ reg_val = data->meas_conf | (rate << HMC5843_RATE_OFFSET);
+ return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
}
-static int hmc5843_get_samp_freq_index(struct hmc5843_data *data,
- int val, int val2)
+static int hmc5843_check_sampling_frequency(struct hmc5843_data *data,
+ const char *buf)
{
+ const char * const *samp_freq = data->variant->regval_to_sample_freq;
int i;
- for (i = 0; i < HMC5843_RATES; i++)
- if (val == data->variant->regval_to_samp_freq[i][0] &&
- val2 == data->variant->regval_to_samp_freq[i][1])
+ for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
+ if (sysfs_streq(buf, samp_freq[i]))
return i;
+ }
return -EINVAL;
}
-static int hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)
+static ssize_t hmc5843_set_sampling_frequency(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- int ret;
+
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+ struct hmc5843_data *data = iio_priv(indio_dev);
+ int rate;
+
+ rate = hmc5843_check_sampling_frequency(data, buf);
+ if (rate < 0) {
+ dev_err(&client->dev,
+ "sampling frequency is not supported\n");
+ return rate;
+ }
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_B,
- range << HMC5843_RANGE_GAIN_OFFSET);
- if (ret >= 0)
- data->range = range;
- mutex_unlock(&data->lock);
+ dev_dbg(dev, "set rate to %d\n", rate);
+ if (hmc5843_set_rate(client, rate)) {
+ count = -EINVAL;
+ goto exit;
+ }
+ data->rate = rate;
- return ret;
+exit:
+ mutex_unlock(&data->lock);
+ return count;
}
-static ssize_t hmc5843_show_scale_avail(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t hmc5843_show_sampling_frequency(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ struct hmc5843_data *data = iio_priv(indio_dev);
+ s32 rate;
- size_t len = 0;
- int i;
+ rate = i2c_smbus_read_byte_data(client, this_attr->address);
+ if (rate < 0)
+ return rate;
+ rate = (rate & HMC5843_RATE_BITMASK) >> HMC5843_RATE_OFFSET;
+ return sprintf(buf, "%s\n", data->variant->regval_to_sample_freq[rate]);
+}
- for (i = 0; i < HMC5843_RANGE_GAINS; i++)
- len += scnprintf(buf + len, PAGE_SIZE - len,
- "0.%09d ", data->variant->regval_to_nanoscale[i]);
+static IIO_DEVICE_ATTR(sampling_frequency,
+ S_IWUSR | S_IRUGO,
+ hmc5843_show_sampling_frequency,
+ hmc5843_set_sampling_frequency,
+ HMC5843_CONFIG_REG_A);
- /* replace trailing space by newline */
- buf[len - 1] = '\n';
+static ssize_t hmc5843_show_range_gain(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 range;
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct hmc5843_data *data = iio_priv(indio_dev);
- return len;
+ range = data->range;
+ return sprintf(buf, "%d\n", data->variant->regval_to_input_field_mga[range]);
}
-static IIO_DEVICE_ATTR(scale_available, S_IRUGO,
- hmc5843_show_scale_avail, NULL, 0);
-
-static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2)
+static ssize_t hmc5843_set_range_gain(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
{
- int i;
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ struct hmc5843_data *data = iio_priv(indio_dev);
+ unsigned long range = 0;
+ int error;
- if (val != 0)
- return -EINVAL;
+ mutex_lock(&data->lock);
+ error = kstrtoul(buf, 10, &range);
+ if (error) {
+ count = error;
+ goto exit;
+ }
+ dev_dbg(dev, "set range to %lu\n", range);
- for (i = 0; i < HMC5843_RANGE_GAINS; i++)
- if (val2 == data->variant->regval_to_nanoscale[i])
- return i;
+ if (range > HMC5843_RANGE_GAIN_MAX) {
+ count = -EINVAL;
+ goto exit;
+ }
- return -EINVAL;
+ data->range = range;
+ range = range << HMC5843_RANGE_GAIN_OFFSET;
+ if (i2c_smbus_write_byte_data(client, this_attr->address, range))
+ count = -EINVAL;
+
+exit:
+ mutex_unlock(&data->lock);
+ return count;
}
+static IIO_DEVICE_ATTR(in_magn_range,
+ S_IWUSR | S_IRUGO,
+ hmc5843_show_range_gain,
+ hmc5843_set_range_gain,
+ HMC5843_CONFIG_REG_B);
+
static int hmc5843_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
- int *val, int *val2, long mask)
+ int *val, int *val2,
+ long mask)
{
struct hmc5843_data *data = iio_priv(indio_dev);
switch (mask) {
case IIO_CHAN_INFO_RAW:
- return hmc5843_read_measurement(data, chan->scan_index, val);
+ return hmc5843_read_measurement(indio_dev,
+ chan->address,
+ val);
case IIO_CHAN_INFO_SCALE:
*val = 0;
*val2 = data->variant->regval_to_nanoscale[data->range];
return IIO_VAL_INT_PLUS_NANO;
- case IIO_CHAN_INFO_SAMP_FREQ:
- *val = data->variant->regval_to_samp_freq[data->rate][0];
- *val2 = data->variant->regval_to_samp_freq[data->rate][1];
- return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
}
-static int hmc5843_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val, int val2, long mask)
-{
- struct hmc5843_data *data = iio_priv(indio_dev);
- int rate, range;
-
- switch (mask) {
- case IIO_CHAN_INFO_SAMP_FREQ:
- rate = hmc5843_get_samp_freq_index(data, val, val2);
- if (rate < 0)
- return -EINVAL;
-
- return hmc5843_set_samp_freq(data, rate);
- case IIO_CHAN_INFO_SCALE:
- range = hmc5843_get_scale_index(data, val, val2);
- if (range < 0)
- return -EINVAL;
-
- return hmc5843_set_range_gain(data, range);
- default:
- return -EINVAL;
- }
-}
-
-static int hmc5843_write_raw_get_fmt(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan, long mask)
-{
- switch (mask) {
- case IIO_CHAN_INFO_SAMP_FREQ:
- return IIO_VAL_INT_PLUS_MICRO;
- case IIO_CHAN_INFO_SCALE:
- return IIO_VAL_INT_PLUS_NANO;
- default:
- return -EINVAL;
- }
-}
-
-static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
-{
- struct iio_poll_func *pf = p;
- struct iio_dev *indio_dev = pf->indio_dev;
- struct hmc5843_data *data = iio_priv(indio_dev);
- int ret;
-
- mutex_lock(&data->lock);
- ret = hmc5843_wait_measurement(data);
- if (ret < 0) {
- mutex_unlock(&data->lock);
- goto done;
- }
-
- ret = i2c_smbus_read_i2c_block_data(data->client,
- HMC5843_DATA_OUT_MSB_REGS, 3 * sizeof(__be16),
- (u8 *) data->buffer);
- mutex_unlock(&data->lock);
- if (ret < 0)
- goto done;
-
- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
- iio_get_time_ns());
-
-done:
- iio_trigger_notify_done(indio_dev->trig);
-
- return IRQ_HANDLED;
-}
-
-#define HMC5843_CHANNEL(axis, idx) \
+#define HMC5843_CHANNEL(axis, addr) \
{ \
.type = IIO_MAGN, \
.modified = 1, \
.channel2 = IIO_MOD_##axis, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
- BIT(IIO_CHAN_INFO_SAMP_FREQ), \
- .scan_index = idx, \
- .scan_type = IIO_ST('s', 16, 16, IIO_BE), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .address = addr \
}
static const struct iio_chan_spec hmc5843_channels[] = {
- HMC5843_CHANNEL(X, 0),
- HMC5843_CHANNEL(Y, 1),
- HMC5843_CHANNEL(Z, 2),
- IIO_CHAN_SOFT_TIMESTAMP(3),
+ HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
+ HMC5843_CHANNEL(Y, HMC5843_DATA_OUT_Y_MSB_REG),
+ HMC5843_CHANNEL(Z, HMC5843_DATA_OUT_Z_MSB_REG),
};
-/* Beware: Y and Z are exchanged on HMC5883 */
static const struct iio_chan_spec hmc5883_channels[] = {
- HMC5843_CHANNEL(X, 0),
- HMC5843_CHANNEL(Z, 1),
- HMC5843_CHANNEL(Y, 2),
- IIO_CHAN_SOFT_TIMESTAMP(3),
+ HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
+ HMC5843_CHANNEL(Y, HMC5883_DATA_OUT_Y_MSB_REG),
+ HMC5843_CHANNEL(Z, HMC5883_DATA_OUT_Z_MSB_REG),
};
static struct attribute *hmc5843_attributes[] = {
&iio_dev_attr_meas_conf.dev_attr.attr,
- &iio_dev_attr_scale_available.dev_attr.attr,
+ &iio_dev_attr_operating_mode.dev_attr.attr,
+ &iio_dev_attr_sampling_frequency.dev_attr.attr,
+ &iio_dev_attr_in_magn_range.dev_attr.attr,
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
NULL
};
@@ -483,101 +590,89 @@ static const struct attribute_group hmc5843_group = {
static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
[HMC5843_ID] = {
.channels = hmc5843_channels,
- .regval_to_samp_freq = hmc5843_regval_to_samp_freq,
+ .regval_to_sample_freq = hmc5843_regval_to_sample_freq,
+ .regval_to_input_field_mga =
+ hmc5843_regval_to_input_field_mga,
.regval_to_nanoscale = hmc5843_regval_to_nanoscale,
},
[HMC5883_ID] = {
.channels = hmc5883_channels,
- .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
+ .regval_to_sample_freq = hmc5883_regval_to_sample_freq,
+ .regval_to_input_field_mga =
+ hmc5883_regval_to_input_field_mga,
.regval_to_nanoscale = hmc5883_regval_to_nanoscale,
},
[HMC5883L_ID] = {
.channels = hmc5883_channels,
- .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
+ .regval_to_sample_freq = hmc5883_regval_to_sample_freq,
+ .regval_to_input_field_mga =
+ hmc5883l_regval_to_input_field_mga,
.regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
},
};
-static int hmc5843_init(struct hmc5843_data *data)
+/* Called when we have found a new HMC58X3 */
+static void hmc5843_init_client(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- int ret;
- u8 id[3];
-
- ret = i2c_smbus_read_i2c_block_data(data->client, HMC5843_ID_REG,
- sizeof(id), id);
- if (ret < 0)
- return ret;
- if (id[0] != 'H' || id[1] != '4' || id[2] != '3') {
- dev_err(&data->client->dev, "no HMC5843/5883/5883L sensor\n");
- return -ENODEV;
- }
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct hmc5843_data *data = iio_priv(indio_dev);
+
+ data->variant = &hmc5843_chip_info_tbl[id->driver_data];
+ indio_dev->channels = data->variant->channels;
+ indio_dev->num_channels = 3;
+ hmc5843_set_meas_conf(client, data->meas_conf);
+ hmc5843_set_rate(client, data->rate);
+ hmc5843_configure(client, data->operating_mode);
+ i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
+ mutex_init(&data->lock);
- ret = hmc5843_set_meas_conf(data, HMC5843_MEAS_CONF_NORMAL);
- if (ret < 0)
- return ret;
- ret = hmc5843_set_samp_freq(data, HMC5843_RATE_DEFAULT);
- if (ret < 0)
- return ret;
- ret = hmc5843_set_range_gain(data, HMC5843_RANGE_GAIN_DEFAULT);
- if (ret < 0)
- return ret;
- return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
+ pr_info("%s initialized\n", id->name);
}
static const struct iio_info hmc5843_info = {
.attrs = &hmc5843_group,
.read_raw = &hmc5843_read_raw,
- .write_raw = &hmc5843_write_raw,
- .write_raw_get_fmt = &hmc5843_write_raw_get_fmt,
.driver_module = THIS_MODULE,
};
-static const unsigned long hmc5843_scan_masks[] = {0x7, 0};
-
static int hmc5843_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct hmc5843_data *data;
struct iio_dev *indio_dev;
- int ret;
+ int err = 0;
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
- if (indio_dev == NULL)
- return -ENOMEM;
+ indio_dev = iio_device_alloc(sizeof(*data));
+ if (indio_dev == NULL) {
+ err = -ENOMEM;
+ goto exit;
+ }
/* default settings at probe */
data = iio_priv(indio_dev);
- data->client = client;
- data->variant = &hmc5843_chip_info_tbl[id->driver_data];
- mutex_init(&data->lock);
+ data->meas_conf = HMC5843_MEAS_CONF_NORMAL;
+ data->range = HMC5843_RANGE_GAIN_DEFAULT;
+ data->operating_mode = HMC5843_MODE_CONVERSION_CONTINUOUS;
i2c_set_clientdata(client, indio_dev);
+ hmc5843_init_client(client, id);
+
indio_dev->info = &hmc5843_info;
indio_dev->name = id->name;
indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = data->variant->channels;
- indio_dev->num_channels = 4;
- indio_dev->available_scan_masks = hmc5843_scan_masks;
-
- ret = hmc5843_init(data);
- if (ret < 0)
- return ret;
-
- ret = iio_triggered_buffer_setup(indio_dev, NULL,
- hmc5843_trigger_handler, NULL);
- if (ret < 0)
- return ret;
- ret = iio_device_register(indio_dev);
- if (ret < 0)
- goto buffer_cleanup;
+ err = iio_device_register(indio_dev);
+ if (err)
+ goto exit_free2;
return 0;
-buffer_cleanup:
- iio_triggered_buffer_cleanup(indio_dev);
- return ret;
+exit_free2:
+ iio_device_free(indio_dev);
+exit:
+ return err;
}
static int hmc5843_remove(struct i2c_client *client)
@@ -585,10 +680,9 @@ static int hmc5843_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
- iio_triggered_buffer_cleanup(indio_dev);
-
- /* sleep mode to save power */
- hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP);
+ /* sleep mode to save power */
+ hmc5843_configure(client, HMC5843_MODE_SLEEP);
+ iio_device_free(indio_dev);
return 0;
}
@@ -596,18 +690,19 @@ static int hmc5843_remove(struct i2c_client *client)
#ifdef CONFIG_PM_SLEEP
static int hmc5843_suspend(struct device *dev)
{
- struct hmc5843_data *data = iio_priv(i2c_get_clientdata(
- to_i2c_client(dev)));
-
- return hmc5843_set_mode(data, HMC5843_MODE_SLEEP);
+ hmc5843_configure(to_i2c_client(dev), HMC5843_MODE_SLEEP);
+ return 0;
}
static int hmc5843_resume(struct device *dev)
{
- struct hmc5843_data *data = iio_priv(i2c_get_clientdata(
- to_i2c_client(dev)));
+ struct i2c_client *client = to_i2c_client(dev);
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct hmc5843_data *data = iio_priv(indio_dev);
- return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
+ hmc5843_configure(client, data->operating_mode);
+
+ return 0;
}
static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_suspend, hmc5843_resume);
@@ -635,6 +730,6 @@ static struct i2c_driver hmc5843_driver = {
};
module_i2c_driver(hmc5843_driver);
-MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com>");
+MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
MODULE_DESCRIPTION("HMC5843/5883/5883L driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index 00492ca..74025fb 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -86,7 +86,7 @@ static int ade7753_spi_read_reg_16(struct device *dev,
struct ade7753_state *st = iio_priv(indio_dev);
ssize_t ret;
- ret = spi_w8r16be(st->us, ADE7753_READ_REG(reg_address));
+ ret = spi_w8r16(st->us, ADE7753_READ_REG(reg_address));
if (ret < 0) {
dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
reg_address);
@@ -94,6 +94,7 @@ static int ade7753_spi_read_reg_16(struct device *dev,
}
*val = ret;
+ *val = be16_to_cpup(val);
return 0;
}
@@ -185,9 +186,9 @@ static ssize_t ade7753_write_8bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- u8 val;
+ long val;
- ret = kstrtou8(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7753_spi_write_reg_8(dev, this_attr->address, val);
@@ -203,9 +204,9 @@ static ssize_t ade7753_write_16bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- u16 val;
+ long val;
- ret = kstrtou16(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7753_spi_write_reg_16(dev, this_attr->address, val);
@@ -398,11 +399,11 @@ static ssize_t ade7753_write_frequency(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7753_state *st = iio_priv(indio_dev);
- u16 val;
+ unsigned long val;
int ret;
u16 reg, t;
- ret = kstrtou16(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
return ret;
if (val == 0)
@@ -496,9 +497,11 @@ static int ade7753_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!indio_dev)
- return -ENOMEM;
+ indio_dev = iio_device_alloc(sizeof(*st));
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -514,13 +517,19 @@ static int ade7753_probe(struct spi_device *spi)
/* Get the device into a sane initial state */
ret = ade7753_initial_setup(indio_dev);
if (ret)
- return ret;
+ goto error_free_dev;
ret = iio_device_register(indio_dev);
if (ret)
- return ret;
+ goto error_free_dev;
return 0;
+
+error_free_dev:
+ iio_device_free(indio_dev);
+
+error_ret:
+ return ret;
}
/* fixme, confirm ordering in this function */
@@ -530,6 +539,7 @@ static int ade7753_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ade7753_stop_device(&indio_dev->dev);
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index e0aa13a..f649ebe 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -86,7 +86,7 @@ static int ade7754_spi_read_reg_16(struct device *dev,
struct ade7754_state *st = iio_priv(indio_dev);
int ret;
- ret = spi_w8r16be(st->us, ADE7754_READ_REG(reg_address));
+ ret = spi_w8r16(st->us, ADE7754_READ_REG(reg_address));
if (ret < 0) {
dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
reg_address);
@@ -94,6 +94,7 @@ static int ade7754_spi_read_reg_16(struct device *dev,
}
*val = ret;
+ *val = be16_to_cpup(val);
return 0;
}
@@ -185,9 +186,9 @@ static ssize_t ade7754_write_8bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- u8 val;
+ long val;
- ret = kstrtou8(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7754_spi_write_reg_8(dev, this_attr->address, val);
@@ -203,9 +204,9 @@ static ssize_t ade7754_write_16bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- u16 val;
+ long val;
- ret = kstrtou16(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7754_spi_write_reg_16(dev, this_attr->address, val);
@@ -418,11 +419,11 @@ static ssize_t ade7754_write_frequency(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7754_state *st = iio_priv(indio_dev);
- u16 val;
+ unsigned long val;
int ret;
u8 reg, t;
- ret = kstrtou16(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
return ret;
if (val == 0)
@@ -519,9 +520,11 @@ static int ade7754_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!indio_dev)
- return -ENOMEM;
+ indio_dev = iio_device_alloc(sizeof(*st));
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -537,12 +540,18 @@ static int ade7754_probe(struct spi_device *spi)
/* Get the device into a sane initial state */
ret = ade7754_initial_setup(indio_dev);
if (ret)
- return ret;
+ goto error_free_dev;
ret = iio_device_register(indio_dev);
if (ret)
- return ret;
+ goto error_free_dev;
return 0;
+
+error_free_dev:
+ iio_device_free(indio_dev);
+
+error_ret:
+ return ret;
}
/* fixme, confirm ordering in this function */
@@ -552,6 +561,7 @@ static int ade7754_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ade7754_stop_device(&indio_dev->dev);
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index cba183e..6005d4a 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -269,9 +269,9 @@ static ssize_t ade7758_write_8bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- u8 val;
+ long val;
- ret = kstrtou8(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7758_spi_write_reg_8(dev, this_attr->address, val);
@@ -287,9 +287,9 @@ static ssize_t ade7758_write_16bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- u16 val;
+ long val;
- ret = kstrtou16(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7758_spi_write_reg_16(dev, this_attr->address, val);
@@ -502,11 +502,11 @@ static ssize_t ade7758_write_frequency(struct device *dev,
size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- u16 val;
+ unsigned long val;
int ret;
u8 reg, t;
- ret = kstrtou16(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
return ret;
@@ -849,11 +849,12 @@ static int ade7758_probe(struct spi_device *spi)
{
int ret;
struct ade7758_state *st;
- struct iio_dev *indio_dev;
+ struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!indio_dev)
- return -ENOMEM;
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
@@ -861,8 +862,10 @@ static int ade7758_probe(struct spi_device *spi)
/* Allocate the comms buffers */
st->rx = kcalloc(ADE7758_MAX_RX, sizeof(*st->rx), GFP_KERNEL);
- if (!st->rx)
- return -ENOMEM;
+ if (st->rx == NULL) {
+ ret = -ENOMEM;
+ goto error_free_dev;
+ }
st->tx = kcalloc(ADE7758_MAX_TX, sizeof(*st->tx), GFP_KERNEL);
if (st->tx == NULL) {
ret = -ENOMEM;
@@ -917,6 +920,9 @@ error_free_tx:
kfree(st->tx);
error_free_rx:
kfree(st->rx);
+error_free_dev:
+ iio_device_free(indio_dev);
+error_ret:
return ret;
}
@@ -933,6 +939,8 @@ static int ade7758_remove(struct spi_device *spi)
kfree(st->tx);
kfree(st->rx);
+ iio_device_free(indio_dev);
+
return 0;
}
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index c0accf8..7d5db71 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -69,7 +69,11 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
if (ade7758_spi_read_burst(indio_dev) >= 0)
*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
- iio_push_to_buffers_with_timestamp(indio_dev, dat64, pf->timestamp);
+ /* Guaranteed to be aligned with 8 byte boundary */
+ if (indio_dev->scan_timestamp)
+ dat64[1] = pf->timestamp;
+
+ iio_push_to_buffers(indio_dev, (u8 *)dat64);
iio_trigger_notify_done(indio_dev->trig);
@@ -87,10 +91,15 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev)
{
struct ade7758_state *st = iio_priv(indio_dev);
unsigned channel;
+ int ret;
if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
+ ret = iio_sw_buffer_preenable(indio_dev);
+ if (ret < 0)
+ return ret;
+
channel = find_first_bit(indio_dev->active_scan_mask,
indio_dev->masklength);
@@ -116,17 +125,14 @@ void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
int ade7758_configure_ring(struct iio_dev *indio_dev)
{
struct ade7758_state *st = iio_priv(indio_dev);
- struct iio_buffer *buffer;
int ret = 0;
- buffer = iio_kfifo_allocate(indio_dev);
- if (!buffer) {
+ indio_dev->buffer = iio_kfifo_allocate(indio_dev);
+ if (!indio_dev->buffer) {
ret = -ENOMEM;
return ret;
}
- iio_device_attach_buffer(indio_dev, buffer);
-
indio_dev->setup_ops = &ade7758_ring_setup_ops;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index ea0c9de..d214ac4 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -86,7 +86,7 @@ static int ade7759_spi_read_reg_16(struct device *dev,
struct ade7759_state *st = iio_priv(indio_dev);
int ret;
- ret = spi_w8r16be(st->us, ADE7759_READ_REG(reg_address));
+ ret = spi_w8r16(st->us, ADE7759_READ_REG(reg_address));
if (ret < 0) {
dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
reg_address);
@@ -94,6 +94,7 @@ static int ade7759_spi_read_reg_16(struct device *dev,
}
*val = ret;
+ *val = be16_to_cpup(val);
return 0;
}
@@ -184,9 +185,9 @@ static ssize_t ade7759_write_8bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- u8 val;
+ long val;
- ret = kstrtou8(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7759_spi_write_reg_8(dev, this_attr->address, val);
@@ -202,9 +203,9 @@ static ssize_t ade7759_write_16bit(struct device *dev,
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
- u16 val;
+ long val;
- ret = kstrtou16(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = ade7759_spi_write_reg_16(dev, this_attr->address, val);
@@ -359,11 +360,11 @@ static ssize_t ade7759_write_frequency(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7759_state *st = iio_priv(indio_dev);
- u16 val;
+ unsigned long val;
int ret;
u16 reg, t;
- ret = kstrtou16(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
return ret;
if (val == 0)
@@ -443,9 +444,11 @@ static int ade7759_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!indio_dev)
- return -ENOMEM;
+ indio_dev = iio_device_alloc(sizeof(*st));
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
@@ -460,13 +463,18 @@ static int ade7759_probe(struct spi_device *spi)
/* Get the device into a sane initial state */
ret = ade7759_initial_setup(indio_dev);
if (ret)
- return ret;
+ goto error_free_dev;
ret = iio_device_register(indio_dev);
if (ret)
- return ret;
+ goto error_free_dev;
return 0;
+
+error_free_dev:
+ iio_device_free(indio_dev);
+error_ret:
+ return ret;
}
/* fixme, confirm ordering in this function */
@@ -476,6 +484,7 @@ static int ade7759_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ade7759_stop_device(&indio_dev->dev);
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c
index 5b33c7f..db9ef6c 100644
--- a/drivers/staging/iio/meter/ade7854-i2c.c
+++ b/drivers/staging/iio/meter/ade7854-i2c.c
@@ -208,7 +208,7 @@ static int ade7854_i2c_probe(struct i2c_client *client,
struct ade7854_state *st;
struct iio_dev *indio_dev;
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
+ indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
@@ -225,6 +225,8 @@ static int ade7854_i2c_probe(struct i2c_client *client,
st->irq = client->irq;
ret = ade7854_probe(indio_dev, &client->dev);
+ if (ret)
+ iio_device_free(indio_dev);
return ret;
}
diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c
index 94f73bb..4c6d204 100644
--- a/drivers/staging/iio/meter/ade7854-spi.c
+++ b/drivers/staging/iio/meter/ade7854-spi.c
@@ -278,7 +278,7 @@ static int ade7854_spi_probe(struct spi_device *spi)
struct ade7854_state *st;
struct iio_dev *indio_dev;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
@@ -296,6 +296,8 @@ static int ade7854_spi_probe(struct spi_device *spi)
ret = ade7854_probe(indio_dev, &spi->dev);
+ if (ret)
+ iio_device_free(indio_dev);
return ret;
}
diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c
index d620bbd..e8379c0 100644
--- a/drivers/staging/iio/meter/ade7854.c
+++ b/drivers/staging/iio/meter/ade7854.c
@@ -100,9 +100,9 @@ static ssize_t ade7854_write_8bit(struct device *dev,
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
- u8 val;
+ long val;
- ret = kstrtou8(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = st->write_reg_8(dev, this_attr->address, val);
@@ -121,9 +121,9 @@ static ssize_t ade7854_write_16bit(struct device *dev,
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
- u16 val;
+ long val;
- ret = kstrtou16(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = st->write_reg_16(dev, this_attr->address, val);
@@ -142,9 +142,9 @@ static ssize_t ade7854_write_24bit(struct device *dev,
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
- u32 val;
+ long val;
- ret = kstrtou32(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = st->write_reg_24(dev, this_attr->address, val);
@@ -163,9 +163,9 @@ static ssize_t ade7854_write_32bit(struct device *dev,
struct ade7854_state *st = iio_priv(indio_dev);
int ret;
- u32 val;
+ long val;
- ret = kstrtou32(buf, 10, &val);
+ ret = strict_strtol(buf, 10, &val);
if (ret)
goto error_ret;
ret = st->write_reg_32(dev, this_attr->address, val);
@@ -550,7 +550,7 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
ret = iio_device_register(indio_dev);
if (ret)
- return ret;
+ goto error_free_dev;
/* Get the device into a sane initial state */
ret = ade7854_initial_setup(indio_dev);
@@ -561,6 +561,9 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
error_unreg_dev:
iio_device_unregister(indio_dev);
+error_free_dev:
+ iio_device_free(indio_dev);
+
return ret;
}
EXPORT_SYMBOL(ade7854_probe);
@@ -568,6 +571,7 @@ EXPORT_SYMBOL(ade7854_probe);
int ade7854_remove(struct iio_dev *indio_dev)
{
iio_device_unregister(indio_dev);
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c
index 62d3017..7122116 100644
--- a/drivers/staging/iio/resolver/ad2s1200.c
+++ b/drivers/staging/iio/resolver/ad2s1200.c
@@ -107,16 +107,16 @@ static int ad2s1200_probe(struct spi_device *spi)
unsigned short *pins = spi->dev.platform_data;
for (pn = 0; pn < AD2S1200_PN; pn++)
- ret = devm_gpio_request_one(&spi->dev, pins[pn], GPIOF_DIR_OUT,
- DRV_NAME);
- if (ret) {
- dev_err(&spi->dev, "request gpio pin %d failed\n",
- pins[pn]);
- return ret;
+ if (gpio_request_one(pins[pn], GPIOF_DIR_OUT, DRV_NAME)) {
+ pr_err("%s: request gpio pin %d failed\n",
+ DRV_NAME, pins[pn]);
+ goto error_ret;
}
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!indio_dev)
- return -ENOMEM;
+ indio_dev = iio_device_alloc(sizeof(*st));
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
spi_set_drvdata(spi, indio_dev);
st = iio_priv(indio_dev);
mutex_init(&st->lock);
@@ -133,18 +133,26 @@ static int ad2s1200_probe(struct spi_device *spi)
ret = iio_device_register(indio_dev);
if (ret)
- return ret;
+ goto error_free_dev;
spi->max_speed_hz = AD2S1200_HZ;
spi->mode = SPI_MODE_3;
spi_setup(spi);
return 0;
+
+error_free_dev:
+ iio_device_free(indio_dev);
+error_ret:
+ for (--pn; pn >= 0; pn--)
+ gpio_free(pins[pn]);
+ return ret;
}
static int ad2s1200_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
+ iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 6966d5f..dcdadbb 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -206,10 +206,10 @@ static ssize_t ad2s1210_store_fclkin(struct device *dev,
size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
- unsigned int fclkin;
+ unsigned long fclkin;
int ret;
- ret = kstrtouint(buf, 10, &fclkin);
+ ret = strict_strtoul(buf, 10, &fclkin);
if (ret)
return ret;
if (fclkin < AD2S1210_MIN_CLKIN || fclkin > AD2S1210_MAX_CLKIN) {
@@ -243,10 +243,10 @@ static ssize_t ad2s1210_store_fexcit(struct device *dev,
const char *buf, size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
- unsigned int fexcit;
+ unsigned long fexcit;
int ret;
- ret = kstrtouint(buf, 10, &fexcit);
+ ret = strict_strtoul(buf, 10, &fexcit);
if (ret < 0)
return ret;
if (fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT) {
@@ -282,11 +282,11 @@ static ssize_t ad2s1210_store_control(struct device *dev,
const char *buf, size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
- unsigned char udata;
+ unsigned long udata;
unsigned char data;
int ret;
- ret = kstrtou8(buf, 16, &udata);
+ ret = strict_strtoul(buf, 16, &udata);
if (ret)
return -EINVAL;
@@ -337,10 +337,10 @@ static ssize_t ad2s1210_store_resolution(struct device *dev,
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
unsigned char data;
- unsigned char udata;
+ unsigned long udata;
int ret;
- ret = kstrtou8(buf, 10, &udata);
+ ret = strict_strtoul(buf, 10, &udata);
if (ret || udata < 10 || udata > 16) {
pr_err("ad2s1210: resolution out of range\n");
return -EINVAL;
@@ -438,11 +438,11 @@ static ssize_t ad2s1210_store_reg(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
- unsigned char data;
+ unsigned long data;
int ret;
struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
- ret = kstrtou8(buf, 10, &data);
+ ret = strict_strtoul(buf, 10, &data);
if (ret)
return -EINVAL;
mutex_lock(&st->lock);
@@ -669,14 +669,16 @@ static int ad2s1210_probe(struct spi_device *spi)
if (spi->dev.platform_data == NULL)
return -EINVAL;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!indio_dev)
- return -ENOMEM;
+ indio_dev = iio_device_alloc(sizeof(*st));
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
st = iio_priv(indio_dev);
st->pdata = spi->dev.platform_data;
ret = ad2s1210_setup_gpios(st);
if (ret < 0)
- return ret;
+ goto error_free_dev;
spi_set_drvdata(spi, indio_dev);
@@ -707,6 +709,9 @@ static int ad2s1210_probe(struct spi_device *spi)
error_free_gpios:
ad2s1210_free_gpios(st);
+error_free_dev:
+ iio_device_free(indio_dev);
+error_ret:
return ret;
}
@@ -716,6 +721,7 @@ static int ad2s1210_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
ad2s1210_free_gpios(iio_priv(indio_dev));
+ iio_device_free(indio_dev);
return 0;
}
diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c
index e24c589..40b8252 100644
--- a/drivers/staging/iio/resolver/ad2s90.c
+++ b/drivers/staging/iio/resolver/ad2s90.c
@@ -64,9 +64,11 @@ static int ad2s90_probe(struct spi_device *spi)
struct ad2s90_state *st;
int ret = 0;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
- if (!indio_dev)
- return -ENOMEM;
+ indio_dev = iio_device_alloc(sizeof(*st));
+ if (indio_dev == NULL) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
st = iio_priv(indio_dev);
spi_set_drvdata(spi, indio_dev);
@@ -81,7 +83,7 @@ static int ad2s90_probe(struct spi_device *spi)
ret = iio_device_register(indio_dev);
if (ret)
- return ret;
+ goto error_free_dev;
/* need 600ns between CS and the first falling edge of SCLK */
spi->max_speed_hz = 830000;
@@ -89,11 +91,17 @@ static int ad2s90_probe(struct spi_device *spi)
spi_setup(spi);
return 0;
+
+error_free_dev:
+ iio_device_free(indio_dev);
+error_ret:
+ return ret;
}
static int ad2s90_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
+ iio_device_free(spi_get_drvdata(spi));
return 0;
}
diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
index 26e1ca0..38a158b 100644
--- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
+++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
@@ -83,28 +83,32 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev,
{
struct iio_trigger *trig = to_iio_trigger(dev);
struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig);
- unsigned int val;
+ unsigned long val;
bool enabled;
int ret;
- ret = kstrtouint(buf, 10, &val);
+ ret = strict_strtoul(buf, 10, &val);
if (ret)
- return ret;
+ goto error_ret;
- if (val > 100000)
- return -EINVAL;
+ if (val > 100000) {
+ ret = -EINVAL;
+ goto error_ret;
+ }
enabled = get_enabled_gptimers() & st->t->bit;
if (enabled)
disable_gptimers(st->t->bit);
- if (val == 0)
- return count;
+ if (!val)
+ goto error_ret;
val = get_sclk() / val;
- if (val <= 4 || val <= st->duty)
- return -EINVAL;
+ if (val <= 4 || val <= st->duty) {
+ ret = -EINVAL;
+ goto error_ret;
+ }
set_gptimer_period(st->t->id, val);
set_gptimer_pwidth(st->t->id, val - st->duty);
@@ -112,7 +116,8 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev,
if (enabled)
enable_gptimers(st->t->bit);
- return count;
+error_ret:
+ return ret ? ret : count;
}
static ssize_t iio_bfin_tmr_frequency_show(struct device *dev,
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
index 48a6afa..7969597 100644
--- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
+++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
@@ -53,10 +53,10 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev,
{
struct iio_trigger *trig = to_iio_trigger(dev);
struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig);
- int val;
+ unsigned long val;
int ret;
- ret = kstrtoint(buf, 10, &val);
+ ret = strict_strtoul(buf, 10, &val);
if (ret)
goto error_ret;