Lines Matching +full:stm32 +full:- +full:lptimer
1 // SPDX-License-Identifier: GPL-2.0
3 * STM32 Low-Power Timer PWM driver
9 * Inspired by Gerald Baeza's pwm-stm32 driver
13 #include <linux/mfd/stm32-lptimer.h>
30 /* STM32 Low-Power Timer is preceded by a configurable power-of-2 prescaler */
46 if (!state->enabled) {
49 ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
53 clk_disable(priv->clk);
59 div = (unsigned long long)clk_get_rate(priv->clk) * state->period;
63 dev_dbg(pwmchip_parent(chip), "Can't reach %llu ns\n", state->period);
64 return -EINVAL;
72 return -EINVAL;
79 dty = prd * state->duty_cycle;
80 do_div(dty, state->period);
84 ret = clk_enable(priv->clk);
89 ret = regmap_read(priv->regmap, STM32_LPTIM_CFGR, &cfgr);
94 (FIELD_GET(STM32_LPTIM_WAVPOL, cfgr) != state->polarity)) {
96 val |= FIELD_PREP(STM32_LPTIM_WAVPOL, state->polarity);
101 ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
105 ret = regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask,
113 ret = regmap_write(priv->regmap, STM32_LPTIM_CR,
119 ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, prd - 1);
123 ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, prd - (1 + dty));
128 ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
135 ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
142 ret = regmap_set_bits(priv->regmap, STM32_LPTIM_CR,
145 regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
153 clk_disable(priv->clk);
163 unsigned long rate = clk_get_rate(priv->clk);
167 regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
168 state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val);
170 if (state->enabled) {
171 int ret = clk_enable(priv->clk);
177 regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val);
179 state->polarity = FIELD_GET(STM32_LPTIM_WAVPOL, val);
181 regmap_read(priv->regmap, STM32_LPTIM_ARR, &prd);
184 state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate);
186 regmap_read(priv->regmap, STM32_LPTIM_CMP, &val);
187 tmp = prd - val;
189 state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate);
201 struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
206 chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*priv));
211 priv->regmap = ddata->regmap;
212 priv->clk = ddata->clk;
213 chip->ops = &stm32_pwm_lp_ops;
215 ret = devm_pwmchip_add(&pdev->dev, chip);
229 pwm_get_state(&chip->pwms[0], &state);
232 chip->pwms[0].label);
233 return -EBUSY;
248 { .compatible = "st,stm32-pwm-lp", },
256 .name = "stm32-pwm-lp",
263 MODULE_ALIAS("platform:stm32-pwm-lp");
264 MODULE_DESCRIPTION("STMicroelectronics STM32 PWM LP driver");