Linux Audio

Check our new training course

Buildroot integration, development and maintenance

Need a Buildroot system for your embedded project?
Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * STM32 Timer Encoder and Counter driver
  4 *
  5 * Copyright (C) STMicroelectronics 2018
  6 *
  7 * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
  8 *
  9 */
 10#include <linux/counter.h>
 11#include <linux/iio/iio.h>
 12#include <linux/iio/types.h>
 13#include <linux/mfd/stm32-timers.h>
 14#include <linux/module.h>
 15#include <linux/platform_device.h>
 16
 17#define TIM_CCMR_CCXS	(BIT(8) | BIT(0))
 18#define TIM_CCMR_MASK	(TIM_CCMR_CC1S | TIM_CCMR_CC2S | \
 19			 TIM_CCMR_IC1F | TIM_CCMR_IC2F)
 20#define TIM_CCER_MASK	(TIM_CCER_CC1P | TIM_CCER_CC1NP | \
 21			 TIM_CCER_CC2P | TIM_CCER_CC2NP)
 22
 23struct stm32_timer_cnt {
 24	struct counter_device counter;
 25	struct regmap *regmap;
 26	struct clk *clk;
 27	u32 ceiling;
 28};
 29
 30/**
 31 * stm32_count_function - enumerates stm32 timer counter encoder modes
 32 * @STM32_COUNT_SLAVE_MODE_DISABLED: counts on internal clock when CEN=1
 33 * @STM32_COUNT_ENCODER_MODE_1: counts TI1FP1 edges, depending on TI2FP2 level
 34 * @STM32_COUNT_ENCODER_MODE_2: counts TI2FP2 edges, depending on TI1FP1 level
 35 * @STM32_COUNT_ENCODER_MODE_3: counts on both TI1FP1 and TI2FP2 edges
 36 */
 37enum stm32_count_function {
 38	STM32_COUNT_SLAVE_MODE_DISABLED = -1,
 39	STM32_COUNT_ENCODER_MODE_1,
 40	STM32_COUNT_ENCODER_MODE_2,
 41	STM32_COUNT_ENCODER_MODE_3,
 42};
 43
 44static enum counter_count_function stm32_count_functions[] = {
 45	[STM32_COUNT_ENCODER_MODE_1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
 46	[STM32_COUNT_ENCODER_MODE_2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B,
 47	[STM32_COUNT_ENCODER_MODE_3] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
 48};
 49
 50static int stm32_count_read(struct counter_device *counter,
 51			    struct counter_count *count,
 52			    struct counter_count_read_value *val)
 53{
 54	struct stm32_timer_cnt *const priv = counter->priv;
 55	u32 cnt;
 56
 57	regmap_read(priv->regmap, TIM_CNT, &cnt);
 58	counter_count_read_value_set(val, COUNTER_COUNT_POSITION, &cnt);
 59
 60	return 0;
 61}
 62
 63static int stm32_count_write(struct counter_device *counter,
 64			     struct counter_count *count,
 65			     struct counter_count_write_value *val)
 66{
 67	struct stm32_timer_cnt *const priv = counter->priv;
 68	u32 cnt;
 69	int err;
 70
 71	err = counter_count_write_value_get(&cnt, COUNTER_COUNT_POSITION, val);
 72	if (err)
 73		return err;
 74
 75	if (cnt > priv->ceiling)
 76		return -EINVAL;
 77
 78	return regmap_write(priv->regmap, TIM_CNT, cnt);
 79}
 80
 81static int stm32_count_function_get(struct counter_device *counter,
 82				    struct counter_count *count,
 83				    size_t *function)
 84{
 85	struct stm32_timer_cnt *const priv = counter->priv;
 86	u32 smcr;
 87
 88	regmap_read(priv->regmap, TIM_SMCR, &smcr);
 89
 90	switch (smcr & TIM_SMCR_SMS) {
 91	case 1:
 92		*function = STM32_COUNT_ENCODER_MODE_1;
 93		return 0;
 94	case 2:
 95		*function = STM32_COUNT_ENCODER_MODE_2;
 96		return 0;
 97	case 3:
 98		*function = STM32_COUNT_ENCODER_MODE_3;
 99		return 0;
100	}
101
102	return -EINVAL;
103}
104
105static int stm32_count_function_set(struct counter_device *counter,
106				    struct counter_count *count,
107				    size_t function)
108{
109	struct stm32_timer_cnt *const priv = counter->priv;
110	u32 cr1, sms;
111
112	switch (function) {
113	case STM32_COUNT_ENCODER_MODE_1:
114		sms = 1;
115		break;
116	case STM32_COUNT_ENCODER_MODE_2:
117		sms = 2;
118		break;
119	case STM32_COUNT_ENCODER_MODE_3:
120		sms = 3;
121		break;
122	default:
123		sms = 0;
124		break;
125	}
126
127	/* Store enable status */
128	regmap_read(priv->regmap, TIM_CR1, &cr1);
129
130	regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
131
132	/* TIMx_ARR register shouldn't be buffered (ARPE=0) */
133	regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0);
134	regmap_write(priv->regmap, TIM_ARR, priv->ceiling);
135
136	regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms);
137
138	/* Make sure that registers are updated */
139	regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
140
141	/* Restore the enable status */
142	regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, cr1);
143
144	return 0;
145}
146
147static ssize_t stm32_count_direction_read(struct counter_device *counter,
148				      struct counter_count *count,
149				      void *private, char *buf)
150{
151	struct stm32_timer_cnt *const priv = counter->priv;
152	const char *direction;
153	u32 cr1;
154
155	regmap_read(priv->regmap, TIM_CR1, &cr1);
156	direction = (cr1 & TIM_CR1_DIR) ? "backward" : "forward";
157
158	return scnprintf(buf, PAGE_SIZE, "%s\n", direction);
159}
160
161static ssize_t stm32_count_ceiling_read(struct counter_device *counter,
162					struct counter_count *count,
163					void *private, char *buf)
164{
165	struct stm32_timer_cnt *const priv = counter->priv;
166	u32 arr;
167
168	regmap_read(priv->regmap, TIM_ARR, &arr);
169
170	return snprintf(buf, PAGE_SIZE, "%u\n", arr);
171}
172
173static ssize_t stm32_count_ceiling_write(struct counter_device *counter,
174					 struct counter_count *count,
175					 void *private,
176					 const char *buf, size_t len)
177{
178	struct stm32_timer_cnt *const priv = counter->priv;
179	unsigned int ceiling;
180	int ret;
181
182	ret = kstrtouint(buf, 0, &ceiling);
183	if (ret)
184		return ret;
185
186	/* TIMx_ARR register shouldn't be buffered (ARPE=0) */
187	regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0);
188	regmap_write(priv->regmap, TIM_ARR, ceiling);
189
190	priv->ceiling = ceiling;
191	return len;
192}
193
194static ssize_t stm32_count_enable_read(struct counter_device *counter,
195				       struct counter_count *count,
196				       void *private, char *buf)
197{
198	struct stm32_timer_cnt *const priv = counter->priv;
199	u32 cr1;
200
201	regmap_read(priv->regmap, TIM_CR1, &cr1);
202
203	return scnprintf(buf, PAGE_SIZE, "%d\n", (bool)(cr1 & TIM_CR1_CEN));
204}
205
206static ssize_t stm32_count_enable_write(struct counter_device *counter,
207					struct counter_count *count,
208					void *private,
209					const char *buf, size_t len)
210{
211	struct stm32_timer_cnt *const priv = counter->priv;
212	int err;
213	u32 cr1;
214	bool enable;
215
216	err = kstrtobool(buf, &enable);
217	if (err)
218		return err;
219
220	if (enable) {
221		regmap_read(priv->regmap, TIM_CR1, &cr1);
222			if (!(cr1 & TIM_CR1_CEN))
223				clk_enable(priv->clk);
224
225		regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN,
226				   TIM_CR1_CEN);
227	} else {
228		regmap_read(priv->regmap, TIM_CR1, &cr1);
229		regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
230		if (cr1 & TIM_CR1_CEN)
231			clk_disable(priv->clk);
232	}
233
234	return len;
235}
236
237static const struct counter_count_ext stm32_count_ext[] = {
238	{
239		.name = "direction",
240		.read = stm32_count_direction_read,
241	},
242	{
243		.name = "enable",
244		.read = stm32_count_enable_read,
245		.write = stm32_count_enable_write
246	},
247	{
248		.name = "ceiling",
249		.read = stm32_count_ceiling_read,
250		.write = stm32_count_ceiling_write
251	},
252};
253
254enum stm32_synapse_action {
255	STM32_SYNAPSE_ACTION_NONE,
256	STM32_SYNAPSE_ACTION_BOTH_EDGES
257};
258
259static enum counter_synapse_action stm32_synapse_actions[] = {
260	[STM32_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE,
261	[STM32_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES
262};
263
264static int stm32_action_get(struct counter_device *counter,
265			    struct counter_count *count,
266			    struct counter_synapse *synapse,
267			    size_t *action)
268{
269	size_t function;
270	int err;
271
272	/* Default action mode (e.g. STM32_COUNT_SLAVE_MODE_DISABLED) */
273	*action = STM32_SYNAPSE_ACTION_NONE;
274
275	err = stm32_count_function_get(counter, count, &function);
276	if (err)
277		return 0;
278
279	switch (function) {
280	case STM32_COUNT_ENCODER_MODE_1:
281		/* counts up/down on TI1FP1 edge depending on TI2FP2 level */
282		if (synapse->signal->id == count->synapses[0].signal->id)
283			*action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
284		break;
285	case STM32_COUNT_ENCODER_MODE_2:
286		/* counts up/down on TI2FP2 edge depending on TI1FP1 level */
287		if (synapse->signal->id == count->synapses[1].signal->id)
288			*action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
289		break;
290	case STM32_COUNT_ENCODER_MODE_3:
291		/* counts up/down on both TI1FP1 and TI2FP2 edges */
292		*action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
293		break;
294	}
295
296	return 0;
297}
298
299static const struct counter_ops stm32_timer_cnt_ops = {
300	.count_read = stm32_count_read,
301	.count_write = stm32_count_write,
302	.function_get = stm32_count_function_get,
303	.function_set = stm32_count_function_set,
304	.action_get = stm32_action_get,
305};
306
307static struct counter_signal stm32_signals[] = {
308	{
309		.id = 0,
310		.name = "Channel 1 Quadrature A"
311	},
312	{
313		.id = 1,
314		.name = "Channel 1 Quadrature B"
315	}
316};
317
318static struct counter_synapse stm32_count_synapses[] = {
319	{
320		.actions_list = stm32_synapse_actions,
321		.num_actions = ARRAY_SIZE(stm32_synapse_actions),
322		.signal = &stm32_signals[0]
323	},
324	{
325		.actions_list = stm32_synapse_actions,
326		.num_actions = ARRAY_SIZE(stm32_synapse_actions),
327		.signal = &stm32_signals[1]
328	}
329};
330
331static struct counter_count stm32_counts = {
332	.id = 0,
333	.name = "Channel 1 Count",
334	.functions_list = stm32_count_functions,
335	.num_functions = ARRAY_SIZE(stm32_count_functions),
336	.synapses = stm32_count_synapses,
337	.num_synapses = ARRAY_SIZE(stm32_count_synapses),
338	.ext = stm32_count_ext,
339	.num_ext = ARRAY_SIZE(stm32_count_ext)
340};
341
342static int stm32_timer_cnt_probe(struct platform_device *pdev)
343{
344	struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent);
345	struct device *dev = &pdev->dev;
346	struct stm32_timer_cnt *priv;
347
348	if (IS_ERR_OR_NULL(ddata))
349		return -EINVAL;
350
351	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
352	if (!priv)
353		return -ENOMEM;
354
355	priv->regmap = ddata->regmap;
356	priv->clk = ddata->clk;
357	priv->ceiling = ddata->max_arr;
358
359	priv->counter.name = dev_name(dev);
360	priv->counter.parent = dev;
361	priv->counter.ops = &stm32_timer_cnt_ops;
362	priv->counter.counts = &stm32_counts;
363	priv->counter.num_counts = 1;
364	priv->counter.signals = stm32_signals;
365	priv->counter.num_signals = ARRAY_SIZE(stm32_signals);
366	priv->counter.priv = priv;
367
368	/* Register Counter device */
369	return devm_counter_register(dev, &priv->counter);
370}
371
372static const struct of_device_id stm32_timer_cnt_of_match[] = {
373	{ .compatible = "st,stm32-timer-counter", },
374	{},
375};
376MODULE_DEVICE_TABLE(of, stm32_timer_cnt_of_match);
377
378static struct platform_driver stm32_timer_cnt_driver = {
379	.probe = stm32_timer_cnt_probe,
380	.driver = {
381		.name = "stm32-timer-counter",
382		.of_match_table = stm32_timer_cnt_of_match,
383	},
384};
385module_platform_driver(stm32_timer_cnt_driver);
386
387MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
388MODULE_ALIAS("platform:stm32-timer-counter");
389MODULE_DESCRIPTION("STMicroelectronics STM32 TIMER counter driver");
390MODULE_LICENSE("GPL v2");