Skip to content

Commit afa9528

Browse files
drivers: power_domain: add nrfs_swext driver
Add power domain driver for nordic nrfs swext power domain. Signed-off-by: Bjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>
1 parent 244df6d commit afa9528

File tree

4 files changed

+174
-0
lines changed

4 files changed

+174
-0
lines changed

drivers/power_domain/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO power_domain_gpio.c)
77
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO_MONITOR power_domain_gpio_monitor.c)
88
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_INTEL_ADSP power_domain_intel_adsp.c)
99
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NXP_SCU power_domain_nxp_scu.c)
10+
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_NRFS_SWEXT power_domain_nrfs_swext.c)
1011
zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_SOC_PM_STATE power_domain_soc_state_change.c)

drivers/power_domain/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,6 @@ config POWER_DOMAIN_SOC_PM_STATE
9999
Generic power domain control to turn on/off devices when the
100100
PM subsystem transitions in and out certain power states.
101101

102+
rsource "Kconfig.nrfs_swext"
103+
102104
endif
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright 2025 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config POWER_DOMAIN_NRFS_SWEXT
5+
bool "NRFS SWEXT power domain driver"
6+
depends on DT_HAS_NORDIC_NRFS_SWEXT_ENABLED
7+
depends on NRFS
8+
depends on NRFS_SWEXT_SERVICE_ENABLED
9+
default y
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT nordic_nrfs_swext
8+
9+
#include <zephyr/kernel.h>
10+
#include <zephyr/device.h>
11+
#include <zephyr/pm/device.h>
12+
#include <zephyr/logging/log.h>
13+
14+
#include <nrfs_swext.h>
15+
#include <nrfs_backend_ipc_service.h>
16+
17+
LOG_MODULE_REGISTER(nrfs_swext, CONFIG_POWER_DOMAIN_LOG_LEVEL);
18+
19+
BUILD_ASSERT(
20+
DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1,
21+
"multiple instances not supported"
22+
);
23+
24+
struct nrfs_swext_data {
25+
struct k_sem evt_sem;
26+
nrfs_swext_evt_type_t evt;
27+
};
28+
29+
struct nrfs_swext_config {
30+
uint16_t current_limit_ua;
31+
bool enable_power_down_clamp;
32+
};
33+
34+
static void nrfs_swext_driver_evt_handler(nrfs_swext_evt_t const *p_evt, void *context)
35+
{
36+
struct nrfs_swext_data *dev_data = context;
37+
38+
LOG_DBG("evt %u", (uint32_t)p_evt->type);
39+
40+
if (p_evt->type == NRFS_SWEXT_EVT_OVERCURRENT) {
41+
/* Overcurrent is an unrecoverable condition which requires hardware fix */
42+
LOG_ERR("overcurrent");
43+
k_panic();
44+
};
45+
46+
dev_data->evt = p_evt->type;
47+
k_sem_give(&dev_data->evt_sem);
48+
}
49+
50+
static int nrfs_swext_driver_suspend(const struct device *dev)
51+
{
52+
struct nrfs_swext_data *dev_data = dev->data;
53+
const struct nrfs_swext_config *dev_config = dev->config;
54+
nrfs_err_t err;
55+
swext_pd_clamp_t pd_clamp = dev_config->enable_power_down_clamp
56+
? SWEXT_PD_CLAMP_ENABLED
57+
: SWEXT_PD_CLAMP_DISABLED;
58+
59+
err = nrfs_swext_power_down(pd_clamp, dev_data);
60+
if (err != NRFS_SUCCESS) {
61+
LOG_ERR("failed to request power up");
62+
return -ENODEV;
63+
}
64+
65+
(void)k_sem_take(&dev_data->evt_sem, K_FOREVER);
66+
67+
if (dev_data->evt == NRFS_SWEXT_EVT_ENABLED) {
68+
return 0;
69+
}
70+
71+
LOG_ERR("power down request rejected");
72+
return -EIO;
73+
}
74+
75+
static int nrfs_swext_driver_resume(const struct device *dev)
76+
{
77+
struct nrfs_swext_data *dev_data = dev->data;
78+
const struct nrfs_swext_config *dev_config = dev->config;
79+
nrfs_err_t err;
80+
uint8_t load_current;
81+
82+
load_current = nrfs_swext_load_current_to_raw(dev_config->current_limit_ua);
83+
err = nrfs_swext_power_up(load_current, dev_data);
84+
if (err != NRFS_SUCCESS) {
85+
LOG_ERR("failed to request power up");
86+
return -ENODEV;
87+
}
88+
89+
(void)k_sem_take(&dev_data->evt_sem, K_FOREVER);
90+
91+
if (dev_data->evt == NRFS_SWEXT_EVT_ENABLED) {
92+
return 0;
93+
}
94+
95+
LOG_ERR("power up request rejected");
96+
return -EIO;
97+
}
98+
99+
static int nrfs_swext_driver_pm_action(const struct device *dev, enum pm_device_action action)
100+
{
101+
int ret;
102+
103+
switch (action) {
104+
case PM_DEVICE_ACTION_SUSPEND:
105+
ret = nrfs_swext_driver_suspend(dev);
106+
break;
107+
108+
case PM_DEVICE_ACTION_RESUME:
109+
ret = nrfs_swext_driver_resume(dev);
110+
break;
111+
112+
default:
113+
ret = -ENOTSUP;
114+
break;
115+
};
116+
117+
return ret;
118+
}
119+
120+
static int nrfs_swext_driver_init(const struct device *dev)
121+
{
122+
struct nrfs_swext_data *dev_data = dev->data;
123+
nrfs_err_t err;
124+
125+
LOG_DBG("waiting for nrfs backend connected");
126+
err = nrfs_backend_wait_for_connection(K_FOREVER);
127+
if (err != NRFS_SUCCESS) {
128+
LOG_ERR("nrfs backend not connected");
129+
return -ENODEV;
130+
}
131+
132+
err = nrfs_swext_init(nrfs_swext_driver_evt_handler);
133+
if (err != NRFS_SUCCESS) {
134+
LOG_ERR("failed to init swext service");
135+
return -ENODEV;
136+
}
137+
138+
k_sem_init(&dev_data->evt_sem, 0, 1);
139+
return pm_device_driver_init(dev, nrfs_swext_driver_pm_action);
140+
}
141+
142+
PM_DEVICE_DT_INST_DEFINE(0, power_domain_driver_pm_action);
143+
144+
BUILD_ASSERT(DT_INST_PROP(0, max_current_ua) <= UINT16_MAX);
145+
BUILD_ASSERT(DT_INST_PROP(0, current_limit_ua) <= DT_INST_PROP(0, max_current_ua));
146+
147+
static struct nrfs_swext_data data0;
148+
static const struct nrfs_swext_config config0 = {
149+
.current_limit_ua = DT_INST_PROP(0, current_limit_ua),
150+
.enable_power_down_clamp = DT_INST_PROP(0, power_down_clamp),
151+
};
152+
153+
DEVICE_DT_INST_DEFINE(
154+
0,
155+
nrfs_swext_driver_init,
156+
PM_DEVICE_DT_INST_GET(inst),
157+
&data0,
158+
&config0,
159+
POST_KERNEL,
160+
UTIL_INC(CONFIG_NRFS_BACKEND_IPC_SERVICE_INIT_PRIO),
161+
NULL
162+
);

0 commit comments

Comments
 (0)