diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index bfd908deefc0..ca411371816f 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -77,8 +77,7 @@ #define AD7380_CONFIG1_REFSEL BIT(1) #define AD7380_CONFIG1_PMODE BIT(0) -#define AD7380_CONFIG2_SDO2 GENMASK(9, 8) -#define AD7380_CONFIG2_SDO BIT(8) +#define AD7380_CONFIG2_SDO GENMASK(9, 8) #define AD7380_CONFIG2_RESET GENMASK(7, 0) #define AD7380_CONFIG2_RESET_SOFT 0x3C @@ -92,11 +91,6 @@ #define T_CONVERT_X_NS 500 /* xth conversion start time (oversampling) */ #define T_POWERUP_US 5000 /* Power up */ -/* - * AD738x support several SDO lines to increase throughput, but driver currently - * supports only 1 SDO line (standard SPI transaction) - */ -#define AD7380_NUM_SDO_LINES 1 #define AD7380_DEFAULT_GAIN_MILLI 1000 /* @@ -888,6 +882,8 @@ struct ad7380_state { bool resolution_boost_enabled; unsigned int ch; bool seq; + /* How many SDO lines are wired up. */ + u8 num_sdo_lines; unsigned int vref_mv; unsigned int vcm_mv[MAX_NUM_CHANNELS]; unsigned int gain_milli[MAX_NUM_CHANNELS]; @@ -1084,7 +1080,7 @@ static int ad7380_set_ch(struct ad7380_state *st, unsigned int ch) if (oversampling_ratio > 1) xfer.delay.value = T_CONVERT_0_NS + T_CONVERT_X_NS * (oversampling_ratio - 1) * - st->chip_info->num_simult_channels / AD7380_NUM_SDO_LINES; + st->chip_info->num_simult_channels / st->num_sdo_lines; return spi_sync_transfer(st->spi, &xfer, 1); } @@ -1113,7 +1109,7 @@ static int ad7380_update_xfers(struct ad7380_state *st, if (oversampling_ratio > 1) t_convert = T_CONVERT_0_NS + T_CONVERT_X_NS * (oversampling_ratio - 1) * - st->chip_info->num_simult_channels / AD7380_NUM_SDO_LINES; + st->chip_info->num_simult_channels / st->num_sdo_lines; if (st->seq) { xfer[0].delay.value = xfer[1].delay.value = t_convert; @@ -1198,6 +1194,8 @@ static int ad7380_init_offload_msg(struct ad7380_state *st, xfer->bits_per_word = scan_type->realbits; xfer->offload_flags = SPI_OFFLOAD_XFER_RX_STREAM; xfer->len = AD7380_SPI_BYTES(scan_type) * st->chip_info->num_simult_channels; + if (st->num_sdo_lines > 1) + xfer->multi_lane_mode = SPI_MULTI_LANE_MODE_STRIPE; spi_message_init_with_transfers(&st->offload_msg, xfer, 1); st->offload_msg.offload = st->offload; @@ -1793,6 +1791,7 @@ static const struct iio_info ad7380_info = { static int ad7380_init(struct ad7380_state *st, bool external_ref_en) { + u32 sdo; int ret; /* perform hard reset */ @@ -1815,11 +1814,24 @@ static int ad7380_init(struct ad7380_state *st, bool external_ref_en) st->ch = 0; st->seq = false; - /* SPI 1-wire mode */ + /* SDO field has an irregular mapping. */ + switch (st->num_sdo_lines) { + case 1: + sdo = 1; + break; + case 2: + sdo = 0; + break; + case 4: + sdo = 2; + break; + default: + return -EINVAL; + } + return regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG2, AD7380_CONFIG2_SDO, - FIELD_PREP(AD7380_CONFIG2_SDO, - AD7380_NUM_SDO_LINES)); + FIELD_PREP(AD7380_CONFIG2_SDO, sdo)); } static int ad7380_probe_spi_offload(struct iio_dev *indio_dev, @@ -1842,7 +1854,7 @@ static int ad7380_probe_spi_offload(struct iio_dev *indio_dev, "failed to get offload trigger\n"); sample_rate = st->chip_info->max_conversion_rate_hz * - AD7380_NUM_SDO_LINES / st->chip_info->num_simult_channels; + st->num_sdo_lines / st->chip_info->num_simult_channels; st->sample_freq_range[0] = 1; /* min */ st->sample_freq_range[1] = 1; /* step */ @@ -1887,6 +1899,13 @@ static int ad7380_probe(struct spi_device *spi) if (!st->chip_info) return dev_err_probe(dev, -EINVAL, "missing match data\n"); + st->num_sdo_lines = spi->num_rx_lanes; + + if (st->num_sdo_lines < 1 || st->num_sdo_lines > st->chip_info->num_simult_channels) + return dev_err_probe(dev, -EINVAL, + "invalid number of SDO lines (%d)\n", + st->num_sdo_lines); + ret = devm_regulator_bulk_get_enable(dev, st->chip_info->num_supplies, st->chip_info->supplies); @@ -2010,6 +2029,8 @@ static int ad7380_probe(struct spi_device *spi) st->normal_xfer[0].cs_change_delay.value = st->chip_info->timing_specs->t_csh_ns; st->normal_xfer[0].cs_change_delay.unit = SPI_DELAY_UNIT_NSECS; st->normal_xfer[1].rx_buf = st->scan_data; + if (st->num_sdo_lines > 1) + st->normal_xfer[1].multi_lane_mode = SPI_MULTI_LANE_MODE_STRIPE; spi_message_init_with_transfers(&st->normal_msg, st->normal_xfer, ARRAY_SIZE(st->normal_xfer)); @@ -2031,6 +2052,10 @@ static int ad7380_probe(struct spi_device *spi) st->seq_xfer[2].cs_change = 1; st->seq_xfer[2].cs_change_delay.value = st->chip_info->timing_specs->t_csh_ns; st->seq_xfer[2].cs_change_delay.unit = SPI_DELAY_UNIT_NSECS; + if (st->num_sdo_lines > 1) { + st->seq_xfer[2].multi_lane_mode = SPI_MULTI_LANE_MODE_STRIPE; + st->seq_xfer[3].multi_lane_mode = SPI_MULTI_LANE_MODE_STRIPE; + } spi_message_init_with_transfers(&st->seq_msg, st->seq_xfer, ARRAY_SIZE(st->seq_xfer));