summaryrefslogtreecommitdiffstats
path: root/drivers/iio/addac/ad74413r.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/addac/ad74413r.c')
-rw-r--r--drivers/iio/addac/ad74413r.c44
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;