1010#include <zephyr/drivers/gpio.h>
1111#include <soc.h>
1212#include <nrfx_spis.h>
13+ #include <zephyr/pm/device.h>
14+ #include <zephyr/pm/device_runtime.h>
1315
1416#include <zephyr/logging/log.h>
1517#include <zephyr/irq.h>
@@ -175,6 +177,10 @@ static int transceive(const struct device *dev,
175177 const struct spi_buf * rx_buf = rx_bufs ? rx_bufs -> buffers : NULL ;
176178 int error ;
177179
180+ #if defined(CONFIG_PM_DEVICE_RUNTIME )
181+ pm_device_runtime_get (dev );
182+ #endif
183+
178184 spi_context_lock (& dev_data -> ctx , asynchronous , cb , userdata , spi_cfg );
179185
180186 error = configure (dev , spi_cfg );
@@ -282,9 +288,53 @@ static void event_handler(const nrfx_spis_evt_t *p_event, void *p_context)
282288 if (p_event -> evt_type == NRFX_SPIS_XFER_DONE ) {
283289 spi_context_complete (& dev_data -> ctx , dev_data -> dev ,
284290 p_event -> rx_amount );
291+
292+ #if defined(CONFIG_PM_DEVICE_RUNTIME )
293+ pm_device_runtime_put (dev_data -> dev );
294+ #endif
295+ }
296+ }
297+
298+ static void spi_nrfx_suspend (const struct device * dev )
299+ {
300+ const struct spi_nrfx_config * dev_config = dev -> config ;
301+
302+ if (dev_config -> wake_gpio .port == NULL ) {
303+ nrf_spis_disable (dev_config -> spis .p_reg );
304+ }
305+
306+ (void )pinctrl_apply_state (dev_config -> pcfg , PINCTRL_STATE_SLEEP );
307+ }
308+
309+ static void spi_nrfx_resume (const struct device * dev )
310+ {
311+ const struct spi_nrfx_config * dev_config = dev -> config ;
312+
313+ (void )pinctrl_apply_state (dev_config -> pcfg , PINCTRL_STATE_DEFAULT );
314+
315+ if (dev_config -> wake_gpio .port == NULL ) {
316+ nrf_spis_enable (dev_config -> spis .p_reg );
285317 }
286318}
287319
320+ static int spi_nrfx_pm_action (const struct device * dev , enum pm_device_action action )
321+ {
322+ switch (action ) {
323+ case PM_DEVICE_ACTION_SUSPEND :
324+ spi_nrfx_suspend (dev );
325+ return 0 ;
326+
327+ case PM_DEVICE_ACTION_RESUME :
328+ spi_nrfx_resume (dev );
329+ return 0 ;
330+
331+ default :
332+ break ;
333+ }
334+
335+ return - ENOTSUP ;
336+ }
337+
288338static int spi_nrfx_init (const struct device * dev )
289339{
290340 const struct spi_nrfx_config * dev_config = dev -> config ;
@@ -308,6 +358,16 @@ static int spi_nrfx_init(const struct device *dev)
308358 return - EBUSY ;
309359 }
310360
361+ /* When the WAKE line is used, the SPIS peripheral is enabled
362+ * only after the master signals that it wants to perform a
363+ * transfer and it is disabled right after the transfer is done.
364+ * Waiting for the WAKE line to go high, what can be done using
365+ * the GPIO PORT event, instead of just waiting for the transfer
366+ * with the SPIS peripheral enabled, significantly reduces idle
367+ * power consumption.
368+ */
369+ nrf_spis_disable (dev_config -> spis .p_reg );
370+
311371 if (dev_config -> wake_gpio .port ) {
312372 if (!gpio_is_ready_dt (& dev_config -> wake_gpio )) {
313373 return - ENODEV ;
@@ -332,21 +392,11 @@ static int spi_nrfx_init(const struct device *dev)
332392 if (err < 0 ) {
333393 return err ;
334394 }
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 );
345395 }
346396
347397 spi_context_unlock_unconditionally (& dev_data -> ctx );
348398
349- return 0 ;
399+ return pm_device_driver_init ( dev , spi_nrfx_pm_action ) ;
350400}
351401
352402/*
@@ -394,9 +444,10 @@ static int spi_nrfx_init(const struct device *dev)
394444 BUILD_ASSERT(!DT_NODE_HAS_PROP(SPIS(idx), wake_gpios) || \
395445 !(DT_GPIO_FLAGS(SPIS(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
396446 "WAKE line must be configured as active high"); \
447+ PM_DEVICE_DT_DEFINE(SPIS(idx), spi_nrfx_pm_action, 1); \
397448 SPI_DEVICE_DT_DEFINE(SPIS(idx), \
398449 spi_nrfx_init, \
399- NULL, \
450+ PM_DEVICE_DT_GET(SPIS(idx)), \
400451 &spi_##idx##_data, \
401452 &spi_##idx##z_config, \
402453 POST_KERNEL, \
0 commit comments