Lines Matching +full:tx +full:- +full:max +full:- +full:burst +full:- +full:prd
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>
50 regmap_read(dev->regmap, TIM_CCER, &ccer); in active_channels()
59 return regmap_write(dev->regmap, TIM_CCR1, value); in write_ccrx()
61 return regmap_write(dev->regmap, TIM_CCR2, value); in write_ccrx()
63 return regmap_write(dev->regmap, TIM_CCR3, value); in write_ccrx()
65 return regmap_write(dev->regmap, TIM_CCR4, value); in write_ccrx()
67 return -EINVAL; in write_ccrx()
90 * CCR1/CCR3: tx..........t0...........t2
91 * CCR2/CCR4: tx..............t1.........
93 * DMA burst transfer: | |
95 * DMA buffer: { t0, tx } { t2, t1 }
98 * 0: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3
99 * + DMA transfer CCR[1/3] & CCR[2/4] values (t0, tx: doesn't care)
100 * 1: IC2/4 snapchot on falling edge: counter value -> CCR2/CCR4
101 * 2: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3
105 * - Period = t2 - t0
106 * - Duty cycle = t1 - t0
112 struct device *parent = priv->chip.dev->parent; in stm32_pwm_raw_capture()
118 regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG); in stm32_pwm_raw_capture()
119 regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); in stm32_pwm_raw_capture()
122 dma_id = pwm->hwpwm < 2 ? STM32_TIMERS_DMA_CH1 : STM32_TIMERS_DMA_CH3; in stm32_pwm_raw_capture()
123 ccen = pwm->hwpwm < 2 ? TIM_CCER_CC12E : TIM_CCER_CC34E; in stm32_pwm_raw_capture()
124 ccr = pwm->hwpwm < 2 ? TIM_CCR1 : TIM_CCR3; in stm32_pwm_raw_capture()
125 regmap_set_bits(priv->regmap, TIM_CCER, ccen); in stm32_pwm_raw_capture()
128 * Timer DMA burst mode. Request 2 registers, 2 bursts, to get both in stm32_pwm_raw_capture()
133 ret = stm32_timers_dma_burst_read(parent, priv->capture, dma_id, ccr, 2, in stm32_pwm_raw_capture()
138 /* Period: t2 - t0 (take care of counter overflow) */ in stm32_pwm_raw_capture()
139 if (priv->capture[0] <= priv->capture[2]) in stm32_pwm_raw_capture()
140 *raw_prd = priv->capture[2] - priv->capture[0]; in stm32_pwm_raw_capture()
142 *raw_prd = priv->max_arr - priv->capture[0] + priv->capture[2]; in stm32_pwm_raw_capture()
145 if (pwm->chip->npwm < 2) in stm32_pwm_raw_capture()
147 else if (priv->capture[0] <= priv->capture[3]) in stm32_pwm_raw_capture()
148 *raw_dty = priv->capture[3] - priv->capture[0]; in stm32_pwm_raw_capture()
150 *raw_dty = priv->max_arr - priv->capture[0] + priv->capture[3]; in stm32_pwm_raw_capture()
159 *raw_dty -= *raw_prd; in stm32_pwm_raw_capture()
163 regmap_clear_bits(priv->regmap, TIM_CCER, ccen); in stm32_pwm_raw_capture()
164 regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); in stm32_pwm_raw_capture()
173 unsigned long long prd, div, dty; in stm32_pwm_capture() local
179 mutex_lock(&priv->lock); in stm32_pwm_capture()
182 ret = -EBUSY; in stm32_pwm_capture()
186 ret = clk_enable(priv->clk); in stm32_pwm_capture()
188 dev_err(priv->chip.dev, "failed to enable counter clock\n"); in stm32_pwm_capture()
192 rate = clk_get_rate(priv->clk); in stm32_pwm_capture()
194 ret = -EINVAL; in stm32_pwm_capture()
201 prd = div; in stm32_pwm_capture()
202 while ((div > priv->max_arr) && (psc < MAX_TIM_PSC)) { in stm32_pwm_capture()
204 div = prd; in stm32_pwm_capture()
207 regmap_write(priv->regmap, TIM_ARR, priv->max_arr); in stm32_pwm_capture()
208 regmap_write(priv->regmap, TIM_PSC, psc); in stm32_pwm_capture()
211 regmap_write(priv->regmap, TIM_TISEL, 0x0); in stm32_pwm_capture()
212 regmap_write(priv->regmap, TIM_SMCR, 0x0); in stm32_pwm_capture()
215 regmap_update_bits(priv->regmap, in stm32_pwm_capture()
216 pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, in stm32_pwm_capture()
217 TIM_CCMR_CC1S | TIM_CCMR_CC2S, pwm->hwpwm & 0x1 ? in stm32_pwm_capture()
222 regmap_update_bits(priv->regmap, TIM_CCER, pwm->hwpwm < 2 ? in stm32_pwm_capture()
223 TIM_CCER_CC12P : TIM_CCER_CC34P, pwm->hwpwm < 2 ? in stm32_pwm_capture()
232 * - decrease counter clock prescaler, scale up to max rate. in stm32_pwm_capture()
233 * - use input prescaler, capture once every /2 /4 or /8 edges. in stm32_pwm_capture()
236 u32 max_arr = priv->max_arr - 0x1000; /* arbitrary margin */ in stm32_pwm_capture()
240 scale = priv->max_arr; /* bellow resolution, use max scale */ in stm32_pwm_capture()
246 regmap_write(priv->regmap, TIM_PSC, psc); in stm32_pwm_capture()
254 prd = (unsigned long long)raw_prd * (psc + 1) * NSEC_PER_SEC; in stm32_pwm_capture()
255 do_div(prd, rate); in stm32_pwm_capture()
259 if (raw_prd >= (priv->max_arr - 0x1000) >> (icpsc + 1)) in stm32_pwm_capture()
261 if (prd >= (tmo_ms * NSEC_PER_MSEC) >> (icpsc + 2)) in stm32_pwm_capture()
269 regmap_update_bits(priv->regmap, in stm32_pwm_capture()
270 pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, in stm32_pwm_capture()
296 * Capture0: .<----------------------------->. in stm32_pwm_capture()
297 * Capture1: .<-------------------------->. . in stm32_pwm_capture()
299 * Period: .<------> . . in stm32_pwm_capture()
303 * - Period = Capture0 / icpsc in stm32_pwm_capture()
304 * - Duty = Period - Low side = Period - (Capture0 - Capture1) in stm32_pwm_capture()
306 raw_dty = (raw_prd >> icpsc) - (raw_prd - raw_dty); in stm32_pwm_capture()
310 prd = (unsigned long long)raw_prd * (psc + 1) * NSEC_PER_SEC; in stm32_pwm_capture()
311 result->period = DIV_ROUND_UP_ULL(prd, rate << icpsc); in stm32_pwm_capture()
313 result->duty_cycle = DIV_ROUND_UP_ULL(dty, rate); in stm32_pwm_capture()
315 regmap_write(priv->regmap, TIM_CCER, 0); in stm32_pwm_capture()
316 regmap_write(priv->regmap, pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, 0); in stm32_pwm_capture()
317 regmap_write(priv->regmap, TIM_PSC, 0); in stm32_pwm_capture()
319 clk_disable(priv->clk); in stm32_pwm_capture()
321 mutex_unlock(&priv->lock); in stm32_pwm_capture()
329 unsigned long long prd, div, dty; in stm32_pwm_config() local
334 div = (unsigned long long)clk_get_rate(priv->clk) * period_ns; in stm32_pwm_config()
337 prd = div; in stm32_pwm_config()
339 while (div > priv->max_arr) { in stm32_pwm_config()
341 div = prd; in stm32_pwm_config()
345 prd = div; in stm32_pwm_config()
347 if (!prd) in stm32_pwm_config()
348 return -EINVAL; in stm32_pwm_config()
351 return -EINVAL; in stm32_pwm_config()
360 regmap_read(priv->regmap, TIM_PSC, &psc); in stm32_pwm_config()
361 regmap_read(priv->regmap, TIM_ARR, &arr); in stm32_pwm_config()
363 if ((psc != prescaler) || (arr != prd - 1)) in stm32_pwm_config()
364 return -EBUSY; in stm32_pwm_config()
367 regmap_write(priv->regmap, TIM_PSC, prescaler); in stm32_pwm_config()
368 regmap_write(priv->regmap, TIM_ARR, prd - 1); in stm32_pwm_config()
369 regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE); in stm32_pwm_config()
372 dty = prd * duty_ns; in stm32_pwm_config()
383 regmap_update_bits(priv->regmap, TIM_CCMR1, mask, ccmr); in stm32_pwm_config()
385 regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr); in stm32_pwm_config()
387 regmap_set_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE); in stm32_pwm_config()
398 if (priv->have_complementary_output) in stm32_pwm_set_polarity()
401 regmap_update_bits(priv->regmap, TIM_CCER, mask, in stm32_pwm_set_polarity()
412 ret = clk_enable(priv->clk); in stm32_pwm_enable()
418 if (priv->have_complementary_output) in stm32_pwm_enable()
421 regmap_set_bits(priv->regmap, TIM_CCER, mask); in stm32_pwm_enable()
424 regmap_set_bits(priv->regmap, TIM_EGR, TIM_EGR_UG); in stm32_pwm_enable()
427 regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); in stm32_pwm_enable()
438 if (priv->have_complementary_output) in stm32_pwm_disable()
441 regmap_clear_bits(priv->regmap, TIM_CCER, mask); in stm32_pwm_disable()
445 regmap_clear_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN); in stm32_pwm_disable()
447 clk_disable(priv->clk); in stm32_pwm_disable()
457 enabled = pwm->state.enabled; in stm32_pwm_apply()
459 if (!state->enabled) { in stm32_pwm_apply()
461 stm32_pwm_disable(priv, pwm->hwpwm); in stm32_pwm_apply()
465 if (state->polarity != pwm->state.polarity) in stm32_pwm_apply()
466 stm32_pwm_set_polarity(priv, pwm->hwpwm, state->polarity); in stm32_pwm_apply()
468 ret = stm32_pwm_config(priv, pwm->hwpwm, in stm32_pwm_apply()
469 state->duty_cycle, state->period); in stm32_pwm_apply()
473 if (!enabled && state->enabled) in stm32_pwm_apply()
474 ret = stm32_pwm_enable(priv, pwm->hwpwm); in stm32_pwm_apply()
486 mutex_lock(&priv->lock); in stm32_pwm_apply_locked()
488 mutex_unlock(&priv->lock); in stm32_pwm_apply_locked()
502 u32 shift = TIM_BDTR_BKF_SHIFT(bi->index); in stm32_pwm_set_breakinput()
503 u32 bke = TIM_BDTR_BKE(bi->index); in stm32_pwm_set_breakinput()
504 u32 bkp = TIM_BDTR_BKP(bi->index); in stm32_pwm_set_breakinput()
505 u32 bkf = TIM_BDTR_BKF(bi->index); in stm32_pwm_set_breakinput()
509 bdtr = (bi->filter & TIM_BDTR_BKF_MASK) << shift | bke; in stm32_pwm_set_breakinput()
511 if (bi->level) in stm32_pwm_set_breakinput()
514 regmap_update_bits(priv->regmap, TIM_BDTR, mask, bdtr); in stm32_pwm_set_breakinput()
516 regmap_read(priv->regmap, TIM_BDTR, &bdtr); in stm32_pwm_set_breakinput()
518 return (bdtr & bke) ? 0 : -EINVAL; in stm32_pwm_set_breakinput()
526 for (i = 0; i < priv->num_breakinputs; i++) { in stm32_pwm_apply_breakinputs()
527 ret = stm32_pwm_set_breakinput(priv, &priv->breakinputs[i]); in stm32_pwm_apply_breakinputs()
552 return -EINVAL; in stm32_pwm_probe_breakinputs()
554 priv->num_breakinputs = nb; in stm32_pwm_probe_breakinputs()
557 (u32 *)priv->breakinputs, array_size); in stm32_pwm_probe_breakinputs()
561 for (i = 0; i < priv->num_breakinputs; i++) { in stm32_pwm_probe_breakinputs()
562 if (priv->breakinputs[i].index > 1 || in stm32_pwm_probe_breakinputs()
563 priv->breakinputs[i].level > 1 || in stm32_pwm_probe_breakinputs()
564 priv->breakinputs[i].filter > 15) in stm32_pwm_probe_breakinputs()
565 return -EINVAL; in stm32_pwm_probe_breakinputs()
579 regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE); in stm32_pwm_detect_complementary()
580 regmap_read(priv->regmap, TIM_CCER, &ccer); in stm32_pwm_detect_complementary()
581 regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE); in stm32_pwm_detect_complementary()
583 priv->have_complementary_output = (ccer != 0); in stm32_pwm_detect_complementary()
595 regmap_read(priv->regmap, TIM_CCER, &ccer_backup); in stm32_pwm_detect_channels()
596 regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); in stm32_pwm_detect_channels()
597 regmap_read(priv->regmap, TIM_CCER, &ccer); in stm32_pwm_detect_channels()
598 regmap_write(priv->regmap, TIM_CCER, ccer_backup); in stm32_pwm_detect_channels()
607 struct device *dev = &pdev->dev; in stm32_pwm_probe()
608 struct device_node *np = dev->of_node; in stm32_pwm_probe()
609 struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); in stm32_pwm_probe()
617 return -ENOMEM; in stm32_pwm_probe()
619 mutex_init(&priv->lock); in stm32_pwm_probe()
620 priv->regmap = ddata->regmap; in stm32_pwm_probe()
621 priv->clk = ddata->clk; in stm32_pwm_probe()
622 priv->max_arr = ddata->max_arr; in stm32_pwm_probe()
624 if (!priv->regmap || !priv->clk) in stm32_pwm_probe()
625 return -EINVAL; in stm32_pwm_probe()
633 priv->chip.dev = dev; in stm32_pwm_probe()
634 priv->chip.ops = &stm32pwm_ops; in stm32_pwm_probe()
635 priv->chip.npwm = stm32_pwm_detect_channels(priv, &num_enabled); in stm32_pwm_probe()
639 clk_enable(priv->clk); in stm32_pwm_probe()
641 ret = devm_pwmchip_add(dev, &priv->chip); in stm32_pwm_probe()
659 for (i = 0; i < priv->chip.npwm; i++) { in stm32_pwm_suspend()
663 i, priv->chip.pwms[i].label); in stm32_pwm_suspend()
664 return -EBUSY; in stm32_pwm_suspend()
687 { .compatible = "st,stm32-pwm", },
695 .name = "stm32-pwm",
702 MODULE_ALIAS("platform:stm32-pwm");