• Home
  • Raw
  • Download

Lines Matching +full:pwm +full:- +full:channels +full:- +full:mask

1 // SPDX-License-Identifier: GPL-2.0
7 * Inspired by timer-stm32.c from Maxime Coquelin
8 * pwm-atmel.c from Bo Shen
12 #include <linux/mfd/stm32-timers.h>
16 #include <linux/pwm.h>
24 struct mutex lock; /* protect pwm config/enable */
47 regmap_read(dev->regmap, TIM_CCER, &ccer); in active_channels()
56 return regmap_write(dev->regmap, TIM_CCR1, value); in write_ccrx()
58 return regmap_write(dev->regmap, TIM_CCR2, value); in write_ccrx()
60 return regmap_write(dev->regmap, TIM_CCR3, value); in write_ccrx()
62 return regmap_write(dev->regmap, TIM_CCR4, value); in write_ccrx()
64 return -EINVAL; in write_ccrx()
73 * Capture using PWM input mode:
95 * 0: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3
97 * 1: IC2/4 snapchot on falling edge: counter value -> CCR2/CCR4
98 * 2: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3
102 * - Period = t2 - t0
103 * - Duty cycle = t1 - t0
105 static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm, in stm32_pwm_raw_capture() argument
109 struct device *parent = priv->chip.dev->parent; in stm32_pwm_raw_capture()
115 regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); in stm32_pwm_raw_capture()
116 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN); in stm32_pwm_raw_capture()
118 /* Use cc1 or cc3 DMA resp for PWM input channels 1 & 2 or 3 & 4 */ in stm32_pwm_raw_capture()
119 dma_id = pwm->hwpwm < 2 ? STM32_TIMERS_DMA_CH1 : STM32_TIMERS_DMA_CH3; in stm32_pwm_raw_capture()
120 ccen = pwm->hwpwm < 2 ? TIM_CCER_CC12E : TIM_CCER_CC34E; in stm32_pwm_raw_capture()
121 ccr = pwm->hwpwm < 2 ? TIM_CCR1 : TIM_CCR3; in stm32_pwm_raw_capture()
122 regmap_update_bits(priv->regmap, TIM_CCER, ccen, ccen); in stm32_pwm_raw_capture()
130 ret = stm32_timers_dma_burst_read(parent, priv->capture, dma_id, ccr, 2, in stm32_pwm_raw_capture()
135 /* Period: t2 - t0 (take care of counter overflow) */ in stm32_pwm_raw_capture()
136 if (priv->capture[0] <= priv->capture[2]) in stm32_pwm_raw_capture()
137 *raw_prd = priv->capture[2] - priv->capture[0]; in stm32_pwm_raw_capture()
139 *raw_prd = priv->max_arr - priv->capture[0] + priv->capture[2]; in stm32_pwm_raw_capture()
142 if (pwm->chip->npwm < 2) in stm32_pwm_raw_capture()
144 else if (priv->capture[0] <= priv->capture[3]) in stm32_pwm_raw_capture()
145 *raw_dty = priv->capture[3] - priv->capture[0]; in stm32_pwm_raw_capture()
147 *raw_dty = priv->max_arr - priv->capture[0] + priv->capture[3]; in stm32_pwm_raw_capture()
151 * Race beetween PWM input and DMA: it may happen in stm32_pwm_raw_capture()
156 *raw_dty -= *raw_prd; in stm32_pwm_raw_capture()
160 regmap_update_bits(priv->regmap, TIM_CCER, ccen, 0); in stm32_pwm_raw_capture()
161 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); in stm32_pwm_raw_capture()
166 static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, in stm32_pwm_capture() argument
176 mutex_lock(&priv->lock); in stm32_pwm_capture()
179 ret = -EBUSY; in stm32_pwm_capture()
183 ret = clk_enable(priv->clk); in stm32_pwm_capture()
185 dev_err(priv->chip.dev, "failed to enable counter clock\n"); in stm32_pwm_capture()
189 rate = clk_get_rate(priv->clk); in stm32_pwm_capture()
191 ret = -EINVAL; in stm32_pwm_capture()
199 while ((div > priv->max_arr) && (psc < MAX_TIM_PSC)) { in stm32_pwm_capture()
204 regmap_write(priv->regmap, TIM_ARR, priv->max_arr); in stm32_pwm_capture()
205 regmap_write(priv->regmap, TIM_PSC, psc); in stm32_pwm_capture()
207 /* Map TI1 or TI2 PWM input to IC1 & IC2 (or TI3/4 to IC3 & IC4) */ in stm32_pwm_capture()
208 regmap_update_bits(priv->regmap, in stm32_pwm_capture()
209 pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, in stm32_pwm_capture()
210 TIM_CCMR_CC1S | TIM_CCMR_CC2S, pwm->hwpwm & 0x1 ? in stm32_pwm_capture()
215 regmap_update_bits(priv->regmap, TIM_CCER, pwm->hwpwm < 2 ? in stm32_pwm_capture()
216 TIM_CCER_CC12P : TIM_CCER_CC34P, pwm->hwpwm < 2 ? in stm32_pwm_capture()
219 ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty); in stm32_pwm_capture()
225 * - decrease counter clock prescaler, scale up to max rate. in stm32_pwm_capture()
226 * - use input prescaler, capture once every /2 /4 or /8 edges. in stm32_pwm_capture()
229 u32 max_arr = priv->max_arr - 0x1000; /* arbitrary margin */ in stm32_pwm_capture()
233 scale = priv->max_arr; /* bellow resolution, use max scale */ in stm32_pwm_capture()
239 regmap_write(priv->regmap, TIM_PSC, psc); in stm32_pwm_capture()
240 ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, in stm32_pwm_capture()
252 if (raw_prd >= (priv->max_arr - 0x1000) >> (icpsc + 1)) in stm32_pwm_capture()
262 regmap_update_bits(priv->regmap, in stm32_pwm_capture()
263 pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, in stm32_pwm_capture()
268 ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty); in stm32_pwm_capture()
289 * Capture0: .<----------------------------->. in stm32_pwm_capture()
290 * Capture1: .<-------------------------->. . in stm32_pwm_capture()
292 * Period: .<------> . . in stm32_pwm_capture()
296 * - Period = Capture0 / icpsc in stm32_pwm_capture()
297 * - Duty = Period - Low side = Period - (Capture0 - Capture1) in stm32_pwm_capture()
299 raw_dty = (raw_prd >> icpsc) - (raw_prd - raw_dty); in stm32_pwm_capture()
304 result->period = DIV_ROUND_UP_ULL(prd, rate << icpsc); in stm32_pwm_capture()
306 result->duty_cycle = DIV_ROUND_UP_ULL(dty, rate); in stm32_pwm_capture()
308 regmap_write(priv->regmap, TIM_CCER, 0); in stm32_pwm_capture()
309 regmap_write(priv->regmap, pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, 0); in stm32_pwm_capture()
310 regmap_write(priv->regmap, TIM_PSC, 0); in stm32_pwm_capture()
312 clk_disable(priv->clk); in stm32_pwm_capture()
314 mutex_unlock(&priv->lock); in stm32_pwm_capture()
324 u32 ccmr, mask, shift; in stm32_pwm_config() local
327 div = (unsigned long long)clk_get_rate(priv->clk) * period_ns; in stm32_pwm_config()
332 while (div > priv->max_arr) { in stm32_pwm_config()
341 return -EINVAL; in stm32_pwm_config()
344 * All channels share the same prescaler and counter so when two in stm32_pwm_config()
345 * channels are active at the same time we can't change them in stm32_pwm_config()
350 regmap_read(priv->regmap, TIM_PSC, &psc); in stm32_pwm_config()
351 regmap_read(priv->regmap, TIM_ARR, &arr); in stm32_pwm_config()
353 if ((psc != prescaler) || (arr != prd - 1)) in stm32_pwm_config()
354 return -EBUSY; in stm32_pwm_config()
357 regmap_write(priv->regmap, TIM_PSC, prescaler); in stm32_pwm_config()
358 regmap_write(priv->regmap, TIM_ARR, prd - 1); in stm32_pwm_config()
359 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); in stm32_pwm_config()
370 mask = CCMR_CHANNEL_MASK << shift; in stm32_pwm_config()
373 regmap_update_bits(priv->regmap, TIM_CCMR1, mask, ccmr); in stm32_pwm_config()
375 regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr); in stm32_pwm_config()
377 regmap_update_bits(priv->regmap, TIM_BDTR, in stm32_pwm_config()
387 u32 mask; in stm32_pwm_set_polarity() local
389 mask = TIM_CCER_CC1P << (ch * 4); in stm32_pwm_set_polarity()
390 if (priv->have_complementary_output) in stm32_pwm_set_polarity()
391 mask |= TIM_CCER_CC1NP << (ch * 4); in stm32_pwm_set_polarity()
393 regmap_update_bits(priv->regmap, TIM_CCER, mask, in stm32_pwm_set_polarity()
394 polarity == PWM_POLARITY_NORMAL ? 0 : mask); in stm32_pwm_set_polarity()
401 u32 mask; in stm32_pwm_enable() local
404 ret = clk_enable(priv->clk); in stm32_pwm_enable()
409 mask = TIM_CCER_CC1E << (ch * 4); in stm32_pwm_enable()
410 if (priv->have_complementary_output) in stm32_pwm_enable()
411 mask |= TIM_CCER_CC1NE << (ch * 4); in stm32_pwm_enable()
413 regmap_update_bits(priv->regmap, TIM_CCER, mask, mask); in stm32_pwm_enable()
416 regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); in stm32_pwm_enable()
419 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN); in stm32_pwm_enable()
426 u32 mask; in stm32_pwm_disable() local
429 mask = TIM_CCER_CC1E << (ch * 4); in stm32_pwm_disable()
430 if (priv->have_complementary_output) in stm32_pwm_disable()
431 mask |= TIM_CCER_CC1NE << (ch * 4); in stm32_pwm_disable()
433 regmap_update_bits(priv->regmap, TIM_CCER, mask, 0); in stm32_pwm_disable()
435 /* When all channels are disabled, we can disable the controller */ in stm32_pwm_disable()
437 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); in stm32_pwm_disable()
439 clk_disable(priv->clk); in stm32_pwm_disable()
442 static int stm32_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, in stm32_pwm_apply() argument
449 enabled = pwm->state.enabled; in stm32_pwm_apply()
451 if (enabled && !state->enabled) { in stm32_pwm_apply()
452 stm32_pwm_disable(priv, pwm->hwpwm); in stm32_pwm_apply()
456 if (state->polarity != pwm->state.polarity) in stm32_pwm_apply()
457 stm32_pwm_set_polarity(priv, pwm->hwpwm, state->polarity); in stm32_pwm_apply()
459 ret = stm32_pwm_config(priv, pwm->hwpwm, in stm32_pwm_apply()
460 state->duty_cycle, state->period); in stm32_pwm_apply()
464 if (!enabled && state->enabled) in stm32_pwm_apply()
465 ret = stm32_pwm_enable(priv, pwm->hwpwm); in stm32_pwm_apply()
470 static int stm32_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device *pwm, in stm32_pwm_apply_locked() argument
476 /* protect common prescaler for all active channels */ in stm32_pwm_apply_locked()
477 mutex_lock(&priv->lock); in stm32_pwm_apply_locked()
478 ret = stm32_pwm_apply(chip, pwm, state); in stm32_pwm_apply_locked()
479 mutex_unlock(&priv->lock); in stm32_pwm_apply_locked()
495 u32 mask = (index == 0) ? TIM_BDTR_BKE | TIM_BDTR_BKP | TIM_BDTR_BKF in stm32_pwm_set_breakinput() local
501 * due to mask value. in stm32_pwm_set_breakinput()
508 regmap_update_bits(priv->regmap, TIM_BDTR, mask, bdtr); in stm32_pwm_set_breakinput()
510 regmap_read(priv->regmap, TIM_BDTR, &bdtr); in stm32_pwm_set_breakinput()
512 return (bdtr & bke) ? 0 : -EINVAL; in stm32_pwm_set_breakinput()
532 return -EINVAL; in stm32_pwm_apply_breakinputs()
558 regmap_update_bits(priv->regmap, in stm32_pwm_detect_complementary()
560 regmap_read(priv->regmap, TIM_CCER, &ccer); in stm32_pwm_detect_complementary()
561 regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE, 0); in stm32_pwm_detect_complementary()
563 priv->have_complementary_output = (ccer != 0); in stm32_pwm_detect_complementary()
572 * If channels enable bits don't exist writing 1 will have no in stm32_pwm_detect_channels()
575 regmap_update_bits(priv->regmap, in stm32_pwm_detect_channels()
577 regmap_read(priv->regmap, TIM_CCER, &ccer); in stm32_pwm_detect_channels()
578 regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE, 0); in stm32_pwm_detect_channels()
597 struct device *dev = &pdev->dev; in stm32_pwm_probe()
598 struct device_node *np = dev->of_node; in stm32_pwm_probe()
599 struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); in stm32_pwm_probe()
605 return -ENOMEM; in stm32_pwm_probe()
607 mutex_init(&priv->lock); in stm32_pwm_probe()
608 priv->regmap = ddata->regmap; in stm32_pwm_probe()
609 priv->clk = ddata->clk; in stm32_pwm_probe()
610 priv->max_arr = ddata->max_arr; in stm32_pwm_probe()
612 if (!priv->regmap || !priv->clk) in stm32_pwm_probe()
613 return -EINVAL; in stm32_pwm_probe()
621 priv->chip.base = -1; in stm32_pwm_probe()
622 priv->chip.dev = dev; in stm32_pwm_probe()
623 priv->chip.ops = &stm32pwm_ops; in stm32_pwm_probe()
624 priv->chip.npwm = stm32_pwm_detect_channels(priv); in stm32_pwm_probe()
626 ret = pwmchip_add(&priv->chip); in stm32_pwm_probe()
640 for (i = 0; i < priv->chip.npwm; i++) in stm32_pwm_remove()
641 pwm_disable(&priv->chip.pwms[i]); in stm32_pwm_remove()
643 pwmchip_remove(&priv->chip); in stm32_pwm_remove()
649 { .compatible = "st,stm32-pwm", },
658 .name = "stm32-pwm",
664 MODULE_ALIAS("platform:stm32-pwm");
665 MODULE_DESCRIPTION("STMicroelectronics STM32 PWM driver");