| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Analog devices AD5764, AD5764R, AD5744, AD5744R quad-channel |
|---|
| 3 | 4 | * Digital to Analog Converters driver |
|---|
| 4 | 5 | * |
|---|
| 5 | 6 | * Copyright 2011 Analog Devices Inc. |
|---|
| 6 | | - * |
|---|
| 7 | | - * Licensed under the GPL-2. |
|---|
| 8 | 7 | */ |
|---|
| 9 | 8 | |
|---|
| 10 | 9 | #include <linux/device.h> |
|---|
| .. | .. |
|---|
| 34 | 33 | * struct ad5764_chip_info - chip specific information |
|---|
| 35 | 34 | * @int_vref: Value of the internal reference voltage in uV - 0 if external |
|---|
| 36 | 35 | * reference voltage is used |
|---|
| 37 | | - * @channel channel specification |
|---|
| 36 | + * @channels: channel specification |
|---|
| 38 | 37 | */ |
|---|
| 39 | | - |
|---|
| 40 | 38 | struct ad5764_chip_info { |
|---|
| 41 | 39 | unsigned long int_vref; |
|---|
| 42 | 40 | const struct iio_chan_spec *channels; |
|---|
| .. | .. |
|---|
| 47 | 45 | * @spi: spi_device |
|---|
| 48 | 46 | * @chip_info: chip info |
|---|
| 49 | 47 | * @vref_reg: vref supply regulators |
|---|
| 48 | + * @lock: lock to protect the data buffer during SPI ops |
|---|
| 50 | 49 | * @data: spi transfer buffers |
|---|
| 51 | 50 | */ |
|---|
| 52 | 51 | |
|---|
| .. | .. |
|---|
| 54 | 53 | struct spi_device *spi; |
|---|
| 55 | 54 | const struct ad5764_chip_info *chip_info; |
|---|
| 56 | 55 | struct regulator_bulk_data vref_reg[2]; |
|---|
| 56 | + struct mutex lock; |
|---|
| 57 | 57 | |
|---|
| 58 | 58 | /* |
|---|
| 59 | 59 | * DMA (thus cache coherency maintenance) requires the |
|---|
| .. | .. |
|---|
| 127 | 127 | struct ad5764_state *st = iio_priv(indio_dev); |
|---|
| 128 | 128 | int ret; |
|---|
| 129 | 129 | |
|---|
| 130 | | - mutex_lock(&indio_dev->mlock); |
|---|
| 130 | + mutex_lock(&st->lock); |
|---|
| 131 | 131 | st->data[0].d32 = cpu_to_be32((reg << 16) | val); |
|---|
| 132 | 132 | |
|---|
| 133 | 133 | ret = spi_write(st->spi, &st->data[0].d8[1], 3); |
|---|
| 134 | | - mutex_unlock(&indio_dev->mlock); |
|---|
| 134 | + mutex_unlock(&st->lock); |
|---|
| 135 | 135 | |
|---|
| 136 | 136 | return ret; |
|---|
| 137 | 137 | } |
|---|
| .. | .. |
|---|
| 152 | 152 | }, |
|---|
| 153 | 153 | }; |
|---|
| 154 | 154 | |
|---|
| 155 | | - mutex_lock(&indio_dev->mlock); |
|---|
| 155 | + mutex_lock(&st->lock); |
|---|
| 156 | 156 | |
|---|
| 157 | 157 | st->data[0].d32 = cpu_to_be32((1 << 23) | (reg << 16)); |
|---|
| 158 | 158 | |
|---|
| .. | .. |
|---|
| 160 | 160 | if (ret >= 0) |
|---|
| 161 | 161 | *val = be32_to_cpu(st->data[1].d32) & 0xffff; |
|---|
| 162 | 162 | |
|---|
| 163 | | - mutex_unlock(&indio_dev->mlock); |
|---|
| 163 | + mutex_unlock(&st->lock); |
|---|
| 164 | 164 | |
|---|
| 165 | 165 | return ret; |
|---|
| 166 | 166 | } |
|---|
| .. | .. |
|---|
| 289 | 289 | st->spi = spi; |
|---|
| 290 | 290 | st->chip_info = &ad5764_chip_infos[type]; |
|---|
| 291 | 291 | |
|---|
| 292 | | - indio_dev->dev.parent = &spi->dev; |
|---|
| 293 | 292 | indio_dev->name = spi_get_device_id(spi)->name; |
|---|
| 294 | 293 | indio_dev->info = &ad5764_info; |
|---|
| 295 | 294 | indio_dev->modes = INDIO_DIRECT_MODE; |
|---|
| 296 | 295 | indio_dev->num_channels = AD5764_NUM_CHANNELS; |
|---|
| 297 | 296 | indio_dev->channels = st->chip_info->channels; |
|---|
| 298 | 297 | |
|---|
| 298 | + mutex_init(&st->lock); |
|---|
| 299 | + |
|---|
| 299 | 300 | if (st->chip_info->int_vref == 0) { |
|---|
| 300 | 301 | st->vref_reg[0].supply = "vrefAB"; |
|---|
| 301 | 302 | st->vref_reg[1].supply = "vrefCD"; |
|---|