drivers: adc: adc_ad559x: implement double range option
Optionally write to ad559x register bit which increases ADC input range from 0V to 2 x Vref. Create an ADC API per instance since the double range option and thus `ref_internal` is instance specific. The functionality has been tested via double range DAC and wiring IO1 and IO3: ``` $ dac setup ad5593dac 1 12 $ adc ad5593adc resolution 12 $ adc ad5593adc channel id 3 $ dac write_value ad5593dac 1 0 $ adc ad5593adc read 3 read: 1 $ dac write_value ad5593dac 1 1024 $ adc ad5593adc read 3 read: 1021 $ dac write_value ad5593dac 1 2048 $ adc ad5593adc read 3 read: 2044 $ dac write_value ad5593dac 1 3072 $ adc ad5593adc read 3 read: 3069 $ dac write_value ad5593dac 1 4095 $ adc ad5593adc read 3 read: 4091 ``` Signed-off-by: Jeppe Odgaard <jeppe.odgaard@prevas.dk>
This commit is contained in:
parent
57626655df
commit
c9dc58178a
2 changed files with 33 additions and 7 deletions
|
@ -29,6 +29,7 @@ LOG_MODULE_REGISTER(adc_ad559x, CONFIG_ADC_LOG_LEVEL);
|
|||
|
||||
struct adc_ad559x_config {
|
||||
const struct device *mfd_dev;
|
||||
bool double_input_range;
|
||||
};
|
||||
|
||||
struct adc_ad559x_data {
|
||||
|
@ -240,11 +241,28 @@ static int adc_ad559x_init(const struct device *dev)
|
|||
struct adc_ad559x_data *data = dev->data;
|
||||
k_tid_t tid;
|
||||
int ret;
|
||||
uint16_t reg_val;
|
||||
|
||||
if (!device_is_ready(config->mfd_dev)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = mfd_ad559x_read_reg(config->mfd_dev, AD559X_REG_GEN_CTRL, 0, ®_val);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (config->double_input_range) {
|
||||
reg_val |= AD559X_ADC_RANGE;
|
||||
} else {
|
||||
reg_val &= ~AD559X_ADC_RANGE;
|
||||
}
|
||||
|
||||
ret = mfd_ad559x_write_reg(config->mfd_dev, AD559X_REG_GEN_CTRL, reg_val);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_ad559x_write_reg(config->mfd_dev, AD559X_REG_PD_REF_CTRL, AD559X_EN_REF);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
@ -272,24 +290,31 @@ static int adc_ad559x_init(const struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct adc_driver_api adc_ad559x_api = {
|
||||
.channel_setup = adc_ad559x_channel_setup,
|
||||
.read = adc_ad559x_read,
|
||||
#ifdef CONFIG_ADC_ASYNC
|
||||
.read_async = adc_ad559x_read_async,
|
||||
#define ADC_AD559X_ASYNC() .read_async = adc_ad559x_read_async,
|
||||
#else
|
||||
#define ADC_AD559X_ASYNC()
|
||||
#endif
|
||||
.ref_internal = AD559X_ADC_VREF_MV,
|
||||
};
|
||||
|
||||
#define ADC_AD559X_DRIVER_API(inst) \
|
||||
static const struct adc_driver_api adc_ad559x_api##inst = { \
|
||||
.channel_setup = adc_ad559x_channel_setup, \
|
||||
.read = adc_ad559x_read, \
|
||||
.ref_internal = AD559X_ADC_VREF_MV * (1 + DT_INST_PROP(inst, double_input_range)), \
|
||||
ADC_AD559X_ASYNC()}
|
||||
|
||||
#define ADC_AD559X_DEFINE(inst) \
|
||||
ADC_AD559X_DRIVER_API(inst); \
|
||||
\
|
||||
static const struct adc_ad559x_config adc_ad559x_config##inst = { \
|
||||
.mfd_dev = DEVICE_DT_GET(DT_INST_PARENT(inst)), \
|
||||
.double_input_range = DT_INST_PROP(inst, double_input_range), \
|
||||
}; \
|
||||
\
|
||||
static struct adc_ad559x_data adc_ad559x_data##inst; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, adc_ad559x_init, NULL, &adc_ad559x_data##inst, \
|
||||
&adc_ad559x_config##inst, POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, \
|
||||
&adc_ad559x_api);
|
||||
&adc_ad559x_api##inst);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(ADC_AD559X_DEFINE)
|
||||
|
|
|
@ -25,6 +25,7 @@ extern "C" {
|
|||
#define AD559X_REG_IO_TS_CONFIG 0x0DU
|
||||
|
||||
#define AD559X_DAC_RANGE BIT(4)
|
||||
#define AD559X_ADC_RANGE BIT(5)
|
||||
#define AD559X_EN_REF BIT(9)
|
||||
|
||||
#define AD559X_PIN_MAX 8U
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue