diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index d4984c8be973..56825e6f5725 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/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 8a78b4f3ef58..a2c50713b0b6 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 52eec254c38c..5989356c5735 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 000000000000..ae847c5a1361 --- /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/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 98c96f90c88b..c1e4690f188d 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 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) 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); diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 1be15fa9d618..293b61dcc559 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 2ca5059ef89e..7f11c1c89960 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,24 +22,40 @@ #include #include -#include "ad5446.h" +#define MODE_PWRDWN_1k 0x1 +#define MODE_PWRDWN_100k 0x2 +#define MODE_PWRDWN_TRISTATE 0x3 -static int ad5446_write(struct ad5446_state *st, unsigned val) -{ - __be16 data = cpu_to_be16(val); - return spi_write(st->spi, &data, sizeof(data)); -} +/** + * 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 + */ -static int ad5660_write(struct ad5446_state *st, unsigned val) -{ - uint8_t data[3]; +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; +}; - data[0] = (val >> 16) & 0xFF; - data[1] = (val >> 8) & 0xFF; - data[2] = val & 0xFF; +/** + * 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 + */ - return spi_write(st->spi, data, sizeof(data)); -} +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" @@ -110,7 +127,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,9 +153,194 @@ 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) + _AD5446_CHANNEL(bits, storage, shift, ad5446_ext_info_powerdown) -static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { +static int ad5446_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ad5446_state *st = iio_priv(indio_dev); + unsigned long scale_uv; + + switch (m) { + case IIO_CHAN_INFO_RAW: + *val = st->cached_val; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits; + *val = scale_uv / 1000; + *val2 = (scale_uv % 1000) * 1000; + return IIO_VAL_INT_PLUS_MICRO; + + } + return -EINVAL; +} + +static int ad5446_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct ad5446_state *st = iio_priv(indio_dev); + int ret = 0; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (val >= (1 << chan->scan_type.realbits) || val < 0) + return -EINVAL; + + val <<= chan->scan_type.shift; + mutex_lock(&indio_dev->mlock); + st->cached_val = val; + if (!st->pwr_down) + ret = st->chip_info->write(st, val); + mutex_unlock(&indio_dev->mlock); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static const struct iio_info ad5446_info = { + .read_raw = ad5446_read_raw, + .write_raw = ad5446_write_raw, + .driver_module = THIS_MODULE, +}; + +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(dev, "vcc"); + if (!IS_ERR(reg)) { + ret = regulator_enable(reg); + if (ret) + goto error_put_reg; + + voltage_uv = regulator_get_voltage(reg); + } + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + st = iio_priv(indio_dev); + st->chip_info = chip_info; + + dev_set_drvdata(dev, indio_dev); + st->reg = reg; + st->dev = dev; + + /* 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; + indio_dev->num_channels = 1; + + st->pwr_down_mode = MODE_PWRDWN_1k; + + if (st->chip_info->int_vref_mv) + st->vref_mv = st->chip_info->int_vref_mv; + else if (voltage_uv) + st->vref_mv = voltage_uv / 1000; + else + dev_warn(dev, "reference voltage unspecified\n"); + + ret = iio_device_register(indio_dev); + if (ret) + goto error_free_device; + + return 0; + +error_free_device: + iio_device_free(indio_dev); +error_disable_reg: + if (!IS_ERR(reg)) + regulator_disable(reg); +error_put_reg: + if (!IS_ERR(reg)) + regulator_put(reg); + + return ret; +} + +static int ad5446_remove(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5446_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + iio_device_free(indio_dev); + + return 0; +} + +#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, @@ -215,143 +417,7 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { }, }; -static int ad5446_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long m) -{ - struct ad5446_state *st = iio_priv(indio_dev); - unsigned long scale_uv; - - switch (m) { - case IIO_CHAN_INFO_RAW: - *val = st->cached_val; - return IIO_VAL_INT; - case IIO_CHAN_INFO_SCALE: - scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits; - *val = scale_uv / 1000; - *val2 = (scale_uv % 1000) * 1000; - return IIO_VAL_INT_PLUS_MICRO; - - } - return -EINVAL; -} - -static int ad5446_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, - int val2, - long mask) -{ - struct ad5446_state *st = iio_priv(indio_dev); - int ret = 0; - - switch (mask) { - case IIO_CHAN_INFO_RAW: - if (val >= (1 << chan->scan_type.realbits) || val < 0) - return -EINVAL; - - val <<= chan->scan_type.shift; - mutex_lock(&indio_dev->mlock); - st->cached_val = val; - if (!st->pwr_down) - ret = st->chip_info->write(st, val); - mutex_unlock(&indio_dev->mlock); - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static const struct iio_info ad5446_info = { - .read_raw = ad5446_read_raw, - .write_raw = ad5446_write_raw, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad5446_probe(struct spi_device *spi) -{ - struct ad5446_state *st; - struct iio_dev *indio_dev; - struct regulator *reg; - int ret, voltage_uv = 0; - - reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(reg)) { - ret = regulator_enable(reg); - if (ret) - goto error_put_reg; - - voltage_uv = regulator_get_voltage(reg); - } - - indio_dev = iio_device_alloc(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_disable_reg; - } - st = iio_priv(indio_dev); - st->chip_info = - &ad5446_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - - spi_set_drvdata(spi, indio_dev); - st->reg = reg; - st->spi = spi; - - /* 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; - indio_dev->info = &ad5446_info; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = &st->chip_info->channel; - indio_dev->num_channels = 1; - - st->pwr_down_mode = MODE_PWRDWN_1k; - - if (st->chip_info->int_vref_mv) - st->vref_mv = st->chip_info->int_vref_mv; - else if (voltage_uv) - st->vref_mv = voltage_uv / 1000; - else - dev_warn(&spi->dev, "reference voltage unspecified\n"); - - ret = iio_device_register(indio_dev); - if (ret) - goto error_free_device; - - return 0; - -error_free_device: - iio_device_free(indio_dev); -error_disable_reg: - if (!IS_ERR(reg)) - regulator_disable(reg); -error_put_reg: - if (!IS_ERR(reg)) - regulator_put(reg); - - return ret; -} - -static int ad5446_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad5446_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); - - return 0; -} - -static const struct spi_device_id ad5446_id[] = { +static const struct spi_device_id ad5446_spi_ids[] = { {"ad5444", ID_AD5444}, {"ad5446", ID_AD5446}, {"ad5450", ID_AD5450}, @@ -375,18 +441,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 struct spi_driver ad5446_driver = { +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 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, }; -module_spi_driver(ad5446_driver); + +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, + }, +}; + +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 deleted file mode 100644 index 2934269a56d5..000000000000 --- a/drivers/iio/dac/ad5446.h +++ /dev/null @@ -1,91 +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 spi_device *spi; - 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); -}; - -/** - * 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_ */ diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 4add9bb40eeb..774891cf8139 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 2ec266ef41a3..fa3b9f5e6c45 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; @@ -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++) { @@ -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"); diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index b5afc2ff34fd..a14e55dd8ddc 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); diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 6bf9d05f4841..63da42498a9a 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; @@ -22,7 +23,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) @@ -35,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; } @@ -81,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); @@ -94,9 +100,12 @@ 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; + r->stufftoread = true; + wake_up_interruptible(&r->pollq); + return 0; } @@ -106,11 +115,18 @@ 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; - n = rounddown(n, r->bytes_per_datum); ret = kfifo_to_user(&kf->kf, buf, n, &copied); + 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; } @@ -136,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); diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index 04cd6ec1f70f..ca56c75a35fc 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 diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO index cf3f9489b9da..04c23262f8e2 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/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index ec2332f568fa..8e37d6e04277 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -565,7 +565,7 @@ static int __devinit adis16201_probe(struct spi_device *spi) 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 34b76c51c78b..002fa9dfc375 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -500,7 +500,7 @@ static int __devinit adis16203_probe(struct spi_device *spi) 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 02fb101aca93..05bdb7c2c8e3 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -558,7 +558,7 @@ static int __devinit adis16204_probe(struct spi_device *spi) 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 4fa2229d8736..b7333bfe0b2f 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -573,7 +573,7 @@ static int __devinit adis16209_probe(struct spi_device *spi) 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 c31e1ec2e66a..c755089c7117 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -663,7 +663,7 @@ static int __devinit adis16220_probe(struct spi_device *spi) 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 dafc0d8cbf63..0fc26a49d681 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -619,7 +619,7 @@ static int __devinit adis16240_probe(struct spi_device *spi) 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/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index 713469fd2ac0..fdd5fbded660 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 ae5f225b4bb2..f9bcd41f7188 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 * @@ -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 0c2b4bae0a9b..d900d63d5a5b 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 @@ -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; @@ -780,7 +780,7 @@ static int lis3l02dq_stop_device(struct iio_dev *indio_dev) } /* 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); @@ -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/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 18d108fd967a..7da2703885d6 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); diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h index 131daac90012..c1016c510dae 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 cc040e14adba..6d72d97fb9e5 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. */ @@ -1233,7 +1233,7 @@ static int sca3000_stop_all_interrupts(struct sca3000_state *st) 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); @@ -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 b7e1a002630a..cbec2f1665e5 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/Kconfig b/drivers/staging/iio/adc/Kconfig index 845fb6c70ca3..a1fa1729acbe 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). @@ -108,13 +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 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). + 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 @@ -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 405d9a8d7b6d..c351cae24c96 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,13 +136,7 @@ */ 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; u16 int_vref_mv; u32 mclk; u32 f_order; @@ -148,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; + + struct ad_sigma_delta sd; }; -static int __ad7192_write_reg(struct ad7192_state *st, bool locked, - bool cs_change, unsigned char reg, - unsigned size, unsigned val) +static struct ad7192_state *ad_sigma_delta_to_ad7192(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] = 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); + return container_of(sd, struct ad7192_state, sd); } -static int ad7192_write_reg(struct ad7192_state *st, - unsigned reg, unsigned size, unsigned val) +static int ad7192_set_channel(struct ad_sigma_delta *sd, unsigned int channel) { - return __ad7192_write_reg(st, false, false, reg, size, val); + struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd); + + st->conf &= ~AD7192_CONF_CHAN_MASK; + st->conf |= AD7192_CONF_CHAN(channel); + + return ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf); } -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_mode(struct ad_sigma_delta *sd, + enum ad_sigma_delta_mode mode) { - 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; + struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd); - data[0] = AD7192_COMM_READ | AD7192_COMM_ADDR(reg); + st->mode &= ~AD7192_MODE_SEL_MASK; + st->mode |= AD7192_MODE_SEL(mode); - 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); - - 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, AD7192_REG_MODE, 3, st->mode); } -static int ad7192_read_reg(struct ad7192_state *st, - unsigned reg, int *val, unsigned size) -{ - return __ad7192_read_reg(st, 0, 0, reg, val, size); -} +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 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); - - spi_bus_lock(st->spi->master); - st->done = false; - - 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; -} - -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 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}, @@ -332,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) +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; + 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: @@ -423,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; @@ -448,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) @@ -662,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); @@ -674,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) { @@ -746,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) @@ -754,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; @@ -810,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: @@ -881,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: @@ -902,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) @@ -923,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, }; @@ -932,60 +588,25 @@ 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), }; 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 +636,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) @@ -1025,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; @@ -1037,17 +655,13 @@ 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); + ret = ad7192_setup(st, pdata); if (ret) goto error_remove_trigger; @@ -1057,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); @@ -1072,14 +684,13 @@ static int __devinit ad7192_probe(struct spi_device *spi) 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); 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); diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index 4d30a798ba0d..4f6d59e89fcd 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -196,7 +196,7 @@ static int __devinit ad7476_probe(struct spi_device *spi) 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 19ee49c95de4..5f807ce3bf11 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; + return container_of(sd, struct ad7780_state, sd); +} - spi_bus_lock(st->spi->master); +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; - enable_irq(st->spi->irq); - st->done = false; - gpio_set_value(st->pdata->gpio_pdrst, 1); + switch (mode) { + case AD_SD_MODE_SINGLE: + case AD_SD_MODE_CONTINUOUS: + val = 1; + break; + default: + val = 0; + break; + } - ret = wait_event_interruptible(st->wq_data_avail, st->done); - disable_irq_nosync(st->spi->irq); - if (ret) - goto out; + gpio_set_value(st->powerdown_gpio, val); - 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); - - return ret; + return 0; } static int ad7780_read_raw(struct iio_dev *indio_dev, @@ -89,87 +85,55 @@ 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 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, - }, - }, - }, - [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, - }, - }, - }, +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, }; -/** - * 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 ad7780_chip_info ad7780_chip_info_tbl[] = { + [ID_AD7780] = { + .channel = AD_SD_CHANNEL(1, 0, 0, 24, 32, 8), + }, + [ID_AD7781] = { + .channel = AD_SD_CHANNEL(1, 0, 0, 20, 32, 12), + }, }; static const struct iio_info ad7780_info = { @@ -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); @@ -272,14 +225,15 @@ static int __devinit ad7780_probe(struct spi_device *spi) 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); 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); diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 112e2b7b5bc4..691a7be6f5cb 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -1,5 +1,5 @@ /* - * AD7792/AD7793 SPI ADC driver + * AD7785/AD7792/AD7793/AD7794/AD7795 SPI ADC driver * * Copyright 2011-2012 Analog Devices Inc. * @@ -24,6 +24,7 @@ #include #include #include +#include #include "ad7793.h" @@ -36,198 +37,65 @@ */ struct ad7793_chip_info { - struct iio_chan_spec channel[7]; + const struct iio_chan_spec *channels; + unsigned int num_channels; }; struct ad7793_state { - struct spi_device *spi; - 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; 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 { + ID_AD7785, ID_AD7792, ID_AD7793, + ID_AD7794, + ID_AD7795, }; -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); + + st->conf &= ~AD7793_CONF_CHAN_MASK; + st->conf |= AD7793_CONF_CHAN(channel); + + return ad_sd_write_reg(&st->sd, AD7793_REG_CONF, 2, st->conf); } -static int __ad7793_read_reg(struct ad7793_state *st, bool locked, - bool cs_change, unsigned char reg, - int *val, unsigned size) +static int ad7793_set_mode(struct ad_sigma_delta *sd, + enum ad_sigma_delta_mode mode) { - 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; + struct ad7793_state *st = ad_sigma_delta_to_ad7793(sd); - data[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(reg); + st->mode &= ~AD7793_MODE_SEL_MASK; + st->mode |= AD7793_MODE_SEL(mode); - 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); - - 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_MODE, 2, st->mode); } -static int ad7793_read_reg(struct ad7793_state *st, - unsigned reg, int *val, unsigned size) -{ - return __ad7793_read_reg(st, 0, 0, reg, val, size); -} +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 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); - - 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); - - ret = __ad7793_read_reg(st, 1, 0, AD7793_REG_DATA, val, len); -out: - spi_bus_unlock(st->spi->master); - - return ret; -} - -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 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}, @@ -238,59 +106,49 @@ 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"); + if (!((id == AD7792_ID) || (id == AD7793_ID) || (id == AD7795_ID))) { + dev_err(&st->sd.spi->dev, "device ID query failed\n"); goto out; } - st->mode = (st->pdata->mode & ~AD7793_MODE_SEL(-1)) | - AD7793_MODE_SEL(AD7793_MODE_IDLE); - st->conf = st->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, - sizeof(st->pdata->io), st->pdata->io); + ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, + sizeof(pdata->io), pdata->io); if (ret) goto out; @@ -301,7 +159,7 @@ static int ad7793_setup(struct ad7793_state *st) /* 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; @@ -311,184 +169,10 @@ static int ad7793_setup(struct ad7793_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 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: - 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 +215,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 +269,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 +349,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 +371,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,172 +383,67 @@ 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, }; +#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), (_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), \ +} + +#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(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_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[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_AD7785] = { + .channels = ad7785_channels, + .num_channels = ARRAY_SIZE(ad7785_channels), }, [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[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), + .channels = ad7792_channels, + .num_channels = ARRAY_SIZE(ad7792_channels), + }, + [ID_AD7793] = { + .channels = ad7793_channels, + .num_channels = ARRAY_SIZE(ad7793_channels), + }, + [ID_AD7794] = { + .channels = ad7794_channels, + .num_channels = ARRAY_SIZE(ad7794_channels), + }, + [ID_AD7795] = { + .channels = ad7795_channels, + .num_channels = ARRAY_SIZE(ad7795_channels), }, }; 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; @@ -903,6 +464,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); @@ -915,8 +478,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) @@ -925,26 +486,19 @@ 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; 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; - 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); + ret = ad7793_setup(indio_dev, pdata); if (ret) goto error_remove_trigger; @@ -955,9 +509,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); @@ -970,14 +522,13 @@ static int __devinit ad7793_probe(struct spi_device *spi) 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); 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); @@ -990,8 +541,11 @@ 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}, + {"ad7795", ID_AD7795}, {} }; MODULE_DEVICE_TABLE(spi, ad7793_id); @@ -1008,5 +562,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 64f7d41dc453..8fdd450a2cd9 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 */ @@ -69,7 +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(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(-) */ @@ -78,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) */ diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c index 397b84947155..551790584a12 100644 --- a/drivers/staging/iio/adc/ad7887_core.c +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -219,7 +219,7 @@ static int __devinit ad7887_probe(struct spi_device *spi) 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 816bb2c2e0c5..d7b4ffcfa052 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -1367,7 +1367,7 @@ static int __devinit max1363_probe(struct i2c_client *client, 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,11 +1434,11 @@ 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); -MODULE_AUTHOR("Jonathan Cameron "); +MODULE_AUTHOR("Jonathan Cameron "); MODULE_DESCRIPTION("Maxim 1363 ADC"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c index 675c427c02ad..0b83e2e1f410 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); diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 9931e2060e1f..87151a7cff04 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -184,7 +184,7 @@ static int __devinit adis16060_r_probe(struct spi_device *spi) } /* 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 @@ static int __devinit adis16060_w_probe(struct spi_device *spi) 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 345e4fa778ba..a73902573f79 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -177,7 +177,7 @@ static int __devinit adis16080_probe(struct spi_device *spi) } /* 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 bf61cd0b5bbc..fbf96b0b6ee8 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -154,7 +154,7 @@ static int __devinit adis16130_probe(struct spi_device *spi) } /* 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 93aa431287ac..dec2504b0086 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -698,7 +698,7 @@ static int __devinit adis16260_probe(struct spi_device *spi) 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 6513119b1e90..d93527d15917 100644 --- a/drivers/staging/iio/gyro/adxrs450_core.c +++ b/drivers/staging/iio/gyro/adxrs450_core.c @@ -409,7 +409,7 @@ static int __devinit adxrs450_probe(struct spi_device *spi) 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/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c index 0cd4fe916bf9..74e24e8aa876 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 4bb017acbf41..69d4a3b0ced4 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 22eea8305ff2..029bcc67f164 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 9dd9f1459a4d..d59d7ac856a9 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 4ce9e3dbe87c..5397497927c2 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 @@ -1204,7 +1204,7 @@ static int __devinit adis16400_probe(struct spi_device *spi) } /* 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 9d740be43a82..954ca2c172c6 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -805,7 +805,7 @@ static int __devinit tsl2563_probe(struct i2c_client *client, 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/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index 6c3e50f7c0d8..10e095486e54 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/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index f04ece7fbc2f..6caf80c35b49 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -553,7 +553,7 @@ static int __devinit ade7753_probe(struct spi_device *spi) } /* 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 6cee28a5e877..ab912ca434ab 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -575,7 +575,7 @@ static int __devinit ade7754_probe(struct spi_device *spi) } /* 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 6d3725a1cd78..958f8f235b42 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -962,7 +962,7 @@ static int __devinit ade7758_probe(struct spi_device *spi) 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 b3f7e0fa9612..d494052d3db3 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -497,7 +497,7 @@ static int __devinit ade7759_probe(struct spi_device *spi) } /* 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 9fb2f8bfca81..7dae03573428 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/ring_hw.h b/drivers/staging/iio/ring_hw.h index cad8a2ed9b68..39c14a715868 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 90b26846fc6b..5ff4d7fa20fa 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 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev) 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, @@ -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 4ceaa18ef9f4..a3de76d70cdc 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 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev) 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, @@ -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"); 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 000000000000..2e4eab9868a3 --- /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 diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index e2657e6d4d26..06ab4ec56c37 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; diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index be82936c4089..057d60382eac 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) \ @@ -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; @@ -367,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); }; @@ -516,6 +520,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 /** diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h index 014d5a13b32b..25eeac762e84 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 400a453ff67b..809a3f08d5a5 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.h b/include/linux/iio/trigger.h index a9819940a84c..20239da1d0f7 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, @@ -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) @@ -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 @@ -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. **/ diff --git a/include/linux/iio/trigger_consumer.h b/include/linux/iio/trigger_consumer.h index 60d64b356945..c4f8c7409666 100644 --- a/include/linux/iio/trigger_consumer.h +++ b/include/linux/iio/trigger_consumer.h @@ -7,6 +7,15 @@ * the Free Software Foundation. */ +#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 * @@ -50,3 +59,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