diff options
Diffstat (limited to 'drivers/staging/iio')
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 = 𝔠 - 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 = 𝔠 - 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 = 𝔠 - 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 = 𝔠 - 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 = 𝔠 - 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; |