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+
3755static 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