|
10 | 10 | #include <zephyr/dt-bindings/adc/nrf-saadc-v3.h> |
11 | 11 | #include <zephyr/dt-bindings/adc/nrf-saadc-nrf54l.h> |
12 | 12 | #include <zephyr/linker/devicetree_regions.h> |
| 13 | +#include <zephyr/pm/device.h> |
| 14 | +#include <zephyr/pm/device_runtime.h> |
13 | 15 |
|
14 | 16 | #define LOG_LEVEL CONFIG_ADC_LOG_LEVEL |
15 | 17 | #include <zephyr/logging/log.h> |
@@ -168,6 +170,26 @@ static int adc_convert_acq_time(uint16_t acquisition_time, nrf_saadc_acqtime_t * |
168 | 170 | return result; |
169 | 171 | } |
170 | 172 |
|
| 173 | +static int saadc_pm_hook(const struct device *dev, enum pm_device_action action) |
| 174 | +{ |
| 175 | + ARG_UNUSED(dev); |
| 176 | + |
| 177 | + switch (action) { |
| 178 | + case PM_DEVICE_ACTION_SUSPEND: |
| 179 | + nrf_saadc_disable(NRF_SAADC); |
| 180 | + return 0; |
| 181 | + |
| 182 | + case PM_DEVICE_ACTION_RESUME: |
| 183 | + nrf_saadc_enable(NRF_SAADC); |
| 184 | + return 0; |
| 185 | + |
| 186 | + default: |
| 187 | + break; |
| 188 | + } |
| 189 | + |
| 190 | + return -ENOTSUP; |
| 191 | +} |
| 192 | + |
171 | 193 | /* Implementation of the ADC driver API function: adc_channel_setup. */ |
172 | 194 | static int adc_nrfx_channel_setup(const struct device *dev, |
173 | 195 | const struct adc_channel_cfg *channel_cfg) |
@@ -320,7 +342,11 @@ static int adc_nrfx_channel_setup(const struct device *dev, |
320 | 342 |
|
321 | 343 | static void adc_context_start_sampling(struct adc_context *ctx) |
322 | 344 | { |
| 345 | +#if defined(CONFIG_PM_DEVICE_RUNTIME) |
| 346 | + pm_device_runtime_get(DEVICE_DT_INST_GET(0)); |
| 347 | +#else |
323 | 348 | nrf_saadc_enable(NRF_SAADC); |
| 349 | +#endif |
324 | 350 |
|
325 | 351 | if (ctx->sequence.calibrate) { |
326 | 352 | nrf_saadc_task_trigger(NRF_SAADC, |
@@ -623,7 +649,12 @@ static void saadc_irq_handler(const struct device *dev) |
623 | 649 | nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END); |
624 | 650 |
|
625 | 651 | nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP); |
| 652 | + |
| 653 | +#if defined(CONFIG_PM_DEVICE_RUNTIME) |
| 654 | + pm_device_runtime_put(DEVICE_DT_INST_GET(0)); |
| 655 | +#else |
626 | 656 | nrf_saadc_disable(NRF_SAADC); |
| 657 | +#endif |
627 | 658 |
|
628 | 659 | if (has_single_ended(&m_data.ctx.sequence)) { |
629 | 660 | correct_single_ended(&m_data.ctx.sequence); |
@@ -663,7 +694,7 @@ static int init_saadc(const struct device *dev) |
663 | 694 |
|
664 | 695 | adc_context_unlock_unconditionally(&m_data.ctx); |
665 | 696 |
|
666 | | - return 0; |
| 697 | + return pm_device_driver_init(dev, saadc_pm_hook); |
667 | 698 | } |
668 | 699 |
|
669 | 700 | static DEVICE_API(adc, adc_nrfx_driver_api) = { |
@@ -693,9 +724,10 @@ static DEVICE_API(adc, adc_nrfx_driver_api) = { |
693 | 724 | #define SAADC_INIT(inst) \ |
694 | 725 | BUILD_ASSERT((inst) == 0, \ |
695 | 726 | "multiple instances not supported"); \ |
| 727 | + PM_DEVICE_DT_INST_DEFINE(0, saadc_pm_hook, 1); \ |
696 | 728 | DEVICE_DT_INST_DEFINE(0, \ |
697 | 729 | init_saadc, \ |
698 | | - NULL, \ |
| 730 | + PM_DEVICE_DT_INST_GET(0), \ |
699 | 731 | NULL, \ |
700 | 732 | NULL, \ |
701 | 733 | POST_KERNEL, \ |
|
0 commit comments