diff options
Diffstat (limited to 'drivers/iio/adc/ad7266.c')
| -rw-r--r-- | drivers/iio/adc/ad7266.c | 186 |
1 files changed, 61 insertions, 125 deletions
diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c index c2744a75c3b0..3364ac6c4631 100644 --- a/drivers/iio/adc/ad7266.c +++ b/drivers/iio/adc/ad7266.c @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * AD7266/65 SPI ADC driver * * Copyright 2012 Analog Devices Inc. - * - * Licensed under the GPL-2. */ #include <linux/device.h> @@ -12,7 +11,7 @@ #include <linux/spi/spi.h> #include <linux/regulator/consumer.h> #include <linux/err.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/interrupt.h> @@ -24,10 +23,11 @@ #include <linux/platform_data/ad7266.h> +#define AD7266_INTERNAL_REF_MV 2500 + struct ad7266_state { struct spi_device *spi; - struct regulator *reg; - unsigned long vref_uv; + unsigned long vref_mv; struct spi_transfer single_xfer[3]; struct spi_message single_msg; @@ -35,43 +35,36 @@ struct ad7266_state { enum ad7266_range range; enum ad7266_mode mode; bool fixed_addr; - struct gpio gpios[3]; + struct gpio_desc *gpios[3]; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. * The buffer needs to be large enough to hold two samples (4 bytes) and * the naturally aligned timestamp (8 bytes). */ - uint8_t data[ALIGN(4, sizeof(s64)) + sizeof(s64)] ____cacheline_aligned; + struct { + __be16 sample[2]; + aligned_s64 timestamp; + } data __aligned(IIO_DMA_MINALIGN); }; static int ad7266_wakeup(struct ad7266_state *st) { /* Any read with >= 2 bytes will wake the device */ - return spi_read(st->spi, st->data, 2); + return spi_read(st->spi, &st->data.sample[0], 2); } static int ad7266_powerdown(struct ad7266_state *st) { /* Any read with < 2 bytes will powerdown the device */ - return spi_read(st->spi, st->data, 1); + return spi_read(st->spi, &st->data.sample[0], 1); } static int ad7266_preenable(struct iio_dev *indio_dev) { struct ad7266_state *st = iio_priv(indio_dev); - int ret; - - ret = ad7266_wakeup(st); - if (ret) - return ret; - - ret = iio_sw_buffer_preenable(indio_dev); - if (ret) - ad7266_powerdown(st); - - return ret; + return ad7266_wakeup(st); } static int ad7266_postdisable(struct iio_dev *indio_dev) @@ -82,8 +75,6 @@ static int ad7266_postdisable(struct iio_dev *indio_dev) static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = { .preenable = &ad7266_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, .postdisable = &ad7266_postdisable, }; @@ -94,12 +85,10 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p) struct ad7266_state *st = iio_priv(indio_dev); int ret; - ret = spi_read(st->spi, st->data, 4); - if (ret == 0) { - if (indio_dev->scan_timestamp) - ((s64 *)st->data)[1] = pf->timestamp; - iio_push_to_buffers(indio_dev, (u8 *)st->data); - } + ret = spi_read(st->spi, st->data.sample, 4); + if (ret == 0) + iio_push_to_buffers_with_ts(indio_dev, &st->data, sizeof(st->data), + pf->timestamp); iio_trigger_notify_done(indio_dev->trig); @@ -126,14 +115,15 @@ static void ad7266_select_input(struct ad7266_state *st, unsigned int nr) } for (i = 0; i < 3; ++i) - gpio_set_value(st->gpios[i].gpio, (bool)(nr & BIT(i))); + gpiod_set_value(st->gpios[i], (bool)(nr & BIT(i))); } static int ad7266_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { struct ad7266_state *st = iio_priv(indio_dev); - unsigned int nr = find_first_bit(scan_mask, indio_dev->masklength); + unsigned int nr = find_first_bit(scan_mask, + iio_get_masklength(indio_dev)); ad7266_select_input(st, nr); @@ -148,7 +138,7 @@ static int ad7266_read_single(struct ad7266_state *st, int *val, ad7266_select_input(st, address); ret = spi_sync(st->spi, &st->single_msg); - *val = be16_to_cpu(st->data[address % 2]); + *val = be16_to_cpu(st->data.sample[address % 2]); return ret; } @@ -157,34 +147,34 @@ static int ad7266_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long m) { struct ad7266_state *st = iio_priv(indio_dev); - unsigned long scale_uv; + unsigned long scale_mv; int ret; switch (m) { case IIO_CHAN_INFO_RAW: - if (iio_buffer_enabled(indio_dev)) + if (!iio_device_claim_direct(indio_dev)) return -EBUSY; - ret = ad7266_read_single(st, val, chan->address); - if (ret) - return ret; + iio_device_release_direct(indio_dev); + if (ret < 0) + return ret; *val = (*val >> 2) & 0xfff; if (chan->scan_type.sign == 's') - *val = sign_extend32(*val, 11); + *val = sign_extend32(*val, + chan->scan_type.realbits - 1); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - scale_uv = (st->vref_uv * 100); + scale_mv = st->vref_mv; if (st->mode == AD7266_MODE_DIFF) - scale_uv *= 2; + scale_mv *= 2; if (st->range == AD7266_RANGE_2VREF) - scale_uv *= 2; + scale_mv *= 2; - scale_uv >>= chan->scan_type.realbits; - *val = scale_uv / 100000; - *val2 = (scale_uv % 100000) * 10; - return IIO_VAL_INT_PLUS_MICRO; + *val = scale_mv; + *val2 = chan->scan_type.realbits; + return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_OFFSET: if (st->range == AD7266_RANGE_2VREF && st->mode != AD7266_MODE_DIFF) @@ -290,10 +280,9 @@ static AD7266_DECLARE_DIFF_CHANNELS_FIXED(u, 'u'); static const struct iio_info ad7266_info = { .read_raw = &ad7266_read_raw, .update_scan_mode = &ad7266_update_scan_mode, - .driver_module = THIS_MODULE, }; -static unsigned long ad7266_available_scan_masks[] = { +static const unsigned long ad7266_available_scan_masks[] = { 0x003, 0x00c, 0x030, @@ -303,14 +292,14 @@ static unsigned long ad7266_available_scan_masks[] = { 0x000, }; -static unsigned long ad7266_available_scan_masks_diff[] = { +static const unsigned long ad7266_available_scan_masks_diff[] = { 0x003, 0x00c, 0x030, 0x000, }; -static unsigned long ad7266_available_scan_masks_fixed[] = { +static const unsigned long ad7266_available_scan_masks_fixed[] = { 0x003, 0x000, }; @@ -318,7 +307,7 @@ static unsigned long ad7266_available_scan_masks_fixed[] = { struct ad7266_chan_info { const struct iio_chan_spec *channels; unsigned int num_channels; - unsigned long *scan_masks; + const unsigned long *scan_masks; }; #define AD7266_CHAN_INFO_INDEX(_differential, _signed, _fixed) \ @@ -384,42 +373,31 @@ static void ad7266_init_channels(struct iio_dev *indio_dev) indio_dev->channels = chan_info->channels; indio_dev->num_channels = chan_info->num_channels; indio_dev->available_scan_masks = chan_info->scan_masks; - indio_dev->masklength = chan_info->num_channels - 1; } static const char * const ad7266_gpio_labels[] = { - "AD0", "AD1", "AD2", + "ad0", "ad1", "ad2", }; static int ad7266_probe(struct spi_device *spi) { - struct ad7266_platform_data *pdata = spi->dev.platform_data; + const struct ad7266_platform_data *pdata = dev_get_platdata(&spi->dev); struct iio_dev *indio_dev; struct ad7266_state *st; unsigned int i; int ret; - indio_dev = iio_device_alloc(sizeof(*st)); + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; st = iio_priv(indio_dev); - st->reg = regulator_get(&spi->dev, "vref"); - if (!IS_ERR_OR_NULL(st->reg)) { - ret = regulator_enable(st->reg); - if (ret) - goto error_put_reg; - - ret = regulator_get_voltage(st->reg); - if (ret < 0) - goto error_disable_reg; + ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vref"); + if (ret < 0 && ret != -ENODEV) + return ret; - st->vref_uv = ret; - } else { - /* Use internal reference */ - st->vref_uv = 2500000; - } + st->vref_mv = ret == -ENODEV ? AD7266_INTERNAL_REF_MV : ret / 1000; if (pdata) { st->fixed_addr = pdata->fixed_addr; @@ -428,14 +406,14 @@ static int ad7266_probe(struct spi_device *spi) if (!st->fixed_addr) { for (i = 0; i < ARRAY_SIZE(st->gpios); ++i) { - st->gpios[i].gpio = pdata->addr_gpios[i]; - st->gpios[i].flags = GPIOF_OUT_INIT_LOW; - st->gpios[i].label = ad7266_gpio_labels[i]; + st->gpios[i] = devm_gpiod_get(&spi->dev, + ad7266_gpio_labels[i], + GPIOD_OUT_LOW); + if (IS_ERR(st->gpios[i])) { + ret = PTR_ERR(st->gpios[i]); + return ret; + } } - ret = gpio_request_array(st->gpios, - ARRAY_SIZE(st->gpios)); - if (ret) - goto error_disable_reg; } } else { st->fixed_addr = true; @@ -443,10 +421,8 @@ static int ad7266_probe(struct spi_device *spi) st->mode = AD7266_MODE_DIFF; } - 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->info = &ad7266_info; @@ -454,15 +430,15 @@ static int ad7266_probe(struct spi_device *spi) ad7266_init_channels(indio_dev); /* wakeup */ - st->single_xfer[0].rx_buf = &st->data; + st->single_xfer[0].rx_buf = &st->data.sample[0]; st->single_xfer[0].len = 2; st->single_xfer[0].cs_change = 1; /* conversion */ - st->single_xfer[1].rx_buf = &st->data; + st->single_xfer[1].rx_buf = st->data.sample; st->single_xfer[1].len = 4; st->single_xfer[1].cs_change = 1; /* powerdown */ - st->single_xfer[2].tx_buf = &st->data; + st->single_xfer[2].tx_buf = &st->data.sample[0]; st->single_xfer[2].len = 1; spi_message_init(&st->single_msg); @@ -470,55 +446,17 @@ static int ad7266_probe(struct spi_device *spi) spi_message_add_tail(&st->single_xfer[1], &st->single_msg); spi_message_add_tail(&st->single_xfer[2], &st->single_msg); - ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, &iio_pollfunc_store_time, &ad7266_trigger_handler, &iio_triggered_buffer_setup_ops); if (ret) - goto error_free_gpios; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_buffer_cleanup; - - return 0; - -error_buffer_cleanup: - iio_triggered_buffer_cleanup(indio_dev); -error_free_gpios: - if (!st->fixed_addr) - gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios)); -error_disable_reg: - if (!IS_ERR_OR_NULL(st->reg)) - regulator_disable(st->reg); -error_put_reg: - if (!IS_ERR_OR_NULL(st->reg)) - regulator_put(st->reg); - - iio_device_free(indio_dev); - - return ret; -} - -static int ad7266_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad7266_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - iio_triggered_buffer_cleanup(indio_dev); - if (!st->fixed_addr) - gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios)); - if (!IS_ERR_OR_NULL(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static const struct spi_device_id ad7266_id[] = { - {"ad7265", 0}, - {"ad7266", 0}, + { "ad7265", 0 }, + { "ad7266", 0 }, { } }; MODULE_DEVICE_TABLE(spi, ad7266_id); @@ -526,10 +464,8 @@ MODULE_DEVICE_TABLE(spi, ad7266_id); static struct spi_driver ad7266_driver = { .driver = { .name = "ad7266", - .owner = THIS_MODULE, }, .probe = ad7266_probe, - .remove = ad7266_remove, .id_table = ad7266_id, }; module_spi_driver(ad7266_driver); |
