10
10
#include <zephyr/drivers/gpio.h>
11
11
#include <soc.h>
12
12
#include <nrfx_spis.h>
13
+ #include <zephyr/pm/device.h>
14
+ #include <zephyr/pm/device_runtime.h>
13
15
14
16
#include <zephyr/logging/log.h>
15
17
#include <zephyr/irq.h>
@@ -175,6 +177,8 @@ static int transceive(const struct device *dev,
175
177
const struct spi_buf * rx_buf = rx_bufs ? rx_bufs -> buffers : NULL ;
176
178
int error ;
177
179
180
+ pm_device_runtime_get (dev );
181
+
178
182
spi_context_lock (& dev_data -> ctx , asynchronous , cb , userdata , spi_cfg );
179
183
180
184
error = configure (dev , spi_cfg );
@@ -282,7 +286,49 @@ static void event_handler(const nrfx_spis_evt_t *p_event, void *p_context)
282
286
if (p_event -> evt_type == NRFX_SPIS_XFER_DONE ) {
283
287
spi_context_complete (& dev_data -> ctx , dev_data -> dev ,
284
288
p_event -> rx_amount );
289
+
290
+ pm_device_runtime_put (dev_data -> dev );
291
+ }
292
+ }
293
+
294
+ static void spi_nrfx_suspend (const struct device * dev )
295
+ {
296
+ const struct spi_nrfx_config * dev_config = dev -> config ;
297
+
298
+ if (dev_config -> wake_gpio .port == NULL ) {
299
+ nrf_spis_disable (dev_config -> spis .p_reg );
300
+ }
301
+
302
+ (void )pinctrl_apply_state (dev_config -> pcfg , PINCTRL_STATE_SLEEP );
303
+ }
304
+
305
+ static void spi_nrfx_resume (const struct device * dev )
306
+ {
307
+ const struct spi_nrfx_config * dev_config = dev -> config ;
308
+
309
+ (void )pinctrl_apply_state (dev_config -> pcfg , PINCTRL_STATE_DEFAULT );
310
+
311
+ if (dev_config -> wake_gpio .port == NULL ) {
312
+ nrf_spis_enable (dev_config -> spis .p_reg );
313
+ }
314
+ }
315
+
316
+ static int spi_nrfx_pm_action (const struct device * dev , enum pm_device_action action )
317
+ {
318
+ switch (action ) {
319
+ case PM_DEVICE_ACTION_SUSPEND :
320
+ spi_nrfx_suspend (dev );
321
+ return 0 ;
322
+
323
+ case PM_DEVICE_ACTION_RESUME :
324
+ spi_nrfx_resume (dev );
325
+ return 0 ;
326
+
327
+ default :
328
+ break ;
285
329
}
330
+
331
+ return - ENOTSUP ;
286
332
}
287
333
288
334
static int spi_nrfx_init (const struct device * dev )
@@ -308,6 +354,16 @@ static int spi_nrfx_init(const struct device *dev)
308
354
return - EBUSY ;
309
355
}
310
356
357
+ /* When the WAKE line is used, the SPIS peripheral is enabled
358
+ * only after the master signals that it wants to perform a
359
+ * transfer and it is disabled right after the transfer is done.
360
+ * Waiting for the WAKE line to go high, what can be done using
361
+ * the GPIO PORT event, instead of just waiting for the transfer
362
+ * with the SPIS peripheral enabled, significantly reduces idle
363
+ * power consumption.
364
+ */
365
+ nrf_spis_disable (dev_config -> spis .p_reg );
366
+
311
367
if (dev_config -> wake_gpio .port ) {
312
368
if (!gpio_is_ready_dt (& dev_config -> wake_gpio )) {
313
369
return - ENODEV ;
@@ -332,21 +388,11 @@ static int spi_nrfx_init(const struct device *dev)
332
388
if (err < 0 ) {
333
389
return err ;
334
390
}
335
-
336
- /* When the WAKE line is used, the SPIS peripheral is enabled
337
- * only after the master signals that it wants to perform a
338
- * transfer and it is disabled right after the transfer is done.
339
- * Waiting for the WAKE line to go high, what can be done using
340
- * the GPIO PORT event, instead of just waiting for the transfer
341
- * with the SPIS peripheral enabled, significantly reduces idle
342
- * power consumption.
343
- */
344
- nrf_spis_disable (dev_config -> spis .p_reg );
345
391
}
346
392
347
393
spi_context_unlock_unconditionally (& dev_data -> ctx );
348
394
349
- return 0 ;
395
+ return pm_device_driver_init ( dev , spi_nrfx_pm_action ) ;
350
396
}
351
397
352
398
/*
@@ -394,9 +440,10 @@ static int spi_nrfx_init(const struct device *dev)
394
440
BUILD_ASSERT(!DT_NODE_HAS_PROP(SPIS(idx), wake_gpios) || \
395
441
!(DT_GPIO_FLAGS(SPIS(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
396
442
"WAKE line must be configured as active high"); \
443
+ PM_DEVICE_DT_DEFINE(SPIS(idx), spi_nrfx_pm_action, 1); \
397
444
SPI_DEVICE_DT_DEFINE(SPIS(idx), \
398
445
spi_nrfx_init, \
399
- NULL, \
446
+ PM_DEVICE_DT_GET(SPIS(idx)), \
400
447
&spi_##idx##_data, \
401
448
&spi_##idx##z_config, \
402
449
POST_KERNEL, \
0 commit comments