diff options
Diffstat (limited to 'drivers/iio/adc/ti-adc084s021.c')
| -rw-r--r-- | drivers/iio/adc/ti-adc084s021.c | 71 |
1 files changed, 31 insertions, 40 deletions
diff --git a/drivers/iio/adc/ti-adc084s021.c b/drivers/iio/adc/ti-adc084s021.c index 25504640e126..a100f770fa1c 100644 --- a/drivers/iio/adc/ti-adc084s021.c +++ b/drivers/iio/adc/ti-adc084s021.c @@ -1,18 +1,16 @@ -/** +// SPDX-License-Identifier: GPL-2.0-only +/* * Copyright (C) 2017 Axis Communications AB * * Driver for Texas Instruments' ADC084S021 ADC chip. * Datasheets can be found here: - * http://www.ti.com/lit/ds/symlink/adc084s021.pdf - * - * 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 - * published by the Free Software Foundation. + * https://www.ti.com/lit/ds/symlink/adc084s021.pdf */ #include <linux/err.h> #include <linux/spi/spi.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/interrupt.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> @@ -28,11 +26,16 @@ struct adc084s021 { struct spi_transfer spi_trans; struct regulator *reg; struct mutex lock; + /* Buffer used to align data */ + struct { + __be16 channels[4]; + aligned_s64 ts; + } scan; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache line. */ - u16 tx_buf[4] ____cacheline_aligned; + u16 tx_buf[4] __aligned(IIO_DMA_MINALIGN); __be16 rx_buf[5]; /* First 16-bits are trash */ }; @@ -62,16 +65,15 @@ static const struct iio_chan_spec adc084s021_channels[] = { }; /** - * Read an ADC channel and return its value. + * adc084s021_adc_conversion() - Read an ADC channel and return its value. * * @adc: The ADC SPI data. * @data: Buffer for converted data. */ -static int adc084s021_adc_conversion(struct adc084s021 *adc, void *data) +static int adc084s021_adc_conversion(struct adc084s021 *adc, __be16 *data) { int n_words = (adc->spi_trans.len >> 1) - 1; /* Discard first word */ int ret, i = 0; - u16 *p = data; /* Do the transfer */ ret = spi_sync(adc->spi, &adc->message); @@ -79,7 +81,7 @@ static int adc084s021_adc_conversion(struct adc084s021 *adc, void *data) return ret; for (; i < n_words; i++) - *(p + i) = adc->rx_buf[i + 1]; + *(data + i) = adc->rx_buf[i + 1]; return ret; } @@ -90,27 +92,27 @@ static int adc084s021_read_raw(struct iio_dev *indio_dev, { struct adc084s021 *adc = iio_priv(indio_dev); int ret; + __be16 be_val; switch (mask) { case IIO_CHAN_INFO_RAW: - ret = iio_device_claim_direct_mode(indio_dev); - if (ret < 0) - return ret; + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; ret = regulator_enable(adc->reg); if (ret) { - iio_device_release_direct_mode(indio_dev); + iio_device_release_direct(indio_dev); return ret; } adc->tx_buf[0] = channel->channel << 3; - ret = adc084s021_adc_conversion(adc, val); - iio_device_release_direct_mode(indio_dev); + ret = adc084s021_adc_conversion(adc, &be_val); + iio_device_release_direct(indio_dev); regulator_disable(adc->reg); if (ret < 0) return ret; - *val = be16_to_cpu(*val); + *val = be16_to_cpu(be_val); *val = (*val >> channel->scan_type.shift) & 0xff; return IIO_VAL_INT; @@ -133,7 +135,7 @@ static int adc084s021_read_raw(struct iio_dev *indio_dev, } /** - * Read enabled ADC channels and push data to the buffer. + * adc084s021_buffer_trigger_handler() - Read ADC channels and push to buffer. * * @irq: The interrupt number (not used). * @pollfunc: Pointer to the poll func. @@ -143,15 +145,14 @@ static irqreturn_t adc084s021_buffer_trigger_handler(int irq, void *pollfunc) struct iio_poll_func *pf = pollfunc; struct iio_dev *indio_dev = pf->indio_dev; struct adc084s021 *adc = iio_priv(indio_dev); - __be16 data[8] = {0}; /* 4 * 16-bit words of data + 8 bytes timestamp */ mutex_lock(&adc->lock); - if (adc084s021_adc_conversion(adc, &data) < 0) + if (adc084s021_adc_conversion(adc, adc->scan.channels) < 0) dev_err(&adc->spi->dev, "Failed to read data\n"); - iio_push_to_buffers_with_timestamp(indio_dev, data, - iio_get_time_ns(indio_dev)); + iio_push_to_buffers_with_ts(indio_dev, &adc->scan, sizeof(adc->scan), + iio_get_time_ns(indio_dev)); mutex_unlock(&adc->lock); iio_trigger_notify_done(indio_dev->trig); @@ -164,8 +165,7 @@ static int adc084s021_buffer_preenable(struct iio_dev *indio_dev) int scan_index; int i = 0; - for_each_set_bit(scan_index, indio_dev->active_scan_mask, - indio_dev->masklength) { + iio_for_each_active_channel(indio_dev, scan_index) { const struct iio_chan_spec *channel = &indio_dev->channels[scan_index]; adc->tx_buf[i++] = channel->channel << 3; @@ -190,8 +190,6 @@ static const struct iio_info adc084s021_info = { static const struct iio_buffer_setup_ops adc084s021_buffer_setup_ops = { .preenable = adc084s021_buffer_preenable, - .postenable = iio_triggered_buffer_postenable, - .predisable = iio_triggered_buffer_predisable, .postdisable = adc084s021_buffer_postdisable, }; @@ -202,20 +200,13 @@ static int adc084s021_probe(struct spi_device *spi) int ret; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); - if (!indio_dev) { - dev_err(&spi->dev, "Failed to allocate IIO device\n"); + if (!indio_dev) return -ENOMEM; - } adc = iio_priv(indio_dev); adc->spi = spi; - /* Connect the SPI device and the iio dev */ - spi_set_drvdata(spi, indio_dev); - /* Initiate the Industrial I/O device */ - indio_dev->dev.parent = &spi->dev; - indio_dev->dev.of_node = spi->dev.of_node; indio_dev->name = spi_get_device_id(spi)->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &adc084s021_info; @@ -248,20 +239,20 @@ static int adc084s021_probe(struct spi_device *spi) static const struct of_device_id adc084s021_of_match[] = { { .compatible = "ti,adc084s021", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, adc084s021_of_match); static const struct spi_device_id adc084s021_id[] = { - { ADC084S021_DRIVER_NAME, 0}, - {} + { ADC084S021_DRIVER_NAME, 0 }, + { } }; MODULE_DEVICE_TABLE(spi, adc084s021_id); static struct spi_driver adc084s021_driver = { .driver = { .name = ADC084S021_DRIVER_NAME, - .of_match_table = of_match_ptr(adc084s021_of_match), + .of_match_table = adc084s021_of_match, }, .probe = adc084s021_probe, .id_table = adc084s021_id, |
