From 8561d0285ddafac8e43b8e07a497609e745d6133 Mon Sep 17 00:00:00 2001 From: Richard Wheatley Date: Thu, 22 Aug 2024 12:43:55 -0500 Subject: [PATCH] drivers: adc: update ambiq adc driver Update Ambiq adc driver to add apollo4 fixed typ of BUMBER to NUMBER Move buffer size prio to configuring slots and enabling the ADC removed #if defined(CONFIG_PM_DEVICE_RUNTIME) Signed-off-by: Richard Wheatley --- drivers/adc/adc_ambiq.c | 87 ++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/drivers/adc/adc_ambiq.c b/drivers/adc/adc_ambiq.c index d7af6ad33fb..34118dc64e5 100644 --- a/drivers/adc/adc_ambiq.c +++ b/drivers/adc/adc_ambiq.c @@ -24,7 +24,7 @@ LOG_MODULE_REGISTER(adc_ambiq, CONFIG_ADC_LOG_LEVEL); typedef int (*ambiq_adc_pwr_func_t)(void); #define PWRCTRL_MAX_WAIT_US 5 /* Number of slots available. */ -#define AMBIQ_ADC_SLOT_BUMBER AM_HAL_ADC_MAX_SLOTS +#define AMBIQ_ADC_SLOT_NUMBER AM_HAL_ADC_MAX_SLOTS struct adc_ambiq_config { uint32_t base; @@ -55,9 +55,11 @@ static int adc_ambiq_set_resolution(am_hal_adc_slot_prec_e *prec, uint8_t adc_re case 12: *prec = AM_HAL_ADC_SLOT_12BIT; break; +#if !defined(CONFIG_SOC_SERIES_APOLLO4X) case 14: *prec = AM_HAL_ADC_SLOT_14BIT; break; +#endif default: return -ENOTSUP; } @@ -81,6 +83,9 @@ static int adc_ambiq_slot_config(const struct device *dev, const struct adc_sequ ADCSlotConfig.eChannel = channel; ADCSlotConfig.bWindowCompare = false; ADCSlotConfig.bEnabled = true; +#if defined(CONFIG_SOC_SERIES_APOLLO4X) + ADCSlotConfig.ui32TrkCyc = AM_HAL_ADC_MIN_TRKCYC; +#endif if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_slot(data->adcHandle, ui32SlotNumber, &ADCSlotConfig)) { LOG_ERR("configuring ADC Slot 0 failed.\n"); @@ -157,9 +162,15 @@ static int adc_ambiq_start_read(const struct device *dev, const struct adc_seque LOG_ERR("No channel selected"); return -EINVAL; } + + error = adc_ambiq_check_buffer_size(sequence, active_channels); + if (error < 0) { + return error; + } + active_channels = POPCOUNT(sequence->channels); - if (active_channels > AMBIQ_ADC_SLOT_BUMBER) { - LOG_ERR("Too many channels for sequencer. Max: %d", AMBIQ_ADC_SLOT_BUMBER); + if (active_channels > AMBIQ_ADC_SLOT_NUMBER) { + LOG_ERR("Too many channels for sequencer. Max: %d", AMBIQ_ADC_SLOT_NUMBER); return -ENOTSUP; } @@ -177,10 +188,6 @@ static int adc_ambiq_start_read(const struct device *dev, const struct adc_seque /* Enable the ADC. */ am_hal_adc_enable(data->adcHandle); - error = adc_ambiq_check_buffer_size(sequence, active_channels); - if (error < 0) { - return error; - } data->active_channels = active_channels; data->buffer = sequence->buffer; /* Start ADC conversion */ @@ -193,25 +200,26 @@ static int adc_ambiq_start_read(const struct device *dev, const struct adc_seque static int adc_ambiq_read(const struct device *dev, const struct adc_sequence *sequence) { struct adc_ambiq_data *data = dev->data; - int error; + int error = 0; -#if defined(CONFIG_PM_DEVICE_RUNTIME) error = pm_device_runtime_get(dev); if (error < 0) { LOG_ERR("pm_device_runtime_get failed: %d", error); } -#endif adc_context_lock(&data->ctx, false, NULL); error = adc_ambiq_start_read(dev, sequence); adc_context_release(&data->ctx, error); -#if defined(CONFIG_PM_DEVICE_RUNTIME) + int ret = error; + error = pm_device_runtime_put(dev); if (error < 0) { LOG_ERR("pm_device_runtime_put failed: %d", error); } -#endif + + error = ret; + return error; } @@ -275,8 +283,7 @@ static int adc_ambiq_init(const struct device *dev) /* Initialize the ADC and get the handle*/ if (AM_HAL_STATUS_SUCCESS != - am_hal_adc_initialize((cfg->base - REG_ADC_BASEADDR) / (cfg->size * 4), - &data->adcHandle)) { + am_hal_adc_initialize((cfg->base - ADC_BASE) / (cfg->size * 4), &data->adcHandle)) { ret = -ENODEV; LOG_ERR("Faile to initialize ADC, code:%d", ret); return ret; @@ -288,10 +295,15 @@ static int adc_ambiq_init(const struct device *dev) /* Set up the ADC configuration parameters. These settings are reasonable * for accurate measurements at a low sample rate. */ +#if !defined(CONFIG_SOC_SERIES_APOLLO4X) ADCConfig.eClock = AM_HAL_ADC_CLKSEL_HFRC; + ADCConfig.eReference = AM_HAL_ADC_REFSEL_INT_1P5; +#else + ADCConfig.eClock = AM_HAL_ADC_CLKSEL_HFRC_24MHZ; + ADCConfig.eRepeatTrigger = AM_HAL_ADC_RPTTRIGSEL_TMR, +#endif ADCConfig.ePolarity = AM_HAL_ADC_TRIGPOL_RISING; ADCConfig.eTrigger = AM_HAL_ADC_TRIGSEL_SOFTWARE; - ADCConfig.eReference = AM_HAL_ADC_REFSEL_INT_1P5; ADCConfig.eClockMode = AM_HAL_ADC_CLKMODE_LOW_POWER; ADCConfig.ePowerMode = AM_HAL_ADC_LPMODE0; ADCConfig.eRepeat = AM_HAL_ADC_SINGLE_SCAN; @@ -315,11 +327,40 @@ static int adc_ambiq_init(const struct device *dev) return 0; } +#ifdef CONFIG_ADC_ASYNC +static int adc_ambiq_read_async(const struct device *dev, const struct adc_sequence *sequence, + struct k_poll_signal *async) +{ + struct adc_ambiq_data *data = dev->data; + int error = 0; + + error = pm_device_runtime_get(dev); + if (error < 0) { + LOG_ERR("pm_device_runtime_get failed: %d", error); + } + + adc_context_lock(&data->ctx, true, async); + error = adc_ambiq_start_read(dev, sequence); + adc_context_release(&data->ctx, error); + + int ret = error; + + error = pm_device_runtime_put(dev); + if (error < 0) { + LOG_ERR("pm_device_runtime_put failed: %d", error); + } + + error = ret; + + return error; +} +#endif + #ifdef CONFIG_PM_DEVICE static int adc_ambiq_pm_action(const struct device *dev, enum pm_device_action action) { struct adc_ambiq_data *data = dev->data; - uint32_t ret; + uint32_t ret = 0; am_hal_sysctrl_power_state_e status; switch (action) { @@ -343,12 +384,22 @@ static int adc_ambiq_pm_action(const struct device *dev, enum pm_device_action a } #endif /* CONFIG_PM_DEVICE */ -#define ADC_AMBIQ_DRIVER_API(n) \ - static const struct adc_driver_api adc_ambiq_driver_api_##n = { \ +#ifdef CONFIG_ADC_ASYNC +#define ADC_AMBIQ_DRIVER_API(n) \ + static const struct adc_driver_api adc_ambiq_driver_api_##n = { \ + .channel_setup = adc_ambiq_channel_setup, \ + .read = adc_ambiq_read, \ + .read_async = adc_ambiq_read_async, \ + .ref_internal = DT_INST_PROP(n, internal_vref_mv), \ + }; +#else +#define ADC_AMBIQ_DRIVER_API(n) \ + static const struct adc_driver_api adc_ambiq_driver_api_##n = { \ .channel_setup = adc_ambiq_channel_setup, \ .read = adc_ambiq_read, \ .ref_internal = DT_INST_PROP(n, internal_vref_mv), \ }; +#endif #define ADC_AMBIQ_INIT(n) \ PINCTRL_DT_INST_DEFINE(n); \