xref: /linux/drivers/pwm/pwm-stm32-lp.c (revision f2ad904e923f70a80f478febf001f88dfd65a64c)
1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   * STM32 Low-Power Timer PWM driver
4   *
5   * Copyright (C) STMicroelectronics 2017
6   *
7   * Author: Gerald Baeza <gerald.baeza@st.com>
8   *
9   * Inspired by Gerald Baeza's pwm-stm32 driver
10   */
11  
12  #include <linux/bitfield.h>
13  #include <linux/mfd/stm32-lptimer.h>
14  #include <linux/module.h>
15  #include <linux/of.h>
16  #include <linux/pinctrl/consumer.h>
17  #include <linux/platform_device.h>
18  #include <linux/pwm.h>
19  
20  struct stm32_pwm_lp {
21  	struct clk *clk;
22  	struct regmap *regmap;
23  };
24  
25  static inline struct stm32_pwm_lp *to_stm32_pwm_lp(struct pwm_chip *chip)
26  {
27  	return pwmchip_get_drvdata(chip);
28  }
29  
30  /* STM32 Low-Power Timer is preceded by a configurable power-of-2 prescaler */
31  #define STM32_LPTIM_MAX_PRESCALER	128
32  
33  static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
34  			      const struct pwm_state *state)
35  {
36  	struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip);
37  	unsigned long long prd, div, dty;
38  	struct pwm_state cstate;
39  	u32 val, mask, cfgr, presc = 0;
40  	bool reenable;
41  	int ret;
42  
43  	pwm_get_state(pwm, &cstate);
44  	reenable = !cstate.enabled;
45  
46  	if (!state->enabled) {
47  		if (cstate.enabled) {
48  			/* Disable LP timer */
49  			ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
50  			if (ret)
51  				return ret;
52  			/* disable clock to PWM counter */
53  			clk_disable(priv->clk);
54  		}
55  		return 0;
56  	}
57  
58  	/* Calculate the period and prescaler value */
59  	div = (unsigned long long)clk_get_rate(priv->clk) * state->period;
60  	do_div(div, NSEC_PER_SEC);
61  	if (!div) {
62  		/* Clock is too slow to achieve requested period. */
63  		dev_dbg(pwmchip_parent(chip), "Can't reach %llu ns\n", state->period);
64  		return -EINVAL;
65  	}
66  
67  	prd = div;
68  	while (div > STM32_LPTIM_MAX_ARR) {
69  		presc++;
70  		if ((1 << presc) > STM32_LPTIM_MAX_PRESCALER) {
71  			dev_err(pwmchip_parent(chip), "max prescaler exceeded\n");
72  			return -EINVAL;
73  		}
74  		div = prd >> presc;
75  	}
76  	prd = div;
77  
78  	/* Calculate the duty cycle */
79  	dty = prd * state->duty_cycle;
80  	do_div(dty, state->period);
81  
82  	if (!cstate.enabled) {
83  		/* enable clock to drive PWM counter */
84  		ret = clk_enable(priv->clk);
85  		if (ret)
86  			return ret;
87  	}
88  
89  	ret = regmap_read(priv->regmap, STM32_LPTIM_CFGR, &cfgr);
90  	if (ret)
91  		goto err;
92  
93  	if ((FIELD_GET(STM32_LPTIM_PRESC, cfgr) != presc) ||
94  	    (FIELD_GET(STM32_LPTIM_WAVPOL, cfgr) != state->polarity)) {
95  		val = FIELD_PREP(STM32_LPTIM_PRESC, presc);
96  		val |= FIELD_PREP(STM32_LPTIM_WAVPOL, state->polarity);
97  		mask = STM32_LPTIM_PRESC | STM32_LPTIM_WAVPOL;
98  
99  		/* Must disable LP timer to modify CFGR */
100  		reenable = true;
101  		ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
102  		if (ret)
103  			goto err;
104  
105  		ret = regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask,
106  					 val);
107  		if (ret)
108  			goto err;
109  	}
110  
111  	if (reenable) {
112  		/* Must (re)enable LP timer to modify CMP & ARR */
113  		ret = regmap_write(priv->regmap, STM32_LPTIM_CR,
114  				   STM32_LPTIM_ENABLE);
115  		if (ret)
116  			goto err;
117  	}
118  
119  	ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, prd - 1);
120  	if (ret)
121  		goto err;
122  
123  	ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, prd - (1 + dty));
124  	if (ret)
125  		goto err;
126  
127  	/* ensure CMP & ARR registers are properly written */
128  	ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
129  				       (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
130  				       100, 1000);
131  	if (ret) {
132  		dev_err(pwmchip_parent(chip), "ARR/CMP registers write issue\n");
133  		goto err;
134  	}
135  	ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
136  			   STM32_LPTIM_CMPOKCF_ARROKCF);
137  	if (ret)
138  		goto err;
139  
140  	if (reenable) {
141  		/* Start LP timer in continuous mode */
142  		ret = regmap_set_bits(priv->regmap, STM32_LPTIM_CR,
143  				      STM32_LPTIM_CNTSTRT);
144  		if (ret) {
145  			regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
146  			goto err;
147  		}
148  	}
149  
150  	return 0;
151  err:
152  	if (!cstate.enabled)
153  		clk_disable(priv->clk);
154  
155  	return ret;
156  }
157  
158  static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
159  				  struct pwm_device *pwm,
160  				  struct pwm_state *state)
161  {
162  	struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip);
163  	unsigned long rate = clk_get_rate(priv->clk);
164  	u32 val, presc, prd;
165  	u64 tmp;
166  
167  	regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
168  	state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val);
169  	/* Keep PWM counter clock refcount in sync with PWM initial state */
170  	if (state->enabled) {
171  		int ret = clk_enable(priv->clk);
172  
173  		if (ret)
174  			return ret;
175  	}
176  
177  	regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val);
178  	presc = FIELD_GET(STM32_LPTIM_PRESC, val);
179  	state->polarity = FIELD_GET(STM32_LPTIM_WAVPOL, val);
180  
181  	regmap_read(priv->regmap, STM32_LPTIM_ARR, &prd);
182  	tmp = prd + 1;
183  	tmp = (tmp << presc) * NSEC_PER_SEC;
184  	state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate);
185  
186  	regmap_read(priv->regmap, STM32_LPTIM_CMP, &val);
187  	tmp = prd - val;
188  	tmp = (tmp << presc) * NSEC_PER_SEC;
189  	state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate);
190  
191  	return 0;
192  }
193  
194  static const struct pwm_ops stm32_pwm_lp_ops = {
195  	.apply = stm32_pwm_lp_apply,
196  	.get_state = stm32_pwm_lp_get_state,
197  };
198  
199  static int stm32_pwm_lp_probe(struct platform_device *pdev)
200  {
201  	struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
202  	struct stm32_pwm_lp *priv;
203  	struct pwm_chip *chip;
204  	int ret;
205  
206  	chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*priv));
207  	if (IS_ERR(chip))
208  		return PTR_ERR(chip);
209  	priv = to_stm32_pwm_lp(chip);
210  
211  	priv->regmap = ddata->regmap;
212  	priv->clk = ddata->clk;
213  	chip->ops = &stm32_pwm_lp_ops;
214  
215  	ret = devm_pwmchip_add(&pdev->dev, chip);
216  	if (ret < 0)
217  		return ret;
218  
219  	platform_set_drvdata(pdev, chip);
220  
221  	return 0;
222  }
223  
224  static int stm32_pwm_lp_suspend(struct device *dev)
225  {
226  	struct pwm_chip *chip = dev_get_drvdata(dev);
227  	struct pwm_state state;
228  
229  	pwm_get_state(&chip->pwms[0], &state);
230  	if (state.enabled) {
231  		dev_err(dev, "The consumer didn't stop us (%s)\n",
232  			chip->pwms[0].label);
233  		return -EBUSY;
234  	}
235  
236  	return pinctrl_pm_select_sleep_state(dev);
237  }
238  
239  static int stm32_pwm_lp_resume(struct device *dev)
240  {
241  	return pinctrl_pm_select_default_state(dev);
242  }
243  
244  static DEFINE_SIMPLE_DEV_PM_OPS(stm32_pwm_lp_pm_ops, stm32_pwm_lp_suspend,
245  				stm32_pwm_lp_resume);
246  
247  static const struct of_device_id stm32_pwm_lp_of_match[] = {
248  	{ .compatible = "st,stm32-pwm-lp", },
249  	{},
250  };
251  MODULE_DEVICE_TABLE(of, stm32_pwm_lp_of_match);
252  
253  static struct platform_driver stm32_pwm_lp_driver = {
254  	.probe	= stm32_pwm_lp_probe,
255  	.driver	= {
256  		.name = "stm32-pwm-lp",
257  		.of_match_table = stm32_pwm_lp_of_match,
258  		.pm = pm_ptr(&stm32_pwm_lp_pm_ops),
259  	},
260  };
261  module_platform_driver(stm32_pwm_lp_driver);
262  
263  MODULE_ALIAS("platform:stm32-pwm-lp");
264  MODULE_DESCRIPTION("STMicroelectronics STM32 PWM LP driver");
265  MODULE_LICENSE("GPL v2");
266