From: Angelo Dureghello <adureghello@xxxxxxxxxxxx> The ad354xr requires DSPI mode to work in buffering mode, so backend needs to allow a mode selection between: SPI (entire ad35xxr family), DSPI (ad354xr), QSPI (ad355xr). Signed-off-by: Angelo Dureghello <adureghello@xxxxxxxxxxxx> --- drivers/iio/dac/adi-axi-dac.c | 46 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c index d02eb535b648..f7d22409e9b3 100644 --- a/drivers/iio/dac/adi-axi-dac.c +++ b/drivers/iio/dac/adi-axi-dac.c @@ -64,7 +64,7 @@ #define AXI_DAC_UI_STATUS_IF_BUSY BIT(4) #define AXI_DAC_CUSTOM_CTRL_REG 0x008C #define AXI_DAC_CUSTOM_CTRL_ADDRESS GENMASK(31, 24) -#define AXI_DAC_CUSTOM_CTRL_SYNCED_TRANSFER BIT(2) +#define AXI_DAC_CUSTOM_CTRL_MULTI_IO_MODE GENMASK(3, 2) #define AXI_DAC_CUSTOM_CTRL_STREAM BIT(1) #define AXI_DAC_CUSTOM_CTRL_TRANSFER_DATA BIT(0) @@ -95,6 +95,12 @@ enum { AXI_DAC_DATA_INTERNAL_RAMP_16BIT = 11, }; +enum multi_io_mode { + AXI_DAC_MULTI_IO_MODE_SPI, + AXI_DAC_MULTI_IO_MODE_DSPI, + AXI_DAC_MULTI_IO_MODE_QSPI, +}; + struct axi_dac_info { unsigned int version; const struct iio_backend_info *backend_info; @@ -725,6 +731,43 @@ static int axi_dac_bus_reg_read(struct iio_backend *back, u32 reg, u32 *val, return regmap_read(st->regmap, AXI_DAC_CUSTOM_RD_REG, val); } +static int axi_dac_interface_type_set(struct iio_backend *back, + enum iio_backend_interface_type type) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + int mode, ival, ret; + + switch (type) { + case IIO_BACKEND_INTERFACE_SERIAL_SPI: + mode = AXI_DAC_MULTI_IO_MODE_SPI; + break; + case IIO_BACKEND_INTERFACE_SERIAL_DSPI: + mode = AXI_DAC_MULTI_IO_MODE_DSPI; + break; + case IIO_BACKEND_INTERFACE_SERIAL_QSPI: + mode = AXI_DAC_MULTI_IO_MODE_QSPI; + break; + default: + return -EINVAL; + } + + ret = regmap_update_bits(st->regmap, AXI_DAC_CUSTOM_CTRL_REG, + AXI_DAC_CUSTOM_CTRL_MULTI_IO_MODE, + FIELD_PREP(AXI_DAC_CUSTOM_CTRL_MULTI_IO_MODE, mode)); + if (ret) + return ret; + + ret = regmap_read_poll_timeout(st->regmap, + AXI_DAC_UI_STATUS_REG, ival, + FIELD_GET(AXI_DAC_UI_STATUS_IF_BUSY, ival) == 0, + 10, 100 * KILO); + + if (ret == -ETIMEDOUT) + dev_err(st->dev, "AXI read timeout\n"); + + return ret; +} + static void axi_dac_child_remove(void *data) { platform_device_unregister(data); @@ -774,6 +817,7 @@ static const struct iio_backend_ops axi_ad3552r_ops = { .request_buffer = axi_dac_request_buffer, .free_buffer = axi_dac_free_buffer, .data_source_set = axi_dac_data_source_set, + .interface_type_set = axi_dac_interface_type_set, .ddr_enable = axi_dac_ddr_enable, .ddr_disable = axi_dac_ddr_disable, .data_stream_enable = axi_dac_data_stream_enable, -- 2.47.0