Skip to content

Commit 7e93016

Browse files
bjarki-andreasenkartben
authored andcommitted
drivers: spi: nrfx_spis: impl pm device runtime
Implement PM device runtime in nrx spis device driver. Signed-off-by: Bjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>
1 parent 97ee3e8 commit 7e93016

File tree

1 file changed

+59
-12
lines changed

1 file changed

+59
-12
lines changed

drivers/spi/spi_nrfx_spis.c

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
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,8 @@ 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+
pm_device_runtime_get(dev);
181+
178182
spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg);
179183

180184
error = configure(dev, spi_cfg);
@@ -282,7 +286,49 @@ static void event_handler(const nrfx_spis_evt_t *p_event, void *p_context)
282286
if (p_event->evt_type == NRFX_SPIS_XFER_DONE) {
283287
spi_context_complete(&dev_data->ctx, dev_data->dev,
284288
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;
285329
}
330+
331+
return -ENOTSUP;
286332
}
287333

288334
static int spi_nrfx_init(const struct device *dev)
@@ -308,6 +354,16 @@ static int spi_nrfx_init(const struct device *dev)
308354
return -EBUSY;
309355
}
310356

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+
311367
if (dev_config->wake_gpio.port) {
312368
if (!gpio_is_ready_dt(&dev_config->wake_gpio)) {
313369
return -ENODEV;
@@ -332,21 +388,11 @@ static int spi_nrfx_init(const struct device *dev)
332388
if (err < 0) {
333389
return err;
334390
}
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);
345391
}
346392

347393
spi_context_unlock_unconditionally(&dev_data->ctx);
348394

349-
return 0;
395+
return pm_device_driver_init(dev, spi_nrfx_pm_action);
350396
}
351397

352398
/*
@@ -394,9 +440,10 @@ static int spi_nrfx_init(const struct device *dev)
394440
BUILD_ASSERT(!DT_NODE_HAS_PROP(SPIS(idx), wake_gpios) || \
395441
!(DT_GPIO_FLAGS(SPIS(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
396442
"WAKE line must be configured as active high"); \
443+
PM_DEVICE_DT_DEFINE(SPIS(idx), spi_nrfx_pm_action, 1); \
397444
SPI_DEVICE_DT_DEFINE(SPIS(idx), \
398445
spi_nrfx_init, \
399-
NULL, \
446+
PM_DEVICE_DT_GET(SPIS(idx)), \
400447
&spi_##idx##_data, \
401448
&spi_##idx##z_config, \
402449
POST_KERNEL, \

0 commit comments

Comments
 (0)