Browse Source

drivers: adc: ad7124: add current sources support

Adds support for configuring the AD7124's excitation current sources.

Signed-off-by: Marco Marche <marco.marche@gmail.com>
pull/92227/head
Marco Marche 1 month ago committed by Benjamin Cabé
parent
commit
f5f90395c9
  1. 1
      drivers/adc/Kconfig.ad7124
  2. 96
      drivers/adc/adc_ad7124.c
  3. 26
      include/zephyr/dt-bindings/adc/ad7124-adc.h

1
drivers/adc/Kconfig.ad7124

@ -8,6 +8,7 @@ config ADC_AD7124 @@ -8,6 +8,7 @@ config ADC_AD7124
select SPI
select CRC
select ADC_CONFIGURABLE_INPUTS
select ADC_CONFIGURABLE_EXCITATION_CURRENT_SOURCE_PIN
help
Enable the ad7124 adc

96
drivers/adc/adc_ad7124.c

@ -56,15 +56,16 @@ LOG_MODULE_REGISTER(adc_ad7124, CONFIG_ADC_LOG_LEVEL); @@ -56,15 +56,16 @@ LOG_MODULE_REGISTER(adc_ad7124, CONFIG_ADC_LOG_LEVEL);
#define ADC_ODR_SEL_BITS_MIN 0x1
/* AD7124 registers */
#define AD7124_STATUS 0x00
#define AD7124_ADC_CONTROL 0x01
#define AD7124_DATA 0x02
#define AD7124_ID 0x05
#define AD7124_ERROR 0x06
#define AD7124_ERROR_EN 0x07
#define AD7124_CHANNEL(x) (0x09 + (x))
#define AD7124_CONFIG(x) (0x19 + (x))
#define AD7124_FILTER(x) (0x21 + (x))
#define AD7124_STATUS 0x00
#define AD7124_ADC_CONTROL 0x01
#define AD7124_DATA 0x02
#define AD7124_IO_CONTROL_1 0x03
#define AD7124_ID 0x05
#define AD7124_ERROR 0x06
#define AD7124_ERROR_EN 0x07
#define AD7124_CHANNEL(x) (0x09 + (x))
#define AD7124_CONFIG(x) (0x19 + (x))
#define AD7124_FILTER(x) (0x21 + (x))
/* Configuration Registers 0-7 bits */
#define AD7124_CFG_REG_BIPOLAR BIT(11)
@ -117,6 +118,21 @@ LOG_MODULE_REGISTER(adc_ad7124, CONFIG_ADC_LOG_LEVEL); @@ -117,6 +118,21 @@ LOG_MODULE_REGISTER(adc_ad7124, CONFIG_ADC_LOG_LEVEL);
#define AD7124_POWER_MODE_MSK GENMASK(7, 6)
#define AD7124_ADC_CTRL_REG_MODE_MSK GENMASK(5, 2)
/* IO Control 1 register bits */
#define AD7124_IOUT1_CURRENT_MSK GENMASK(13, 11)
#define AD7124_IOUT0_CURRENT_MSK GENMASK(10, 8)
#define AD7124_IOUT1_CHANNEL_MSK GENMASK(7, 4)
#define AD7124_IOUT0_CHANNEL_MSK GENMASK(3, 0)
#define AD7124_IOUT_MSK \
(AD7124_IOUT1_CURRENT_MSK | AD7124_IOUT0_CURRENT_MSK | AD7124_IOUT1_CHANNEL_MSK | \
AD7124_IOUT0_CHANNEL_MSK)
/* Current source configuration bits */
#define AD7124_CURRENT_SOURCE_IOUT_MSK BIT(3)
#define AD7124_CURRENT_SOURCE_CURRENT_MSK GENMASK(2, 0)
#define AD7124_CURRENT_SOURCE_MASK \
(AD7124_CURRENT_SOURCE_IOUT_MSK | AD7124_CURRENT_SOURCE_CURRENT_MSK)
/* Error register bits */
#define AD7124_ERR_REG_SPI_IGNORE_ERR BIT(6)
@ -124,6 +140,7 @@ enum ad7124_register_lengths { @@ -124,6 +140,7 @@ enum ad7124_register_lengths {
AD7124_STATUS_REG_LEN = 1,
AD7124_ADC_CONTROL_REG_LEN = 2,
AD7124_DATA_REG_LEN = 3,
AD7124_IO_CONTROL_1_REG_LEN = 2,
AD7124_ID_REG_LEN = 1,
AD7124_ERROR_REG_LEN = 3,
AD7124_ERROR_EN_REG_LEN = 3,
@ -193,6 +210,33 @@ enum ad7124_filter_type { @@ -193,6 +210,33 @@ enum ad7124_filter_type {
AD7124_FILTER_SINC3 = 2U,
};
enum ad7124_iout_current {
AD7124_IOUT_CURRENT_OFF,
AD7124_IOUT_CURRENT_50_UA,
AD7124_IOUT_CURRENT_100_UA,
AD7124_IOUT_CURRENT_250_UA,
AD7124_IOUT_CURRENT_500_UA,
AD7124_IOUT_CURRENT_750_UA,
AD7124_IOUT_CURRENT_1000_UA,
AD7124_IOUT_CURRENT_0_1_UA,
};
enum ad7124_iout_channel {
AD7124_IOUT_AIN0 = 0,
AD7124_IOUT_AIN1 = 1,
AD7124_IOUT_AIN2 = 4,
AD7124_IOUT_AIN3 = 5,
AD7124_IOUT_AIN4 = 10,
AD7124_IOUT_AIN5 = 11,
AD7124_IOUT_AIN6 = 14,
AD7124_IOUT_AIN7 = 15,
};
struct ad7124_current_source_config {
enum ad7124_iout_current current;
enum ad7124_iout_channel channel;
};
struct ad7124_config_props {
enum ad7124_reference_source refsel;
enum ad7124_gain pga_bits;
@ -227,6 +271,7 @@ struct adc_ad7124_data { @@ -227,6 +271,7 @@ struct adc_ad7124_data {
struct adc_context ctx;
struct ad7124_control_status adc_control_status;
struct ad7124_channel_config channel_setup_cfg[AD7124_MAX_CHANNELS];
struct ad7124_current_source_config current_sources[2];
uint8_t setup_cfg_slots;
struct k_sem acquire_signal;
uint16_t channels;
@ -795,6 +840,31 @@ static int adc_ad7124_channel_cfg(const struct device *dev, const struct adc_cha @@ -795,6 +840,31 @@ static int adc_ad7124_channel_cfg(const struct device *dev, const struct adc_cha
return 0;
}
static int adc_ad7124_enable_current_sources(const struct device *dev,
const struct adc_channel_cfg *cfg)
{
struct adc_ad7124_data *data = dev->data;
uint8_t iout_idx;
if (cfg->current_source_pin[0] > AD7124_CURRENT_SOURCE_MASK) {
LOG_ERR("Invalid current source configuration %u", cfg->current_source_pin[0]);
return -EINVAL;
}
iout_idx = FIELD_GET(AD7124_CURRENT_SOURCE_IOUT_MSK, cfg->current_source_pin[0]);
data->current_sources[iout_idx].current = (enum ad7124_iout_current)FIELD_GET(
AD7124_CURRENT_SOURCE_CURRENT_MSK, cfg->current_source_pin[0]);
data->current_sources[iout_idx].channel = cfg->current_source_pin[1];
uint32_t value = FIELD_PREP(AD7124_IOUT0_CURRENT_MSK, data->current_sources[0].current) |
FIELD_PREP(AD7124_IOUT0_CHANNEL_MSK, data->current_sources[0].channel) |
FIELD_PREP(AD7124_IOUT1_CURRENT_MSK, data->current_sources[1].current) |
FIELD_PREP(AD7124_IOUT1_CHANNEL_MSK, data->current_sources[1].channel);
return adc_ad7124_reg_write_msk(dev, AD7124_IO_CONTROL_1, AD7124_IO_CONTROL_1_REG_LEN,
FIELD_PREP(AD7124_IOUT_MSK, value), AD7124_IOUT_MSK);
}
static int adc_ad7124_channel_setup(const struct device *dev, const struct adc_channel_cfg *cfg)
{
struct adc_ad7124_data *data = dev->data;
@ -844,6 +914,14 @@ static int adc_ad7124_channel_setup(const struct device *dev, const struct adc_c @@ -844,6 +914,14 @@ static int adc_ad7124_channel_setup(const struct device *dev, const struct adc_c
return ret;
}
if (cfg->current_source_pin_set) {
ret = adc_ad7124_enable_current_sources(dev, cfg);
if (ret) {
LOG_ERR("Error setting up current sources");
return ret;
}
}
/* Setup the channel */
ret = adc_ad7124_channel_cfg(dev, cfg);
if (ret) {

26
include/zephyr/dt-bindings/adc/ad7124-adc.h

@ -40,4 +40,30 @@ @@ -40,4 +40,30 @@
#define AD7124_ADC_V_20MV_P 28
#define AD7124_ADC_V_20MV_M 29
#define AD7124_IOUT0_OFF 00
#define AD7124_IOUT0_50_UA 01
#define AD7124_IOUT0_100_UA 02
#define AD7124_IOUT0_250_UA 03
#define AD7124_IOUT0_500_UA 04
#define AD7124_IOUT0_750_UA 05
#define AD7124_IOUT0_1000_UA 06
#define AD7124_IOUT0_0_1_UA 07
#define AD7124_IOUT1_OFF 08
#define AD7124_IOUT1_50_UA 09
#define AD7124_IOUT1_100_UA 0A
#define AD7124_IOUT1_250_UA 0B
#define AD7124_IOUT1_500_UA 0C
#define AD7124_IOUT1_750_UA 0D
#define AD7124_IOUT1_1000_UA 0E
#define AD7124_IOUT1_0_1_UA 0F
#define AD7124_IOUT_CH_AIN0 00
#define AD7124_IOUT_CH_AIN1 01
#define AD7124_IOUT_CH_AIN2 04
#define AD7124_IOUT_CH_AIN3 05
#define AD7124_IOUT_CH_AIN4 0A
#define AD7124_IOUT_CH_AIN5 0B
#define AD7124_IOUT_CH_AIN6 0E
#define AD7124_IOUT_CH_AIN7 0F
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_AD7124_ADC_H_ */

Loading…
Cancel
Save