Skip to content

Commit dc084de

Browse files
committed
iio: adc: ad7768-1: use new spi-engine implementation
Add support for new spi-engine implementation on ad7768-1 driver, optimizing offload transfers by reducing CS delay and minimizing the number of commands in the offload FIFO. Without the otimization, there's not enough time between the end of a transfer and the start of the next one, reducing the actual sample rate. Adjust 'tx_data' buffer handling in SPI register read and write functions to ensure endianness consistency with the new spi-engine. Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
1 parent 855f0e1 commit dc084de

File tree

1 file changed

+25
-20
lines changed

1 file changed

+25
-20
lines changed

drivers/iio/adc/ad7768-1.c

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include <linux/sysfs.h>
2323
#include "linux/util_macros.h"
2424
#include <linux/spi/spi.h>
25-
#include <linux/spi/spi-engine.h>
25+
#include <linux/spi/spi-engine-ex.h>
2626

2727
#include <linux/iio/buffer.h>
2828
#include <linux/iio/buffer-dma.h>
@@ -289,6 +289,8 @@ struct ad7768_state {
289289
struct mutex lock;
290290
struct clk *mclk;
291291
struct gpio_chip gpiochip;
292+
struct spi_transfer offload_xfer;
293+
struct spi_message offload_msg;
292294
unsigned int gpio_avail_map;
293295
unsigned int mclk_freq;
294296
unsigned int mclk_div;
@@ -329,11 +331,11 @@ static int ad7768_spi_reg_read(struct ad7768_state *st, unsigned int addr,
329331
.len = len + 1,
330332
.bits_per_word = (len == 3 ? 32 : 16),
331333
};
332-
unsigned char tx_data[4];
334+
u32 tx_data;
333335
int ret;
334336

335-
tx_data[0] = AD7768_RD_FLAG_MSK(addr);
336-
xfer.tx_buf = tx_data;
337+
tx_data = AD7768_RD_FLAG_MSK(addr) << (len * 8);
338+
xfer.tx_buf = &tx_data;
337339
ret = spi_sync_transfer(st->spi, &xfer, 1);
338340
if (ret < 0)
339341
return ret;
@@ -351,11 +353,11 @@ static int ad7768_spi_reg_write(struct ad7768_state *st,
351353
.len = 2,
352354
.bits_per_word = 16,
353355
};
354-
unsigned char tx_data[2];
356+
u16 tx_data;
355357

356-
tx_data[0] = AD7768_WR_FLAG_MSK(addr);
357-
tx_data[1] = val & 0xFF;
358-
xfer.tx_buf = tx_data;
358+
tx_data = AD7768_WR_FLAG_MSK(addr) << 8;
359+
tx_data |= val & 0xFF;
360+
xfer.tx_buf = &tx_data;
359361
return spi_sync_transfer(st->spi, &xfer, 1);
360362
}
361363

@@ -1107,18 +1109,14 @@ static int ad7768_buffer_postenable(struct iio_dev *indio_dev)
11071109
{
11081110
struct ad7768_state *st = iio_priv(indio_dev);
11091111
const struct iio_scan_type *scan_type;
1110-
struct spi_transfer xfer = {
1111-
.len = 1,
1112-
};
1113-
unsigned int rx_data[2];
1114-
struct spi_message msg;
11151112
int ret;
11161113

11171114
scan_type = iio_get_current_scan_type(indio_dev, &indio_dev->channels[0]);
11181115
if (IS_ERR(scan_type))
11191116
return PTR_ERR(scan_type);
11201117

1121-
xfer.bits_per_word = scan_type->realbits;
1118+
st->offload_xfer.len = roundup_pow_of_two(BITS_TO_BYTES(scan_type->realbits));
1119+
st->offload_xfer.bits_per_word = scan_type->realbits;
11221120

11231121
/*
11241122
* Write a 1 to the LSB of the INTERFACE_FORMAT register to enter
@@ -1130,14 +1128,20 @@ static int ad7768_buffer_postenable(struct iio_dev *indio_dev)
11301128
return ret;
11311129

11321130
if (st->spi_is_dma_mapped) {
1131+
/* HACK: invalid pointer indicates read data from SPI offload DMA */
1132+
st->offload_xfer.rx_buf = (void *)(-1);
1133+
spi_message_init_with_transfers(&st->offload_msg, &st->offload_xfer, 1);
1134+
1135+
ret = spi_optimize_message(st->spi, &st->offload_msg);
1136+
if (ret < 0)
1137+
return ret;
1138+
11331139
spi_bus_lock(st->spi->master);
11341140

1135-
xfer.rx_buf = rx_data;
1136-
spi_message_init_with_transfers(&msg, &xfer, 1);
1137-
ret = spi_engine_offload_load_msg(st->spi, &msg);
1141+
ret = spi_engine_ex_offload_load_msg(st->spi, &st->offload_msg);
11381142
if (ret < 0)
11391143
return ret;
1140-
spi_engine_offload_enable(st->spi, true);
1144+
spi_engine_ex_offload_enable(st->spi, true);
11411145
}
11421146

11431147
return ret;
@@ -1149,9 +1153,10 @@ static int ad7768_buffer_predisable(struct iio_dev *indio_dev)
11491153
unsigned int regval;
11501154

11511155
if (st->spi_is_dma_mapped) {
1152-
spi_engine_offload_enable(st->spi, false);
1156+
spi_engine_ex_offload_enable(st->spi, false);
11531157
spi_bus_unlock(st->spi->master);
11541158
}
1159+
spi_unoptimize_message(&st->offload_msg);
11551160

11561161
/*
11571162
* To exit continuous read mode, perform a single read of the ADC_DATA
@@ -1285,7 +1290,7 @@ static int ad7768_probe(struct spi_device *spi)
12851290
return PTR_ERR(st->mclk);
12861291

12871292
st->mclk_freq = clk_get_rate(st->mclk);
1288-
st->spi_is_dma_mapped = spi_engine_offload_supported(spi);
1293+
st->spi_is_dma_mapped = spi_engine_ex_offload_supported(spi);
12891294
st->irq = spi->irq;
12901295

12911296
mutex_init(&st->lock);

0 commit comments

Comments
 (0)