| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * AD5755, AD5755-1, AD5757, AD5735, AD5737 Digital to analog converters driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2012 Analog Devices Inc. |
|---|
| 5 | | - * |
|---|
| 6 | | - * Licensed under the GPL-2. |
|---|
| 7 | 6 | */ |
|---|
| 8 | 7 | |
|---|
| 9 | 8 | #include <linux/device.h> |
|---|
| .. | .. |
|---|
| 83 | 82 | * @pwr_down: bitmask which contains hether a channel is powered down or not |
|---|
| 84 | 83 | * @ctrl: software shadow of the channel ctrl registers |
|---|
| 85 | 84 | * @channels: iio channel spec for the device |
|---|
| 85 | + * @lock: lock to protect the data buffer during SPI ops |
|---|
| 86 | 86 | * @data: spi transfer buffers |
|---|
| 87 | 87 | */ |
|---|
| 88 | 88 | struct ad5755_state { |
|---|
| .. | .. |
|---|
| 91 | 91 | unsigned int pwr_down; |
|---|
| 92 | 92 | unsigned int ctrl[AD5755_NUM_CHANNELS]; |
|---|
| 93 | 93 | struct iio_chan_spec channels[AD5755_NUM_CHANNELS]; |
|---|
| 94 | + struct mutex lock; |
|---|
| 94 | 95 | |
|---|
| 95 | 96 | /* |
|---|
| 96 | 97 | * DMA (thus cache coherency maintenance) requires the |
|---|
| .. | .. |
|---|
| 175 | 176 | static int ad5755_write(struct iio_dev *indio_dev, unsigned int reg, |
|---|
| 176 | 177 | unsigned int val) |
|---|
| 177 | 178 | { |
|---|
| 179 | + struct ad5755_state *st = iio_priv(indio_dev); |
|---|
| 178 | 180 | int ret; |
|---|
| 179 | 181 | |
|---|
| 180 | | - mutex_lock(&indio_dev->mlock); |
|---|
| 182 | + mutex_lock(&st->lock); |
|---|
| 181 | 183 | ret = ad5755_write_unlocked(indio_dev, reg, val); |
|---|
| 182 | | - mutex_unlock(&indio_dev->mlock); |
|---|
| 184 | + mutex_unlock(&st->lock); |
|---|
| 183 | 185 | |
|---|
| 184 | 186 | return ret; |
|---|
| 185 | 187 | } |
|---|
| .. | .. |
|---|
| 187 | 189 | static int ad5755_write_ctrl(struct iio_dev *indio_dev, unsigned int channel, |
|---|
| 188 | 190 | unsigned int reg, unsigned int val) |
|---|
| 189 | 191 | { |
|---|
| 192 | + struct ad5755_state *st = iio_priv(indio_dev); |
|---|
| 190 | 193 | int ret; |
|---|
| 191 | 194 | |
|---|
| 192 | | - mutex_lock(&indio_dev->mlock); |
|---|
| 195 | + mutex_lock(&st->lock); |
|---|
| 193 | 196 | ret = ad5755_write_ctrl_unlocked(indio_dev, channel, reg, val); |
|---|
| 194 | | - mutex_unlock(&indio_dev->mlock); |
|---|
| 197 | + mutex_unlock(&st->lock); |
|---|
| 195 | 198 | |
|---|
| 196 | 199 | return ret; |
|---|
| 197 | 200 | } |
|---|
| .. | .. |
|---|
| 212 | 215 | }, |
|---|
| 213 | 216 | }; |
|---|
| 214 | 217 | |
|---|
| 215 | | - mutex_lock(&indio_dev->mlock); |
|---|
| 218 | + mutex_lock(&st->lock); |
|---|
| 216 | 219 | |
|---|
| 217 | 220 | st->data[0].d32 = cpu_to_be32(AD5755_READ_FLAG | (addr << 16)); |
|---|
| 218 | 221 | st->data[1].d32 = cpu_to_be32(AD5755_NOOP); |
|---|
| .. | .. |
|---|
| 221 | 224 | if (ret >= 0) |
|---|
| 222 | 225 | ret = be32_to_cpu(st->data[1].d32) & 0xffff; |
|---|
| 223 | 226 | |
|---|
| 224 | | - mutex_unlock(&indio_dev->mlock); |
|---|
| 227 | + mutex_unlock(&st->lock); |
|---|
| 225 | 228 | |
|---|
| 226 | 229 | return ret; |
|---|
| 227 | 230 | } |
|---|
| .. | .. |
|---|
| 247 | 250 | struct ad5755_state *st = iio_priv(indio_dev); |
|---|
| 248 | 251 | unsigned int mask = BIT(channel); |
|---|
| 249 | 252 | |
|---|
| 250 | | - mutex_lock(&indio_dev->mlock); |
|---|
| 253 | + mutex_lock(&st->lock); |
|---|
| 251 | 254 | |
|---|
| 252 | 255 | if ((bool)(st->pwr_down & mask) == pwr_down) |
|---|
| 253 | 256 | goto out_unlock; |
|---|
| .. | .. |
|---|
| 267 | 270 | } |
|---|
| 268 | 271 | |
|---|
| 269 | 272 | out_unlock: |
|---|
| 270 | | - mutex_unlock(&indio_dev->mlock); |
|---|
| 273 | + mutex_unlock(&st->lock); |
|---|
| 271 | 274 | |
|---|
| 272 | 275 | return 0; |
|---|
| 273 | 276 | } |
|---|
| .. | .. |
|---|
| 632 | 635 | } |
|---|
| 633 | 636 | } |
|---|
| 634 | 637 | |
|---|
| 635 | | - if (i == ARRAY_SIZE(ad5755_dcdc_freq_table)) { |
|---|
| 638 | + if (i == ARRAY_SIZE(ad5755_dcdc_freq_table)) |
|---|
| 636 | 639 | dev_err(dev, |
|---|
| 637 | | - "adi,dc-dc-freq out of range selecting 410kHz"); |
|---|
| 638 | | - } |
|---|
| 640 | + "adi,dc-dc-freq out of range selecting 410kHz\n"); |
|---|
| 639 | 641 | } |
|---|
| 640 | 642 | |
|---|
| 641 | 643 | pdata->dc_dc_maxv = AD5755_DC_DC_MAXV_23V; |
|---|
| .. | .. |
|---|
| 646 | 648 | break; |
|---|
| 647 | 649 | } |
|---|
| 648 | 650 | } |
|---|
| 649 | | - if (i == ARRAY_SIZE(ad5755_dcdc_maxv_table)) { |
|---|
| 651 | + if (i == ARRAY_SIZE(ad5755_dcdc_maxv_table)) |
|---|
| 650 | 652 | dev_err(dev, |
|---|
| 651 | | - "adi,dc-dc-maxv out of range selecting 23V"); |
|---|
| 652 | | - } |
|---|
| 653 | + "adi,dc-dc-maxv out of range selecting 23V\n"); |
|---|
| 653 | 654 | } |
|---|
| 654 | 655 | |
|---|
| 655 | 656 | devnr = 0; |
|---|
| 656 | 657 | for_each_child_of_node(np, pp) { |
|---|
| 657 | 658 | if (devnr >= AD5755_NUM_CHANNELS) { |
|---|
| 658 | 659 | dev_err(dev, |
|---|
| 659 | | - "There is to many channels defined in DT\n"); |
|---|
| 660 | + "There are too many channels defined in DT\n"); |
|---|
| 660 | 661 | goto error_out; |
|---|
| 661 | 662 | } |
|---|
| 662 | 663 | |
|---|
| .. | .. |
|---|
| 682 | 683 | break; |
|---|
| 683 | 684 | } |
|---|
| 684 | 685 | } |
|---|
| 685 | | - if (i == ARRAY_SIZE(ad5755_slew_rate_table)) { |
|---|
| 686 | + if (i == ARRAY_SIZE(ad5755_slew_rate_table)) |
|---|
| 686 | 687 | dev_err(dev, |
|---|
| 687 | | - "channel %d slew rate out of range selecting 64kHz", |
|---|
| 688 | + "channel %d slew rate out of range selecting 64kHz\n", |
|---|
| 688 | 689 | devnr); |
|---|
| 689 | | - } |
|---|
| 690 | 690 | |
|---|
| 691 | 691 | pdata->dac[devnr].slew.step_size = AD5755_SLEW_STEP_SIZE_1; |
|---|
| 692 | 692 | for (i = 0; i < ARRAY_SIZE(ad5755_slew_step_table); i++) { |
|---|
| .. | .. |
|---|
| 696 | 696 | break; |
|---|
| 697 | 697 | } |
|---|
| 698 | 698 | } |
|---|
| 699 | | - if (i == ARRAY_SIZE(ad5755_slew_step_table)) { |
|---|
| 699 | + if (i == ARRAY_SIZE(ad5755_slew_step_table)) |
|---|
| 700 | 700 | dev_err(dev, |
|---|
| 701 | | - "channel %d slew step size out of range selecting 1 LSB", |
|---|
| 701 | + "channel %d slew step size out of range selecting 1 LSB\n", |
|---|
| 702 | 702 | devnr); |
|---|
| 703 | | - } |
|---|
| 704 | 703 | } else { |
|---|
| 705 | 704 | pdata->dac[devnr].slew.enable = false; |
|---|
| 706 | 705 | pdata->dac[devnr].slew.rate = AD5755_SLEW_RATE_64k; |
|---|
| .. | .. |
|---|
| 745 | 744 | st->spi = spi; |
|---|
| 746 | 745 | st->pwr_down = 0xf; |
|---|
| 747 | 746 | |
|---|
| 748 | | - indio_dev->dev.parent = &spi->dev; |
|---|
| 749 | 747 | indio_dev->name = spi_get_device_id(spi)->name; |
|---|
| 750 | 748 | indio_dev->info = &ad5755_info; |
|---|
| 751 | 749 | indio_dev->modes = INDIO_DIRECT_MODE; |
|---|
| 752 | 750 | indio_dev->num_channels = AD5755_NUM_CHANNELS; |
|---|
| 753 | 751 | |
|---|
| 752 | + mutex_init(&st->lock); |
|---|
| 753 | + |
|---|
| 754 | 754 | if (spi->dev.of_node) |
|---|
| 755 | 755 | pdata = ad5755_parse_dt(&spi->dev); |
|---|
| 756 | 756 | else |
|---|