-
Notifications
You must be signed in to change notification settings - Fork 3
PWM with power management fix #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
| #include <zephyr/drivers/pinctrl.h> | ||
| #include <zephyr/drivers/clock_control.h> | ||
| #include <zephyr/pm/device.h> | ||
| #include <zephyr/pm/device_runtime.h> | ||
| #include <zephyr/types.h> | ||
| #include "sl_si91x_pwm.h" | ||
|
|
||
|
|
@@ -121,24 +122,28 @@ static int pwm_siwx91x_set_cycles(const struct device *dev, uint32_t channel, | |
| return -ENOTSUP; | ||
| } | ||
|
|
||
| if (pulse_cycles > 0 && data->pwm_channel_cfg[channel].is_chan_active == false) { | ||
| pm_device_runtime_get(dev); | ||
| } | ||
|
|
||
| if (data->pwm_channel_cfg[channel].is_chan_active == false) { | ||
| /* Configure the channel with default parameters */ | ||
| ret = siwx91x_default_channel_config(dev, channel); | ||
| if (ret) { | ||
| return -EINVAL; | ||
| goto out; | ||
| } | ||
| } | ||
|
|
||
| ret = sl_si91x_pwm_get_time_period(channel, (uint16_t *)&prev_period); | ||
| if (ret) { | ||
| return -EINVAL; | ||
| goto out; | ||
| } | ||
|
|
||
| if (period_cycles != prev_period) { | ||
| ret = sl_si91x_pwm_set_time_period(channel, period_cycles, 0); | ||
| if (ret) { | ||
| /* Programmed value must be out of range (>65535) */ | ||
| return -EINVAL; | ||
| goto out; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -149,7 +154,7 @@ static int pwm_siwx91x_set_cycles(const struct device *dev, uint32_t channel, | |
| if (duty_cycle != data->pwm_channel_cfg[channel].duty_cycle) { | ||
| ret = sl_si91x_pwm_set_duty_cycle(pulse_cycles, channel); | ||
| if (ret) { | ||
| return -EINVAL; | ||
| goto out; | ||
| } | ||
| data->pwm_channel_cfg[channel].duty_cycle = duty_cycle; | ||
| } | ||
|
|
@@ -158,12 +163,22 @@ static int pwm_siwx91x_set_cycles(const struct device *dev, uint32_t channel, | |
| /* Start PWM after configuring the channel for first time */ | ||
| ret = sl_si91x_pwm_start(channel); | ||
| if (ret) { | ||
| return -EINVAL; | ||
| goto out; | ||
| } | ||
| data->pwm_channel_cfg[channel].is_chan_active = true; | ||
| } | ||
|
|
||
| if (pulse_cycles == 0 && data->pwm_channel_cfg[channel].is_chan_active == true) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor:
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree, I've to admit that I've reapplied the existing pattern in the function but that's a fair point. Will do that in another PR if that's ok for you. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure |
||
| pm_device_runtime_put(dev); | ||
| data->pwm_channel_cfg[channel].is_chan_active = false; | ||
| } | ||
|
|
||
| return 0; | ||
|
|
||
| out: | ||
| pm_device_runtime_put(dev); | ||
| data->pwm_channel_cfg[channel].is_chan_active = false; | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| static int pwm_siwx91x_get_cycles_per_sec(const struct device *dev, uint32_t channel, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use devicetree for this:
DT_PROP(DT_NODELABEL(cpu0), clock_frequency)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we have a debate about that with Jérôme Pouiller (@jerome-pouiller), SystemCoreClock is actually the real Core clock value updated dynamically in Wiseconnect. But fair point, will use DT_PROP(DT_NODELABEL(cpu0), clock_frequency) for the moment to have consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought this was in the PWM driver when I first reviewed, in which case it would be a violation of responsibility between drivers (PWM should use clock control only). Since this is in the clock driver, it's more OK since the clock driver is responsible for clocks, and should therefore be allowed to use that global as part of its HAL usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok then let's still use SystemCoreClock for the moment (since this is with what i've tested).