The SPI transfers for AD4020, AD4021, and AD4022 have slightly different
timing specifications. Use device specific timing constraints to set SPI
transfer parameters.
Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
---
drivers/iio/adc/ad4000.c | 50 ++++++++++++++++++++++++++++++++--------
1 file changed, 41 insertions(+), 9 deletions(-)
diff --git a/drivers/iio/adc/ad4000.c b/drivers/iio/adc/ad4000.c
index 21731c4d31ee..68ac77494263 100644
--- a/drivers/iio/adc/ad4000.c
+++ b/drivers/iio/adc/ad4000.c
@@ -35,10 +35,6 @@
#define AD4000_SCALE_OPTIONS 2
-#define AD4000_TQUIET1_NS 190
-#define AD4000_TQUIET2_NS 60
-#define AD4000_TCONV_NS 320
-
#define __AD4000_DIFF_CHANNEL(_sign, _real_bits, _storage_bits, _reg_access) \
{ \
.type = IIO_VOLTAGE, \
@@ -122,10 +118,30 @@ static const int ad4000_gains[] = {
454, 909, 1000, 1900,
};
+struct ad4000_time_spec {
+ int t_conv_ns;
+ int t_quiet2_ns;
+};
+
+/*
+ * Same timing specifications for all of AD4000, AD4001, ..., AD4008, AD4010,
+ * ADAQ4001, and ADAQ4003.
+ */
+static const struct ad4000_time_spec ad4000_t_spec = {
+ .t_conv_ns = 320,
+ .t_quiet2_ns = 60,
+};
+
+static const struct ad4000_time_spec ad4020_t_spec = {
+ .t_conv_ns = 350,
+ .t_quiet2_ns = 60,
+};
+
struct ad4000_chip_info {
const char *dev_name;
struct iio_chan_spec chan_spec[2];
struct iio_chan_spec reg_access_chan_spec[2];
+ const struct ad4000_time_spec *time_spec;
bool has_hardware_gain;
};
@@ -133,90 +149,105 @@ static const struct ad4000_chip_info ad4000_chip_info = {
.dev_name = "ad4000",
.chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 16, 0),
.reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 16, 1),
+ .time_spec = &ad4000_t_spec,
};
static const struct ad4000_chip_info ad4001_chip_info = {
.dev_name = "ad4001",
.chan_spec = AD4000_DIFF_CHANNELS('s', 16, 0),
.reg_access_chan_spec = AD4000_DIFF_CHANNELS('s', 16, 1),
+ .time_spec = &ad4000_t_spec,
};
static const struct ad4000_chip_info ad4002_chip_info = {
.dev_name = "ad4002",
.chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 18, 0),
.reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 18, 1),
+ .time_spec = &ad4000_t_spec,
};
static const struct ad4000_chip_info ad4003_chip_info = {
.dev_name = "ad4003",
.chan_spec = AD4000_DIFF_CHANNELS('s', 18, 0),
.reg_access_chan_spec = AD4000_DIFF_CHANNELS('s', 18, 1),
+ .time_spec = &ad4000_t_spec,
};
static const struct ad4000_chip_info ad4004_chip_info = {
.dev_name = "ad4004",
.chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 16, 0),
.reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 16, 1),
+ .time_spec = &ad4000_t_spec,
};
static const struct ad4000_chip_info ad4005_chip_info = {
.dev_name = "ad4005",
.chan_spec = AD4000_DIFF_CHANNELS('s', 16, 0),
.reg_access_chan_spec = AD4000_DIFF_CHANNELS('s', 16, 1),
+ .time_spec = &ad4000_t_spec,
};
static const struct ad4000_chip_info ad4006_chip_info = {
.dev_name = "ad4006",
.chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 18, 0),
.reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 18, 1),
+ .time_spec = &ad4000_t_spec,
};
static const struct ad4000_chip_info ad4007_chip_info = {
.dev_name = "ad4007",
.chan_spec = AD4000_DIFF_CHANNELS('s', 18, 0),
.reg_access_chan_spec = AD4000_DIFF_CHANNELS('s', 18, 1),
+ .time_spec = &ad4000_t_spec,
};
static const struct ad4000_chip_info ad4008_chip_info = {
.dev_name = "ad4008",
.chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 16, 0),
.reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 16, 1),
+ .time_spec = &ad4000_t_spec,
};
static const struct ad4000_chip_info ad4010_chip_info = {
.dev_name = "ad4010",
.chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 18, 0),
.reg_access_chan_spec = AD4000_PSEUDO_DIFF_CHANNELS('u', 18, 1),
+ .time_spec = &ad4000_t_spec,
};
static const struct ad4000_chip_info ad4011_chip_info = {
.dev_name = "ad4011",
.chan_spec = AD4000_DIFF_CHANNELS('s', 18, 0),
.reg_access_chan_spec = AD4000_DIFF_CHANNELS('s', 18, 1),
+ .time_spec = &ad4000_t_spec,
};
static const struct ad4000_chip_info ad4020_chip_info = {
.dev_name = "ad4020",
.chan_spec = AD4000_DIFF_CHANNELS('s', 20, 0),
.reg_access_chan_spec = AD4000_DIFF_CHANNELS('s', 20, 1),
+ .time_spec = &ad4020_t_spec,
};
static const struct ad4000_chip_info ad4021_chip_info = {
.dev_name = "ad4021",
.chan_spec = AD4000_DIFF_CHANNELS('s', 20, 0),
.reg_access_chan_spec = AD4000_DIFF_CHANNELS('s', 20, 1),
+ .time_spec = &ad4020_t_spec,
};
static const struct ad4000_chip_info ad4022_chip_info = {
.dev_name = "ad4022",
.chan_spec = AD4000_DIFF_CHANNELS('s', 20, 0),
.reg_access_chan_spec = AD4000_DIFF_CHANNELS('s', 20, 1),
+ .time_spec = &ad4020_t_spec,
};
static const struct ad4000_chip_info adaq4001_chip_info = {
.dev_name = "adaq4001",
.chan_spec = AD4000_DIFF_CHANNELS('s', 16, 0),
.reg_access_chan_spec = AD4000_DIFF_CHANNELS('s', 16, 1),
+ .time_spec = &ad4000_t_spec,
.has_hardware_gain = true,
};
@@ -224,6 +255,7 @@ static const struct ad4000_chip_info adaq4003_chip_info = {
.dev_name = "adaq4003",
.chan_spec = AD4000_DIFF_CHANNELS('s', 18, 0),
.reg_access_chan_spec = AD4000_DIFF_CHANNELS('s', 18, 1),
+ .time_spec = &ad4000_t_spec,
.has_hardware_gain = true,
};
@@ -238,6 +270,7 @@ struct ad4000_state {
bool span_comp;
u16 gain_milli;
int scale_tbl[AD4000_SCALE_OPTIONS][2];
+ const struct ad4000_time_spec *time_spec;
/*
* DMA (thus cache coherency maintenance) requires the transfer buffers
@@ -502,16 +535,15 @@ static const struct iio_info ad4000_info = {
static int ad4000_prepare_3wire_mode_message(struct ad4000_state *st,
const struct iio_chan_spec *chan)
{
- unsigned int cnv_pulse_time = AD4000_TCONV_NS;
struct spi_transfer *xfers = st->xfers;
xfers[0].cs_change = 1;
- xfers[0].cs_change_delay.value = cnv_pulse_time;
+ xfers[0].cs_change_delay.value = st->time_spec->t_conv_ns;
xfers[0].cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
xfers[1].rx_buf = &st->scan.data;
xfers[1].len = BITS_TO_BYTES(chan->scan_type.storagebits);
- xfers[1].delay.value = AD4000_TQUIET2_NS;
+ xfers[1].delay.value = st->time_spec->t_quiet2_ns;
xfers[1].delay.unit = SPI_DELAY_UNIT_NSECS;
spi_message_init_with_transfers(&st->msg, st->xfers, 2);
@@ -529,7 +561,6 @@ static int ad4000_prepare_3wire_mode_message(struct ad4000_state *st,
static int ad4000_prepare_4wire_mode_message(struct ad4000_state *st,
const struct iio_chan_spec *chan)
{
- unsigned int cnv_to_sdi_time = AD4000_TCONV_NS;
struct spi_transfer *xfers = st->xfers;
/*
@@ -537,7 +568,7 @@ static int ad4000_prepare_4wire_mode_message(struct ad4000_state *st,
* going low.
*/
xfers[0].cs_off = 1;
- xfers[0].delay.value = cnv_to_sdi_time;
+ xfers[0].delay.value = st->time_spec->t_conv_ns;
xfers[0].delay.unit = SPI_DELAY_UNIT_NSECS;
xfers[1].rx_buf = &st->scan.data;
@@ -576,6 +607,7 @@ static int ad4000_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
st->spi = spi;
+ st->time_spec = chip->time_spec;
ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(ad4000_power_supplies),
ad4000_power_supplies);
--
2.45.2
On 11/14/24 5:51 PM, Marcelo Schmitt wrote: > The SPI transfers for AD4020, AD4021, and AD4022 have slightly different > timing specifications. Use device specific timing constraints to set SPI > transfer parameters. > > Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com> > --- > drivers/iio/adc/ad4000.c | 50 ++++++++++++++++++++++++++++++++-------- > 1 file changed, 41 insertions(+), 9 deletions(-) > > diff --git a/drivers/iio/adc/ad4000.c b/drivers/iio/adc/ad4000.c > index 21731c4d31ee..68ac77494263 100644 > --- a/drivers/iio/adc/ad4000.c > +++ b/drivers/iio/adc/ad4000.c > @@ -35,10 +35,6 @@ > > #define AD4000_SCALE_OPTIONS 2 > > -#define AD4000_TQUIET1_NS 190 > -#define AD4000_TQUIET2_NS 60 > -#define AD4000_TCONV_NS 320 We are removing 3 but only adding 2 in the struct below? If one of these was unused, best to mention it in the commit message. > - > #define __AD4000_DIFF_CHANNEL(_sign, _real_bits, _storage_bits, _reg_access) \ > { \ > .type = IIO_VOLTAGE, \ > @@ -122,10 +118,30 @@ static const int ad4000_gains[] = { > 454, 909, 1000, 1900, > }; > > +struct ad4000_time_spec { > + int t_conv_ns; > + int t_quiet2_ns; > +}; > + > +/* > + * Same timing specifications for all of AD4000, AD4001, ..., AD4008, AD4010, > + * ADAQ4001, and ADAQ4003. > + */ > +static const struct ad4000_time_spec ad4000_t_spec = { > + .t_conv_ns = 320, > + .t_quiet2_ns = 60, > +}; > + > +static const struct ad4000_time_spec ad4020_t_spec = { > + .t_conv_ns = 350, > + .t_quiet2_ns = 60, > +}; t_quiet2_ns is the same in both cases, so do we actually need to add it here instead of using a common macro? Or if it is for future differences, mention that in the commit message.
On 11/15, David Lechner wrote: > On 11/14/24 5:51 PM, Marcelo Schmitt wrote: > > The SPI transfers for AD4020, AD4021, and AD4022 have slightly different > > timing specifications. Use device specific timing constraints to set SPI > > transfer parameters. > > > > Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com> > > --- > > drivers/iio/adc/ad4000.c | 50 ++++++++++++++++++++++++++++++++-------- > > 1 file changed, 41 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/iio/adc/ad4000.c b/drivers/iio/adc/ad4000.c > > index 21731c4d31ee..68ac77494263 100644 > > --- a/drivers/iio/adc/ad4000.c > > +++ b/drivers/iio/adc/ad4000.c > > @@ -35,10 +35,6 @@ > > > > #define AD4000_SCALE_OPTIONS 2 > > > > -#define AD4000_TQUIET1_NS 190 > > -#define AD4000_TQUIET2_NS 60 > > -#define AD4000_TCONV_NS 320 > > We are removing 3 but only adding 2 in the struct below? > > If one of these was unused, best to mention it in the commit message. One of them was unused (AD4000_TQUIET1_NS IRCC). Sure, will add a comment about it in the commit body. > > > - > > #define __AD4000_DIFF_CHANNEL(_sign, _real_bits, _storage_bits, _reg_access) \ > > { \ > > .type = IIO_VOLTAGE, \ > > @@ -122,10 +118,30 @@ static const int ad4000_gains[] = { > > 454, 909, 1000, 1900, > > }; > > > > +struct ad4000_time_spec { > > + int t_conv_ns; > > + int t_quiet2_ns; > > +}; > > + > > +/* > > + * Same timing specifications for all of AD4000, AD4001, ..., AD4008, AD4010, > > + * ADAQ4001, and ADAQ4003. > > + */ > > +static const struct ad4000_time_spec ad4000_t_spec = { > > + .t_conv_ns = 320, > > + .t_quiet2_ns = 60, > > +}; > > + > > +static const struct ad4000_time_spec ad4020_t_spec = { > > + .t_conv_ns = 350, > > + .t_quiet2_ns = 60, > > +}; > > t_quiet2_ns is the same in both cases, so do we actually need to > add it here instead of using a common macro? Or if it is for future > differences, mention that in the commit message. Okay, will add a macro for setting ad4000_time_spec. My plan is to also add a t_quiet1_ns filed which will be needed for offloading support. t_quiet1_ns will also differ between AD4000 and AD4020.
© 2016 - 2024 Red Hat, Inc.