diff options
Diffstat (limited to 'drivers/iio/dac/ad5764.c')
| -rw-r--r-- | drivers/iio/dac/ad5764.c | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/drivers/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c index 9333177062c0..fbbd7105a80c 100644 --- a/drivers/iio/dac/ad5764.c +++ b/drivers/iio/dac/ad5764.c @@ -1,10 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Analog devices AD5764, AD5764R, AD5744, AD5744R quad-channel * Digital to Analog Converters driver * * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. */ #include <linux/device.h> @@ -34,9 +33,8 @@ * struct ad5764_chip_info - chip specific information * @int_vref: Value of the internal reference voltage in uV - 0 if external * reference voltage is used - * @channel channel specification + * @channels: channel specification */ - struct ad5764_chip_info { unsigned long int_vref; const struct iio_chan_spec *channels; @@ -47,6 +45,7 @@ struct ad5764_chip_info { * @spi: spi_device * @chip_info: chip info * @vref_reg: vref supply regulators + * @lock: lock to protect the data buffer during SPI ops * @data: spi transfer buffers */ @@ -54,15 +53,16 @@ struct ad5764_state { struct spi_device *spi; const struct ad5764_chip_info *chip_info; struct regulator_bulk_data vref_reg[2]; + struct mutex lock; /* - * DMA (thus cache coherency maintenance) requires the + * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. */ union { __be32 d32; u8 d8[4]; - } data[2] ____cacheline_aligned; + } data[2] __aligned(IIO_DMA_MINALIGN); }; enum ad5764_type { @@ -127,11 +127,11 @@ static int ad5764_write(struct iio_dev *indio_dev, unsigned int reg, struct ad5764_state *st = iio_priv(indio_dev); int ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); st->data[0].d32 = cpu_to_be32((reg << 16) | val); ret = spi_write(st->spi, &st->data[0].d8[1], 3); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; } @@ -152,7 +152,7 @@ static int ad5764_read(struct iio_dev *indio_dev, unsigned int reg, }, }; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); st->data[0].d32 = cpu_to_be32((1 << 23) | (reg << 16)); @@ -160,7 +160,7 @@ static int ad5764_read(struct iio_dev *indio_dev, unsigned int reg, if (ret >= 0) *val = be32_to_cpu(st->data[1].d32) & 0xffff; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; } @@ -278,10 +278,8 @@ static int ad5764_probe(struct spi_device *spi) int ret; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (indio_dev == NULL) { - dev_err(&spi->dev, "Failed to allocate iio device\n"); + if (indio_dev == NULL) return -ENOMEM; - } st = iio_priv(indio_dev); spi_set_drvdata(spi, indio_dev); @@ -289,13 +287,14 @@ static int ad5764_probe(struct spi_device *spi) st->spi = spi; st->chip_info = &ad5764_chip_infos[type]; - indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; indio_dev->info = &ad5764_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->num_channels = AD5764_NUM_CHANNELS; indio_dev->channels = st->chip_info->channels; + mutex_init(&st->lock); + if (st->chip_info->int_vref == 0) { st->vref_reg[0].supply = "vrefAB"; st->vref_reg[1].supply = "vrefCD"; @@ -331,7 +330,7 @@ error_disable_reg: return ret; } -static int ad5764_remove(struct spi_device *spi) +static void ad5764_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad5764_state *st = iio_priv(indio_dev); @@ -340,8 +339,6 @@ static int ad5764_remove(struct spi_device *spi) if (st->chip_info->int_vref == 0) regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg); - - return 0; } static const struct spi_device_id ad5764_ids[] = { |
