You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2020/11/06 21:31:38 UTC

[incubator-nuttx] branch master updated: Add injected channel support.

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new a5d340a  Add injected channel support.
a5d340a is described below

commit a5d340a5df64edc7d179c6a220dc0fe096ffc31e
Author: Daniel P. Carvalho <da...@gmail.com>
AuthorDate: Fri Nov 6 16:56:00 2020 -0300

    Add injected channel support.
---
 arch/arm/src/stm32l4/Kconfig                | 224 ++++++--
 arch/arm/src/stm32l4/hardware/stm32l4_adc.h | 171 +++---
 arch/arm/src/stm32l4/stm32l4_adc.c          | 777 ++++++++++++++++++----------
 arch/arm/src/stm32l4/stm32l4_adc.h          | 371 ++++++++++++-
 include/nuttx/analog/ioctl.h                |   5 +
 5 files changed, 1156 insertions(+), 392 deletions(-)

diff --git a/arch/arm/src/stm32l4/Kconfig b/arch/arm/src/stm32l4/Kconfig
index 086616e..e8a831c 100644
--- a/arch/arm/src/stm32l4/Kconfig
+++ b/arch/arm/src/stm32l4/Kconfig
@@ -3603,26 +3603,26 @@ config STM32L4_TIM1_ADC
 		channel it is assigned to.
 
 choice
-	prompt "Select TIM1 ADC channel"
+	prompt "Select ADC to trigger"
 	default STM32L4_TIM1_ADC1
 	depends on STM32L4_TIM1_ADC
 
 config STM32L4_TIM1_ADC1
-	bool "TIM1 ADC channel 1"
+	bool "TIM1 trigger ADC1"
 	depends on STM32L4_ADC1
 	select STM32L4_HAVE_ADC1_TIMER
 	---help---
 		Reserve TIM1 to trigger ADC1
 
 config STM32L4_TIM1_ADC2
-	bool "TIM1 ADC channel 2"
+	bool "TIM1 trigger ADC2"
 	depends on STM32L4_ADC2
 	select STM32L4_HAVE_ADC2_TIMER
 	---help---
 		Reserve TIM1 to trigger ADC2
 
 config STM32L4_TIM1_ADC3
-	bool "TIM1 ADC channel 3"
+	bool "TIM1 trigger ADC3"
 	depends on STM32L4_ADC3
 	select STM32L4_HAVE_ADC3_TIMER
 	---help---
@@ -3630,6 +3630,14 @@ config STM32L4_TIM1_ADC3
 
 endchoice
 
+config STM32L4_TIM1_ADC_CHAN
+	int "TIM1 channel"
+	default 1
+	range 1 4
+	depends on STM32L4_TIM1_ADC
+	---help---
+		Values 1:CC1 2:CC2 3:CC3 4:CC4
+
 config STM32L4_TIM2_ADC
 	bool "TIM2 ADC"
 	default n
@@ -3645,26 +3653,26 @@ config STM32L4_TIM2_ADC
 		channel it is assigned to.
 
 choice
-	prompt "Select TIM2 ADC channel"
+	prompt "Select ADC to trigger"
 	default STM32L4_TIM2_ADC1
 	depends on STM32L4_TIM2_ADC
 
 config STM32L4_TIM2_ADC1
-	bool "TIM2 ADC channel 1"
+	bool "TIM2 trigger ADC1"
 	depends on STM32L4_ADC1
 	select STM32L4_HAVE_ADC1_TIMER
 	---help---
 		Reserve TIM2 to trigger ADC1
 
 config STM32L4_TIM2_ADC2
-	bool "TIM2 ADC channel 2"
+	bool "TIM2 trigger ADC2"
 	depends on STM32L4_ADC2
 	select STM32L4_HAVE_ADC2_TIMER
 	---help---
 		Reserve TIM2 to trigger ADC2
 
 config STM32L4_TIM2_ADC3
-	bool "TIM2 ADC channel 3"
+	bool "TIM2 trigger ADC3"
 	depends on STM32L4_ADC3
 	select STM32L4_HAVE_ADC3_TIMER
 	---help---
@@ -3672,6 +3680,14 @@ config STM32L4_TIM2_ADC3
 
 endchoice
 
+config STM32L4_TIM2_ADC_CHAN
+	int "TIM2 channel"
+	default 1
+	range 1 4
+	depends on STM32L4_TIM2_ADC
+	---help---
+		Values 1:CC1 2:CC2 3:CC3 4:CC4
+
 config STM32L4_TIM3_ADC
 	bool "TIM3 ADC"
 	default n
@@ -3687,26 +3703,26 @@ config STM32L4_TIM3_ADC
 		channel it is assigned to.
 
 choice
-	prompt "Select TIM3 ADC channel"
+	prompt "Select ADC to trigger"
 	default STM32L4_TIM3_ADC1
 	depends on STM32L4_TIM3_ADC
 
 config STM32L4_TIM3_ADC1
-	bool "TIM3 ADC channel 1"
+	bool "TIM3 trigger ADC1"
 	depends on STM32L4_ADC1
 	select STM32L4_HAVE_ADC1_TIMER
 	---help---
 		Reserve TIM3 to trigger ADC1
 
 config STM32L4_TIM3_ADC2
-	bool "TIM3 ADC channel 2"
+	bool "TIM3 trigger ADC2"
 	depends on STM32L4_ADC2
 	select STM32L4_HAVE_ADC2_TIMER
 	---help---
 		Reserve TIM3 to trigger ADC2
 
 config STM32L4_TIM3_ADC3
-	bool "TIM3 ADC channel 3"
+	bool "TIM3 trigger ADC3"
 	depends on STM32L4_ADC3
 	select STM32L4_HAVE_ADC3_TIMER
 	---help---
@@ -3714,6 +3730,14 @@ config STM32L4_TIM3_ADC3
 
 endchoice
 
+config STM32L4_TIM3_ADC_CHAN
+	int "TIM3 channel"
+	default 1
+	range 1 4
+	depends on STM32L4_TIM3_ADC
+	---help---
+		Values 1:CC2 2:CC2 3:CC3 4:CC4
+
 config STM32L4_TIM4_ADC
 	bool "TIM4 ADC"
 	default n
@@ -3729,26 +3753,26 @@ config STM32L4_TIM4_ADC
 		channel it is assigned to.
 
 choice
-	prompt "Select TIM4 ADC channel"
+	prompt "Select ADC to trigger"
 	default STM32L4_TIM4_ADC1
 	depends on STM32L4_TIM4_ADC
 
 config STM32L4_TIM4_ADC1
-	bool "TIM4 ADC channel 1"
+	bool "TIM4 trigger ADC1"
 	depends on STM32L4_ADC1
 	select STM32L4_HAVE_ADC1_TIMER
 	---help---
 		Reserve TIM4 to trigger ADC1
 
 config STM32L4_TIM4_ADC2
-	bool "TIM4 ADC channel 2"
+	bool "TIM4 trigger ADC2"
 	depends on STM32L4_ADC2
 	select STM32L4_HAVE_ADC2_TIMER
 	---help---
 		Reserve TIM4 to trigger ADC2
 
 config STM32L4_TIM4_ADC3
-	bool "TIM4 ADC channel 3"
+	bool "TIM4 trigger ADC3"
 	depends on STM32L4_ADC3
 	select STM32L4_HAVE_ADC3_TIMER
 	---help---
@@ -3756,6 +3780,14 @@ config STM32L4_TIM4_ADC3
 
 endchoice
 
+config STM32L4_TIM4_ADC_CHAN
+	int "TIM4 channel"
+	default 1
+	range 1 4
+	depends on STM32L4_TIM4_ADC
+	---help---
+		Values 1:CC2 2:CC2 3:CC3 4:CC4
+
 config STM32L4_TIM6_ADC
 	bool "TIM6 ADC"
 	default n
@@ -3771,26 +3803,26 @@ config STM32L4_TIM6_ADC
 		channel it is assigned to.
 
 choice
-	prompt "Select TIM6 ADC channel"
+	prompt "Select ADC to trigger"
 	default STM32L4_TIM6_ADC1
 	depends on STM32L4_TIM6_ADC
 
 config STM32L4_TIM6_ADC1
-	bool "TIM6 ADC channel 1"
+	bool "TIM6 trigger ADC1"
 	depends on STM32L4_ADC1
 	select STM32L4_HAVE_ADC1_TIMER
 	---help---
 		Reserve TIM6 to trigger ADC1
 
 config STM32L4_TIM6_ADC2
-	bool "TIM6 ADC channel 2"
+	bool "TIM6 trigger ADC2"
 	depends on STM32L4_ADC2
 	select STM32L4_HAVE_ADC2_TIMER
 	---help---
 		Reserve TIM6 to trigger ADC2
 
 config STM32L4_TIM6_ADC3
-	bool "TIM6 ADC channel 3"
+	bool "TIM6 trigger ADC3"
 	depends on STM32L4_ADC3
 	select STM32L4_HAVE_ADC3_TIMER
 	---help---
@@ -3798,6 +3830,14 @@ config STM32L4_TIM6_ADC3
 
 endchoice
 
+config STM32L4_TIM6_ADC_CHAN
+	int "TIM6 channel"
+	default 1
+	range 1 4
+	depends on STM32L4_TIM6_ADC
+	---help---
+		Values 1:CC2 2:CC2 3:CC3 4:CC4
+
 config STM32L4_TIM8_ADC
 	bool "TIM8 ADC"
 	default n
@@ -3813,26 +3853,26 @@ config STM32L4_TIM8_ADC
 		channel it is assigned to.
 
 choice
-	prompt "Select TIM8 ADC channel"
+	prompt "Select ADC to trigger"
 	default STM32L4_TIM8_ADC1
 	depends on STM32L4_TIM8_ADC
 
 config STM32L4_TIM8_ADC1
-	bool "TIM8 ADC channel 1"
+	bool "TIM8 trigger ADC1"
 	depends on STM32L4_ADC1
 	select STM32L4_HAVE_ADC1_TIMER
 	---help---
 		Reserve TIM8 to trigger ADC1
 
 config STM32L4_TIM8_ADC2
-	bool "TIM8 ADC channel 2"
+	bool "TIM8 trigger ADC2"
 	depends on STM32L4_ADC2
 	select STM32L4_HAVE_ADC2_TIMER
 	---help---
 		Reserve TIM8 to trigger ADC2
 
 config STM32L4_TIM8_ADC3
-	bool "TIM8 ADC channel 3"
+	bool "TIM8 trigger ADC3"
 	depends on STM32L4_ADC3
 	select STM32L4_HAVE_ADC3_TIMER
 	---help---
@@ -3840,6 +3880,14 @@ config STM32L4_TIM8_ADC3
 
 endchoice
 
+config STM32L4_TIM8_ADC_CHAN
+	int "TIM8 channel"
+	default 1
+	range 1 4
+	depends on STM32L4_TIM8_ADC
+	---help---
+		Values 1:CC2 2:CC2 3:CC3 4:CC4
+
 config STM32L4_TIM15_ADC
 	bool "TIM15 ADC"
 	default n
@@ -3855,26 +3903,26 @@ config STM32L4_TIM15_ADC
 		channel it is assigned to.
 
 choice
-	prompt "Select TIM15 ADC channel"
+	prompt "Select ADC to trigger"
 	default STM32L4_TIM15_ADC1
 	depends on STM32L4_TIM15_ADC
 
 config STM32L4_TIM15_ADC1
-	bool "TIM15 ADC channel 1"
+	bool "TIM15 trigger ADC1"
 	depends on STM32L4_ADC1
 	select STM32L4_HAVE_ADC1_TIMER
 	---help---
 		Reserve TIM15 to trigger ADC1
 
 config STM32L4_TIM15_ADC2
-	bool "TIM15 ADC channel 2"
+	bool "TIM15 trigger ADC2"
 	depends on STM32L4_ADC2
 	select STM32L4_HAVE_ADC2_TIMER
 	---help---
 		Reserve TIM15 to trigger ADC2
 
 config STM32L4_TIM15_ADC3
-	bool "TIM15 ADC channel 3"
+	bool "TIM15 trigger ADC3"
 	depends on STM32L4_ADC3
 	select STM32L4_HAVE_ADC3_TIMER
 	---help---
@@ -3882,6 +3930,14 @@ config STM32L4_TIM15_ADC3
 
 endchoice
 
+config STM32L4_TIM15_ADC_CHAN
+	int "TIM15 channel"
+	default 1
+	range 1 4
+	depends on STM32L4_TIM15_ADC
+	---help---
+		Values 1:CC2 2:CC2 3:CC3 4:CC4
+
 config STM32L4_HAVE_ADC1_TIMER
 	bool
 
@@ -3898,14 +3954,6 @@ config STM32L4_ADC1_SAMPLE_FREQUENCY
 	---help---
 		ADC1 sampling frequency.  Default:  100Hz
 
-config STM32L4_ADC1_TIMTRIG
-	int "ADC1 Timer Trigger"
-	default 0
-	range 0 4
-	depends on STM32L4_HAVE_ADC1_TIMER
-	---help---
-		Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO
-
 config STM32L4_ADC2_SAMPLE_FREQUENCY
 	int "ADC2 Sampling Frequency"
 	default 100
@@ -3913,14 +3961,6 @@ config STM32L4_ADC2_SAMPLE_FREQUENCY
 	---help---
 		ADC2 sampling frequency.  Default:  100Hz
 
-config STM32L4_ADC2_TIMTRIG
-	int "ADC2 Timer Trigger"
-	default 0
-	range 0 4
-	depends on STM32L4_HAVE_ADC2_TIMER
-	---help---
-		Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO
-
 config STM32L4_ADC3_SAMPLE_FREQUENCY
 	int "ADC3 Sampling Frequency"
 	default 100
@@ -3928,14 +3968,6 @@ config STM32L4_ADC3_SAMPLE_FREQUENCY
 	---help---
 		ADC3 sampling frequency.  Default:  100Hz
 
-config STM32L4_ADC3_TIMTRIG
-	int "ADC3 Timer Trigger"
-	default 0
-	range 0 4
-	depends on STM32L4_HAVE_ADC3_TIMER
-	---help---
-		Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO
-
 config STM32L4_TIM1_DAC
 	bool "TIM1 DAC"
 	default n
@@ -5150,6 +5182,94 @@ config STM32L4_ADC3_OUTPUT_DFSDM
 	---help---
 		Route ADC3 output directly to DFSDM parallel inputs.
 
+menu "STM32L4 ADCx triggering Configuration"
+
+config STM32L4_ADC1_TIMTRIG
+	int "ADC1 regular channel trigger"
+	default 0
+	range 0 4
+	depends on STM32L4_HAVE_ADC1_TIMER
+	---help---
+		Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO
+
+config STM32L4_ADC2_TIMTRIG
+	int "ADC2 Timer Trigger"
+	default 0
+	range 0 4
+	depends on STM32L4_HAVE_ADC2_TIMER
+	---help---
+		Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO
+
+config STM32L4_ADC3_TIMTRIG
+	int "ADC3 Timer Trigger"
+	default 0
+	range 0 4
+	depends on STM32L4_HAVE_ADC3_TIMER
+	---help---
+		Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO
+
+config STM32L4_ADC1_INJ_CHAN
+	int "ADC1 configured injected channels"
+	depends on STM32L4_ADC1
+	range 0 4
+	default 0
+	---help---
+		Number of configured ADC1 injected channels.
+
+config STM32L4_ADC2_INJ_CHAN
+	int "ADC2 configured injected channels"
+	depends on STM32L4_ADC2
+	range 0 4
+	default 0
+	---help---
+		Number of configured ADC2 injected channels.
+
+config STM32L4_ADC3_INJ_CHAN
+	int "ADC3 configured injected channels"
+	depends on STM32L4_ADC3
+	range 0 4
+	default 0
+	---help---
+		Number of configured ADC3 injected channels.
+
+if STM32L4_ADC1_INJ_CHAN > 0
+
+config STM32L4_ADC1_JTIMTRIG
+	int "ADC1 external trigger for injected channels"
+	default 0
+	range 0 5
+	depends on STM32L4_HAVE_ADC1_TIMER
+	---help---
+		Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO 5:TRGO2
+
+endif
+
+if STM32L4_ADC2_INJ_CHAN > 0
+
+config STM32L4_ADC2_JTIMTRIG
+	int "ADC2 external trigger for injected channels"
+	default 0
+	range 0 5
+	depends on STM32L4_HAVE_ADC2_TIMER
+	---help---
+		Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO 5:TRGO2
+
+endif
+
+if STM32L4_ADC3_INJ_CHAN > 0
+
+config STM32L4_ADC3_JTIMTRIG
+	int "ADC3 external trigger for injected channels"
+	default 0
+	range 0 5
+	depends on STM32L4_HAVE_ADC3_TIMER
+	---help---
+		Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO 5:TRGO2
+
+endif
+
+endmenu #STM32L4 ADCx triggering Configuration
+
 endmenu
 
 menu "DAC Configuration"
diff --git a/arch/arm/src/stm32l4/hardware/stm32l4_adc.h b/arch/arm/src/stm32l4/hardware/stm32l4_adc.h
index 5db9b10..5fa3e9a 100644
--- a/arch/arm/src/stm32l4/hardware/stm32l4_adc.h
+++ b/arch/arm/src/stm32l4/hardware/stm32l4_adc.h
@@ -50,8 +50,9 @@
  ************************************************************************************/
 
 /* Register Offsets *****************************************************************/
-/* Register Offsets for each ADC (ADC1-3).  At offset 0x0000 for master and offset 0x0100
- * for slave.
+
+/* Register Offsets for each ADC (ADC1-3).  At offset 0x0000 for master and offset
+ * 0x0100 for slave.
  */
 
 #define STM32L4_ADC_ISR_OFFSET         0x0000  /* ADC interrupt and status register */
@@ -187,6 +188,7 @@
 #endif
 
 /* Register Bitfield Definitions ****************************************************/
+
 /* ADC interrupt and status register (ISR) and ADC interrupt enable register (IER) */
 
 #define ADC_INT_ADRDY                (1 << 0)  /* Bit 0:  ADC ready */
@@ -223,51 +225,53 @@
 #define ADC_CFGR_DFSDMCFG            (1 << 2)  /* Bit 2: DFSDM mode configuration */
 #define ADC_CFGR_RES_SHIFT           (3)       /* Bits 3-4: Data resolution */
 #define ADC_CFGR_RES_MASK            (3 << ADC_CFGR_RES_SHIFT)
-#  define ADC_CFGR_RES_12BIT         (0 << ADC_CFGR_RES_SHIFT) /* 12-bit resolution */
-#  define ADC_CFGR_RES_10BIT         (1 << ADC_CFGR_RES_SHIFT) /* 10-bit resolution */
-#  define ADC_CFGR_RES_8BIT          (2 << ADC_CFGR_RES_SHIFT) /* 8-bit resolution */
-#  define ADC_CFGR_RES_6BIT          (3 << ADC_CFGR_RES_SHIFT) /* 6-bit resolution */
-#define ADC_CFGR_ALIGN               (1 << 5)  /* Bit 5: Data Alignment */
-#define ADC_CFGR_EXTSEL_SHIFT        (6)       /* Bits 6-9: External Event Select for regular group */
+#  define ADC_CFGR_RES_12BIT         (0 << ADC_CFGR_RES_SHIFT)         /* 12-bit resolution */
+#  define ADC_CFGR_RES_10BIT         (1 << ADC_CFGR_RES_SHIFT)         /* 10-bit resolution */
+#  define ADC_CFGR_RES_8BIT          (2 << ADC_CFGR_RES_SHIFT)         /* 8-bit resolution */
+#  define ADC_CFGR_RES_6BIT          (3 << ADC_CFGR_RES_SHIFT)         /* 6-bit resolution */
+#define ADC_CFGR_ALIGN               (1 << 5)                          /* Bit 5: Data Alignment */
+#define ADC_CFGR_EXTSEL_SHIFT        (6)                               /* Bits 6-9: External Event Select for regular group */
 #define ADC_CFGR_EXTSEL_MASK         (15 << ADC_CFGR_EXTSEL_SHIFT)
-#  define ADC_CFGR_EXTSEL(event)     ((event) << ADC_CFGR_EXTSEL_SHIFT) /* Event = 0..15 */
-#  define ADC_CFGR_EXTSEL_T1CC1      (0x0 << ADC_CFGR_EXTSEL_SHIFT)  /* 0000: Timer 1 CC1 event */
-#  define ADC_CFGR_EXTSEL_T1CC2      (0x01 << ADC_CFGR_EXTSEL_SHIFT) /* 0001: Timer 1 CC2 event */
-#  define ADC_CFGR_EXTSEL_T1CC3      (0x02 << ADC_CFGR_EXTSEL_SHIFT) /* 0010: Timer 1 CC3 event */
-#  define ADC_CFGR_EXTSEL_T2CC2      (0x03 << ADC_CFGR_EXTSEL_SHIFT) /* 0011: Timer 2 CC2 event */
-#  define ADC_CFGR_EXTSEL_T3TRGO     (0x04 << ADC_CFGR_EXTSEL_SHIFT) /* 0100: Timer 3 TRGO event */
+#  define ADC_CFGR_EXTSEL(event)     ((event) << ADC_CFGR_EXTSEL_SHIFT)/* Event = 0..15 */
+#  define ADC_CFGR_EXTSEL_T1CC1      (0x0 << ADC_CFGR_EXTSEL_SHIFT)    /* 0000: Timer 1 CC1 event */
+#  define ADC_CFGR_EXTSEL_T1CC2      (0x01 << ADC_CFGR_EXTSEL_SHIFT)   /* 0001: Timer 1 CC2 event */
+#  define ADC_CFGR_EXTSEL_T1CC3      (0x02 << ADC_CFGR_EXTSEL_SHIFT)   /* 0010: Timer 1 CC3 event */
+#  define ADC_CFGR_EXTSEL_T2CC2      (0x03 << ADC_CFGR_EXTSEL_SHIFT)   /* 0011: Timer 2 CC2 event */
+#  define ADC_CFGR_EXTSEL_T3TRGO     (0x04 << ADC_CFGR_EXTSEL_SHIFT)   /* 0100: Timer 3 TRGO event */
 #  if !defined(CONFIG_STM32L4_STM32L4X3)
-#    define ADC_CFGR_EXTSEL_T4CC4    (0x05 << ADC_CFGR_EXTSEL_SHIFT) /* 0101: Timer 4 CC4 event */
+#    define ADC_CFGR_EXTSEL_T4CC4    (0x05 << ADC_CFGR_EXTSEL_SHIFT)   /* 0101: Timer 4 CC4 event */
 #  endif
-#  define ADC_CFGR_EXTSEL_EXTI11     (0x06 << ADC_CFGR_EXTSEL_SHIFT) /* 0110: EXTI line 11 */
+#  define ADC_CFGR_EXTSEL_EXTI11     (0x06 << ADC_CFGR_EXTSEL_SHIFT)   /* 0110: EXTI line 11 */
 #  if !defined(CONFIG_STM32L4_STM32L4X3)
-#    define ADC_CFGR_EXTSEL_T8TRGO   (0x07 << ADC_CFGR_EXTSEL_SHIFT) /* 0111: Timer 8 TRGO event */
-#    define ADC_CFGR_EXTSEL_T8TRGO2  (0x08 << ADC_CFGR_EXTSEL_SHIFT) /* 1000: Timer 8 TRGO2 event */
+#    define ADC_CFGR_EXTSEL_T8TRGO   (0x07 << ADC_CFGR_EXTSEL_SHIFT)   /* 0111: Timer 8 TRGO event */
+#    define ADC_CFGR_EXTSEL_T8TRGO2  (0x08 << ADC_CFGR_EXTSEL_SHIFT)   /* 1000: Timer 8 TRGO2 event */
 #  endif
-#  define ADC_CFGR_EXTSEL_T1TRGO     (0x09 << ADC_CFGR_EXTSEL_SHIFT) /* 1001: Timer 1 TRGO event */
-#  define ADC_CFGR_EXTSEL_T1TRGO2    (0x0a << ADC_CFGR_EXTSEL_SHIFT) /* 1010: Timer 1 TRGO2 event */
-#  define ADC_CFGR_EXTSEL_T2TRGO     (0x0b << ADC_CFGR_EXTSEL_SHIFT) /* 1011: Timer 2 TRGO event */
+#  define ADC_CFGR_EXTSEL_T1TRGO     (0x09 << ADC_CFGR_EXTSEL_SHIFT)   /* 1001: Timer 1 TRGO event */
+#  define ADC_CFGR_EXTSEL_T1TRGO2    (0x0a << ADC_CFGR_EXTSEL_SHIFT)   /* 1010: Timer 1 TRGO2 event */
+#  define ADC_CFGR_EXTSEL_T2TRGO     (0x0b << ADC_CFGR_EXTSEL_SHIFT)   /* 1011: Timer 2 TRGO event */
 #  if !defined(CONFIG_STM32L4_STM32L4X3)
-#    define ADC_CFGR_EXTSEL_T4TRGO   (0x0c << ADC_CFGR_EXTSEL_SHIFT) /* 1100: Timer 4 TRGO event */
+#    define ADC_CFGR_EXTSEL_T4TRGO   (0x0c << ADC_CFGR_EXTSEL_SHIFT)   /* 1100: Timer 4 TRGO event */
 #  endif
-#  define ADC_CFGR_EXTSEL_T6TRGO     (0x0d << ADC_CFGR_EXTSEL_SHIFT) /* 1101: Timer 6 TRGO event */
-#  define ADC_CFGR_EXTSEL_T15TRGO    (0x0e << ADC_CFGR_EXTSEL_SHIFT) /* 1110: Timer 15 TRGO event */
+#  define ADC_CFGR_EXTSEL_T6TRGO     (0x0d << ADC_CFGR_EXTSEL_SHIFT)   /* 1101: Timer 6 TRGO event */
+#  define ADC_CFGR_EXTSEL_T15TRGO    (0x0e << ADC_CFGR_EXTSEL_SHIFT)   /* 1110: Timer 15 TRGO event */
 #  if !defined(CONFIG_STM32L4_STM32L4X3)
-#    define ADC_CFGR_EXTSEL_T3CC4    (0x0f << ADC_CFGR_EXTSEL_SHIFT) /* 1111: Timer 3 CC4 event */
+#    define ADC_CFGR_EXTSEL_T3CC4    (0x0f << ADC_CFGR_EXTSEL_SHIFT)   /* 1111: Timer 3 CC4 event */
 #  endif
-#define ADC_CFGR_EXTEN_SHIFT         (10)      /* Bits 10-11: External trigger/polarity selection regular channels */
+#define ADC_CFGR_EXTEN_SHIFT         (10)                              /* Bits 10-11: External trigger/polarity selection regular channels */
 #define ADC_CFGR_EXTEN_MASK          (3 << ADC_CFGR_EXTEN_SHIFT)
-#  define ADC_CFGR_EXTEN_NONE        (0 << ADC_CFGR_EXTEN_SHIFT) /* Trigger detection disabled */
-#  define ADC_CFGR_EXTEN_RISING      (1 << ADC_CFGR_EXTEN_SHIFT) /* Trigger detection on the rising edge */
-#  define ADC_CFGR_EXTEN_FALLING     (2 << ADC_CFGR_EXTEN_SHIFT) /* Trigger detection on the falling edge */
-#  define ADC_CFGR_EXTEN_BOTH        (3 << ADC_CFGR_EXTEN_SHIFT) /* Trigger detection on both edges */
-#define ADC_CFGR_OVRMOD              (1 << 12) /* Bit 12: Overrun Mode */
-#define ADC_CFGR_CONT                (1 << 13) /* Bit 13: Continuous mode for regular conversions */
-#define ADC_CFGR_AUTDLY              (1 << 14) /* Bit 14: Delayed conversion mode */
-#define ADC_CFGR_DISCEN              (1 << 16) /* Bit 16: Discontinuous mode on regular channels */
-#define ADC_CFGR_DISCNUM_SHIFT       (17)      /* Bits 17-19: Discontinuous mode channel count */
+#  define ADC_CFGR_EXTEN_NONE        (0 << ADC_CFGR_EXTEN_SHIFT)       /* Trigger detection disabled */
+#  define ADC_CFGR_EXTEN_RISING      (1 << ADC_CFGR_EXTEN_SHIFT)       /* Trigger detection on the rising edge */
+#  define ADC_CFGR_EXTEN_FALLING     (2 << ADC_CFGR_EXTEN_SHIFT)       /* Trigger detection on the falling edge */
+#  define ADC_CFGR_EXTEN_BOTH        (3 << ADC_CFGR_EXTEN_SHIFT)       /* Trigger detection on both edges */
+#define ADC_CFGR_OVRMOD              (1 << 12)                         /* Bit 12: Overrun Mode */
+#define ADC_CFGR_CONT                (1 << 13)                         /* Bit 13: Continuous mode for regular conversions */
+#define ADC_CFGR_AUTDLY              (1 << 14)                         /* Bit 14: Delayed conversion mode */
+#define ADC_CFGR_DISCEN              (1 << 16)                         /* Bit 16: Discontinuous mode on regular channels */
+#define ADC_CFGR_DISCNUM_SHIFT       (17)                              /* Bits 17-19: Discontinuous mode channel count */
 #define ADC_CFGR_DISCNUM_MASK        (7 << ADC_CFGR_DISCNUM_SHIFT)
-#  define ADC_CFGR_DISCNUM(n)        (((n) - 1) << ADC_CFGR_DISCNUM_SHIFT) /* n = 1..8 channels */
+#  define ADC_CFGR_DISCNUM(n)        (((n) - 1) << ADC_CFGR_DISCNUM_SHIFT) 
+                                                                       /* n = 1..8 channels */
+
 #define ADC_CFGR_JDISCEN             (1 << 20) /* Bit 20: Discontinuous mode on injected channels */
 #define ADC_CFGR_JQM                 (1 << 21) /* Bit 21: JSQR queue mode */
 #define ADC_CFGR_AWD1SGL             (1 << 22) /* Bit 22: Enable watchdog on single/all channels */
@@ -293,11 +297,12 @@
 #  define ADC_CFGR2_OVSR_64X         (5 << ADC_CFGR2_OVSR_SHIFT) /* 64X oversampling */
 #  define ADC_CFGR2_OVSR_128X        (6 << ADC_CFGR2_OVSR_SHIFT) /* 128X oversampling */
 #  define ADC_CFGR2_OVSR_256X        (7 << ADC_CFGR2_OVSR_SHIFT) /* 256X oversampling */
-#define ADC_CFGR2_OVSS_SHIFT         (5)       /* Bits 5-8: Oversampling shift */
+#define ADC_CFGR2_OVSS_SHIFT         (5)                         /* Bits 5-8: Oversampling shift */
 #define ADC_CFGR2_OVSS_MASK          (0xf << ADC_CFGR2_OVSS_SHIFT)
-#  define ADC_CFGR2_OVSS(value)      ((value) << ADC_CFGR2_OVSS_SHIFT) /* Value = 0..8 */
-#define ADC_CFGR2_TROVS              (1 << 9)  /* Bit 9: Triggered Regular Oversampling */
-#define ADC_CFGR2_ROVSM              (1 << 10) /* Bit 10: Regular Oversampling mode */
+#  define ADC_CFGR2_OVSS(value)      ((value) << ADC_CFGR2_OVSS_SHIFT)
+                                                                /* Value = 0..8 */
+#define ADC_CFGR2_TROVS              (1 << 9)                   /* Bit 9: Triggered Regular Oversampling */
+#define ADC_CFGR2_ROVSM              (1 << 10)                  /* Bit 10: Regular Oversampling mode */
 
 /* ADC sample time register 1 */
 
@@ -446,30 +451,49 @@
 
 /* ADC injected sequence register */
 
-#define ADC_JSQR_JL_SHIFT            (0)       /* Bits 0-1: Injected Sequence length */
+#define ADC_JSQR_JL_SHIFT            (0)                          /* Bits 0-1: Injected Sequence length */
 #define ADC_JSQR_JL_MASK             (3 << ADC_JSQR_JL_SHIFT)
-#  define ADC_JSQR_JL(n)             (((n)-1) << ADC_JSQR_JL_SHIFT) /* n=1..4 */
-#define ADC_JSQR_JEXTSEL_SHIFT       (2)       /* Bits 2-5: External Trigger Selection for injected group */
+#  define ADC_JSQR_JL(n)             (((n)-1) << ADC_JSQR_JL_SHIFT)
+                                                                  /* n=1..4 */
+#define ADC_JSQR_JEXTSEL_SHIFT       (2)                          /* Bits 2-5: External Trigger Selection for injected group */
 #define ADC_JSQR_JEXTSEL_MASK        (15 << ADC_JSQR_JEXTSEL_SHIFT)
-#  define ADC_JSQR_JEXTSEL(event)    ((event) << ADC_JSQR_JEXTSEL_SHIFT) /* Event = 0..15 */
-#define ADC_JSQR_JEXTEN_SHIFT        (6)       /* Bits 6-7: External trigger selection for injected greoup */
+#  define ADC_JSQR_JEXTSEL(event)    ((event) << ADC_JSQR_JEXTSEL_SHIFT) 
+                                                                  /* Event = 0..15 */
+#  define ADC_JEXTSEL_T1TRGO         ADC_JSQR_JEXTSEL(0)          /* 0000 TIM1_TRGO */
+#  define ADC_JEXTSEL_T1CC4          ADC_JSQR_JEXTSEL(1)          /* 0001 TIM1_CH4 */
+#  define ADC_JEXTSEL_T2TRGO         ADC_JSQR_JEXTSEL(2)          /* 0010 TIM2_TRGO */
+#  define ADC_JEXTSEL_T2CC1          ADC_JSQR_JEXTSEL(3)          /* 0011 TIM2_CH1 */
+#  define ADC_JEXTSEL_T3CC4          ADC_JSQR_JEXTSEL(4)          /* 0100 TIM3_CH4 */
+#  define ADC_JEXTSEL_T4TRGO         ADC_JSQR_JEXTSEL(5)          /* 0101 TIM4_TRGO */
+#  define ADC_JEXTSEL_EXTI15         ADC_JSQR_JEXTSEL(6)          /* 0110 EXTI line 15 */
+#  define ADC_JEXTSEL_T8CC4          ADC_JSQR_JEXTSEL(7)          /* 0111 TIM8_CH4 */
+#  define ADC_JEXTSEL_T1TRGO2        ADC_JSQR_JEXTSEL(8)          /* 1000 TIM1_TRGO2 */
+#  define ADC_JEXTSEL_T8TRGO         ADC_JSQR_JEXTSEL(9)          /* 1001 TIM8_TRGO */
+#  define ADC_JEXTSEL_T8TRGO2        ADC_JSQR_JEXTSEL(10)         /* 1010 TIM8_TRG02 */
+#  define ADC_JEXTSEL_T3CC3          ADC_JSQR_JEXTSEL(11)         /* 1011 TIM3_CH3 */
+#  define ADC_JEXTSEL_T3TRGO         ADC_JSQR_JEXTSEL(12)         /* 1011 TIM3_TRGO */
+#  define ADC_JEXTSEL_T3CC1          ADC_JSQR_JEXTSEL(13)         /* 1101 TIM3_CH1 */
+#  define ADC_JEXTSEL_T6TRGO         ADC_JSQR_JEXTSEL(14)         /* 1110 TIM6_TRGO */
+#  define ADC_JEXTSEL_T15TRGO        ADC_JSQR_JEXTSEL(15)         /* 1111 TIM15_TRGO */
+#define ADC_JSQR_JEXTEN_SHIFT        (6)                          /* Bits 6-7: External trigger selection for injected greoup */
 #define ADC_JSQR_JEXTEN_MASK         (3 << ADC_JSQR_JEXTEN_SHIFT)
 #  define ADC_JSQR_JEXTEN_NONE       (0 << ADC_JSQR_JEXTEN_SHIFT) /* 00: Trigger detection disabled */
 #  define ADC_JSQR_JEXTEN_RISING     (1 << ADC_JSQR_JEXTEN_SHIFT) /* 01: Trigger detection on the rising edge */
 #  define ADC_JSQR_JEXTEN_FALLING    (2 << ADC_JSQR_JEXTEN_SHIFT) /* 10: Trigger detection on the falling edge */
 #  define ADC_JSQR_JEXTEN_BOTH       (3 << ADC_JSQR_JEXTEN_SHIFT) /* 11: Trigger detection on both the rising and falling edges */
-#define ADC_JSQR_JSQ1_SHIFT          (8)        /* Bits 8-12: 1st conversion in injected sequence */
+#define ADC_JSQR_JSQ_SHIFT           (6)
+#define ADC_JSQR_JSQ1_SHIFT          (8)                          /* Bits 8-12: 1st conversion in injected sequence */
 #define ADC_JSQR_JSQ1_MASK           (0x1f << ADC_JSQR_JSQ1_SHIFT)
-#  define ADC_JSQR_JSQ1(ch)          ((ch) << ADC_JSQR_JSQ1_SHIFT) /* Channel number 1..18 */
-#define ADC_JSQR_JSQ2_SHIFT          (14)       /* Bits 14-18: 2nd conversion in injected sequence */
+#  define ADC_JSQR_JSQ1(ch)          ((ch) << ADC_JSQR_JSQ1_SHIFT)/* Channel number 1..18 */
+#define ADC_JSQR_JSQ2_SHIFT          (14)                         /* Bits 14-18: 2nd conversion in injected sequence */
 #define ADC_JSQR_JSQ2_MASK           (0x1f << ADC_JSQR_JSQ2_MASK)
 #  define ADC_JSQR_JSQ2(ch)          ((ch) << ADC_JSQR_JSQ2_MASK) /* Channel number 1..18 */
-#define ADC_JSQR_JSQ3_SHIFT          (20)       /* Bits 20-24: 3rd conversion in injected sequence */
+#define ADC_JSQR_JSQ3_SHIFT          (20)                         /* Bits 20-24: 3rd conversion in injected sequence */
 #define ADC_JSQR_JSQ3_MASK           (0x1f << ADC_JSQR_JSQ3_SHIFT)
-#  define ADC_JSQR_JSQ3(ch)          ((ch) << ADC_JSQR_JSQ3_SHIFT) /* Channel number 1..18 */
-#define ADC_JSQR_JSQ4_SHIFT          (26)       /* Bits 26-30: 4th conversion in injected sequence */
+#  define ADC_JSQR_JSQ3(ch)          ((ch) << ADC_JSQR_JSQ3_SHIFT)/* Channel number 1..18 */
+#define ADC_JSQR_JSQ4_SHIFT          (26)                         /* Bits 26-30: 4th conversion in injected sequence */
 #define ADC_JSQR_JSQ4_MASK           (0x1f << ADC_JSQR_JSQ4_SHIFT)
-#  define ADC_JSQR_JSQ4(ch)          ((ch) << ADC_JSQR_JSQ4_SHIFT) /* Channel number 1..18 */
+#  define ADC_JSQR_JSQ4(ch)          ((ch) << ADC_JSQR_JSQ4_SHIFT)/* Channel number 1..18 */
 
 /* ADC offset register 1, 2, 3, and 4 */
 
@@ -541,33 +565,34 @@
 /* Common control register */
 
 #ifndef CONFIG_STM32L4_STM32L4X3
-#  define ADC_CCR_DUAL_SHIFT         (0)       /* Bits 0-4: Dual ADC mode selection */
+#  define ADC_CCR_DUAL_SHIFT         (0)                         /* Bits 0-4: Dual ADC mode selection */
 #  define ADC_CCR_DUAL_MASK          (31 << ADC_CCR_DUAL_SHIFT)
-#    define ADC_CCR_DUAL_IND         (0 << ADC_CCR_DUAL_SHIFT) /* Independent mode */
-#    define ADC_CCR_DUAL_DUAL        (1 << ADC_CCR_DUAL_SHIFT) /* Dual mode, master/slave ADCs together */
-#    define ADC_CCR_DUAL_SIMINJ      (1 << ADC_CCR_DUAL_SHIFT) /* Combined regular sim. + injected sim. */
-#    define ADC_CCR_DUAL_SIMALT      (2 << ADC_CCR_DUAL_SHIFT) /* Combined regular sim. + alternate trigger */
-#    define ADC_CCR_DUAL_INJECTED    (5 << ADC_CCR_DUAL_SHIFT) /* Injected simultaneous mode only */
-#    define ADC_CCR_DUAL_SIM         (6 << ADC_CCR_DUAL_SHIFT) /* Regular simultaneous mode only */
-#    define ADC_CCR_DUAL_INTERLEAVE  (7 << ADC_CCR_DUAL_SHIFT) /* Interleaved mode only */
-#    define ADC_CCR_DUAL_ALT         (9 << ADC_CCR_DUAL_SHIFT) /* Alternate trigger mode only */
-#  define ADC_CCR_DELAY_SHIFT        (8)       /* Bits 8-11: Delay between 2 sampling phases */
+#    define ADC_CCR_DUAL_IND         (0 << ADC_CCR_DUAL_SHIFT)   /* Independent mode */
+#    define ADC_CCR_DUAL_DUAL        (1 << ADC_CCR_DUAL_SHIFT)   /* Dual mode, master/slave ADCs together */
+#    define ADC_CCR_DUAL_SIMINJ      (1 << ADC_CCR_DUAL_SHIFT)   /* Combined regular sim. + injected sim. */
+#    define ADC_CCR_DUAL_SIMALT      (2 << ADC_CCR_DUAL_SHIFT)   /* Combined regular sim. + alternate trigger */
+#    define ADC_CCR_DUAL_INJECTED    (5 << ADC_CCR_DUAL_SHIFT)   /* Injected simultaneous mode only */
+#    define ADC_CCR_DUAL_SIM         (6 << ADC_CCR_DUAL_SHIFT)   /* Regular simultaneous mode only */
+#    define ADC_CCR_DUAL_INTERLEAVE  (7 << ADC_CCR_DUAL_SHIFT)   /* Interleaved mode only */
+#    define ADC_CCR_DUAL_ALT         (9 << ADC_CCR_DUAL_SHIFT)   /* Alternate trigger mode only */
+#  define ADC_CCR_DELAY_SHIFT        (8)                         /* Bits 8-11: Delay between 2 sampling phases */
 #  define ADC_CCR_DELAY_MASK         (15 << ADC_CCR_DELAY_SHIFT)
-#    define ADC_CCR_DELAY(n)         (((n)-1) << ADC_CCR_DELAY_SHIFT) /* n * TADCCLK, 1-13 */
-#  define ADC_CCR_DMACFG             (1 << 13) /* Bit 13: DMA configuration (for dual ADC mode) */
-#  define ADC_CCR_MDMA_SHIFT         (14)      /* Bits 14-15: Direct memory access mode for dual ADC mode */
+#    define ADC_CCR_DELAY(n)         (((n)-1) << ADC_CCR_DELAY_SHIFT) 
+                                                                 /* n * TADCCLK, 1-13 */
+#  define ADC_CCR_DMACFG             (1 << 13)                   /* Bit 13: DMA configuration (for dual ADC mode) */
+#  define ADC_CCR_MDMA_SHIFT         (14)                        /* Bits 14-15: Direct memory access mode for dual ADC mode */
 #  define ADC_CCR_MDMA_MASK          (3 << ADC_CCR_MDMA_SHIFT)
-#    define ADC_CCR_MDMA_DISABLE     (0 << ADC_CCR_MDMA_SHIFT) /* MDMA mode disabled */
-#    define ADC_CCR_MDMA_10_12       (2 << ADC_CCR_MDMA_SHIFT) /* MDMA mode enabled (12 / 10-bit) */
-#    define ADC_CCR_MDMA_6_8         (3 << ADC_CCR_MDMA_SHIFT) /* MDMA mode enabled (8 / 6-bit) */
+#    define ADC_CCR_MDMA_DISABLE     (0 << ADC_CCR_MDMA_SHIFT)   /* MDMA mode disabled */
+#    define ADC_CCR_MDMA_10_12       (2 << ADC_CCR_MDMA_SHIFT)   /* MDMA mode enabled (12 / 10-bit) */
+#    define ADC_CCR_MDMA_6_8         (3 << ADC_CCR_MDMA_SHIFT)   /* MDMA mode enabled (8 / 6-bit) */
 #endif
-#define ADC_CCR_CKMODE_SHIFT         (16)      /* Bits 16-17: ADC clock mode */
+#define ADC_CCR_CKMODE_SHIFT         (16)                        /* Bits 16-17: ADC clock mode */
 #define ADC_CCR_CKMODE_MASK          (3 << ADC_CCR_CKMODE_SHIFT)
 #  define ADC_CCR_CKMODE_ASYCH       (0 << ADC_CCR_CKMODE_SHIFT) /* Asynchronous clock mode */
 #  define ADC_CCR_CKMODE_SYNCH_DIV1  (1 << ADC_CCR_CKMODE_SHIFT) /* Synchronous clock mode divided by 1 */
 #  define ADC_CCR_CKMODE_SYNCH_DIV2  (2 << ADC_CCR_CKMODE_SHIFT) /* Synchronous clock mode divided by 2 */
 #  define ADC_CCR_CKMODE_SYNCH_DIV4  (3 << ADC_CCR_CKMODE_SHIFT) /* Synchronous clock mode divided by 4 */
-#define ADC_CCR_PRESC_SHIFT          (18)      /* Bits 18-21: ADC prescaler */
+#define ADC_CCR_PRESC_SHIFT          (18)                        /* Bits 18-21: ADC prescaler */
 #define ADC_CCR_PRESC_MASK           (3 << ADC_CCR_PRESC_SHIFT)
 #  define ADC_CCR_PRESC_NOT_DIV      (0 << ADC_CCR_PRESC_SHIFT)  /* Input ADC clock not divided */
 #  define ADC_CCR_PRESC_DIV2         (1 << ADC_CCR_PRESC_SHIFT)  /* Input ADC clock divided by 2 */
@@ -581,9 +606,9 @@
 #  define ADC_CCR_PRESC_DIV64        (9 << ADC_CCR_PRESC_SHIFT)  /* Input ADC clock divided by 64 */
 #  define ADC_CCR_PRESC_DIV128       (10 << ADC_CCR_PRESC_SHIFT) /* Input ADC clock divided by 128 */
 #  define ADC_CCR_PRESC_DIV256       (11 << ADC_CCR_PRESC_SHIFT) /* Input ADC clock divided by 256 */
-#define ADC_CCR_VREFEN               (1 << 22) /* Bit 22: VREFINT enable */
-#define ADC_CCR_TSEN                 (1 << 23) /* Bit 23: Temperature sensor enable */
-#define ADC_CCR_VBATEN               (1 << 24) /* Bit 22: VBAT enable */
+#define ADC_CCR_VREFEN               (1 << 22)                   /* Bit 22: VREFINT enable */
+#define ADC_CCR_TSEN                 (1 << 23)                   /* Bit 23: Temperature sensor enable */
+#define ADC_CCR_VBATEN               (1 << 24)                   /* Bit 22: VBAT enable */
 
 /* Common regular data register for dual mode */
 
diff --git a/arch/arm/src/stm32l4/stm32l4_adc.c b/arch/arm/src/stm32l4/stm32l4_adc.c
index c777ed2..522dab6 100644
--- a/arch/arm/src/stm32l4/stm32l4_adc.c
+++ b/arch/arm/src/stm32l4/stm32l4_adc.c
@@ -155,48 +155,14 @@
 #define ADC_EXTERNAL_CHAN_MIN  1
 #define ADC_EXTERNAL_CHAN_MAX  16
 
-/* ADCx_EXTSEL_VALUE can be set by this driver (look at stm32l4_adc.h) or
- * by board specific logic in board.h file.
- */
-
-#define ADC_EXTREG_EXTSEL_MASK       ADC_CFGR_EXTSEL_MASK
-#define ADC_EXTREG_EXTEN_MASK        ADC_CFGR_EXTEN_MASK
-#define ADC_EXTREG_EXTEN_DEFAULT     ADC_CFGR_EXTEN_RISING
-
-#ifdef ADC1_EXTSEL_VALUE
-#  define ADC1_HAVE_EXTCFG  1
-#  define ADC1_EXTCFG_VALUE (ADC1_EXTSEL_VALUE | ADC_EXTREG_EXTEN_DEFAULT)
-#else
-#  undef ADC1_HAVE_EXTCFG
-#endif
-#ifdef ADC2_EXTSEL_VALUE
-#  define ADC2_HAVE_EXTCFG  1
-#  define ADC2_EXTCFG_VALUE (ADC2_EXTSEL_VALUE | ADC_EXTREG_EXTEN_DEFAULT)
-#else
-#  undef ADC2_HAVE_EXTCFG
-#endif
-#ifdef ADC3_EXTSEL_VALUE
-#  define ADC3_HAVE_EXTCFG  1
-#  define ADC3_EXTCFG_VALUE (ADC3_EXTSEL_VALUE | ADC_EXTREG_EXTEN_DEFAULT)
-#else
-#  undef ADC3_HAVE_EXTCFG
-#endif
-#ifdef ADC4_EXTSEL_VALUE
-#  define ADC4_HAVE_EXTCFG  1
-#  define ADC4_EXTCFG_VALUE (ADC4_EXTSEL_VALUE | ADC_EXTREG_EXTEN_DEFAULT)
-#else
-#  undef ADC4_HAVE_EXTCFG
-#endif
-
-#if defined(ADC1_HAVE_EXTCFG) || defined(ADC2_HAVE_EXTCFG) || \
-    defined(ADC3_HAVE_EXTCFG) || defined(ADC3_HAVE_EXTCFG)
-#  define ADC_HAVE_EXTCFG
-#endif
-
 /* ADC resolution supported */
 
 #define HAVE_ADC_RESOLUTION
 
+/* Max 4 injected channels */
+
+#define ADC_INJ_MAX_SAMPLES   4
+
 /*****************************************************************************
  * Private Types
  *****************************************************************************/
@@ -212,8 +178,11 @@ struct stm32_dev_s
   FAR const struct adc_callback_s *cb;
   uint8_t irq;          /* Interrupt generated by this ADC block */
 #endif
-  uint8_t nchannels;    /* Number of channels */
-  uint8_t cchannels;    /* Number of configured channels */
+  uint8_t nchannels;    /* Number of regular channels */
+  uint8_t cchannels;    /* Number of configured regular channels */
+#ifdef ADC_HAVE_INJECTED
+  uint8_t cjchannels;   /* Number of configured injected channels */
+#endif
   uint8_t intf;         /* ADC interface number */
   uint8_t current;      /* Current ADC channel being converted */
 #ifdef HAVE_ADC_RESOLUTION
@@ -228,15 +197,17 @@ struct stm32_dev_s
   bool    hasdfsdm;     /* True: This ADC routes its output to DFSDM */
 #endif
 #ifdef ADC_HAVE_TIMER
-  uint8_t trigger;      /* Timer trigger channel: 0=CC1, 1=CC2, 2=CC3,
-                         * 3=CC4, 4=TRGO, 5=TRGO2 */
+  uint8_t channel;      /* Timer channel: 1=CC1, 2=CC2, 3=CC3, 4=CC4 */
 #endif
   xcpt_t   isr;         /* Interrupt handler for this ADC block */
   uint32_t base;        /* Base address of registers unique to this ADC
                          * block */
-#if defined(ADC_HAVE_TIMER) || defined(ADC_HAVE_EXTCFG)
+#ifdef ADC_HAVE_EXTCFG
   uint32_t extcfg;      /* External event configuration for regular group */
 #endif
+#ifdef ADC_HAVE_JEXTCFG
+  uint32_t jextcfg;     /* External event configuration for injected group */
+#endif
 #ifdef ADC_HAVE_TIMER
   uint32_t tbase;       /* Base address of timer used by this ADC block */
   uint32_t pclck;       /* The PCLK frequency that drives this timer */
@@ -258,6 +229,12 @@ struct stm32_dev_s
   /* List of selected ADC channels to sample */
 
   uint8_t  chanlist[ADC_MAX_SAMPLES];
+
+#ifdef ADC_HAVE_INJECTED
+  /* List of selected ADC injected channels to sample */
+
+  uint8_t  jchanlist[ADC_INJ_MAX_SAMPLES];
+#endif
 };
 
 /*****************************************************************************
@@ -292,6 +269,9 @@ static void     adc_enable(FAR struct stm32_dev_s *priv);
 static uint32_t adc_sqrbits(FAR struct stm32_dev_s *priv, int first,
                             int last, int offset);
 static int      adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch);
+#ifdef ADC_HAVE_INJECTED
+static int      adc_inj_set_ch(FAR struct adc_dev_s *dev, uint8_t ch);
+#endif
 static bool     adc_internal(FAR struct stm32_dev_s * priv,
                              uint32_t *adc_ccr);
 #ifdef HAVE_ADC_RESOLUTION
@@ -299,6 +279,9 @@ static int      adc_resolution_set(FAR struct adc_dev_s *dev, uint8_t res);
 #endif
 static void     adc_sample_time_set(FAR struct adc_dev_s *dev);
 static void     adc_startconv(FAR struct stm32_dev_s *priv, bool enable);
+#ifdef ADC_HAVE_INJECTED
+static void     adc_inj_startconv(FAR struct stm32_dev_s *priv, bool enable);
+#endif
 #ifdef ADC_HAVE_TIMER
 static void     adc_timstart(FAR struct stm32_dev_s *priv, bool enable);
 static int      adc_timinit(FAR struct stm32_dev_s *priv);
@@ -315,13 +298,19 @@ static void     adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr,
 static int      adc_offset_set(FAR struct stm32_dev_s *priv, uint8_t ch,
                                uint8_t i, uint16_t offset);
 #endif
-#if defined(ADC_HAVE_EXTCFG) || defined(CONFIG_STM32L4_ADC_LL_OPS)
+#ifdef ADC_HAVE_EXTCFG
 static int      adc_extsel_set(FAR struct stm32_dev_s *priv, uint32_t extcfg);
 #endif
+#ifdef ADC_HAVE_JEXTCFG
+static int      adc_jextsel_set(FAR struct stm32_dev_s *priv,
+                                uint32_t jextcfg);
+#endif
+
 #ifdef CONFIG_PM
 static int      adc_pm_prepare(struct pm_callback_s *cb, int domain,
                           enum pm_state_e state);
 #endif
+
 #ifdef CONFIG_STM32L4_ADC_LL_OPS
 static void     adc_llops_intack(FAR struct stm32_adc_dev_s *dev,
                                  uint32_t source);
@@ -339,9 +328,21 @@ static int      adc_llops_offset_set(FAR struct stm32_adc_dev_s *dev,
 static int      adc_regbufregister(FAR struct stm32_adc_dev_s *dev,
                                    uint16_t *buffer, uint8_t len);
 #  endif
+#  ifdef ADC_HAVE_EXTCFG
 static int      adc_llops_extsel_set(FAR struct stm32_adc_dev_s *dev,
-                                 uint32_t extcfg);
+                                     uint32_t extcfg);
+#  endif
+#  ifdef ADC_HAVE_JEXTCFG
+static void     adc_llops_jextsel_set(FAR struct stm32_adc_dev_s *dev,
+                                      uint32_t jextcfg);
+#  endif
 static void     adc_llops_dumpregs(FAR struct stm32_adc_dev_s *dev);
+#  ifdef ADC_HAVE_INJECTED
+static uint32_t adc_llops_injget(FAR struct stm32_adc_dev_s *dev,
+                                 uint8_t chan);
+static void     adc_llops_inj_startconv(FAR struct stm32_adc_dev_s *dev,
+                                        bool enable);
+#  endif
 #endif /* CONFIG_STM32L4_ADC_LL_OPS */
 
 /* ADC Interrupt Handler */
@@ -397,7 +398,16 @@ static const struct stm32_adc_ops_s g_adc_llops =
 #  ifdef ADC_HAVE_DMA
   .regbuf_reg    = adc_regbufregister,
 #  endif
+#  ifdef ADC_HAVE_INJECTED
+  .inj_get       = adc_llops_injget,
+  .inj_startconv = adc_llops_inj_startconv,
+#  endif
+#  ifdef ADC_HAVE_EXTCFG
   .extsel_set    = adc_llops_extsel_set,
+#  endif
+#  ifdef ADC_HAVE_JEXTCFG
+  .jextsel_set   = adc_llops_jextsel_set,
+#  endif
   .dump_regs     = adc_llops_dumpregs
 };
 #endif /* CONFIG_STM32L4_ADC_LL_OPS */
@@ -422,8 +432,11 @@ static struct stm32_dev_s g_adcpriv1 =
 #if defined(ADC1_HAVE_TIMER) || defined(ADC1_HAVE_EXTCFG)
   .extcfg      = ADC1_EXTCFG_VALUE,
 #endif
+#ifdef ADC1_HAVE_JEXTCFG
+  .jextcfg     = ADC1_JEXTCFG_VALUE,
+#endif
 #ifdef ADC1_HAVE_TIMER
-  .trigger     = CONFIG_STM32L4_ADC1_TIMTRIG,
+  .channel     = ADC1_TIMER_CHANNEL,
   .tbase       = ADC1_TIMER_BASE,
   .pclck       = ADC1_TIMER_PCLK_FREQUENCY,
   .freq        = CONFIG_STM32L4_ADC1_SAMPLE_FREQUENCY,
@@ -471,8 +484,11 @@ static struct stm32_dev_s g_adcpriv2 =
 #if defined(ADC2_HAVE_TIMER) || defined(ADC2_HAVE_EXTCFG)
   .extcfg      = ADC2_EXTCFG_VALUE,
 #endif
+#ifdef ADC2_HAVE_JEXTCFG
+  .jextcfg     = ADC2_JEXTCFG_VALUE,
+#endif
 #ifdef ADC2_HAVE_TIMER
-  .trigger     = CONFIG_STM32L4_ADC2_TIMTRIG,
+  .channel     = ADC2_TIMER_CHANNEL,
   .tbase       = ADC2_TIMER_BASE,
   .pclck       = ADC2_TIMER_PCLK_FREQUENCY,
   .freq        = CONFIG_STM32L4_ADC2_SAMPLE_FREQUENCY,
@@ -520,8 +536,11 @@ static struct stm32_dev_s g_adcpriv3 =
 #if defined(ADC3_HAVE_TIMER) || defined(ADC3_HAVE_EXTCFG)
   .extcfg      = ADC3_EXTCFG_VALUE,
 #endif
+#ifdef ADC3_HAVE_JEXTCFG
+  .jextcfg     = ADC3_JEXTCFG_VALUE,
+#endif
 #ifdef ADC3_HAVE_TIMER
-  .trigger     = CONFIG_STM32L4_ADC3_TIMTRIG,
+  .channel     = ADC3_TIMER_CHANNEL,
   .tbase       = ADC3_TIMER_BASE,
   .pclck       = ADC3_TIMER_PCLK_FREQUENCY,
   .freq        = CONFIG_STM32L4_ADC3_SAMPLE_FREQUENCY,
@@ -789,6 +808,7 @@ static void adc_timstart(FAR struct stm32_dev_s *priv, bool enable)
     {
       /* Start the counter */
 
+      tim_modifyreg(priv, STM32L4_GTIM_EGR_OFFSET, 0, GTIM_EGR_UG);
       tim_modifyreg(priv, STM32L4_GTIM_CR1_OFFSET, 0, GTIM_CR1_CEN);
     }
   else
@@ -824,14 +844,12 @@ static int adc_timinit(FAR struct stm32_dev_s *priv)
 
   uint16_t clrbits = 0;
   uint16_t setbits = 0;
-  uint16_t cr2;
-  uint16_t ccmr1;
-  uint16_t ccmr2;
-  uint16_t ocmode1;
-  uint16_t ocmode2;
-  uint16_t ccenable;
-  uint16_t ccer;
-  uint16_t egr;
+  uint16_t ccmr_orig   = 0;
+  uint16_t ccmr_val    = 0;
+  uint16_t ccmr_mask   = 0xff;
+  uint16_t ccer_val;
+  uint8_t  ccmr_offset = STM32L4_GTIM_CCMR1_OFFSET;
+  uint32_t channel = priv->channel - 1;
 
   /* If the timer base address is zero, then this ADC was not configured to
    * use a timer.
@@ -917,6 +935,10 @@ static int adc_timinit(FAR struct stm32_dev_s *priv)
   setbits = GTIM_CR1_EDGE;
   tim_modifyreg(priv, STM32L4_GTIM_CR1_OFFSET, clrbits, setbits);
 
+  /* Set the ARR Preload Bit */
+
+  tim_modifyreg(priv, STM32L4_GTIM_CR1_OFFSET, 0, GTIM_CR1_ARPE);
+
   /* Set the reload and prescaler values */
 
   tim_putreg(priv, STM32L4_GTIM_PSC_OFFSET, prescaler - 1);
@@ -930,186 +952,62 @@ static int adc_timinit(FAR struct stm32_dev_s *priv)
       tim_putreg(priv, STM32L4_ATIM_BDTR_OFFSET, ATIM_BDTR_MOE); /* Check me */
     }
 
-  /* TIMx event generation: Bit 0 UG: Update generation */
+  /* Handle channel specific setup */
 
-  tim_putreg(priv, STM32L4_GTIM_EGR_OFFSET, GTIM_EGR_UG);
+  /* Assume that channel is disabled and polarity is active high */
 
-  /* Handle channel specific setup */
+  ccer_val = tim_getreg(priv, STM32L4_GTIM_CCER_OFFSET);
+  ccer_val &= ~(3 << (channel << 2));
 
-  ocmode1 = 0;
-  ocmode2 = 0;
+  ccmr_val = (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) |
+             (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC1S_SHIFT) |
+              ATIM_CCMR1_OC1PE;
+  ccer_val |= ATIM_CCER_CC1E << (channel << 2);
 
-  switch (priv->trigger)
+  if (channel & 1)
     {
-      case 0: /* TimerX CC1 event */
-        {
-          ccenable = ATIM_CCER_CC1E;
-          ocmode1  = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC1S_SHIFT) |
-                     (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) |
-                     ATIM_CCMR1_OC1PE;
-
-          /* Set the event CC1 */
+      ccmr_val  <<= 8;
+      ccmr_mask <<= 8;
+    }
 
-          egr      = ATIM_EGR_CC1G;
+  if (channel > 1)
+    {
+      ccmr_offset = STM32L4_GTIM_CCMR2_OFFSET;
+    }
 
-          /* Set the duty cycle by writing to the CCR register for this
-           * channel
-           */
+  ccmr_orig  = tim_getreg(priv, ccmr_offset);
+  ccmr_orig &= ~ccmr_mask;
+  ccmr_orig |= ccmr_val;
+  tim_putreg(priv, ccmr_offset, ccmr_orig);
+  tim_putreg(priv, STM32L4_GTIM_CCER_OFFSET, ccer_val);
 
+  switch (channel)
+    {
+      case 0: /* TIMx CC1 */
+        {
           tim_putreg(priv, STM32L4_GTIM_CCR1_OFFSET, (uint16_t)(reload >> 1));
         }
         break;
 
-      case 1: /* TimerX CC2 event */
+      case 1: /* TIMx CC2 */
         {
-          ccenable = ATIM_CCER_CC2E;
-          ocmode1  = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC2S_SHIFT) |
-                     (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC2M_SHIFT) |
-                     ATIM_CCMR1_OC2PE;
-
-          /* Set the event CC2 */
-
-          egr      = ATIM_EGR_CC2G;
-
-          /* Set the duty cycle by writing to the CCR register for this
-           * channel
-           */
-
           tim_putreg(priv, STM32L4_GTIM_CCR2_OFFSET, (uint16_t)(reload >> 1));
         }
         break;
 
-      case 2: /* TimerX CC3 event */
+      case 2: /* TIMx CC3 */
         {
-          ccenable = ATIM_CCER_CC3E;
-          ocmode2  = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC3S_SHIFT) |
-                     (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR2_OC3M_SHIFT) |
-                     ATIM_CCMR2_OC3PE;
-
-          /* Set the event CC3 */
-
-          egr      = ATIM_EGR_CC3G;
-
-          /* Set the duty cycle by writing to the CCR register for this
-           * channel
-           */
-
           tim_putreg(priv, STM32L4_GTIM_CCR3_OFFSET, (uint16_t)(reload >> 1));
         }
         break;
 
-      case 3: /* TimerX CC4 event */
-        {
-          ccenable = ATIM_CCER_CC4E;
-          ocmode2  = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC4S_SHIFT) |
-                     (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR2_OC4M_SHIFT) |
-                     ATIM_CCMR2_OC4PE;
-
-          /* Set the event CC4 */
-
-          egr      = ATIM_EGR_CC4G;
-
-          /* Set the duty cycle by writing to the CCR register for this
-           * channel
-           */
-
-          tim_putreg(priv, STM32L4_GTIM_CCR4_OFFSET, (uint16_t)(reload >> 1));
-        }
-        break;
-
-      case 4: /* TimerX TRGO event */
+      case 3: /* TIMx CC4 */
         {
-          /* TODO: TRGO support not yet implemented */
-
-          /* Set the event TRGO */
-
-          ccenable = 0;
-          egr      = GTIM_EGR_TG;
-
-          /* Set the duty cycle by writing to the CCR register for this
-           * channel
-           */
-
           tim_putreg(priv, STM32L4_GTIM_CCR4_OFFSET, (uint16_t)(reload >> 1));
         }
         break;
-
-      default:
-        aerr("ERROR: No such trigger: %d\n", priv->trigger);
-        return -EINVAL;
-    }
-
-  /* Disable the Channel by resetting the CCxE Bit in the CCER register */
-
-  ccer = tim_getreg(priv, STM32L4_GTIM_CCER_OFFSET);
-  ccer &= ~ccenable;
-  tim_putreg(priv, STM32L4_GTIM_CCER_OFFSET, ccer);
-
-  /* Fetch the CR2, CCMR1, and CCMR2 register (already have ccer) */
-
-  cr2   = tim_getreg(priv, STM32L4_GTIM_CR2_OFFSET);
-  ccmr1 = tim_getreg(priv, STM32L4_GTIM_CCMR1_OFFSET);
-  ccmr2 = tim_getreg(priv, STM32L4_GTIM_CCMR2_OFFSET);
-
-  /* Reset the Output Compare Mode Bits and set the select output compare
-   * mode
-   */
-
-  ccmr1 &= ~(ATIM_CCMR1_CC1S_MASK | ATIM_CCMR1_OC1M_MASK | ATIM_CCMR1_OC1PE |
-             ATIM_CCMR1_CC2S_MASK | ATIM_CCMR1_OC2M_MASK | ATIM_CCMR1_OC2PE);
-  ccmr2 &= ~(ATIM_CCMR2_CC3S_MASK | ATIM_CCMR2_OC3M_MASK | ATIM_CCMR2_OC3PE |
-             ATIM_CCMR2_CC4S_MASK | ATIM_CCMR2_OC4M_MASK | ATIM_CCMR2_OC4PE);
-  ccmr1 |= ocmode1;
-  ccmr2 |= ocmode2;
-
-  /* Reset the output polarity level of all channels (selects high
-   * polarity)
-   */
-
-  ccer &= ~(ATIM_CCER_CC1P | ATIM_CCER_CC2P |
-            ATIM_CCER_CC3P | ATIM_CCER_CC4P);
-
-  /* Enable the output state of the selected channel (only) */
-
-  ccer &= ~(ATIM_CCER_CC1E | ATIM_CCER_CC2E |
-            ATIM_CCER_CC3E | ATIM_CCER_CC4E);
-  ccer |= ccenable;
-
-  if (priv->tbase == STM32L4_TIM1_BASE || priv->tbase == STM32L4_TIM8_BASE)
-    {
-      /* Reset output N polarity level, output N state, output compare state,
-       * output compare N idle state.
-       */
-
-      ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP |
-                ATIM_CCER_CC2NE | ATIM_CCER_CC2NP |
-                ATIM_CCER_CC3NE | ATIM_CCER_CC3NP |
-                ATIM_CCER_CC4NP);
-
-      /* Reset the output compare and output compare N IDLE State */
-
-      cr2 &= ~(ATIM_CR2_OIS1 | ATIM_CR2_OIS1N |
-               ATIM_CR2_OIS2 | ATIM_CR2_OIS2N |
-               ATIM_CR2_OIS3 | ATIM_CR2_OIS3N |
-               ATIM_CR2_OIS4);
-    }
-  else
-    {
-      ccer &= ~(GTIM_CCER_CC1NP | GTIM_CCER_CC2NP | GTIM_CCER_CC3NP);
     }
 
-  /* Save the modified register values */
-
-  tim_putreg(priv, STM32L4_GTIM_CR2_OFFSET, cr2);
-  tim_putreg(priv, STM32L4_GTIM_CCMR1_OFFSET, ccmr1);
-  tim_putreg(priv, STM32L4_GTIM_CCMR2_OFFSET, ccmr2);
-  tim_putreg(priv, STM32L4_GTIM_CCER_OFFSET, ccer);
-  tim_putreg(priv, STM32L4_GTIM_EGR_OFFSET, egr);
-
-  /* Set the ARR Preload Bit */
-
-  tim_modifyreg(priv, STM32L4_GTIM_CR1_OFFSET, 0, GTIM_CR1_ARPE);
-
   /* Enable the timer counter */
 
   adc_timstart(priv, true);
@@ -1210,6 +1108,55 @@ static void adc_startconv(FAR struct stm32_dev_s *priv, bool enable)
   adc_putreg(priv, STM32L4_ADC_CR_OFFSET, regval);
 }
 
+#ifdef ADC_HAVE_INJECTED
+
+/*****************************************************************************
+ * Name: adc_inj_startconv
+ *
+ * Description:
+ *   Start (or stop) the ADC injected conversion process
+ *
+ * Input Parameters:
+ *   priv - A reference to the ADC block status
+ *   enable - True: Start conversion
+ *
+ * Returned Value:
+ *
+ *****************************************************************************/
+
+static void adc_inj_startconv(FAR struct stm32_dev_s *priv, bool enable)
+{
+  uint32_t regval;
+
+  ainfo("inj enable: %d\n", enable ? 1 : 0);
+
+  if (enable)
+    {
+      /* Start the conversion of regular channels */
+
+      adc_modifyreg(priv, STM32L4_ADC_CR_OFFSET, 0, ADC_CR_JADSTART);
+    }
+  else
+    {
+      regval = adc_getreg(priv, STM32L4_ADC_CR_OFFSET);
+
+      /* Is a conversion ongoing? */
+
+      if ((regval & ADC_CR_JADSTART) != 0)
+        {
+          /* Stop the conversion */
+
+          adc_putreg(priv, STM32L4_ADC_CR_OFFSET, regval | ADC_CR_JADSTP);
+
+          /* Wait for the conversion to stop */
+
+          while ((adc_getreg(priv, STM32L4_ADC_CR_OFFSET) &
+                             ADC_CR_JADSTP) != 0);
+        }
+    }
+}
+#endif  /* ADC_HAVE_INJECTED */
+
 /*****************************************************************************
  * Name: adc_rccreset
  *
@@ -1429,7 +1376,19 @@ static int adc_setup(FAR struct adc_dev_s *dev)
 
   /* Configuration of the channel conversions */
 
-  adc_set_ch(dev, 0);
+  if (priv->cchannels > 0)
+    {
+      adc_set_ch(dev, 0);
+    }
+
+#ifdef ADC_HAVE_INJECTED
+  /* Configuration of the injected channel conversions */
+
+  if (priv->cjchannels > 0)
+    {
+      adc_inj_set_ch(dev, 0);
+    }
+#endif
 
   /* ADC CCR configuration */
 
@@ -1472,26 +1431,15 @@ static int adc_setup(FAR struct adc_dev_s *dev)
     }
 #endif
 
-  /* Set ADEN to wake up the ADC from Power Down. */
-
-  adc_enable(priv);
+#ifdef ADC_HAVE_JEXTCFG
+  /* Configure external event for injected group when ADC enabled */
 
-#ifdef ADC_HAVE_TIMER
-  if (priv->tbase != 0)
-    {
-      ret = adc_timinit(priv);
-      if (ret < 0)
-        {
-          aerr("ERROR: adc_timinit failed: %d\n", ret);
-        }
-    }
+  adc_jextsel_set(priv, priv->jextcfg);
 #endif
 
-  leave_critical_section(flags);
-
-  /* Dump regs */
+  /* Set ADEN to wake up the ADC from Power Down. */
 
-  adc_dumpregs(priv);
+  adc_enable(priv);
 
 /* As default conversion is started here.
    *
@@ -1504,7 +1452,16 @@ static int adc_setup(FAR struct adc_dev_s *dev)
 #ifndef CONFIG_STM32L4_ADC_NO_STARTUP_CONV
   /* Start regular conversion */
 
-  adc_startconv(priv, true);
+  if (priv->cchannels > 0)
+    {
+      adc_startconv(priv, true);
+    }
+
+#  ifdef ADC_HAVE_INJECTED
+  /* Start injected conversion */
+
+  adc_inj_startconv(priv, true);
+#  endif
 #endif
 
   /* Enable the ADC interrupt */
@@ -1514,6 +1471,23 @@ static int adc_setup(FAR struct adc_dev_s *dev)
   up_enable_irq(priv->irq);
 #endif
 
+  /* Dump regs */
+
+  adc_dumpregs(priv);
+
+#ifdef ADC_HAVE_TIMER
+  if (priv->tbase != 0)
+    {
+      ret = adc_timinit(priv);
+      if (ret < 0)
+        {
+          aerr("ERROR: adc_timinit failed: %d\n", ret);
+        }
+    }
+#endif
+
+  leave_critical_section(flags);
+
   return ret;
 }
 
@@ -1570,7 +1544,16 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable)
     {
       /* Enable end of conversion interrupt */
 
-      regval |= ADC_INT_EOC;
+      if (priv->cchannels > 0)
+        {
+          regval |= ADC_INT_EOC;
+        }
+
+#ifdef ADC_HAVE_INJECTED
+      /* Enable end of sequence injected interrupt */
+
+      regval |= ADC_INT_JEOS;
+#endif
     }
   else
     {
@@ -1630,7 +1613,7 @@ static void adc_sample_time_set(FAR struct adc_dev_s *dev)
  * Name: adc_extsel_set
  *****************************************************************************/
 
-#if defined(ADC_HAVE_EXTCFG) || defined(CONFIG_STM32L4_ADC_LL_OPS)
+#ifdef ADC_HAVE_EXTCFG
 static int adc_extsel_set(FAR struct stm32_dev_s *priv, uint32_t extcfg)
 {
   uint32_t exten  = 0;
@@ -1640,8 +1623,8 @@ static int adc_extsel_set(FAR struct stm32_dev_s *priv, uint32_t extcfg)
 
   /* Get EXTEN and EXTSEL from input */
 
-  exten = (extcfg & ADC_EXTREG_EXTEN_MASK);
-  extsel = (extcfg & ADC_EXTREG_EXTSEL_MASK);
+  exten = (extcfg & ADC_CFGR_EXTEN_MASK);
+  extsel = (extcfg & ADC_CFGR_EXTSEL_MASK);
 
   /* EXTSEL selection: These bits select the external event used
    * to trigger the start of conversion of a regular group.  NOTE:
@@ -1654,7 +1637,7 @@ static int adc_extsel_set(FAR struct stm32_dev_s *priv, uint32_t extcfg)
   if (exten > 0)
     {
       setbits = (extsel | exten);
-      clrbits = (ADC_EXTREG_EXTEN_MASK | ADC_EXTREG_EXTSEL_MASK);
+      clrbits = (ADC_CFGR_EXTEN_MASK | ADC_CFGR_EXTSEL_MASK);
 
       ainfo("Initializing extsel = 0x%08x\n", extsel);
 
@@ -1668,6 +1651,47 @@ static int adc_extsel_set(FAR struct stm32_dev_s *priv, uint32_t extcfg)
 #endif
 
 /*****************************************************************************
+ * Name: adc_jextsel_set
+ *****************************************************************************/
+
+#if defined(ADC_HAVE_JEXTCFG)
+static int adc_jextsel_set(FAR struct stm32_dev_s *priv, uint32_t jextcfg)
+{
+  uint32_t jexten =  0;
+  uint32_t jextsel = 0;
+  uint32_t setbits = 0;
+  uint32_t clrbits = 0;
+
+  /* Get JEXTEN and JEXTSEL from input */
+
+  jexten = (jextcfg & ADC_JSQR_JEXTEN_MASK);
+  jextsel = (jextcfg & ADC_JSQR_JEXTSEL_MASK);
+
+  /* JEXTSEL selection: These bits select the external event used
+   * to trigger the start of conversion of a injected group.  NOTE:
+   *
+   * - The position with of the JEXTSEL field varies from one STM32L4 MCU
+   *   to another.
+   * - The width of the JEXTSEL field varies from one STM32 MCU to another.
+   */
+
+  if (jexten > 0)
+    {
+      setbits = (jexten | jextsel);
+      clrbits = (ADC_JSQR_JEXTEN_MASK | ADC_JSQR_JEXTSEL_MASK);
+
+      ainfo("Initializing jextsel = 0x%08x\n", jextsel);
+
+      /* Write register */
+
+      adc_modifyreg(priv, STM32L4_ADC_JSQR_OFFSET, clrbits, setbits);
+    }
+
+  return OK;
+}
+#endif
+
+/*****************************************************************************
  * Name: adc_dumpregs
  *****************************************************************************/
 
@@ -1690,6 +1714,10 @@ static void adc_dumpregs(FAR struct stm32_dev_s *priv)
   ainfo("SMPR1: 0x%08x SMPR2: 0x%08x\n",
         adc_getreg(priv, STM32L4_ADC_SMPR1_OFFSET),
         adc_getreg(priv, STM32L4_ADC_SMPR2_OFFSET));
+
+#ifdef ADC_HAVE_INJECTED
+  ainfo("JSQR: 0x%08x\n", adc_getreg(priv, STM32L4_ADC_JSQR_OFFSET));
+#endif
 }
 
 /*****************************************************************************
@@ -1867,6 +1895,40 @@ static int adc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch)
   return OK;
 }
 
+#ifdef ADC_HAVE_INJECTED
+
+/*****************************************************************************
+ * Name: adc_inj_set_ch
+ *****************************************************************************/
+
+static int adc_inj_set_ch(FAR struct adc_dev_s *dev, uint8_t ch)
+{
+  FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
+  uint32_t clrbits;
+  uint32_t setbits;
+  int i;
+
+  /* Configure injected sequence length */
+
+  setbits = ADC_JSQR_JL(priv->cjchannels);
+  clrbits = ADC_JSQR_JEXTSEL_MASK | ADC_JSQR_JL_MASK;
+
+  /* Configure injected channels */
+
+  for (i = 0 ; i < priv->cjchannels; i += 1)
+    {
+      setbits |= priv->jchanlist[i] << (ADC_JSQR_JSQ1_SHIFT +
+                                        ADC_JSQR_JSQ_SHIFT * i);
+    }
+
+  /* Write register */
+
+  adc_modifyreg(priv, STM32L4_ADC_JSQR_OFFSET, clrbits, setbits);
+
+  return OK;
+}
+#endif /* ADC_HAVE_INJECTED */
+
 /*****************************************************************************
  * Name: adc_ioctl
  *
@@ -1892,7 +1954,23 @@ static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg)
   switch (cmd)
     {
       case ANIOC_TRIGGER:
-        adc_startconv(priv, true);
+        {
+          /* Start regular conversion if regular channels configured */
+
+          if (priv->cchannels > 0)
+            {
+              adc_startconv(priv, true);
+            }
+
+#ifdef ADC_HAVE_INJECTED
+          /* Start injected conversion if injected channels configured */
+
+          if (priv->cjchannels > 0)
+            {
+              adc_inj_startconv(priv, true);
+            }
+#endif
+        }
         break;
 
       case ANIOC_WDOG_UPPER: /* Set watchdog upper threshold */
@@ -1945,6 +2023,30 @@ static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg)
         }
         break;
 
+      case ANIOC_STM32L4_TRIGGER_REG:
+
+        /* Start regular conversion if regular channels configured */
+
+        if (priv->cchannels > 0)
+          {
+            adc_startconv(priv, true);
+          }
+
+        break;
+
+#ifdef ADC_HAVE_INJECTED
+      case ANIOC_STM32L4_TRIGGER_INJ:
+
+        /* Start injected conversion if injected channels configured */
+
+        if (priv->cjchannels > 0)
+          {
+            adc_inj_startconv(priv, true);
+          }
+
+        break;
+#endif
+
       default:
         aerr("ERROR: Unknown cmd: %d\n", cmd);
         ret = -ENOTTY;
@@ -1972,6 +2074,9 @@ static int adc_interrupt(FAR struct adc_dev_s *dev, uint32_t adcisr)
 {
   FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
   int32_t value;
+#ifdef ADC_HAVE_INJECTED
+  int32_t i;
+#endif
 
   /* Identifies the interruption AWD or OVR */
 
@@ -2034,6 +2139,25 @@ static int adc_interrupt(FAR struct adc_dev_s *dev, uint32_t adcisr)
         }
     }
 
+  /* JEOS: Injected end of sequence */
+
+#ifdef ADC_HAVE_INJECTED
+  if ((adcisr & ADC_INT_JEOS) != 0)
+    {
+      for (i = 0; i < priv->cjchannels; i++)
+        {
+          value = adc_getreg(priv, STM32L4_ADC_JDR1_OFFSET + (4 * i)) &
+                    ADC_JDR_MASK;
+
+          if (priv->cb != NULL)
+            {
+              DEBUGASSERT(priv->cb->au_receive != NULL);
+              priv->cb->au_receive(dev, priv->jchanlist[i], value);
+            }
+        }
+    }
+#endif
+
   return OK;
 }
 
@@ -2341,6 +2465,20 @@ static int  adc_llops_offset_set(FAR struct stm32_adc_dev_s *dev, uint8_t ch,
 }
 
 /*****************************************************************************
+ * Name: adc_llops_jextsel_set
+ *****************************************************************************/
+
+#ifdef ADC_HAVE_JEXTCFG
+static void  adc_llops_jextsel_set(FAR struct stm32_adc_dev_s *dev,
+                                   uint32_t jextcfg)
+{
+  FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev;
+
+  adc_jextsel_set(priv, jextcfg);
+}
+#endif
+
+/*****************************************************************************
  * Name: adc_regbufregister
  *****************************************************************************/
 
@@ -2368,6 +2506,7 @@ static int adc_regbufregister(FAR struct stm32_adc_dev_s *dev,
  * Name: adc_llops_extsel_set
  *****************************************************************************/
 
+#ifdef ADC_HAVE_EXTCFG
 static int  adc_llops_extsel_set(FAR struct stm32_adc_dev_s *dev,
                                  uint32_t extcfg)
 {
@@ -2377,6 +2516,46 @@ static int  adc_llops_extsel_set(FAR struct stm32_adc_dev_s *dev,
 
   return ret;
 }
+#endif
+
+/*****************************************************************************
+ * Name: adc_llops_injget
+ *****************************************************************************/
+
+#ifdef ADC_HAVE_INJECTED
+static uint32_t adc_llops_injget(FAR struct stm32_adc_dev_s *dev,
+                                 uint8_t chan)
+{
+  FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev;
+  uint32_t regval = 0;
+
+  if (chan > priv->cjchannels - 1)
+    {
+      /* REVISIT: return valute with MSB set to indicate error ? */
+
+      goto errout;
+    }
+
+  regval = adc_getreg(priv, STM32L4_ADC_JDR1_OFFSET + (4 * chan)) &
+                      ADC_JDR_MASK;
+
+errout:
+  return regval;
+}
+
+/*****************************************************************************
+ * Name: adc_llops_inj_startconv
+ *****************************************************************************/
+
+static void adc_llops_inj_startconv(FAR struct stm32_adc_dev_s *dev,
+                                    bool enable)
+{
+  FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev;
+
+  adc_inj_startconv(priv, enable);
+}
+
+#endif  /* ADC_HAVE_INJECTED */
 
 /*****************************************************************************
  * Name: adc_llops_dumpregs
@@ -2401,20 +2580,42 @@ static void adc_llops_dumpregs(FAR struct stm32_adc_dev_s *dev)
  * Description:
  *   Initialize the ADC.
  *
- *   The logic is, save nchannels : # of channels (conversions) in ADC_SQR1_L
- *   Then, take the chanlist array and store it in the SQR Regs,
- *     chanlist[0] -> ADC_SQR3_SQ1
- *     chanlist[1] -> ADC_SQR3_SQ2
+ *   The logic allow initialize ADC regular and injected channels.
+ *
+ *   The number of injected channels for given ADC is selected from Kconfig
+ *   with CONFIG_STM32L4_ADCx_INJECTED_CHAN definitions
+ *
+ *   The number of regular channels is obtained from the equation:
+ *
+ *     cr_channels = channels - cj_channels
+ *
+ *   where:
+ *     cr_channels - regular channels
+ *     cj_channels - injected channels
+ *     channels    - this function parameter
+ *
+ *   The chanlist array store both regular channels and injected channels
+ *   configuration so that regular channels are the first in order:
+ *
+ *     # regular channels start from here
+ *     chanlist[0]                  -> ADC_SQRx_SQ1
+ *     chanlist[1]                  -> ADC_SQRx_SQ2
  *     ...
- *     chanlist[15]-> ADC_SQR1_SQ16
+ *     # injected channels start from here
+ *     chanlist[channels - (y - 1)] -> ADC_JSQR_JSQ1
+ *     ...
+ *     chanlist[channels]           -> ADC_JSQR_ISQy
+ *
+ *   where:
+ *      y = CONFIG_STM32L4_ADCx_INJECTED_CHAN, and y > 0
  *
- *   up to
- *     chanlist[nchannels]
+ *   If CONFIG_STM32L4_ADCx_INJECTED_CHAN = 0, then all channels from chanlist
+ *   are regular channels.
  *
  * Input Parameters:
- *   intf      - Could be {1,2,3} for ADC1, ADC2, or ADC3
- *   chanlist  - The list of channels
- *   cchannels - Number of channels
+ *   intf      - Could be {1,2,3,4} for ADC1, ADC2, ADC3 or ADC4
+ *   chanlist  - The list of channels (regular + injected)
+ *   channels  - Number of channels (regular + injected)
  *
  * Returned Value:
  *   Valid ADC device structure reference on success; a NULL on failure
@@ -2426,28 +2627,70 @@ struct adc_dev_s *stm32l4_adc_initialize(int intf, FAR
 {
   FAR struct adc_dev_s   *dev;
   FAR struct stm32_dev_s *priv;
-
-  ainfo("intf: %d cchannels: %d\n", intf, cchannels);
+  uint8_t                crchannels = 0;
+  uint8_t                cjchannels = 0;
+#ifdef ADC_HAVE_INJECTED
+  FAR uint8_t            *jchanlist = NULL;
+#endif
 
   switch (intf)
     {
 #ifdef CONFIG_STM32L4_ADC1
       case 1:
-        ainfo("ADC1 selected\n");
-        dev = &g_adcdev1;
-        break;
+        {
+          ainfo("ADC1 selected\n");
+          cjchannels = CONFIG_STM32L4_ADC1_INJ_CHAN;
+          crchannels = cchannels - cjchannels;
+          ainfo("  Reg. chan: %d Inj chan: %d\n", crchannels, cjchannels);
+#  ifdef ADC_HAVE_INJECTED
+          if (cjchannels > 0)
+            {
+              jchanlist  = (FAR uint8_t *)chanlist + crchannels;
+            }
+
+#  endif
+          dev = &g_adcdev1;
+        }
+
+      break;
 #endif
 #ifdef CONFIG_STM32L4_ADC2
       case 2:
-        ainfo("ADC2 selected\n");
-        dev = &g_adcdev2;
-        break;
+        {
+          ainfo("ADC2 selected\n");
+          cjchannels = CONFIG_STM32L4_ADC2_INJ_CHAN;
+          crchannels = cchannels - cjchannels;
+          ainfo("  Reg. chan: %d Inj chan: %d\n", crchannels, cjchannels);
+#  ifdef ADC_HAVE_INJECTED
+          if (cjchannels > 0)
+            {
+              jchanlist  = (FAR uint8_t *)chanlist + crchannels;
+            }
+
+#  endif
+          dev = &g_adcdev2;
+        }
+
+      break;
 #endif
 #ifdef CONFIG_STM32L4_ADC3
       case 3:
-        ainfo("ADC3 selected\n");
-        dev = &g_adcdev3;
-        break;
+        {
+          ainfo("ADC3 selected\n");
+          cjchannels = CONFIG_STM32L4_ADC3_INJ_CHAN;
+          crchannels = cchannels - cjchannels;
+          ainfo("  Reg. chan: %d Inj chan: %d\n", crchannels, cjchannels);
+#  ifdef ADC_HAVE_INJECTED
+          if (cjchannels > 0)
+            {
+              jchanlist  = (FAR uint8_t *)chanlist + crchannels;
+            }
+
+#  endif
+          dev = &g_adcdev3;
+        }
+
+      break;
 #endif
       default:
         aerr("ERROR: No ADC interface defined\n");
@@ -2458,18 +2701,28 @@ struct adc_dev_s *stm32l4_adc_initialize(int intf, FAR
 
   priv = (FAR struct stm32_dev_s *)dev->ad_priv;
 
-#ifndef CONFIG_STM32L4_ADC_NOIRQ
-  priv->cb = NULL;
-#endif
-
-  DEBUGASSERT(cchannels <= ADC_MAX_SAMPLES);
-  if (cchannels > ADC_MAX_SAMPLES)
+  DEBUGASSERT(crchannels <= ADC_MAX_SAMPLES);
+  if (crchannels > ADC_MAX_SAMPLES)
     {
-      cchannels = ADC_MAX_SAMPLES;
+      crchannels = ADC_MAX_SAMPLES;
     }
 
-  priv->cchannels = cchannels;
-  memcpy(priv->chanlist, chanlist, cchannels);
+  priv->cchannels = crchannels;
+  memcpy(priv->chanlist, chanlist, crchannels);
+
+#ifdef ADC_HAVE_INJECTED
+  /* Configure injected channels */
+
+  DEBUGASSERT(cjchannels <= ADC_INJ_MAX_SAMPLES);
+
+  priv->cjchannels = cjchannels;
+  memcpy(priv->jchanlist, jchanlist, cjchannels);
+
+#endif
+
+#ifndef CONFIG_STM32L4_ADC_NOIRQ
+  priv->cb = NULL;
+#endif
 
 #ifdef CONFIG_PM
   if (pm_register(&priv->pm_callback) != OK)
diff --git a/arch/arm/src/stm32l4/stm32l4_adc.h b/arch/arm/src/stm32l4/stm32l4_adc.h
index eecc455..61d66a8 100644
--- a/arch/arm/src/stm32l4/stm32l4_adc.h
+++ b/arch/arm/src/stm32l4/stm32l4_adc.h
@@ -161,6 +161,14 @@
 #  undef  ADC3_HAVE_DMA
 #endif
 
+/* Injected channels support */
+
+#if (defined(CONFIG_STM32L4_ADC1) && (CONFIG_STM32L4_ADC1_INJ_CHAN > 0)) || \
+    (defined(CONFIG_STM32L4_ADC2) && (CONFIG_STM32L4_ADC2_INJ_CHAN > 0)) || \
+    (defined(CONFIG_STM32L4_ADC3) && (CONFIG_STM32L4_ADC3_INJ_CHAN > 0))
+#  define ADC_HAVE_INJECTED
+#endif
+
 /* Timer configuration:  If a timer trigger is specified, then get
  * information about the timer.
  */
@@ -169,30 +177,37 @@
 #    define ADC1_HAVE_TIMER           1
 #    define ADC1_TIMER_BASE           STM32L4_TIM1_BASE
 #    define ADC1_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM1_CLKIN
+#    define ADC1_TIMER_CHANNEL        CONFIG_STM32L4_TIM1_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM2_ADC1)
 #    define ADC1_HAVE_TIMER           1
 #    define ADC1_TIMER_BASE           STM32L4_TIM2_BASE
 #    define ADC1_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM2_CLKIN
+#    define ADC1_TIMER_CHANNEL        CONFIG_STM32L4_TIM2_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM3_ADC1)
 #    define ADC1_HAVE_TIMER           1
 #    define ADC1_TIMER_BASE           STM32L4_TIM3_BASE
 #    define ADC1_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM3_CLKIN
+#    define ADC1_TIMER_CHANNEL        CONFIG_STM32L4_TIM3_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM4_ADC1)
 #    define ADC1_HAVE_TIMER           1
 #    define ADC1_TIMER_BASE           STM32L4_TIM4_BASE
 #    define ADC1_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM4_CLKIN
+#    define ADC1_TIMER_CHANNEL        CONFIG_STM32L4_TIM4_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM6_ADC1)
 #    define ADC1_HAVE_TIMER           1
 #    define ADC1_TIMER_BASE           STM32L4_TIM6_BASE
 #    define ADC1_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM6_CLKIN
+#    define ADC1_TIMER_CHANNEL        CONFIG_STM32L4_TIM6_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM8_ADC1)
 #    define ADC1_HAVE_TIMER           1
 #    define ADC1_TIMER_BASE           STM32L4_TIM8_BASE
 #    define ADC1_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM8_CLKIN
+#    define ADC1_TIMER_CHANNEL        CONFIG_STM32L4_TIM8_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM15_ADC1)
 #    define ADC1_HAVE_TIMER           1
 #    define ADC1_TIMER_BASE           STM32L4_TIM15_BASE
 #    define ADC1_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM15_CLKIN
+#    define ADC1_TIMER_CHANNEL        CONFIG_STM32L4_TIM15_ADC_CHAN
 #else
 #    undef  ADC1_HAVE_TIMER
 #endif
@@ -211,30 +226,37 @@
 #    define ADC2_HAVE_TIMER           1
 #    define ADC2_TIMER_BASE           STM32L4_TIM1_BASE
 #    define ADC2_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM1_CLKIN
+#    define ADC2_TIMER_CHANNEL        CONFIG_STM32L4_TIM1_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM2_ADC2)
 #    define ADC2_HAVE_TIMER           1
 #    define ADC2_TIMER_BASE           STM32L4_TIM2_BASE
 #    define ADC2_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM2_CLKIN
+#    define ADC2_TIMER_CHANNEL        CONFIG_STM32L4_TIM2_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM3_ADC2)
 #    define ADC2_HAVE_TIMER           1
 #    define ADC2_TIMER_BASE           STM32L4_TIM3_BASE
 #    define ADC2_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM3_CLKIN
+#    define ADC2_TIMER_CHANNEL        CONFIG_STM32L4_TIM3_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM4_ADC2)
 #    define ADC2_HAVE_TIMER           1
 #    define ADC2_TIMER_BASE           STM32L4_TIM4_BASE
 #    define ADC2_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM4_CLKIN
+#    define ADC2_TIMER_CHANNEL        CONFIG_STM32L4_TIM4_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM6_ADC2)
 #    define ADC2_HAVE_TIMER           1
 #    define ADC2_TIMER_BASE           STM32L4_TIM6_BASE
 #    define ADC2_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM6_CLKIN
+#    define ADC2_TIMER_CHANNEL        CONFIG_STM32L4_TIM6_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM8_ADC2)
 #    define ADC2_HAVE_TIMER           1
 #    define ADC2_TIMER_BASE           STM32L4_TIM8_BASE
 #    define ADC2_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM8_CLKIN
+#    define ADC2_TIMER_CHANNEL        CONFIG_STM32L4_TIM8_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM15_ADC2)
 #    define ADC2_HAVE_TIMER           1
 #    define ADC2_TIMER_BASE           STM32L4_TIM15_BASE
 #    define ADC2_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM15_CLKIN
+#    define ADC2_TIMER_CHANNEL        CONFIG_STM32L4_TIM15_ADC_CHAN
 #else
 #    undef  ADC2_HAVE_TIMER
 #endif
@@ -253,30 +275,37 @@
 #    define ADC3_HAVE_TIMER           1
 #    define ADC3_TIMER_BASE           STM32L4_TIM1_BASE
 #    define ADC3_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM1_CLKIN
+#    define ADC3_TIMER_CHANNEL        CONFIG_STM32L4_TIM1_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM2_ADC3)
 #    define ADC3_HAVE_TIMER           1
 #    define ADC3_TIMER_BASE           STM32L4_TIM2_BASE
 #    define ADC3_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM2_CLKIN
+#    define ADC3_TIMER_CHANNEL        CONFIG_STM32L4_TIM1_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM3_ADC3)
 #    define ADC3_HAVE_TIMER           1
 #    define ADC3_TIMER_BASE           STM32L4_TIM3_BASE
 #    define ADC3_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM3_CLKIN
+#    define ADC3_TIMER_CHANNEL        CONFIG_STM32L4_TIM3_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM4_ADC3)
 #    define ADC3_HAVE_TIMER           1
 #    define ADC3_TIMER_BASE           STM32L4_TIM4_BASE
 #    define ADC3_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM4_CLKIN
+#    define ADC3_TIMER_CHANNEL        CONFIG_STM32L4_TIM4_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM6_ADC3)
 #    define ADC3_HAVE_TIMER           1
 #    define ADC3_TIMER_BASE           STM32L4_TIM6_BASE
 #    define ADC3_TIMER_PCLK_FREQUENCY STM32L4_APB1_TIM6_CLKIN
+#    define ADC3_TIMER_CHANNEL        CONFIG_STM32L4_TIM6_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM8_ADC3)
 #    define ADC3_HAVE_TIMER           1
 #    define ADC3_TIMER_BASE           STM32L4_TIM8_BASE
 #    define ADC3_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM8_CLKIN
+#    define ADC3_TIMER_CHANNEL        CONFIG_STM32L4_TIM8_ADC_CHAN
 #elif defined(CONFIG_STM32L4_TIM15_ADC3)
 #    define ADC3_HAVE_TIMER           1
 #    define ADC3_TIMER_BASE           STM32L4_TIM15_BASE
 #    define ADC3_TIMER_PCLK_FREQUENCY STM32L4_APB2_TIM15_CLKIN
+#    define ADC3_TIMER_CHANNEL        CONFIG_STM32L4_TIM15_ADC_CHAN
 #else
 #    undef  ADC3_HAVE_TIMER
 #endif
@@ -426,7 +455,13 @@
 
 /* EXTSEL configuration ******************************************************/
 
-/* Configure external event for regular group */
+/* ADCx_EXTSEL_VALUE can be set by this driver or by board specific logic in
+ * board.h file.
+ */
+
+#ifndef ADC_EXTREG_EXTEN_DEFAULT
+#  define ADC_EXTREG_EXTEN_DEFAULT     ADC_CFGR_EXTEN_RISING
+#endif
 
 #if defined(CONFIG_STM32L4_TIM1_ADC1)
 #  if CONFIG_STM32L4_ADC1_TIMTRIG == 0
@@ -740,10 +775,306 @@
 #  endif
 #endif
 
+#ifdef ADC1_EXTSEL_VALUE
+#  define ADC1_HAVE_EXTCFG  1
+#  define ADC1_EXTCFG_VALUE (ADC1_EXTSEL_VALUE | ADC_EXTREG_EXTEN_DEFAULT)
+#else
+#  undef ADC1_HAVE_EXTCFG
+#endif
+#ifdef ADC2_EXTSEL_VALUE
+#  define ADC2_HAVE_EXTCFG  1
+#  define ADC2_EXTCFG_VALUE (ADC2_EXTSEL_VALUE | ADC_EXTREG_EXTEN_DEFAULT)
+#else
+#  undef ADC2_HAVE_EXTCFG
+#endif
+#ifdef ADC3_EXTSEL_VALUE
+#  define ADC3_HAVE_EXTCFG  1
+#  define ADC3_EXTCFG_VALUE (ADC3_EXTSEL_VALUE | ADC_EXTREG_EXTEN_DEFAULT)
+#else
+#  undef ADC3_HAVE_EXTCFG
+#endif
+
+#if defined(ADC1_HAVE_EXTCFG) || defined(ADC2_HAVE_EXTCFG) || \
+    defined(ADC3_HAVE_EXTCFG) || defined(ADC3_HAVE_EXTCFG)
+#  define ADC_HAVE_EXTCFG
+#endif
+
+/* JEXTSEL configuration *****************************************************/
+
+#ifndef ADC_JEXTREG_JEXTEN_DEFAULT
+#  define ADC_JEXTREG_JEXTEN_DEFAULT   ADC_JSQR_JEXTEN_RISING
+#endif
+
+#if (CONFIG_STM32L4_ADC1_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM1)
+#  if CONFIG_STM32L4_ADC1_JTIMTRIG == 3
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T1CC4
+#  elif CONFIG_STM32L4_ADC1_JTIMTRIG == 4
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T1TRGO
+#  elif CONFIG_STM32L4_ADC1_JTIMTRIG == 5
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T1TRGO2
+#  else
+#    error "CONFIG_STM32L4_ADC1_TIMTRIG is out of range"
+#  endif
+#endif
+
+#if (CONFIG_STM32L4_ADC1_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM2)
+#  if CONFIG_STM32L4_ADC1_JTIMTRIG == 0
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T2CC1
+#  elif CONFIG_STM32L4_ADC1_JTIMTRIG == 4
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T2TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC1_TIMTRIG is out of range"
+#  endif
+#endif
+
+#if (CONFIG_STM32L4_ADC1_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM3)
+#  if CONFIG_STM32L4_ADC1_JTIMTRIG == 0
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T3CC1
+#  elif CONFIG_STM32L4_ADC1_JTIMTRIG == 2
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T3CC3
+#  elif CONFIG_STM32L4_ADC1_JTIMTRIG == 3
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T3CC4
+#  elif CONFIG_STM32L4_ADC1_JTIMTRIG == 4
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T3TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC1_TIMTRIG is out of range"
+#  endif
+#endif
+
+#if (CONFIG_STM32L4_ADC1_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM4)
+#  if CONFIG_STM32L4_ADC1_JTIMTRIG == 4
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T4TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC1_TIMTRIG is out of range"
+#  endif
+#endif
+
+#if (CONFIG_STM32L4_ADC1_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM6)
+#  if CONFIG_STM32L4_ADC1_JTIMTRIG == 4
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T6TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC1_TIMTRIG is out of range"
+#  endif
+#endif
+
+#if (CONFIG_STM32L4_ADC1_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM8)
+#  if CONFIG_STM32L4_ADC1_JTIMTRIG == 3
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T8CC4
+#  elif CONFIG_STM32L4_ADC1_JTIMTRIG == 4
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T8TRGO
+#  elif CONFIG_STM32L4_ADC1_JTIMTRIG == 5
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T8TRGO2
+#  else
+#    error "CONFIG_STM32L4_ADC1_TIMTRIG is out of range"
+#  endif
+#endif
+
+#if (CONFIG_STM32L4_ADC1_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM15)
+#  if CONFIG_STM32L4_ADC1_JTIMTRIG == 4
+#    define ADC1_JEXTSEL_VALUE ADC_JEXTSEL_T15TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC1_TIMTRIG is out of range"
+#  endif
+#endif
+
+#ifdef ADC1_JEXTSEL_VALUE
+#  define ADC1_HAVE_JEXTCFG  1
+#  define ADC1_JEXTCFG_VALUE (ADC1_JEXTSEL_VALUE | ADC_JEXTREG_JEXTEN_DEFAULT)
+#endif
+
+#ifdef CONFIG_STM32L4_ADC2
+#if (CONFIG_STM32L4_ADC2_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM1)
+#  if CONFIG_STM32L4_ADC2_JTIMTRIG == 3
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T1CC4
+#  elif CONFIG_STM32L4_ADC2_JTIMTRIG == 4
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T1TRGO
+#  elif CONFIG_STM32L4_ADC2_JTIMTRIG == 5
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T1TRGO2
+#  else
+#    error "CONFIG_STM32L4_ADC2_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC2
+#if (CONFIG_STM32L4_ADC2_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM2)
+#  if CONFIG_STM32L4_ADC2_JTIMTRIG == 0
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T2CC1
+#  elif CONFIG_STM32L4_ADC2_JTIMTRIG == 4
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T2TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC2_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC2
+#if (CONFIG_STM32L4_ADC2_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM3)
+#  if CONFIG_STM32L4_ADC2_JTIMTRIG == 0
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T3CC1
+#  elif CONFIG_STM32L4_ADC2_JTIMTRIG == 2
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T3CC3
+#  elif CONFIG_STM32L4_ADC2_JTIMTRIG == 3
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T3CC4
+#  elif CONFIG_STM32L4_ADC2_JTIMTRIG == 4
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T3TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC2_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC2
+#if (CONFIG_STM32L4_ADC2_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM4)
+#  if CONFIG_STM32L4_ADC2_JTIMTRIG == 4
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T4TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC2_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC2
+#if (CONFIG_STM32L4_ADC2_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM6)
+#  if CONFIG_STM32L4_ADC2_JTIMTRIG == 4
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T6TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC2_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC2
+#if (CONFIG_STM32L4_ADC2_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM8)
+#  if CONFIG_STM32L4_ADC2_JTIMTRIG == 3
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T8CC4
+#  elif CONFIG_STM32L4_ADC2_JTIMTRIG == 4
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T8TRGO
+#  elif CONFIG_STM32L4_ADC2_JTIMTRIG == 5
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T8TRGO2
+#  else
+#    error "CONFIG_STM32L4_ADC2_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC2
+#if (CONFIG_STM32L4_ADC2_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM15)
+#  if CONFIG_STM32L4_ADC2_JTIMTRIG == 4
+#    define ADC2_JEXTSEL_VALUE ADC_JEXTSEL_T15TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC2_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef ADC2_JEXTSEL_VALUE
+#  define ADC2_HAVE_JEXTCFG  1
+#  define ADC2_JEXTCFG_VALUE (ADC2_JEXTSEL_VALUE | ADC_JEXTREG_JEXTEN_DEFAULT)
+#endif
+
+#ifdef CONFIG_STM32L4_ADC3
+#if (CONFIG_STM32L4_ADC3_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM1)
+#  if CONFIG_STM32L4_ADC3_JTIMTRIG == 3
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T1CC4
+#  elif CONFIG_STM32L4_ADC3_JTIMTRIG == 4
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T1TRGO
+#  elif CONFIG_STM32L4_ADC3_JTIMTRIG == 5
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T1TRGO2
+#  else
+#    error "CONFIG_STM32L4_ADC3_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC3
+#if (CONFIG_STM32L4_ADC3_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM2)
+#  if CONFIG_STM32L4_ADC3_JTIMTRIG == 0
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T2CC1
+#  elif CONFIG_STM32L4_ADC3_JTIMTRIG == 4
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T2TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC3_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC3
+#if (CONFIG_STM32L4_ADC3_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM3)
+#  if CONFIG_STM32L4_ADC3_JTIMTRIG == 0
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T3CC1
+#  elif CONFIG_STM32L4_ADC3_JTIMTRIG == 2
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T3CC3
+#  elif CONFIG_STM32L4_ADC3_JTIMTRIG == 3
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T3CC4
+#  elif CONFIG_STM32L4_ADC3_JTIMTRIG == 4
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T3TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC3_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC3
+#if (CONFIG_STM32L4_ADC3_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM4)
+#  if CONFIG_STM32L4_ADC3_JTIMTRIG == 4
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T4TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC3_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC3
+#if (CONFIG_STM32L4_ADC3_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM6)
+#  if CONFIG_STM32L4_ADC3_JTIMTRIG == 4
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T6TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC3_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC3
+#if (CONFIG_STM32L4_ADC3_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM8)
+#  if CONFIG_STM32L4_ADC3_JTIMTRIG == 3
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T8CC4
+#  elif CONFIG_STM32L4_ADC3_JTIMTRIG == 4
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T8TRGO
+#  elif CONFIG_STM32L4_ADC3_JTIMTRIG == 5
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T8TRGO2
+#  else
+#    error "CONFIG_STM32L4_ADC3_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_ADC3
+#if (CONFIG_STM32L4_ADC3_INJ_CHAN > 0) && defined(CONFIG_STM32L4_TIM15)
+#  if CONFIG_STM32L4_ADC3_JTIMTRIG == 4
+#    define ADC3_JEXTSEL_VALUE ADC_JEXTSEL_T15TRGO
+#  else
+#    error "CONFIG_STM32L4_ADC3_TIMTRIG is out of range"
+#  endif
+#endif
+#endif
+
+#ifdef ADC3_JEXTSEL_VALUE
+#  define ADC3_HAVE_JEXTCFG  1
+#  define ADC3_JEXTCFG_VALUE (ADC3_JEXTSEL_VALUE | ADC_JEXTREG_JEXTEN_DEFAULT)
+#endif
+
+#if defined(ADC1_HAVE_JEXTCFG) || defined(ADC2_HAVE_JEXTCFG) || \
+    defined(ADC3_HAVE_JEXTCFG)
+#  define ADC_HAVE_JEXTCFG
+#endif
+
 /* ADC interrupts ************************************************************/
 
 #define ADC_ISR_EOC                  ADC_INT_EOC
 #define ADC_IER_EOC                  ADC_INT_EOC
+#define ADC_ISR_EOS                  ADC_INT_EOS
+#define ADC_IER_EOS                  ADC_INT_EOS
 #define ADC_ISR_AWD                  ADC_INT_AWD1
 #define ADC_IER_AWD                  ADC_INT_AWD1
 #define ADC_ISR_JEOC                 ADC_INT_JEOC
@@ -753,10 +1084,10 @@
 #define ADC_ISR_JEOS                 ADC_INT_JEOS
 #define ADC_IER_JEOS                 ADC_INT_JEOS
 
-#define ADC_ISR_ALLINTS (ADC_ISR_EOC | ADC_ISR_AWD | ADC_ISR_JEOC | \
-                         ADC_ISR_JEOS | ADC_ISR_OVR)
-#define ADC_IER_ALLINTS (ADC_IER_EOC | ADC_IER_AWD | ADC_IER_JEOC | \
-                         ADC_IER_JEOS | ADC_IER_OVR)
+#define ADC_ISR_ALLINTS (ADC_ISR_EOC | ADC_ISR_EOS | ADC_ISR_AWD | \
+                         ADC_ISR_JEOC | ADC_ISR_JEOS | ADC_ISR_OVR)
+#define ADC_IER_ALLINTS (ADC_IER_EOC | ADC_IER_EOS | ADC_IER_AWD | \
+                         ADC_IER_JEOC | ADC_IER_JEOS | ADC_IER_OVR)
 
 /* Low-level ops helpers *****************************************************/
 
@@ -770,10 +1101,14 @@
         (adc)->llops->int_dis(adc, source)
 #define ADC_REGDATA_GET(adc)                         \
         (adc)->llops->val_get(adc)
+#define ADC_INJDATA_GET(adc, chan)                   \
+        (adc)->llops->inj_get(adc, chan)
 #define ADC_REGBUF_REGISTER(adc, buffer, len)        \
         (adc)->llops->regbuf_reg(adc, buffer, len)
 #define ADC_REG_STARTCONV(adc, state)                \
         (adc)->llops->reg_startconv(adc, state)
+#define ADC_INJ_STARTCONV(adc, state)         \
+        (adc)->llops->inj_startconv(adc, state)
 #define ADC_OFFSET_SET(adc, ch, i, o)                \
         (adc)->llops->offset_set(adc, ch, i, o)
 #define ADC_EXTSEL_SET(adc, extcfg)                  \
@@ -781,6 +1116,16 @@
 #define ADC_DUMP_REGS(adc)                           \
         (adc)->llops->dump_regs(adc)
 
+/* IOCTL Commands ************************************************************
+ *
+ * Cmd: ANIOC_STM32L4_TRIGGER_REG           Arg:
+ * Cmd: ANIOC_STM32L4_TRIGGER_INJ           Arg:
+ *
+ */
+
+#define ANIOC_STM32L4_TRIGGER_REG           _ANIOC(AN_STM32L4_FIRST + 0)
+#define ANIOC_STM32L4_TRIGGER_INJ           _ANIOC(AN_STM32L4_FIRST + 1)
+
 /*****************************************************************************
  * Public Types
  *****************************************************************************/
@@ -842,6 +1187,22 @@ struct stm32_adc_ops_s
 
   int (*extsel_set)(FAR struct stm32_adc_dev_s *dev, uint32_t extcfg);
 
+#ifdef ADC_HAVE_JEXTCFG
+  /* Configure the ADC external trigger for injected conversion */
+
+  void (*jextsel_set)(FAR struct stm32_adc_dev_s *dev, uint32_t jextcfg);
+#endif
+
+#ifdef ADC_HAVE_INJECTED
+  /* Get current ADC injected data register */
+
+  uint32_t (*inj_get)(FAR struct stm32_adc_dev_s *dev, uint8_t chan);
+
+  /* Start/stop injected conversion */
+
+  void (*inj_startconv)(FAR struct stm32_adc_dev_s *dev, bool state);
+#endif
+
   /* Dump ADC regs */
 
   void (*dump_regs)(FAR struct stm32_adc_dev_s *dev);
diff --git a/include/nuttx/analog/ioctl.h b/include/nuttx/analog/ioctl.h
index 92b1988..2527983 100644
--- a/include/nuttx/analog/ioctl.h
+++ b/include/nuttx/analog/ioctl.h
@@ -91,6 +91,11 @@
                           AN_LMP92001_NCMDS)
 #define AN_ADS7828_NCMDS 6
 
+/* See arch/arm/src/stm32l4/stm32l4_adc.h */
+
+#define AN_STM32L4_FIRST (AN_ADS7828_FIRST + AN_ADS7828_NCMDS)
+#define AN_STM32L4_NCMDS 2
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/