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>;