Lines Matching +full:stm32 +full:- +full:timers
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>
49 regmap_read(dev->regmap, TIM_CCER, &ccer); in active_channels()
82 * 0: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3
84 * 1: IC2/4 snapchot on falling edge: counter value -> CCR2/CCR4
85 * 2: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3
89 * - Period = t2 - t0
90 * - Duty cycle = t1 - t0
97 struct device *parent = pwmchip_parent(chip)->parent; in stm32_pwm_raw_capture()
103 regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG); in stm32_pwm_raw_capture()
104 regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); in stm32_pwm_raw_capture()
107 dma_id = pwm->hwpwm < 2 ? STM32_TIMERS_DMA_CH1 : STM32_TIMERS_DMA_CH3; in stm32_pwm_raw_capture()
108 ccen = pwm->hwpwm < 2 ? TIM_CCER_CC12E : TIM_CCER_CC34E; in stm32_pwm_raw_capture()
109 ccr = pwm->hwpwm < 2 ? TIM_CCR1 : TIM_CCR3; in stm32_pwm_raw_capture()
110 regmap_set_bits(priv->regmap, TIM_CCER, ccen); in stm32_pwm_raw_capture()
118 ret = stm32_timers_dma_burst_read(parent, priv->capture, dma_id, ccr, 2, in stm32_pwm_raw_capture()
123 /* Period: t2 - t0 (take care of counter overflow) */ in stm32_pwm_raw_capture()
124 if (priv->capture[0] <= priv->capture[2]) in stm32_pwm_raw_capture()
125 *raw_prd = priv->capture[2] - priv->capture[0]; in stm32_pwm_raw_capture()
127 *raw_prd = priv->max_arr - priv->capture[0] + priv->capture[2]; in stm32_pwm_raw_capture()
130 if (pwm->chip->npwm < 2) in stm32_pwm_raw_capture()
132 else if (priv->capture[0] <= priv->capture[3]) in stm32_pwm_raw_capture()
133 *raw_dty = priv->capture[3] - priv->capture[0]; in stm32_pwm_raw_capture()
135 *raw_dty = priv->max_arr - priv->capture[0] + priv->capture[3]; in stm32_pwm_raw_capture()
144 *raw_dty -= *raw_prd; in stm32_pwm_raw_capture()
148 regmap_clear_bits(priv->regmap, TIM_CCER, ccen); in stm32_pwm_raw_capture()
149 regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); in stm32_pwm_raw_capture()
164 mutex_lock(&priv->lock); in stm32_pwm_capture()
167 ret = -EBUSY; in stm32_pwm_capture()
171 ret = clk_enable(priv->clk); in stm32_pwm_capture()
177 rate = clk_get_rate(priv->clk); in stm32_pwm_capture()
179 ret = -EINVAL; in stm32_pwm_capture()
187 while ((div > priv->max_arr) && (psc < MAX_TIM_PSC)) { in stm32_pwm_capture()
192 regmap_write(priv->regmap, TIM_ARR, priv->max_arr); in stm32_pwm_capture()
193 regmap_write(priv->regmap, TIM_PSC, psc); in stm32_pwm_capture()
196 regmap_write(priv->regmap, TIM_TISEL, 0x0); in stm32_pwm_capture()
197 regmap_write(priv->regmap, TIM_SMCR, 0x0); in stm32_pwm_capture()
200 regmap_update_bits(priv->regmap, in stm32_pwm_capture()
201 pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, in stm32_pwm_capture()
202 TIM_CCMR_CC1S | TIM_CCMR_CC2S, pwm->hwpwm & 0x1 ? in stm32_pwm_capture()
207 regmap_update_bits(priv->regmap, TIM_CCER, pwm->hwpwm < 2 ? in stm32_pwm_capture()
208 TIM_CCER_CC12P : TIM_CCER_CC34P, pwm->hwpwm < 2 ? in stm32_pwm_capture()
217 * - decrease counter clock prescaler, scale up to max rate. in stm32_pwm_capture()
218 * - use input prescaler, capture once every /2 /4 or /8 edges. in stm32_pwm_capture()
221 u32 max_arr = priv->max_arr - 0x1000; /* arbitrary margin */ in stm32_pwm_capture()
225 scale = priv->max_arr; /* below resolution, use max scale */ in stm32_pwm_capture()
231 regmap_write(priv->regmap, TIM_PSC, psc); in stm32_pwm_capture()
244 if (raw_prd >= (priv->max_arr - 0x1000) >> (icpsc + 1)) in stm32_pwm_capture()
254 regmap_update_bits(priv->regmap, in stm32_pwm_capture()
255 pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, in stm32_pwm_capture()
281 * Capture0: .<----------------------------->. in stm32_pwm_capture()
282 * Capture1: .<-------------------------->. . in stm32_pwm_capture()
284 * Period: .<------> . . in stm32_pwm_capture()
288 * - Period = Capture0 / icpsc in stm32_pwm_capture()
289 * - Duty = Period - Low side = Period - (Capture0 - Capture1) in stm32_pwm_capture()
291 raw_dty = (raw_prd >> icpsc) - (raw_prd - raw_dty); in stm32_pwm_capture()
296 result->period = DIV_ROUND_UP_ULL(prd, rate << icpsc); in stm32_pwm_capture()
298 result->duty_cycle = DIV_ROUND_UP_ULL(dty, rate); in stm32_pwm_capture()
300 regmap_write(priv->regmap, TIM_CCER, 0); in stm32_pwm_capture()
301 regmap_write(priv->regmap, pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, 0); in stm32_pwm_capture()
302 regmap_write(priv->regmap, TIM_PSC, 0); in stm32_pwm_capture()
304 clk_disable(priv->clk); in stm32_pwm_capture()
306 mutex_unlock(&priv->lock); in stm32_pwm_capture()
324 * ------------------------------ < max_arr + 1 in stm32_pwm_config()
330 * ---------------------------- < prescaler + 1 in stm32_pwm_config()
339 prescaler = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk), in stm32_pwm_config()
340 (u64)NSEC_PER_SEC * ((u64)priv->max_arr + 1)); in stm32_pwm_config()
342 return -EINVAL; in stm32_pwm_config()
344 prd = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk), in stm32_pwm_config()
347 return -EINVAL; in stm32_pwm_config()
356 regmap_read(priv->regmap, TIM_PSC, &psc); in stm32_pwm_config()
357 regmap_read(priv->regmap, TIM_ARR, &arr); in stm32_pwm_config()
359 if ((psc != prescaler) || (arr != prd - 1)) in stm32_pwm_config()
360 return -EBUSY; in stm32_pwm_config()
363 regmap_write(priv->regmap, TIM_PSC, prescaler); in stm32_pwm_config()
364 regmap_write(priv->regmap, TIM_ARR, prd - 1); in stm32_pwm_config()
365 regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE); in stm32_pwm_config()
368 dty = mul_u64_u64_div_u64(duty_ns, clk_get_rate(priv->clk), in stm32_pwm_config()
371 regmap_write(priv->regmap, TIM_CCRx(ch + 1), dty); in stm32_pwm_config()
379 regmap_update_bits(priv->regmap, TIM_CCMR1, mask, ccmr); in stm32_pwm_config()
381 regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr); in stm32_pwm_config()
383 regmap_set_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE); in stm32_pwm_config()
394 if (priv->have_complementary_output) in stm32_pwm_set_polarity()
397 regmap_update_bits(priv->regmap, TIM_CCER, mask, in stm32_pwm_set_polarity()
408 ret = clk_enable(priv->clk); in stm32_pwm_enable()
414 if (priv->have_complementary_output) in stm32_pwm_enable()
417 regmap_set_bits(priv->regmap, TIM_CCER, mask); in stm32_pwm_enable()
420 regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG); in stm32_pwm_enable()
423 regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); in stm32_pwm_enable()
434 if (priv->have_complementary_output) in stm32_pwm_disable()
437 regmap_clear_bits(priv->regmap, TIM_CCER, mask); in stm32_pwm_disable()
441 regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); in stm32_pwm_disable()
443 clk_disable(priv->clk); in stm32_pwm_disable()
453 enabled = pwm->state.enabled; in stm32_pwm_apply()
455 if (!state->enabled) { in stm32_pwm_apply()
457 stm32_pwm_disable(priv, pwm->hwpwm); in stm32_pwm_apply()
461 if (state->polarity != pwm->state.polarity) in stm32_pwm_apply()
462 stm32_pwm_set_polarity(priv, pwm->hwpwm, state->polarity); in stm32_pwm_apply()
464 ret = stm32_pwm_config(priv, pwm->hwpwm, in stm32_pwm_apply()
465 state->duty_cycle, state->period); in stm32_pwm_apply()
469 if (!enabled && state->enabled) in stm32_pwm_apply()
470 ret = stm32_pwm_enable(priv, pwm->hwpwm); in stm32_pwm_apply()
482 mutex_lock(&priv->lock); in stm32_pwm_apply_locked()
484 mutex_unlock(&priv->lock); in stm32_pwm_apply_locked()
493 int ch = pwm->hwpwm; in stm32_pwm_get_state()
499 mutex_lock(&priv->lock); in stm32_pwm_get_state()
501 ret = regmap_read(priv->regmap, TIM_CCER, &ccer); in stm32_pwm_get_state()
505 state->enabled = ccer & TIM_CCER_CCxE(ch + 1); in stm32_pwm_get_state()
506 state->polarity = (ccer & TIM_CCER_CCxP(ch + 1)) ? in stm32_pwm_get_state()
508 ret = regmap_read(priv->regmap, TIM_PSC, &psc); in stm32_pwm_get_state()
511 ret = regmap_read(priv->regmap, TIM_ARR, &arr); in stm32_pwm_get_state()
514 ret = regmap_read(priv->regmap, TIM_CCRx(ch + 1), &ccr); in stm32_pwm_get_state()
518 rate = clk_get_rate(priv->clk); in stm32_pwm_get_state()
521 state->period = DIV_ROUND_UP_ULL(prd, rate); in stm32_pwm_get_state()
523 state->duty_cycle = DIV_ROUND_UP_ULL(dty, rate); in stm32_pwm_get_state()
526 mutex_unlock(&priv->lock); in stm32_pwm_get_state()
539 u32 shift = TIM_BDTR_BKF_SHIFT(bi->index); in stm32_pwm_set_breakinput()
540 u32 bke = TIM_BDTR_BKE(bi->index); in stm32_pwm_set_breakinput()
541 u32 bkp = TIM_BDTR_BKP(bi->index); in stm32_pwm_set_breakinput()
542 u32 bkf = TIM_BDTR_BKF(bi->index); in stm32_pwm_set_breakinput()
546 bdtr = (bi->filter & TIM_BDTR_BKF_MASK) << shift | bke; in stm32_pwm_set_breakinput()
548 if (bi->level) in stm32_pwm_set_breakinput()
551 regmap_update_bits(priv->regmap, TIM_BDTR, mask, bdtr); in stm32_pwm_set_breakinput()
553 regmap_read(priv->regmap, TIM_BDTR, &bdtr); in stm32_pwm_set_breakinput()
555 return (bdtr & bke) ? 0 : -EINVAL; in stm32_pwm_set_breakinput()
563 for (i = 0; i < priv->num_breakinputs; i++) { in stm32_pwm_apply_breakinputs()
564 ret = stm32_pwm_set_breakinput(priv, &priv->breakinputs[i]); in stm32_pwm_apply_breakinputs()
589 return -EINVAL; in stm32_pwm_probe_breakinputs()
591 priv->num_breakinputs = nb; in stm32_pwm_probe_breakinputs()
594 (u32 *)priv->breakinputs, array_size); in stm32_pwm_probe_breakinputs()
598 for (i = 0; i < priv->num_breakinputs; i++) { in stm32_pwm_probe_breakinputs()
599 if (priv->breakinputs[i].index > 1 || in stm32_pwm_probe_breakinputs()
600 priv->breakinputs[i].level > 1 || in stm32_pwm_probe_breakinputs()
601 priv->breakinputs[i].filter > 15) in stm32_pwm_probe_breakinputs()
602 return -EINVAL; in stm32_pwm_probe_breakinputs()
616 regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE); in stm32_pwm_detect_complementary()
617 regmap_read(priv->regmap, TIM_CCER, &ccer); in stm32_pwm_detect_complementary()
618 regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE); in stm32_pwm_detect_complementary()
620 priv->have_complementary_output = (ccer != 0); in stm32_pwm_detect_complementary()
644 struct device *dev = &pdev->dev; in stm32_pwm_probe()
645 struct device_node *np = dev->of_node; in stm32_pwm_probe()
646 struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); in stm32_pwm_probe()
653 npwm = stm32_pwm_detect_channels(ddata->regmap, &num_enabled); in stm32_pwm_probe()
660 mutex_init(&priv->lock); in stm32_pwm_probe()
661 priv->regmap = ddata->regmap; in stm32_pwm_probe()
662 priv->clk = ddata->clk; in stm32_pwm_probe()
663 priv->max_arr = ddata->max_arr; in stm32_pwm_probe()
665 if (!priv->regmap || !priv->clk) in stm32_pwm_probe()
666 return dev_err_probe(dev, -EINVAL, "Failed to get %s\n", in stm32_pwm_probe()
667 priv->regmap ? "clk" : "regmap"); in stm32_pwm_probe()
676 ret = devm_clk_rate_exclusive_get(dev, priv->clk); in stm32_pwm_probe()
684 if (clk_get_rate(priv->clk) > 1000000000) in stm32_pwm_probe()
685 return dev_err_probe(dev, -EINVAL, "Clock freq too high (%lu)\n", in stm32_pwm_probe()
686 clk_get_rate(priv->clk)); in stm32_pwm_probe()
688 chip->ops = &stm32pwm_ops; in stm32_pwm_probe()
692 clk_enable(priv->clk); in stm32_pwm_probe()
714 for (i = 0; i < chip->npwm; i++) { in stm32_pwm_suspend()
718 i, chip->pwms[i].label); in stm32_pwm_suspend()
719 return -EBUSY; in stm32_pwm_suspend()
743 { .compatible = "st,stm32-pwm", },
751 .name = "stm32-pwm",
758 MODULE_ALIAS("platform:stm32-pwm");
759 MODULE_DESCRIPTION("STMicroelectronics STM32 PWM driver");