From c8c194d5c21fc157c2329436e541bf8f33a2ee25 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7793: Remove unused platform_data from device state struct The platform data for the device is only used from within the drivers probe callback, so there is no need to keep it around in the devices state struct. While we are at it mark the platform data struct as const. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 112e2b7..5c2fcd7 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -44,7 +44,6 @@ struct ad7793_state { struct iio_trigger *trig; const struct ad7793_chip_info *chip_info; struct regulator *reg; - struct ad7793_platform_data *pdata; wait_queue_head_t wq_data_avail; bool done; bool irq_dis; @@ -253,7 +252,8 @@ out: return ret; } -static int ad7793_setup(struct ad7793_state *st) +static int ad7793_setup(struct ad7793_state *st, + const struct ad7793_platform_data *pdata) { int i, ret = -1; unsigned long long scale_uv; @@ -277,9 +277,9 @@ static int ad7793_setup(struct ad7793_state *st) goto out; } - st->mode = (st->pdata->mode & ~AD7793_MODE_SEL(-1)) | + st->mode = (pdata->mode & ~AD7793_MODE_SEL(-1)) | AD7793_MODE_SEL(AD7793_MODE_IDLE); - st->conf = st->pdata->conf & ~AD7793_CONF_CHAN(-1); + st->conf = pdata->conf & ~AD7793_CONF_CHAN(-1); ret = ad7793_write_reg(st, AD7793_REG_MODE, sizeof(st->mode), st->mode); if (ret) @@ -290,7 +290,7 @@ static int ad7793_setup(struct ad7793_state *st) goto out; ret = ad7793_write_reg(st, AD7793_REG_IO, - sizeof(st->pdata->io), st->pdata->io); + sizeof(pdata->io), pdata->io); if (ret) goto out; @@ -882,7 +882,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { static int __devinit ad7793_probe(struct spi_device *spi) { - struct ad7793_platform_data *pdata = spi->dev.platform_data; + const struct ad7793_platform_data *pdata = spi->dev.platform_data; struct ad7793_state *st; struct iio_dev *indio_dev; int ret, voltage_uv = 0; @@ -915,8 +915,6 @@ static int __devinit ad7793_probe(struct spi_device *spi) st->chip_info = &ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - st->pdata = pdata; - if (pdata && pdata->vref_mv) st->int_vref_mv = pdata->vref_mv; else if (voltage_uv) @@ -944,7 +942,7 @@ static int __devinit ad7793_probe(struct spi_device *spi) if (ret) goto error_unreg_ring; - ret = ad7793_setup(st); + ret = ad7793_setup(st, pdata); if (ret) goto error_remove_trigger; -- cgit v0.10.2 From 49f8812e4d15970341f0ed320e78951cc16b596d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7192: Remove unused platform_data from device state struct The platform data for the device is only used from within the drivers probe callback, so there is no need to keep it around in the devices state struct. While we are at it mark the platform data struct as const. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 405d9a8..cdb4fc4 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -136,7 +136,6 @@ struct ad7192_state { struct spi_device *spi; struct iio_trigger *trig; struct regulator *reg; - struct ad7192_platform_data *pdata; wait_queue_head_t wq_data_avail; bool done; bool irq_dis; @@ -347,10 +346,10 @@ out: return ret; } -static int ad7192_setup(struct ad7192_state *st) +static int ad7192_setup(struct ad7192_state *st, + const struct ad7192_platform_data *pdata) { struct iio_dev *indio_dev = spi_get_drvdata(st->spi); - struct ad7192_platform_data *pdata = st->pdata; unsigned long long scale_uv; int i, ret, id; u8 ones[6]; @@ -985,7 +984,7 @@ static const struct iio_chan_spec ad7192_channels[] = { static int __devinit ad7192_probe(struct spi_device *spi) { - struct ad7192_platform_data *pdata = spi->dev.platform_data; + const struct ad7192_platform_data *pdata = spi->dev.platform_data; struct ad7192_state *st; struct iio_dev *indio_dev; int ret , voltage_uv = 0; @@ -1015,8 +1014,6 @@ static int __devinit ad7192_probe(struct spi_device *spi) voltage_uv = regulator_get_voltage(st->reg); } - st->pdata = pdata; - if (pdata && pdata->vref_mv) st->int_vref_mv = pdata->vref_mv; else if (voltage_uv) @@ -1047,7 +1044,7 @@ static int __devinit ad7192_probe(struct spi_device *spi) if (ret) goto error_ring_cleanup; - ret = ad7192_setup(st); + ret = ad7192_setup(st, pdata); if (ret) goto error_remove_trigger; -- cgit v0.10.2 From 2d66f389ccf2c3ffea93c0270ef34186e4995333 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: iio: Introduce iio_device_{set,get}_drvdata() Introduce two new helper functions to attach a arbitrary pointer to a IIO device. This is useful to get access to external non-global data from within a IIO device callbacks where only the IIO device is available. Internally these functions use dev_{set,get}_drvdata() on the struct device embedded in the IIO device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index be82936..b18e74e 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -516,6 +516,31 @@ static inline struct iio_dev *iio_device_get(struct iio_dev *indio_dev) return indio_dev ? dev_to_iio_dev(get_device(&indio_dev->dev)) : NULL; } + +/** + * iio_device_set_drvdata() - Set device driver data + * @indio_dev: IIO device structure + * @data: Driver specific data + * + * Allows to attach an arbitrary pointer to an IIO device, which can later be + * retrieved by iio_device_get_drvdata(). + */ +static inline void iio_device_set_drvdata(struct iio_dev *indio_dev, void *data) +{ + dev_set_drvdata(&indio_dev->dev, data); +} + +/** + * iio_device_get_drvdata() - Get device driver data + * @indio_dev: IIO device structure + * + * Returns the data previously set with iio_device_set_drvdata() + */ +static inline void *iio_device_get_drvdata(struct iio_dev *indio_dev) +{ + return dev_get_drvdata(&indio_dev->dev); +} + /* Can we make this smaller? */ #define IIO_ALIGN L1_CACHE_BYTES /** -- cgit v0.10.2 From af3008485ea0372fb9ce1f69f3768617d39eb4e6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: iio:adc: Add common code for ADI Sigma Delta devices Most devices from the Analog Devices Sigma Delta family use a similar scheme for communication with the device. This includes register access, as well as trigger handling. But each device sub-family has different features and different register layouts (some even have no registers at all) and thus it is impractical to try to support all of the devices by the same driver. This patch adds a common base library for Sigma Delta converter devices. It will be used by individual drivers. This code is mostly based on the three existing Sigma Delta drivers the AD7192, AD7780 and AD7793, but has been improved for more robustness and flexibility. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 8a78b4f..a2c5071 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -3,6 +3,11 @@ # menu "Analog to digital converters" +config AD_SIGMA_DELTA + tristate + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + config AD7266 tristate "Analog Devices AD7265/AD7266 ADC driver" depends on SPI_MASTER diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 52eec25..5989356 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -2,5 +2,6 @@ # Makefile for IIO ADC drivers # +obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o obj-$(CONFIG_AD7266) += ad7266.o obj-$(CONFIG_AT91_ADC) += at91_adc.o diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c new file mode 100644 index 0000000..ae847c5 --- /dev/null +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -0,0 +1,558 @@ +/* + * Support code for Analog Devices Sigma-Delta ADCs + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define AD_SD_COMM_CHAN_MASK 0x3 + +#define AD_SD_REG_COMM 0x00 +#define AD_SD_REG_DATA 0x03 + +/** + * ad_sd_set_comm() - Set communications register + * + * @sigma_delta: The sigma delta device + * @comm: New value for the communications register + */ +void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm) +{ + /* Some variants use the lower two bits of the communications register + * to select the channel */ + sigma_delta->comm = comm & AD_SD_COMM_CHAN_MASK; +} +EXPORT_SYMBOL_GPL(ad_sd_set_comm); + +/** + * ad_sd_write_reg() - Write a register + * + * @sigma_delta: The sigma delta device + * @reg: Address of the register + * @size: Size of the register (0-3) + * @val: Value to write to the register + * + * Returns 0 on success, an error code otherwise. + **/ +int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, + unsigned int size, unsigned int val) +{ + uint8_t *data = sigma_delta->data; + struct spi_transfer t = { + .tx_buf = data, + .len = size + 1, + .cs_change = sigma_delta->bus_locked, + }; + struct spi_message m; + int ret; + + data[0] = (reg << sigma_delta->info->addr_shift) | sigma_delta->comm; + + switch (size) { + case 3: + data[1] = val >> 16; + data[2] = val >> 8; + data[3] = val; + break; + case 2: + put_unaligned_be16(val, &data[1]); + break; + case 1: + data[1] = val; + break; + case 0: + break; + default: + return -EINVAL; + } + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + + if (sigma_delta->bus_locked) + ret = spi_sync_locked(sigma_delta->spi, &m); + else + ret = spi_sync(sigma_delta->spi, &m); + + return ret; +} +EXPORT_SYMBOL_GPL(ad_sd_write_reg); + +static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta, + unsigned int reg, unsigned int size, uint8_t *val) +{ + uint8_t *data = sigma_delta->data; + int ret; + struct spi_transfer t[] = { + { + .tx_buf = data, + .len = 1, + }, { + .rx_buf = val, + .len = size, + .cs_change = sigma_delta->bus_locked, + }, + }; + struct spi_message m; + + spi_message_init(&m); + + if (sigma_delta->info->has_registers) { + data[0] = reg << sigma_delta->info->addr_shift; + data[0] |= sigma_delta->info->read_mask; + spi_message_add_tail(&t[0], &m); + } + spi_message_add_tail(&t[1], &m); + + if (sigma_delta->bus_locked) + ret = spi_sync_locked(sigma_delta->spi, &m); + else + ret = spi_sync(sigma_delta->spi, &m); + + return ret; +} + +/** + * ad_sd_read_reg() - Read a register + * + * @sigma_delta: The sigma delta device + * @reg: Address of the register + * @size: Size of the register (1-4) + * @val: Read value + * + * Returns 0 on success, an error code otherwise. + **/ +int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, + unsigned int reg, unsigned int size, unsigned int *val) +{ + int ret; + + ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->data); + if (ret < 0) + goto out; + + switch (size) { + case 4: + *val = get_unaligned_be32(sigma_delta->data); + break; + case 3: + *val = (sigma_delta->data[0] << 16) | + (sigma_delta->data[1] << 8) | + sigma_delta->data[2]; + break; + case 2: + *val = get_unaligned_be16(sigma_delta->data); + break; + case 1: + *val = sigma_delta->data[0]; + break; + default: + ret = -EINVAL; + break; + } + +out: + return ret; +} +EXPORT_SYMBOL_GPL(ad_sd_read_reg); + +static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta, + unsigned int mode, unsigned int channel) +{ + int ret; + + ret = ad_sigma_delta_set_channel(sigma_delta, channel); + if (ret) + return ret; + + spi_bus_lock(sigma_delta->spi->master); + sigma_delta->bus_locked = true; + INIT_COMPLETION(sigma_delta->completion); + + ret = ad_sigma_delta_set_mode(sigma_delta, mode); + if (ret < 0) + goto out; + + sigma_delta->irq_dis = false; + enable_irq(sigma_delta->spi->irq); + ret = wait_for_completion_timeout(&sigma_delta->completion, 2*HZ); + if (ret == 0) { + sigma_delta->irq_dis = true; + disable_irq_nosync(sigma_delta->spi->irq); + ret = -EIO; + } else { + ret = 0; + } +out: + sigma_delta->bus_locked = false; + spi_bus_unlock(sigma_delta->spi->master); + ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); + + return ret; +} + +/** + * ad_sd_calibrate_all() - Performs channel calibration + * @sigma_delta: The sigma delta device + * @cb: Array of channels and calibration type to perform + * @n: Number of items in cb + * + * Returns 0 on success, an error code otherwise. + **/ +int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta, + const struct ad_sd_calib_data *cb, unsigned int n) +{ + unsigned int i; + int ret; + + for (i = 0; i < n; i++) { + ret = ad_sd_calibrate(sigma_delta, cb[i].mode, cb[i].channel); + if (ret) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ad_sd_calibrate_all); + +/** + * ad_sigma_delta_single_conversion() - Performs a single data conversion + * @indio_dev: The IIO device + * @chan: The conversion is done for this channel + * @val: Pointer to the location where to store the read value + * + * Returns: 0 on success, an error value otherwise. + */ +int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *val) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + unsigned int sample, raw_sample; + int ret = 0; + + if (iio_buffer_enabled(indio_dev)) + return -EBUSY; + + mutex_lock(&indio_dev->mlock); + ad_sigma_delta_set_channel(sigma_delta, chan->address); + + spi_bus_lock(sigma_delta->spi->master); + sigma_delta->bus_locked = true; + INIT_COMPLETION(sigma_delta->completion); + + ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_SINGLE); + + sigma_delta->irq_dis = false; + enable_irq(sigma_delta->spi->irq); + ret = wait_for_completion_interruptible_timeout( + &sigma_delta->completion, HZ); + + sigma_delta->bus_locked = false; + spi_bus_unlock(sigma_delta->spi->master); + + if (ret == 0) + ret = -EIO; + if (ret < 0) + goto out; + + ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_DATA, + DIV_ROUND_UP(chan->scan_type.realbits + chan->scan_type.shift, 8), + &raw_sample); + +out: + if (!sigma_delta->irq_dis) { + disable_irq_nosync(sigma_delta->spi->irq); + sigma_delta->irq_dis = true; + } + + ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); + mutex_unlock(&indio_dev->mlock); + + if (ret) + return ret; + + sample = raw_sample >> chan->scan_type.shift; + sample &= (1 << chan->scan_type.realbits) - 1; + *val = sample; + + ret = ad_sigma_delta_postprocess_sample(sigma_delta, raw_sample); + if (ret) + return ret; + + return IIO_VAL_INT; +} +EXPORT_SYMBOL_GPL(ad_sigma_delta_single_conversion); + +static int ad_sd_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + unsigned int channel; + int ret; + + ret = iio_triggered_buffer_postenable(indio_dev); + if (ret < 0) + return ret; + + channel = find_first_bit(indio_dev->active_scan_mask, + indio_dev->masklength); + ret = ad_sigma_delta_set_channel(sigma_delta, + indio_dev->channels[channel].address); + if (ret) + goto err_predisable; + + spi_bus_lock(sigma_delta->spi->master); + sigma_delta->bus_locked = true; + ret = ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_CONTINUOUS); + if (ret) + goto err_unlock; + + sigma_delta->irq_dis = false; + enable_irq(sigma_delta->spi->irq); + + return 0; + +err_unlock: + spi_bus_unlock(sigma_delta->spi->master); +err_predisable: + + return ret; +} + +static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + + INIT_COMPLETION(sigma_delta->completion); + wait_for_completion_timeout(&sigma_delta->completion, HZ); + + if (!sigma_delta->irq_dis) { + disable_irq_nosync(sigma_delta->spi->irq); + sigma_delta->irq_dis = true; + } + + ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); + + sigma_delta->bus_locked = false; + return spi_bus_unlock(sigma_delta->spi->master); +} + +static irqreturn_t ad_sd_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + unsigned int reg_size; + uint8_t data[16]; + int ret; + + memset(data, 0x00, 16); + + /* Guaranteed to be aligned with 8 byte boundary */ + if (indio_dev->scan_timestamp) + ((s64 *)data)[1] = pf->timestamp; + + reg_size = indio_dev->channels[0].scan_type.realbits + + indio_dev->channels[0].scan_type.shift; + reg_size = DIV_ROUND_UP(reg_size, 8); + + switch (reg_size) { + case 4: + case 2: + case 1: + ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA, + reg_size, &data[0]); + break; + case 3: + /* We store 24 bit samples in a 32 bit word. Keep the upper + * byte set to zero. */ + ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA, + reg_size, &data[1]); + break; + } + + iio_push_to_buffer(indio_dev->buffer, (uint8_t *)data, pf->timestamp); + + iio_trigger_notify_done(indio_dev->trig); + sigma_delta->irq_dis = false; + enable_irq(sigma_delta->spi->irq); + + return IRQ_HANDLED; +} + +static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = { + .preenable = &iio_sw_buffer_preenable, + .postenable = &ad_sd_buffer_postenable, + .predisable = &iio_triggered_buffer_predisable, + .postdisable = &ad_sd_buffer_postdisable, + .validate_scan_mask = &iio_validate_scan_mask_onehot, +}; + +static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private) +{ + struct ad_sigma_delta *sigma_delta = private; + + complete(&sigma_delta->completion); + disable_irq_nosync(irq); + sigma_delta->irq_dis = true; + iio_trigger_poll(sigma_delta->trig, iio_get_time_ns()); + + return IRQ_HANDLED; +} + +/** + * ad_sd_validate_trigger() - validate_trigger callback for ad_sigma_delta devices + * @indio_dev: The IIO device + * @trig: The new trigger + * + * Returns: 0 if the 'trig' matches the trigger registered by the ad_sigma_delta + * device, -EINVAL otherwise. + */ +int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + + if (sigma_delta->trig != trig) + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL_GPL(ad_sd_validate_trigger); + +static const struct iio_trigger_ops ad_sd_trigger_ops = { + .owner = THIS_MODULE, +}; + +static int ad_sd_probe_trigger(struct iio_dev *indio_dev) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + int ret; + + sigma_delta->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, + indio_dev->id); + if (sigma_delta->trig == NULL) { + ret = -ENOMEM; + goto error_ret; + } + sigma_delta->trig->ops = &ad_sd_trigger_ops; + init_completion(&sigma_delta->completion); + + ret = request_irq(sigma_delta->spi->irq, + ad_sd_data_rdy_trig_poll, + IRQF_TRIGGER_LOW, + indio_dev->name, + sigma_delta); + if (ret) + goto error_free_trig; + + if (!sigma_delta->irq_dis) { + sigma_delta->irq_dis = true; + disable_irq_nosync(sigma_delta->spi->irq); + } + sigma_delta->trig->dev.parent = &sigma_delta->spi->dev; + sigma_delta->trig->private_data = sigma_delta; + + ret = iio_trigger_register(sigma_delta->trig); + if (ret) + goto error_free_irq; + + /* select default trigger */ + indio_dev->trig = sigma_delta->trig; + + return 0; + +error_free_irq: + free_irq(sigma_delta->spi->irq, sigma_delta); +error_free_trig: + iio_trigger_free(sigma_delta->trig); +error_ret: + return ret; +} + +static void ad_sd_remove_trigger(struct iio_dev *indio_dev) +{ + struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); + + iio_trigger_unregister(sigma_delta->trig); + free_irq(sigma_delta->spi->irq, sigma_delta); + iio_trigger_free(sigma_delta->trig); +} + +/** + * ad_sd_setup_buffer_and_trigger() - + * @indio_dev: The IIO device + */ +int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev) +{ + int ret; + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + &ad_sd_trigger_handler, &ad_sd_buffer_setup_ops); + if (ret) + return ret; + + ret = ad_sd_probe_trigger(indio_dev); + if (ret) { + iio_triggered_buffer_cleanup(indio_dev); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ad_sd_setup_buffer_and_trigger); + +/** + * ad_sd_cleanup_buffer_and_trigger() - + * @indio_dev: The IIO device + */ +void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev) +{ + ad_sd_remove_trigger(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); +} +EXPORT_SYMBOL_GPL(ad_sd_cleanup_buffer_and_trigger); + +/** + * ad_sd_init() - Initializes a ad_sigma_delta struct + * @sigma_delta: The ad_sigma_delta device + * @indio_dev: The IIO device which the Sigma Delta device is used for + * @spi: The SPI device for the ad_sigma_delta device + * @info: Device specific callbacks and options + * + * This function needs to be called before any other operations are performed on + * the ad_sigma_delta struct. + */ +int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev, + struct spi_device *spi, const struct ad_sigma_delta_info *info) +{ + sigma_delta->spi = spi; + sigma_delta->info = info; + iio_device_set_drvdata(indio_dev, sigma_delta); + + return 0; +} +EXPORT_SYMBOL_GPL(ad_sd_init); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Analog Devices Sigma-Delta ADCs"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h new file mode 100644 index 0000000..2e4eab9 --- /dev/null +++ b/include/linux/iio/adc/ad_sigma_delta.h @@ -0,0 +1,173 @@ +/* + * Support code for Analog Devices Sigma-Delta ADCs + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ +#ifndef __AD_SIGMA_DELTA_H__ +#define __AD_SIGMA_DELTA_H__ + +enum ad_sigma_delta_mode { + AD_SD_MODE_CONTINUOUS = 0, + AD_SD_MODE_SINGLE = 1, + AD_SD_MODE_IDLE = 2, + AD_SD_MODE_POWERDOWN = 3, +}; + +/** + * struct ad_sigma_delta_calib_data - Calibration data for Sigma Delta devices + * @mode: Calibration mode. + * @channel: Calibration channel. + */ +struct ad_sd_calib_data { + unsigned int mode; + unsigned int channel; +}; + +struct ad_sigma_delta; +struct iio_dev; + +/** + * struct ad_sigma_delta_info - Sigma Delta driver specific callbacks and options + * @set_channel: Will be called to select the current channel, may be NULL. + * @set_mode: Will be called to select the current mode, may be NULL. + * @postprocess_sample: Is called for each sampled data word, can be used to + * modify or drop the sample data, it, may be NULL. + * @has_registers: true if the device has writable and readable registers, false + * if there is just one read-only sample data shift register. + * @addr_shift: Shift of the register address in the communications register. + * @read_mask: Mask for the communications register having the read bit set. + */ +struct ad_sigma_delta_info { + int (*set_channel)(struct ad_sigma_delta *, unsigned int channel); + int (*set_mode)(struct ad_sigma_delta *, enum ad_sigma_delta_mode mode); + int (*postprocess_sample)(struct ad_sigma_delta *, unsigned int raw_sample); + bool has_registers; + unsigned int addr_shift; + unsigned int read_mask; +}; + +/** + * struct ad_sigma_delta - Sigma Delta device struct + * @spi: The spi device associated with the Sigma Delta device. + * @trig: The IIO trigger associated with the Sigma Delta device. + * + * Most of the fields are private to the sigma delta library code and should not + * be accessed by individual drivers. + */ +struct ad_sigma_delta { + struct spi_device *spi; + struct iio_trigger *trig; + +/* private: */ + struct completion completion; + bool irq_dis; + + bool bus_locked; + + uint8_t comm; + + const struct ad_sigma_delta_info *info; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + uint8_t data[4] ____cacheline_aligned; +}; + +static inline int ad_sigma_delta_set_channel(struct ad_sigma_delta *sd, + unsigned int channel) +{ + if (sd->info->set_channel) + return sd->info->set_channel(sd, channel); + + return 0; +} + +static inline int ad_sigma_delta_set_mode(struct ad_sigma_delta *sd, + unsigned int mode) +{ + if (sd->info->set_mode) + return sd->info->set_mode(sd, mode); + + return 0; +} + +static inline int ad_sigma_delta_postprocess_sample(struct ad_sigma_delta *sd, + unsigned int raw_sample) +{ + if (sd->info->postprocess_sample) + return sd->info->postprocess_sample(sd, raw_sample); + + return 0; +} + +void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm); +int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, + unsigned int size, unsigned int val); +int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, + unsigned int size, unsigned int *val); + +int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *val); +int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta, + const struct ad_sd_calib_data *cd, unsigned int n); +int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev, + struct spi_device *spi, const struct ad_sigma_delta_info *info); + +int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev); +void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev); + +int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig); + +#define __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ + _storagebits, _shift, _extend_name, _type) \ + { \ + .type = (_type), \ + .differential = (_channel2 == -1 ? 0 : 1), \ + .indexed = 1, \ + .channel = (_channel1), \ + .channel2 = (_channel2), \ + .address = (_address), \ + .extend_name = (_extend_name), \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \ + .scan_index = (_si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (_bits), \ + .storagebits = (_storagebits), \ + .shift = (_shift), \ + .endianness = IIO_BE, \ + }, \ + } + +#define AD_SD_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ + _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ + _storagebits, _shift, NULL, IIO_VOLTAGE) + +#define AD_SD_SHORTED_CHANNEL(_si, _channel, _address, _bits, \ + _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, _channel, _channel, _address, _bits, \ + _storagebits, _shift, "shorted", IIO_VOLTAGE) + +#define AD_SD_CHANNEL(_si, _channel, _address, _bits, \ + _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \ + _storagebits, _shift, NULL, IIO_VOLTAGE) + +#define AD_SD_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, 0, -1, _address, _bits, \ + _storagebits, _shift, NULL, IIO_TEMP) + +#define AD_SD_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \ + _shift) \ + __AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \ + _storagebits, _shift, "supply", IIO_VOLTAGE) + +#endif -- cgit v0.10.2 From 32e0e7e08c32fbd61ddfb7e80ba96c13085f3d39 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7780: Use common Sigma Delta library Convert the ad7780 driver to make use of the new common code for devices from the Analog Devices Sigma Delta family. As a bonus the ad7780 driver gains support for buffered mode. Although this is a bit tricky. The ad7780 reports in the lower 4 unused bits of the data word the internal gain used. The driver will update the scale attribute value depending on the gain accordingly, but obviously this will only work if the gain does not change while sampling. This is not perfect, but since we store the raw value in the buffer an application which is aware of this can extract the gain factor from the buffer as well an apply it accordingly. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 845fb6c..d0eb27b 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -99,6 +99,7 @@ config AD7780 tristate "Analog Devices AD7780 AD7781 ADC driver" depends on SPI depends on GPIOLIB + select AD_SIGMA_DELTA help Say yes here to build support for Analog Devices AD7780 and AD7781 SPI analog to digital converters (ADC). diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 19ee49c..853f8b1 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -20,6 +20,7 @@ #include #include +#include #include "ad7780.h" @@ -37,20 +38,13 @@ struct ad7780_chip_info { }; struct ad7780_state { - struct spi_device *spi; const struct ad7780_chip_info *chip_info; struct regulator *reg; - struct ad7780_platform_data *pdata; - wait_queue_head_t wq_data_avail; - bool done; + int powerdown_gpio; + unsigned int gain; u16 int_vref_mv; - struct spi_transfer xfer; - struct spi_message msg; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - */ - unsigned int data ____cacheline_aligned; + + struct ad_sigma_delta sd; }; enum ad7780_supported_device_ids { @@ -58,28 +52,30 @@ enum ad7780_supported_device_ids { ID_AD7781, }; -static int ad7780_read(struct ad7780_state *st, int *val) +static struct ad7780_state *ad_sigma_delta_to_ad7780(struct ad_sigma_delta *sd) { - int ret; - - spi_bus_lock(st->spi->master); - - enable_irq(st->spi->irq); - st->done = false; - gpio_set_value(st->pdata->gpio_pdrst, 1); + return container_of(sd, struct ad7780_state, sd); +} - ret = wait_event_interruptible(st->wq_data_avail, st->done); - disable_irq_nosync(st->spi->irq); - if (ret) - goto out; +static int ad7780_set_mode(struct ad_sigma_delta *sigma_delta, + enum ad_sigma_delta_mode mode) +{ + struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta); + unsigned val; + + switch (mode) { + case AD_SD_MODE_SINGLE: + case AD_SD_MODE_CONTINUOUS: + val = 1; + break; + default: + val = 0; + break; + } - ret = spi_sync_locked(st->spi, &st->msg); - *val = be32_to_cpu(st->data); -out: - gpio_set_value(st->pdata->gpio_pdrst, 0); - spi_bus_unlock(st->spi->master); + gpio_set_value(st->powerdown_gpio, val); - return ret; + return 0; } static int ad7780_read_raw(struct iio_dev *indio_dev, @@ -89,89 +85,57 @@ static int ad7780_read_raw(struct iio_dev *indio_dev, long m) { struct ad7780_state *st = iio_priv(indio_dev); - struct iio_chan_spec channel = st->chip_info->channel; - int ret, smpl = 0; unsigned long scale_uv; switch (m) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - ret = ad7780_read(st, &smpl); - mutex_unlock(&indio_dev->mlock); - - if (ret < 0) - return ret; - - if ((smpl & AD7780_ERR) || - !((smpl & AD7780_PAT0) && !(smpl & AD7780_PAT1))) - return -EIO; - - *val = (smpl >> channel.scan_type.shift) & - ((1 << (channel.scan_type.realbits)) - 1); - *val -= (1 << (channel.scan_type.realbits - 1)); - - if (!(smpl & AD7780_GAIN)) - *val *= 128; - - return IIO_VAL_INT; + return ad_sigma_delta_single_conversion(indio_dev, chan, val); case IIO_CHAN_INFO_SCALE: - scale_uv = (st->int_vref_mv * 100000) - >> (channel.scan_type.realbits - 1); + 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; } + return -EINVAL; } +static int ad7780_postprocess_sample(struct ad_sigma_delta *sigma_delta, + unsigned int raw_sample) +{ + struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta); + + if ((raw_sample & AD7780_ERR) || + !((raw_sample & AD7780_PAT0) && !(raw_sample & AD7780_PAT1))) + return -EIO; + + if (raw_sample & AD7780_GAIN) + st->gain = 1; + else + st->gain = 128; + + return 0; +} + +static const struct ad_sigma_delta_info ad7780_sigma_delta_info = { + .set_mode = ad7780_set_mode, + .postprocess_sample = ad7780_postprocess_sample, + .has_registers = false, +}; + static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { [ID_AD7780] = { - .channel = { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_type = { - .sign = 'u', - .realbits = 24, - .storagebits = 32, - .shift = 8, - }, - }, + .channel = AD_SD_CHANNEL(1, 0, 0, 24, 32, 8), }, [ID_AD7781] = { - .channel = { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_type = { - .sign = 'u', - .realbits = 20, - .storagebits = 32, - .shift = 12, - }, - }, + .channel = AD_SD_CHANNEL(1, 0, 0, 20, 32, 12), }, }; -/** - * Interrupt handler - */ -static irqreturn_t ad7780_interrupt(int irq, void *dev_id) -{ - struct ad7780_state *st = dev_id; - - st->done = true; - wake_up_interruptible(&st->wq_data_avail); - - return IRQ_HANDLED; -}; - static const struct iio_info ad7780_info = { .read_raw = &ad7780_read_raw, .driver_module = THIS_MODULE, @@ -194,6 +158,9 @@ static int __devinit ad7780_probe(struct spi_device *spi) return -ENOMEM; st = iio_priv(indio_dev); + st->gain = 1; + + ad_sd_init(&st->sd, indio_dev, spi, &ad7780_sigma_delta_info); st->reg = regulator_get(&spi->dev, "vcc"); if (!IS_ERR(st->reg)) { @@ -207,7 +174,7 @@ static int __devinit ad7780_probe(struct spi_device *spi) st->chip_info = &ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - st->pdata = pdata; + st->powerdown_gpio = pdata->gpio_pdrst; if (pdata && pdata->vref_mv) st->int_vref_mv = pdata->vref_mv; @@ -217,7 +184,6 @@ static int __devinit ad7780_probe(struct spi_device *spi) dev_warn(&spi->dev, "reference voltage unspecified\n"); spi_set_drvdata(spi, indio_dev); - st->spi = spi; indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; @@ -226,40 +192,27 @@ static int __devinit ad7780_probe(struct spi_device *spi) indio_dev->num_channels = 1; indio_dev->info = &ad7780_info; - init_waitqueue_head(&st->wq_data_avail); - - /* Setup default message */ - - st->xfer.rx_buf = &st->data; - st->xfer.len = st->chip_info->channel.scan_type.storagebits / 8; - - spi_message_init(&st->msg); - spi_message_add_tail(&st->xfer, &st->msg); - - ret = gpio_request_one(st->pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW, + 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; } - ret = request_irq(spi->irq, ad7780_interrupt, - IRQF_TRIGGER_FALLING, spi_get_device_id(spi)->name, st); + ret = ad_sd_setup_buffer_and_trigger(indio_dev); if (ret) goto error_free_gpio; - disable_irq(spi->irq); - ret = iio_device_register(indio_dev); if (ret) - goto error_free_irq; + goto error_cleanup_buffer_and_trigger; return 0; -error_free_irq: - free_irq(spi->irq, st); +error_cleanup_buffer_and_trigger: + ad_sd_cleanup_buffer_and_trigger(indio_dev); error_free_gpio: - gpio_free(st->pdata->gpio_pdrst); + gpio_free(pdata->gpio_pdrst); error_disable_reg: if (!IS_ERR(st->reg)) regulator_disable(st->reg); @@ -278,8 +231,9 @@ static int ad7780_remove(struct spi_device *spi) struct ad7780_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - free_irq(spi->irq, st); - gpio_free(st->pdata->gpio_pdrst); + ad_sd_cleanup_buffer_and_trigger(indio_dev); + + gpio_free(st->powerdown_gpio); if (!IS_ERR(st->reg)) { regulator_disable(st->reg); regulator_put(st->reg); -- cgit v0.10.2 From 1abec6ac69fe5aea1013c1e8f764d9e71a8e64c4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7793: Use common Sigma Delta library Convert the ad7793 driver to make use of the new common code for devices from the Analog Devices Sigma Delta family. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index d0eb27b..f7d7e44 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -111,8 +111,7 @@ config AD7780 config AD7793 tristate "Analog Devices AD7792 AD7793 ADC driver" depends on SPI - select IIO_BUFFER - select IIO_TRIGGERED_BUFFER + select AD_SIGMA_DELTA help Say yes here to build support for Analog Devices AD7792 and AD7793 SPI analog to digital converters (ADC). diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 5c2fcd7..9033595 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "ad7793.h" @@ -36,27 +37,19 @@ */ struct ad7793_chip_info { - struct iio_chan_spec channel[7]; + struct iio_chan_spec channel[7]; }; struct ad7793_state { - struct spi_device *spi; - struct iio_trigger *trig; const struct ad7793_chip_info *chip_info; struct regulator *reg; - wait_queue_head_t wq_data_avail; - bool done; - bool irq_dis; u16 int_vref_mv; u16 mode; u16 conf; u32 scale_avail[8][2]; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - */ - u8 data[4] ____cacheline_aligned; + struct ad_sigma_delta sd; + }; enum ad7793_supported_device_ids { @@ -64,169 +57,41 @@ enum ad7793_supported_device_ids { ID_AD7793, }; -static int __ad7793_write_reg(struct ad7793_state *st, bool locked, - bool cs_change, unsigned char reg, - unsigned size, unsigned val) +static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd) { - u8 *data = st->data; - struct spi_transfer t = { - .tx_buf = data, - .len = size + 1, - .cs_change = cs_change, - }; - struct spi_message m; - - data[0] = AD7793_COMM_WRITE | AD7793_COMM_ADDR(reg); - - switch (size) { - case 3: - data[1] = val >> 16; - data[2] = val >> 8; - data[3] = val; - break; - case 2: - data[1] = val >> 8; - data[2] = val; - break; - case 1: - data[1] = val; - break; - default: - return -EINVAL; - } - - spi_message_init(&m); - spi_message_add_tail(&t, &m); - - if (locked) - return spi_sync_locked(st->spi, &m); - else - return spi_sync(st->spi, &m); + return container_of(sd, struct ad7793_state, sd); } -static int ad7793_write_reg(struct ad7793_state *st, - unsigned reg, unsigned size, unsigned val) +static int ad7793_set_channel(struct ad_sigma_delta *sd, unsigned int channel) { - return __ad7793_write_reg(st, false, false, reg, size, val); -} + struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd); -static int __ad7793_read_reg(struct ad7793_state *st, bool locked, - bool cs_change, unsigned char reg, - int *val, unsigned size) -{ - u8 *data = st->data; - int ret; - struct spi_transfer t[] = { - { - .tx_buf = data, - .len = 1, - }, { - .rx_buf = data, - .len = size, - .cs_change = cs_change, - }, - }; - struct spi_message m; - - data[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(reg); - - spi_message_init(&m); - spi_message_add_tail(&t[0], &m); - spi_message_add_tail(&t[1], &m); - - if (locked) - ret = spi_sync_locked(st->spi, &m); - else - ret = spi_sync(st->spi, &m); + st->conf &= ~AD7793_CONF_CHAN_MASK; + st->conf |= AD7793_CONF_CHAN(channel); - if (ret < 0) - return ret; - - switch (size) { - case 3: - *val = data[0] << 16 | data[1] << 8 | data[2]; - break; - case 2: - *val = data[0] << 8 | data[1]; - break; - case 1: - *val = data[0]; - break; - default: - return -EINVAL; - } - - return 0; + return ad_sd_write_reg(&st->sd, AD7793_REG_CONF, 2, st->conf); } -static int ad7793_read_reg(struct ad7793_state *st, - unsigned reg, int *val, unsigned size) +static int ad7793_set_mode(struct ad_sigma_delta *sd, + enum ad_sigma_delta_mode mode) { - return __ad7793_read_reg(st, 0, 0, reg, val, size); -} - -static int ad7793_read(struct ad7793_state *st, unsigned ch, - unsigned len, int *val) -{ - int ret; - st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | AD7793_CONF_CHAN(ch); - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | - AD7793_MODE_SEL(AD7793_MODE_SINGLE); + struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd); - ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); + st->mode &= ~AD7793_MODE_SEL_MASK; + st->mode |= AD7793_MODE_SEL(mode); - spi_bus_lock(st->spi->master); - st->done = false; - - ret = __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, - sizeof(st->mode), st->mode); - if (ret < 0) - goto out; - - st->irq_dis = false; - enable_irq(st->spi->irq); - wait_event_interruptible(st->wq_data_avail, st->done); - - ret = __ad7793_read_reg(st, 1, 0, AD7793_REG_DATA, val, len); -out: - spi_bus_unlock(st->spi->master); - - return ret; + return ad_sd_write_reg(&st->sd, AD7793_REG_MODE, 2, st->mode); } -static int ad7793_calibrate(struct ad7793_state *st, unsigned mode, unsigned ch) -{ - int ret; - - st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | AD7793_CONF_CHAN(ch); - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | AD7793_MODE_SEL(mode); - - ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); - - spi_bus_lock(st->spi->master); - st->done = false; - - ret = __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, - sizeof(st->mode), st->mode); - if (ret < 0) - goto out; - - st->irq_dis = false; - enable_irq(st->spi->irq); - wait_event_interruptible(st->wq_data_avail, st->done); - - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | - AD7793_MODE_SEL(AD7793_MODE_IDLE); - - ret = __ad7793_write_reg(st, 1, 0, AD7793_REG_MODE, - sizeof(st->mode), st->mode); -out: - spi_bus_unlock(st->spi->master); - - return ret; -} +static const struct ad_sigma_delta_info ad7793_sigma_delta_info = { + .set_channel = ad7793_set_channel, + .set_mode = ad7793_set_mode, + .has_registers = true, + .addr_shift = 3, + .read_mask = BIT(6), +}; -static const u8 ad7793_calib_arr[6][2] = { +static const struct ad_sd_calib_data ad7793_calib_arr[6] = { {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M}, {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M}, {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN2P_AIN2M}, @@ -237,59 +102,48 @@ static const u8 ad7793_calib_arr[6][2] = { static int ad7793_calibrate_all(struct ad7793_state *st) { - int i, ret; - - for (i = 0; i < ARRAY_SIZE(ad7793_calib_arr); i++) { - ret = ad7793_calibrate(st, ad7793_calib_arr[i][0], - ad7793_calib_arr[i][1]); - if (ret) - goto out; - } - - return 0; -out: - dev_err(&st->spi->dev, "Calibration failed\n"); - return ret; + return ad_sd_calibrate_all(&st->sd, ad7793_calib_arr, + ARRAY_SIZE(ad7793_calib_arr)); } -static int ad7793_setup(struct ad7793_state *st, +static int ad7793_setup(struct iio_dev *indio_dev, const struct ad7793_platform_data *pdata) { + struct ad7793_state *st = iio_priv(indio_dev); int i, ret = -1; unsigned long long scale_uv; u32 id; /* reset the serial interface */ - ret = spi_write(st->spi, (u8 *)&ret, sizeof(ret)); + ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret)); if (ret < 0) goto out; msleep(1); /* Wait for at least 500us */ /* write/read test for device presence */ - ret = ad7793_read_reg(st, AD7793_REG_ID, &id, 1); + ret = ad_sd_read_reg(&st->sd, AD7793_REG_ID, 1, &id); if (ret) goto out; id &= AD7793_ID_MASK; if (!((id == AD7792_ID) || (id == AD7793_ID))) { - dev_err(&st->spi->dev, "device ID query failed\n"); + dev_err(&st->sd.spi->dev, "device ID query failed\n"); goto out; } - st->mode = (pdata->mode & ~AD7793_MODE_SEL(-1)) | - AD7793_MODE_SEL(AD7793_MODE_IDLE); - st->conf = pdata->conf & ~AD7793_CONF_CHAN(-1); + st->mode = pdata->mode; + st->conf = pdata->conf; - ret = ad7793_write_reg(st, AD7793_REG_MODE, sizeof(st->mode), st->mode); + ret = ad7793_set_mode(&st->sd, AD_SD_MODE_IDLE); if (ret) goto out; - ret = ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); + ret = ad7793_set_channel(&st->sd, 0); if (ret) goto out; - ret = ad7793_write_reg(st, AD7793_REG_IO, + ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, sizeof(pdata->io), pdata->io); if (ret) goto out; @@ -311,184 +165,10 @@ static int ad7793_setup(struct ad7793_state *st, return 0; out: - dev_err(&st->spi->dev, "setup failed\n"); - return ret; -} - -static int ad7793_ring_preenable(struct iio_dev *indio_dev) -{ - struct ad7793_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); - - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | - AD7793_MODE_SEL(AD7793_MODE_CONT); - st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | - AD7793_CONF_CHAN(indio_dev->channels[channel].address); - - ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); - - spi_bus_lock(st->spi->master); - __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, - sizeof(st->mode), st->mode); - - st->irq_dis = false; - enable_irq(st->spi->irq); - - return 0; -} - -static int ad7793_ring_postdisable(struct iio_dev *indio_dev) -{ - struct ad7793_state *st = iio_priv(indio_dev); - - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | - AD7793_MODE_SEL(AD7793_MODE_IDLE); - - st->done = false; - wait_event_interruptible(st->wq_data_avail, st->done); - - if (!st->irq_dis) - disable_irq_nosync(st->spi->irq); - - __ad7793_write_reg(st, 1, 0, AD7793_REG_MODE, - sizeof(st->mode), st->mode); - - return spi_bus_unlock(st->spi->master); -} - -/** - * ad7793_trigger_handler() bh of trigger launched polling to ring buffer - **/ - -static irqreturn_t ad7793_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - 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; - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) - __ad7793_read_reg(st, 1, 1, AD7793_REG_DATA, - dat32, - indio_dev->channels[0].scan_type.realbits/8); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - dat64[1] = pf->timestamp; - - ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); - - iio_trigger_notify_done(indio_dev->trig); - st->irq_dis = false; - enable_irq(st->spi->irq); - - return IRQ_HANDLED; -} - -static const struct iio_buffer_setup_ops ad7793_ring_setup_ops = { - .preenable = &ad7793_ring_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, - .postdisable = &ad7793_ring_postdisable, - .validate_scan_mask = &iio_validate_scan_mask_onehot, -}; - -static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - &ad7793_trigger_handler, &ad7793_ring_setup_ops); -} - -static void ad7793_ring_cleanup(struct iio_dev *indio_dev) -{ - iio_triggered_buffer_cleanup(indio_dev); -} - -/** - * ad7793_data_rdy_trig_poll() the event handler for the data rdy trig - **/ -static irqreturn_t ad7793_data_rdy_trig_poll(int irq, void *private) -{ - struct ad7793_state *st = iio_priv(private); - - st->done = true; - wake_up_interruptible(&st->wq_data_avail); - disable_irq_nosync(irq); - st->irq_dis = true; - iio_trigger_poll(st->trig, iio_get_time_ns()); - - return IRQ_HANDLED; -} - -static struct iio_trigger_ops ad7793_trigger_ops = { - .owner = THIS_MODULE, -}; - -static int ad7793_probe_trigger(struct iio_dev *indio_dev) -{ - struct ad7793_state *st = iio_priv(indio_dev); - int ret; - - st->trig = iio_trigger_alloc("%s-dev%d", - spi_get_device_id(st->spi)->name, - indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - st->trig->ops = &ad7793_trigger_ops; - - ret = request_irq(st->spi->irq, - ad7793_data_rdy_trig_poll, - IRQF_TRIGGER_LOW, - spi_get_device_id(st->spi)->name, - indio_dev); - if (ret) - goto error_free_trig; - - disable_irq_nosync(st->spi->irq); - st->irq_dis = true; - st->trig->dev.parent = &st->spi->dev; - st->trig->private_data = indio_dev; - - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->spi->irq, indio_dev); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: + dev_err(&st->sd.spi->dev, "setup failed\n"); return ret; } -static void ad7793_remove_trigger(struct iio_dev *indio_dev) -{ - struct ad7793_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->spi->irq, indio_dev); - iio_trigger_free(st->trig); -} - static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19, 17, 16, 12, 10, 8, 6, 4}; @@ -531,7 +211,7 @@ static ssize_t ad7793_write_frequency(struct device *dev, mutex_lock(&indio_dev->mlock); st->mode &= ~AD7793_MODE_RATE(-1); st->mode |= AD7793_MODE_RATE(i); - ad7793_write_reg(st, AD7793_REG_MODE, + ad_sd_write_reg(&st->sd, AD7793_REG_MODE, sizeof(st->mode), st->mode); mutex_unlock(&indio_dev->mlock); ret = 0; @@ -585,26 +265,16 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, long m) { struct ad7793_state *st = iio_priv(indio_dev); - int ret, smpl = 0; + int ret; unsigned long long scale_uv; bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR); switch (m) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) - ret = -EBUSY; - else - ret = ad7793_read(st, chan->address, - chan->scan_type.realbits / 8, &smpl); - mutex_unlock(&indio_dev->mlock); - + ret = ad_sigma_delta_single_conversion(indio_dev, chan, val); if (ret < 0) return ret; - *val = (smpl >> chan->scan_type.shift) & - ((1 << (chan->scan_type.realbits)) - 1); - return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: @@ -675,17 +345,18 @@ static int ad7793_write_raw(struct iio_dev *indio_dev, ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) if (val2 == st->scale_avail[i][1]) { + ret = 0; tmp = st->conf; st->conf &= ~AD7793_CONF_GAIN(-1); st->conf |= AD7793_CONF_GAIN(i); - if (tmp != st->conf) { - ad7793_write_reg(st, AD7793_REG_CONF, - sizeof(st->conf), - st->conf); - ad7793_calibrate_all(st); - } - ret = 0; + if (tmp == st->conf) + break; + + ad_sd_write_reg(&st->sd, AD7793_REG_CONF, + sizeof(st->conf), st->conf); + ad7793_calibrate_all(st); + break; } break; default: @@ -696,15 +367,6 @@ static int ad7793_write_raw(struct iio_dev *indio_dev, return ret; } -static int ad7793_validate_trigger(struct iio_dev *indio_dev, - struct iio_trigger *trig) -{ - if (indio_dev->trig != trig) - return -EINVAL; - - return 0; -} - static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, long mask) @@ -717,166 +379,32 @@ static const struct iio_info ad7793_info = { .write_raw = &ad7793_write_raw, .write_raw_get_fmt = &ad7793_write_raw_get_fmt, .attrs = &ad7793_attribute_group, - .validate_trigger = ad7793_validate_trigger, + .validate_trigger = ad_sd_validate_trigger, .driver_module = THIS_MODULE, }; static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { [ID_AD7793] = { - .channel[0] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 0, - .channel2 = 0, - .address = AD7793_CH_AIN1P_AIN1M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 0, - .scan_type = IIO_ST('u', 24, 32, 0) - }, - .channel[1] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 1, - .channel2 = 1, - .address = AD7793_CH_AIN2P_AIN2M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 1, - .scan_type = IIO_ST('u', 24, 32, 0) - }, - .channel[2] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 2, - .channel2 = 2, - .address = AD7793_CH_AIN3P_AIN3M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 2, - .scan_type = IIO_ST('u', 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 = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 3, - .scan_type = IIO_ST('u', 24, 32, 0) - }, - .channel[4] = { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .address = AD7793_CH_TEMP, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .scan_index = 4, - .scan_type = IIO_ST('u', 24, 32, 0), + .channel = { + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, 24, 32, 0), + AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, 24, 32, 0), + AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, 24, 32, 0), + AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, 24, 32, 0), + AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, 24, 32, 0), + AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, 24, 32, 0), + IIO_CHAN_SOFT_TIMESTAMP(6), }, - .channel[5] = { - .type = IIO_VOLTAGE, - .extend_name = "supply", - .indexed = 1, - .channel = 4, - .address = AD7793_CH_AVDD_MONITOR, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 5, - .scan_type = IIO_ST('u', 24, 32, 0), - }, - .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), }, [ID_AD7792] = { - .channel[0] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 0, - .channel2 = 0, - .address = AD7793_CH_AIN1P_AIN1M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 0, - .scan_type = IIO_ST('u', 16, 32, 0) - }, - .channel[1] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 1, - .channel2 = 1, - .address = AD7793_CH_AIN2P_AIN2M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 1, - .scan_type = IIO_ST('u', 16, 32, 0) - }, - .channel[2] = { - .type = IIO_VOLTAGE, - .differential = 1, - .indexed = 1, - .channel = 2, - .channel2 = 2, - .address = AD7793_CH_AIN3P_AIN3M, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 2, - .scan_type = IIO_ST('u', 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 = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 3, - .scan_type = IIO_ST('u', 16, 32, 0) - }, - .channel[4] = { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .address = AD7793_CH_TEMP, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .scan_index = 4, - .scan_type = IIO_ST('u', 16, 32, 0), + .channel = { + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, 16, 32, 0), + AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, 16, 32, 0), + AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, 16, 32, 0), + AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, 16, 32, 0), + AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, 16, 32, 0), + AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, 16, 32, 0), + IIO_CHAN_SOFT_TIMESTAMP(6), }, - .channel[5] = { - .type = IIO_VOLTAGE, - .extend_name = "supply", - .indexed = 1, - .channel = 4, - .address = AD7793_CH_AVDD_MONITOR, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SHARED_BIT, - .scan_index = 5, - .scan_type = IIO_ST('u', 16, 32, 0), - }, - .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), }, }; @@ -903,6 +431,8 @@ static int __devinit ad7793_probe(struct spi_device *spi) st = iio_priv(indio_dev); + ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info); + st->reg = regulator_get(&spi->dev, "vcc"); if (!IS_ERR(st->reg)) { ret = regulator_enable(st->reg); @@ -923,7 +453,6 @@ static int __devinit ad7793_probe(struct spi_device *spi) st->int_vref_mv = 1170; /* Build-in ref */ spi_set_drvdata(spi, indio_dev); - st->spi = spi; indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; @@ -932,17 +461,11 @@ static int __devinit ad7793_probe(struct spi_device *spi) indio_dev->num_channels = 7; indio_dev->info = &ad7793_info; - init_waitqueue_head(&st->wq_data_avail); - - ret = ad7793_register_ring_funcs_and_init(indio_dev); + ret = ad_sd_setup_buffer_and_trigger(indio_dev); if (ret) goto error_disable_reg; - ret = ad7793_probe_trigger(indio_dev); - if (ret) - goto error_unreg_ring; - - ret = ad7793_setup(st, pdata); + ret = ad7793_setup(indio_dev, pdata); if (ret) goto error_remove_trigger; @@ -953,9 +476,7 @@ static int __devinit ad7793_probe(struct spi_device *spi) return 0; error_remove_trigger: - ad7793_remove_trigger(indio_dev); -error_unreg_ring: - ad7793_ring_cleanup(indio_dev); + ad_sd_cleanup_buffer_and_trigger(indio_dev); error_disable_reg: if (!IS_ERR(st->reg)) regulator_disable(st->reg); @@ -974,8 +495,7 @@ static int ad7793_remove(struct spi_device *spi) struct ad7793_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - ad7793_remove_trigger(indio_dev); - ad7793_ring_cleanup(indio_dev); + ad_sd_cleanup_buffer_and_trigger(indio_dev); if (!IS_ERR(st->reg)) { regulator_disable(st->reg); diff --git a/drivers/staging/iio/adc/ad7793.h b/drivers/staging/iio/adc/ad7793.h index 64f7d41..0e296d8 100644 --- a/drivers/staging/iio/adc/ad7793.h +++ b/drivers/staging/iio/adc/ad7793.h @@ -41,6 +41,7 @@ /* Mode Register Bit Designations (AD7793_REG_MODE) */ #define AD7793_MODE_SEL(x) (((x) & 0x7) << 13) /* Operation Mode Select */ +#define AD7793_MODE_SEL_MASK (0x7 << 13) /* Operation Mode Select mask */ #define AD7793_MODE_CLKSRC(x) (((x) & 0x3) << 6) /* ADC Clock Source Select */ #define AD7793_MODE_RATE(x) ((x) & 0xF) /* Filter Update Rate Select */ @@ -70,6 +71,7 @@ #define AD7793_CONF_REFSEL (1 << 7) /* INT/EXT Reference Select */ #define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */ #define AD7793_CONF_CHAN(x) ((x) & 0x7) /* Channel select */ +#define AD7793_CONF_CHAN_MASK 0x7 /* Channel select mask */ #define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */ #define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */ -- cgit v0.10.2 From 3f7c3306cf385d015d84c741e5433781f83d9254 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7192: Use common Sigma Delta library Convert the ad7192 driver to make use of the new common code for devices from the Analog Devices Sigma Delta family. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index f7d7e44..3f1f2c3 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -131,8 +131,7 @@ config AD7816 config AD7192 tristate "Analog Devices AD7190 AD7192 AD7195 ADC driver" depends on SPI - select IIO_BUFFER - select IIO_TRIGGERED_BUFFER + select AD_SIGMA_DELTA help Say yes here to build support for Analog Devices AD7190, AD7192 or AD7195 SPI analog to digital converters (ADC). diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index cdb4fc4..189d951 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "ad7192.h" @@ -57,6 +58,7 @@ /* Mode Register Bit Designations (AD7192_REG_MODE) */ #define AD7192_MODE_SEL(x) (((x) & 0x7) << 21) /* Operation Mode Select */ +#define AD7192_MODE_SEL_MASK (0x7 << 21) /* Operation Mode Select Mask */ #define AD7192_MODE_DAT_STA (1 << 20) /* Status Register transmission */ #define AD7192_MODE_CLKSRC(x) (((x) & 0x3) << 18) /* Clock Source Select */ #define AD7192_MODE_SINC3 (1 << 15) /* SINC3 Filter Select */ @@ -91,7 +93,8 @@ #define AD7192_CONF_CHOP (1 << 23) /* CHOP enable */ #define AD7192_CONF_REFSEL (1 << 20) /* REFIN1/REFIN2 Reference Select */ -#define AD7192_CONF_CHAN(x) (((x) & 0xFF) << 8) /* Channel select */ +#define AD7192_CONF_CHAN(x) (((1 << (x)) & 0xFF) << 8) /* Channel select */ +#define AD7192_CONF_CHAN_MASK (0xFF << 8) /* Channel select mask */ #define AD7192_CONF_BURN (1 << 7) /* Burnout current enable */ #define AD7192_CONF_REFDET (1 << 6) /* Reference detect enable */ #define AD7192_CONF_BUF (1 << 4) /* Buffered Mode Enable */ @@ -133,12 +136,7 @@ */ struct ad7192_state { - struct spi_device *spi; - struct iio_trigger *trig; struct regulator *reg; - wait_queue_head_t wq_data_avail; - bool done; - bool irq_dis; u16 int_vref_mv; u32 mclk; u32 f_order; @@ -147,178 +145,45 @@ struct ad7192_state { u32 scale_avail[8][2]; u8 gpocon; u8 devid; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - */ - u8 data[4] ____cacheline_aligned; -}; - -static int __ad7192_write_reg(struct ad7192_state *st, bool locked, - bool cs_change, unsigned char reg, - unsigned size, unsigned val) -{ - u8 *data = st->data; - struct spi_transfer t = { - .tx_buf = data, - .len = size + 1, - .cs_change = cs_change, - }; - struct spi_message m; - - data[0] = AD7192_COMM_WRITE | AD7192_COMM_ADDR(reg); - - switch (size) { - case 3: - data[1] = val >> 16; - data[2] = val >> 8; - data[3] = val; - break; - case 2: - data[1] = val >> 8; - data[2] = val; - break; - case 1: - data[1] = val; - break; - default: - return -EINVAL; - } - spi_message_init(&m); - spi_message_add_tail(&t, &m); - - if (locked) - return spi_sync_locked(st->spi, &m); - else - return spi_sync(st->spi, &m); -} + struct ad_sigma_delta sd; +}; -static int ad7192_write_reg(struct ad7192_state *st, - unsigned reg, unsigned size, unsigned val) +static struct ad7192_state *ad_sigma_delta_to_ad7192(struct ad_sigma_delta *sd) { - return __ad7192_write_reg(st, false, false, reg, size, val); + return container_of(sd, struct ad7192_state, sd); } -static int __ad7192_read_reg(struct ad7192_state *st, bool locked, - bool cs_change, unsigned char reg, - int *val, unsigned size) +static int ad7192_set_channel(struct ad_sigma_delta *sd, unsigned int channel) { - u8 *data = st->data; - int ret; - struct spi_transfer t[] = { - { - .tx_buf = data, - .len = 1, - }, { - .rx_buf = data, - .len = size, - .cs_change = cs_change, - }, - }; - struct spi_message m; - - data[0] = AD7192_COMM_READ | AD7192_COMM_ADDR(reg); - - spi_message_init(&m); - spi_message_add_tail(&t[0], &m); - spi_message_add_tail(&t[1], &m); - - if (locked) - ret = spi_sync_locked(st->spi, &m); - else - ret = spi_sync(st->spi, &m); + struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd); - if (ret < 0) - return ret; + st->conf &= ~AD7192_CONF_CHAN_MASK; + st->conf |= AD7192_CONF_CHAN(channel); - switch (size) { - case 3: - *val = data[0] << 16 | data[1] << 8 | data[2]; - break; - case 2: - *val = data[0] << 8 | data[1]; - break; - case 1: - *val = data[0]; - break; - default: - return -EINVAL; - } - - return 0; + return ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf); } -static int ad7192_read_reg(struct ad7192_state *st, - unsigned reg, int *val, unsigned size) +static int ad7192_set_mode(struct ad_sigma_delta *sd, + enum ad_sigma_delta_mode mode) { - return __ad7192_read_reg(st, 0, 0, reg, val, size); -} - -static int ad7192_read(struct ad7192_state *st, unsigned ch, - unsigned len, int *val) -{ - int ret; - st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) | - AD7192_CONF_CHAN(1 << ch); - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | - AD7192_MODE_SEL(AD7192_MODE_SINGLE); - - ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); + struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd); - spi_bus_lock(st->spi->master); - st->done = false; + st->mode &= ~AD7192_MODE_SEL_MASK; + st->mode |= AD7192_MODE_SEL(mode); - ret = __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3, st->mode); - if (ret < 0) - goto out; - - st->irq_dis = false; - enable_irq(st->spi->irq); - wait_event_interruptible(st->wq_data_avail, st->done); - - ret = __ad7192_read_reg(st, 1, 0, AD7192_REG_DATA, val, len); -out: - spi_bus_unlock(st->spi->master); - - return ret; + return ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); } -static int ad7192_calibrate(struct ad7192_state *st, unsigned mode, unsigned ch) -{ - int ret; - - st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) | - AD7192_CONF_CHAN(1 << ch); - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | AD7192_MODE_SEL(mode); - - ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); - - spi_bus_lock(st->spi->master); - st->done = false; - - ret = __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3, - (st->devid != ID_AD7195) ? - st->mode | AD7192_MODE_CLKDIV : - st->mode); - if (ret < 0) - goto out; - - st->irq_dis = false; - enable_irq(st->spi->irq); - wait_event_interruptible(st->wq_data_avail, st->done); - - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | - AD7192_MODE_SEL(AD7192_MODE_IDLE); - - ret = __ad7192_write_reg(st, 1, 0, AD7192_REG_MODE, 3, st->mode); -out: - spi_bus_unlock(st->spi->master); - - return ret; -} +static const struct ad_sigma_delta_info ad7192_sigma_delta_info = { + .set_channel = ad7192_set_channel, + .set_mode = ad7192_set_mode, + .has_registers = true, + .addr_shift = 3, + .read_mask = BIT(6), +}; -static const u8 ad7192_calib_arr[8][2] = { +static const struct ad_sd_calib_data ad7192_calib_arr[8] = { {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN1}, {AD7192_MODE_CAL_INT_FULL, AD7192_CH_AIN1}, {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN2}, @@ -331,45 +196,34 @@ static const u8 ad7192_calib_arr[8][2] = { static int ad7192_calibrate_all(struct ad7192_state *st) { - int i, ret; - - for (i = 0; i < ARRAY_SIZE(ad7192_calib_arr); i++) { - ret = ad7192_calibrate(st, ad7192_calib_arr[i][0], - ad7192_calib_arr[i][1]); - if (ret) - goto out; - } - - return 0; -out: - dev_err(&st->spi->dev, "Calibration failed\n"); - return ret; + return ad_sd_calibrate_all(&st->sd, ad7192_calib_arr, + ARRAY_SIZE(ad7192_calib_arr)); } static int ad7192_setup(struct ad7192_state *st, const struct ad7192_platform_data *pdata) { - struct iio_dev *indio_dev = spi_get_drvdata(st->spi); + struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi); unsigned long long scale_uv; int i, ret, id; u8 ones[6]; /* reset the serial interface */ memset(&ones, 0xFF, 6); - ret = spi_write(st->spi, &ones, 6); + ret = spi_write(st->sd.spi, &ones, 6); if (ret < 0) goto out; msleep(1); /* Wait for at least 500us */ /* write/read test for device presence */ - ret = ad7192_read_reg(st, AD7192_REG_ID, &id, 1); + ret = ad_sd_read_reg(&st->sd, AD7192_REG_ID, 1, &id); if (ret) goto out; id &= AD7192_ID_MASK; if (id != st->devid) - dev_warn(&st->spi->dev, "device ID query failed (0x%X)\n", id); + dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X)\n", id); switch (pdata->clock_source_sel) { case AD7192_CLK_EXT_MCLK1_2: @@ -422,11 +276,11 @@ static int ad7192_setup(struct ad7192_state *st, if (pdata->burnout_curr_en) st->conf |= AD7192_CONF_BURN; - ret = ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode); + ret = ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); if (ret) goto out; - ret = ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); + ret = ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf); if (ret) goto out; @@ -447,181 +301,10 @@ static int ad7192_setup(struct ad7192_state *st, return 0; out: - dev_err(&st->spi->dev, "setup failed\n"); + dev_err(&st->sd.spi->dev, "setup failed\n"); return ret; } -static int ad7192_ring_preenable(struct iio_dev *indio_dev) -{ - struct ad7192_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); - - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | - AD7192_MODE_SEL(AD7192_MODE_CONT); - st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) | - AD7192_CONF_CHAN(1 << indio_dev->channels[channel].address); - - ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); - - spi_bus_lock(st->spi->master); - __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3, st->mode); - - st->irq_dis = false; - enable_irq(st->spi->irq); - - return 0; -} - -static int ad7192_ring_postdisable(struct iio_dev *indio_dev) -{ - struct ad7192_state *st = iio_priv(indio_dev); - - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | - AD7192_MODE_SEL(AD7192_MODE_IDLE); - - st->done = false; - wait_event_interruptible(st->wq_data_avail, st->done); - - if (!st->irq_dis) - disable_irq_nosync(st->spi->irq); - - __ad7192_write_reg(st, 1, 0, AD7192_REG_MODE, 3, st->mode); - - return spi_bus_unlock(st->spi->master); -} - -/** - * ad7192_trigger_handler() bh of trigger launched polling to ring buffer - **/ -static irqreturn_t ad7192_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct iio_buffer *ring = indio_dev->buffer; - struct ad7192_state *st = iio_priv(indio_dev); - s64 dat64[2]; - s32 *dat32 = (s32 *)dat64; - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) - __ad7192_read_reg(st, 1, 1, AD7192_REG_DATA, - dat32, - indio_dev->channels[0].scan_type.realbits/8); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - dat64[1] = pf->timestamp; - - ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); - - iio_trigger_notify_done(indio_dev->trig); - st->irq_dis = false; - enable_irq(st->spi->irq); - - return IRQ_HANDLED; -} - -static const struct iio_buffer_setup_ops ad7192_ring_setup_ops = { - .preenable = &ad7192_ring_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, - .postdisable = &ad7192_ring_postdisable, - .validate_scan_mask = &iio_validate_scan_mask_onehot, -}; - -static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - &ad7192_trigger_handler, &ad7192_ring_setup_ops); -} - -static void ad7192_ring_cleanup(struct iio_dev *indio_dev) -{ - iio_triggered_buffer_cleanup(indio_dev); -} - -/** - * ad7192_data_rdy_trig_poll() the event handler for the data rdy trig - **/ -static irqreturn_t ad7192_data_rdy_trig_poll(int irq, void *private) -{ - struct ad7192_state *st = iio_priv(private); - - st->done = true; - wake_up_interruptible(&st->wq_data_avail); - disable_irq_nosync(irq); - st->irq_dis = true; - iio_trigger_poll(st->trig, iio_get_time_ns()); - - return IRQ_HANDLED; -} - -static struct iio_trigger_ops ad7192_trigger_ops = { - .owner = THIS_MODULE, -}; - -static int ad7192_probe_trigger(struct iio_dev *indio_dev) -{ - struct ad7192_state *st = iio_priv(indio_dev); - int ret; - - st->trig = iio_trigger_alloc("%s-dev%d", - spi_get_device_id(st->spi)->name, - indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - st->trig->ops = &ad7192_trigger_ops; - ret = request_irq(st->spi->irq, - ad7192_data_rdy_trig_poll, - IRQF_TRIGGER_LOW, - spi_get_device_id(st->spi)->name, - indio_dev); - if (ret) - goto error_free_trig; - - disable_irq_nosync(st->spi->irq); - st->irq_dis = true; - st->trig->dev.parent = &st->spi->dev; - st->trig->private_data = indio_dev; - - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->spi->irq, indio_dev); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -static void ad7192_remove_trigger(struct iio_dev *indio_dev) -{ - struct ad7192_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->spi->irq, indio_dev); - iio_trigger_free(st->trig); -} - static ssize_t ad7192_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) @@ -661,7 +344,7 @@ static ssize_t ad7192_write_frequency(struct device *dev, st->mode &= ~AD7192_MODE_RATE(-1); st->mode |= AD7192_MODE_RATE(div); - ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode); + ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); out: mutex_unlock(&indio_dev->mlock); @@ -673,7 +356,6 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, ad7192_read_frequency, ad7192_write_frequency); - static ssize_t ad7192_show_scale_available(struct device *dev, struct device_attribute *attr, char *buf) { @@ -745,7 +427,7 @@ static ssize_t ad7192_set(struct device *dev, else st->gpocon &= ~AD7192_GPOCON_BPDSW; - ad7192_write_reg(st, AD7192_REG_GPOCON, 1, st->gpocon); + ad_sd_write_reg(&st->sd, AD7192_REG_GPOCON, 1, st->gpocon); break; case AD7192_REG_MODE: if (val) @@ -753,7 +435,7 @@ static ssize_t ad7192_set(struct device *dev, else st->mode &= ~AD7192_MODE_ACX; - ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode); + ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); break; default: ret = -EINVAL; @@ -809,27 +491,11 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, long m) { struct ad7192_state *st = iio_priv(indio_dev); - int ret, smpl = 0; bool unipolar = !!(st->conf & AD7192_CONF_UNIPOLAR); switch (m) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) - ret = -EBUSY; - else - ret = ad7192_read(st, chan->address, - chan->scan_type.realbits / 8, &smpl); - mutex_unlock(&indio_dev->mlock); - - if (ret < 0) - return ret; - - *val = (smpl >> chan->scan_type.shift) & - ((1 << (chan->scan_type.realbits)) - 1); - - return IIO_VAL_INT; - + return ad_sigma_delta_single_conversion(indio_dev, chan, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -880,16 +546,16 @@ static int ad7192_write_raw(struct iio_dev *indio_dev, ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) if (val2 == st->scale_avail[i][1]) { + ret = 0; tmp = st->conf; st->conf &= ~AD7192_CONF_GAIN(-1); st->conf |= AD7192_CONF_GAIN(i); - - if (tmp != st->conf) { - ad7192_write_reg(st, AD7192_REG_CONF, - 3, st->conf); - ad7192_calibrate_all(st); - } - ret = 0; + if (tmp == st->conf) + break; + ad_sd_write_reg(&st->sd, AD7192_REG_CONF, + 3, st->conf); + ad7192_calibrate_all(st); + break; } break; default: @@ -901,15 +567,6 @@ static int ad7192_write_raw(struct iio_dev *indio_dev, return ret; } -static int ad7192_validate_trigger(struct iio_dev *indio_dev, - struct iio_trigger *trig) -{ - if (indio_dev->trig != trig) - return -EINVAL; - - return 0; -} - static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, long mask) @@ -922,7 +579,7 @@ static const struct iio_info ad7192_info = { .write_raw = &ad7192_write_raw, .write_raw_get_fmt = &ad7192_write_raw_get_fmt, .attrs = &ad7192_attribute_group, - .validate_trigger = ad7192_validate_trigger, + .validate_trigger = ad_sd_validate_trigger, .driver_module = THIS_MODULE, }; @@ -931,54 +588,19 @@ static const struct iio_info ad7195_info = { .write_raw = &ad7192_write_raw, .write_raw_get_fmt = &ad7192_write_raw_get_fmt, .attrs = &ad7195_attribute_group, - .validate_trigger = ad7192_validate_trigger, + .validate_trigger = ad_sd_validate_trigger, .driver_module = THIS_MODULE, }; -#define AD7192_CHAN_DIFF(_chan, _chan2, _name, _address, _si) \ - { .type = IIO_VOLTAGE, \ - .differential = 1, \ - .indexed = 1, \ - .extend_name = _name, \ - .channel = _chan, \ - .channel2 = _chan2, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ - .address = _address, \ - .scan_index = _si, \ - .scan_type = IIO_ST('u', 24, 32, 0)} - -#define AD7192_CHAN(_chan, _address, _si) \ - { .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = _chan, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ - .address = _address, \ - .scan_index = _si, \ - .scan_type = IIO_ST('u', 24, 32, 0)} - -#define AD7192_CHAN_TEMP(_chan, _address, _si) \ - { .type = IIO_TEMP, \ - .indexed = 1, \ - .channel = _chan, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - .address = _address, \ - .scan_index = _si, \ - .scan_type = IIO_ST('u', 24, 32, 0)} - static const struct iio_chan_spec ad7192_channels[] = { - AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0), - AD7192_CHAN_DIFF(3, 4, NULL, AD7192_CH_AIN3P_AIN4M, 1), - AD7192_CHAN_TEMP(0, AD7192_CH_TEMP, 2), - AD7192_CHAN_DIFF(2, 2, "shorted", AD7192_CH_AIN2P_AIN2M, 3), - AD7192_CHAN(1, AD7192_CH_AIN1, 4), - AD7192_CHAN(2, AD7192_CH_AIN2, 5), - AD7192_CHAN(3, AD7192_CH_AIN3, 6), - AD7192_CHAN(4, AD7192_CH_AIN4, 7), + AD_SD_DIFF_CHANNEL(0, 1, 2, AD7192_CH_AIN1P_AIN2M, 24, 32, 0), + AD_SD_DIFF_CHANNEL(1, 3, 4, AD7192_CH_AIN3P_AIN4M, 24, 32, 0), + AD_SD_TEMP_CHANNEL(2, AD7192_CH_TEMP, 24, 32, 0), + AD_SD_SHORTED_CHANNEL(3, 2, AD7192_CH_AIN2P_AIN2M, 24, 32, 0), + AD_SD_CHANNEL(4, 1, AD7192_CH_AIN1, 24, 32, 0), + AD_SD_CHANNEL(5, 2, AD7192_CH_AIN2, 24, 32, 0), + AD_SD_CHANNEL(6, 3, AD7192_CH_AIN3, 24, 32, 0), + AD_SD_CHANNEL(7, 4, AD7192_CH_AIN4, 24, 32, 0), IIO_CHAN_SOFT_TIMESTAMP(8), }; @@ -1022,7 +644,6 @@ static int __devinit ad7192_probe(struct spi_device *spi) dev_warn(&spi->dev, "reference voltage undefined\n"); spi_set_drvdata(spi, indio_dev); - st->spi = spi; st->devid = spi_get_device_id(spi)->driver_data; indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; @@ -1034,16 +655,12 @@ static int __devinit ad7192_probe(struct spi_device *spi) else indio_dev->info = &ad7192_info; - init_waitqueue_head(&st->wq_data_avail); + ad_sd_init(&st->sd, indio_dev, spi, &ad7192_sigma_delta_info); - ret = ad7192_register_ring_funcs_and_init(indio_dev); + ret = ad_sd_setup_buffer_and_trigger(indio_dev); if (ret) goto error_disable_reg; - ret = ad7192_probe_trigger(indio_dev); - if (ret) - goto error_ring_cleanup; - ret = ad7192_setup(st, pdata); if (ret) goto error_remove_trigger; @@ -1054,9 +671,7 @@ static int __devinit ad7192_probe(struct spi_device *spi) return 0; error_remove_trigger: - ad7192_remove_trigger(indio_dev); -error_ring_cleanup: - ad7192_ring_cleanup(indio_dev); + ad_sd_cleanup_buffer_and_trigger(indio_dev); error_disable_reg: if (!IS_ERR(st->reg)) regulator_disable(st->reg); @@ -1075,8 +690,7 @@ static int ad7192_remove(struct spi_device *spi) struct ad7192_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - ad7192_remove_trigger(indio_dev); - ad7192_ring_cleanup(indio_dev); + ad_sd_cleanup_buffer_and_trigger(indio_dev); if (!IS_ERR(st->reg)) { regulator_disable(st->reg); -- cgit v0.10.2 From 525e643e4812cd0ced0f40908fafaf0c4317ac73 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7793: Add support for ad7794/ad7795 The ad7794/ad7795 are similar to the ad7792/ad7793, but have 6 channels instead of 3. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 3f1f2c3..0eab0c6 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -109,12 +109,12 @@ config AD7780 module will be called ad7780. config AD7793 - tristate "Analog Devices AD7792 AD7793 ADC driver" + tristate "Analog Devices AD7793 and similar ADCs driver" depends on SPI select AD_SIGMA_DELTA help - Say yes here to build support for Analog Devices - AD7792 and AD7793 SPI analog to digital converters (ADC). + Say yes here to build support for Analog Devices AD7792, AD7793, AD7794 + and AD7795 SPI analog to digital converters (ADC). If unsure, say N (but it's safe to say "Y"). To compile this driver as a module, choose M here: the diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 9033595..f11dcaf 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -1,5 +1,5 @@ /* - * AD7792/AD7793 SPI ADC driver + * AD7792/AD7793/AD7794/AD7795 SPI ADC driver * * Copyright 2011-2012 Analog Devices Inc. * @@ -37,7 +37,8 @@ */ struct ad7793_chip_info { - struct iio_chan_spec channel[7]; + const struct iio_chan_spec *channels; + unsigned int num_channels; }; struct ad7793_state { @@ -55,6 +56,8 @@ struct ad7793_state { enum ad7793_supported_device_ids { ID_AD7792, ID_AD7793, + ID_AD7794, + ID_AD7795, }; static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd) @@ -127,7 +130,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, id &= AD7793_ID_MASK; - if (!((id == AD7792_ID) || (id == AD7793_ID))) { + if (!((id == AD7792_ID) || (id == AD7793_ID) || (id == AD7795_ID))) { dev_err(&st->sd.spi->dev, "device ID query failed\n"); goto out; } @@ -155,7 +158,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, /* Populate available ADC input ranges */ for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) { scale_uv = ((u64)st->int_vref_mv * 100000000) - >> (st->chip_info->channel[0].scan_type.realbits - + >> (st->chip_info->channels[0].scan_type.realbits - (!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1)); scale_uv >>= i; @@ -383,28 +386,52 @@ static const struct iio_info ad7793_info = { .driver_module = THIS_MODULE, }; +#define DECLARE_AD7793_CHANNELS(_name, _b, _sb) \ +const struct iio_chan_spec _name##_channels[] = { \ + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ + AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ + AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), 0), \ + AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ + IIO_CHAN_SOFT_TIMESTAMP(6), \ +} + +#define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \ +const struct iio_chan_spec _name##_channels[] = { \ + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \ + AD_SD_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ + AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \ + AD_SD_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ + IIO_CHAN_SOFT_TIMESTAMP(9), \ +} + +static DECLARE_AD7793_CHANNELS(ad7792, 16, 32); +static DECLARE_AD7793_CHANNELS(ad7793, 24, 32); +static DECLARE_AD7795_CHANNELS(ad7794, 16, 32); +static DECLARE_AD7795_CHANNELS(ad7795, 24, 32); + static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { + [ID_AD7792] = { + .channels = ad7792_channels, + .num_channels = ARRAY_SIZE(ad7792_channels), + }, [ID_AD7793] = { - .channel = { - AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, 24, 32, 0), - AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, 24, 32, 0), - AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, 24, 32, 0), - AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, 24, 32, 0), - AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, 24, 32, 0), - AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, 24, 32, 0), - IIO_CHAN_SOFT_TIMESTAMP(6), - }, + .channels = ad7793_channels, + .num_channels = ARRAY_SIZE(ad7793_channels), }, - [ID_AD7792] = { - .channel = { - AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, 16, 32, 0), - AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, 16, 32, 0), - AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, 16, 32, 0), - AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, 16, 32, 0), - AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, 16, 32, 0), - AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, 16, 32, 0), - IIO_CHAN_SOFT_TIMESTAMP(6), - }, + [ID_AD7794] = { + .channels = ad7794_channels, + .num_channels = ARRAY_SIZE(ad7794_channels), + }, + [ID_AD7795] = { + .channels = ad7795_channels, + .num_channels = ARRAY_SIZE(ad7795_channels), }, }; @@ -457,8 +484,8 @@ static int __devinit ad7793_probe(struct spi_device *spi) indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = st->chip_info->channel; - indio_dev->num_channels = 7; + indio_dev->channels = st->chip_info->channels; + indio_dev->num_channels = st->chip_info->num_channels; indio_dev->info = &ad7793_info; ret = ad_sd_setup_buffer_and_trigger(indio_dev); @@ -510,6 +537,8 @@ static int ad7793_remove(struct spi_device *spi) static const struct spi_device_id ad7793_id[] = { {"ad7792", ID_AD7792}, {"ad7793", ID_AD7793}, + {"ad7794", ID_AD7794}, + {"ad7795", ID_AD7795}, {} }; MODULE_DEVICE_TABLE(spi, ad7793_id); @@ -526,5 +555,5 @@ static struct spi_driver ad7793_driver = { module_spi_driver(ad7793_driver); MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD7792/3 ADC"); +MODULE_DESCRIPTION("Analog Devices AD7793 and simialr ADCs"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7793.h b/drivers/staging/iio/adc/ad7793.h index 0e296d8..8fdd450a 100644 --- a/drivers/staging/iio/adc/ad7793.h +++ b/drivers/staging/iio/adc/ad7793.h @@ -70,8 +70,8 @@ #define AD7793_CONF_GAIN(x) (((x) & 0x7) << 8) /* Gain Select */ #define AD7793_CONF_REFSEL (1 << 7) /* INT/EXT Reference Select */ #define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */ -#define AD7793_CONF_CHAN(x) ((x) & 0x7) /* Channel select */ -#define AD7793_CONF_CHAN_MASK 0x7 /* Channel select mask */ +#define AD7793_CONF_CHAN(x) ((x) & 0xf) /* Channel select */ +#define AD7793_CONF_CHAN_MASK 0xf /* Channel select mask */ #define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */ #define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */ @@ -80,9 +80,15 @@ #define AD7793_CH_TEMP 6 /* Temp Sensor */ #define AD7793_CH_AVDD_MONITOR 7 /* AVDD Monitor */ +#define AD7795_CH_AIN4P_AIN4M 4 /* AIN4(+) - AIN4(-) */ +#define AD7795_CH_AIN5P_AIN5M 5 /* AIN5(+) - AIN5(-) */ +#define AD7795_CH_AIN6P_AIN6M 6 /* AIN6(+) - AIN6(-) */ +#define AD7795_CH_AIN1M_AIN1M 8 /* AIN1(-) - AIN1(-) */ + /* ID Register Bit Designations (AD7793_REG_ID) */ #define AD7792_ID 0xA #define AD7793_ID 0xB +#define AD7795_ID 0xF #define AD7793_ID_MASK 0xF /* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */ -- cgit v0.10.2 From 8c29ecd3620cce207f383fd3ab9b345061a9a8dc Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 10 Aug 2012 17:36:00 +0100 Subject: staging:iio:ad7793: Add ad7785 support The ad7785 is similar to the ad7792/ad7793, but has 20 bit wide data samples. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 0eab0c6..a1fa172 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -113,8 +113,8 @@ config AD7793 depends on SPI select AD_SIGMA_DELTA help - Say yes here to build support for Analog Devices AD7792, AD7793, AD7794 - and AD7795 SPI analog to digital converters (ADC). + Say yes here to build support for Analog Devices AD7785, AD7792, AD7793, + AD7794 and AD7795 SPI analog to digital converters (ADC). If unsure, say N (but it's safe to say "Y"). To compile this driver as a module, choose M here: the diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index f11dcaf..ddc7fd7 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -1,5 +1,5 @@ /* - * AD7792/AD7793/AD7794/AD7795 SPI ADC driver + * AD7785/AD7792/AD7793/AD7794/AD7795 SPI ADC driver * * Copyright 2011-2012 Analog Devices Inc. * @@ -54,6 +54,7 @@ struct ad7793_state { }; enum ad7793_supported_device_ids { + ID_AD7785, ID_AD7792, ID_AD7793, ID_AD7794, @@ -386,14 +387,14 @@ static const struct iio_info ad7793_info = { .driver_module = THIS_MODULE, }; -#define DECLARE_AD7793_CHANNELS(_name, _b, _sb) \ +#define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \ const struct iio_chan_spec _name##_channels[] = { \ - AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ - AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ - AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ - AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ - AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), 0), \ - AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \ + AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \ + AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \ + AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \ + AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \ + AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \ IIO_CHAN_SOFT_TIMESTAMP(6), \ } @@ -411,12 +412,17 @@ const struct iio_chan_spec _name##_channels[] = { \ IIO_CHAN_SOFT_TIMESTAMP(9), \ } -static DECLARE_AD7793_CHANNELS(ad7792, 16, 32); -static DECLARE_AD7793_CHANNELS(ad7793, 24, 32); +static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4); +static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0); +static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0); static DECLARE_AD7795_CHANNELS(ad7794, 16, 32); static DECLARE_AD7795_CHANNELS(ad7795, 24, 32); static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { + [ID_AD7785] = { + .channels = ad7785_channels, + .num_channels = ARRAY_SIZE(ad7785_channels), + }, [ID_AD7792] = { .channels = ad7792_channels, .num_channels = ARRAY_SIZE(ad7792_channels), @@ -535,6 +541,7 @@ static int ad7793_remove(struct spi_device *spi) } static const struct spi_device_id ad7793_id[] = { + {"ad7785", ID_AD7785}, {"ad7792", ID_AD7792}, {"ad7793", ID_AD7793}, {"ad7794", ID_AD7794}, -- cgit v0.10.2 From d965a8bc0cf56e0b2448b9aed6afe9066bc2616d Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Thu, 16 Aug 2012 08:39:00 +0100 Subject: iio: use IIO_CHAN_INFO_RAW rather than 0 (a) For better readability, replace 0 with IIO_CHAN_INFO_RAW. (b) Make same line-format as other apis() : iio_read_channel_scale() and iio_read_channel_offset() Signed-off-by: Milo(Woogyom) Kim Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index b5afc2f..a14e55d 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -239,8 +239,10 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val) goto err_unlock; } - ret = chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel, - val, &val2, 0); + ret = chan->indio_dev->info->read_raw(chan->indio_dev, + chan->channel, + val, &val2, + IIO_CHAN_INFO_RAW); err_unlock: mutex_unlock(&chan->indio_dev->info_exist_lock); -- cgit v0.10.2 From 88238fef16845c18abecb9285c97b0225f71d544 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 17 Aug 2012 16:57:00 +0100 Subject: iio:consumer.h: Fix include guard The symbol name for the #ifndef and the #define of the include guard do not match and thus it becomes quite ineffective. Add the missing '_' to fix this. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index e2657e6..06ab4ec 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -8,7 +8,7 @@ * the Free Software Foundation. */ #ifndef _IIO_INKERN_CONSUMER_H_ -#define _IIO_INKERN_CONSUMER_H +#define _IIO_INKERN_CONSUMER_H_ #include struct iio_dev; -- cgit v0.10.2 From 08d6005c031631429ed307a28503e00e3970c203 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 17 Aug 2012 16:57:00 +0100 Subject: iio: Add missing include guards to headers Add include guards to the IIO headers where they are missing. This avoids compile errors due to redefined types if a file is included more than once. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h index 014d5a1..25eeac7 100644 --- a/include/linux/iio/kfifo_buf.h +++ b/include/linux/iio/kfifo_buf.h @@ -1,3 +1,5 @@ +#ifndef __LINUX_IIO_KFIFO_BUF_H__ +#define __LINUX_IIO_KFIFO_BUF_H__ #include #include @@ -6,3 +8,4 @@ struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev); void iio_kfifo_free(struct iio_buffer *r); +#endif diff --git a/include/linux/iio/machine.h b/include/linux/iio/machine.h index 400a453..809a3f0 100644 --- a/include/linux/iio/machine.h +++ b/include/linux/iio/machine.h @@ -8,6 +8,9 @@ * the Free Software Foundation. */ +#ifndef __LINUX_IIO_MACHINE_H__ +#define __LINUX_IIO_MACHINE_H__ + /** * struct iio_map - description of link between consumer and device channels * @adc_channel_label: Label used to identify the channel on the provider. @@ -22,3 +25,5 @@ struct iio_map { const char *consumer_dev_name; const char *consumer_channel; }; + +#endif diff --git a/include/linux/iio/trigger_consumer.h b/include/linux/iio/trigger_consumer.h index 60d64b3..762a3d3 100644 --- a/include/linux/iio/trigger_consumer.h +++ b/include/linux/iio/trigger_consumer.h @@ -7,6 +7,9 @@ * the Free Software Foundation. */ +#ifndef __LINUX_IIO_TRIGGER_CONSUMER_H__ +#define __LINUX_IIO_TRIGGER_CONSUMER_H__ + /** * struct iio_poll_func - poll function pair * @@ -50,3 +53,5 @@ void iio_trigger_notify_done(struct iio_trigger *trig); */ int iio_triggered_buffer_postenable(struct iio_dev *indio_dev); int iio_triggered_buffer_predisable(struct iio_dev *indio_dev); + +#endif -- cgit v0.10.2 From 161e7f6d136549d6432218f9f42f88dd443a4719 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 17 Aug 2012 16:57:00 +0100 Subject: iio:trigger_consumer.h: Add missing includes and forward declarations Add includes and forward declarations for types used in this file. This avoids compile errors if the other files have not been included before. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/include/linux/iio/trigger_consumer.h b/include/linux/iio/trigger_consumer.h index 762a3d3..c4f8c74 100644 --- a/include/linux/iio/trigger_consumer.h +++ b/include/linux/iio/trigger_consumer.h @@ -10,6 +10,12 @@ #ifndef __LINUX_IIO_TRIGGER_CONSUMER_H__ #define __LINUX_IIO_TRIGGER_CONSUMER_H__ +#include +#include + +struct iio_dev; +struct iio_trigger; + /** * struct iio_poll_func - poll function pair * -- cgit v0.10.2 From 8e8287526844441008df286536a21722277bb487 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 17 Aug 2012 18:29:00 +0100 Subject: staging:iio: Add missing __devinit and __devexit annotations Autogenerated using the following coccinelle semantic patch: // @r1@ identifier driver; identifier fn; position p; type T; @@ T driver = { .remove = ( fn@p | __devexit_p(fn@p) ) }; @r2@ identifier r1.fn; position p != r1.p; @@ fn@p @r3@ identifier r1.fn; position r1.p; @@ ( __devexit_p(fn@p) | -fn@p +__devexit_p(fn) ) @depends on !r2@ identifier r1.fn; @@ static -int fn +int __devexit fn (...) { ... } @r11@ identifier driver; identifier fn; position p; type T; @@ T driver = { .probe = fn@p }; @r12@ identifier r11.fn; position p != r11.p; @@ fn@p @depends on !r12@ identifier r11.fn; @@ static -int fn +int __devinit fn (...) { ... } // Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index ec2332f..8e37d6e 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -565,7 +565,7 @@ error_ret: return ret; } -static int adis16201_remove(struct spi_device *spi) +static int __devexit adis16201_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 34b76c5..002fa9d 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -500,7 +500,7 @@ error_ret: return ret; } -static int adis16203_remove(struct spi_device *spi) +static int __devexit adis16203_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 02fb101..05bdb7c 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -558,7 +558,7 @@ error_ret: return ret; } -static int adis16204_remove(struct spi_device *spi) +static int __devexit adis16204_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index 4fa2229..b7333bf 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -573,7 +573,7 @@ error_ret: return ret; } -static int adis16209_remove(struct spi_device *spi) +static int __devexit adis16209_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index c31e1ec..c755089 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -663,7 +663,7 @@ error_ret: return ret; } -static int adis16220_remove(struct spi_device *spi) +static int __devexit adis16220_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index dafc0d8..0fc26a49 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -619,7 +619,7 @@ error_ret: return ret; } -static int adis16240_remove(struct spi_device *spi) +static int __devexit adis16240_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 0c2b4ba..54ce17f 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -780,7 +780,7 @@ err_ret: } /* fixme, confirm ordering in this function */ -static int lis3l02dq_remove(struct spi_device *spi) +static int __devexit lis3l02dq_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index cc040e1..581cdbd 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -1233,7 +1233,7 @@ error_ret: return ret; } -static int sca3000_remove(struct spi_device *spi) +static int __devexit sca3000_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct sca3000_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 189d951..c351cae 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -684,7 +684,7 @@ error_put_reg: return ret; } -static int ad7192_remove(struct spi_device *spi) +static int __devexit ad7192_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7192_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index 4d30a79..4f6d59e 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -196,7 +196,7 @@ error_ret: return ret; } -static int ad7476_remove(struct spi_device *spi) +static int __devexit ad7476_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7476_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 853f8b1..5f807ce 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -225,7 +225,7 @@ error_put_reg: return ret; } -static int ad7780_remove(struct spi_device *spi) +static int __devexit ad7780_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7780_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index ddc7fd7..691a7be 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -522,7 +522,7 @@ error_put_reg: return ret; } -static int ad7793_remove(struct spi_device *spi) +static int __devexit ad7793_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7793_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c index 397b849..5517905 100644 --- a/drivers/staging/iio/adc/ad7887_core.c +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -219,7 +219,7 @@ error_put_reg: return ret; } -static int ad7887_remove(struct spi_device *spi) +static int __devexit ad7887_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7887_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 816bb2c..adb90fe 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -1367,7 +1367,7 @@ error_out: return ret; } -static int max1363_remove(struct i2c_client *client) +static int __devexit max1363_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); struct max1363_state *st = iio_priv(indio_dev); @@ -1434,7 +1434,7 @@ static struct i2c_driver max1363_driver = { .name = "max1363", }, .probe = max1363_probe, - .remove = max1363_remove, + .remove = __devexit_p(max1363_remove), .id_table = max1363_id, }; module_i2c_driver(max1363_driver); diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 9931e20..87151a7 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -184,7 +184,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int adis16060_r_remove(struct spi_device *spi) +static int __devexit adis16060_r_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); iio_device_free(spi_get_drvdata(spi)); @@ -210,7 +210,7 @@ error_ret: return ret; } -static int adis16060_w_remove(struct spi_device *spi) +static int __devexit adis16060_w_remove(struct spi_device *spi) { return 0; } diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index 345e4fa..a739025 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -177,7 +177,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int adis16080_remove(struct spi_device *spi) +static int __devexit adis16080_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); iio_device_free(spi_get_drvdata(spi)); diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index bf61cd0..fbf96b0 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -154,7 +154,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int adis16130_remove(struct spi_device *spi) +static int __devexit adis16130_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); iio_device_free(spi_get_drvdata(spi)); diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 93aa431..dec2504 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -698,7 +698,7 @@ error_ret: return ret; } -static int adis16260_remove(struct spi_device *spi) +static int __devexit adis16260_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c index 6513119..d93527d 100644 --- a/drivers/staging/iio/gyro/adxrs450_core.c +++ b/drivers/staging/iio/gyro/adxrs450_core.c @@ -409,7 +409,7 @@ error_ret: return ret; } -static int adxrs450_remove(struct spi_device *spi) +static int __devexit adxrs450_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); iio_device_free(spi_get_drvdata(spi)); diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 4ce9e3d..b9f8438 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -1204,7 +1204,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int adis16400_remove(struct spi_device *spi) +static int __devexit adis16400_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 9d740be..954ca2c 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -805,7 +805,7 @@ fail1: return err; } -static int tsl2563_remove(struct i2c_client *client) +static int __devexit tsl2563_remove(struct i2c_client *client) { struct tsl2563_chip *chip = i2c_get_clientdata(client); struct iio_dev *indio_dev = iio_priv_to_dev(chip); diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index f04ece7..6caf80c 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -553,7 +553,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int ade7753_remove(struct spi_device *spi) +static int __devexit ade7753_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 6cee28a..ab912ca 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -575,7 +575,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int ade7754_remove(struct spi_device *spi) +static int __devexit ade7754_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 6d3725a..958f8f2 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -962,7 +962,7 @@ error_ret: return ret; } -static int ade7758_remove(struct spi_device *spi) +static int __devexit ade7758_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ade7758_state *st = iio_priv(indio_dev); diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index b3f7e0fa9..d494052 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -497,7 +497,7 @@ error_ret: } /* fixme, confirm ordering in this function */ -static int ade7759_remove(struct spi_device *spi) +static int __devexit ade7759_remove(struct spi_device *spi) { int ret; struct iio_dev *indio_dev = spi_get_drvdata(spi); diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c index 9fb2f8b..7dae035 100644 --- a/drivers/staging/iio/meter/ade7854-spi.c +++ b/drivers/staging/iio/meter/ade7854-spi.c @@ -330,7 +330,7 @@ static int __devinit ade7854_spi_probe(struct spi_device *spi) return 0; } -static int ade7854_spi_remove(struct spi_device *spi) +static int __devexit ade7854_spi_remove(struct spi_device *spi) { ade7854_remove(spi_get_drvdata(spi)); diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index 90b2684..de26d54 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -51,7 +51,7 @@ static const struct iio_trigger_ops iio_gpio_trigger_ops = { .owner = THIS_MODULE, }; -static int iio_gpio_trigger_probe(struct platform_device *pdev) +static int __devinit iio_gpio_trigger_probe(struct platform_device *pdev) { struct iio_gpio_trigger_info *trig_info; struct iio_trigger *trig, *trig2; @@ -130,7 +130,7 @@ error_free_completed_registrations: return ret; } -static int iio_gpio_trigger_remove(struct platform_device *pdev) +static int __devexit iio_gpio_trigger_remove(struct platform_device *pdev) { struct iio_trigger *trig, *trig2; struct iio_gpio_trigger_info *trig_info; @@ -153,7 +153,7 @@ static int iio_gpio_trigger_remove(struct platform_device *pdev) static struct platform_driver iio_gpio_trigger_driver = { .probe = iio_gpio_trigger_probe, - .remove = iio_gpio_trigger_remove, + .remove = __devexit_p(iio_gpio_trigger_remove), .driver = { .name = "iio_gpio_trigger", .owner = THIS_MODULE, diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index 4ceaa18..b837801 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -101,7 +101,7 @@ static const struct iio_trigger_ops iio_prtc_trigger_ops = { .set_trigger_state = &iio_trig_periodic_rtc_set_state, }; -static int iio_trig_periodic_rtc_probe(struct platform_device *dev) +static int __devinit iio_trig_periodic_rtc_probe(struct platform_device *dev) { char **pdata = dev->dev.platform_data; struct iio_prtc_trigger_info *trig_info; @@ -167,7 +167,7 @@ error_free_completed_registrations: return ret; } -static int iio_trig_periodic_rtc_remove(struct platform_device *dev) +static int __devexit iio_trig_periodic_rtc_remove(struct platform_device *dev) { struct iio_trigger *trig, *trig2; struct iio_prtc_trigger_info *trig_info; @@ -188,7 +188,7 @@ static int iio_trig_periodic_rtc_remove(struct platform_device *dev) static struct platform_driver iio_trig_periodic_rtc_driver = { .probe = iio_trig_periodic_rtc_probe, - .remove = iio_trig_periodic_rtc_remove, + .remove = __devexit_p(iio_trig_periodic_rtc_remove), .driver = { .name = "iio_prtc_trigger", .owner = THIS_MODULE, -- cgit v0.10.2 From c559afbfb08c7eac215ba417251225d3a8e01062 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 30 Jun 2012 13:52:00 +0100 Subject: iio:kfifo_buf Take advantage of the fixed record size used in IIO By bypassing the standard macros for setting up the kfifo we can take advantage of the fixed record size implementation without having to have a type to pass in (from which the size of an element is normally established). In IIO we have variable 'scans' as our records in which any element can be present or not. They do not however vary when we are actually filling or reading from the buffer. Thus we have a fixed record size whenever we are actually running. As setup and tear down are not in the fast path we can take the overhead of reinitializing the kfifo every time. Signed-off-by: Jonathan Cameron Tested-by: Lars-Peter Clausen diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 6bf9d05..8a6d28c 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c @@ -22,7 +22,8 @@ static inline int __iio_allocate_kfifo(struct iio_kfifo *buf, return -EINVAL; __iio_update_buffer(&buf->buffer, bytes_per_datum, length); - return kfifo_alloc(&buf->kf, bytes_per_datum*length, GFP_KERNEL); + return __kfifo_alloc((struct __kfifo *)&buf->kf, length, + bytes_per_datum, GFP_KERNEL); } static int iio_request_update_kfifo(struct iio_buffer *r) @@ -94,9 +95,10 @@ static int iio_store_to_kfifo(struct iio_buffer *r, { int ret; struct iio_kfifo *kf = iio_to_kfifo(r); - ret = kfifo_in(&kf->kf, data, r->bytes_per_datum); - if (ret != r->bytes_per_datum) + ret = kfifo_in(&kf->kf, data, 1); + if (ret != 1) return -EBUSY; + return 0; } @@ -109,7 +111,6 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r, if (n < r->bytes_per_datum) return -EINVAL; - n = rounddown(n, r->bytes_per_datum); ret = kfifo_to_user(&kf->kf, buf, n, &copied); return copied; -- cgit v0.10.2 From 08ce9b44b53c580987b6a63df4e2206e45e20b92 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 27 Aug 2012 18:40:04 +0100 Subject: iio:kfifo_buf improve error handling in read_first_n. These two elements were originally in the patch iio:kfifo_buf Take advantage of the fixed record size used in IIO but Lars-Peter Clausen pointed out they should not have been so here they are. Signed-off-by: Jonathan Cameron Tested-by: Lars-Peter Clausen diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 8a6d28c..6ec763f 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c @@ -108,10 +108,12 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r, int ret, copied; struct iio_kfifo *kf = iio_to_kfifo(r); - if (n < r->bytes_per_datum) + if (n < r->bytes_per_datum || r->bytes_per_datum == 0) return -EINVAL; ret = kfifo_to_user(&kf->kf, buf, n, &copied); + if (ret < 0) + return ret; return copied; } -- cgit v0.10.2 From 7c388ec1d4bc55b72802afbddb26ab87bc762438 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 30 Jun 2012 13:52:00 +0100 Subject: iio: kfifo - add poll support. This buffer implementation was missing poll support. Signed-off-by: Jonathan Cameron Tested-by: Lars-Peter Clausen Acked-by: srinivas pandruvada diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 6ec763f..63da424 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c @@ -6,6 +6,7 @@ #include #include #include +#include struct iio_kfifo { struct iio_buffer buffer; @@ -36,6 +37,7 @@ static int iio_request_update_kfifo(struct iio_buffer *r) kfifo_free(&buf->kf); ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum, buf->buffer.length); + r->stufftoread = false; error_ret: return ret; } @@ -82,6 +84,9 @@ static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd) static int iio_set_length_kfifo(struct iio_buffer *r, int length) { + /* Avoid an invalid state */ + if (length < 2) + length = 2; if (r->length != length) { r->length = length; iio_mark_update_needed_kfifo(r); @@ -98,6 +103,8 @@ static int iio_store_to_kfifo(struct iio_buffer *r, ret = kfifo_in(&kf->kf, data, 1); if (ret != 1) return -EBUSY; + r->stufftoread = true; + wake_up_interruptible(&r->pollq); return 0; } @@ -115,6 +122,12 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r, if (ret < 0) return ret; + if (kfifo_is_empty(&kf->kf)) + r->stufftoread = false; + /* verify it is still empty to avoid race */ + if (!kfifo_is_empty(&kf->kf)) + r->stufftoread = true; + return copied; } @@ -139,7 +152,7 @@ struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) iio_buffer_init(&kf->buffer); kf->buffer.attrs = &iio_kfifo_attribute_group; kf->buffer.access = &kfifo_access_funcs; - + kf->buffer.length = 2; return &kf->buffer; } EXPORT_SYMBOL(iio_kfifo_allocate); -- cgit v0.10.2 From 91b4171f4e7e2d49aee54259b50e703e09bcff20 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Wed, 22 Aug 2012 20:42:00 +0100 Subject: staging iio: lis3l02dq cleanup fixes some typos, whitespace, comments Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h index ae5f225..ad51658 100644 --- a/drivers/staging/iio/accel/lis3l02dq.h +++ b/drivers/staging/iio/accel/lis3l02dq.h @@ -28,7 +28,7 @@ /* Control Register (1 of 2) */ #define LIS3L02DQ_REG_CTRL_1_ADDR 0x20 /* Power ctrl - either bit set corresponds to on*/ -#define LIS3L02DQ_REG_CTRL_1_PD_ON 0xC0 +#define LIS3L02DQ_REG_CTRL_1_PD_ON 0xC0 /* Decimation Factor */ #define LIS3L02DQ_DEC_MASK 0x30 @@ -73,14 +73,14 @@ /* Interrupt related stuff */ #define LIS3L02DQ_REG_WAKE_UP_CFG_ADDR 0x23 -/* Switch from or combination fo conditions to and */ +/* Switch from or combination of conditions to and */ #define LIS3L02DQ_REG_WAKE_UP_CFG_BOOLEAN_AND 0x80 /* Latch interrupt request, * if on ack must be given by reading the ack register */ #define LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC 0x40 -/* Z Interrupt on High (above threshold)*/ +/* Z Interrupt on High (above threshold) */ #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH 0x20 /* Z Interrupt on Low */ #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW 0x10 @@ -117,13 +117,13 @@ #define LIS3L02DQ_REG_STATUS_Y_OVERRUN 0x20 #define LIS3L02DQ_REG_STATUS_X_OVERRUN 0x10 /* XYZ new data available - first is all 3 available? */ -#define LIS3L02DQ_REG_STATUS_XYZ_NEW_DATA 0x08 +#define LIS3L02DQ_REG_STATUS_XYZ_NEW_DATA 0x08 #define LIS3L02DQ_REG_STATUS_Z_NEW_DATA 0x04 #define LIS3L02DQ_REG_STATUS_Y_NEW_DATA 0x02 #define LIS3L02DQ_REG_STATUS_X_NEW_DATA 0x01 /* The accelerometer readings - low and high bytes. -Form of high byte dependent on justification set in ctrl reg */ + * Form of high byte dependent on justification set in ctrl reg */ #define LIS3L02DQ_REG_OUT_X_L_ADDR 0x28 #define LIS3L02DQ_REG_OUT_X_H_ADDR 0x29 #define LIS3L02DQ_REG_OUT_Y_L_ADDR 0x2A @@ -150,9 +150,9 @@ Form of high byte dependent on justification set in ctrl reg */ * struct lis3l02dq_state - device instance specific data * @us: actual spi_device * @trig: data ready trigger registered with iio + * @buf_lock: mutex to protect tx and rx * @tx: transmit buffer * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx **/ struct lis3l02dq_state { struct spi_device *us; diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 54ce17f..0144afe 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -392,7 +392,7 @@ static int lis3l02dq_initial_setup(struct iio_dev *indio_dev) dev_err(&st->us->dev, "problem with setup control register 1"); goto err_ret; } - /* Repeat as sometimes doesn't work first time?*/ + /* Repeat as sometimes doesn't work first time? */ ret = lis3l02dq_spi_write_reg_8(indio_dev, LIS3L02DQ_REG_CTRL_1_ADDR, val); @@ -686,7 +686,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) goto error_ret; } st = iio_priv(indio_dev); - /* this is only used tor removal purposes */ + /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); st->us = spi; diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 18d108f..7da2703 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -14,7 +14,7 @@ #include "lis3l02dq.h" /** - * combine_8_to_16() utility function to munge to u8s into u16 + * combine_8_to_16() utility function to munge two u8s into u16 **/ static inline u16 combine_8_to_16(u8 lower, u8 upper) { @@ -49,7 +49,7 @@ static const u8 read_all_tx_array[] = { /** * lis3l02dq_read_all() Reads all channels currently selected - * @st: device specific state + * @indio_dev: IIO device state * @rx_array: (dma capable) receive array, must be at least * 4*number of channels **/ @@ -170,22 +170,22 @@ __lis3l02dq_write_data_ready_config(struct iio_dev *indio_dev, bool state) bool currentlyset; struct lis3l02dq_state *st = iio_priv(indio_dev); -/* Get the current event mask register */ + /* Get the current event mask register */ ret = lis3l02dq_spi_read_reg_8(indio_dev, LIS3L02DQ_REG_CTRL_2_ADDR, &valold); if (ret) goto error_ret; -/* Find out if data ready is already on */ + /* Find out if data ready is already on */ currentlyset = valold & LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION; -/* Disable requested */ + /* Disable requested */ if (!state && currentlyset) { - /* disable the data ready signal */ + /* Disable the data ready signal */ valold &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION; - /* The double write is to overcome a hardware bug?*/ + /* The double write is to overcome a hardware bug? */ ret = lis3l02dq_spi_write_reg_8(indio_dev, LIS3L02DQ_REG_CTRL_2_ADDR, valold); @@ -197,10 +197,10 @@ __lis3l02dq_write_data_ready_config(struct iio_dev *indio_dev, bool state) if (ret) goto error_ret; st->trigger_on = false; -/* Enable requested */ + /* Enable requested */ } else if (state && !currentlyset) { - /* if not set, enable requested */ - /* first disable all events */ + /* If not set, enable requested + * first disable all events */ ret = lis3l02dq_disable_all_events(indio_dev); if (ret < 0) goto error_ret; @@ -239,7 +239,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig, if (state == false) { /* * A possible quirk with the handler is currently worked around - * by ensuring outstanding read events are cleared. + * by ensuring outstanding read events are cleared. */ ret = lis3l02dq_read_all(indio_dev, NULL); } @@ -250,7 +250,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig, } /** - * lis3l02dq_trig_try_reen() try renabling irq for data rdy trigger + * lis3l02dq_trig_try_reen() try reenabling irq for data rdy trigger * @trig: the datardy trigger */ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig) @@ -259,8 +259,8 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig) struct lis3l02dq_state *st = iio_priv(indio_dev); int i; - /* If gpio still high (or high again) */ - /* In theory possible we will need to do this several times */ + /* If gpio still high (or high again) + * In theory possible we will need to do this several times */ for (i = 0; i < 5; i++) if (gpio_get_value(irq_to_gpio(st->us->irq))) lis3l02dq_read_all(indio_dev, NULL); -- cgit v0.10.2 From f5ed9c35bd2af6d9d171290d3dc45004f4f79bcf Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 26 Aug 2012 17:00:00 +0100 Subject: drivers/staging/iio/adc/spear_adc.c: use clk_prepare_enable and clk_disable_unprepare Clk_prepare_enable and clk_disable_unprepare combine clk_prepare and clk_enable, and clk_disable and clk_unprepare. They make the code more concise, and ensure that clk_unprepare is called when clk_enable fails. A simplified version of the semantic patch that introduces calls to these functions is as follows: (http://coccinelle.lip6.fr/) // @@ expression e; @@ - clk_prepare(e); - clk_enable(e); + clk_prepare_enable(e); @@ expression e; @@ - clk_disable(e); - clk_unprepare(e); + clk_disable_unprepare(e); // Signed-off-by: Julia Lawall Reviewed-by: Viresh Kumar Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index 675c427..0b83e2e 100644 --- a/drivers/staging/iio/adc/spear_adc.c +++ b/drivers/staging/iio/adc/spear_adc.c @@ -330,36 +330,30 @@ static int __devinit spear_adc_probe(struct platform_device *pdev) goto errout3; } - ret = clk_prepare(info->clk); - if (ret) { - dev_err(dev, "failed preparing clock\n"); - goto errout4; - } - - ret = clk_enable(info->clk); + ret = clk_prepare_enable(info->clk); if (ret) { dev_err(dev, "failed enabling clock\n"); - goto errout5; + goto errout4; } irq = platform_get_irq(pdev, 0); if ((irq < 0) || (irq >= NR_IRQS)) { dev_err(dev, "failed getting interrupt resource\n"); ret = -EINVAL; - goto errout6; + goto errout5; } ret = devm_request_irq(dev, irq, spear_adc_isr, 0, MOD_NAME, info); if (ret < 0) { dev_err(dev, "failed requesting interrupt\n"); - goto errout6; + goto errout5; } if (of_property_read_u32(np, "sampling-frequency", &info->sampling_freq)) { dev_err(dev, "sampling-frequency missing in DT\n"); ret = -EINVAL; - goto errout6; + goto errout5; } /* @@ -389,16 +383,14 @@ static int __devinit spear_adc_probe(struct platform_device *pdev) ret = iio_device_register(iodev); if (ret) - goto errout6; + goto errout5; dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq); return 0; -errout6: - clk_disable(info->clk); errout5: - clk_unprepare(info->clk); + clk_disable_unprepare(info->clk); errout4: clk_put(info->clk); errout3: @@ -416,8 +408,7 @@ static int __devexit spear_adc_remove(struct platform_device *pdev) iio_device_unregister(iodev); platform_set_drvdata(pdev, NULL); - clk_disable(info->clk); - clk_unprepare(info->clk); + clk_disable_unprepare(info->clk); clk_put(info->clk); iounmap(info->adc_base_spear6xx); iio_device_free(iodev); -- cgit v0.10.2 From 00062a9c2e772345388cd352695790f00a95b934 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 26 Aug 2012 17:00:00 +0100 Subject: drivers/iio/adc/at91_adc.c: use clk_prepare_enable and clk_disable_unprepare Clk_prepare_enable and clk_disable_unprepare combine clk_prepare and clk_enable, and clk_disable and clk_unprepare. They make the code more concise, and ensure that clk_unprepare is called when clk_enable fails. A simplified version of the semantic patch that introduces calls to these functions is as follows: (http://coccinelle.lip6.fr/) // @@ expression e; @@ - clk_prepare(e); - clk_enable(e); + clk_prepare_enable(e); @@ expression e; @@ - clk_disable(e); - clk_unprepare(e); + clk_disable_unprepare(e); // Signed-off-by: Julia Lawall Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 98c96f9..c1e4690 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -589,18 +589,13 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) goto error_free_irq; } - ret = clk_prepare(st->clk); + ret = clk_prepare_enable(st->clk); if (ret) { - dev_err(&pdev->dev, "Could not prepare the clock.\n"); + dev_err(&pdev->dev, + "Could not prepare or enable the clock.\n"); goto error_free_irq; } - ret = clk_enable(st->clk); - if (ret) { - dev_err(&pdev->dev, "Could not enable the clock.\n"); - goto error_unprepare_clk; - } - st->adc_clk = devm_clk_get(&pdev->dev, "adc_op_clk"); if (IS_ERR(st->adc_clk)) { dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); @@ -608,18 +603,13 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) goto error_disable_clk; } - ret = clk_prepare(st->adc_clk); + ret = clk_prepare_enable(st->adc_clk); if (ret) { - dev_err(&pdev->dev, "Could not prepare the ADC clock.\n"); + dev_err(&pdev->dev, + "Could not prepare or enable the ADC clock.\n"); goto error_disable_clk; } - ret = clk_enable(st->adc_clk); - if (ret) { - dev_err(&pdev->dev, "Could not enable the ADC clock.\n"); - goto error_unprepare_adc_clk; - } - /* * Prescaler rate computation using the formula from the Atmel's * datasheet : ADC Clock = MCK / ((Prescaler + 1) * 2), ADC Clock being @@ -681,13 +671,9 @@ error_remove_triggers: error_unregister_buffer: at91_adc_buffer_remove(idev); error_disable_adc_clk: - clk_disable(st->adc_clk); -error_unprepare_adc_clk: - clk_unprepare(st->adc_clk); + clk_disable_unprepare(st->adc_clk); error_disable_clk: - clk_disable(st->clk); -error_unprepare_clk: - clk_unprepare(st->clk); + clk_disable_unprepare(st->clk); error_free_irq: free_irq(st->irq, idev); error_free_device: @@ -705,8 +691,7 @@ static int __devexit at91_adc_remove(struct platform_device *pdev) at91_adc_trigger_remove(idev); at91_adc_buffer_remove(idev); clk_disable_unprepare(st->adc_clk); - clk_disable(st->clk); - clk_unprepare(st->clk); + clk_disable_unprepare(st->clk); free_irq(st->irq, idev); iio_device_free(idev); -- cgit v0.10.2 From c3668a0f8097af2f24a5fd67695f4ee830f99eda Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sun, 26 Aug 2012 13:43:00 +0100 Subject: iio: document missing elements Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index b18e74e..2c395a8 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -229,6 +229,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * @indexed: Specify the channel has a numerical index. If not, * the channel index number will be suppressed for sysfs * attributes but not for event codes. + * @output: Channel is output. * @differential: Channel is differential. */ struct iio_chan_spec { @@ -312,6 +313,9 @@ struct iio_dev; * Meaning is event dependent. * @validate_trigger: function to validate the trigger when the * current trigger gets changed. + * @update_scan_mode: function to configure device and scan buffer when + * channels have changed + * @debugfs_reg_access: function to read or write register value of device **/ struct iio_info { struct module *driver_module; diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h index a981994..f0af267 100644 --- a/include/linux/iio/trigger.h +++ b/include/linux/iio/trigger.h @@ -39,7 +39,7 @@ struct iio_trigger_ops { /** * struct iio_trigger - industrial I/O trigger device - * + * @ops: [DRIVER] operations structure * @id: [INTERN] unique id number * @name: [DRIVER] unique name * @dev: [DRIVER] associated device (if relevant) @@ -104,7 +104,8 @@ void iio_trigger_unregister(struct iio_trigger *trig_info); /** * iio_trigger_poll() - called on a trigger occurring - * @trig: trigger which occurred + * @trig: trigger which occurred + * @time: timestamp when trigger occurred * * Typically called in relevant hardware interrupt handler. **/ -- cgit v0.10.2 From d25b3808db3a03deb12ffc0660c757b4a619f262 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sun, 26 Aug 2012 13:43:00 +0100 Subject: iio: fix typos Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 2ec266e..47c1ffa 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -729,7 +729,7 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) attrcount = attrcount_orig; /* * New channel registration method - relies on the fact a group does - * not need to be initialized if it is name is NULL. + * not need to be initialized if its name is NULL. */ if (indio_dev->channels) for (i = 0; i < indio_dev->num_channels; i++) { diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 2c395a8..677e3d8 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -164,7 +164,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * IIO_ENUM() - Initialize enum extended channel attribute * @_name: Attribute name * @_shared: Whether the attribute is shared between all channels - * @_e: Pointer to a iio_enum struct + * @_e: Pointer to an iio_enum struct * * This should usually be used together with IIO_ENUM_AVAILABLE() */ @@ -180,9 +180,9 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, /** * IIO_ENUM_AVAILABLE() - Initialize enum available extended channel attribute * @_name: Attribute name ("_available" will be appended to the name) - * @_e: Pointer to a iio_enum struct + * @_e: Pointer to an iio_enum struct * - * Creates a read only attribute which list all the available enum items in a + * Creates a read only attribute which lists all the available enum items in a * space separated list. This should usually be used together with IIO_ENUM() */ #define IIO_ENUM_AVAILABLE(_name, _e) \ -- cgit v0.10.2 From 99698b45670a37b5304d5c6a743c8e96baa9ed8f Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sun, 26 Aug 2012 13:43:00 +0100 Subject: iio: whitespace cleanup and removal of semicolon after functions Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 4add9bb..774891c 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -422,7 +422,7 @@ ssize_t iio_buffer_store_enable(struct device *dev, ret = indio_dev->setup_ops->preenable(indio_dev); if (ret) { printk(KERN_ERR - "Buffer not started:" + "Buffer not started: " "buffer preenable failed\n"); goto error_ret; } @@ -431,12 +431,12 @@ ssize_t iio_buffer_store_enable(struct device *dev, ret = buffer->access->request_update(buffer); if (ret) { printk(KERN_INFO - "Buffer not started:" + "Buffer not started: " "buffer parameter update failed\n"); goto error_ret; } } - /* Definitely possible for devices to support both of these.*/ + /* Definitely possible for devices to support both of these. */ if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) { if (!indio_dev->trig) { printk(KERN_INFO @@ -456,7 +456,7 @@ ssize_t iio_buffer_store_enable(struct device *dev, ret = indio_dev->setup_ops->postenable(indio_dev); if (ret) { printk(KERN_INFO - "Buffer not started:" + "Buffer not started: " "postenable failed\n"); indio_dev->currentmode = previous_mode; if (indio_dev->setup_ops->postdisable) @@ -657,7 +657,7 @@ EXPORT_SYMBOL_GPL(iio_scan_mask_query); /** * struct iio_demux_table() - table describing demux memcpy ops * @from: index to copy from - * @to: index to copy to + * @to: index to copy to * @length: how many bytes to copy * @l: list head used for management */ diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 47c1ffa..a288792 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -29,7 +29,7 @@ #include #include -/* IDA to assign each registered device a unique id*/ +/* IDA to assign each registered device a unique id */ static DEFINE_IDA(iio_ida); static dev_t iio_devt; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 677e3d8..057d603 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -371,10 +371,10 @@ struct iio_info { * scan mask is valid for the device. */ struct iio_buffer_setup_ops { - int (*preenable)(struct iio_dev *); - int (*postenable)(struct iio_dev *); - int (*predisable)(struct iio_dev *); - int (*postdisable)(struct iio_dev *); + int (*preenable)(struct iio_dev *); + int (*postenable)(struct iio_dev *); + int (*predisable)(struct iio_dev *); + int (*postdisable)(struct iio_dev *); bool (*validate_scan_mask)(struct iio_dev *indio_dev, const unsigned long *scan_mask); }; diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h index f0af267..20239da 100644 --- a/include/linux/iio/trigger.h +++ b/include/linux/iio/trigger.h @@ -29,7 +29,7 @@ struct iio_subirq { * instances of a given device. **/ struct iio_trigger_ops { - struct module *owner; + struct module *owner; int (*set_trigger_state)(struct iio_trigger *trig, bool state); int (*try_reenable)(struct iio_trigger *trig); int (*validate_device)(struct iio_trigger *trig, @@ -76,19 +76,19 @@ struct iio_trigger { static inline struct iio_trigger *to_iio_trigger(struct device *d) { return container_of(d, struct iio_trigger, dev); -}; +} static inline void iio_trigger_put(struct iio_trigger *trig) { module_put(trig->ops->owner); put_device(&trig->dev); -}; +} static inline void iio_trigger_get(struct iio_trigger *trig) { get_device(&trig->dev); __module_get(trig->ops->owner); -}; +} /** * iio_trigger_register() - register a trigger with the IIO core -- cgit v0.10.2 From e58bf5332d8ccc14ae0788e5541d4b8327728f5b Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Mon, 27 Aug 2012 22:12:00 +0100 Subject: iio: fix spelling of subsystem Signed-off-by: Peter Meerwald Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index d4984c8..56825e6 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -1,5 +1,5 @@ # -# Industrial I/O subsytem configuration +# Industrial I/O subsystem configuration # menuconfig IIO diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index 04cd6ec..ca56c75 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -1,5 +1,5 @@ # -# Industrial I/O subsytem configuration +# Industrial I/O subsystem configuration # menu "IIO staging drivers" depends on IIO -- cgit v0.10.2 From 3ec36a2cf0d50db61e15c6ee77d1dcdc73a7aca5 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dagenais Date: Tue, 21 Aug 2012 15:28:00 +0100 Subject: iio:ad5446: Add support for I2C based DACs This patch adds support for I2C based single channel DACs to the ad5446 driver. Specifically AD5602, AD5612 and AD5622. V1: from Lars-Peter Clausen V2: Split the device IDs into two enums and move them to the c file. Signed-off-by: Jean-Francois Dagenais Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 1be15fa..293b61d 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -57,11 +57,12 @@ config AD5624R_SPI config AD5446 tristate "Analog Devices AD5446 and similar single channel DACs driver" - depends on SPI + depends on (SPI_MASTER || I2C) help - Say yes here to build support for Analog Devices AD5444, AD5446, AD5450, - AD5451, AD5452, AD5453, AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, - AD5611, AD5620, AD5621, AD5640, AD5660, AD5662 DACs. + Say yes here to build support for Analog Devices AD5602, AD5612, AD5622, + AD5444, AD5446, AD5450, AD5451, AD5452, AD5453, AD5512A, AD5541A, AD5542A, + AD5543, AD5553, AD5601, AD5611, AD5620, AD5621, AD5640, AD5660, AD5662 + DACs. To compile this driver as a module, choose M here: the module will be called ad5446. diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 2ca5059..241665b 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -23,23 +24,6 @@ #include "ad5446.h" -static int ad5446_write(struct ad5446_state *st, unsigned val) -{ - __be16 data = cpu_to_be16(val); - return spi_write(st->spi, &data, sizeof(data)); -} - -static int ad5660_write(struct ad5446_state *st, unsigned val) -{ - uint8_t data[3]; - - data[0] = (val >> 16) & 0xFF; - data[1] = (val >> 8) & 0xFF; - data[2] = val & 0xFF; - - return spi_write(st->spi, data, sizeof(data)); -} - static const char * const ad5446_powerdown_modes[] = { "1kohm_to_gnd", "100kohm_to_gnd", "three_state" }; @@ -110,7 +94,7 @@ static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev, return ret ? ret : len; } -static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = { +static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = { { .name = "powerdown", .read = ad5446_read_dac_powerdown, @@ -136,84 +120,7 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = { _AD5446_CHANNEL(bits, storage, shift, NULL) #define AD5446_CHANNEL_POWERDOWN(bits, storage, shift) \ - _AD5446_CHANNEL(bits, storage, shift, ad5064_ext_info_powerdown) - -static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { - [ID_AD5444] = { - .channel = AD5446_CHANNEL(12, 16, 2), - .write = ad5446_write, - }, - [ID_AD5446] = { - .channel = AD5446_CHANNEL(14, 16, 0), - .write = ad5446_write, - }, - [ID_AD5450] = { - .channel = AD5446_CHANNEL(8, 16, 6), - .write = ad5446_write, - }, - [ID_AD5451] = { - .channel = AD5446_CHANNEL(10, 16, 4), - .write = ad5446_write, - }, - [ID_AD5541A] = { - .channel = AD5446_CHANNEL(16, 16, 0), - .write = ad5446_write, - }, - [ID_AD5512A] = { - .channel = AD5446_CHANNEL(12, 16, 4), - .write = ad5446_write, - }, - [ID_AD5553] = { - .channel = AD5446_CHANNEL(14, 16, 0), - .write = ad5446_write, - }, - [ID_AD5601] = { - .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6), - .write = ad5446_write, - }, - [ID_AD5611] = { - .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4), - .write = ad5446_write, - }, - [ID_AD5621] = { - .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), - .write = ad5446_write, - }, - [ID_AD5620_2500] = { - .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), - .int_vref_mv = 2500, - .write = ad5446_write, - }, - [ID_AD5620_1250] = { - .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), - .int_vref_mv = 1250, - .write = ad5446_write, - }, - [ID_AD5640_2500] = { - .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), - .int_vref_mv = 2500, - .write = ad5446_write, - }, - [ID_AD5640_1250] = { - .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), - .int_vref_mv = 1250, - .write = ad5446_write, - }, - [ID_AD5660_2500] = { - .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), - .int_vref_mv = 2500, - .write = ad5660_write, - }, - [ID_AD5660_1250] = { - .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), - .int_vref_mv = 1250, - .write = ad5660_write, - }, - [ID_AD5662] = { - .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), - .write = ad5660_write, - }, -}; + _AD5446_CHANNEL(bits, storage, shift, ad5446_ext_info_powerdown) static int ad5446_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, @@ -272,14 +179,15 @@ static const struct iio_info ad5446_info = { .driver_module = THIS_MODULE, }; -static int __devinit ad5446_probe(struct spi_device *spi) +static int __devinit ad5446_probe(struct device *dev, const char *name, + const struct ad5446_chip_info *chip_info) { struct ad5446_state *st; struct iio_dev *indio_dev; struct regulator *reg; int ret, voltage_uv = 0; - reg = regulator_get(&spi->dev, "vcc"); + reg = regulator_get(dev, "vcc"); if (!IS_ERR(reg)) { ret = regulator_enable(reg); if (ret) @@ -294,16 +202,15 @@ static int __devinit ad5446_probe(struct spi_device *spi) goto error_disable_reg; } st = iio_priv(indio_dev); - st->chip_info = - &ad5446_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + st->chip_info = chip_info; - spi_set_drvdata(spi, indio_dev); + dev_set_drvdata(dev, indio_dev); st->reg = reg; - st->spi = spi; + st->dev = dev; - /* Establish that the iio_dev is a child of the spi device */ - indio_dev->dev.parent = &spi->dev; - indio_dev->name = spi_get_device_id(spi)->name; + /* Establish that the iio_dev is a child of the device */ + indio_dev->dev.parent = dev; + indio_dev->name = name; indio_dev->info = &ad5446_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = &st->chip_info->channel; @@ -316,7 +223,7 @@ static int __devinit ad5446_probe(struct spi_device *spi) else if (voltage_uv) st->vref_mv = voltage_uv / 1000; else - dev_warn(&spi->dev, "reference voltage unspecified\n"); + dev_warn(dev, "reference voltage unspecified\n"); ret = iio_device_register(indio_dev); if (ret) @@ -336,9 +243,9 @@ error_put_reg: return ret; } -static int ad5446_remove(struct spi_device *spi) +static int ad5446_remove(struct device *dev) { - struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5446_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); @@ -351,7 +258,133 @@ static int ad5446_remove(struct spi_device *spi) return 0; } -static const struct spi_device_id ad5446_id[] = { +#if IS_ENABLED(CONFIG_SPI_MASTER) + +static int ad5446_write(struct ad5446_state *st, unsigned val) +{ + struct spi_device *spi = to_spi_device(st->dev); + __be16 data = cpu_to_be16(val); + + return spi_write(spi, &data, sizeof(data)); +} + +static int ad5660_write(struct ad5446_state *st, unsigned val) +{ + struct spi_device *spi = to_spi_device(st->dev); + uint8_t data[3]; + + data[0] = (val >> 16) & 0xFF; + data[1] = (val >> 8) & 0xFF; + data[2] = val & 0xFF; + + return spi_write(spi, data, sizeof(data)); +} + +/** + * ad5446_supported_spi_device_ids: + * The AD5620/40/60 parts are available in different fixed internal reference + * voltage options. The actual part numbers may look differently + * (and a bit cryptic), however this style is used to make clear which + * parts are supported here. + */ +enum ad5446_supported_spi_device_ids { + ID_AD5444, + ID_AD5446, + ID_AD5450, + ID_AD5451, + ID_AD5541A, + ID_AD5512A, + ID_AD5553, + ID_AD5601, + ID_AD5611, + ID_AD5621, + ID_AD5620_2500, + ID_AD5620_1250, + ID_AD5640_2500, + ID_AD5640_1250, + ID_AD5660_2500, + ID_AD5660_1250, + ID_AD5662, +}; + +static const struct ad5446_chip_info ad5446_spi_chip_info[] = { + [ID_AD5444] = { + .channel = AD5446_CHANNEL(12, 16, 2), + .write = ad5446_write, + }, + [ID_AD5446] = { + .channel = AD5446_CHANNEL(14, 16, 0), + .write = ad5446_write, + }, + [ID_AD5450] = { + .channel = AD5446_CHANNEL(8, 16, 6), + .write = ad5446_write, + }, + [ID_AD5451] = { + .channel = AD5446_CHANNEL(10, 16, 4), + .write = ad5446_write, + }, + [ID_AD5541A] = { + .channel = AD5446_CHANNEL(16, 16, 0), + .write = ad5446_write, + }, + [ID_AD5512A] = { + .channel = AD5446_CHANNEL(12, 16, 4), + .write = ad5446_write, + }, + [ID_AD5553] = { + .channel = AD5446_CHANNEL(14, 16, 0), + .write = ad5446_write, + }, + [ID_AD5601] = { + .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6), + .write = ad5446_write, + }, + [ID_AD5611] = { + .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4), + .write = ad5446_write, + }, + [ID_AD5621] = { + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), + .write = ad5446_write, + }, + [ID_AD5620_2500] = { + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), + .int_vref_mv = 2500, + .write = ad5446_write, + }, + [ID_AD5620_1250] = { + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), + .int_vref_mv = 1250, + .write = ad5446_write, + }, + [ID_AD5640_2500] = { + .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), + .int_vref_mv = 2500, + .write = ad5446_write, + }, + [ID_AD5640_1250] = { + .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), + .int_vref_mv = 1250, + .write = ad5446_write, + }, + [ID_AD5660_2500] = { + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), + .int_vref_mv = 2500, + .write = ad5660_write, + }, + [ID_AD5660_1250] = { + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), + .int_vref_mv = 1250, + .write = ad5660_write, + }, + [ID_AD5662] = { + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), + .write = ad5660_write, + }, +}; + +static const struct spi_device_id ad5446_spi_ids[] = { {"ad5444", ID_AD5444}, {"ad5446", ID_AD5446}, {"ad5450", ID_AD5450}, @@ -375,18 +408,157 @@ static const struct spi_device_id ad5446_id[] = { {"ad5662", ID_AD5662}, {} }; -MODULE_DEVICE_TABLE(spi, ad5446_id); +MODULE_DEVICE_TABLE(spi, ad5446_spi_ids); + +static int __devinit ad5446_spi_probe(struct spi_device *spi) +{ + const struct spi_device_id *id = spi_get_device_id(spi); + + return ad5446_probe(&spi->dev, id->name, + &ad5446_spi_chip_info[id->driver_data]); +} -static struct spi_driver ad5446_driver = { +static int __devexit ad5446_spi_remove(struct spi_device *spi) +{ + return ad5446_remove(&spi->dev); +} + +static struct spi_driver ad5446_spi_driver = { .driver = { .name = "ad5446", .owner = THIS_MODULE, }, - .probe = ad5446_probe, - .remove = __devexit_p(ad5446_remove), - .id_table = ad5446_id, + .probe = ad5446_spi_probe, + .remove = __devexit_p(ad5446_spi_remove), + .id_table = ad5446_spi_ids, +}; + +static int __init ad5446_spi_register_driver(void) +{ + return spi_register_driver(&ad5446_spi_driver); +} + +static void ad5446_spi_unregister_driver(void) +{ + spi_unregister_driver(&ad5446_spi_driver); +} + +#else + +static inline int ad5446_spi_register_driver(void) { return 0; } +static inline void ad5446_spi_unregister_driver(void) { } + +#endif + +#if IS_ENABLED(CONFIG_I2C) + +static int ad5622_write(struct ad5446_state *st, unsigned val) +{ + struct i2c_client *client = to_i2c_client(st->dev); + __be16 data = cpu_to_be16(val); + + return i2c_master_send(client, (char *)&data, sizeof(data)); +} + +/** + * ad5446_supported_i2c_device_ids: + * The AD5620/40/60 parts are available in different fixed internal reference + * voltage options. The actual part numbers may look differently + * (and a bit cryptic), however this style is used to make clear which + * parts are supported here. + */ +enum ad5446_supported_i2c_device_ids { + ID_AD5602, + ID_AD5612, + ID_AD5622, +}; + +static const struct ad5446_chip_info ad5446_i2c_chip_info[] = { + [ID_AD5602] = { + .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 4), + .write = ad5622_write, + }, + [ID_AD5612] = { + .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 2), + .write = ad5622_write, + }, + [ID_AD5622] = { + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 0), + .write = ad5622_write, + }, }; -module_spi_driver(ad5446_driver); + +static int __devinit ad5446_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + return ad5446_probe(&i2c->dev, id->name, + &ad5446_i2c_chip_info[id->driver_data]); +} + +static int __devexit ad5446_i2c_remove(struct i2c_client *i2c) +{ + return ad5446_remove(&i2c->dev); +} + +static const struct i2c_device_id ad5446_i2c_ids[] = { + {"ad5602", ID_AD5602}, + {"ad5612", ID_AD5612}, + {"ad5622", ID_AD5622}, + {} +}; +MODULE_DEVICE_TABLE(i2c, ad5446_i2c_ids); + +static struct i2c_driver ad5446_i2c_driver = { + .driver = { + .name = "ad5446", + .owner = THIS_MODULE, + }, + .probe = ad5446_i2c_probe, + .remove = __devexit_p(ad5446_i2c_remove), + .id_table = ad5446_i2c_ids, +}; + +static int __init ad5446_i2c_register_driver(void) +{ + return i2c_add_driver(&ad5446_i2c_driver); +} + +static void __exit ad5446_i2c_unregister_driver(void) +{ + i2c_del_driver(&ad5446_i2c_driver); +} + +#else + +static inline int ad5446_i2c_register_driver(void) { return 0; } +static inline void ad5446_i2c_unregister_driver(void) { } + +#endif + +static int __init ad5446_init(void) +{ + int ret; + + ret = ad5446_spi_register_driver(); + if (ret) + return ret; + + ret = ad5446_i2c_register_driver(); + if (ret) { + ad5446_spi_unregister_driver(); + return ret; + } + + return 0; +} +module_init(ad5446_init); + +static void __exit ad5446_exit(void) +{ + ad5446_i2c_unregister_driver(); + ad5446_spi_unregister_driver(); +} +module_exit(ad5446_exit); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC"); diff --git a/drivers/iio/dac/ad5446.h b/drivers/iio/dac/ad5446.h index 2934269..6b7a176 100644 --- a/drivers/iio/dac/ad5446.h +++ b/drivers/iio/dac/ad5446.h @@ -38,7 +38,7 @@ */ struct ad5446_state { - struct spi_device *spi; + struct device *dev; const struct ad5446_chip_info *chip_info; struct regulator *reg; unsigned short vref_mv; @@ -60,32 +60,5 @@ struct ad5446_chip_info { int (*write)(struct ad5446_state *st, unsigned val); }; -/** - * ad5446_supported_device_ids: - * The AD5620/40/60 parts are available in different fixed internal reference - * voltage options. The actual part numbers may look differently - * (and a bit cryptic), however this style is used to make clear which - * parts are supported here. - */ - -enum ad5446_supported_device_ids { - ID_AD5444, - ID_AD5446, - ID_AD5450, - ID_AD5451, - ID_AD5541A, - ID_AD5512A, - ID_AD5553, - ID_AD5601, - ID_AD5611, - ID_AD5621, - ID_AD5620_2500, - ID_AD5620_1250, - ID_AD5640_2500, - ID_AD5640_1250, - ID_AD5660_2500, - ID_AD5660_1250, - ID_AD5662, -}; #endif /* IIO_DAC_AD5446_H_ */ -- cgit v0.10.2 From 2e15c903c1e6238735775b9ce491fa4f942cd5fc Mon Sep 17 00:00:00 2001 From: Jean-Francois Dagenais Date: Tue, 21 Aug 2012 15:28:00 +0100 Subject: iio:ad5446: get rid of private header file Most of the defines in there were not even used, and the structs left are private to the .c file. Makes the driver more in line with most of the kernel drivers. Signed-off-by: Jean-Francois Dagenais Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 241665b..7f11c1c 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -22,7 +22,40 @@ #include #include -#include "ad5446.h" +#define MODE_PWRDWN_1k 0x1 +#define MODE_PWRDWN_100k 0x2 +#define MODE_PWRDWN_TRISTATE 0x3 + +/** + * struct ad5446_state - driver instance specific data + * @spi: spi_device + * @chip_info: chip model specific constants, available modes etc + * @reg: supply regulator + * @vref_mv: actual reference voltage used + */ + +struct ad5446_state { + struct device *dev; + const struct ad5446_chip_info *chip_info; + struct regulator *reg; + unsigned short vref_mv; + unsigned cached_val; + unsigned pwr_down_mode; + unsigned pwr_down; +}; + +/** + * struct ad5446_chip_info - chip specific information + * @channel: channel spec for the DAC + * @int_vref_mv: AD5620/40/60: the internal reference voltage + * @write: chip specific helper function to write to the register + */ + +struct ad5446_chip_info { + struct iio_chan_spec channel; + u16 int_vref_mv; + int (*write)(struct ad5446_state *st, unsigned val); +}; static const char * const ad5446_powerdown_modes[] = { "1kohm_to_gnd", "100kohm_to_gnd", "three_state" diff --git a/drivers/iio/dac/ad5446.h b/drivers/iio/dac/ad5446.h deleted file mode 100644 index 6b7a176..0000000 --- a/drivers/iio/dac/ad5446.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * AD5446 SPI DAC driver - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ -#ifndef IIO_DAC_AD5446_H_ -#define IIO_DAC_AD5446_H_ - -/* DAC Control Bits */ - -#define AD5446_LOAD (0x0 << 14) /* Load and update */ -#define AD5446_SDO_DIS (0x1 << 14) /* Disable SDO */ -#define AD5446_NOP (0x2 << 14) /* No operation */ -#define AD5446_CLK_RISING (0x3 << 14) /* Clock data on rising edge */ - -#define AD5620_LOAD (0x0 << 14) /* Load and update Norm Operation*/ -#define AD5620_PWRDWN_1k (0x1 << 14) /* Power-down: 1kOhm to GND */ -#define AD5620_PWRDWN_100k (0x2 << 14) /* Power-down: 100kOhm to GND */ -#define AD5620_PWRDWN_TRISTATE (0x3 << 14) /* Power-down: Three-state */ - -#define AD5660_LOAD (0x0 << 16) /* Load and update Norm Operation*/ -#define AD5660_PWRDWN_1k (0x1 << 16) /* Power-down: 1kOhm to GND */ -#define AD5660_PWRDWN_100k (0x2 << 16) /* Power-down: 100kOhm to GND */ -#define AD5660_PWRDWN_TRISTATE (0x3 << 16) /* Power-down: Three-state */ - -#define MODE_PWRDWN_1k 0x1 -#define MODE_PWRDWN_100k 0x2 -#define MODE_PWRDWN_TRISTATE 0x3 - -/** - * struct ad5446_state - driver instance specific data - * @spi: spi_device - * @chip_info: chip model specific constants, available modes etc - * @reg: supply regulator - * @vref_mv: actual reference voltage used - */ - -struct ad5446_state { - struct device *dev; - const struct ad5446_chip_info *chip_info; - struct regulator *reg; - unsigned short vref_mv; - unsigned cached_val; - unsigned pwr_down_mode; - unsigned pwr_down; -}; - -/** - * struct ad5446_chip_info - chip specific information - * @channel: channel spec for the DAC - * @int_vref_mv: AD5620/40/60: the internal reference voltage - * @write: chip specific helper function to write to the register - */ - -struct ad5446_chip_info { - struct iio_chan_spec channel; - u16 int_vref_mv; - int (*write)(struct ad5446_state *st, unsigned val); -}; - - -#endif /* IIO_DAC_AD5446_H_ */ -- cgit v0.10.2 From c8b95952e7ad2ff850153a12f090f810bf90f27c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 2 Sep 2012 21:27:56 +0100 Subject: IIO: Update email address for Jonathan Cameron. Signed-off-by: Jonathan Cameron diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index a288792..fa3b9f5 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -980,6 +980,6 @@ EXPORT_SYMBOL(iio_device_unregister); subsys_initcall(iio_init); module_exit(iio_exit); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Industrial I/O core"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 0f8c9620046d698b8a00d38d25dcdc1d2fa23592 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 2 Sep 2012 21:34:59 +0100 Subject: staging:iio: Update email address for Jonathan Cameron. Signed-off-by: Jonathan Cameron diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO index cf3f948..04c2326 100644 --- a/drivers/staging/iio/TODO +++ b/drivers/staging/iio/TODO @@ -69,5 +69,5 @@ Documentation 1) Lots of cleanup and expansion. 2) Some device require individual docs. -Contact: Jonathan Cameron . +Contact: Jonathan Cameron . Mailing list: linux-iio@vger.kernel.org diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index 713469f..fdd5fbd 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -2,7 +2,7 @@ * kxsd9.c simple support for the Kionix KXSD9 3D * accelerometer. * - * Copyright (c) 2008-2009 Jonathan Cameron + * Copyright (c) 2008-2009 Jonathan Cameron * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -286,6 +286,6 @@ static struct spi_driver kxsd9_driver = { }; module_spi_driver(kxsd9_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Kionix KXSD9 SPI driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h index ad51658..f9bcd41 100644 --- a/drivers/staging/iio/accel/lis3l02dq.h +++ b/drivers/staging/iio/accel/lis3l02dq.h @@ -2,7 +2,7 @@ * LISL02DQ.h -- support STMicroelectronics LISD02DQ * 3d 2g Linear Accelerometers via SPI * - * Copyright (c) 2007 Jonathan Cameron + * Copyright (c) 2007 Jonathan Cameron * * Loosely based upon tle62x0.c * diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 0144afe..d900d63 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -2,7 +2,7 @@ * lis3l02dq.c support STMicroelectronics LISD02DQ * 3d 2g Linear Accelerometers via SPI * - * Copyright (c) 2007 Jonathan Cameron + * Copyright (c) 2007 Jonathan Cameron * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -818,7 +818,7 @@ static struct spi_driver lis3l02dq_driver = { }; module_spi_driver(lis3l02dq_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("ST LIS3L02DQ Accelerometer SPI driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("spi:lis3l02dq"); diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h index 131daac..c1016c5 100644 --- a/drivers/staging/iio/accel/sca3000.h +++ b/drivers/staging/iio/accel/sca3000.h @@ -2,7 +2,7 @@ * sca3000.c -- support VTI sca3000 series accelerometers * via SPI * - * Copyright (c) 2007 Jonathan Cameron + * Copyright (c) 2007 Jonathan Cameron * * Partly based upon tle62x0.c * diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 581cdbd..6d72d97 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -5,7 +5,7 @@ * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * - * Copyright (c) 2009 Jonathan Cameron + * Copyright (c) 2009 Jonathan Cameron * * See industrialio/accels/sca3000.h for comments. */ @@ -1272,6 +1272,6 @@ static struct spi_driver sca3000_driver = { }; module_spi_driver(sca3000_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("VTI SCA3000 Series Accelerometers SPI driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index b7e1a00..cbec2f1 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -5,7 +5,7 @@ * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * - * Copyright (c) 2009 Jonathan Cameron + * Copyright (c) 2009 Jonathan Cameron * */ diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index adb90fe..d7b4ffc 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -1439,6 +1439,6 @@ static struct i2c_driver max1363_driver = { }; module_i2c_driver(max1363_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Maxim 1363 ADC"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c index 0cd4fe9..74e24e8 100644 --- a/drivers/staging/iio/iio_dummy_evgen.c +++ b/drivers/staging/iio/iio_dummy_evgen.c @@ -216,6 +216,6 @@ static __exit void iio_dummy_evgen_exit(void) } module_exit(iio_dummy_evgen_exit); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("IIO dummy driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c index 4bb017a..69d4a3b 100644 --- a/drivers/staging/iio/iio_hwmon.c +++ b/drivers/staging/iio/iio_hwmon.c @@ -217,6 +217,6 @@ static struct platform_driver __refdata iio_hwmon_driver = { module_platform_driver(iio_hwmon_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("IIO to hwmon driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index 22eea83..029bcc6 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -558,6 +558,6 @@ static __exit void iio_dummy_exit(void) } module_exit(iio_dummy_exit); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("IIO dummy driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h index 9dd9f14..d59d7ac 100644 --- a/drivers/staging/iio/imu/adis16400.h +++ b/drivers/staging/iio/imu/adis16400.h @@ -5,7 +5,7 @@ * 3d 2.5gauss magnetometers via SPI * * Copyright (c) 2009 Manuel Stahl - * Copyright (c) 2007 Jonathan Cameron + * Copyright (c) 2007 Jonathan Cameron * * Loosely based upon lis3l02dq.h * diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index b9f8438..5397497 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -5,7 +5,7 @@ * 3d Magnetometers via SPI * * Copyright (c) 2009 Manuel Stahl - * Copyright (c) 2007 Jonathan Cameron + * Copyright (c) 2007 Jonathan Cameron * Copyright (c) 2011 Analog Devices Inc. * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index 6c3e50f..10e0954 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -1,6 +1,6 @@ /* Copyright (C) 2010 Texas Instruments Author: Shubhrajyoti Datta - Acknowledgement: Jonathan Cameron for valuable inputs. + Acknowledgement: Jonathan Cameron for valuable inputs. Support for HMC5883 and HMC5883L by Peter Meerwald . diff --git a/drivers/staging/iio/ring_hw.h b/drivers/staging/iio/ring_hw.h index cad8a2e..39c14a7 100644 --- a/drivers/staging/iio/ring_hw.h +++ b/drivers/staging/iio/ring_hw.h @@ -5,7 +5,7 @@ * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * - * Copyright (c) 2009 Jonathan Cameron + * Copyright (c) 2009 Jonathan Cameron * */ diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index de26d54..5ff4d7f 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -162,6 +162,6 @@ static struct platform_driver iio_gpio_trigger_driver = { module_platform_driver(iio_gpio_trigger_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Example gpio trigger for the iio subsystem"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index b837801..a3de76d 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -197,6 +197,6 @@ static struct platform_driver iio_trig_periodic_rtc_driver = { module_platform_driver(iio_trig_periodic_rtc_driver); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Periodic realtime clock trigger for the iio subsystem"); MODULE_LICENSE("GPL v2"); -- cgit v0.10.2