Add support for selecting the data format within the AXI ADC ip. Signed-off-by: Antoniu Miclaus <antoniu.miclaus@xxxxxxxxxx> --- changes in v8: - provide inline comments explaning the packet formats as requested in previous review. drivers/iio/adc/adi-axi-adc.c | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index f6475bc93796..9a3968769512 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -45,6 +45,12 @@ #define ADI_AXI_ADC_REG_CTRL 0x0044 #define ADI_AXI_ADC_CTRL_DDR_EDGESEL_MASK BIT(1) +#define ADI_AXI_ADC_REG_CNTRL_3 0x004c +#define AD485X_CNTRL_3_CUSTOM_CTRL_PACKET_FORMAT_MSK GENMASK(1, 0) +#define AD485X_PACKET_FORMAT_20BIT 0x0 +#define AD485X_PACKET_FORMAT_24BIT 0x1 +#define AD485X_PACKET_FORMAT_32BIT 0x2 + #define ADI_AXI_ADC_REG_DRP_STATUS 0x0074 #define ADI_AXI_ADC_DRP_LOCKED BIT(17) @@ -312,6 +318,45 @@ static int axi_adc_interface_type_get(struct iio_backend *back, return 0; } +static int axi_adc_data_size_set(struct iio_backend *back, unsigned int size) +{ + struct adi_axi_adc_state *st = iio_backend_get_priv(back); + unsigned int val; + + switch (size) { + /* + * There are two different variants of the AXI AD485X IP block, a 16-bit + * and a 20-bit variant. + * The 0x0 value (AD485X_PACKET_FORMAT_20BIT) is corresponding also to + * the 16-bit variant of the IP block. + */ + case 16: + case 20: + val = AD485X_PACKET_FORMAT_20BIT; + break; + case 24: + val = AD485X_PACKET_FORMAT_24BIT; + break; + /* + * The 0x2 (AD485X_PACKET_FORMAT_32BIT) corresponds only to the 20-bit + * variant of the IP block. Setting this value properly is ensured by + * the upper layers of the drivers calling the axi-adc functions. + * Also, for 16-bit IP block, the 0x2 (AD485X_PACKET_FORMAT_32BIT) + * value is handled as maximum size available which is 24-bit for this + * configuration. + */ + case 32: + val = AD485X_PACKET_FORMAT_32BIT; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(st->regmap, ADI_AXI_ADC_REG_CNTRL_3, + AD485X_CNTRL_3_CUSTOM_CTRL_PACKET_FORMAT_MSK, + FIELD_PREP(AD485X_CNTRL_3_CUSTOM_CTRL_PACKET_FORMAT_MSK, val)); +} + static struct iio_buffer *axi_adc_request_buffer(struct iio_backend *back, struct iio_dev *indio_dev) { @@ -360,6 +405,7 @@ static const struct iio_backend_ops adi_axi_adc_ops = { .test_pattern_set = axi_adc_test_pattern_set, .chan_status = axi_adc_chan_status, .interface_type_get = axi_adc_interface_type_get, + .data_size_set = axi_adc_data_size_set, .debugfs_reg_access = iio_backend_debugfs_ptr(axi_adc_reg_access), .debugfs_print_chan_status = iio_backend_debugfs_ptr(axi_adc_debugfs_print_chan_status), }; -- 2.47.1