diff options
Diffstat (limited to 'drivers/iio/addac/ad74413r.c')
-rw-r--r-- | drivers/iio/addac/ad74413r.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c index f32c8c2fb26d..07e9f6ae16a8 100644 --- a/drivers/iio/addac/ad74413r.c +++ b/drivers/iio/addac/ad74413r.c @@ -39,6 +39,7 @@ struct ad74413r_chip_info { struct ad74413r_channel_config { u32 func; + u32 drive_strength; bool gpo_comparator; bool initialized; }; @@ -99,6 +100,7 @@ struct ad74413r_state { #define AD74413R_REG_ADC_CONFIG_X(x) (0x05 + (x)) #define AD74413R_ADC_CONFIG_RANGE_MASK GENMASK(7, 5) #define AD74413R_ADC_CONFIG_REJECTION_MASK GENMASK(4, 3) +#define AD74413R_ADC_CONFIG_CH_200K_TO_GND BIT(2) #define AD74413R_ADC_RANGE_10V 0b000 #define AD74413R_ADC_RANGE_2P5V_EXT_POW 0b001 #define AD74413R_ADC_RANGE_2P5V_INT_POW 0b010 @@ -111,6 +113,7 @@ struct ad74413r_state { #define AD74413R_REG_DIN_CONFIG_X(x) (0x09 + (x)) #define AD74413R_DIN_DEBOUNCE_MASK GENMASK(4, 0) #define AD74413R_DIN_DEBOUNCE_LEN BIT(5) +#define AD74413R_DIN_SINK_MASK GENMASK(9, 6) #define AD74413R_REG_DAC_CODE_X(x) (0x16 + (x)) #define AD74413R_DAC_CODE_MAX GENMASK(12, 0) @@ -261,6 +264,18 @@ static int ad74413r_set_comp_debounce(struct ad74413r_state *st, val); } +static int ad74413r_set_comp_drive_strength(struct ad74413r_state *st, + unsigned int offset, + unsigned int strength) +{ + strength = min(strength, 1800U); + + return regmap_update_bits(st->regmap, AD74413R_REG_DIN_CONFIG_X(offset), + AD74413R_DIN_SINK_MASK, + FIELD_PREP(AD74413R_DIN_SINK_MASK, strength / 120)); +} + + static void ad74413r_gpio_set(struct gpio_chip *chip, unsigned int offset, int val) { @@ -424,9 +439,20 @@ static int ad74413r_set_channel_dac_code(struct ad74413r_state *st, static int ad74413r_set_channel_function(struct ad74413r_state *st, unsigned int channel, u8 func) { - return regmap_update_bits(st->regmap, + int ret; + + ret = regmap_update_bits(st->regmap, AD74413R_REG_CH_FUNC_SETUP_X(channel), AD74413R_CH_FUNC_SETUP_MASK, func); + if (ret) + return ret; + + if (func == CH_FUNC_CURRENT_INPUT_LOOP_POWER) + ret = regmap_set_bits(st->regmap, + AD74413R_REG_ADC_CONFIG_X(channel), + AD74413R_ADC_CONFIG_CH_200K_TO_GND); + + return ret; } static int ad74413r_set_adc_conv_seq(struct ad74413r_state *st, @@ -1112,6 +1138,11 @@ static struct iio_chan_spec ad74413r_current_input_channels[] = { AD74413R_ADC_CURRENT_CHANNEL, }; +static struct iio_chan_spec ad74413r_current_input_loop_channels[] = { + AD74413R_DAC_CHANNEL(IIO_CURRENT, BIT(IIO_CHAN_INFO_SCALE)), + AD74413R_ADC_CURRENT_CHANNEL, +}; + static struct iio_chan_spec ad74413r_resistance_input_channels[] = { AD74413R_ADC_CHANNEL(IIO_RESISTANCE, BIT(IIO_CHAN_INFO_PROCESSED)), }; @@ -1135,7 +1166,7 @@ static const struct ad74413r_channels ad74413r_channels_map[] = { [CH_FUNC_CURRENT_OUTPUT] = AD74413R_CHANNELS(current_output), [CH_FUNC_VOLTAGE_INPUT] = AD74413R_CHANNELS(voltage_input), [CH_FUNC_CURRENT_INPUT_EXT_POWER] = AD74413R_CHANNELS(current_input), - [CH_FUNC_CURRENT_INPUT_LOOP_POWER] = AD74413R_CHANNELS(current_input), + [CH_FUNC_CURRENT_INPUT_LOOP_POWER] = AD74413R_CHANNELS(current_input_loop), [CH_FUNC_RESISTANCE_INPUT] = AD74413R_CHANNELS(resistance_input), [CH_FUNC_DIGITAL_INPUT_LOGIC] = AD74413R_CHANNELS(digital_input), [CH_FUNC_DIGITAL_INPUT_LOOP_POWER] = AD74413R_CHANNELS(digital_input), @@ -1190,6 +1221,9 @@ static int ad74413r_parse_channel_config(struct iio_dev *indio_dev, config->gpo_comparator = fwnode_property_read_bool(channel_node, "adi,gpo-comparator"); + fwnode_property_read_u32(channel_node, "drive-strength-microamp", + &config->drive_strength); + if (!config->gpo_comparator) st->num_gpo_gpios++; @@ -1269,6 +1303,7 @@ static int ad74413r_setup_gpios(struct ad74413r_state *st) unsigned int gpo_gpio_i = 0; unsigned int i; u8 gpo_config; + u32 strength; int ret; for (i = 0; i < AD74413R_CHANNEL_MAX; i++) { @@ -1285,6 +1320,11 @@ static int ad74413r_setup_gpios(struct ad74413r_state *st) config->func == CH_FUNC_DIGITAL_INPUT_LOOP_POWER) st->comp_gpio_offsets[comp_gpio_i++] = i; + strength = config->drive_strength; + ret = ad74413r_set_comp_drive_strength(st, i, strength); + if (ret) + return ret; + ret = ad74413r_set_gpo_config(st, i, gpo_config); if (ret) return ret; |