blob: 889ea7a6ed630cd48b820ab2e4eb3ef8209fd45e [file] [log] [blame]
David Brazdil0f672f62019-12-10 10:32:29 +00001// 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;
Olivier Deprez0e641232021-09-23 10:07:05 +020027 u32 max_arr;
David Brazdil0f672f62019-12-10 10:32:29 +000028};
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 {
Olivier Deprez0e641232021-09-23 10:07:05 +020038 STM32_COUNT_SLAVE_MODE_DISABLED,
David Brazdil0f672f62019-12-10 10:32:29 +000039 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[] = {
Olivier Deprez0e641232021-09-23 10:07:05 +020045 [STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_COUNT_FUNCTION_INCREASE,
David Brazdil0f672f62019-12-10 10:32:29 +000046 [STM32_COUNT_ENCODER_MODE_1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
47 [STM32_COUNT_ENCODER_MODE_2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B,
48 [STM32_COUNT_ENCODER_MODE_3] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
49};
50
51static int stm32_count_read(struct counter_device *counter,
52 struct counter_count *count,
53 struct counter_count_read_value *val)
54{
55 struct stm32_timer_cnt *const priv = counter->priv;
56 u32 cnt;
57
58 regmap_read(priv->regmap, TIM_CNT, &cnt);
59 counter_count_read_value_set(val, COUNTER_COUNT_POSITION, &cnt);
60
61 return 0;
62}
63
64static int stm32_count_write(struct counter_device *counter,
65 struct counter_count *count,
66 struct counter_count_write_value *val)
67{
68 struct stm32_timer_cnt *const priv = counter->priv;
Olivier Deprez0e641232021-09-23 10:07:05 +020069 u32 cnt, ceiling;
David Brazdil0f672f62019-12-10 10:32:29 +000070 int err;
71
72 err = counter_count_write_value_get(&cnt, COUNTER_COUNT_POSITION, val);
73 if (err)
74 return err;
75
Olivier Deprez0e641232021-09-23 10:07:05 +020076 regmap_read(priv->regmap, TIM_ARR, &ceiling);
77 if (cnt > ceiling)
David Brazdil0f672f62019-12-10 10:32:29 +000078 return -EINVAL;
79
80 return regmap_write(priv->regmap, TIM_CNT, cnt);
81}
82
83static int stm32_count_function_get(struct counter_device *counter,
84 struct counter_count *count,
85 size_t *function)
86{
87 struct stm32_timer_cnt *const priv = counter->priv;
88 u32 smcr;
89
90 regmap_read(priv->regmap, TIM_SMCR, &smcr);
91
92 switch (smcr & TIM_SMCR_SMS) {
Olivier Deprez0e641232021-09-23 10:07:05 +020093 case 0:
94 *function = STM32_COUNT_SLAVE_MODE_DISABLED;
95 return 0;
David Brazdil0f672f62019-12-10 10:32:29 +000096 case 1:
97 *function = STM32_COUNT_ENCODER_MODE_1;
98 return 0;
99 case 2:
100 *function = STM32_COUNT_ENCODER_MODE_2;
101 return 0;
102 case 3:
103 *function = STM32_COUNT_ENCODER_MODE_3;
104 return 0;
Olivier Deprez0e641232021-09-23 10:07:05 +0200105 default:
106 return -EINVAL;
David Brazdil0f672f62019-12-10 10:32:29 +0000107 }
David Brazdil0f672f62019-12-10 10:32:29 +0000108}
109
110static int stm32_count_function_set(struct counter_device *counter,
111 struct counter_count *count,
112 size_t function)
113{
114 struct stm32_timer_cnt *const priv = counter->priv;
115 u32 cr1, sms;
116
117 switch (function) {
Olivier Deprez0e641232021-09-23 10:07:05 +0200118 case STM32_COUNT_SLAVE_MODE_DISABLED:
119 sms = 0;
120 break;
David Brazdil0f672f62019-12-10 10:32:29 +0000121 case STM32_COUNT_ENCODER_MODE_1:
122 sms = 1;
123 break;
124 case STM32_COUNT_ENCODER_MODE_2:
125 sms = 2;
126 break;
127 case STM32_COUNT_ENCODER_MODE_3:
128 sms = 3;
129 break;
130 default:
Olivier Deprez0e641232021-09-23 10:07:05 +0200131 return -EINVAL;
David Brazdil0f672f62019-12-10 10:32:29 +0000132 }
133
134 /* Store enable status */
135 regmap_read(priv->regmap, TIM_CR1, &cr1);
136
137 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
138
David Brazdil0f672f62019-12-10 10:32:29 +0000139 regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms);
140
141 /* Make sure that registers are updated */
142 regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
143
144 /* Restore the enable status */
145 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, cr1);
146
147 return 0;
148}
149
150static ssize_t stm32_count_direction_read(struct counter_device *counter,
151 struct counter_count *count,
152 void *private, char *buf)
153{
154 struct stm32_timer_cnt *const priv = counter->priv;
155 const char *direction;
156 u32 cr1;
157
158 regmap_read(priv->regmap, TIM_CR1, &cr1);
159 direction = (cr1 & TIM_CR1_DIR) ? "backward" : "forward";
160
161 return scnprintf(buf, PAGE_SIZE, "%s\n", direction);
162}
163
164static ssize_t stm32_count_ceiling_read(struct counter_device *counter,
165 struct counter_count *count,
166 void *private, char *buf)
167{
168 struct stm32_timer_cnt *const priv = counter->priv;
169 u32 arr;
170
171 regmap_read(priv->regmap, TIM_ARR, &arr);
172
173 return snprintf(buf, PAGE_SIZE, "%u\n", arr);
174}
175
176static ssize_t stm32_count_ceiling_write(struct counter_device *counter,
177 struct counter_count *count,
178 void *private,
179 const char *buf, size_t len)
180{
181 struct stm32_timer_cnt *const priv = counter->priv;
182 unsigned int ceiling;
183 int ret;
184
185 ret = kstrtouint(buf, 0, &ceiling);
186 if (ret)
187 return ret;
188
Olivier Deprez0e641232021-09-23 10:07:05 +0200189 if (ceiling > priv->max_arr)
190 return -ERANGE;
191
David Brazdil0f672f62019-12-10 10:32:29 +0000192 /* TIMx_ARR register shouldn't be buffered (ARPE=0) */
193 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0);
194 regmap_write(priv->regmap, TIM_ARR, ceiling);
195
David Brazdil0f672f62019-12-10 10:32:29 +0000196 return len;
197}
198
199static ssize_t stm32_count_enable_read(struct counter_device *counter,
200 struct counter_count *count,
201 void *private, char *buf)
202{
203 struct stm32_timer_cnt *const priv = counter->priv;
204 u32 cr1;
205
206 regmap_read(priv->regmap, TIM_CR1, &cr1);
207
208 return scnprintf(buf, PAGE_SIZE, "%d\n", (bool)(cr1 & TIM_CR1_CEN));
209}
210
211static ssize_t stm32_count_enable_write(struct counter_device *counter,
212 struct counter_count *count,
213 void *private,
214 const char *buf, size_t len)
215{
216 struct stm32_timer_cnt *const priv = counter->priv;
217 int err;
218 u32 cr1;
219 bool enable;
220
221 err = kstrtobool(buf, &enable);
222 if (err)
223 return err;
224
225 if (enable) {
226 regmap_read(priv->regmap, TIM_CR1, &cr1);
227 if (!(cr1 & TIM_CR1_CEN))
228 clk_enable(priv->clk);
229
230 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN,
231 TIM_CR1_CEN);
232 } else {
233 regmap_read(priv->regmap, TIM_CR1, &cr1);
234 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
235 if (cr1 & TIM_CR1_CEN)
236 clk_disable(priv->clk);
237 }
238
239 return len;
240}
241
242static const struct counter_count_ext stm32_count_ext[] = {
243 {
244 .name = "direction",
245 .read = stm32_count_direction_read,
246 },
247 {
248 .name = "enable",
249 .read = stm32_count_enable_read,
250 .write = stm32_count_enable_write
251 },
252 {
253 .name = "ceiling",
254 .read = stm32_count_ceiling_read,
255 .write = stm32_count_ceiling_write
256 },
257};
258
259enum stm32_synapse_action {
260 STM32_SYNAPSE_ACTION_NONE,
261 STM32_SYNAPSE_ACTION_BOTH_EDGES
262};
263
264static enum counter_synapse_action stm32_synapse_actions[] = {
265 [STM32_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE,
266 [STM32_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES
267};
268
269static int stm32_action_get(struct counter_device *counter,
270 struct counter_count *count,
271 struct counter_synapse *synapse,
272 size_t *action)
273{
274 size_t function;
275 int err;
276
David Brazdil0f672f62019-12-10 10:32:29 +0000277 err = stm32_count_function_get(counter, count, &function);
278 if (err)
Olivier Deprez0e641232021-09-23 10:07:05 +0200279 return err;
David Brazdil0f672f62019-12-10 10:32:29 +0000280
281 switch (function) {
Olivier Deprez0e641232021-09-23 10:07:05 +0200282 case STM32_COUNT_SLAVE_MODE_DISABLED:
283 /* counts on internal clock when CEN=1 */
284 *action = STM32_SYNAPSE_ACTION_NONE;
285 return 0;
David Brazdil0f672f62019-12-10 10:32:29 +0000286 case STM32_COUNT_ENCODER_MODE_1:
287 /* counts up/down on TI1FP1 edge depending on TI2FP2 level */
288 if (synapse->signal->id == count->synapses[0].signal->id)
289 *action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
Olivier Deprez0e641232021-09-23 10:07:05 +0200290 else
291 *action = STM32_SYNAPSE_ACTION_NONE;
292 return 0;
David Brazdil0f672f62019-12-10 10:32:29 +0000293 case STM32_COUNT_ENCODER_MODE_2:
294 /* counts up/down on TI2FP2 edge depending on TI1FP1 level */
295 if (synapse->signal->id == count->synapses[1].signal->id)
296 *action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
Olivier Deprez0e641232021-09-23 10:07:05 +0200297 else
298 *action = STM32_SYNAPSE_ACTION_NONE;
299 return 0;
David Brazdil0f672f62019-12-10 10:32:29 +0000300 case STM32_COUNT_ENCODER_MODE_3:
301 /* counts up/down on both TI1FP1 and TI2FP2 edges */
302 *action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
Olivier Deprez0e641232021-09-23 10:07:05 +0200303 return 0;
304 default:
305 return -EINVAL;
David Brazdil0f672f62019-12-10 10:32:29 +0000306 }
David Brazdil0f672f62019-12-10 10:32:29 +0000307}
308
309static const struct counter_ops stm32_timer_cnt_ops = {
310 .count_read = stm32_count_read,
311 .count_write = stm32_count_write,
312 .function_get = stm32_count_function_get,
313 .function_set = stm32_count_function_set,
314 .action_get = stm32_action_get,
315};
316
317static struct counter_signal stm32_signals[] = {
318 {
319 .id = 0,
320 .name = "Channel 1 Quadrature A"
321 },
322 {
323 .id = 1,
324 .name = "Channel 1 Quadrature B"
325 }
326};
327
328static struct counter_synapse stm32_count_synapses[] = {
329 {
330 .actions_list = stm32_synapse_actions,
331 .num_actions = ARRAY_SIZE(stm32_synapse_actions),
332 .signal = &stm32_signals[0]
333 },
334 {
335 .actions_list = stm32_synapse_actions,
336 .num_actions = ARRAY_SIZE(stm32_synapse_actions),
337 .signal = &stm32_signals[1]
338 }
339};
340
341static struct counter_count stm32_counts = {
342 .id = 0,
343 .name = "Channel 1 Count",
344 .functions_list = stm32_count_functions,
345 .num_functions = ARRAY_SIZE(stm32_count_functions),
346 .synapses = stm32_count_synapses,
347 .num_synapses = ARRAY_SIZE(stm32_count_synapses),
348 .ext = stm32_count_ext,
349 .num_ext = ARRAY_SIZE(stm32_count_ext)
350};
351
352static int stm32_timer_cnt_probe(struct platform_device *pdev)
353{
354 struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent);
355 struct device *dev = &pdev->dev;
356 struct stm32_timer_cnt *priv;
357
358 if (IS_ERR_OR_NULL(ddata))
359 return -EINVAL;
360
361 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
362 if (!priv)
363 return -ENOMEM;
364
365 priv->regmap = ddata->regmap;
366 priv->clk = ddata->clk;
Olivier Deprez0e641232021-09-23 10:07:05 +0200367 priv->max_arr = ddata->max_arr;
David Brazdil0f672f62019-12-10 10:32:29 +0000368
369 priv->counter.name = dev_name(dev);
370 priv->counter.parent = dev;
371 priv->counter.ops = &stm32_timer_cnt_ops;
372 priv->counter.counts = &stm32_counts;
373 priv->counter.num_counts = 1;
374 priv->counter.signals = stm32_signals;
375 priv->counter.num_signals = ARRAY_SIZE(stm32_signals);
376 priv->counter.priv = priv;
377
378 /* Register Counter device */
379 return devm_counter_register(dev, &priv->counter);
380}
381
382static const struct of_device_id stm32_timer_cnt_of_match[] = {
383 { .compatible = "st,stm32-timer-counter", },
384 {},
385};
386MODULE_DEVICE_TABLE(of, stm32_timer_cnt_of_match);
387
388static struct platform_driver stm32_timer_cnt_driver = {
389 .probe = stm32_timer_cnt_probe,
390 .driver = {
391 .name = "stm32-timer-counter",
392 .of_match_table = stm32_timer_cnt_of_match,
393 },
394};
395module_platform_driver(stm32_timer_cnt_driver);
396
397MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
398MODULE_ALIAS("platform:stm32-timer-counter");
399MODULE_DESCRIPTION("STMicroelectronics STM32 TIMER counter driver");
400MODULE_LICENSE("GPL v2");