drivers: adc: esp32: enable adc dma on non gdma socs
Enables adc dma on:
- esp32
- esp32-s2
Signed-off-by: Marcio Ribeiro <marcio.ribeiro@espressif.com>
diff --git a/drivers/adc/Kconfig.esp32 b/drivers/adc/Kconfig.esp32
index 8f050c4..a404214 100644
--- a/drivers/adc/Kconfig.esp32
+++ b/drivers/adc/Kconfig.esp32
@@ -13,9 +13,8 @@
config ADC_ESP32_DMA
bool "ESP32 ADC DMA Support"
- depends on DT_HAS_ESPRESSIF_ESP32_GDMA_ENABLED
+ select DMA if DT_HAS_ESPRESSIF_ESP32_GDMA_ENABLED
help
- Enable the ADC DMA mode for ADC instances
- that enable dma channels in their device tree node.
+ Enable the ADC DMA mode
endif
diff --git a/drivers/adc/adc_esp32.c b/drivers/adc/adc_esp32.c
index 7258c22..3bfbcb0 100644
--- a/drivers/adc/adc_esp32.c
+++ b/drivers/adc/adc_esp32.c
@@ -19,12 +19,47 @@
#include <esp_private/adc_share_hw_ctrl.h>
#if defined(CONFIG_ADC_ESP32_DMA)
-#if !SOC_GDMA_SUPPORTED
-#error "SoCs without GDMA peripheral are not supported!"
-#endif
+#if SOC_GDMA_SUPPORTED
#include <zephyr/drivers/dma.h>
#include <zephyr/drivers/dma/dma_esp32.h>
-#endif
+#else
+#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
+
+#if CONFIG_SOC_SERIES_ESP32
+#include <zephyr/dt-bindings/interrupt-controller/esp-xtensa-intmux.h>
+
+#define ADC_DMA_I2S_HOST 0
+#define ADC_DMA_INTR_MASK ADC_HAL_DMA_INTR_MASK
+#define ADC_DMA_DEV I2S_LL_GET_HW(ADC_DMA_I2S_HOST)
+#define ADC_DMA_CHANNEL 0
+#define adc_dma_check_event(dev, mask) (i2s_ll_get_intr_status(dev) & mask)
+#define adc_dma_digi_clr_intr(dev, mask) i2s_ll_clear_intr_status(dev, mask)
+
+#define I2S0_NODE_ID DT_NODELABEL(i2s0)
+#define I2S0_DEV ((const struct device *)DEVICE_DT_GET_OR_NULL(I2S0_NODE_ID))
+#define I2S0_CLK_DEV ((const struct device *)DEVICE_DT_GET(DT_CLOCKS_CTLR(I2S0_NODE_ID)))
+#define I2S0_CLK_SUBSYS ((clock_control_subsys_t)DT_CLOCKS_CELL(I2S0_NODE_ID, offset))
+#endif /* CONFIG_SOC_SERIES_ESP32 */
+
+#if CONFIG_SOC_SERIES_ESP32S2
+#include <zephyr/dt-bindings/interrupt-controller/esp32s2-xtensa-intmux.h>
+
+#define ADC_DMA_SPI_HOST SPI3_HOST
+#define ADC_DMA_INTR_MASK ADC_HAL_DMA_INTR_MASK
+#define ADC_DMA_DEV SPI_LL_GET_HW(ADC_DMA_SPI_HOST)
+#define ADC_DMA_CHANNEL (DT_PROP(DT_NODELABEL(spi3), dma_host) + 1)
+#define adc_dma_check_event(dev, mask) spi_ll_get_intr(dev, mask)
+#define adc_dma_digi_clr_intr(dev, mask) spi_ll_clear_intr(dev, mask)
+
+#define SPI3_NODE_ID DT_NODELABEL(spi3)
+#define SPI3_DEV ((const struct device *)DEVICE_DT_GET_OR_NULL(SPI3_NODE_ID))
+#define SPI3_CLK_DEV ((const struct device *)DEVICE_DT_GET(DT_CLOCKS_CTLR(SPI3_NODE_ID)))
+#define SPI3_CLK_SUBSYS ((clock_control_subsys_t)DT_CLOCKS_CELL(SPI3_NODE_ID, offset))
+#define SPI3_DMA_CLK_SUBSYS ((clock_control_subsys_t)DT_PROP(SPI3_NODE_ID, dma_clk))
+#endif /* CONFIG_SOC_SERIES_ESP32 */
+
+#endif /* SOC_GDMA_SUPPORTED */
+#endif /* defined(CONFIG_ADC_ESP32_DMA) */
#include <zephyr/kernel.h>
#include <zephyr/device.h>
@@ -53,10 +88,10 @@
adc_unit_t unit;
uint8_t channel_count;
const struct device *gpio_port;
-#if defined(CONFIG_ADC_ESP32_DMA)
+#if defined(CONFIG_ADC_ESP32_DMA) && SOC_GDMA_SUPPORTED
const struct device *dma_dev;
uint8_t dma_channel;
-#endif /* defined(CONFIG_ADC_ESP32_DMA) */
+#endif /* defined(CONFIG_ADC_ESP32_DMA) && SOC_GDMA_SUPPORTED */
};
struct adc_esp32_data {
@@ -66,13 +101,32 @@
adc_cali_handle_t cal_handle[SOC_ADC_MAX_CHANNEL_NUM];
uint16_t meas_ref_internal;
uint16_t *buffer;
-#if defined(CONFIG_ADC_ESP32_DMA)
+#ifdef CONFIG_ADC_ESP32_DMA
adc_hal_dma_ctx_t adc_hal_dma_ctx;
uint8_t *dma_buffer;
struct k_sem dma_conv_wait_lock;
-#endif /* defined(CONFIG_ADC_ESP32_DMA) */
+#if !SOC_GDMA_SUPPORTED
+ struct intr_handle_data_t *irq_handle;
+#endif /* !SOC_GDMA_SUPPORTED */
+#endif /* CONFIG_ADC_ESP32_DMA */
};
+static void adc_hw_calibration(adc_unit_t unit)
+{
+#if SOC_ADC_CALIBRATION_V1_SUPPORTED
+ adc_hal_calibration_init(unit);
+ for (int j = 0; j < SOC_ADC_ATTEN_NUM; j++) {
+ adc_calc_hw_calibration_code(unit, j);
+#if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED
+ /* Load the channel compensation from efuse */
+ for (int k = 0; k < SOC_ADC_CHANNEL_NUM(unit); k++) {
+ adc_load_hw_calibration_chan_compens(unit, k, j);
+ }
+#endif /* SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED */
+ }
+#endif /* SOC_ADC_CALIBRATION_V1_SUPPORTED */
+}
+
/* Convert zephyr,gain property to the ESP32 attenuation */
static inline int gain_to_atten(enum adc_gain gain, adc_atten_t *atten)
{
@@ -95,7 +149,7 @@
return 0;
}
-#if !defined(CONFIG_ADC_ESP32_DMA)
+#ifndef CONFIG_ADC_ESP32_DMA
/* Convert voltage by inverted attenuation to support zephyr gain values */
static void atten_to_gain(adc_atten_t atten, uint32_t *val_mv)
@@ -129,25 +183,9 @@
*val_mv = (*val_mv * num) / den;
}
-#endif /* !defined(CONFIG_ADC_ESP32_DMA) */
+#else
-static void adc_hw_calibration(adc_unit_t unit)
-{
-#if SOC_ADC_CALIBRATION_V1_SUPPORTED
- adc_hal_calibration_init(unit);
- for (int j = 0; j < SOC_ADC_ATTEN_NUM; j++) {
- adc_calc_hw_calibration_code(unit, j);
-#if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED
- /* Load the channel compensation from efuse */
- for (int k = 0; k < SOC_ADC_CHANNEL_NUM(unit); k++) {
- adc_load_hw_calibration_chan_compens(unit, k, j);
- }
-#endif /* SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED */
- }
-#endif /* SOC_ADC_CALIBRATION_V1_SUPPORTED */
-}
-
-#if defined(CONFIG_ADC_ESP32_DMA)
+#if SOC_GDMA_SUPPORTED
static void IRAM_ATTR adc_esp32_dma_conv_done(const struct device *dma_dev, void *user_data,
uint32_t channel, int status)
@@ -164,8 +202,8 @@
static int adc_esp32_dma_start(const struct device *dev, uint8_t *buf, size_t len)
{
const struct adc_esp32_conf *conf = dev->config;
-
int err = 0;
+
struct dma_config dma_cfg = {0};
struct dma_status dma_status = {0};
struct dma_block_config dma_blk = {0};
@@ -225,15 +263,38 @@
return err;
}
-static int adc_esp32_fill_digi_pattern(const struct device *dev, const struct adc_sequence *seq,
- void *pattern_config, uint32_t *pattern_len,
- uint32_t *unit_attenuation)
+#else
+
+static IRAM_ATTR void adc_esp32_dma_intr_handler(void *arg)
+{
+ if (arg == NULL) {
+ return;
+ }
+
+ const struct device *dev = arg;
+ struct adc_esp32_data *data = dev->data;
+
+ bool conv_completed = adc_dma_check_event(ADC_DMA_DEV, ADC_DMA_INTR_MASK);
+
+ if (conv_completed) {
+ adc_dma_digi_clr_intr(ADC_DMA_DEV, ADC_DMA_INTR_MASK);
+
+ k_sem_give(&data->dma_conv_wait_lock);
+ }
+}
+
+#endif /* SOC_GDMA_SUPPORTED */
+
+static int adc_esp32_fill_digi_ctrlr_cfg(const struct device *dev, const struct adc_sequence *seq,
+ uint32_t sample_freq_hz,
+ adc_digi_pattern_config_t *pattern_config,
+ adc_hal_digi_ctrlr_cfg_t *adc_hal_digi_ctrlr_cfg,
+ uint32_t *pattern_len, uint32_t *unit_attenuation)
{
const struct adc_esp32_conf *conf = dev->config;
struct adc_esp32_data *data = dev->data;
- adc_digi_pattern_config_t *adc_digi_pattern_config =
- (adc_digi_pattern_config_t *)pattern_config;
+ adc_digi_pattern_config_t *adc_digi_pattern_config = pattern_config;
const uint32_t unit_atten_uninit = 999;
uint32_t channel_mask = 1, channels_copy = seq->channels;
@@ -269,16 +330,35 @@
channel_mask <<= 1;
}
+ soc_module_clk_t clk_src = ADC_DIGI_CLK_SRC_DEFAULT;
+ uint32_t clk_src_freq_hz = 0;
+
+ int err = esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED,
+ &clk_src_freq_hz);
+ if (err != ESP_OK) {
+ return -1;
+ }
+
+ adc_hal_digi_ctrlr_cfg->conv_mode =
+ (conf->unit == ADC_UNIT_1) ? ADC_CONV_SINGLE_UNIT_1 : ADC_CONV_SINGLE_UNIT_2;
+ adc_hal_digi_ctrlr_cfg->clk_src = clk_src;
+ adc_hal_digi_ctrlr_cfg->clk_src_freq_hz = clk_src_freq_hz;
+ adc_hal_digi_ctrlr_cfg->sample_freq_hz = sample_freq_hz;
+ adc_hal_digi_ctrlr_cfg->adc_pattern = pattern_config;
+ adc_hal_digi_ctrlr_cfg->adc_pattern_len = *pattern_len;
+
return 0;
}
-static void adc_esp32_digi_start(const struct device *dev, void *pattern_config,
- uint32_t pattern_len, uint32_t number_of_samplings,
- uint32_t sample_freq_hz, uint32_t unit_attenuation)
+static void adc_esp32_digi_start(const struct device *dev,
+ adc_hal_digi_ctrlr_cfg_t *adc_hal_digi_ctrlr_cfg,
+ uint32_t number_of_adc_samples, uint32_t unit_attenuation)
+
{
const struct adc_esp32_conf *conf = dev->config;
struct adc_esp32_data *data = dev->data;
+ periph_module_reset(PERIPH_SARADC_MODULE);
sar_periph_ctrl_adc_continuous_power_acquire();
adc_lock_acquire(conf->unit);
@@ -294,36 +374,20 @@
}
#endif /* SOC_ADC_ARBITER_SUPPORTED */
- adc_hal_digi_ctrlr_cfg_t adc_hal_digi_ctrlr_cfg;
- soc_module_clk_t clk_src = ADC_DIGI_CLK_SRC_DEFAULT;
- uint32_t clk_src_freq_hz = 0;
-
- esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED,
- &clk_src_freq_hz);
-
- adc_hal_digi_ctrlr_cfg.conv_mode =
- (conf->unit == ADC_UNIT_1) ? ADC_CONV_SINGLE_UNIT_1 : ADC_CONV_SINGLE_UNIT_2;
- adc_hal_digi_ctrlr_cfg.clk_src = clk_src;
- adc_hal_digi_ctrlr_cfg.clk_src_freq_hz = clk_src_freq_hz;
- adc_hal_digi_ctrlr_cfg.sample_freq_hz = sample_freq_hz;
- adc_hal_digi_ctrlr_cfg.adc_pattern = (adc_digi_pattern_config_t *)pattern_config;
- adc_hal_digi_ctrlr_cfg.adc_pattern_len = pattern_len;
-
- uint32_t number_of_adc_digi_samples = number_of_samplings * pattern_len;
-
adc_hal_dma_config_t adc_hal_dma_config = {
- .dev = (void *)GDMA_LL_GET_HW(0),
+#if !SOC_GDMA_SUPPORTED
+ .dev = (void *)ADC_DMA_DEV,
.eof_desc_num = 1,
+ .dma_chan = ADC_DMA_CHANNEL,
.eof_step = 1,
- .dma_chan = conf->dma_channel,
- .eof_num = number_of_adc_digi_samples,
+#endif /* !SOC_GDMA_SUPPORTED */
+ .eof_num = number_of_adc_samples
};
adc_hal_dma_ctx_config(&data->adc_hal_dma_ctx, &adc_hal_dma_config);
-
adc_hal_set_controller(conf->unit, ADC_HAL_CONTINUOUS_READ_MODE);
adc_hal_digi_init(&data->adc_hal_dma_ctx);
- adc_hal_digi_controller_config(&data->adc_hal_dma_ctx, &adc_hal_digi_ctrlr_cfg);
+ adc_hal_digi_controller_config(&data->adc_hal_dma_ctx, adc_hal_digi_ctrlr_cfg);
adc_hal_digi_start(&data->adc_hal_dma_ctx, data->dma_buffer);
}
@@ -335,6 +399,12 @@
adc_hal_digi_dis_intr(&data->adc_hal_dma_ctx, ADC_HAL_DMA_INTR_MASK);
adc_hal_digi_clr_intr(&data->adc_hal_dma_ctx, ADC_HAL_DMA_INTR_MASK);
adc_hal_digi_stop(&data->adc_hal_dma_ctx);
+
+#if ADC_LL_WORKAROUND_CLEAR_EOF_COUNTER
+ periph_module_reset(PERIPH_SARADC_MODULE);
+ adc_ll_digi_dma_clr_eof();
+#endif
+
adc_hal_digi_deinit(&data->adc_hal_dma_ctx);
adc_lock_release(conf->unit);
sar_periph_ctrl_adc_continuous_power_release();
@@ -347,7 +417,11 @@
adc_digi_output_data_t *digi_data = (adc_digi_output_data_t *)dma_buffer;
for (uint32_t k = 0; k < number_of_samples; k++) {
+#if SOC_GDMA_SUPPORTED
*sample++ = (uint16_t)(digi_data++)->type2.data;
+#else
+ *sample++ = (uint16_t)(digi_data++)->type1.data;
+#endif /* SOC_GDMA_SUPPORTED */
}
}
@@ -364,7 +438,7 @@
return err;
}
-#endif /* defined(CONFIG_ADC_ESP32_DMA) */
+#endif /* CONFIG_ADC_ESP32_DMA */
static int adc_esp32_read(const struct device *dev, const struct adc_sequence *seq)
{
@@ -377,12 +451,12 @@
return -ENOMEM;
}
-#if !defined(CONFIG_ADC_ESP32_DMA)
+#ifndef CONFIG_ADC_ESP32_DMA
if (seq->channels > BIT(channel_id)) {
LOG_ERR("Multi-channel readings not supported");
return -ENOTSUP;
}
-#endif /* !defined(CONFIG_ADC_ESP32_DMA) */
+#endif /* CONFIG_ADC_ESP32_DMA */
if (seq->options) {
if (seq->options->extra_samplings) {
@@ -390,12 +464,12 @@
return -ENOTSUP;
}
-#if !defined(CONFIG_ADC_ESP32_DMA)
+#ifndef CONFIG_ADC_ESP32_DMA
if (seq->options->interval_us) {
LOG_ERR("Interval between samplings not supported");
return -ENOTSUP;
}
-#endif /* !defined(CONFIG_ADC_ESP32_DMA) */
+#endif /* CONFIG_ADC_ESP32_DMA */
}
if (!VALID_RESOLUTION(seq->resolution)) {
@@ -411,7 +485,7 @@
data->resolution[channel_id] = seq->resolution;
-#if !defined(CONFIG_ADC_ESP32_DMA)
+#ifndef CONFIG_ADC_ESP32_DMA
uint32_t acq_raw;
@@ -455,27 +529,34 @@
data->buffer = (uint16_t *)seq->buffer;
data->buffer[0] = acq_raw;
-#else /* !defined(CONFIG_ADC_ESP32_DMA) */
+#else /* CONFIG_ADC_ESP32_DMA */
int err = 0;
uint32_t adc_pattern_len, unit_attenuation;
+ adc_hal_digi_ctrlr_cfg_t adc_hal_digi_ctrlr_cfg;
adc_digi_pattern_config_t adc_digi_pattern_config[SOC_ADC_MAX_CHANNEL_NUM];
- err = adc_esp32_fill_digi_pattern(dev, seq, &adc_digi_pattern_config, &adc_pattern_len,
- &unit_attenuation);
- if (err || adc_pattern_len == 0) {
- return -EINVAL;
- }
-
const struct adc_sequence_options *options = seq->options;
uint32_t sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH, number_of_samplings = 1;
+ if (options && options->interval_us) {
+ sample_freq_hz = MHZ(1) / options->interval_us;
+ if (sample_freq_hz < SOC_ADC_SAMPLE_FREQ_THRES_LOW ||
+ sample_freq_hz > SOC_ADC_SAMPLE_FREQ_THRES_HIGH) {
+ LOG_ERR("ADC sampling frequency out of range: %uHz", sample_freq_hz);
+ return -EINVAL;
+ }
+ }
+
+ err = adc_esp32_fill_digi_ctrlr_cfg(dev, seq, sample_freq_hz, adc_digi_pattern_config,
+ &adc_hal_digi_ctrlr_cfg, &adc_pattern_len,
+ &unit_attenuation);
+ if (err || adc_pattern_len == 0) {
+ return -EINVAL;
+ }
+
if (options != NULL) {
number_of_samplings = seq->buffer_size / (adc_pattern_len * sizeof(uint16_t));
-
- if (options->interval_us) {
- sample_freq_hz = MHZ(1) / options->interval_us;
- }
}
if (!number_of_samplings) {
@@ -483,12 +564,6 @@
return -EINVAL;
}
- if (sample_freq_hz < SOC_ADC_SAMPLE_FREQ_THRES_LOW ||
- sample_freq_hz > SOC_ADC_SAMPLE_FREQ_THRES_HIGH) {
- LOG_ERR("ADC sampling frequency out of range: %uHz", sample_freq_hz);
- return -EINVAL;
- }
-
uint32_t number_of_adc_samples = number_of_samplings * adc_pattern_len;
uint32_t number_of_adc_dma_data_bytes =
number_of_adc_samples * SOC_ADC_DIGI_DATA_BYTES_PER_CONV;
@@ -498,29 +573,36 @@
return -EINVAL;
}
+ adc_esp32_digi_start(dev, &adc_hal_digi_ctrlr_cfg, number_of_adc_samples, unit_attenuation);
+
+#if SOC_GDMA_SUPPORTED
err = adc_esp32_dma_start(dev, data->dma_buffer, number_of_adc_dma_data_bytes);
+#else
+ err = esp_intr_enable(data->irq_handle);
+#endif /* SOC_GDMA_SUPPORTED */
if (err) {
return err;
}
- adc_esp32_digi_start(dev, &adc_digi_pattern_config, adc_pattern_len, number_of_samplings,
- sample_freq_hz, unit_attenuation);
-
err = adc_esp32_wait_for_dma_conv_done(dev);
if (err) {
return err;
}
- adc_esp32_digi_stop(dev);
-
+#if SOC_GDMA_SUPPORTED
err = adc_esp32_dma_stop(dev);
+#else
+ err = esp_intr_disable(data->irq_handle);
+#endif /* SOC_GDMA_SUPPORTED */
if (err) {
return err;
}
+ adc_esp32_digi_stop(dev);
+
adc_esp32_fill_seq_buffer(seq->buffer, data->dma_buffer, number_of_adc_samples);
-#endif /* !defined(CONFIG_ADC_ESP32_DMA) */
+#endif /* CONFIG_ADC_ESP32_DMA */
return 0;
}
@@ -541,7 +623,6 @@
{
const struct adc_esp32_conf *conf = (const struct adc_esp32_conf *)dev->config;
struct adc_esp32_data *data = (struct adc_esp32_data *)dev->data;
- adc_atten_t old_atten = data->attenuation[cfg->channel_id];
if (cfg->channel_id >= conf->channel_count) {
LOG_ERR("Unsupported channel id '%d'", cfg->channel_id);
@@ -568,6 +649,9 @@
return -ENOTSUP;
}
+#ifndef CONFIG_ADC_ESP32_DMA
+ adc_atten_t old_atten = data->attenuation[cfg->channel_id];
+
adc_oneshot_hal_chan_cfg_t config = {
.atten = data->attenuation[cfg->channel_id],
.bitwidth = data->resolution[cfg->channel_id],
@@ -621,13 +705,12 @@
&data->cal_handle[cfg->channel_id]);
#endif /* ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED */
}
-
-#if defined(CONFIG_ADC_ESP32_DMA)
+#else
if (!SOC_ADC_DIG_SUPPORTED_UNIT(conf->unit)) {
LOG_ERR("ADC2 dma mode is no longer supported, please use ADC1!");
return -EINVAL;
}
-#endif /* defined(CONFIG_ADC_ESP32_DMA) */
+#endif /* CONFIG_ADC_ESP32_DMA */
/* GPIO config for ADC mode */
@@ -660,7 +743,8 @@
const struct adc_esp32_conf *conf = (struct adc_esp32_conf *)dev->config;
uint32_t clock_src_hz;
-#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
+
+#if SOC_ADC_DIG_CTRL_SUPPORTED && (!SOC_ADC_RTC_CTRL_SUPPORTED || CONFIG_ADC_ESP32_DMA)
if (!device_is_ready(conf->clock_dev)) {
return -ENODEV;
}
@@ -671,6 +755,12 @@
esp_clk_tree_src_get_freq_hz(ADC_DIGI_CLK_SRC_DEFAULT,
ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clock_src_hz);
+ if (!device_is_ready(conf->gpio_port)) {
+ LOG_ERR("gpio0 port not ready");
+ return -ENODEV;
+ }
+
+#ifndef CONFIG_ADC_ESP32_DMA
adc_oneshot_hal_cfg_t config = {
.unit = conf->unit,
.work_mode = ADC_HAL_SINGLE_READ_MODE,
@@ -681,13 +771,7 @@
adc_oneshot_hal_init(&data->hal, &config);
sar_periph_ctrl_adc_oneshot_power_acquire();
-
- if (!device_is_ready(conf->gpio_port)) {
- LOG_ERR("gpio0 port not ready");
- return -ENODEV;
- }
-
-#if defined(CONFIG_ADC_ESP32_DMA)
+#else
if (k_sem_init(&data->dma_conv_wait_lock, 0, 1)) {
LOG_ERR("dma_conv_wait_lock initialization failed!");
@@ -709,7 +793,53 @@
}
LOG_DBG("data->dma_buffer = 0x%08X", (unsigned int)data->dma_buffer);
-#endif /* defined(CONFIG_ADC_ESP32_DMA) */
+#ifdef CONFIG_SOC_SERIES_ESP32
+ const struct device *i2s0_dev = I2S0_DEV;
+
+ if (i2s0_dev != NULL) {
+ LOG_ERR("I2S0 not available for ADC_ESP32_DMA");
+ return -ENODEV;
+ }
+
+ if (!device_is_ready(I2S0_CLK_DEV)) {
+ return -ENODEV;
+ }
+
+ clock_control_on(I2S0_CLK_DEV, I2S0_CLK_SUBSYS);
+ i2s_ll_enable_clock(ADC_DMA_DEV);
+
+ int err = esp_intr_alloc(I2S0_INTR_SOURCE, ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED,
+ adc_esp32_dma_intr_handler, (void *)dev, &(data->irq_handle));
+ if (err != 0) {
+ LOG_ERR("Could not allocate interrupt (err %d)", err);
+ return err;
+ }
+#endif /* CONFIG_SOC_SERIES_ESP32S2 */
+
+#ifdef CONFIG_SOC_SERIES_ESP32S2
+ const struct device *spi3_dev = SPI3_DEV;
+
+ if (spi3_dev != NULL) {
+ LOG_ERR("SPI3 not available for ADC_ESP32_DMA");
+ return -ENODEV;
+ }
+
+ if (!device_is_ready(SPI3_CLK_DEV)) {
+ return -ENODEV;
+ }
+
+ clock_control_on(SPI3_CLK_DEV, SPI3_CLK_SUBSYS);
+ clock_control_on(SPI3_CLK_DEV, SPI3_DMA_CLK_SUBSYS);
+
+ int err = esp_intr_alloc(SPI3_DMA_INTR_SOURCE,
+ ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED,
+ adc_esp32_dma_intr_handler, (void *)dev, &(data->irq_handle));
+ if (err != 0) {
+ LOG_ERR("Could not allocate interrupt (err %d)", err);
+ return err;
+ }
+#endif /* CONFIG_SOC_SERIES_ESP32S2 */
+#endif /* CONFIG_ADC_ESP32_DMA */
for (uint8_t i = 0; i < SOC_ADC_MAX_CHANNEL_NUM; i++) {
data->resolution[i] = ADC_RESOLUTION_MAX;
@@ -734,22 +864,17 @@
.ref_internal = ADC_ESP32_DEFAULT_VREF_INTERNAL,
};
-#define ADC_ESP32_CONF_GPIO_PORT_INIT .gpio_port = DEVICE_DT_GET(DT_NODELABEL(gpio0)),
-
-#if defined(CONFIG_ADC_ESP32_DMA)
-
-#define ADC_ESP32_CONF_DMA_INIT(n) \
- .dma_dev = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \
- (DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_IDX(n, 0))), \
- (NULL)), \
- .dma_channel = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \
- (DT_INST_DMAS_CELL_BY_IDX(n, 0, channel)), \
- (0xff)),
+#ifdef CONFIG_ADC_ESP32_DMA
+#if SOC_GDMA_SUPPORTED
+#define ADC_ESP32_CONF_INIT(n) \
+ .dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_IDX(n, 0)), \
+ .dma_channel = DT_INST_DMAS_CELL_BY_IDX(n, 0, channel)
#else
-
-#define ADC_ESP32_CONF_DMA_INIT(inst)
-
-#endif /* defined(CONFIG_ADC_ESP32_DMA) */
+#define ADC_ESP32_CONF_INIT(n)
+#endif /* SOC_GDMA_SUPPORTED */
+#else
+#define ADC_ESP32_CONF_INIT(n)
+#endif /* CONFIG_ADC_ESP32_DMA */
#define ADC_ESP32_CHECK_CHANNEL_REF(chan) \
BUILD_ASSERT(DT_ENUM_HAS_VALUE(chan, zephyr_reference, adc_ref_internal), \
@@ -764,7 +889,8 @@
.clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(inst, offset), \
.unit = DT_PROP(DT_DRV_INST(inst), unit) - 1, \
.channel_count = DT_PROP(DT_DRV_INST(inst), channel_count), \
- ADC_ESP32_CONF_GPIO_PORT_INIT ADC_ESP32_CONF_DMA_INIT(inst)}; \
+ .gpio_port = DEVICE_DT_GET(DT_NODELABEL(gpio0)), \
+ ADC_ESP32_CONF_INIT(inst)}; \
\
static struct adc_esp32_data adc_esp32_data_##inst = { \
.hal = \
diff --git a/dts/xtensa/espressif/esp32/esp32_common.dtsi b/dts/xtensa/espressif/esp32/esp32_common.dtsi
index 1baad06..0b035bc 100644
--- a/dts/xtensa/espressif/esp32/esp32_common.dtsi
+++ b/dts/xtensa/espressif/esp32/esp32_common.dtsi
@@ -516,6 +516,7 @@
compatible = "espressif,esp32-adc";
reg = <0x3ff48800 10>;
clocks = <&clock ESP32_SARADC_MODULE>;
+ interrupt-parent = <&intc>;
unit = <1>;
channel-count = <8>;
#io-channel-cells = <1>;
diff --git a/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi b/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi
index 5cc3333..416acd5 100644
--- a/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi
+++ b/dts/xtensa/espressif/esp32s2/esp32s2_common.dtsi
@@ -400,6 +400,7 @@
compatible = "espressif,esp32-adc";
reg = <0x3f440018 100>;
clocks = <&clock ESP32_PERIPH_SARADC_MODULE>;
+ interrupt-parent = <&intc>;
unit = <1>;
channel-count = <10>;
#io-channel-cells = <1>;