GNU Linux-libre 5.15.131-gnu
[releases.git] / include / linux / counter.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Counter interface
4  * Copyright (C) 2018 William Breathitt Gray
5  */
6 #ifndef _COUNTER_H_
7 #define _COUNTER_H_
8
9 #include <linux/device.h>
10 #include <linux/kernel.h>
11 #include <linux/types.h>
12
13 struct counter_device;
14 struct counter_count;
15 struct counter_synapse;
16 struct counter_signal;
17
18 enum counter_comp_type {
19         COUNTER_COMP_U8,
20         COUNTER_COMP_U64,
21         COUNTER_COMP_BOOL,
22         COUNTER_COMP_SIGNAL_LEVEL,
23         COUNTER_COMP_FUNCTION,
24         COUNTER_COMP_SYNAPSE_ACTION,
25         COUNTER_COMP_ENUM,
26         COUNTER_COMP_COUNT_DIRECTION,
27         COUNTER_COMP_COUNT_MODE,
28 };
29
30 enum counter_scope {
31         COUNTER_SCOPE_DEVICE,
32         COUNTER_SCOPE_SIGNAL,
33         COUNTER_SCOPE_COUNT,
34 };
35
36 enum counter_count_direction {
37         COUNTER_COUNT_DIRECTION_FORWARD,
38         COUNTER_COUNT_DIRECTION_BACKWARD,
39 };
40
41 enum counter_count_mode {
42         COUNTER_COUNT_MODE_NORMAL,
43         COUNTER_COUNT_MODE_RANGE_LIMIT,
44         COUNTER_COUNT_MODE_NON_RECYCLE,
45         COUNTER_COUNT_MODE_MODULO_N,
46 };
47
48 enum counter_function {
49         COUNTER_FUNCTION_INCREASE,
50         COUNTER_FUNCTION_DECREASE,
51         COUNTER_FUNCTION_PULSE_DIRECTION,
52         COUNTER_FUNCTION_QUADRATURE_X1_A,
53         COUNTER_FUNCTION_QUADRATURE_X1_B,
54         COUNTER_FUNCTION_QUADRATURE_X2_A,
55         COUNTER_FUNCTION_QUADRATURE_X2_B,
56         COUNTER_FUNCTION_QUADRATURE_X4,
57 };
58
59 enum counter_signal_level {
60         COUNTER_SIGNAL_LEVEL_LOW,
61         COUNTER_SIGNAL_LEVEL_HIGH,
62 };
63
64 enum counter_synapse_action {
65         COUNTER_SYNAPSE_ACTION_NONE,
66         COUNTER_SYNAPSE_ACTION_RISING_EDGE,
67         COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
68         COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
69 };
70
71 /**
72  * struct counter_comp - Counter component node
73  * @type:               Counter component data type
74  * @name:               device-specific component name
75  * @priv:               component-relevant data
76  * @action_read:                Synapse action mode read callback. The read value of the
77  *                      respective Synapse action mode should be passed back via
78  *                      the action parameter.
79  * @device_u8_read:             Device u8 component read callback. The read value of the
80  *                      respective Device u8 component should be passed back via
81  *                      the val parameter.
82  * @count_u8_read:              Count u8 component read callback. The read value of the
83  *                      respective Count u8 component should be passed back via
84  *                      the val parameter.
85  * @signal_u8_read:             Signal u8 component read callback. The read value of the
86  *                      respective Signal u8 component should be passed back via
87  *                      the val parameter.
88  * @device_u32_read:            Device u32 component read callback. The read value of
89  *                      the respective Device u32 component should be passed
90  *                      back via the val parameter.
91  * @count_u32_read:             Count u32 component read callback. The read value of the
92  *                      respective Count u32 component should be passed back via
93  *                      the val parameter.
94  * @signal_u32_read:            Signal u32 component read callback. The read value of
95  *                      the respective Signal u32 component should be passed
96  *                      back via the val parameter.
97  * @device_u64_read:            Device u64 component read callback. The read value of
98  *                      the respective Device u64 component should be passed
99  *                      back via the val parameter.
100  * @count_u64_read:             Count u64 component read callback. The read value of the
101  *                      respective Count u64 component should be passed back via
102  *                      the val parameter.
103  * @signal_u64_read:            Signal u64 component read callback. The read value of
104  *                      the respective Signal u64 component should be passed
105  *                      back via the val parameter.
106  * @action_write:               Synapse action mode write callback. The write value of
107  *                      the respective Synapse action mode is passed via the
108  *                      action parameter.
109  * @device_u8_write:            Device u8 component write callback. The write value of
110  *                      the respective Device u8 component is passed via the val
111  *                      parameter.
112  * @count_u8_write:             Count u8 component write callback. The write value of
113  *                      the respective Count u8 component is passed via the val
114  *                      parameter.
115  * @signal_u8_write:            Signal u8 component write callback. The write value of
116  *                      the respective Signal u8 component is passed via the val
117  *                      parameter.
118  * @device_u32_write:           Device u32 component write callback. The write value of
119  *                      the respective Device u32 component is passed via the
120  *                      val parameter.
121  * @count_u32_write:            Count u32 component write callback. The write value of
122  *                      the respective Count u32 component is passed via the val
123  *                      parameter.
124  * @signal_u32_write:           Signal u32 component write callback. The write value of
125  *                      the respective Signal u32 component is passed via the
126  *                      val parameter.
127  * @device_u64_write:           Device u64 component write callback. The write value of
128  *                      the respective Device u64 component is passed via the
129  *                      val parameter.
130  * @count_u64_write:            Count u64 component write callback. The write value of
131  *                      the respective Count u64 component is passed via the val
132  *                      parameter.
133  * @signal_u64_write:           Signal u64 component write callback. The write value of
134  *                      the respective Signal u64 component is passed via the
135  *                      val parameter.
136  */
137 struct counter_comp {
138         enum counter_comp_type type;
139         const char *name;
140         void *priv;
141         union {
142                 int (*action_read)(struct counter_device *counter,
143                                    struct counter_count *count,
144                                    struct counter_synapse *synapse,
145                                    enum counter_synapse_action *action);
146                 int (*device_u8_read)(struct counter_device *counter, u8 *val);
147                 int (*count_u8_read)(struct counter_device *counter,
148                                      struct counter_count *count, u8 *val);
149                 int (*signal_u8_read)(struct counter_device *counter,
150                                       struct counter_signal *signal, u8 *val);
151                 int (*device_u32_read)(struct counter_device *counter,
152                                        u32 *val);
153                 int (*count_u32_read)(struct counter_device *counter,
154                                       struct counter_count *count, u32 *val);
155                 int (*signal_u32_read)(struct counter_device *counter,
156                                        struct counter_signal *signal, u32 *val);
157                 int (*device_u64_read)(struct counter_device *counter,
158                                        u64 *val);
159                 int (*count_u64_read)(struct counter_device *counter,
160                                       struct counter_count *count, u64 *val);
161                 int (*signal_u64_read)(struct counter_device *counter,
162                                        struct counter_signal *signal, u64 *val);
163         };
164         union {
165                 int (*action_write)(struct counter_device *counter,
166                                     struct counter_count *count,
167                                     struct counter_synapse *synapse,
168                                     enum counter_synapse_action action);
169                 int (*device_u8_write)(struct counter_device *counter, u8 val);
170                 int (*count_u8_write)(struct counter_device *counter,
171                                       struct counter_count *count, u8 val);
172                 int (*signal_u8_write)(struct counter_device *counter,
173                                        struct counter_signal *signal, u8 val);
174                 int (*device_u32_write)(struct counter_device *counter,
175                                         u32 val);
176                 int (*count_u32_write)(struct counter_device *counter,
177                                        struct counter_count *count, u32 val);
178                 int (*signal_u32_write)(struct counter_device *counter,
179                                         struct counter_signal *signal, u32 val);
180                 int (*device_u64_write)(struct counter_device *counter,
181                                         u64 val);
182                 int (*count_u64_write)(struct counter_device *counter,
183                                        struct counter_count *count, u64 val);
184                 int (*signal_u64_write)(struct counter_device *counter,
185                                         struct counter_signal *signal, u64 val);
186         };
187 };
188
189 /**
190  * struct counter_signal - Counter Signal node
191  * @id:         unique ID used to identify signal
192  * @name:       device-specific Signal name; ideally, this should match the name
193  *              as it appears in the datasheet documentation
194  * @ext:        optional array of Counter Signal extensions
195  * @num_ext:    number of Counter Signal extensions specified in @ext
196  */
197 struct counter_signal {
198         int id;
199         const char *name;
200
201         struct counter_comp *ext;
202         size_t num_ext;
203 };
204
205 /**
206  * struct counter_synapse - Counter Synapse node
207  * @actions_list:       array of available action modes
208  * @num_actions:        number of action modes specified in @actions_list
209  * @signal:             pointer to associated signal
210  */
211 struct counter_synapse {
212         const enum counter_synapse_action *actions_list;
213         size_t num_actions;
214
215         struct counter_signal *signal;
216 };
217
218 /**
219  * struct counter_count - Counter Count node
220  * @id:                 unique ID used to identify Count
221  * @name:               device-specific Count name; ideally, this should match
222  *                      the name as it appears in the datasheet documentation
223  * @functions_list:     array available function modes
224  * @num_functions:      number of function modes specified in @functions_list
225  * @synapses:           array of synapses for initialization
226  * @num_synapses:       number of synapses specified in @synapses
227  * @ext:                optional array of Counter Count extensions
228  * @num_ext:            number of Counter Count extensions specified in @ext
229  */
230 struct counter_count {
231         int id;
232         const char *name;
233
234         const enum counter_function *functions_list;
235         size_t num_functions;
236
237         struct counter_synapse *synapses;
238         size_t num_synapses;
239
240         struct counter_comp *ext;
241         size_t num_ext;
242 };
243
244 /**
245  * struct counter_ops - Callbacks from driver
246  * @signal_read:        optional read callback for Signal attribute. The read
247  *                      level of the respective Signal should be passed back via
248  *                      the level parameter.
249  * @count_read:         optional read callback for Count attribute. The read
250  *                      value of the respective Count should be passed back via
251  *                      the val parameter.
252  * @count_write:        optional write callback for Count attribute. The write
253  *                      value for the respective Count is passed in via the val
254  *                      parameter.
255  * @function_read:      read callback the Count function modes. The read
256  *                      function mode of the respective Count should be passed
257  *                      back via the function parameter.
258  * @function_write:     write callback for Count function modes. The function
259  *                      mode to write for the respective Count is passed in via
260  *                      the function parameter.
261  * @action_read:        read callback the Synapse action modes. The read action
262  *                      mode of the respective Synapse should be passed back via
263  *                      the action parameter.
264  * @action_write:       write callback for Synapse action modes. The action mode
265  *                      to write for the respective Synapse is passed in via the
266  *                      action parameter.
267  */
268 struct counter_ops {
269         int (*signal_read)(struct counter_device *counter,
270                            struct counter_signal *signal,
271                            enum counter_signal_level *level);
272         int (*count_read)(struct counter_device *counter,
273                           struct counter_count *count, u64 *value);
274         int (*count_write)(struct counter_device *counter,
275                            struct counter_count *count, u64 value);
276         int (*function_read)(struct counter_device *counter,
277                              struct counter_count *count,
278                              enum counter_function *function);
279         int (*function_write)(struct counter_device *counter,
280                               struct counter_count *count,
281                               enum counter_function function);
282         int (*action_read)(struct counter_device *counter,
283                            struct counter_count *count,
284                            struct counter_synapse *synapse,
285                            enum counter_synapse_action *action);
286         int (*action_write)(struct counter_device *counter,
287                             struct counter_count *count,
288                             struct counter_synapse *synapse,
289                             enum counter_synapse_action action);
290 };
291
292 /**
293  * struct counter_device - Counter data structure
294  * @name:               name of the device as it appears in the datasheet
295  * @parent:             optional parent device providing the counters
296  * @ops:                callbacks from driver
297  * @signals:            array of Signals
298  * @num_signals:        number of Signals specified in @signals
299  * @counts:             array of Counts
300  * @num_counts:         number of Counts specified in @counts
301  * @ext:                optional array of Counter device extensions
302  * @num_ext:            number of Counter device extensions specified in @ext
303  * @priv:               optional private data supplied by driver
304  * @dev:                internal device structure
305  */
306 struct counter_device {
307         const char *name;
308         struct device *parent;
309
310         const struct counter_ops *ops;
311
312         struct counter_signal *signals;
313         size_t num_signals;
314         struct counter_count *counts;
315         size_t num_counts;
316
317         struct counter_comp *ext;
318         size_t num_ext;
319
320         void *priv;
321
322         struct device dev;
323 };
324
325 int counter_register(struct counter_device *const counter);
326 void counter_unregister(struct counter_device *const counter);
327 int devm_counter_register(struct device *dev,
328                           struct counter_device *const counter);
329
330 #define COUNTER_COMP_DEVICE_U8(_name, _read, _write) \
331 { \
332         .type = COUNTER_COMP_U8, \
333         .name = (_name), \
334         .device_u8_read = (_read), \
335         .device_u8_write = (_write), \
336 }
337 #define COUNTER_COMP_COUNT_U8(_name, _read, _write) \
338 { \
339         .type = COUNTER_COMP_U8, \
340         .name = (_name), \
341         .count_u8_read = (_read), \
342         .count_u8_write = (_write), \
343 }
344 #define COUNTER_COMP_SIGNAL_U8(_name, _read, _write) \
345 { \
346         .type = COUNTER_COMP_U8, \
347         .name = (_name), \
348         .signal_u8_read = (_read), \
349         .signal_u8_write = (_write), \
350 }
351
352 #define COUNTER_COMP_DEVICE_U64(_name, _read, _write) \
353 { \
354         .type = COUNTER_COMP_U64, \
355         .name = (_name), \
356         .device_u64_read = (_read), \
357         .device_u64_write = (_write), \
358 }
359 #define COUNTER_COMP_COUNT_U64(_name, _read, _write) \
360 { \
361         .type = COUNTER_COMP_U64, \
362         .name = (_name), \
363         .count_u64_read = (_read), \
364         .count_u64_write = (_write), \
365 }
366 #define COUNTER_COMP_SIGNAL_U64(_name, _read, _write) \
367 { \
368         .type = COUNTER_COMP_U64, \
369         .name = (_name), \
370         .signal_u64_read = (_read), \
371         .signal_u64_write = (_write), \
372 }
373
374 #define COUNTER_COMP_DEVICE_BOOL(_name, _read, _write) \
375 { \
376         .type = COUNTER_COMP_BOOL, \
377         .name = (_name), \
378         .device_u8_read = (_read), \
379         .device_u8_write = (_write), \
380 }
381 #define COUNTER_COMP_COUNT_BOOL(_name, _read, _write) \
382 { \
383         .type = COUNTER_COMP_BOOL, \
384         .name = (_name), \
385         .count_u8_read = (_read), \
386         .count_u8_write = (_write), \
387 }
388 #define COUNTER_COMP_SIGNAL_BOOL(_name, _read, _write) \
389 { \
390         .type = COUNTER_COMP_BOOL, \
391         .name = (_name), \
392         .signal_u8_read = (_read), \
393         .signal_u8_write = (_write), \
394 }
395
396 struct counter_available {
397         union {
398                 const u32 *enums;
399                 const char *const *strs;
400         };
401         size_t num_items;
402 };
403
404 #define DEFINE_COUNTER_AVAILABLE(_name, _enums) \
405         struct counter_available _name = { \
406                 .enums = (_enums), \
407                 .num_items = ARRAY_SIZE(_enums), \
408         }
409
410 #define DEFINE_COUNTER_ENUM(_name, _strs) \
411         struct counter_available _name = { \
412                 .strs = (_strs), \
413                 .num_items = ARRAY_SIZE(_strs), \
414         }
415
416 #define COUNTER_COMP_DEVICE_ENUM(_name, _get, _set, _available) \
417 { \
418         .type = COUNTER_COMP_ENUM, \
419         .name = (_name), \
420         .device_u32_read = (_get), \
421         .device_u32_write = (_set), \
422         .priv = &(_available), \
423 }
424 #define COUNTER_COMP_COUNT_ENUM(_name, _get, _set, _available) \
425 { \
426         .type = COUNTER_COMP_ENUM, \
427         .name = (_name), \
428         .count_u32_read = (_get), \
429         .count_u32_write = (_set), \
430         .priv = &(_available), \
431 }
432 #define COUNTER_COMP_SIGNAL_ENUM(_name, _get, _set, _available) \
433 { \
434         .type = COUNTER_COMP_ENUM, \
435         .name = (_name), \
436         .signal_u32_read = (_get), \
437         .signal_u32_write = (_set), \
438         .priv = &(_available), \
439 }
440
441 #define COUNTER_COMP_CEILING(_read, _write) \
442         COUNTER_COMP_COUNT_U64("ceiling", _read, _write)
443
444 #define COUNTER_COMP_COUNT_MODE(_read, _write, _available) \
445 { \
446         .type = COUNTER_COMP_COUNT_MODE, \
447         .name = "count_mode", \
448         .count_u32_read = (_read), \
449         .count_u32_write = (_write), \
450         .priv = &(_available), \
451 }
452
453 #define COUNTER_COMP_DIRECTION(_read) \
454 { \
455         .type = COUNTER_COMP_COUNT_DIRECTION, \
456         .name = "direction", \
457         .count_u32_read = (_read), \
458 }
459
460 #define COUNTER_COMP_ENABLE(_read, _write) \
461         COUNTER_COMP_COUNT_BOOL("enable", _read, _write)
462
463 #define COUNTER_COMP_FLOOR(_read, _write) \
464         COUNTER_COMP_COUNT_U64("floor", _read, _write)
465
466 #define COUNTER_COMP_PRESET(_read, _write) \
467         COUNTER_COMP_COUNT_U64("preset", _read, _write)
468
469 #define COUNTER_COMP_PRESET_ENABLE(_read, _write) \
470         COUNTER_COMP_COUNT_BOOL("preset_enable", _read, _write)
471
472 #endif /* _COUNTER_H_ */