Browse Source

drivers: adc: ad405x: Add diff support and res used form adc spec

Added support for differentail or single ended setup.
Reading resolution form dt - adc spec.

Signed-off-by: Dimitrije Lilic <dimitrije.lilic@orioninc.com>
pull/87592/head
Dimitrije Lilic 3 months ago committed by Benjamin Cabé
parent
commit
c0e5e5236f
  1. 51
      drivers/adc/adc_ad405x.c

51
drivers/adc/adc_ad405x.c

@ -58,6 +58,8 @@ LOG_MODULE_REGISTER(adc_ad405x, CONFIG_ADC_LOG_LEVEL); @@ -58,6 +58,8 @@ LOG_MODULE_REGISTER(adc_ad405x, CONFIG_ADC_LOG_LEVEL);
/** AD405X_REG_AVG_CONFIG Bit Definitions */
#define AD405X_AVG_WIN_LEN_MSK GENMASK(3, 0)
#define AD405X_SINGLE_DIFFERENTIAL_MSK BIT(7)
#define AD405X_WRITE_CMD 0x0U
#define AD405X_READ_CMD 0x80U
@ -68,6 +70,9 @@ LOG_MODULE_REGISTER(adc_ad405x, CONFIG_ADC_LOG_LEVEL); @@ -68,6 +70,9 @@ LOG_MODULE_REGISTER(adc_ad405x, CONFIG_ADC_LOG_LEVEL);
#define AD405X_GP1 0x1U
#define AD405X_GP0 0x0U
#define AD405X_SINGLE_ENDED 0x0U
#define AD405X_DIFFERENTIAL BIT(7)
/** AD405X_REG_TIMER_CONFIG Bit Definitions */
#define AD405X_FS_BURST_AUTO_MSK GENMASK(7, 4)
@ -145,7 +150,7 @@ struct adc_ad405x_config { @@ -145,7 +150,7 @@ struct adc_ad405x_config {
#endif
struct gpio_dt_spec conversion;
uint16_t chip_id;
uint16_t resolution;
const struct adc_dt_spec spec;
};
struct adc_ad405x_data {
@ -419,12 +424,23 @@ int ad405x_init_interrupt(const struct device *dev) @@ -419,12 +424,23 @@ int ad405x_init_interrupt(const struct device *dev)
static int ad405x_channel_setup(const struct device *dev,
const struct adc_channel_cfg *channel_cfg)
{
const struct adc_ad405x_config *cfg = dev->config;
if (channel_cfg->channel_id != 0) {
LOG_ERR("invalid channel id %d", channel_cfg->channel_id);
return -EINVAL;
}
if (channel_cfg->differential != cfg->spec.channel_cfg.differential) {
LOG_ERR("invalid mode %d", channel_cfg->differential);
return -EINVAL;
}
return 0;
uint8_t diff_mode = AD405X_SINGLE_ENDED;
if (channel_cfg->differential) {
diff_mode = AD405X_DIFFERENTIAL;
}
return ad405x_reg_update_bits(dev, AD405X_REG_ADC_MODES,
AD405X_SINGLE_DIFFERENTIAL_MSK, diff_mode);
}
static int adc_ad405x_validate_buffer_size(const struct device *dev,
@ -715,13 +731,13 @@ static int adc_ad405x_start_read(const struct device *dev, const struct adc_sequ @@ -715,13 +731,13 @@ static int adc_ad405x_start_read(const struct device *dev, const struct adc_sequ
int ret;
if (cfg->chip_id == AD4050_CHIP_ID) {
if (sequence->resolution != AD4050_ADC_RESOLUTION) {
if (sequence->resolution != cfg->spec.resolution) {
LOG_ERR("invalid resolution %d", sequence->resolution);
return -EINVAL;
}
}
if (cfg->chip_id == AD4052_CHIP_ID) {
if (sequence->resolution != AD4052_ADC_RESOLUTION) {
if (sequence->resolution != cfg->spec.resolution) {
LOG_ERR("invalid resolution %d", sequence->resolution);
return -EINVAL;
}
@ -858,6 +874,18 @@ static int adc_ad405x_init(const struct device *dev) @@ -858,6 +874,18 @@ static int adc_ad405x_init(const struct device *dev)
return -ENODEV;
}
if (cfg->chip_id == AD4050_CHIP_ID) {
if (cfg->spec.resolution != AD4050_ADC_RESOLUTION) {
LOG_ERR("Invalid resolution %d", cfg->spec.resolution);
return -EINVAL;
}
} else {
if (cfg->spec.resolution != AD4052_ADC_RESOLUTION) {
LOG_ERR("Invalid resolution %d", cfg->spec.resolution);
return -EINVAL;
}
}
#if CONFIG_AD405X_TRIGGER
if (cfg->has_gp1 != 0) {
ad405x_set_gpx_mode(dev, AD405X_GP1, AD405X_DATA_READY);
@ -874,12 +902,14 @@ static int adc_ad405x_init(const struct device *dev) @@ -874,12 +902,14 @@ static int adc_ad405x_init(const struct device *dev)
static DEVICE_API(adc, ad405x_api_funcs) = {
.channel_setup = ad405x_channel_setup,
.read = ad405x_read,
.ref_internal = 2048,
.ref_internal = 2500,
#ifdef CONFIG_ADC_ASYNC
.read_async = ad405x_adc_read_async,
#endif
};
#define AD405X_SPI_CFG SPI_WORD_SET(8) | SPI_TRANSFER_MSB
#define DT_INST_AD405X(inst, t) DT_INST(inst, adi_ad##t##_adc)
#define AD405X_GPIO_PROPS1(n) \
@ -896,16 +926,15 @@ static DEVICE_API(adc, ad405x_api_funcs) = { @@ -896,16 +926,15 @@ static DEVICE_API(adc, ad405x_api_funcs) = {
IF_ENABLED(DT_NODE_HAS_PROP(DT_INST_AD405X(n, t), gp0_gpios), \
(AD405X_GPIO_PROPS0(n)))
#define AD405X_INIT(t, n, res) \
#define AD405X_INIT(t, n) \
static struct adc_ad405x_data ad##t##_data_##n = {}; \
static const struct adc_ad405x_config ad##t##_config_##n = { \
.bus = {.spi = SPI_DT_SPEC_GET(DT_INST_AD405X(n, t), SPI_WORD_SET(8) | \
SPI_TRANSFER_MSB, 0)}, \
.bus = {.spi = SPI_DT_SPEC_GET(DT_INST_AD405X(n, t), AD405X_SPI_CFG, 0)}, \
.conversion = GPIO_DT_SPEC_GET_BY_IDX(DT_INST_AD405X(n, t), conversion_gpios, 0),\
IF_ENABLED(CONFIG_AD405X_TRIGGER, (AD405X_GPIO(t, n))) \
.chip_id = t, \
.active_mode = AD405X_SAMPLE_MODE_OP, \
.resolution = res, \
.spec = ADC_DT_SPEC_STRUCT(DT_INST(n, DT_DRV_COMPAT), 0) \
}; \
DEVICE_DT_DEFINE(DT_INST_AD405X(n, t), adc_ad405x_init, NULL, &ad##t##_data_##n, \
&ad##t##_config_##n, POST_KERNEL, \
@ -914,7 +943,7 @@ static DEVICE_API(adc, ad405x_api_funcs) = { @@ -914,7 +943,7 @@ static DEVICE_API(adc, ad405x_api_funcs) = {
/*
* AD4052: 16 bit
*/
#define AD4052_INIT(n) AD405X_INIT(AD4052_CHIP_ID, n, AD4052_ADC_RESOLUTION)
#define AD4052_INIT(n) AD405X_INIT(AD4052_CHIP_ID, n)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT adi_ad4052_adc
DT_INST_FOREACH_STATUS_OKAY(AD4052_INIT)
@ -922,7 +951,7 @@ DT_INST_FOREACH_STATUS_OKAY(AD4052_INIT) @@ -922,7 +951,7 @@ DT_INST_FOREACH_STATUS_OKAY(AD4052_INIT)
/*
* AD4050: 12 bit
*/
#define AD4050_INIT(n) AD405X_INIT(AD4050_CHIP_ID, n, AD4050_ADC_RESOLUTION)
#define AD4050_INIT(n) AD405X_INIT(AD4050_CHIP_ID, n)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT adi_ad4050_adc
DT_INST_FOREACH_STATUS_OKAY(AD4050_INIT)

Loading…
Cancel
Save