diff options
| author | Lars-Peter Clausen <lars@metafoo.de> | 2013-11-25 07:41:00 -0500 |
|---|---|---|
| committer | Jonathan Cameron <jic23@kernel.org> | 2013-12-03 15:22:25 -0500 |
| commit | 0dbe59c7a78811144cd1860c5bc603eb6b536cfb (patch) | |
| tree | e4c465a207770729df3e11fb8cd76b4c813e59aa /drivers/iio | |
| parent | 61c358e3bc20abeab2ba2ae9625ca723409b6766 (diff) | |
iio:ad5504: Do not store transfer buffers on the stack
Some SPI controllers may not be able to handle transfer buffers that are placed
on the stack.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio')
| -rw-r--r-- | drivers/iio/dac/ad5504.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c index 6cd0dd60c17f..d44c8f5fadee 100644 --- a/drivers/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c | |||
| @@ -47,14 +47,16 @@ | |||
| 47 | * @vref_mv: actual reference voltage used | 47 | * @vref_mv: actual reference voltage used |
| 48 | * @pwr_down_mask power down mask | 48 | * @pwr_down_mask power down mask |
| 49 | * @pwr_down_mode current power down mode | 49 | * @pwr_down_mode current power down mode |
| 50 | * @data: transfer buffer | ||
| 50 | */ | 51 | */ |
| 51 | |||
| 52 | struct ad5504_state { | 52 | struct ad5504_state { |
| 53 | struct spi_device *spi; | 53 | struct spi_device *spi; |
| 54 | struct regulator *reg; | 54 | struct regulator *reg; |
| 55 | unsigned short vref_mv; | 55 | unsigned short vref_mv; |
| 56 | unsigned pwr_down_mask; | 56 | unsigned pwr_down_mask; |
| 57 | unsigned pwr_down_mode; | 57 | unsigned pwr_down_mode; |
| 58 | |||
| 59 | __be16 data[2] ____cacheline_aligned; | ||
| 58 | }; | 60 | }; |
| 59 | 61 | ||
| 60 | /** | 62 | /** |
| @@ -66,31 +68,29 @@ enum ad5504_supported_device_ids { | |||
| 66 | ID_AD5501, | 68 | ID_AD5501, |
| 67 | }; | 69 | }; |
| 68 | 70 | ||
| 69 | static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val) | 71 | static int ad5504_spi_write(struct ad5504_state *st, u8 addr, u16 val) |
| 70 | { | 72 | { |
| 71 | __be16 tmp = cpu_to_be16(AD5504_CMD_WRITE | | 73 | st->data[0] = cpu_to_be16(AD5504_CMD_WRITE | AD5504_ADDR(addr) | |
| 72 | AD5504_ADDR(addr) | | ||
| 73 | (val & AD5504_RES_MASK)); | 74 | (val & AD5504_RES_MASK)); |
| 74 | 75 | ||
| 75 | return spi_write(spi, (u8 *)&tmp, 2); | 76 | return spi_write(st->spi, &st->data[0], 2); |
| 76 | } | 77 | } |
| 77 | 78 | ||
| 78 | static int ad5504_spi_read(struct spi_device *spi, u8 addr) | 79 | static int ad5504_spi_read(struct ad5504_state *st, u8 addr) |
| 79 | { | 80 | { |
| 80 | __be16 tmp = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr)); | ||
| 81 | __be16 val; | ||
| 82 | int ret; | 81 | int ret; |
| 83 | struct spi_transfer t = { | 82 | struct spi_transfer t = { |
| 84 | .tx_buf = &tmp, | 83 | .tx_buf = &st->data[0], |
| 85 | .rx_buf = &val, | 84 | .rx_buf = &st->data[1], |
| 86 | .len = 2, | 85 | .len = 2, |
| 87 | }; | 86 | }; |
| 88 | ret = spi_sync_transfer(spi, &t, 1); | 87 | |
| 89 | 88 | st->data[0] = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr)); | |
| 89 | ret = spi_sync_transfer(st->spi, &t, 1); | ||
| 90 | if (ret < 0) | 90 | if (ret < 0) |
| 91 | return ret; | 91 | return ret; |
| 92 | 92 | ||
| 93 | return be16_to_cpu(val) & AD5504_RES_MASK; | 93 | return be16_to_cpu(st->data[1]) & AD5504_RES_MASK; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | static int ad5504_read_raw(struct iio_dev *indio_dev, | 96 | static int ad5504_read_raw(struct iio_dev *indio_dev, |
| @@ -104,7 +104,7 @@ static int ad5504_read_raw(struct iio_dev *indio_dev, | |||
| 104 | 104 | ||
| 105 | switch (m) { | 105 | switch (m) { |
| 106 | case IIO_CHAN_INFO_RAW: | 106 | case IIO_CHAN_INFO_RAW: |
| 107 | ret = ad5504_spi_read(st->spi, chan->address); | 107 | ret = ad5504_spi_read(st, chan->address); |
| 108 | if (ret < 0) | 108 | if (ret < 0) |
| 109 | return ret; | 109 | return ret; |
| 110 | 110 | ||
| @@ -133,7 +133,7 @@ static int ad5504_write_raw(struct iio_dev *indio_dev, | |||
| 133 | if (val >= (1 << chan->scan_type.realbits) || val < 0) | 133 | if (val >= (1 << chan->scan_type.realbits) || val < 0) |
| 134 | return -EINVAL; | 134 | return -EINVAL; |
| 135 | 135 | ||
| 136 | return ad5504_spi_write(st->spi, chan->address, val); | 136 | return ad5504_spi_write(st, chan->address, val); |
| 137 | default: | 137 | default: |
| 138 | ret = -EINVAL; | 138 | ret = -EINVAL; |
| 139 | } | 139 | } |
| @@ -197,12 +197,12 @@ static ssize_t ad5504_write_dac_powerdown(struct iio_dev *indio_dev, | |||
| 197 | else | 197 | else |
| 198 | st->pwr_down_mask &= ~(1 << chan->channel); | 198 | st->pwr_down_mask &= ~(1 << chan->channel); |
| 199 | 199 | ||
| 200 | ret = ad5504_spi_write(st->spi, AD5504_ADDR_CTRL, | 200 | ret = ad5504_spi_write(st, AD5504_ADDR_CTRL, |
| 201 | AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) | | 201 | AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) | |
| 202 | AD5504_DAC_PWR(st->pwr_down_mask)); | 202 | AD5504_DAC_PWR(st->pwr_down_mask)); |
| 203 | 203 | ||
| 204 | /* writes to the CTRL register must be followed by a NOOP */ | 204 | /* writes to the CTRL register must be followed by a NOOP */ |
| 205 | ad5504_spi_write(st->spi, AD5504_ADDR_NOOP, 0); | 205 | ad5504_spi_write(st, AD5504_ADDR_NOOP, 0); |
| 206 | 206 | ||
| 207 | return ret ? ret : len; | 207 | return ret ? ret : len; |
| 208 | } | 208 | } |
