Skip to content

Commit dddfd0c

Browse files
threexcjic23
authored andcommitted
iio: adc: ad4695: fix buffered read, single sample timings
Modify ad4695_buffer_preenable() by adding an extra SPI transfer after each data read to help ensure that the timing requirement between the last SCLK rising edge and the next CNV rising edge is met. This requires a restructure of the buf_read_xfer array in ad4695_state. Also define AD4695_T_SCK_CNV_DELAY_NS to use for each added transfer. Without this change it is possible for the data to become corrupted on sequential buffered reads due to the device not properly exiting conversion mode. Similarly, make adjustments to ad4695_read_one_sample() so that timings are respected, and clean up the function slightly in the process. Fixes: 6cc7e4b ("iio: adc: ad4695: implement triggered buffer") Co-developed-by: David Lechner <[email protected]> Signed-off-by: David Lechner <[email protected]> Signed-off-by: Trevor Gamblin <[email protected]> Reviewed-by: David Lechner <[email protected]> Tested-by: David Lechner <[email protected]> Link: https://patch.msgid.link/20241113-tgamblin-ad4695_improvements-v2-1-b6bb7c758fc4@baylibre.com Signed-off-by: Jonathan Cameron <[email protected]>
1 parent 65a60a5 commit dddfd0c

File tree

1 file changed

+69
-31
lines changed

1 file changed

+69
-31
lines changed

drivers/iio/adc/ad4695.c

Lines changed: 69 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
#define AD4695_T_WAKEUP_SW_MS 3
9292
#define AD4695_T_REFBUF_MS 100
9393
#define AD4695_T_REGCONFIG_NS 20
94+
#define AD4695_T_SCK_CNV_DELAY_NS 80
9495
#define AD4695_REG_ACCESS_SCLK_HZ (10 * MEGA)
9596

9697
/* Max number of voltage input channels. */
@@ -132,8 +133,13 @@ struct ad4695_state {
132133
unsigned int vref_mv;
133134
/* Common mode input pin voltage. */
134135
unsigned int com_mv;
135-
/* 1 per voltage and temperature chan plus 1 xfer to trigger 1st CNV */
136-
struct spi_transfer buf_read_xfer[AD4695_MAX_CHANNELS + 2];
136+
/*
137+
* 2 per voltage and temperature chan plus 1 xfer to trigger 1st
138+
* CNV. Excluding the trigger xfer, every 2nd xfer only serves
139+
* to control CS and add a delay between the last SCLK and next
140+
* CNV rising edges.
141+
*/
142+
struct spi_transfer buf_read_xfer[AD4695_MAX_CHANNELS * 2 + 3];
137143
struct spi_message buf_read_msg;
138144
/* Raw conversion data received. */
139145
u8 buf[ALIGN((AD4695_MAX_CHANNELS + 2) * AD4695_MAX_CHANNEL_SIZE,
@@ -423,7 +429,7 @@ static int ad4695_buffer_preenable(struct iio_dev *indio_dev)
423429
u8 temp_chan_bit = st->chip_info->num_voltage_inputs;
424430
u32 bit, num_xfer, num_slots;
425431
u32 temp_en = 0;
426-
int ret;
432+
int ret, rx_buf_offset = 0;
427433

428434
/*
429435
* We are using the advanced sequencer since it is the only way to read
@@ -449,11 +455,9 @@ static int ad4695_buffer_preenable(struct iio_dev *indio_dev)
449455
iio_for_each_active_channel(indio_dev, bit) {
450456
xfer = &st->buf_read_xfer[num_xfer];
451457
xfer->bits_per_word = 16;
452-
xfer->rx_buf = &st->buf[(num_xfer - 1) * 2];
458+
xfer->rx_buf = &st->buf[rx_buf_offset];
453459
xfer->len = 2;
454-
xfer->cs_change = 1;
455-
xfer->cs_change_delay.value = AD4695_T_CONVERT_NS;
456-
xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
460+
rx_buf_offset += xfer->len;
457461

458462
if (bit == temp_chan_bit) {
459463
temp_en = 1;
@@ -468,21 +472,44 @@ static int ad4695_buffer_preenable(struct iio_dev *indio_dev)
468472
}
469473

470474
num_xfer++;
475+
476+
/*
477+
* We need to add a blank xfer in data reads, to meet the timing
478+
* requirement of a minimum delay between the last SCLK rising
479+
* edge and the CS deassert.
480+
*/
481+
xfer = &st->buf_read_xfer[num_xfer];
482+
xfer->delay.value = AD4695_T_SCK_CNV_DELAY_NS;
483+
xfer->delay.unit = SPI_DELAY_UNIT_NSECS;
484+
xfer->cs_change = 1;
485+
xfer->cs_change_delay.value = AD4695_T_CONVERT_NS;
486+
xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
487+
488+
num_xfer++;
471489
}
472490

473491
/*
474492
* The advanced sequencer requires that at least 2 slots are enabled.
475493
* Since slot 0 is always used for other purposes, we need only 1
476-
* enabled voltage channel to meet this requirement. If the temperature
477-
* channel is the only enabled channel, we need to add one more slot
478-
* in the sequence but not read from it.
494+
* enabled voltage channel to meet this requirement. If the temperature
495+
* channel is the only enabled channel, we need to add one more slot in
496+
* the sequence but not read from it. This is because the temperature
497+
* sensor is sampled at the end of the channel sequence in advanced
498+
* sequencer mode (see datasheet page 38).
499+
*
500+
* From the iio_for_each_active_channel() block above, we now have an
501+
* xfer with data followed by a blank xfer to allow us to meet the
502+
* timing spec, so move both of those up before adding an extra to
503+
* handle the temperature-only case.
479504
*/
480505
if (num_slots < 2) {
481-
/* move last xfer so we can insert one more xfer before it */
482-
st->buf_read_xfer[num_xfer] = *xfer;
506+
/* Move last two xfers */
507+
st->buf_read_xfer[num_xfer] = st->buf_read_xfer[num_xfer - 1];
508+
st->buf_read_xfer[num_xfer - 1] = st->buf_read_xfer[num_xfer - 2];
483509
num_xfer++;
484510

485-
/* modify 2nd to last xfer for extra slot */
511+
/* Modify inserted xfer for extra slot. */
512+
xfer = &st->buf_read_xfer[num_xfer - 3];
486513
memset(xfer, 0, sizeof(*xfer));
487514
xfer->cs_change = 1;
488515
xfer->delay.value = st->chip_info->t_acq_ns;
@@ -499,6 +526,12 @@ static int ad4695_buffer_preenable(struct iio_dev *indio_dev)
499526
return ret;
500527

501528
num_slots++;
529+
530+
/*
531+
* We still want to point at the last xfer when finished, so
532+
* update the pointer.
533+
*/
534+
xfer = &st->buf_read_xfer[num_xfer - 1];
502535
}
503536

504537
/*
@@ -583,38 +616,43 @@ static irqreturn_t ad4695_trigger_handler(int irq, void *p)
583616
*/
584617
static int ad4695_read_one_sample(struct ad4695_state *st, unsigned int address)
585618
{
586-
struct spi_transfer xfer[2] = { };
587-
int ret, i = 0;
619+
struct spi_transfer xfers[2] = {
620+
{
621+
.speed_hz = AD4695_REG_ACCESS_SCLK_HZ,
622+
.bits_per_word = 16,
623+
.tx_buf = &st->cnv_cmd,
624+
.len = 2,
625+
},
626+
{
627+
/* Required delay between last SCLK and CNV/CS */
628+
.delay.value = AD4695_T_SCK_CNV_DELAY_NS,
629+
.delay.unit = SPI_DELAY_UNIT_NSECS,
630+
}
631+
};
632+
int ret;
588633

589634
ret = ad4695_set_single_cycle_mode(st, address);
590635
if (ret)
591636
return ret;
592637

593638
/*
594639
* Setting the first channel to the temperature channel isn't supported
595-
* in single-cycle mode, so we have to do an extra xfer to read the
596-
* temperature.
640+
* in single-cycle mode, so we have to do an extra conversion to read
641+
* the temperature.
597642
*/
598643
if (address == AD4695_CMD_TEMP_CHAN) {
599-
/* We aren't reading, so we can make this a short xfer. */
600-
st->cnv_cmd2 = AD4695_CMD_TEMP_CHAN << 3;
601-
xfer[0].tx_buf = &st->cnv_cmd2;
602-
xfer[0].len = 1;
603-
xfer[0].cs_change = 1;
604-
xfer[0].cs_change_delay.value = AD4695_T_CONVERT_NS;
605-
xfer[0].cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
606-
607-
i = 1;
644+
st->cnv_cmd = AD4695_CMD_TEMP_CHAN << 11;
645+
646+
ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
647+
if (ret)
648+
return ret;
608649
}
609650

610651
/* Then read the result and exit conversion mode. */
611652
st->cnv_cmd = AD4695_CMD_EXIT_CNV_MODE << 11;
612-
xfer[i].bits_per_word = 16;
613-
xfer[i].tx_buf = &st->cnv_cmd;
614-
xfer[i].rx_buf = &st->raw_data;
615-
xfer[i].len = 2;
653+
xfers[0].rx_buf = &st->raw_data;
616654

617-
return spi_sync_transfer(st->spi, xfer, i + 1);
655+
return spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
618656
}
619657

620658
static int ad4695_read_raw(struct iio_dev *indio_dev,

0 commit comments

Comments
 (0)