power: supply: axp20x_usb_power: Use a match structure
[linux/fpc-iii.git] / drivers / counter / stm32-timer-cnt.c
blob3eafccec3beb169f01d9e3fc724466e361f4a0fd
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * STM32 Timer Encoder and Counter driver
5 * Copyright (C) STMicroelectronics 2018
7 * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
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>
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)
23 struct stm32_timer_cnt {
24 struct counter_device counter;
25 struct regmap *regmap;
26 struct clk *clk;
27 u32 ceiling;
30 /**
31 * enum 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
37 enum 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,
44 static 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,
50 static int stm32_count_read(struct counter_device *counter,
51 struct counter_count *count, unsigned long *val)
53 struct stm32_timer_cnt *const priv = counter->priv;
54 u32 cnt;
56 regmap_read(priv->regmap, TIM_CNT, &cnt);
57 *val = cnt;
59 return 0;
62 static int stm32_count_write(struct counter_device *counter,
63 struct counter_count *count,
64 const unsigned long val)
66 struct stm32_timer_cnt *const priv = counter->priv;
68 if (val > priv->ceiling)
69 return -EINVAL;
71 return regmap_write(priv->regmap, TIM_CNT, val);
74 static int stm32_count_function_get(struct counter_device *counter,
75 struct counter_count *count,
76 size_t *function)
78 struct stm32_timer_cnt *const priv = counter->priv;
79 u32 smcr;
81 regmap_read(priv->regmap, TIM_SMCR, &smcr);
83 switch (smcr & TIM_SMCR_SMS) {
84 case 1:
85 *function = STM32_COUNT_ENCODER_MODE_1;
86 return 0;
87 case 2:
88 *function = STM32_COUNT_ENCODER_MODE_2;
89 return 0;
90 case 3:
91 *function = STM32_COUNT_ENCODER_MODE_3;
92 return 0;
95 return -EINVAL;
98 static int stm32_count_function_set(struct counter_device *counter,
99 struct counter_count *count,
100 size_t function)
102 struct stm32_timer_cnt *const priv = counter->priv;
103 u32 cr1, sms;
105 switch (function) {
106 case STM32_COUNT_ENCODER_MODE_1:
107 sms = 1;
108 break;
109 case STM32_COUNT_ENCODER_MODE_2:
110 sms = 2;
111 break;
112 case STM32_COUNT_ENCODER_MODE_3:
113 sms = 3;
114 break;
115 default:
116 sms = 0;
117 break;
120 /* Store enable status */
121 regmap_read(priv->regmap, TIM_CR1, &cr1);
123 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
125 /* TIMx_ARR register shouldn't be buffered (ARPE=0) */
126 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0);
127 regmap_write(priv->regmap, TIM_ARR, priv->ceiling);
129 regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms);
131 /* Make sure that registers are updated */
132 regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
134 /* Restore the enable status */
135 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, cr1);
137 return 0;
140 static ssize_t stm32_count_direction_read(struct counter_device *counter,
141 struct counter_count *count,
142 void *private, char *buf)
144 struct stm32_timer_cnt *const priv = counter->priv;
145 const char *direction;
146 u32 cr1;
148 regmap_read(priv->regmap, TIM_CR1, &cr1);
149 direction = (cr1 & TIM_CR1_DIR) ? "backward" : "forward";
151 return scnprintf(buf, PAGE_SIZE, "%s\n", direction);
154 static ssize_t stm32_count_ceiling_read(struct counter_device *counter,
155 struct counter_count *count,
156 void *private, char *buf)
158 struct stm32_timer_cnt *const priv = counter->priv;
159 u32 arr;
161 regmap_read(priv->regmap, TIM_ARR, &arr);
163 return snprintf(buf, PAGE_SIZE, "%u\n", arr);
166 static ssize_t stm32_count_ceiling_write(struct counter_device *counter,
167 struct counter_count *count,
168 void *private,
169 const char *buf, size_t len)
171 struct stm32_timer_cnt *const priv = counter->priv;
172 unsigned int ceiling;
173 int ret;
175 ret = kstrtouint(buf, 0, &ceiling);
176 if (ret)
177 return ret;
179 /* TIMx_ARR register shouldn't be buffered (ARPE=0) */
180 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0);
181 regmap_write(priv->regmap, TIM_ARR, ceiling);
183 priv->ceiling = ceiling;
184 return len;
187 static ssize_t stm32_count_enable_read(struct counter_device *counter,
188 struct counter_count *count,
189 void *private, char *buf)
191 struct stm32_timer_cnt *const priv = counter->priv;
192 u32 cr1;
194 regmap_read(priv->regmap, TIM_CR1, &cr1);
196 return scnprintf(buf, PAGE_SIZE, "%d\n", (bool)(cr1 & TIM_CR1_CEN));
199 static ssize_t stm32_count_enable_write(struct counter_device *counter,
200 struct counter_count *count,
201 void *private,
202 const char *buf, size_t len)
204 struct stm32_timer_cnt *const priv = counter->priv;
205 int err;
206 u32 cr1;
207 bool enable;
209 err = kstrtobool(buf, &enable);
210 if (err)
211 return err;
213 if (enable) {
214 regmap_read(priv->regmap, TIM_CR1, &cr1);
215 if (!(cr1 & TIM_CR1_CEN))
216 clk_enable(priv->clk);
218 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN,
219 TIM_CR1_CEN);
220 } else {
221 regmap_read(priv->regmap, TIM_CR1, &cr1);
222 regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
223 if (cr1 & TIM_CR1_CEN)
224 clk_disable(priv->clk);
227 return len;
230 static const struct counter_count_ext stm32_count_ext[] = {
232 .name = "direction",
233 .read = stm32_count_direction_read,
236 .name = "enable",
237 .read = stm32_count_enable_read,
238 .write = stm32_count_enable_write
241 .name = "ceiling",
242 .read = stm32_count_ceiling_read,
243 .write = stm32_count_ceiling_write
247 enum stm32_synapse_action {
248 STM32_SYNAPSE_ACTION_NONE,
249 STM32_SYNAPSE_ACTION_BOTH_EDGES
252 static enum counter_synapse_action stm32_synapse_actions[] = {
253 [STM32_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE,
254 [STM32_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES
257 static int stm32_action_get(struct counter_device *counter,
258 struct counter_count *count,
259 struct counter_synapse *synapse,
260 size_t *action)
262 size_t function;
263 int err;
265 /* Default action mode (e.g. STM32_COUNT_SLAVE_MODE_DISABLED) */
266 *action = STM32_SYNAPSE_ACTION_NONE;
268 err = stm32_count_function_get(counter, count, &function);
269 if (err)
270 return 0;
272 switch (function) {
273 case STM32_COUNT_ENCODER_MODE_1:
274 /* counts up/down on TI1FP1 edge depending on TI2FP2 level */
275 if (synapse->signal->id == count->synapses[0].signal->id)
276 *action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
277 break;
278 case STM32_COUNT_ENCODER_MODE_2:
279 /* counts up/down on TI2FP2 edge depending on TI1FP1 level */
280 if (synapse->signal->id == count->synapses[1].signal->id)
281 *action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
282 break;
283 case STM32_COUNT_ENCODER_MODE_3:
284 /* counts up/down on both TI1FP1 and TI2FP2 edges */
285 *action = STM32_SYNAPSE_ACTION_BOTH_EDGES;
286 break;
289 return 0;
292 static const struct counter_ops stm32_timer_cnt_ops = {
293 .count_read = stm32_count_read,
294 .count_write = stm32_count_write,
295 .function_get = stm32_count_function_get,
296 .function_set = stm32_count_function_set,
297 .action_get = stm32_action_get,
300 static struct counter_signal stm32_signals[] = {
302 .id = 0,
303 .name = "Channel 1 Quadrature A"
306 .id = 1,
307 .name = "Channel 1 Quadrature B"
311 static struct counter_synapse stm32_count_synapses[] = {
313 .actions_list = stm32_synapse_actions,
314 .num_actions = ARRAY_SIZE(stm32_synapse_actions),
315 .signal = &stm32_signals[0]
318 .actions_list = stm32_synapse_actions,
319 .num_actions = ARRAY_SIZE(stm32_synapse_actions),
320 .signal = &stm32_signals[1]
324 static struct counter_count stm32_counts = {
325 .id = 0,
326 .name = "Channel 1 Count",
327 .functions_list = stm32_count_functions,
328 .num_functions = ARRAY_SIZE(stm32_count_functions),
329 .synapses = stm32_count_synapses,
330 .num_synapses = ARRAY_SIZE(stm32_count_synapses),
331 .ext = stm32_count_ext,
332 .num_ext = ARRAY_SIZE(stm32_count_ext)
335 static int stm32_timer_cnt_probe(struct platform_device *pdev)
337 struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent);
338 struct device *dev = &pdev->dev;
339 struct stm32_timer_cnt *priv;
341 if (IS_ERR_OR_NULL(ddata))
342 return -EINVAL;
344 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
345 if (!priv)
346 return -ENOMEM;
348 priv->regmap = ddata->regmap;
349 priv->clk = ddata->clk;
350 priv->ceiling = ddata->max_arr;
352 priv->counter.name = dev_name(dev);
353 priv->counter.parent = dev;
354 priv->counter.ops = &stm32_timer_cnt_ops;
355 priv->counter.counts = &stm32_counts;
356 priv->counter.num_counts = 1;
357 priv->counter.signals = stm32_signals;
358 priv->counter.num_signals = ARRAY_SIZE(stm32_signals);
359 priv->counter.priv = priv;
361 /* Register Counter device */
362 return devm_counter_register(dev, &priv->counter);
365 static const struct of_device_id stm32_timer_cnt_of_match[] = {
366 { .compatible = "st,stm32-timer-counter", },
369 MODULE_DEVICE_TABLE(of, stm32_timer_cnt_of_match);
371 static struct platform_driver stm32_timer_cnt_driver = {
372 .probe = stm32_timer_cnt_probe,
373 .driver = {
374 .name = "stm32-timer-counter",
375 .of_match_table = stm32_timer_cnt_of_match,
378 module_platform_driver(stm32_timer_cnt_driver);
380 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
381 MODULE_ALIAS("platform:stm32-timer-counter");
382 MODULE_DESCRIPTION("STMicroelectronics STM32 TIMER counter driver");
383 MODULE_LICENSE("GPL v2");