Skip to content

Commit de53fb2

Browse files
committed
[nrf fromlist] drivers: sensor: nordic: qdec: Add runtime PM
Add runtime PM to the driver. Upstream PR: zephyrproject-rtos/zephyr#78660 Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent b83478a commit de53fb2

File tree

1 file changed

+50
-52
lines changed

1 file changed

+50
-52
lines changed

drivers/sensor/nordic/qdec_nrfx/qdec_nrfx.c

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <zephyr/drivers/sensor.h>
88
#include <zephyr/pm/device.h>
9+
#include <zephyr/pm/device_runtime.h>
910
#include <zephyr/drivers/pinctrl.h>
1011
#include <soc.h>
1112

@@ -173,81 +174,78 @@ static const struct sensor_driver_api qdec_nrfx_driver_api = {
173174
.trigger_set = qdec_nrfx_trigger_set,
174175
};
175176

176-
#ifdef CONFIG_PM_DEVICE
177-
static int qdec_nrfx_pm_action(const struct device *dev,
178-
enum pm_device_action action)
177+
static int qdec_pm_suspend(const struct device *dev)
179178
{
180179
const struct qdec_nrfx_config *config = dev->config;
181-
int ret = 0;
180+
181+
nrfx_qdec_disable(&config->qdec);
182+
qdec_nrfx_gpio_ctrl(dev, false);
183+
184+
if (!IS_ENABLED(CONFIG_PM_DEVICE)) {
185+
return 0;
186+
}
187+
188+
return pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
189+
}
190+
191+
static int qdec_pm_resume(const struct device *dev)
192+
{
193+
const struct qdec_nrfx_config *config = dev->config;
194+
int ret;
195+
196+
ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
197+
if (ret < 0) {
198+
return ret;
199+
}
200+
201+
qdec_nrfx_gpio_ctrl(dev, true);
202+
nrfx_qdec_enable(&config->qdec);
203+
204+
return 0;
205+
}
206+
207+
static int qdec_nrfx_pm_action(const struct device *dev, enum pm_device_action action)
208+
{
209+
int ret = -ENOTSUP;
182210

183211
switch (action) {
184212
case PM_DEVICE_ACTION_RESUME:
185-
ret = pinctrl_apply_state(config->pcfg,
186-
PINCTRL_STATE_DEFAULT);
187-
if (ret < 0) {
188-
return ret;
189-
}
190-
qdec_nrfx_gpio_ctrl(dev, true);
191-
nrfx_qdec_enable(&config->qdec);
192-
break;
193-
194-
case PM_DEVICE_ACTION_TURN_OFF:
195-
/* device must be uninitialized */
196-
nrfx_qdec_uninit(&config->qdec);
197-
ret = pinctrl_apply_state(config->pcfg,
198-
PINCTRL_STATE_SLEEP);
199-
if (ret < 0) {
200-
return ret;
201-
}
213+
ret = qdec_pm_resume(dev);
202214
break;
203215

204216
case PM_DEVICE_ACTION_SUSPEND:
205-
/* device must be suspended */
206-
nrfx_qdec_disable(&config->qdec);
207-
qdec_nrfx_gpio_ctrl(dev, false);
208-
ret = pinctrl_apply_state(config->pcfg,
209-
PINCTRL_STATE_SLEEP);
210-
if (ret < 0) {
211-
return ret;
217+
if (IS_ENABLED(CONFIG_PM_DEVICE)) {
218+
ret = qdec_pm_suspend(dev);
212219
}
213220
break;
214221
default:
215-
return -ENOTSUP;
222+
break;
216223
}
217224

218225
return ret;
219226
}
220-
#endif /* CONFIG_PM_DEVICE */
221227

222228
static int qdec_nrfx_init(const struct device *dev)
223229
{
224-
const struct qdec_nrfx_config *dev_config = dev->config;
225-
226-
dev_config->irq_connect();
230+
const struct qdec_nrfx_config *config = dev->config;
231+
int ret;
232+
nrfx_err_t nerr;
227233

228-
int err = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT);
234+
config->irq_connect();
229235

230-
if (err < 0) {
231-
return err;
236+
nerr = nrfx_qdec_init(&config->qdec, &config->config, qdec_nrfx_event_handler, (void *)dev);
237+
if (nerr != NRFX_SUCCESS) {
238+
return (nerr == NRFX_ERROR_INVALID_STATE) ? -EBUSY : -EFAULT;
232239
}
233240

234-
nrfx_err_t nerr = nrfx_qdec_init(&dev_config->qdec,
235-
&dev_config->config,
236-
qdec_nrfx_event_handler,
237-
(void *)dev);
238-
239-
if (nerr == NRFX_ERROR_INVALID_STATE) {
240-
LOG_ERR("qdec already in use");
241-
return -EBUSY;
242-
} else if (nerr != NRFX_SUCCESS) {
243-
LOG_ERR("failed to initialize qdec");
244-
return -EFAULT;
241+
if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
242+
ret = qdec_pm_suspend(dev);
243+
if (ret < 0) {
244+
return ret;
245+
}
245246
}
246247

247-
qdec_nrfx_gpio_ctrl(dev, true);
248-
nrfx_qdec_enable(&dev_config->qdec);
249-
250-
return 0;
248+
return pm_device_driver_init(dev, qdec_nrfx_pm_action);
251249
}
252250

253251
#define QDEC(idx) DT_NODELABEL(qdec##idx)
@@ -282,7 +280,7 @@ static int qdec_nrfx_init(const struct device *dev)
282280
.enable_pin = DT_PROP_OR(QDEC(idx), enable_pin, NRF_QDEC_PIN_NOT_CONNECTED), \
283281
.steps = QDEC_PROP(idx, steps), \
284282
}; \
285-
PM_DEVICE_DT_DEFINE(QDEC(idx), qdec_nrfx_pm_action); \
283+
PM_DEVICE_DT_DEFINE(QDEC(idx), qdec_nrfx_pm_action, PM_DEVICE_ISR_SAFE); \
286284
SENSOR_DEVICE_DT_DEFINE(QDEC(idx), \
287285
qdec_nrfx_init, \
288286
PM_DEVICE_DT_GET(QDEC(idx)), \

0 commit comments

Comments
 (0)