diff options
-rw-r--r-- | chip/stm32/pwm.c | 15 | ||||
-rw-r--r-- | chip/stm32/pwm_chip.h | 2 | ||||
-rw-r--r-- | include/pwm.h | 11 |
3 files changed, 22 insertions, 6 deletions
diff --git a/chip/stm32/pwm.c b/chip/stm32/pwm.c index a457cb709d..aa5149b074 100644 --- a/chip/stm32/pwm.c +++ b/chip/stm32/pwm.c @@ -37,6 +37,9 @@ static void pwm_configure(enum pwm_channel ch) const struct pwm_t *pwm = pwm_channels + ch; timer_ctlr_t *tim = (timer_ctlr_t *)(pwm->tim.base); volatile unsigned *ccmr = NULL; + /* Default frequency = 100 Hz */ + int frequency = pwm->frequency ? pwm->frequency : 100; + uint16_t ccer; if (using_pwm[ch]) return; @@ -54,7 +57,7 @@ static void pwm_configure(enum pwm_channel ch) * * frequency = cpu_freq / (cpu_freq/10000 + 1) / (99 + 1) = 100 Hz. */ - tim->psc = clock_get_freq() / 10000 - 1; + tim->psc = clock_get_freq() / (frequency * 100) - 1; tim->arr = 99; if (pwm->channel <= 2) /* Channel ID starts from 1 */ @@ -70,9 +73,15 @@ static void pwm_configure(enum pwm_channel ch) /* Output enable. Set active high/low. */ if (pwm->flags & PWM_CONFIG_ACTIVE_LOW) - tim->ccer = 3 << (pwm->channel * 4 - 4); + ccer = 3 << (pwm->channel * 4 - 4); else - tim->ccer = 1 << (pwm->channel * 4 - 4); + ccer = 1 << (pwm->channel * 4 - 4); + + /* Enable complementary output, if present. */ + if (pwm->flags & PWM_CONFIG_COMPLEMENTARY_OUTPUT) + ccer |= (ccer << 2); + + tim->ccer = ccer; /* * Main output enable. diff --git a/chip/stm32/pwm_chip.h b/chip/stm32/pwm_chip.h index 418c7417fe..8dc9ad2d0b 100644 --- a/chip/stm32/pwm_chip.h +++ b/chip/stm32/pwm_chip.h @@ -22,6 +22,8 @@ struct pwm_t { int channel; /* PWM channel flags. See include/pwm.h */ uint32_t flags; + /* PWM frequency (Hz) */ + int frequency; }; extern const struct pwm_t pwm_channels[]; diff --git a/include/pwm.h b/include/pwm.h index 66610b9240..39835012e9 100644 --- a/include/pwm.h +++ b/include/pwm.h @@ -35,16 +35,21 @@ int pwm_get_duty(enum pwm_channel ch); /** * PWM output signal is inverted, so 100% duty means always low */ -#define PWM_CONFIG_ACTIVE_LOW (1 << 0) +#define PWM_CONFIG_ACTIVE_LOW (1 << 0) /** * PWM channel has a fan controller with a tach input and can auto-adjust * its duty cycle to produce a given fan RPM. */ -#define PWM_CONFIG_HAS_RPM_MODE (1 << 1) +#define PWM_CONFIG_HAS_RPM_MODE (1 << 1) /** * PWM clock select alternate source. The actual clock and alternate * source are chip dependent. */ -#define PWM_CONFIG_ALT_CLOCK (1 << 2) +#define PWM_CONFIG_ALT_CLOCK (1 << 2) +/** + * PWM channel has a complementary output signal which should be enabled in + * addition to the primary output. + */ +#define PWM_CONFIG_COMPLEMENTARY_OUTPUT (1 << 3) #endif /* __CROS_EC_PWM_H */ |