Commit 7a8e7f13 authored by Nuno Sa's avatar Nuno Sa Committed by Jonathan Cameron

iio: adc: ad9467: use DMA safe buffer for spi

Make sure we use a DMA safe buffer (IIO_DMA_MINALIGN) for all the spi
transfers. Only relevant for writes since for reads
spi_write_then_read() is used which does not require DMA safe buffers.

Also note that for consistency, ad9467_spi_read() is also taking struct
ad9467_state as a parameter (even if not really needed).

Fixes: ad679712 ("iio: adc: ad9467: add support AD9467 ADC")
Signed-off-by: default avatarNuno Sa <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20240522-dev-ad9467-dma-v2-1-a37bec463632@analog.comSigned-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent cba37c2e
...@@ -141,9 +141,10 @@ struct ad9467_state { ...@@ -141,9 +141,10 @@ struct ad9467_state {
struct gpio_desc *pwrdown_gpio; struct gpio_desc *pwrdown_gpio;
/* ensure consistent state obtained on multiple related accesses */ /* ensure consistent state obtained on multiple related accesses */
struct mutex lock; struct mutex lock;
u8 buf[3] __aligned(IIO_DMA_MINALIGN);
}; };
static int ad9467_spi_read(struct spi_device *spi, unsigned int reg) static int ad9467_spi_read(struct ad9467_state *st, unsigned int reg)
{ {
unsigned char tbuf[2], rbuf[1]; unsigned char tbuf[2], rbuf[1];
int ret; int ret;
...@@ -151,7 +152,7 @@ static int ad9467_spi_read(struct spi_device *spi, unsigned int reg) ...@@ -151,7 +152,7 @@ static int ad9467_spi_read(struct spi_device *spi, unsigned int reg)
tbuf[0] = 0x80 | (reg >> 8); tbuf[0] = 0x80 | (reg >> 8);
tbuf[1] = reg & 0xFF; tbuf[1] = reg & 0xFF;
ret = spi_write_then_read(spi, ret = spi_write_then_read(st->spi,
tbuf, ARRAY_SIZE(tbuf), tbuf, ARRAY_SIZE(tbuf),
rbuf, ARRAY_SIZE(rbuf)); rbuf, ARRAY_SIZE(rbuf));
...@@ -161,35 +162,32 @@ static int ad9467_spi_read(struct spi_device *spi, unsigned int reg) ...@@ -161,35 +162,32 @@ static int ad9467_spi_read(struct spi_device *spi, unsigned int reg)
return rbuf[0]; return rbuf[0];
} }
static int ad9467_spi_write(struct spi_device *spi, unsigned int reg, static int ad9467_spi_write(struct ad9467_state *st, unsigned int reg,
unsigned int val) unsigned int val)
{ {
unsigned char buf[3]; st->buf[0] = reg >> 8;
st->buf[1] = reg & 0xFF;
st->buf[2] = val;
buf[0] = reg >> 8; return spi_write(st->spi, st->buf, ARRAY_SIZE(st->buf));
buf[1] = reg & 0xFF;
buf[2] = val;
return spi_write(spi, buf, ARRAY_SIZE(buf));
} }
static int ad9467_reg_access(struct iio_dev *indio_dev, unsigned int reg, static int ad9467_reg_access(struct iio_dev *indio_dev, unsigned int reg,
unsigned int writeval, unsigned int *readval) unsigned int writeval, unsigned int *readval)
{ {
struct ad9467_state *st = iio_priv(indio_dev); struct ad9467_state *st = iio_priv(indio_dev);
struct spi_device *spi = st->spi;
int ret; int ret;
if (!readval) { if (!readval) {
guard(mutex)(&st->lock); guard(mutex)(&st->lock);
ret = ad9467_spi_write(spi, reg, writeval); ret = ad9467_spi_write(st, reg, writeval);
if (ret) if (ret)
return ret; return ret;
return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC); AN877_ADC_TRANSFER_SYNC);
} }
ret = ad9467_spi_read(spi, reg); ret = ad9467_spi_read(st, reg);
if (ret < 0) if (ret < 0)
return ret; return ret;
*readval = ret; *readval = ret;
...@@ -295,7 +293,7 @@ static int ad9467_get_scale(struct ad9467_state *st, int *val, int *val2) ...@@ -295,7 +293,7 @@ static int ad9467_get_scale(struct ad9467_state *st, int *val, int *val2)
unsigned int i, vref_val; unsigned int i, vref_val;
int ret; int ret;
ret = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); ret = ad9467_spi_read(st, AN877_ADC_REG_VREF);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -330,31 +328,31 @@ static int ad9467_set_scale(struct ad9467_state *st, int val, int val2) ...@@ -330,31 +328,31 @@ static int ad9467_set_scale(struct ad9467_state *st, int val, int val2)
continue; continue;
guard(mutex)(&st->lock); guard(mutex)(&st->lock);
ret = ad9467_spi_write(st->spi, AN877_ADC_REG_VREF, ret = ad9467_spi_write(st, AN877_ADC_REG_VREF,
info->scale_table[i][1]); info->scale_table[i][1]);
if (ret < 0) if (ret < 0)
return ret; return ret;
return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC); AN877_ADC_TRANSFER_SYNC);
} }
return -EINVAL; return -EINVAL;
} }
static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode) static int ad9467_outputmode_set(struct ad9467_state *st, unsigned int mode)
{ {
int ret; int ret;
ret = ad9467_spi_write(spi, AN877_ADC_REG_OUTPUT_MODE, mode); ret = ad9467_spi_write(st, AN877_ADC_REG_OUTPUT_MODE, mode);
if (ret < 0) if (ret < 0)
return ret; return ret;
return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC); AN877_ADC_TRANSFER_SYNC);
} }
static int ad9647_calibrate_prepare(const struct ad9467_state *st) static int ad9647_calibrate_prepare(struct ad9467_state *st)
{ {
struct iio_backend_data_fmt data = { struct iio_backend_data_fmt data = {
.enable = false, .enable = false,
...@@ -362,17 +360,17 @@ static int ad9647_calibrate_prepare(const struct ad9467_state *st) ...@@ -362,17 +360,17 @@ static int ad9647_calibrate_prepare(const struct ad9467_state *st)
unsigned int c; unsigned int c;
int ret; int ret;
ret = ad9467_spi_write(st->spi, AN877_ADC_REG_TEST_IO, ret = ad9467_spi_write(st, AN877_ADC_REG_TEST_IO,
AN877_ADC_TESTMODE_PN9_SEQ); AN877_ADC_TESTMODE_PN9_SEQ);
if (ret) if (ret)
return ret; return ret;
ret = ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, ret = ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC); AN877_ADC_TRANSFER_SYNC);
if (ret) if (ret)
return ret; return ret;
ret = ad9467_outputmode_set(st->spi, st->info->default_output_mode); ret = ad9467_outputmode_set(st, st->info->default_output_mode);
if (ret) if (ret)
return ret; return ret;
...@@ -390,7 +388,7 @@ static int ad9647_calibrate_prepare(const struct ad9467_state *st) ...@@ -390,7 +388,7 @@ static int ad9647_calibrate_prepare(const struct ad9467_state *st)
return iio_backend_chan_enable(st->back, 0); return iio_backend_chan_enable(st->back, 0);
} }
static int ad9647_calibrate_polarity_set(const struct ad9467_state *st, static int ad9647_calibrate_polarity_set(struct ad9467_state *st,
bool invert) bool invert)
{ {
enum iio_backend_sample_trigger trigger; enum iio_backend_sample_trigger trigger;
...@@ -401,7 +399,7 @@ static int ad9647_calibrate_polarity_set(const struct ad9467_state *st, ...@@ -401,7 +399,7 @@ static int ad9647_calibrate_polarity_set(const struct ad9467_state *st,
if (invert) if (invert)
phase |= AN877_ADC_INVERT_DCO_CLK; phase |= AN877_ADC_INVERT_DCO_CLK;
return ad9467_spi_write(st->spi, AN877_ADC_REG_OUTPUT_PHASE, return ad9467_spi_write(st, AN877_ADC_REG_OUTPUT_PHASE,
phase); phase);
} }
...@@ -437,19 +435,18 @@ static unsigned int ad9467_find_optimal_point(const unsigned long *calib_map, ...@@ -437,19 +435,18 @@ static unsigned int ad9467_find_optimal_point(const unsigned long *calib_map,
return cnt; return cnt;
} }
static int ad9467_calibrate_apply(const struct ad9467_state *st, static int ad9467_calibrate_apply(struct ad9467_state *st, unsigned int val)
unsigned int val)
{ {
unsigned int lane; unsigned int lane;
int ret; int ret;
if (st->info->has_dco) { if (st->info->has_dco) {
ret = ad9467_spi_write(st->spi, AN877_ADC_REG_OUTPUT_DELAY, ret = ad9467_spi_write(st, AN877_ADC_REG_OUTPUT_DELAY,
val); val);
if (ret) if (ret)
return ret; return ret;
return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC); AN877_ADC_TRANSFER_SYNC);
} }
...@@ -462,7 +459,7 @@ static int ad9467_calibrate_apply(const struct ad9467_state *st, ...@@ -462,7 +459,7 @@ static int ad9467_calibrate_apply(const struct ad9467_state *st,
return 0; return 0;
} }
static int ad9647_calibrate_stop(const struct ad9467_state *st) static int ad9647_calibrate_stop(struct ad9467_state *st)
{ {
struct iio_backend_data_fmt data = { struct iio_backend_data_fmt data = {
.sign_extend = true, .sign_extend = true,
...@@ -487,16 +484,16 @@ static int ad9647_calibrate_stop(const struct ad9467_state *st) ...@@ -487,16 +484,16 @@ static int ad9647_calibrate_stop(const struct ad9467_state *st)
} }
mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
ret = ad9467_outputmode_set(st->spi, mode); ret = ad9467_outputmode_set(st, mode);
if (ret) if (ret)
return ret; return ret;
ret = ad9467_spi_write(st->spi, AN877_ADC_REG_TEST_IO, ret = ad9467_spi_write(st, AN877_ADC_REG_TEST_IO,
AN877_ADC_TESTMODE_OFF); AN877_ADC_TESTMODE_OFF);
if (ret) if (ret)
return ret; return ret;
return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER,
AN877_ADC_TRANSFER_SYNC); AN877_ADC_TRANSFER_SYNC);
} }
...@@ -846,7 +843,7 @@ static int ad9467_probe(struct spi_device *spi) ...@@ -846,7 +843,7 @@ static int ad9467_probe(struct spi_device *spi)
if (ret) if (ret)
return ret; return ret;
id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID); id = ad9467_spi_read(st, AN877_ADC_REG_CHIP_ID);
if (id != st->info->id) { if (id != st->info->id) {
dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n", dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n",
id, st->info->id); id, st->info->id);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment