1212#include <soc.h>
1313#include <fsl_pwm.h>
1414#include <zephyr/drivers/pinctrl.h>
15+ #include <zephyr/kernel.h>
1516
1617#include <zephyr/logging/log.h>
1718
@@ -35,34 +36,17 @@ struct pwm_mcux_config {
3536struct pwm_mcux_data {
3637 uint32_t period_cycles [CHANNEL_COUNT ];
3738 pwm_signal_param_t channel [CHANNEL_COUNT ];
39+ struct k_mutex lock ;
3840};
3941
40- static int mcux_pwm_set_cycles (const struct device * dev , uint32_t channel ,
42+ static int mcux_pwm_set_cycles_internal (const struct device * dev , uint32_t channel ,
4143 uint32_t period_cycles , uint32_t pulse_cycles ,
4244 pwm_flags_t flags )
4345{
4446 const struct pwm_mcux_config * config = dev -> config ;
4547 struct pwm_mcux_data * data = dev -> data ;
4648 pwm_level_select_t level ;
4749
48- if (channel >= CHANNEL_COUNT ) {
49- LOG_ERR ("Invalid channel" );
50- return - EINVAL ;
51- }
52-
53- if (period_cycles == 0 ) {
54- LOG_ERR ("Channel can not be set to inactive level" );
55- return - ENOTSUP ;
56- }
57-
58- if (period_cycles > UINT16_MAX ) {
59- /* 16-bit resolution */
60- LOG_ERR ("Too long period (%u), adjust pwm prescaler!" ,
61- period_cycles );
62- /* TODO: dynamically adjust prescaler */
63- return - EINVAL ;
64- }
65-
6650 if (flags & PWM_POLARITY_INVERTED ) {
6751 level = kPWM_LowTrue ;
6852 } else {
@@ -158,6 +142,36 @@ static int mcux_pwm_set_cycles(const struct device *dev, uint32_t channel,
158142 return 0 ;
159143}
160144
145+ static int mcux_pwm_set_cycles (const struct device * dev , uint32_t channel ,
146+ uint32_t period_cycles , uint32_t pulse_cycles ,
147+ pwm_flags_t flags )
148+ {
149+ struct pwm_mcux_data * data = dev -> data ;
150+ int result ;
151+
152+ if (channel >= CHANNEL_COUNT ) {
153+ LOG_ERR ("Invalid channel" );
154+ return - EINVAL ;
155+ }
156+
157+ if (period_cycles == 0 ) {
158+ LOG_ERR ("Channel can not be set to inactive level" );
159+ return - ENOTSUP ;
160+ }
161+
162+ if (period_cycles > UINT16_MAX ) {
163+ /* 16-bit resolution */
164+ LOG_ERR ("Too long period (%u), adjust pwm prescaler!" ,
165+ period_cycles );
166+ /* TODO: dynamically adjust prescaler */
167+ return - EINVAL ;
168+ }
169+ k_mutex_lock (& data -> lock , K_FOREVER );
170+ result = mcux_pwm_set_cycles_internal (dev , channel , period_cycles , pulse_cycles , flags );
171+ k_mutex_unlock (& data -> lock );
172+ return result ;
173+ }
174+
161175static int mcux_pwm_get_cycles_per_sec (const struct device * dev ,
162176 uint32_t channel , uint64_t * cycles )
163177{
@@ -181,6 +195,8 @@ static int pwm_mcux_init(const struct device *dev)
181195 status_t status ;
182196 int i , err ;
183197
198+ k_mutex_init (& data -> lock );
199+
184200 if (!device_is_ready (config -> clock_dev )) {
185201 LOG_ERR ("clock control device not ready" );
186202 return - ENODEV ;
0 commit comments