#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
#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
/*
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];
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);
}
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;
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;
static int ad7380_init(struct ad7380_state *st, bool external_ref_en)
{
+ u32 sdo;
int ret;
/* perform hard reset */
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,
"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 */
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);
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));
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));