1 /*
2 * Copyright (c) 2024 STMicroelectronics
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * Terminology used in this file:
9 * - sampling: a single analog-to-digital conversion performed by the ADC
10 * - sequence: one or more sampling(s) performed one after the other by the
11 * ADC after a single programmation. This is the meaning used in the
12 * STM32WB0 ADC documentation.
13 * - round: all ADC operations needed to read all channels in the adc_sequence passed
14 * to adc_read. Zephyr calls this a "sampling", but we use the term "round" to
15 * prevent confusion with STM32 terminology. A single round may require multiple
16 * sequences to be performed by the ADC to be completed, due to hardware limitations.
17 *
18 * When Zephyr's "sequence" feature is used, the same round is repeated multiple times.
19 *
20 * - idle mode: clock & ADC configuration that minimizes power consumption
21 * - Only the ADC digital domain clock is turned on:
22 * - ADC is powered off (CTRL.ADC_CTRL_ADC_ON_OFF = 0)
23 * - ADC analog domain clock is turned off
24 * - If applicable:
25 * - ADC LDO is disabled
26 * - ADC I/O Booster clock is turned off
27 * - ADC I/O Booster is disabled
28 * - ADC-SMPS clock synchronization is disabled
29 */
30
31 #define DT_DRV_COMPAT st_stm32wb0_adc
32
33 #include <errno.h>
34 #include <stdbool.h>
35
36 #include <zephyr/drivers/adc.h>
37 #include <zephyr/drivers/pinctrl.h>
38 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
39 #include <zephyr/device.h>
40 #include <zephyr/kernel.h>
41 #include <zephyr/init.h>
42 #include <zephyr/pm/device.h>
43 #include <zephyr/pm/policy.h>
44 #include <zephyr/sys/check.h>
45 #include <zephyr/sys/util_macro.h>
46 #include <zephyr/sys/math_extras.h>
47
48 #include <soc.h>
49 #include <stm32_ll_adc.h>
50 #include <stm32_ll_utils.h>
51
52 #ifdef CONFIG_ADC_STM32_DMA
53 #include <zephyr/drivers/dma/dma_stm32.h>
54 #include <zephyr/drivers/dma.h>
55 #include <zephyr/toolchain.h>
56 #include <stm32_ll_dma.h>
57 #endif
58
59 #define ADC_CONTEXT_USES_KERNEL_TIMER
60 #define ADC_CONTEXT_ENABLE_ON_COMPLETE
61 #include "adc_context.h"
62
63 #include <zephyr/logging/log.h>
64 LOG_MODULE_REGISTER(adc_stm32wb0, CONFIG_ADC_LOG_LEVEL);
65
66 /**
67 * Driver private definitions & assertions
68 */
69 #define ADC_INSTANCE 0
70 #define ADC_NODE DT_DRV_INST(ADC_INSTANCE)
71 #define ADC_USE_IO_BOOSTER DT_PROP_OR(ADC_NODE, io_booster, 0)
72
73 #define LL_ADC_EXTERNAL_CHANNEL_NUM 12 /* must be a plain constant for LISTIFY */
74 #define LL_ADC_EXTERNAL_CHANNEL_MAX (LL_ADC_CHANNEL_VINP3_VINM3 + 1U)
75 #define LL_ADC_CHANNEL_MAX (LL_ADC_CHANNEL_TEMPSENSOR + 1U)
76 #define LL_ADC_VIN_RANGE_INVALID ((uint8_t)0xFFU)
77
78 #define NUM_CALIBRATION_POINTS 4 /* 4 calibration point registers (COMP_[0-3]) */
79
80 #if !defined(ADC_CONF_SAMPLE_RATE_MSB)
81 # define NUM_ADC_SAMPLE_RATES 4 /* SAMPLE_RATE on 2 bits */
82 #else
83 # define NUM_ADC_SAMPLE_RATES 32 /* SAMPLE_RATE on 5 bits */
84 #endif
85
86 /* The STM32WB0 has a 12-bit ADC, but the resolution can be
87 * enhanced to 16-bit by oversampling (using the downsampler)
88 */
89 #define ADC_MIN_RESOLUTION 12
90 #define ADC_MAX_RESOLUTION 16
91
92 /* ADC channel type definitions are not provided by LL as
93 * it uses per-type functions instead. Bring our own.
94 */
95 #define ADC_CHANNEL_TYPE_SINGLE_NEG (0x00U) /* Single-ended, positive */
96 #define ADC_CHANNEL_TYPE_SINGLE_POS (0x01U) /* Single-ended, negative */
97 #define ADC_CHANNEL_TYPE_DIFF (0x02U) /* Differential */
98 #define ADC_CHANNEL_TYPE_INVALID (0xFFU) /* Invalid */
99
100 /** See RM0505 §6.2.1 "System clock details" */
101 BUILD_ASSERT(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC >= (8 * 1000 * 1000),
102 "STM32WB0: system clock frequency must be at least 8MHz to use ADC");
103
104 /**
105 * Driver private structures
106 */
107 struct adc_stm32wb0_data {
108 struct adc_context ctx;
109 const struct device *const dev;
110
111 /**
112 * Bitmask of all channels requested as part of this round
113 * but not sampled yet.
114 */
115 uint32_t unsampled_channels;
116
117 /**
118 * Pointer in output buffer where the first data sample of the round
119 * is stored. This is used to reload next_sample_ptr when the user
120 * callback asks to repeat a round.
121 */
122 uint16_t *round_buf_pointer;
123
124 /**
125 * Pointer in output buffer where the next data sample from ADC should
126 * be stored.
127 */
128 uint16_t *next_sample_ptr;
129
130 #if defined(CONFIG_ADC_STM32_DMA)
131 /** Size of the sequence currently scheduled and executing */
132 size_t sequence_length;
133 struct dma_config dmac_config;
134 struct dma_block_config dma_block_config;
135 #endif
136
137 /** Channels configuration */
138 struct adc_stm32wb0_channel_config {
139 /** Vinput range selection */
140 uint8_t vinput_range;
141 } channel_config[LL_ADC_CHANNEL_MAX];
142 };
143
144 struct adc_stm32wb0_config {
145 ADC_TypeDef *reg;
146 const struct pinctrl_dev_config *pinctrl_cfg;
147 /** ADC digital domain clock */
148 struct stm32_pclken dig_clk;
149 /** ADC analog domain clock */
150 struct stm32_pclken ana_clk;
151 #if defined(CONFIG_ADC_STM32_DMA)
152 const struct device *dmac;
153 uint32_t dma_channel;
154 #endif
155 };
156
157 /**
158 * Driver private utility functions
159 */
160
161 /**
162 * In STM32CubeWB0 v1.0.0, the LL_GetPackageType is buggy and returns wrong values.
163 * This bug is reported in the ST internal bugtracker under reference 185295.
164 * For now, implement the function ourselves.
165 */
ll_get_package_type(void)166 static inline uint32_t ll_get_package_type(void)
167 {
168 return sys_read32(PACKAGE_BASE);
169 }
170
drv_data_from_adc_ctx(struct adc_context * adc_ctx)171 static inline struct adc_stm32wb0_data *drv_data_from_adc_ctx(struct adc_context *adc_ctx)
172 {
173 return CONTAINER_OF(adc_ctx, struct adc_stm32wb0_data, ctx);
174 }
175
vinput_range_from_adc_ref(uint32_t reference)176 static inline uint8_t vinput_range_from_adc_ref(uint32_t reference)
177 {
178 switch (reference) {
179 case ADC_REF_INTERNAL:
180 case ADC_REF_VDD_1:
181 return LL_ADC_VIN_RANGE_3V6;
182 case ADC_REF_VDD_1_2:
183 return LL_ADC_VIN_RANGE_2V4;
184 case ADC_REF_VDD_1_3:
185 return LL_ADC_VIN_RANGE_1V2;
186 default:
187 return LL_ADC_VIN_RANGE_INVALID;
188 }
189 }
190
ds_width_from_adc_res(uint32_t resolution)191 static inline uint32_t ds_width_from_adc_res(uint32_t resolution)
192 {
193 /*
194 * 12 -> 0 (LL_ADC_DS_DATA_WIDTH_12_BIT)
195 * 13 -> 1 (LL_ADC_DS_DATA_WIDTH_13_BIT)
196 * 14 -> 2 (LL_ADC_DS_DATA_WIDTH_14_BIT)
197 * 15 -> 3 (LL_ADC_DS_DATA_WIDTH_15_BIT)
198 * 16 -> 4 (LL_ADC_DS_DATA_WIDTH_16_BIT)
199 */
200 return resolution - 12;
201 }
202
get_channel_type(uint32_t channel)203 static inline uint8_t get_channel_type(uint32_t channel)
204 {
205 switch (channel) {
206 case LL_ADC_CHANNEL_VINM0:
207 case LL_ADC_CHANNEL_VINM1:
208 case LL_ADC_CHANNEL_VINM2:
209 case LL_ADC_CHANNEL_VINM3:
210 case LL_ADC_CHANNEL_VBAT:
211 return ADC_CHANNEL_TYPE_SINGLE_NEG;
212 case LL_ADC_CHANNEL_VINP0:
213 case LL_ADC_CHANNEL_VINP1:
214 case LL_ADC_CHANNEL_VINP2:
215 case LL_ADC_CHANNEL_VINP3:
216 case LL_ADC_CHANNEL_TEMPSENSOR:
217 return ADC_CHANNEL_TYPE_SINGLE_POS;
218 case LL_ADC_CHANNEL_VINP0_VINM0:
219 case LL_ADC_CHANNEL_VINP1_VINM1:
220 case LL_ADC_CHANNEL_VINP2_VINM2:
221 case LL_ADC_CHANNEL_VINP3_VINM3:
222 return ADC_CHANNEL_TYPE_DIFF;
223 default:
224 __ASSERT_NO_MSG(0);
225 return ADC_CHANNEL_TYPE_INVALID;
226 }
227 }
228
229 /**
230 * @brief Checks all fields of the adc_sequence and asserts they are
231 * valid and all configuration options are supported by the driver.
232 *
233 * @param sequence adc_sequence to validate
234 * @return 0 if the adc_sequence is valid, negative value otherwise
235 */
validate_adc_sequence(const struct adc_sequence * sequence)236 static int validate_adc_sequence(const struct adc_sequence *sequence)
237 {
238 const size_t round_size = sizeof(uint16_t) * POPCOUNT(sequence->channels);
239 size_t needed_buf_size;
240
241 if (sequence->channels == 0 ||
242 (sequence->channels & ~BIT_MASK(LL_ADC_CHANNEL_MAX)) != 0) {
243 LOG_ERR("invalid channels selection");
244 return -EINVAL;
245 }
246
247 CHECKIF(!sequence->buffer) {
248 LOG_ERR("storage buffer pointer is NULL");
249 return -EINVAL;
250 }
251
252 if (!IN_RANGE(sequence->resolution, ADC_MIN_RESOLUTION, ADC_MAX_RESOLUTION)) {
253 LOG_ERR("invalid resolution %u (must be between %u and %u)",
254 sequence->resolution, ADC_MIN_RESOLUTION, ADC_MAX_RESOLUTION);
255 return -EINVAL;
256 }
257
258 /* N.B.: LL define is in the same log2(x) format as the Zephyr variable */
259 if (sequence->oversampling > LL_ADC_DS_RATIO_128) {
260 LOG_ERR("oversampling unsupported by hardware (max: %lu)", LL_ADC_DS_RATIO_128);
261 return -ENOTSUP;
262 }
263
264 if (sequence->options) {
265 const size_t samplings = (size_t)sequence->options->extra_samplings + 1;
266
267 if (size_mul_overflow(round_size, samplings, &needed_buf_size)) {
268 return -ENOMEM;
269 }
270 } else {
271 needed_buf_size = round_size;
272 }
273
274 if (needed_buf_size > sequence->buffer_size) {
275 return -ENOMEM;
276 }
277
278 return 0;
279 }
280
281 /**
282 * @brief Set which channel is sampled during a given conversion of the sequence.
283 *
284 * @param ADCx ADC registers pointer
285 * @param Conversion Target conversion index (0~15)
286 * @param Channel Channel to sample during specified conversion
287 *
288 * @note This function is a more convenient implementation of LL_ADC_SetSequencerRanks
289 */
ll_adc_set_conversion_channel(ADC_TypeDef * ADCx,uint32_t Conversion,uint32_t Channel)290 static inline void ll_adc_set_conversion_channel(ADC_TypeDef *ADCx,
291 uint32_t Conversion, uint32_t Channel)
292 {
293 /**
294 * There are two registers to control the sequencer:
295 * - SEQ_1 holds channel selection for conversions 0~7
296 * - SEQ_2 holds channel selection for conversions 8~15
297 *
298 * Notice that all conversions in SEQ_2 have 3rd bit set,
299 * whereas all conversions in SEQ_1 have 3rd bit clear.
300 *
301 * In a SEQ_x register, each channel occupies 4 bits, so the
302 * field for conversion N is at bit offset (4 * (N % 7)).
303 */
304 const uint32_t reg = (Conversion & 8) ? 1 : 0;
305 const uint32_t shift = 4 * (Conversion & 7);
306
307 MODIFY_REG((&ADCx->SEQ_1)[reg], ADC_SEQ_1_SEQ0 << shift, Channel << shift);
308 }
309
310 /**
311 * @brief Set the calibration point to use for a chosen channel type and Vinput range.
312 *
313 * @param ADCx ADC registers pointer
314 * @param Type Channel type
315 * @param Range Channel Vinput range
316 * @param Point Calibration point to use
317 *
318 * @note This is a generic version of the LL_ADC_SetCalibPointFor* functions.
319 */
ll_adc_set_calib_point_for_any(ADC_TypeDef * ADCx,uint32_t Type,uint32_t Range,uint32_t Point)320 static inline void ll_adc_set_calib_point_for_any(ADC_TypeDef *ADCx, uint32_t Type,
321 uint32_t Range, uint32_t Point)
322 {
323 __ASSERT(Range == LL_ADC_VIN_RANGE_1V2
324 || Range == LL_ADC_VIN_RANGE_2V4
325 || Range == LL_ADC_VIN_RANGE_3V6, "Range is not valid");
326
327 __ASSERT(Type == ADC_CHANNEL_TYPE_SINGLE_NEG
328 || Type == ADC_CHANNEL_TYPE_SINGLE_POS
329 || Type == ADC_CHANNEL_TYPE_DIFF, "Type is not valid");
330
331 __ASSERT(Point == LL_ADC_CALIB_POINT_1
332 || Point == LL_ADC_CALIB_POINT_2
333 || Point == LL_ADC_CALIB_POINT_3
334 || Point == LL_ADC_CALIB_POINT_4, "Point is not valid");
335
336 /* Register organization is as follows:
337 *
338 * - Group for 1.2V Vinput range
339 * - Group for 2.4V Vinput range
340 * - Group for 3.6V Vinput range
341 *
342 * where Group is organized as:
343 * - Select for Single Negative mode
344 * - Select for Single Positive mode
345 * - Select for Differential mode
346 *
347 * Each select is 2 bits, and each group is thus 6 bits.
348 */
349
350 uint32_t type_shift, group_shift;
351
352 switch (Type) {
353 case ADC_CHANNEL_TYPE_SINGLE_NEG:
354 type_shift = 0 * 2;
355 break;
356 case ADC_CHANNEL_TYPE_SINGLE_POS:
357 type_shift = 1 * 2;
358 break;
359 case ADC_CHANNEL_TYPE_DIFF:
360 type_shift = 2 * 2;
361 break;
362 default:
363 CODE_UNREACHABLE;
364 }
365
366 switch (Range) {
367 case LL_ADC_VIN_RANGE_1V2:
368 group_shift = 0 * 6;
369 break;
370 case LL_ADC_VIN_RANGE_2V4:
371 group_shift = 1 * 6;
372 break;
373 case LL_ADC_VIN_RANGE_3V6:
374 group_shift = 2 * 6;
375 break;
376 default:
377 CODE_UNREACHABLE;
378 }
379
380 const uint32_t shift = (group_shift + type_shift);
381
382 MODIFY_REG(ADCx->COMP_SEL, (ADC_COMP_SEL_OFFSET_GAIN0 << shift), (Point << shift));
383 }
384
adc_acquire_pm_locks(void)385 static void adc_acquire_pm_locks(void)
386 {
387 pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
388 if (IS_ENABLED(CONFIG_PM_S2RAM)) {
389 pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_RAM, PM_ALL_SUBSTATES);
390 }
391 }
392
adc_release_pm_locks(void)393 static void adc_release_pm_locks(void)
394 {
395 pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
396 if (IS_ENABLED(CONFIG_PM_S2RAM)) {
397 pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_RAM, PM_ALL_SUBSTATES);
398 }
399 }
400
401 /**
402 * Driver private functions
403 */
404
configure_tempsensor_calib_point(ADC_TypeDef * adc,uint32_t calib_point)405 static void configure_tempsensor_calib_point(ADC_TypeDef *adc, uint32_t calib_point)
406 {
407 uint16_t gain;
408 #if defined(CONFIG_SOC_STM32WB09XX) || defined(CONFIG_SOC_STM32WB05XX)
409 /** RM0505/RM0529 §12.2.1 "Temperature sensor subsystem" */
410 gain = 0xFFF;
411 #else
412 /** RM0530 §12.2.2 "Temperature sensor subsystem" */
413 gain = LL_ADC_GET_CALIB_GAIN_FOR_VINPX_1V2();
414 #endif /* CONFIG_SOC_STM32WB09XX | CONFIG_SOC_STM32WB05XX */
415
416 LL_ADC_ConfigureCalibPoint(adc, calib_point, gain, 0x0);
417 }
418
419 /**
420 * @brief Obtain calibration data for specified channel type and Vinput range
421 * from engineering flash, and write it to specified calibration point
422 *
423 * @param ADCx ADC registers pointer
424 * @param Point Calibration point to configure
425 * @param Type Target channel type
426 * @param Range Target channel Vinput range
427 */
configure_calib_point_from_flash(ADC_TypeDef * ADCx,uint32_t Point,uint32_t Type,uint32_t Range)428 static void configure_calib_point_from_flash(ADC_TypeDef *ADCx, uint32_t Point,
429 uint32_t Type, uint32_t Range)
430 {
431 int8_t offset = 0;
432 uint16_t gain = 0;
433
434 switch (Range) {
435 case LL_ADC_VIN_RANGE_1V2:
436 switch (Type) {
437 case ADC_CHANNEL_TYPE_SINGLE_POS:
438 gain = LL_ADC_GET_CALIB_GAIN_FOR_VINPX_1V2();
439 offset = LL_ADC_GET_CALIB_OFFSET_FOR_VINPX_1V2();
440 break;
441 case ADC_CHANNEL_TYPE_SINGLE_NEG:
442 gain = LL_ADC_GET_CALIB_GAIN_FOR_VINMX_1V2();
443 offset = LL_ADC_GET_CALIB_OFFSET_FOR_VINMX_1V2();
444 break;
445 case ADC_CHANNEL_TYPE_DIFF:
446 gain = LL_ADC_GET_CALIB_GAIN_FOR_VINDIFF_1V2();
447 offset = LL_ADC_GET_CALIB_OFFSET_FOR_VINDIFF_1V2();
448 break;
449 }
450 break;
451 case LL_ADC_VIN_RANGE_2V4:
452 switch (Type) {
453 case ADC_CHANNEL_TYPE_SINGLE_POS:
454 gain = LL_ADC_GET_CALIB_GAIN_FOR_VINPX_2V4();
455 offset = LL_ADC_GET_CALIB_OFFSET_FOR_VINPX_2V4();
456 break;
457 case ADC_CHANNEL_TYPE_SINGLE_NEG:
458 gain = LL_ADC_GET_CALIB_GAIN_FOR_VINMX_2V4();
459 offset = LL_ADC_GET_CALIB_OFFSET_FOR_VINMX_2V4();
460 break;
461 case ADC_CHANNEL_TYPE_DIFF:
462 gain = LL_ADC_GET_CALIB_GAIN_FOR_VINDIFF_2V4();
463 offset = LL_ADC_GET_CALIB_OFFSET_FOR_VINDIFF_2V4();
464 break;
465 }
466 break;
467 case LL_ADC_VIN_RANGE_3V6:
468 switch (Type) {
469 case ADC_CHANNEL_TYPE_SINGLE_POS:
470 gain = LL_ADC_GET_CALIB_GAIN_FOR_VINPX_3V6();
471 offset = LL_ADC_GET_CALIB_OFFSET_FOR_VINPX_3V6();
472 break;
473 case ADC_CHANNEL_TYPE_SINGLE_NEG:
474 gain = LL_ADC_GET_CALIB_GAIN_FOR_VINMX_3V6();
475 offset = LL_ADC_GET_CALIB_OFFSET_FOR_VINMX_3V6();
476 break;
477 case ADC_CHANNEL_TYPE_DIFF:
478 gain = LL_ADC_GET_CALIB_GAIN_FOR_VINDIFF_3V6();
479 offset = LL_ADC_GET_CALIB_OFFSET_FOR_VINDIFF_3V6();
480 break;
481 }
482 break;
483 }
484
485 LL_ADC_ConfigureCalibPoint(ADCx, Point, gain, offset);
486 }
487
adc_enter_idle_mode(ADC_TypeDef * adc,const struct stm32_pclken * ana_clk)488 static void adc_enter_idle_mode(ADC_TypeDef *adc, const struct stm32_pclken *ana_clk)
489 {
490 const struct device *clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
491 int err;
492
493 /* Power down the ADC */
494 LL_ADC_Disable(adc);
495
496 #if SMPS_MODE != STM32WB0_SMPS_MODE_OFF
497 /* Disable SMPS synchronization */
498 LL_ADC_SMPSSyncDisable(adc);
499 #endif /* SMPS_MODE != STM32WB0_SMPS_MODE_OFF */
500
501 #if ADC_USE_IO_BOOSTER
502 /* Disable ADC I/O booster */
503 LL_RCC_IOBOOST_Disable();
504
505 # if defined(RCC_CFGR_IOBOOSTCLKEN)
506 /* Disable ADC I/O Booster clock if present */
507 LL_RCC_IOBOOSTCLK_Disable();
508 # endif
509 #endif /* ADC_USE_IO_BOOSTER */
510
511 #if defined(ADC_CTRL_ADC_LDO_ENA)
512 /* Disable ADC voltage regulator */
513 LL_ADC_DisableInternalRegulator(adc);
514 #endif /* ADC_CTRL_ADC_LDO_ENA */
515
516 /* Turn off ADC analog domain clock */
517 err = clock_control_off(clk, (clock_control_subsys_t)ana_clk);
518 if (err < 0) {
519 LOG_WRN("failed to turn off ADC analog clock (%d)", err);
520 }
521
522 /* Release power management locks */
523 adc_release_pm_locks();
524 }
525
adc_exit_idle_mode(ADC_TypeDef * adc,const struct stm32_pclken * ana_clk)526 static int adc_exit_idle_mode(ADC_TypeDef *adc, const struct stm32_pclken *ana_clk)
527 {
528 const struct device *clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
529 int err;
530
531 /* Acquire power management locks */
532 adc_acquire_pm_locks();
533
534 /* Turn on ADC analog domain clock */
535 err = clock_control_on(clk,
536 (clock_control_subsys_t)ana_clk);
537 if (err < 0) {
538 LOG_ERR("failed to turn on ADC analog clock: %d", err);
539 adc_release_pm_locks();
540 return err;
541 }
542
543 #if defined(ADC_CTRL_ADC_LDO_ENA)
544 /* RM0479 §12.6.3: bit ADC_LDO_ENA must not be set on QFN32 packages.
545 * Using an equality check with supported package types ensures that
546 * we never accidentally set the bit on an unsupported MCU.
547 */
548 const uint32_t package_type = ll_get_package_type();
549
550 if (package_type == LL_UTILS_PACKAGETYPE_QFN48
551 || package_type == LL_UTILS_PACKAGETYPE_CSP49) {
552 LL_ADC_EnableInternalRegulator(adc);
553 }
554 #endif /* ADC_CTRL_ADC_LDO_ENA */
555
556 #if ADC_USE_IO_BOOSTER
557 # if defined(RCC_CFGR_IOBOOSTCLKEN)
558 /* Enable ADC I/O Booster clock if needed by hardware */
559 LL_RCC_IOBOOSTCLK_Enable();
560 # endif
561
562 /* Enable ADC I/O Booster */
563 LL_RCC_IOBOOST_Enable();
564 #endif /* ADC_USE_IO_BOOSTER*/
565
566 #if SMPS_MODE != STM32WB0_SMPS_MODE_OFF
567 /* RM0505 §6.2.2 "Peripherals clock details":
568 * To avoid SNR degradation of the ADC,
569 * SMPS and ADC clocks must be synchronous.
570 */
571 LL_ADC_SMPSSyncEnable(adc);
572 #endif /* SMPS_MODE != STM32WB0_SMPS_MODE_OFF */
573
574 /* Power up the ADC */
575 LL_ADC_Enable(adc);
576
577 return err;
578 }
579
580 /**
581 * @brief Schedule as many samplings as possible in a sequence
582 * then start the ADC conversion.
583 */
schedule_and_start_adc_sequence(ADC_TypeDef * adc,struct adc_stm32wb0_data * data)584 static void schedule_and_start_adc_sequence(ADC_TypeDef *adc, struct adc_stm32wb0_data *data)
585 {
586 uint32_t remaining_unsampled = data->unsampled_channels;
587 uint32_t allocated_calib_points = 0;
588 uint32_t sequence_length = 0;
589 bool temp_sensor_scheduled = false;
590
591 /**
592 * These tables are used to keep track of which calibration
593 * point registers are used for what type of acquisition, in
594 * order to share the same calibration point for different
595 * channels if they use compatible configurations.
596 *
597 * Initialize only the first table with invalid values; since
598 * both tables are updated at the same time, this is sufficient
599 * to know when to stop programming calibration points.
600 */
601 uint8_t calib_pt_ch_type[NUM_CALIBRATION_POINTS] = {
602 ADC_CHANNEL_TYPE_INVALID, ADC_CHANNEL_TYPE_INVALID,
603 ADC_CHANNEL_TYPE_INVALID, ADC_CHANNEL_TYPE_INVALID
604 };
605 uint8_t calib_pt_vin_range[NUM_CALIBRATION_POINTS];
606
607 /* Schedule as many channels as possible for sampling */
608 for (uint32_t channel = 0;
609 channel < LL_ADC_CHANNEL_MAX && remaining_unsampled != 0U;
610 channel++) {
611 const uint32_t ch_bit = BIT(channel);
612
613 if ((remaining_unsampled & ch_bit) == 0) {
614 continue;
615 }
616
617 /* Get channel information */
618 const uint8_t ch_type = get_channel_type(channel);
619 const uint8_t ch_vin_range = data->channel_config[channel].vinput_range;
620
621 /* Attempt to find a compatible calibration point */
622 uint32_t calib_pt = 0;
623
624 for (; calib_pt < allocated_calib_points; calib_pt++) {
625 if (calib_pt_ch_type[calib_pt] == ch_type
626 && calib_pt_vin_range[calib_pt] == ch_vin_range) {
627 break;
628 }
629 }
630
631 if (calib_pt == allocated_calib_points) {
632 /* No compatible calibration point found.
633 * If an unallocated calibration point remains, use it.
634 * Otherwise, this channel cannot be scheduled; since we must
635 * perform samplings in order, exit the scheduling loop.
636 */
637 if (allocated_calib_points < NUM_CALIBRATION_POINTS) {
638 allocated_calib_points++;
639 } else {
640 /* Exit scheduling loop */
641 break;
642 }
643 }
644
645 if (channel == LL_ADC_CHANNEL_TEMPSENSOR) {
646 if (calib_pt_ch_type[calib_pt] == ADC_CHANNEL_TYPE_INVALID) {
647 /**
648 * Temperature sensor is a special channel: it must be sampled
649 * with special gain/offset instead of the calibration values found
650 * in engineering flash. For this reason, it must NOT be scheduled
651 * with any other 1.2V Vinput range, single-ended positive channel.
652 *
653 * If this check succeeds, then no such channel is scheduled, and we
654 * can add the temperature sensor to this sequence. We're sure there
655 * won't be any conflict because the temperature sensor is the last
656 * channel. Otherwise, a channel with 1.2V Vinput range has been
657 * scheduled and we must delay the temperature sensor measurement to
658 * another sequence.
659 */
660 temp_sensor_scheduled = true;
661 } else {
662 /* Exit scheduling loop before scheduling temperature sensor */
663 break;
664 }
665 }
666
667 /* Ensure calibration point tables are updated.
668 * This is unneeded if the entry was already filled up,
669 * but cheaper than checking for duplicate work.
670 */
671 calib_pt_ch_type[calib_pt] = ch_type;
672 calib_pt_vin_range[calib_pt] = ch_vin_range;
673
674 /* Remove channel from unscheduled list */
675 remaining_unsampled &= ~ch_bit;
676
677 /* Add channel to sequence */
678 ll_adc_set_conversion_channel(adc, sequence_length, channel);
679 sequence_length++;
680
681 /* Select the calibration point to use for channel */
682 ll_adc_set_calib_point_for_any(adc, ch_type, ch_vin_range, calib_pt);
683
684 /* Configure the channel Vinput range selection.
685 * This must not be done for internal channels, which
686 * use a hardwired Vinput range selection instead.
687 */
688 if (channel < LL_ADC_EXTERNAL_CHANNEL_MAX) {
689 LL_ADC_SetChannelVoltageRange(adc, channel, ch_vin_range);
690 }
691 #if !defined(CONFIG_ADC_STM32_DMA)
692 /* If DMA is not enabled, only schedule one channel at a time.
693 * Otherwise, the ADC will overflow and everything will break.
694 */
695 __ASSERT_NO_MSG(sequence_length == 1);
696 break;
697 #endif
698 }
699
700 /* Configure all (used) calibration points */
701 for (int i = 0; i < NUM_CALIBRATION_POINTS; i++) {
702 uint8_t type = calib_pt_ch_type[i];
703 uint8_t range = calib_pt_vin_range[i];
704
705 if (type == ADC_CHANNEL_TYPE_INVALID) {
706 break;
707 } else if ((type == ADC_CHANNEL_TYPE_SINGLE_POS)
708 && (range == LL_ADC_VIN_RANGE_1V2)
709 && temp_sensor_scheduled) {
710 /* Configure special calibration point for temperature sensor */
711 configure_tempsensor_calib_point(adc, i);
712 } else {
713 configure_calib_point_from_flash(adc, i, type, range);
714 }
715 }
716
717 __ASSERT_NO_MSG(sequence_length > 0);
718
719 /* Now that scheduling is done, we can set the sequence length */
720 LL_ADC_SetSequenceLength(adc, sequence_length);
721
722 /* Save unsampled channels (if any) for next sequence */
723 data->unsampled_channels = remaining_unsampled;
724
725 #if defined(CONFIG_ADC_STM32_DMA)
726 const struct adc_stm32wb0_config *config = data->dev->config;
727 int err;
728
729 /* Save sequence length in driver data for later usage */
730 data->sequence_length = sequence_length;
731
732 /* Prepare the DMA controller for ADC->memory transfers */
733 data->dma_block_config.source_address = (uint32_t)&adc->DS_DATAOUT;
734 data->dma_block_config.dest_address = (uint32_t)data->next_sample_ptr;
735 data->dma_block_config.block_size = data->sequence_length * sizeof(uint16_t);
736
737 err = dma_config(config->dmac, config->dma_channel, &data->dmac_config);
738 if (err < 0) {
739 LOG_ERR("%s: FAIL - dma_config returns %d", __func__, err);
740 adc_context_complete(&data->ctx, err);
741 return;
742 }
743
744 err = dma_start(config->dmac, config->dma_channel);
745 if (err < 0) {
746 LOG_ERR("%s: FAIL - dma_start returns %d", __func__, err);
747 adc_context_complete(&data->ctx, err);
748 return;
749 }
750 #endif
751
752 /* Start conversion sequence */
753 LL_ADC_StartConversion(adc);
754 }
755
handle_end_of_sequence(ADC_TypeDef * adc,struct adc_stm32wb0_data * data)756 static inline void handle_end_of_sequence(ADC_TypeDef *adc, struct adc_stm32wb0_data *data)
757 {
758 if (data->unsampled_channels != 0) {
759 /* Some channels requested for this round have
760 * not been sampled yet. Schedule and start another
761 * acquisition sequence.
762 */
763 schedule_and_start_adc_sequence(adc, data);
764 } else {
765 /* All channels sampled: round is complete. */
766 adc_context_on_sampling_done(&data->ctx, data->dev);
767 }
768 }
769
initiate_read_operation(const struct device * dev,const struct adc_sequence * sequence)770 static int initiate_read_operation(const struct device *dev,
771 const struct adc_sequence *sequence)
772 {
773 const struct adc_stm32wb0_config *config = dev->config;
774 struct adc_stm32wb0_data *data = dev->data;
775 ADC_TypeDef *adc = (ADC_TypeDef *)config->reg;
776 int err;
777
778 err = validate_adc_sequence(sequence);
779 if (err < 0) {
780 return err;
781 }
782
783 /* Take ADC out of idle mode before getting to work */
784 err = adc_exit_idle_mode(adc, &config->ana_clk);
785 if (err < 0) {
786 return err;
787 }
788
789 /* Initialize output pointers to first byte of user buffer */
790 data->next_sample_ptr = data->round_buf_pointer = sequence->buffer;
791
792 /* Configure resolution */
793 LL_ADC_SetDSDataOutputWidth(adc, ds_width_from_adc_res(sequence->resolution));
794
795 /* Configure oversampling */
796 LL_ADC_SetDSDataOutputRatio(adc, sequence->oversampling);
797
798 /* Start reading using the ADC */
799 adc_context_start_read(&data->ctx, sequence);
800
801 return 0;
802 }
803
804 #if !defined(CONFIG_ADC_STM32_DMA)
adc_stm32wb0_isr(const struct device * dev)805 void adc_stm32wb0_isr(const struct device *dev)
806 {
807 const struct adc_stm32wb0_config *config = dev->config;
808 struct adc_stm32wb0_data *data = dev->data;
809 ADC_TypeDef *adc = config->reg;
810
811 /* Down sampler output data available */
812 if (LL_ADC_IsActiveFlag_EODS(adc)) {
813 /* Clear pending interrupt flag */
814 LL_ADC_ClearFlag_EODS(adc);
815
816 /* Write ADC data to output buffer and update pointer */
817 *data->next_sample_ptr++ = LL_ADC_DSGetOutputData(adc);
818 }
819
820 /* Down sampler overflow detected - return error */
821 if (LL_ADC_IsActiveFlag_OVRDS(adc)) {
822 LL_ADC_ClearFlag_OVRDS(adc);
823
824 LOG_ERR("ADC overflow\n");
825
826 adc_context_complete(&data->ctx, -EIO);
827 return;
828 }
829
830 if (!LL_ADC_IsActiveFlag_EOS(adc)) {
831 /* ADC sequence not finished yet */
832 return;
833 }
834
835 /* Clear pending interrupt flag */
836 LL_ADC_ClearFlag_EOS(adc);
837
838 /* Execute end-of-sequence logic */
839 handle_end_of_sequence(adc, data);
840 }
841 #else /* CONFIG_ADC_STM32_DMA */
adc_stm32wb0_dma_callback(const struct device * dma,void * user_data,uint32_t dma_channel,int dma_status)842 static void adc_stm32wb0_dma_callback(const struct device *dma, void *user_data,
843 uint32_t dma_channel, int dma_status)
844 {
845 struct adc_stm32wb0_data *data = user_data;
846 const struct device *dev = data->dev;
847 const struct adc_stm32wb0_config *config = dev->config;
848 ADC_TypeDef *adc = config->reg;
849 int err;
850
851 /* N.B.: some of this code is borrowed from existing ADC driver,
852 * but may be not applicable to STM32WB0 series' ADC.
853 */
854 if (dma_channel == config->dma_channel) {
855 if (LL_ADC_IsActiveFlag_OVRDS(adc) || (dma_status >= 0)) {
856 /* Sequence finished - update driver data accordingly */
857 data->next_sample_ptr += data->sequence_length;
858
859 /* Stop the DMA controller */
860 err = dma_stop(config->dmac, config->dma_channel);
861 LOG_DBG("%s: dma_stop returns %d", __func__, err);
862
863 LL_ADC_ClearFlag_OVRDS(adc);
864
865 /* Execute the common end-of-sequence logic */
866 handle_end_of_sequence(adc, data);
867 } else { /* dma_status < 0 */
868 LOG_ERR("%s: dma error %d", __func__, dma_status);
869 LL_ADC_StopConversion(adc);
870
871 err = dma_stop(config->dmac, config->dma_channel);
872
873 LOG_DBG("dma_stop returns %d", err);
874
875 adc_context_complete(&data->ctx, dma_status);
876 }
877 } else {
878 LOG_DBG("dma_channel 0x%08X != config->dma_channel 0x%08X",
879 dma_channel, config->dma_channel);
880 }
881 }
882 #endif /* !CONFIG_ADC_STM32_DMA */
883
884 /**
885 * adc_context API implementation
886 */
adc_context_start_sampling(struct adc_context * ctx)887 static void adc_context_start_sampling(struct adc_context *ctx)
888 {
889 struct adc_stm32wb0_data *data = drv_data_from_adc_ctx(ctx);
890 const struct adc_stm32wb0_config *config = data->dev->config;
891
892 /* Mark all channels of this round as unsampled */
893 data->unsampled_channels = data->ctx.sequence.channels;
894
895 /* Schedule and start first sequence of this round */
896 schedule_and_start_adc_sequence(config->reg, data);
897 }
898
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)899 static void adc_context_update_buffer_pointer(
900 struct adc_context *ctx, bool repeat_sampling)
901 {
902 struct adc_stm32wb0_data *data = drv_data_from_adc_ctx(ctx);
903
904 if (repeat_sampling) {
905 /* Roll back output pointer to address of first sample in round */
906 data->next_sample_ptr = data->round_buf_pointer;
907 } else /* a new round is starting: */ {
908 /* Save address of first sample in round in case we have to repeat it */
909 data->round_buf_pointer = data->next_sample_ptr;
910 }
911 }
912
adc_context_on_complete(struct adc_context * ctx,int status)913 static void adc_context_on_complete(struct adc_context *ctx, int status)
914 {
915 struct adc_stm32wb0_data *data = drv_data_from_adc_ctx(ctx);
916 const struct adc_stm32wb0_config *config = data->dev->config;
917
918 ARG_UNUSED(status);
919
920 /**
921 * All ADC operations are complete.
922 * Save power by placing ADC in idle mode.
923 */
924 adc_enter_idle_mode(config->reg, &config->ana_clk);
925
926 /* Prevent data corruption if something goes wrong. */
927 data->next_sample_ptr = NULL;
928 }
929
930 /**
931 * Driver subsystem API implementation
932 */
adc_stm32wb0_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)933 int adc_stm32wb0_channel_setup(const struct device *dev,
934 const struct adc_channel_cfg *channel_cfg)
935 {
936 CHECKIF(dev == NULL) { return -ENODEV; }
937 CHECKIF(channel_cfg == NULL) { return -EINVAL; }
938 const bool is_diff_channel =
939 (channel_cfg->channel_id == LL_ADC_CHANNEL_VINP0_VINM0
940 || channel_cfg->channel_id == LL_ADC_CHANNEL_VINP1_VINM1
941 || channel_cfg->channel_id == LL_ADC_CHANNEL_VINP2_VINM2
942 || channel_cfg->channel_id == LL_ADC_CHANNEL_VINP3_VINM3);
943 const uint8_t vin_range = vinput_range_from_adc_ref(channel_cfg->reference);
944 const uint32_t channel_id = channel_cfg->channel_id;
945 struct adc_stm32wb0_data *data = dev->data;
946 int res;
947
948 /* Forbid reconfiguration while operation in progress */
949 res = k_sem_take(&data->ctx.lock, K_NO_WAIT);
950 if (res < 0) {
951 return res;
952 }
953
954 /* Validate channel configuration parameters */
955 if (channel_cfg->gain != ADC_GAIN_1) {
956 LOG_ERR("gain unsupported by hardware");
957 res = -ENOTSUP;
958 goto unlock_and_return;
959 }
960
961 if (vin_range == LL_ADC_VIN_RANGE_INVALID) {
962 LOG_ERR("invalid channel voltage reference");
963 res = -EINVAL;
964 goto unlock_and_return;
965 }
966
967 if (channel_id >= LL_ADC_CHANNEL_MAX) {
968 LOG_ERR("invalid channel id %d", channel_cfg->channel_id);
969 res = -EINVAL;
970 goto unlock_and_return;
971 } else if (is_diff_channel != channel_cfg->differential) {
972 /* channel_cfg->differential flag does not match
973 * with the selected channel's type
974 */
975 LOG_ERR("differential flag does not match channel type");
976 res = -EINVAL;
977 goto unlock_and_return;
978 }
979
980 if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
981 LOG_ERR("acquisition time unsupported by hardware");
982 res = -ENOTSUP;
983 goto unlock_and_return;
984 }
985
986 /* Verify that the correct reference is selected for special channels */
987 if (channel_id == LL_ADC_CHANNEL_VBAT && vin_range != LL_ADC_VIN_RANGE_3V6) {
988 LOG_ERR("invalid reference for Vbat channel");
989 res = -EINVAL;
990 goto unlock_and_return;
991 } else if (channel_id == LL_ADC_CHANNEL_TEMPSENSOR && vin_range != LL_ADC_VIN_RANGE_1V2) {
992 LOG_ERR("invalid reference for temperature sensor channel");
993 res = -EINVAL;
994 goto unlock_and_return;
995 }
996
997 /* Save the channel configuration in driver data.
998 * Note that the only configuration option available
999 * is the ADC channel reference (= Vinput range).
1000 */
1001 data->channel_config[channel_id].vinput_range = vin_range;
1002
1003 unlock_and_return:
1004 /* Unlock the instance after updating configuration */
1005 k_sem_give(&data->ctx.lock);
1006
1007 return res;
1008 }
1009
adc_stm32wb0_read(const struct device * dev,const struct adc_sequence * sequence)1010 int adc_stm32wb0_read(const struct device *dev,
1011 const struct adc_sequence *sequence)
1012 {
1013 CHECKIF(dev == NULL) { return -ENODEV; }
1014 struct adc_stm32wb0_data *data = dev->data;
1015 int err;
1016
1017 adc_context_lock(&data->ctx, false, NULL);
1018
1019 /* When context is locked in synchronous mode, this
1020 * function blocks until the whole operation is complete.
1021 */
1022 err = initiate_read_operation(dev, sequence);
1023
1024 if (err >= 0) {
1025 err = adc_context_wait_for_completion(&data->ctx);
1026 } else {
1027 adc_release_pm_locks();
1028 }
1029
1030 adc_context_release(&data->ctx, err);
1031
1032 return err;
1033 }
1034
1035 #if defined(CONFIG_ADC_ASYNC)
adc_stm32wb0_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)1036 int adc_stm32wb0_read_async(const struct device *dev,
1037 const struct adc_sequence *sequence, struct k_poll_signal *async)
1038 {
1039 CHECKIF(dev == NULL) { return -ENODEV; }
1040 struct adc_stm32wb0_data *data = dev->data;
1041 int err;
1042
1043 adc_context_lock(&data->ctx, true, async);
1044
1045 /* When context is locked in synchronous mode, this
1046 * function blocks until the whole operation is complete.
1047 */
1048 err = initiate_read_operation(dev, sequence);
1049 if (err < 0) {
1050 adc_release_pm_locks();
1051 }
1052
1053 adc_context_release(&data->ctx, err);
1054
1055 return err;
1056 }
1057 #endif /* CONFIG_ADC_ASYNC */
1058
1059 static DEVICE_API(adc, api_stm32wb0_driver_api) = {
1060 .channel_setup = adc_stm32wb0_channel_setup,
1061 .read = adc_stm32wb0_read,
1062 #if defined(CONFIG_ADC_ASYNC)
1063 .read_async = adc_stm32wb0_read_async,
1064 #endif /* CONFIG_ADC_ASYNC */
1065 .ref_internal = 3600U /* ADC_REF_INTERNAL is mapped to Vinput 3.6V range */
1066 };
1067
adc_stm32wb0_init(const struct device * dev)1068 int adc_stm32wb0_init(const struct device *dev)
1069 {
1070 const struct device *clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
1071 const struct adc_stm32wb0_config *config = dev->config;
1072 struct adc_stm32wb0_data *data = dev->data;
1073 ADC_TypeDef *adc = config->reg;
1074 int err;
1075
1076 if (!device_is_ready(clk)) {
1077 LOG_ERR("clock control device not ready");
1078 return -ENODEV;
1079 }
1080
1081 /* Turn on ADC digital clock (always on) */
1082 err = clock_control_on(clk,
1083 (clock_control_subsys_t)&config->dig_clk);
1084 if (err < 0) {
1085 LOG_ERR("failed to turn on ADC digital clock (%d)", err);
1086 return err;
1087 }
1088
1089 /* Configure DT-provided signals when available */
1090 err = pinctrl_apply_state(config->pinctrl_cfg, PINCTRL_STATE_DEFAULT);
1091 if (err < 0 && err != -ENOENT) {
1092 /* ENOENT indicates no entry - should not be treated as failure */
1093 LOG_ERR("fail to apply ADC pinctrl state (%d)", err);
1094 return err;
1095 }
1096
1097 #if defined(ADC_SUPPORT_AUDIO_FEATURES)
1098 /* Configure ADC for analog sampling */
1099 LL_ADC_SetADCMode(adc, LL_ADC_OP_MODE_ADC);
1100 #endif
1101
1102 #if defined(PWR_CR2_ENTS)
1103 /* Enable on-die temperature sensor */
1104 LL_PWR_EnableTempSens();
1105 #endif
1106
1107 /* Set ADC sample rate to 1 Msps (maximum speed) */
1108 LL_ADC_SetSampleRate(adc, LL_ADC_SAMPLE_RATE_16);
1109
1110 /* Keep new data on overrun, if it ever happens */
1111 LL_ADC_SetOverrunDS(adc, LL_ADC_NEW_DATA_IS_KEPT);
1112
1113 #if !defined(CONFIG_ADC_STM32_DMA)
1114 /* Attach ISR and enable ADC interrupt in NVIC */
1115 IRQ_CONNECT(DT_IRQN(ADC_NODE), DT_IRQ(ADC_NODE, priority),
1116 adc_stm32wb0_isr, DEVICE_DT_GET(ADC_NODE), 0);
1117 irq_enable(DT_IRQN(ADC_NODE));
1118
1119 /* Enable ADC interrupt after each sampling.
1120 * NOTE: enabling EOS interrupt is not necessary because
1121 * the EODS interrupt flag is also set to high when the
1122 * EOS flag is being set to high.
1123 */
1124 LL_ADC_EnableIT_EODS(adc);
1125 #else
1126 /* Check that DMA controller exists and is ready to be used */
1127 if (!config->dmac) {
1128 LOG_ERR("no DMA assigned to ADC in DMA driver mode!");
1129 return -ENODEV;
1130 }
1131
1132 if (!device_is_ready(config->dmac)) {
1133 LOG_ERR("DMA controller '%s' for ADC not ready", config->dmac->name);
1134 return -ENODEV;
1135 }
1136
1137 /* Finalize DMA configuration structure in driver data */
1138 data->dmac_config.head_block = &data->dma_block_config;
1139 data->dmac_config.user_data = data;
1140
1141 /* Enable DMA datapath in ADC */
1142 LL_ADC_DMAModeDSEnable(adc);
1143 #endif /* !CONFIG_ADC_STM32_DMA */
1144
1145 /* Unlock the ADC context to mark ADC as ready to use */
1146 adc_context_unlock_unconditionally(&data->ctx);
1147
1148 /* Keep ADC powered down ("idle mode").
1149 * It will be awakened on-demand when a call to the ADC API
1150 * is performed by the application.
1151 */
1152 return 0;
1153 }
1154
1155 /**
1156 * Driver power management implementation
1157 */
1158 #ifdef CONFIG_PM_DEVICE
adc_stm32wb0_pm_action(const struct device * dev,enum pm_device_action action)1159 static int adc_stm32wb0_pm_action(const struct device *dev,
1160 enum pm_device_action action)
1161 {
1162 const struct adc_stm32wb0_config *config = dev->config;
1163 ADC_TypeDef *adc = config->reg;
1164 int res;
1165
1166 switch (action) {
1167 case PM_DEVICE_ACTION_RESUME:
1168 return adc_stm32wb0_init(dev);
1169 case PM_DEVICE_ACTION_SUSPEND:
1170 adc_enter_idle_mode(adc, &config->ana_clk);
1171
1172 /* Move pins to sleep state */
1173 res = pinctrl_apply_state(config->pinctrl_cfg, PINCTRL_STATE_SLEEP);
1174
1175 /**
1176 * -ENOENT is returned if there are no pins defined in DTS for sleep mode.
1177 * This is fine and should not block PM from suspending the device.
1178 * Silently ignore the error by returning 0 instead.
1179 */
1180 if (res >= 0 || res == -ENOENT) {
1181 return 0;
1182 } else {
1183 return res;
1184 }
1185 default:
1186 return -ENOTSUP;
1187 }
1188 }
1189 #endif /* CONFIG_PM_DEVICE */
1190
1191 /**
1192 * Driver device instantiation
1193 */
1194 PINCTRL_DT_DEFINE(ADC_NODE);
1195
1196 static const struct adc_stm32wb0_config adc_config = {
1197 .reg = (ADC_TypeDef *)DT_REG_ADDR(ADC_NODE),
1198 .pinctrl_cfg = PINCTRL_DT_DEV_CONFIG_GET(ADC_NODE),
1199 .dig_clk = STM32_CLOCK_INFO(0, ADC_NODE),
1200 .ana_clk = STM32_CLOCK_INFO(1, ADC_NODE),
1201 #if defined(CONFIG_ADC_STM32_DMA)
1202 .dmac = DEVICE_DT_GET(DT_DMAS_CTLR_BY_IDX(ADC_NODE, 0)),
1203 .dma_channel = DT_DMAS_CELL_BY_IDX(ADC_NODE, 0, channel),
1204 #endif
1205 };
1206
1207 static struct adc_stm32wb0_data adc_data = {
1208 ADC_CONTEXT_INIT_TIMER(adc_data, ctx),
1209 ADC_CONTEXT_INIT_LOCK(adc_data, ctx),
1210 ADC_CONTEXT_INIT_SYNC(adc_data, ctx),
1211 .dev = DEVICE_DT_GET(ADC_NODE),
1212 .channel_config = {
1213 /* Internal channels selection is hardwired */
1214 [LL_ADC_CHANNEL_VBAT] = {
1215 .vinput_range = LL_ADC_VIN_RANGE_3V6
1216 },
1217 [LL_ADC_CHANNEL_TEMPSENSOR] = {
1218 .vinput_range = LL_ADC_VIN_RANGE_1V2
1219 }
1220 },
1221 #if defined(CONFIG_ADC_STM32_DMA)
1222 .dmac_config = {
1223 .dma_slot = DT_INST_DMAS_CELL_BY_IDX(ADC_INSTANCE, 0, slot),
1224 .channel_direction = STM32_DMA_CONFIG_DIRECTION(
1225 STM32_DMA_CHANNEL_CONFIG_BY_IDX(ADC_INSTANCE, 0)),
1226 .channel_priority = STM32_DMA_CONFIG_PRIORITY(
1227 STM32_DMA_CHANNEL_CONFIG_BY_IDX(ADC_INSTANCE, 0)),
1228 .source_data_size = STM32_DMA_CONFIG_PERIPHERAL_DATA_SIZE(
1229 STM32_DMA_CHANNEL_CONFIG_BY_IDX(ADC_INSTANCE, 0)),
1230 .dest_data_size = STM32_DMA_CONFIG_MEMORY_DATA_SIZE(
1231 STM32_DMA_CHANNEL_CONFIG_BY_IDX(ADC_INSTANCE, 0)),
1232 .source_burst_length = 1, /* SINGLE transfer */
1233 .dest_burst_length = 1, /* SINGLE transfer */
1234 .block_count = 1,
1235 .dma_callback = adc_stm32wb0_dma_callback,
1236 /* head_block and user_data are initialized at runtime */
1237 },
1238 .dma_block_config = {
1239 .source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE,
1240 .source_reload_en = 0,
1241 .dest_addr_adj = DMA_ADDR_ADJ_INCREMENT,
1242 .dest_reload_en = 0,
1243 }
1244 #endif
1245 };
1246
1247 PM_DEVICE_DT_DEFINE(ADC_NODE, adc_stm32wb0_pm_action);
1248
1249 DEVICE_DT_DEFINE(ADC_NODE, &adc_stm32wb0_init, PM_DEVICE_DT_GET(ADC_NODE),
1250 &adc_data, &adc_config, POST_KERNEL, CONFIG_ADC_INIT_PRIORITY,
1251 &api_stm32wb0_driver_api);
1252