xref: /linux/drivers/counter/stm32-lptimer-cnt.c (revision 18fbf5151d2c0bfe433c7428eef03cabf5fdb2fa)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * STM32 Low-Power Timer Encoder and Counter driver
4  *
5  * Copyright (C) STMicroelectronics 2017
6  *
7  * Author: Fabrice Gasnier <fabrice.gasnier@st.com>
8  *
9  * Inspired by 104-quad-8 and stm32-timer-trigger drivers.
10  *
11  */
12 
13 #include <linux/bitfield.h>
14 #include <linux/counter.h>
15 #include <linux/mfd/stm32-lptimer.h>
16 #include <linux/module.h>
17 #include <linux/pinctrl/consumer.h>
18 #include <linux/platform_device.h>
19 #include <linux/types.h>
20 
21 struct stm32_lptim_cnt {
22 	struct device *dev;
23 	struct regmap *regmap;
24 	struct clk *clk;
25 	u32 ceiling;
26 	u32 polarity;
27 	u32 quadrature_mode;
28 	bool enabled;
29 };
30 
31 static int stm32_lptim_is_enabled(struct stm32_lptim_cnt *priv)
32 {
33 	u32 val;
34 	int ret;
35 
36 	ret = regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
37 	if (ret)
38 		return ret;
39 
40 	return FIELD_GET(STM32_LPTIM_ENABLE, val);
41 }
42 
43 static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv,
44 					int enable)
45 {
46 	int ret;
47 	u32 val;
48 
49 	val = FIELD_PREP(STM32_LPTIM_ENABLE, enable);
50 	ret = regmap_write(priv->regmap, STM32_LPTIM_CR, val);
51 	if (ret)
52 		return ret;
53 
54 	if (!enable) {
55 		clk_disable(priv->clk);
56 		priv->enabled = false;
57 		return 0;
58 	}
59 
60 	ret = clk_enable(priv->clk);
61 	if (ret)
62 		goto disable_cnt;
63 
64 	/* LP timer must be enabled before writing CMP & ARR */
65 	ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, priv->ceiling);
66 	if (ret)
67 		goto disable_clk;
68 
69 	ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, 0);
70 	if (ret)
71 		goto disable_clk;
72 
73 	/* ensure CMP & ARR registers are properly written */
74 	ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
75 				       (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
76 				       100, 1000);
77 	if (ret)
78 		goto disable_clk;
79 
80 	ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
81 			   STM32_LPTIM_CMPOKCF_ARROKCF);
82 	if (ret)
83 		goto disable_clk;
84 
85 	priv->enabled = true;
86 
87 	/* Start LP timer in continuous mode */
88 	return regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
89 				  STM32_LPTIM_CNTSTRT, STM32_LPTIM_CNTSTRT);
90 
91 disable_clk:
92 	clk_disable(priv->clk);
93 disable_cnt:
94 	regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
95 
96 	return ret;
97 }
98 
99 static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
100 {
101 	u32 mask = STM32_LPTIM_ENC | STM32_LPTIM_COUNTMODE |
102 		   STM32_LPTIM_CKPOL | STM32_LPTIM_PRESC;
103 	u32 val;
104 
105 	/* Setup LP timer encoder/counter and polarity, without prescaler */
106 	if (priv->quadrature_mode)
107 		val = enable ? STM32_LPTIM_ENC : 0;
108 	else
109 		val = enable ? STM32_LPTIM_COUNTMODE : 0;
110 	val |= FIELD_PREP(STM32_LPTIM_CKPOL, enable ? priv->polarity : 0);
111 
112 	return regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask, val);
113 }
114 
115 /*
116  * In non-quadrature mode, device counts up on active edge.
117  * In quadrature mode, encoder counting scenarios are as follows:
118  * +---------+----------+--------------------+--------------------+
119  * | Active  | Level on |      IN1 signal    |     IN2 signal     |
120  * | edge    | opposite +----------+---------+----------+---------+
121  * |         | signal   |  Rising  | Falling |  Rising  | Falling |
122  * +---------+----------+----------+---------+----------+---------+
123  * | Rising  | High ->  |   Down   |    -    |   Up     |    -    |
124  * | edge    | Low  ->  |   Up     |    -    |   Down   |    -    |
125  * +---------+----------+----------+---------+----------+---------+
126  * | Falling | High ->  |    -     |   Up    |    -     |   Down  |
127  * | edge    | Low  ->  |    -     |   Down  |    -     |   Up    |
128  * +---------+----------+----------+---------+----------+---------+
129  * | Both    | High ->  |   Down   |   Up    |   Up     |   Down  |
130  * | edges   | Low  ->  |   Up     |   Down  |   Down   |   Up    |
131  * +---------+----------+----------+---------+----------+---------+
132  */
133 static const enum counter_function stm32_lptim_cnt_functions[] = {
134 	COUNTER_FUNCTION_INCREASE,
135 	COUNTER_FUNCTION_QUADRATURE_X4,
136 };
137 
138 static const enum counter_synapse_action stm32_lptim_cnt_synapse_actions[] = {
139 	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
140 	COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
141 	COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
142 	COUNTER_SYNAPSE_ACTION_NONE,
143 };
144 
145 static int stm32_lptim_cnt_read(struct counter_device *counter,
146 				struct counter_count *count, u64 *val)
147 {
148 	struct stm32_lptim_cnt *const priv = counter_priv(counter);
149 	u32 cnt;
150 	int ret;
151 
152 	ret = regmap_read(priv->regmap, STM32_LPTIM_CNT, &cnt);
153 	if (ret)
154 		return ret;
155 
156 	*val = cnt;
157 
158 	return 0;
159 }
160 
161 static int stm32_lptim_cnt_function_read(struct counter_device *counter,
162 					 struct counter_count *count,
163 					 enum counter_function *function)
164 {
165 	struct stm32_lptim_cnt *const priv = counter_priv(counter);
166 
167 	if (!priv->quadrature_mode) {
168 		*function = COUNTER_FUNCTION_INCREASE;
169 		return 0;
170 	}
171 
172 	if (priv->polarity == STM32_LPTIM_CKPOL_BOTH_EDGES) {
173 		*function = COUNTER_FUNCTION_QUADRATURE_X4;
174 		return 0;
175 	}
176 
177 	return -EINVAL;
178 }
179 
180 static int stm32_lptim_cnt_function_write(struct counter_device *counter,
181 					  struct counter_count *count,
182 					  enum counter_function function)
183 {
184 	struct stm32_lptim_cnt *const priv = counter_priv(counter);
185 
186 	if (stm32_lptim_is_enabled(priv))
187 		return -EBUSY;
188 
189 	switch (function) {
190 	case COUNTER_FUNCTION_INCREASE:
191 		priv->quadrature_mode = 0;
192 		return 0;
193 	case COUNTER_FUNCTION_QUADRATURE_X4:
194 		priv->quadrature_mode = 1;
195 		priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES;
196 		return 0;
197 	default:
198 		/* should never reach this path */
199 		return -EINVAL;
200 	}
201 }
202 
203 static int stm32_lptim_cnt_enable_read(struct counter_device *counter,
204 				       struct counter_count *count,
205 				       u8 *enable)
206 {
207 	struct stm32_lptim_cnt *const priv = counter_priv(counter);
208 	int ret;
209 
210 	ret = stm32_lptim_is_enabled(priv);
211 	if (ret < 0)
212 		return ret;
213 
214 	*enable = ret;
215 
216 	return 0;
217 }
218 
219 static int stm32_lptim_cnt_enable_write(struct counter_device *counter,
220 					struct counter_count *count,
221 					u8 enable)
222 {
223 	struct stm32_lptim_cnt *const priv = counter_priv(counter);
224 	int ret;
225 
226 	/* Check nobody uses the timer, or already disabled/enabled */
227 	ret = stm32_lptim_is_enabled(priv);
228 	if ((ret < 0) || (!ret && !enable))
229 		return ret;
230 	if (enable && ret)
231 		return -EBUSY;
232 
233 	ret = stm32_lptim_setup(priv, enable);
234 	if (ret)
235 		return ret;
236 
237 	ret = stm32_lptim_set_enable_state(priv, enable);
238 	if (ret)
239 		return ret;
240 
241 	return 0;
242 }
243 
244 static int stm32_lptim_cnt_ceiling_read(struct counter_device *counter,
245 					struct counter_count *count,
246 					u64 *ceiling)
247 {
248 	struct stm32_lptim_cnt *const priv = counter_priv(counter);
249 
250 	*ceiling = priv->ceiling;
251 
252 	return 0;
253 }
254 
255 static int stm32_lptim_cnt_ceiling_write(struct counter_device *counter,
256 					 struct counter_count *count,
257 					 u64 ceiling)
258 {
259 	struct stm32_lptim_cnt *const priv = counter_priv(counter);
260 
261 	if (stm32_lptim_is_enabled(priv))
262 		return -EBUSY;
263 
264 	if (ceiling > STM32_LPTIM_MAX_ARR)
265 		return -ERANGE;
266 
267 	priv->ceiling = ceiling;
268 
269 	return 0;
270 }
271 
272 static struct counter_comp stm32_lptim_cnt_ext[] = {
273 	COUNTER_COMP_ENABLE(stm32_lptim_cnt_enable_read,
274 			    stm32_lptim_cnt_enable_write),
275 	COUNTER_COMP_CEILING(stm32_lptim_cnt_ceiling_read,
276 			     stm32_lptim_cnt_ceiling_write),
277 };
278 
279 static int stm32_lptim_cnt_action_read(struct counter_device *counter,
280 				       struct counter_count *count,
281 				       struct counter_synapse *synapse,
282 				       enum counter_synapse_action *action)
283 {
284 	struct stm32_lptim_cnt *const priv = counter_priv(counter);
285 	enum counter_function function;
286 	int err;
287 
288 	err = stm32_lptim_cnt_function_read(counter, count, &function);
289 	if (err)
290 		return err;
291 
292 	switch (function) {
293 	case COUNTER_FUNCTION_INCREASE:
294 		/* LP Timer acts as up-counter on input 1 */
295 		if (synapse->signal->id != count->synapses[0].signal->id) {
296 			*action = COUNTER_SYNAPSE_ACTION_NONE;
297 			return 0;
298 		}
299 
300 		switch (priv->polarity) {
301 		case STM32_LPTIM_CKPOL_RISING_EDGE:
302 			*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
303 			return 0;
304 		case STM32_LPTIM_CKPOL_FALLING_EDGE:
305 			*action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE;
306 			return 0;
307 		case STM32_LPTIM_CKPOL_BOTH_EDGES:
308 			*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
309 			return 0;
310 		default:
311 			/* should never reach this path */
312 			return -EINVAL;
313 		}
314 	case COUNTER_FUNCTION_QUADRATURE_X4:
315 		*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
316 		return 0;
317 	default:
318 		/* should never reach this path */
319 		return -EINVAL;
320 	}
321 }
322 
323 static int stm32_lptim_cnt_action_write(struct counter_device *counter,
324 					struct counter_count *count,
325 					struct counter_synapse *synapse,
326 					enum counter_synapse_action action)
327 {
328 	struct stm32_lptim_cnt *const priv = counter_priv(counter);
329 	enum counter_function function;
330 	int err;
331 
332 	if (stm32_lptim_is_enabled(priv))
333 		return -EBUSY;
334 
335 	err = stm32_lptim_cnt_function_read(counter, count, &function);
336 	if (err)
337 		return err;
338 
339 	/* only set polarity when in counter mode (on input 1) */
340 	if (function != COUNTER_FUNCTION_INCREASE
341 	    || synapse->signal->id != count->synapses[0].signal->id)
342 		return -EINVAL;
343 
344 	switch (action) {
345 	case COUNTER_SYNAPSE_ACTION_RISING_EDGE:
346 		priv->polarity = STM32_LPTIM_CKPOL_RISING_EDGE;
347 		return 0;
348 	case COUNTER_SYNAPSE_ACTION_FALLING_EDGE:
349 		priv->polarity = STM32_LPTIM_CKPOL_FALLING_EDGE;
350 		return 0;
351 	case COUNTER_SYNAPSE_ACTION_BOTH_EDGES:
352 		priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES;
353 		return 0;
354 	default:
355 		return -EINVAL;
356 	}
357 }
358 
359 static const struct counter_ops stm32_lptim_cnt_ops = {
360 	.count_read = stm32_lptim_cnt_read,
361 	.function_read = stm32_lptim_cnt_function_read,
362 	.function_write = stm32_lptim_cnt_function_write,
363 	.action_read = stm32_lptim_cnt_action_read,
364 	.action_write = stm32_lptim_cnt_action_write,
365 };
366 
367 static struct counter_signal stm32_lptim_cnt_signals[] = {
368 	{
369 		.id = 0,
370 		.name = "Channel 1 Quadrature A"
371 	},
372 	{
373 		.id = 1,
374 		.name = "Channel 1 Quadrature B"
375 	}
376 };
377 
378 static struct counter_synapse stm32_lptim_cnt_synapses[] = {
379 	{
380 		.actions_list = stm32_lptim_cnt_synapse_actions,
381 		.num_actions = ARRAY_SIZE(stm32_lptim_cnt_synapse_actions),
382 		.signal = &stm32_lptim_cnt_signals[0]
383 	},
384 	{
385 		.actions_list = stm32_lptim_cnt_synapse_actions,
386 		.num_actions = ARRAY_SIZE(stm32_lptim_cnt_synapse_actions),
387 		.signal = &stm32_lptim_cnt_signals[1]
388 	}
389 };
390 
391 /* LP timer with encoder */
392 static struct counter_count stm32_lptim_enc_counts = {
393 	.id = 0,
394 	.name = "LPTimer Count",
395 	.functions_list = stm32_lptim_cnt_functions,
396 	.num_functions = ARRAY_SIZE(stm32_lptim_cnt_functions),
397 	.synapses = stm32_lptim_cnt_synapses,
398 	.num_synapses = ARRAY_SIZE(stm32_lptim_cnt_synapses),
399 	.ext = stm32_lptim_cnt_ext,
400 	.num_ext = ARRAY_SIZE(stm32_lptim_cnt_ext)
401 };
402 
403 /* LP timer without encoder (counter only) */
404 static struct counter_count stm32_lptim_in1_counts = {
405 	.id = 0,
406 	.name = "LPTimer Count",
407 	.functions_list = stm32_lptim_cnt_functions,
408 	.num_functions = 1,
409 	.synapses = stm32_lptim_cnt_synapses,
410 	.num_synapses = 1,
411 	.ext = stm32_lptim_cnt_ext,
412 	.num_ext = ARRAY_SIZE(stm32_lptim_cnt_ext)
413 };
414 
415 static int stm32_lptim_cnt_probe(struct platform_device *pdev)
416 {
417 	struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
418 	struct counter_device *counter;
419 	struct stm32_lptim_cnt *priv;
420 	int ret;
421 
422 	if (IS_ERR_OR_NULL(ddata))
423 		return -EINVAL;
424 
425 	counter = devm_counter_alloc(&pdev->dev, sizeof(*priv));
426 	if (!counter)
427 		return -ENOMEM;
428 	priv = counter_priv(counter);
429 
430 	priv->dev = &pdev->dev;
431 	priv->regmap = ddata->regmap;
432 	priv->clk = ddata->clk;
433 	priv->ceiling = STM32_LPTIM_MAX_ARR;
434 
435 	/* Initialize Counter device */
436 	counter->name = dev_name(&pdev->dev);
437 	counter->parent = &pdev->dev;
438 	counter->ops = &stm32_lptim_cnt_ops;
439 	if (ddata->has_encoder) {
440 		counter->counts = &stm32_lptim_enc_counts;
441 		counter->num_signals = ARRAY_SIZE(stm32_lptim_cnt_signals);
442 	} else {
443 		counter->counts = &stm32_lptim_in1_counts;
444 		counter->num_signals = 1;
445 	}
446 	counter->num_counts = 1;
447 	counter->signals = stm32_lptim_cnt_signals;
448 
449 	platform_set_drvdata(pdev, priv);
450 
451 	ret = devm_counter_add(&pdev->dev, counter);
452 	if (ret < 0)
453 		return dev_err_probe(&pdev->dev, ret, "Failed to add counter\n");
454 
455 	return 0;
456 }
457 
458 #ifdef CONFIG_PM_SLEEP
459 static int stm32_lptim_cnt_suspend(struct device *dev)
460 {
461 	struct stm32_lptim_cnt *priv = dev_get_drvdata(dev);
462 	int ret;
463 
464 	/* Only take care of enabled counter: don't disturb other MFD child */
465 	if (priv->enabled) {
466 		ret = stm32_lptim_setup(priv, 0);
467 		if (ret)
468 			return ret;
469 
470 		ret = stm32_lptim_set_enable_state(priv, 0);
471 		if (ret)
472 			return ret;
473 
474 		/* Force enable state for later resume */
475 		priv->enabled = true;
476 	}
477 
478 	return pinctrl_pm_select_sleep_state(dev);
479 }
480 
481 static int stm32_lptim_cnt_resume(struct device *dev)
482 {
483 	struct stm32_lptim_cnt *priv = dev_get_drvdata(dev);
484 	int ret;
485 
486 	ret = pinctrl_pm_select_default_state(dev);
487 	if (ret)
488 		return ret;
489 
490 	if (priv->enabled) {
491 		priv->enabled = false;
492 		ret = stm32_lptim_setup(priv, 1);
493 		if (ret)
494 			return ret;
495 
496 		ret = stm32_lptim_set_enable_state(priv, 1);
497 		if (ret)
498 			return ret;
499 	}
500 
501 	return 0;
502 }
503 #endif
504 
505 static SIMPLE_DEV_PM_OPS(stm32_lptim_cnt_pm_ops, stm32_lptim_cnt_suspend,
506 			 stm32_lptim_cnt_resume);
507 
508 static const struct of_device_id stm32_lptim_cnt_of_match[] = {
509 	{ .compatible = "st,stm32-lptimer-counter", },
510 	{},
511 };
512 MODULE_DEVICE_TABLE(of, stm32_lptim_cnt_of_match);
513 
514 static struct platform_driver stm32_lptim_cnt_driver = {
515 	.probe = stm32_lptim_cnt_probe,
516 	.driver = {
517 		.name = "stm32-lptimer-counter",
518 		.of_match_table = stm32_lptim_cnt_of_match,
519 		.pm = &stm32_lptim_cnt_pm_ops,
520 	},
521 };
522 module_platform_driver(stm32_lptim_cnt_driver);
523 
524 MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
525 MODULE_ALIAS("platform:stm32-lptimer-counter");
526 MODULE_DESCRIPTION("STMicroelectronics STM32 LPTIM counter driver");
527 MODULE_LICENSE("GPL v2");
528 MODULE_IMPORT_NS("COUNTER");
529