diff options
Diffstat (limited to 'drivers/staging/iio/adc/ad7793.c')
-rw-r--r-- | drivers/staging/iio/adc/ad7793.c | 275 |
1 files changed, 175 insertions, 100 deletions
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 90f6c039d6c6..a831b92cd082 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -19,10 +19,10 @@ #include "../iio.h" #include "../sysfs.h" -#include "../ring_generic.h" +#include "../buffer_generic.h" #include "../ring_sw.h" #include "../trigger.h" -#include "adc.h" +#include "../trigger_consumer.h" #include "ad7793.h" @@ -51,7 +51,8 @@ struct ad7793_state { u16 mode; u16 conf; u32 scale_avail[8][2]; - u32 available_scan_masks[7]; + /* Note this uses fact that 8 the mask always fits in a long */ + unsigned long available_scan_masks[7]; /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. @@ -316,12 +317,12 @@ out: static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val) { - struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring; + struct iio_buffer *ring = iio_priv_to_dev(st)->buffer; int ret; s64 dat64[2]; u32 *dat32 = (u32 *)dat64; - if (!(ring->scan_mask & (1 << ch))) + if (!(test_bit(ch, ring->scan_mask))) return -EBUSY; ret = ring->access->read_last(ring, (u8 *) &dat64); @@ -336,14 +337,15 @@ static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val) static int ad7793_ring_preenable(struct iio_dev *indio_dev) { struct ad7793_state *st = iio_priv(indio_dev); - struct iio_ring_buffer *ring = indio_dev->ring; + struct iio_buffer *ring = indio_dev->buffer; size_t d_size; unsigned channel; if (!ring->scan_count) return -EINVAL; - channel = __ffs(ring->scan_mask); + channel = find_first_bit(ring->scan_mask, + indio_dev->masklength); d_size = ring->scan_count * indio_dev->channels[0].scan_type.storagebits / 8; @@ -355,9 +357,9 @@ static int ad7793_ring_preenable(struct iio_dev *indio_dev) d_size += sizeof(s64) - (d_size % sizeof(s64)); } - if (indio_dev->ring->access->set_bytes_per_datum) - indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring, - d_size); + if (indio_dev->buffer->access->set_bytes_per_datum) + indio_dev->buffer->access-> + set_bytes_per_datum(indio_dev->buffer, d_size); st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | AD7793_MODE_SEL(AD7793_MODE_CONT); @@ -402,8 +404,8 @@ static int ad7793_ring_postdisable(struct iio_dev *indio_dev) static irqreturn_t ad7793_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; - struct iio_ring_buffer *ring = indio_dev->ring; + struct iio_dev *indio_dev = pf->indio_dev; + struct iio_buffer *ring = indio_dev->buffer; struct ad7793_state *st = iio_priv(indio_dev); s64 dat64[2]; s32 *dat32 = (s32 *)dat64; @@ -426,10 +428,10 @@ static irqreturn_t ad7793_trigger_handler(int irq, void *p) return IRQ_HANDLED; } -static const struct iio_ring_setup_ops ad7793_ring_setup_ops = { +static const struct iio_buffer_setup_ops ad7793_ring_setup_ops = { .preenable = &ad7793_ring_preenable, - .postenable = &iio_triggered_ring_postenable, - .predisable = &iio_triggered_ring_predisable, + .postenable = &iio_triggered_buffer_postenable, + .predisable = &iio_triggered_buffer_predisable, .postdisable = &ad7793_ring_postdisable, }; @@ -437,13 +439,13 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) { int ret; - indio_dev->ring = iio_sw_rb_allocate(indio_dev); - if (!indio_dev->ring) { + indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; } /* Effectively select the ring buffer implementation */ - indio_dev->ring->access = &ring_sw_access_funcs; + indio_dev->buffer->access = &ring_sw_access_funcs; indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, &ad7793_trigger_handler, IRQF_ONESHOT, @@ -456,28 +458,22 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) } /* Ring buffer functions - here trigger setup related */ - indio_dev->ring->setup_ops = &ad7793_ring_setup_ops; + indio_dev->buffer->setup_ops = &ad7793_ring_setup_ops; /* Flag that polled ring buffering is possible */ - indio_dev->modes |= INDIO_RING_TRIGGERED; + indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->ring); + iio_sw_rb_free(indio_dev->buffer); error_ret: return ret; } static void ad7793_ring_cleanup(struct iio_dev *indio_dev) { - /* ensure that the trigger has been detached */ - if (indio_dev->trig) { - iio_put_trigger(indio_dev->trig); - iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc); - } iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->ring); + iio_sw_rb_free(indio_dev->buffer); } /** @@ -574,7 +570,7 @@ static ssize_t ad7793_write_frequency(struct device *dev, int i, ret; mutex_lock(&indio_dev->mlock); - if (iio_ring_enabled(indio_dev)) { + if (iio_buffer_enabled(indio_dev)) { mutex_unlock(&indio_dev->mlock); return -EBUSY; } @@ -651,7 +647,7 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, switch (m) { case 0: mutex_lock(&indio_dev->mlock); - if (iio_ring_enabled(indio_dev)) + if (iio_buffer_enabled(indio_dev)) ret = ad7793_scan_from_ring(st, chan->scan_index, &smpl); else @@ -678,7 +674,7 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, case (1 << IIO_CHAN_INFO_SCALE_SEPARATE): switch (chan->type) { - case IIO_IN: + case IIO_VOLTAGE: /* 1170mV / 2^23 * 6 */ scale_uv = (1170ULL * 100000000ULL * 6ULL) >> (chan->scan_type.realbits - @@ -713,7 +709,7 @@ static int ad7793_write_raw(struct iio_dev *indio_dev, unsigned int tmp; mutex_lock(&indio_dev->mlock); - if (iio_ring_enabled(indio_dev)) { + if (iio_buffer_enabled(indio_dev)) { mutex_unlock(&indio_dev->mlock); return -EBUSY; } @@ -771,57 +767,137 @@ static const struct iio_info ad7793_info = { static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { [ID_AD7793] = { - .channel[0] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 0, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - AD7793_CH_AIN1P_AIN1M, - 0, IIO_ST('s', 24, 32, 0), 0), - .channel[1] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 1, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - AD7793_CH_AIN2P_AIN2M, - 1, IIO_ST('s', 24, 32, 0), 0), - .channel[2] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 2, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - AD7793_CH_AIN3P_AIN3M, - 2, IIO_ST('s', 24, 32, 0), 0), - .channel[3] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, "shorted", 0, 0, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - AD7793_CH_AIN1M_AIN1M, - 3, IIO_ST('s', 24, 32, 0), 0), - .channel[4] = IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - AD7793_CH_TEMP, - 4, IIO_ST('s', 24, 32, 0), 0), - .channel[5] = IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 4, 0, - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - AD7793_CH_AVDD_MONITOR, - 5, IIO_ST('s', 24, 32, 0), 0), + .channel[0] = { + .type = IIO_VOLTAGE, + .differential = 1, + .indexed = 1, + .channel = 0, + .channel2 = 0, + .address = AD7793_CH_AIN1P_AIN1M, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .scan_index = 0, + .scan_type = IIO_ST('s', 24, 32, 0) + }, + .channel[1] = { + .type = IIO_VOLTAGE, + .differential = 1, + .indexed = 1, + .channel = 1, + .channel2 = 1, + .address = AD7793_CH_AIN2P_AIN2M, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .scan_index = 1, + .scan_type = IIO_ST('s', 24, 32, 0) + }, + .channel[2] = { + .type = IIO_VOLTAGE, + .differential = 1, + .indexed = 1, + .channel = 2, + .channel2 = 2, + .address = AD7793_CH_AIN3P_AIN3M, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .scan_index = 2, + .scan_type = IIO_ST('s', 24, 32, 0) + }, + .channel[3] = { + .type = IIO_VOLTAGE, + .differential = 1, + .extend_name = "shorted", + .indexed = 1, + .channel = 2, + .channel2 = 2, + .address = AD7793_CH_AIN1M_AIN1M, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .scan_index = 2, + .scan_type = IIO_ST('s', 24, 32, 0) + }, + .channel[4] = { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .address = AD7793_CH_TEMP, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .scan_index = 4, + .scan_type = IIO_ST('s', 24, 32, 0), + }, + .channel[5] = { + .type = IIO_VOLTAGE, + .extend_name = "supply", + .indexed = 1, + .channel = 4, + .address = AD7793_CH_AVDD_MONITOR, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .scan_index = 5, + .scan_type = IIO_ST('s', 24, 32, 0), + }, .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), }, [ID_AD7792] = { - .channel[0] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 0, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - AD7793_CH_AIN1P_AIN1M, - 0, IIO_ST('s', 16, 32, 0), 0), - .channel[1] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 1, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - AD7793_CH_AIN2P_AIN2M, - 1, IIO_ST('s', 16, 32, 0), 0), - .channel[2] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 2, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - AD7793_CH_AIN3P_AIN3M, - 2, IIO_ST('s', 16, 32, 0), 0), - .channel[3] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, "shorted", 0, 0, - (1 << IIO_CHAN_INFO_SCALE_SHARED), - AD7793_CH_AIN1M_AIN1M, - 3, IIO_ST('s', 16, 32, 0), 0), - .channel[4] = IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - AD7793_CH_TEMP, - 4, IIO_ST('s', 16, 32, 0), 0), - .channel[5] = IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 4, 0, - (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - AD7793_CH_AVDD_MONITOR, - 5, IIO_ST('s', 16, 32, 0), 0), + .channel[0] = { + .type = IIO_VOLTAGE, + .differential = 1, + .indexed = 1, + .channel = 0, + .channel2 = 0, + .address = AD7793_CH_AIN1P_AIN1M, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .scan_index = 0, + .scan_type = IIO_ST('s', 16, 32, 0) + }, + .channel[1] = { + .type = IIO_VOLTAGE, + .differential = 1, + .indexed = 1, + .channel = 1, + .channel2 = 1, + .address = AD7793_CH_AIN2P_AIN2M, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .scan_index = 1, + .scan_type = IIO_ST('s', 16, 32, 0) + }, + .channel[2] = { + .type = IIO_VOLTAGE, + .differential = 1, + .indexed = 1, + .channel = 2, + .channel2 = 2, + .address = AD7793_CH_AIN3P_AIN3M, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .scan_index = 2, + .scan_type = IIO_ST('s', 16, 32, 0) + }, + .channel[3] = { + .type = IIO_VOLTAGE, + .differential = 1, + .extend_name = "shorted", + .indexed = 1, + .channel = 2, + .channel2 = 2, + .address = AD7793_CH_AIN1M_AIN1M, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), + .scan_index = 2, + .scan_type = IIO_ST('s', 16, 32, 0) + }, + .channel[4] = { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .address = AD7793_CH_TEMP, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .scan_index = 4, + .scan_type = IIO_ST('s', 16, 32, 0), + }, + .channel[5] = { + .type = IIO_VOLTAGE, + .extend_name = "supply", + .indexed = 1, + .channel = 4, + .address = AD7793_CH_AVDD_MONITOR, + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .scan_index = 5, + .scan_type = IIO_ST('s', 16, 32, 0), + }, .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), }, }; @@ -831,7 +907,7 @@ static int __devinit ad7793_probe(struct spi_device *spi) struct ad7793_platform_data *pdata = spi->dev.platform_data; struct ad7793_state *st; struct iio_dev *indio_dev; - int ret, i, voltage_uv = 0, regdone = 0; + int ret, i, voltage_uv = 0; if (!pdata) { dev_err(&spi->dev, "no platform data?\n"); @@ -881,10 +957,12 @@ static int __devinit ad7793_probe(struct spi_device *spi) indio_dev->num_channels = 7; indio_dev->info = &ad7793_info; - for (i = 0; i < indio_dev->num_channels; i++) - st->available_scan_masks[i] = (1 << i) | (1 << - indio_dev->channels[indio_dev->num_channels - 1]. - scan_index); + for (i = 0; i < indio_dev->num_channels; i++) { + set_bit(i, &st->available_scan_masks[i]); + set_bit(indio_dev-> + channels[indio_dev->num_channels - 1].scan_index, + &st->available_scan_masks[i]); + } init_waitqueue_head(&st->wq_data_avail); @@ -892,18 +970,13 @@ static int __devinit ad7793_probe(struct spi_device *spi) if (ret) goto error_disable_reg; - ret = iio_device_register(indio_dev); - if (ret) - goto error_unreg_ring; - regdone = 1; - ret = ad7793_probe_trigger(indio_dev); if (ret) goto error_unreg_ring; - ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, - indio_dev->channels, - indio_dev->num_channels); + ret = iio_buffer_register(indio_dev, + indio_dev->channels, + indio_dev->num_channels); if (ret) goto error_remove_trigger; @@ -911,10 +984,14 @@ static int __devinit ad7793_probe(struct spi_device *spi) if (ret) goto error_uninitialize_ring; + ret = iio_device_register(indio_dev); + if (ret) + goto error_uninitialize_ring; + return 0; error_uninitialize_ring: - iio_ring_buffer_unregister(indio_dev->ring); + iio_buffer_unregister(indio_dev); error_remove_trigger: ad7793_remove_trigger(indio_dev); error_unreg_ring: @@ -926,10 +1003,7 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - if (regdone) - iio_device_unregister(indio_dev); - else - iio_free_device(indio_dev); + iio_free_device(indio_dev); return ret; } @@ -939,7 +1013,8 @@ static int ad7793_remove(struct spi_device *spi) struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7793_state *st = iio_priv(indio_dev); - iio_ring_buffer_unregister(indio_dev->ring); + iio_device_unregister(indio_dev); + iio_buffer_unregister(indio_dev); ad7793_remove_trigger(indio_dev); ad7793_ring_cleanup(indio_dev); @@ -948,7 +1023,7 @@ static int ad7793_remove(struct spi_device *spi) regulator_put(st->reg); } - iio_device_unregister(indio_dev); + iio_free_device(indio_dev); return 0; } |