Linux 6.9-rc1
[linux-2.6-microblaze.git] / drivers / counter / ti-eqep.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2019 David Lechner <david@lechnology.com>
4  *
5  * Counter driver for Texas Instruments Enhanced Quadrature Encoder Pulse (eQEP)
6  */
7
8 #include <linux/bitops.h>
9 #include <linux/counter.h>
10 #include <linux/kernel.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/regmap.h>
16 #include <linux/types.h>
17
18 /* 32-bit registers */
19 #define QPOSCNT         0x0
20 #define QPOSINIT        0x4
21 #define QPOSMAX         0x8
22 #define QPOSCMP         0xc
23 #define QPOSILAT        0x10
24 #define QPOSSLAT        0x14
25 #define QPOSLAT         0x18
26 #define QUTMR           0x1c
27 #define QUPRD           0x20
28
29 /* 16-bit registers */
30 #define QWDTMR          0x0     /* 0x24 */
31 #define QWDPRD          0x2     /* 0x26 */
32 #define QDECCTL         0x4     /* 0x28 */
33 #define QEPCTL          0x6     /* 0x2a */
34 #define QCAPCTL         0x8     /* 0x2c */
35 #define QPOSCTL         0xa     /* 0x2e */
36 #define QEINT           0xc     /* 0x30 */
37 #define QFLG            0xe     /* 0x32 */
38 #define QCLR            0x10    /* 0x34 */
39 #define QFRC            0x12    /* 0x36 */
40 #define QEPSTS          0x14    /* 0x38 */
41 #define QCTMR           0x16    /* 0x3a */
42 #define QCPRD           0x18    /* 0x3c */
43 #define QCTMRLAT        0x1a    /* 0x3e */
44 #define QCPRDLAT        0x1c    /* 0x40 */
45
46 #define QDECCTL_QSRC_SHIFT      14
47 #define QDECCTL_QSRC            GENMASK(15, 14)
48 #define QDECCTL_SOEN            BIT(13)
49 #define QDECCTL_SPSEL           BIT(12)
50 #define QDECCTL_XCR             BIT(11)
51 #define QDECCTL_SWAP            BIT(10)
52 #define QDECCTL_IGATE           BIT(9)
53 #define QDECCTL_QAP             BIT(8)
54 #define QDECCTL_QBP             BIT(7)
55 #define QDECCTL_QIP             BIT(6)
56 #define QDECCTL_QSP             BIT(5)
57
58 #define QEPCTL_FREE_SOFT        GENMASK(15, 14)
59 #define QEPCTL_PCRM             GENMASK(13, 12)
60 #define QEPCTL_SEI              GENMASK(11, 10)
61 #define QEPCTL_IEI              GENMASK(9, 8)
62 #define QEPCTL_SWI              BIT(7)
63 #define QEPCTL_SEL              BIT(6)
64 #define QEPCTL_IEL              GENMASK(5, 4)
65 #define QEPCTL_PHEN             BIT(3)
66 #define QEPCTL_QCLM             BIT(2)
67 #define QEPCTL_UTE              BIT(1)
68 #define QEPCTL_WDE              BIT(0)
69
70 /* EQEP Inputs */
71 enum {
72         TI_EQEP_SIGNAL_QEPA,    /* QEPA/XCLK */
73         TI_EQEP_SIGNAL_QEPB,    /* QEPB/XDIR */
74 };
75
76 /* Position Counter Input Modes */
77 enum ti_eqep_count_func {
78         TI_EQEP_COUNT_FUNC_QUAD_COUNT,
79         TI_EQEP_COUNT_FUNC_DIR_COUNT,
80         TI_EQEP_COUNT_FUNC_UP_COUNT,
81         TI_EQEP_COUNT_FUNC_DOWN_COUNT,
82 };
83
84 struct ti_eqep_cnt {
85         struct counter_device counter;
86         struct regmap *regmap32;
87         struct regmap *regmap16;
88 };
89
90 static struct ti_eqep_cnt *ti_eqep_count_from_counter(struct counter_device *counter)
91 {
92         return counter_priv(counter);
93 }
94
95 static int ti_eqep_count_read(struct counter_device *counter,
96                               struct counter_count *count, u64 *val)
97 {
98         struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter);
99         u32 cnt;
100
101         regmap_read(priv->regmap32, QPOSCNT, &cnt);
102         *val = cnt;
103
104         return 0;
105 }
106
107 static int ti_eqep_count_write(struct counter_device *counter,
108                                struct counter_count *count, u64 val)
109 {
110         struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter);
111         u32 max;
112
113         regmap_read(priv->regmap32, QPOSMAX, &max);
114         if (val > max)
115                 return -EINVAL;
116
117         return regmap_write(priv->regmap32, QPOSCNT, val);
118 }
119
120 static int ti_eqep_function_read(struct counter_device *counter,
121                                  struct counter_count *count,
122                                  enum counter_function *function)
123 {
124         struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter);
125         u32 qdecctl;
126
127         regmap_read(priv->regmap16, QDECCTL, &qdecctl);
128
129         switch ((qdecctl & QDECCTL_QSRC) >> QDECCTL_QSRC_SHIFT) {
130         case TI_EQEP_COUNT_FUNC_QUAD_COUNT:
131                 *function = COUNTER_FUNCTION_QUADRATURE_X4;
132                 break;
133         case TI_EQEP_COUNT_FUNC_DIR_COUNT:
134                 *function = COUNTER_FUNCTION_PULSE_DIRECTION;
135                 break;
136         case TI_EQEP_COUNT_FUNC_UP_COUNT:
137                 *function = COUNTER_FUNCTION_INCREASE;
138                 break;
139         case TI_EQEP_COUNT_FUNC_DOWN_COUNT:
140                 *function = COUNTER_FUNCTION_DECREASE;
141                 break;
142         }
143
144         return 0;
145 }
146
147 static int ti_eqep_function_write(struct counter_device *counter,
148                                   struct counter_count *count,
149                                   enum counter_function function)
150 {
151         struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter);
152         enum ti_eqep_count_func qsrc;
153
154         switch (function) {
155         case COUNTER_FUNCTION_QUADRATURE_X4:
156                 qsrc = TI_EQEP_COUNT_FUNC_QUAD_COUNT;
157                 break;
158         case COUNTER_FUNCTION_PULSE_DIRECTION:
159                 qsrc = TI_EQEP_COUNT_FUNC_DIR_COUNT;
160                 break;
161         case COUNTER_FUNCTION_INCREASE:
162                 qsrc = TI_EQEP_COUNT_FUNC_UP_COUNT;
163                 break;
164         case COUNTER_FUNCTION_DECREASE:
165                 qsrc = TI_EQEP_COUNT_FUNC_DOWN_COUNT;
166                 break;
167         default:
168                 /* should never reach this path */
169                 return -EINVAL;
170         }
171
172         return regmap_write_bits(priv->regmap16, QDECCTL, QDECCTL_QSRC,
173                                  qsrc << QDECCTL_QSRC_SHIFT);
174 }
175
176 static int ti_eqep_action_read(struct counter_device *counter,
177                                struct counter_count *count,
178                                struct counter_synapse *synapse,
179                                enum counter_synapse_action *action)
180 {
181         struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter);
182         enum counter_function function;
183         u32 qdecctl;
184         int err;
185
186         err = ti_eqep_function_read(counter, count, &function);
187         if (err)
188                 return err;
189
190         switch (function) {
191         case COUNTER_FUNCTION_QUADRATURE_X4:
192                 /* In quadrature mode, the rising and falling edge of both
193                  * QEPA and QEPB trigger QCLK.
194                  */
195                 *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
196                 return 0;
197         case COUNTER_FUNCTION_PULSE_DIRECTION:
198                 /* In direction-count mode only rising edge of QEPA is counted
199                  * and QEPB gives direction.
200                  */
201                 switch (synapse->signal->id) {
202                 case TI_EQEP_SIGNAL_QEPA:
203                         *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
204                         return 0;
205                 case TI_EQEP_SIGNAL_QEPB:
206                         *action = COUNTER_SYNAPSE_ACTION_NONE;
207                         return 0;
208                 default:
209                         /* should never reach this path */
210                         return -EINVAL;
211                 }
212         case COUNTER_FUNCTION_INCREASE:
213         case COUNTER_FUNCTION_DECREASE:
214                 /* In up/down-count modes only QEPA is counted and QEPB is not
215                  * used.
216                  */
217                 switch (synapse->signal->id) {
218                 case TI_EQEP_SIGNAL_QEPA:
219                         err = regmap_read(priv->regmap16, QDECCTL, &qdecctl);
220                         if (err)
221                                 return err;
222
223                         if (qdecctl & QDECCTL_XCR)
224                                 *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
225                         else
226                                 *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
227                         return 0;
228                 case TI_EQEP_SIGNAL_QEPB:
229                         *action = COUNTER_SYNAPSE_ACTION_NONE;
230                         return 0;
231                 default:
232                         /* should never reach this path */
233                         return -EINVAL;
234                 }
235         default:
236                 /* should never reach this path */
237                 return -EINVAL;
238         }
239 }
240
241 static const struct counter_ops ti_eqep_counter_ops = {
242         .count_read     = ti_eqep_count_read,
243         .count_write    = ti_eqep_count_write,
244         .function_read  = ti_eqep_function_read,
245         .function_write = ti_eqep_function_write,
246         .action_read    = ti_eqep_action_read,
247 };
248
249 static int ti_eqep_position_ceiling_read(struct counter_device *counter,
250                                          struct counter_count *count,
251                                          u64 *ceiling)
252 {
253         struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter);
254         u32 qposmax;
255
256         regmap_read(priv->regmap32, QPOSMAX, &qposmax);
257
258         *ceiling = qposmax;
259
260         return 0;
261 }
262
263 static int ti_eqep_position_ceiling_write(struct counter_device *counter,
264                                           struct counter_count *count,
265                                           u64 ceiling)
266 {
267         struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter);
268
269         if (ceiling != (u32)ceiling)
270                 return -ERANGE;
271
272         regmap_write(priv->regmap32, QPOSMAX, ceiling);
273
274         return 0;
275 }
276
277 static int ti_eqep_position_enable_read(struct counter_device *counter,
278                                         struct counter_count *count, u8 *enable)
279 {
280         struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter);
281         u32 qepctl;
282
283         regmap_read(priv->regmap16, QEPCTL, &qepctl);
284
285         *enable = !!(qepctl & QEPCTL_PHEN);
286
287         return 0;
288 }
289
290 static int ti_eqep_position_enable_write(struct counter_device *counter,
291                                          struct counter_count *count, u8 enable)
292 {
293         struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter);
294
295         regmap_write_bits(priv->regmap16, QEPCTL, QEPCTL_PHEN, enable ? -1 : 0);
296
297         return 0;
298 }
299
300 static struct counter_comp ti_eqep_position_ext[] = {
301         COUNTER_COMP_CEILING(ti_eqep_position_ceiling_read,
302                              ti_eqep_position_ceiling_write),
303         COUNTER_COMP_ENABLE(ti_eqep_position_enable_read,
304                             ti_eqep_position_enable_write),
305 };
306
307 static struct counter_signal ti_eqep_signals[] = {
308         [TI_EQEP_SIGNAL_QEPA] = {
309                 .id = TI_EQEP_SIGNAL_QEPA,
310                 .name = "QEPA"
311         },
312         [TI_EQEP_SIGNAL_QEPB] = {
313                 .id = TI_EQEP_SIGNAL_QEPB,
314                 .name = "QEPB"
315         },
316 };
317
318 static const enum counter_function ti_eqep_position_functions[] = {
319         COUNTER_FUNCTION_QUADRATURE_X4,
320         COUNTER_FUNCTION_PULSE_DIRECTION,
321         COUNTER_FUNCTION_INCREASE,
322         COUNTER_FUNCTION_DECREASE,
323 };
324
325 static const enum counter_synapse_action ti_eqep_position_synapse_actions[] = {
326         COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
327         COUNTER_SYNAPSE_ACTION_RISING_EDGE,
328         COUNTER_SYNAPSE_ACTION_NONE,
329 };
330
331 static struct counter_synapse ti_eqep_position_synapses[] = {
332         {
333                 .actions_list   = ti_eqep_position_synapse_actions,
334                 .num_actions    = ARRAY_SIZE(ti_eqep_position_synapse_actions),
335                 .signal         = &ti_eqep_signals[TI_EQEP_SIGNAL_QEPA],
336         },
337         {
338                 .actions_list   = ti_eqep_position_synapse_actions,
339                 .num_actions    = ARRAY_SIZE(ti_eqep_position_synapse_actions),
340                 .signal         = &ti_eqep_signals[TI_EQEP_SIGNAL_QEPB],
341         },
342 };
343
344 static struct counter_count ti_eqep_counts[] = {
345         {
346                 .id             = 0,
347                 .name           = "QPOSCNT",
348                 .functions_list = ti_eqep_position_functions,
349                 .num_functions  = ARRAY_SIZE(ti_eqep_position_functions),
350                 .synapses       = ti_eqep_position_synapses,
351                 .num_synapses   = ARRAY_SIZE(ti_eqep_position_synapses),
352                 .ext            = ti_eqep_position_ext,
353                 .num_ext        = ARRAY_SIZE(ti_eqep_position_ext),
354         },
355 };
356
357 static const struct regmap_config ti_eqep_regmap32_config = {
358         .name = "32-bit",
359         .reg_bits = 32,
360         .val_bits = 32,
361         .reg_stride = 4,
362         .max_register = QUPRD,
363 };
364
365 static const struct regmap_config ti_eqep_regmap16_config = {
366         .name = "16-bit",
367         .reg_bits = 16,
368         .val_bits = 16,
369         .reg_stride = 2,
370         .max_register = QCPRDLAT,
371 };
372
373 static int ti_eqep_probe(struct platform_device *pdev)
374 {
375         struct device *dev = &pdev->dev;
376         struct counter_device *counter;
377         struct ti_eqep_cnt *priv;
378         void __iomem *base;
379         int err;
380
381         counter = devm_counter_alloc(dev, sizeof(*priv));
382         if (!counter)
383                 return -ENOMEM;
384         priv = counter_priv(counter);
385
386         base = devm_platform_ioremap_resource(pdev, 0);
387         if (IS_ERR(base))
388                 return PTR_ERR(base);
389
390         priv->regmap32 = devm_regmap_init_mmio(dev, base,
391                                                &ti_eqep_regmap32_config);
392         if (IS_ERR(priv->regmap32))
393                 return PTR_ERR(priv->regmap32);
394
395         priv->regmap16 = devm_regmap_init_mmio(dev, base + 0x24,
396                                                &ti_eqep_regmap16_config);
397         if (IS_ERR(priv->regmap16))
398                 return PTR_ERR(priv->regmap16);
399
400         counter->name = dev_name(dev);
401         counter->parent = dev;
402         counter->ops = &ti_eqep_counter_ops;
403         counter->counts = ti_eqep_counts;
404         counter->num_counts = ARRAY_SIZE(ti_eqep_counts);
405         counter->signals = ti_eqep_signals;
406         counter->num_signals = ARRAY_SIZE(ti_eqep_signals);
407
408         platform_set_drvdata(pdev, counter);
409
410         /*
411          * Need to make sure power is turned on. On AM33xx, this comes from the
412          * parent PWMSS bus driver. On AM17xx, this comes from the PSC power
413          * domain.
414          */
415         pm_runtime_enable(dev);
416         pm_runtime_get_sync(dev);
417
418         err = counter_add(counter);
419         if (err < 0) {
420                 pm_runtime_put_sync(dev);
421                 pm_runtime_disable(dev);
422                 return err;
423         }
424
425         return 0;
426 }
427
428 static int ti_eqep_remove(struct platform_device *pdev)
429 {
430         struct counter_device *counter = platform_get_drvdata(pdev);
431         struct device *dev = &pdev->dev;
432
433         counter_unregister(counter);
434         pm_runtime_put_sync(dev);
435         pm_runtime_disable(dev);
436
437         return 0;
438 }
439
440 static const struct of_device_id ti_eqep_of_match[] = {
441         { .compatible = "ti,am3352-eqep", },
442         { },
443 };
444 MODULE_DEVICE_TABLE(of, ti_eqep_of_match);
445
446 static struct platform_driver ti_eqep_driver = {
447         .probe = ti_eqep_probe,
448         .remove = ti_eqep_remove,
449         .driver = {
450                 .name = "ti-eqep-cnt",
451                 .of_match_table = ti_eqep_of_match,
452         },
453 };
454 module_platform_driver(ti_eqep_driver);
455
456 MODULE_AUTHOR("David Lechner <david@lechnology.com>");
457 MODULE_DESCRIPTION("TI eQEP counter driver");
458 MODULE_LICENSE("GPL v2");
459 MODULE_IMPORT_NS(COUNTER);