Skip to content

Commit afd2962

Browse files
bogdanovscfriedt
authored andcommitted
drivers: pwm: cc23x0: Add power management
Add PM support for PWM (LGPT0, LGPT1, LGPT2 and LGPT3) to cc23x0 SoC. Signed-off-by: Stoyan Bogdanov <[email protected]>
1 parent b04384b commit afd2962

File tree

1 file changed

+55
-6
lines changed

1 file changed

+55
-6
lines changed

drivers/pwm/pwm_cc23x0_timer.c

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include <zephyr/drivers/pinctrl.h>
1010
#include <zephyr/drivers/pwm.h>
11+
#include <zephyr/pm/device.h>
12+
#include <zephyr/pm/policy.h>
1113

1214
#include <driverlib/gpio.h>
1315
#include <driverlib/clkctl.h>
@@ -34,13 +36,33 @@ struct pwm_cc23x0_config {
3436
const struct pinctrl_dev_config *pcfg;
3537
};
3638

39+
static inline void pwm_cc23x0_pm_policy_state_lock_get(void)
40+
{
41+
#ifdef CONFIG_PM_DEVICE
42+
pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);
43+
pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
44+
#endif
45+
}
46+
47+
static inline void pwm_cc23x0_pm_policy_state_lock_put(void)
48+
{
49+
#ifdef CONFIG_PM_DEVICE
50+
pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
51+
pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);
52+
#endif
53+
}
54+
3755
static int pwm_cc23x0_set_cycles(const struct device *dev, uint32_t channel, uint32_t period,
3856
uint32_t pulse, pwm_flags_t flags)
3957
{
4058
const struct pwm_cc23x0_config *config = dev->config;
4159

4260
LOG_DBG("set cycles period[%x] pulse[%x]", period, pulse);
4361

62+
if (pulse == 0) {
63+
pwm_cc23x0_pm_policy_state_lock_get();
64+
}
65+
4466
if ((config->base != LGPT3_BASE) && (pulse > 0xffff || period > 0xffff || pulse > period)) {
4567
/* LGPT0, LGPT1, LGPT2 - 16bit counters */
4668
LOG_ERR("Period of pulse out of range");
@@ -72,6 +94,10 @@ static int pwm_cc23x0_set_cycles(const struct device *dev, uint32_t channel, uin
7294
/* Activate LGPT */
7395
HWREG(config->base + LGPT_O_STARTCFG) = 0x1;
7496

97+
if (pulse > 0) {
98+
pwm_cc23x0_pm_policy_state_lock_put();
99+
}
100+
75101
return 0;
76102
}
77103

@@ -90,7 +116,7 @@ static const struct pwm_driver_api pwm_cc23x0_driver_api = {
90116
.get_cycles_per_sec = pwm_cc23x0_get_cycles_per_sec,
91117
};
92118

93-
static int pwm_cc23x0_activate_clock(const struct device *dev)
119+
static int pwm_cc23x0_clock_action(const struct device *dev, bool activate)
94120
{
95121
const struct pwm_cc23x0_config *config = dev->config;
96122
struct pwm_cc23x0_data *data = dev->data;
@@ -113,13 +139,35 @@ static int pwm_cc23x0_activate_clock(const struct device *dev)
113139
return -EINVAL;
114140
}
115141

116-
CLKCTLEnable(CLKCTL_BASE, lgpt_clk_id);
117-
HWREG(config->base + LGPT_O_PRECFG) = LGPT_CLK_PRESCALE(data->prescale);
118-
HWREG(EVTSVT_BASE + EVTSVT_O_LGPTSYNCSEL) = EVTSVT_LGPTSYNCSEL_PUBID_SYSTIM0;
142+
if (activate) {
143+
CLKCTLEnable(CLKCTL_BASE, lgpt_clk_id);
144+
HWREG(config->base + LGPT_O_PRECFG) = LGPT_CLK_PRESCALE(data->prescale);
145+
HWREG(EVTSVT_BASE + EVTSVT_O_LGPTSYNCSEL) = EVTSVT_LGPTSYNCSEL_PUBID_SYSTIM0;
146+
} else {
147+
CLKCTLDisable(CLKCTL_BASE, lgpt_clk_id);
148+
}
119149

120150
return 0;
121151
}
122152

153+
#ifdef CONFIG_PM_DEVICE
154+
155+
static int pwm_cc23x0_pm_action(const struct device *dev, enum pm_device_action action)
156+
{
157+
switch (action) {
158+
case PM_DEVICE_ACTION_SUSPEND:
159+
pwm_cc23x0_clock_action(dev, false);
160+
return 0;
161+
case PM_DEVICE_ACTION_RESUME:
162+
pwm_cc23x0_clock_action(dev, true);
163+
return 0;
164+
default:
165+
return -ENOTSUP;
166+
}
167+
}
168+
169+
#endif /* CONFIG_PM_DEVICE */
170+
123171
#define DT_TIMER(idx) DT_INST_PARENT(idx)
124172
#define DT_TIMER_BASE_ADDR(idx) (DT_REG_ADDR(DT_TIMER(idx)))
125173

@@ -137,12 +185,13 @@ static int pwm_cc23x0_init(const struct device *dev)
137185
return ret;
138186
}
139187

140-
pwm_cc23x0_activate_clock(dev);
188+
pwm_cc23x0_clock_action(dev, true);
141189

142190
return 0;
143191
}
144192

145193
#define PWM_DEVICE_INIT(idx) \
194+
PM_DEVICE_DT_INST_DEFINE(idx, pwm_cc23x0_pm_action); \
146195
PINCTRL_DT_INST_DEFINE(idx); \
147196
LOG_INSTANCE_REGISTER(LOG_MODULE_NAME, idx, CONFIG_PWM_LOG_LEVEL); \
148197
\
@@ -156,7 +205,7 @@ static int pwm_cc23x0_init(const struct device *dev)
156205
.base_clk = DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency), \
157206
}; \
158207
\
159-
DEVICE_DT_INST_DEFINE(idx, pwm_cc23x0_init, NULL, &pwm_cc23x0_##idx##_data, \
208+
DEVICE_DT_INST_DEFINE(idx, pwm_cc23x0_init, NULL, &pwm_cc23x0_##idx##_data, \
160209
&pwm_cc23x0_##idx##_config, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \
161210
&pwm_cc23x0_driver_api)
162211

0 commit comments

Comments
 (0)