]>
Commit | Line | Data |
---|---|---|
0040a390 WBG |
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/counter_enum.h> | |
10 | #include <linux/device.h> | |
11 | #include <linux/types.h> | |
12 | ||
13 | enum counter_count_direction { | |
14 | COUNTER_COUNT_DIRECTION_FORWARD = 0, | |
15 | COUNTER_COUNT_DIRECTION_BACKWARD | |
16 | }; | |
17 | extern const char *const counter_count_direction_str[2]; | |
18 | ||
19 | enum counter_count_mode { | |
20 | COUNTER_COUNT_MODE_NORMAL = 0, | |
21 | COUNTER_COUNT_MODE_RANGE_LIMIT, | |
22 | COUNTER_COUNT_MODE_NON_RECYCLE, | |
23 | COUNTER_COUNT_MODE_MODULO_N | |
24 | }; | |
25 | extern const char *const counter_count_mode_str[4]; | |
26 | ||
27 | struct counter_device; | |
28 | struct counter_signal; | |
29 | ||
30 | /** | |
31 | * struct counter_signal_ext - Counter Signal extensions | |
32 | * @name: attribute name | |
33 | * @read: read callback for this attribute; may be NULL | |
34 | * @write: write callback for this attribute; may be NULL | |
35 | * @priv: data private to the driver | |
36 | */ | |
37 | struct counter_signal_ext { | |
38 | const char *name; | |
39 | ssize_t (*read)(struct counter_device *counter, | |
40 | struct counter_signal *signal, void *priv, char *buf); | |
41 | ssize_t (*write)(struct counter_device *counter, | |
42 | struct counter_signal *signal, void *priv, | |
43 | const char *buf, size_t len); | |
44 | void *priv; | |
45 | }; | |
46 | ||
47 | /** | |
48 | * struct counter_signal - Counter Signal node | |
49 | * @id: unique ID used to identify signal | |
50 | * @name: device-specific Signal name; ideally, this should match the name | |
51 | * as it appears in the datasheet documentation | |
52 | * @ext: optional array of Counter Signal extensions | |
53 | * @num_ext: number of Counter Signal extensions specified in @ext | |
54 | * @priv: optional private data supplied by driver | |
55 | */ | |
56 | struct counter_signal { | |
57 | int id; | |
58 | const char *name; | |
59 | ||
60 | const struct counter_signal_ext *ext; | |
61 | size_t num_ext; | |
62 | ||
63 | void *priv; | |
64 | }; | |
65 | ||
66 | /** | |
67 | * struct counter_signal_enum_ext - Signal enum extension attribute | |
68 | * @items: Array of strings | |
69 | * @num_items: Number of items specified in @items | |
70 | * @set: Set callback function; may be NULL | |
71 | * @get: Get callback function; may be NULL | |
72 | * | |
73 | * The counter_signal_enum_ext structure can be used to implement enum style | |
74 | * Signal extension attributes. Enum style attributes are those which have a set | |
75 | * of strings that map to unsigned integer values. The Generic Counter Signal | |
76 | * enum extension helper code takes care of mapping between value and string, as | |
77 | * well as generating a "_available" file which contains a list of all available | |
78 | * items. The get callback is used to query the currently active item; the index | |
79 | * of the item within the respective items array is returned via the 'item' | |
80 | * parameter. The set callback is called when the attribute is updated; the | |
81 | * 'item' parameter contains the index of the newly activated item within the | |
82 | * respective items array. | |
83 | */ | |
84 | struct counter_signal_enum_ext { | |
85 | const char * const *items; | |
86 | size_t num_items; | |
87 | int (*get)(struct counter_device *counter, | |
88 | struct counter_signal *signal, size_t *item); | |
89 | int (*set)(struct counter_device *counter, | |
90 | struct counter_signal *signal, size_t item); | |
91 | }; | |
92 | ||
93 | /** | |
94 | * COUNTER_SIGNAL_ENUM() - Initialize Signal enum extension | |
95 | * @_name: Attribute name | |
96 | * @_e: Pointer to a counter_signal_enum_ext structure | |
97 | * | |
98 | * This should usually be used together with COUNTER_SIGNAL_ENUM_AVAILABLE() | |
99 | */ | |
100 | #define COUNTER_SIGNAL_ENUM(_name, _e) \ | |
101 | { \ | |
102 | .name = (_name), \ | |
103 | .read = counter_signal_enum_read, \ | |
104 | .write = counter_signal_enum_write, \ | |
105 | .priv = (_e) \ | |
106 | } | |
107 | ||
108 | /** | |
109 | * COUNTER_SIGNAL_ENUM_AVAILABLE() - Initialize Signal enum available extension | |
110 | * @_name: Attribute name ("_available" will be appended to the name) | |
111 | * @_e: Pointer to a counter_signal_enum_ext structure | |
112 | * | |
113 | * Creates a read only attribute that lists all the available enum items in a | |
114 | * newline separated list. This should usually be used together with | |
115 | * COUNTER_SIGNAL_ENUM() | |
116 | */ | |
117 | #define COUNTER_SIGNAL_ENUM_AVAILABLE(_name, _e) \ | |
118 | { \ | |
119 | .name = (_name "_available"), \ | |
120 | .read = counter_signal_enum_available_read, \ | |
121 | .priv = (_e) \ | |
122 | } | |
123 | ||
124 | enum counter_synapse_action { | |
125 | COUNTER_SYNAPSE_ACTION_NONE = 0, | |
126 | COUNTER_SYNAPSE_ACTION_RISING_EDGE, | |
127 | COUNTER_SYNAPSE_ACTION_FALLING_EDGE, | |
128 | COUNTER_SYNAPSE_ACTION_BOTH_EDGES | |
129 | }; | |
130 | ||
131 | /** | |
132 | * struct counter_synapse - Counter Synapse node | |
133 | * @action: index of current action mode | |
134 | * @actions_list: array of available action modes | |
135 | * @num_actions: number of action modes specified in @actions_list | |
136 | * @signal: pointer to associated signal | |
137 | */ | |
138 | struct counter_synapse { | |
139 | size_t action; | |
140 | const enum counter_synapse_action *actions_list; | |
141 | size_t num_actions; | |
142 | ||
143 | struct counter_signal *signal; | |
144 | }; | |
145 | ||
146 | struct counter_count; | |
147 | ||
148 | /** | |
149 | * struct counter_count_ext - Counter Count extension | |
150 | * @name: attribute name | |
151 | * @read: read callback for this attribute; may be NULL | |
152 | * @write: write callback for this attribute; may be NULL | |
153 | * @priv: data private to the driver | |
154 | */ | |
155 | struct counter_count_ext { | |
156 | const char *name; | |
157 | ssize_t (*read)(struct counter_device *counter, | |
158 | struct counter_count *count, void *priv, char *buf); | |
159 | ssize_t (*write)(struct counter_device *counter, | |
160 | struct counter_count *count, void *priv, | |
161 | const char *buf, size_t len); | |
162 | void *priv; | |
163 | }; | |
164 | ||
165 | enum counter_count_function { | |
166 | COUNTER_COUNT_FUNCTION_INCREASE = 0, | |
167 | COUNTER_COUNT_FUNCTION_DECREASE, | |
168 | COUNTER_COUNT_FUNCTION_PULSE_DIRECTION, | |
169 | COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A, | |
170 | COUNTER_COUNT_FUNCTION_QUADRATURE_X1_B, | |
171 | COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A, | |
172 | COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B, | |
173 | COUNTER_COUNT_FUNCTION_QUADRATURE_X4 | |
174 | }; | |
175 | ||
176 | /** | |
177 | * struct counter_count - Counter Count node | |
178 | * @id: unique ID used to identify Count | |
179 | * @name: device-specific Count name; ideally, this should match | |
180 | * the name as it appears in the datasheet documentation | |
181 | * @function: index of current function mode | |
182 | * @functions_list: array available function modes | |
183 | * @num_functions: number of function modes specified in @functions_list | |
184 | * @synapses: array of synapses for initialization | |
185 | * @num_synapses: number of synapses specified in @synapses | |
186 | * @ext: optional array of Counter Count extensions | |
187 | * @num_ext: number of Counter Count extensions specified in @ext | |
188 | * @priv: optional private data supplied by driver | |
189 | */ | |
190 | struct counter_count { | |
191 | int id; | |
192 | const char *name; | |
193 | ||
194 | size_t function; | |
195 | const enum counter_count_function *functions_list; | |
196 | size_t num_functions; | |
197 | ||
198 | struct counter_synapse *synapses; | |
199 | size_t num_synapses; | |
200 | ||
201 | const struct counter_count_ext *ext; | |
202 | size_t num_ext; | |
203 | ||
204 | void *priv; | |
205 | }; | |
206 | ||
207 | /** | |
208 | * struct counter_count_enum_ext - Count enum extension attribute | |
209 | * @items: Array of strings | |
210 | * @num_items: Number of items specified in @items | |
211 | * @set: Set callback function; may be NULL | |
212 | * @get: Get callback function; may be NULL | |
213 | * | |
214 | * The counter_count_enum_ext structure can be used to implement enum style | |
215 | * Count extension attributes. Enum style attributes are those which have a set | |
216 | * of strings that map to unsigned integer values. The Generic Counter Count | |
217 | * enum extension helper code takes care of mapping between value and string, as | |
218 | * well as generating a "_available" file which contains a list of all available | |
219 | * items. The get callback is used to query the currently active item; the index | |
220 | * of the item within the respective items array is returned via the 'item' | |
221 | * parameter. The set callback is called when the attribute is updated; the | |
222 | * 'item' parameter contains the index of the newly activated item within the | |
223 | * respective items array. | |
224 | */ | |
225 | struct counter_count_enum_ext { | |
226 | const char * const *items; | |
227 | size_t num_items; | |
228 | int (*get)(struct counter_device *counter, struct counter_count *count, | |
229 | size_t *item); | |
230 | int (*set)(struct counter_device *counter, struct counter_count *count, | |
231 | size_t item); | |
232 | }; | |
233 | ||
234 | /** | |
235 | * COUNTER_COUNT_ENUM() - Initialize Count enum extension | |
236 | * @_name: Attribute name | |
237 | * @_e: Pointer to a counter_count_enum_ext structure | |
238 | * | |
239 | * This should usually be used together with COUNTER_COUNT_ENUM_AVAILABLE() | |
240 | */ | |
241 | #define COUNTER_COUNT_ENUM(_name, _e) \ | |
242 | { \ | |
243 | .name = (_name), \ | |
244 | .read = counter_count_enum_read, \ | |
245 | .write = counter_count_enum_write, \ | |
246 | .priv = (_e) \ | |
247 | } | |
248 | ||
249 | /** | |
250 | * COUNTER_COUNT_ENUM_AVAILABLE() - Initialize Count enum available extension | |
251 | * @_name: Attribute name ("_available" will be appended to the name) | |
252 | * @_e: Pointer to a counter_count_enum_ext structure | |
253 | * | |
254 | * Creates a read only attribute that lists all the available enum items in a | |
255 | * newline separated list. This should usually be used together with | |
256 | * COUNTER_COUNT_ENUM() | |
257 | */ | |
258 | #define COUNTER_COUNT_ENUM_AVAILABLE(_name, _e) \ | |
259 | { \ | |
260 | .name = (_name "_available"), \ | |
261 | .read = counter_count_enum_available_read, \ | |
262 | .priv = (_e) \ | |
263 | } | |
264 | ||
265 | /** | |
266 | * struct counter_device_attr_group - internal container for attribute group | |
267 | * @attr_group: Counter sysfs attributes group | |
268 | * @attr_list: list to keep track of created Counter sysfs attributes | |
269 | * @num_attr: number of Counter sysfs attributes | |
270 | */ | |
271 | struct counter_device_attr_group { | |
272 | struct attribute_group attr_group; | |
273 | struct list_head attr_list; | |
274 | size_t num_attr; | |
275 | }; | |
276 | ||
277 | /** | |
278 | * struct counter_device_state - internal state container for a Counter device | |
279 | * @id: unique ID used to identify the Counter | |
280 | * @dev: internal device structure | |
281 | * @groups_list: attribute groups list (for Signals, Counts, and ext) | |
282 | * @num_groups: number of attribute groups containers | |
283 | * @groups: Counter sysfs attribute groups (to populate @dev.groups) | |
284 | */ | |
285 | struct counter_device_state { | |
286 | int id; | |
287 | struct device dev; | |
288 | struct counter_device_attr_group *groups_list; | |
289 | size_t num_groups; | |
290 | const struct attribute_group **groups; | |
291 | }; | |
292 | ||
293 | /** | |
294 | * struct counter_signal_read_value - Opaque Signal read value | |
295 | * @buf: string representation of Signal read value | |
296 | * @len: length of string in @buf | |
297 | */ | |
298 | struct counter_signal_read_value { | |
299 | char *buf; | |
300 | size_t len; | |
301 | }; | |
302 | ||
303 | /** | |
304 | * struct counter_count_read_value - Opaque Count read value | |
305 | * @buf: string representation of Count read value | |
306 | * @len: length of string in @buf | |
307 | */ | |
308 | struct counter_count_read_value { | |
309 | char *buf; | |
310 | size_t len; | |
311 | }; | |
312 | ||
313 | /** | |
314 | * struct counter_count_write_value - Opaque Count write value | |
315 | * @buf: string representation of Count write value | |
316 | */ | |
317 | struct counter_count_write_value { | |
318 | const char *buf; | |
319 | }; | |
320 | ||
321 | /** | |
322 | * struct counter_ops - Callbacks from driver | |
323 | * @signal_read: optional read callback for Signal attribute. The read | |
324 | * value of the respective Signal should be passed back via | |
325 | * the val parameter. val points to an opaque type which | |
326 | * should be set only by calling the | |
327 | * counter_signal_read_value_set function from within the | |
328 | * signal_read callback. | |
329 | * @count_read: optional read callback for Count attribute. The read | |
330 | * value of the respective Count should be passed back via | |
331 | * the val parameter. val points to an opaque type which | |
332 | * should be set only by calling the | |
333 | * counter_count_read_value_set function from within the | |
334 | * count_read callback. | |
335 | * @count_write: optional write callback for Count attribute. The write | |
336 | * value for the respective Count is passed in via the val | |
337 | * parameter. val points to an opaque type which should be | |
338 | * accessed only by calling the | |
339 | * counter_count_write_value_get function. | |
340 | * @function_get: function to get the current count function mode. Returns | |
341 | * 0 on success and negative error code on error. The index | |
342 | * of the respective Count's returned function mode should | |
343 | * be passed back via the function parameter. | |
344 | * @function_set: function to set the count function mode. function is the | |
345 | * index of the requested function mode from the respective | |
346 | * Count's functions_list array. | |
347 | * @action_get: function to get the current action mode. Returns 0 on | |
348 | * success and negative error code on error. The index of | |
349 | * the respective Signal's returned action mode should be | |
350 | * passed back via the action parameter. | |
351 | * @action_set: function to set the action mode. action is the index of | |
352 | * the requested action mode from the respective Synapse's | |
353 | * actions_list array. | |
354 | */ | |
355 | struct counter_ops { | |
356 | int (*signal_read)(struct counter_device *counter, | |
357 | struct counter_signal *signal, | |
358 | struct counter_signal_read_value *val); | |
359 | int (*count_read)(struct counter_device *counter, | |
360 | struct counter_count *count, | |
361 | struct counter_count_read_value *val); | |
362 | int (*count_write)(struct counter_device *counter, | |
363 | struct counter_count *count, | |
364 | struct counter_count_write_value *val); | |
365 | int (*function_get)(struct counter_device *counter, | |
366 | struct counter_count *count, size_t *function); | |
367 | int (*function_set)(struct counter_device *counter, | |
368 | struct counter_count *count, size_t function); | |
369 | int (*action_get)(struct counter_device *counter, | |
370 | struct counter_count *count, | |
371 | struct counter_synapse *synapse, size_t *action); | |
372 | int (*action_set)(struct counter_device *counter, | |
373 | struct counter_count *count, | |
374 | struct counter_synapse *synapse, size_t action); | |
375 | }; | |
376 | ||
377 | /** | |
378 | * struct counter_device_ext - Counter device extension | |
379 | * @name: attribute name | |
380 | * @read: read callback for this attribute; may be NULL | |
381 | * @write: write callback for this attribute; may be NULL | |
382 | * @priv: data private to the driver | |
383 | */ | |
384 | struct counter_device_ext { | |
385 | const char *name; | |
386 | ssize_t (*read)(struct counter_device *counter, void *priv, char *buf); | |
387 | ssize_t (*write)(struct counter_device *counter, void *priv, | |
388 | const char *buf, size_t len); | |
389 | void *priv; | |
390 | }; | |
391 | ||
392 | /** | |
393 | * struct counter_device_enum_ext - Counter enum extension attribute | |
394 | * @items: Array of strings | |
395 | * @num_items: Number of items specified in @items | |
396 | * @set: Set callback function; may be NULL | |
397 | * @get: Get callback function; may be NULL | |
398 | * | |
399 | * The counter_device_enum_ext structure can be used to implement enum style | |
400 | * Counter extension attributes. Enum style attributes are those which have a | |
401 | * set of strings that map to unsigned integer values. The Generic Counter enum | |
402 | * extension helper code takes care of mapping between value and string, as well | |
403 | * as generating a "_available" file which contains a list of all available | |
404 | * items. The get callback is used to query the currently active item; the index | |
405 | * of the item within the respective items array is returned via the 'item' | |
406 | * parameter. The set callback is called when the attribute is updated; the | |
407 | * 'item' parameter contains the index of the newly activated item within the | |
408 | * respective items array. | |
409 | */ | |
410 | struct counter_device_enum_ext { | |
411 | const char * const *items; | |
412 | size_t num_items; | |
413 | int (*get)(struct counter_device *counter, size_t *item); | |
414 | int (*set)(struct counter_device *counter, size_t item); | |
415 | }; | |
416 | ||
417 | /** | |
418 | * COUNTER_DEVICE_ENUM() - Initialize Counter enum extension | |
419 | * @_name: Attribute name | |
420 | * @_e: Pointer to a counter_device_enum_ext structure | |
421 | * | |
422 | * This should usually be used together with COUNTER_DEVICE_ENUM_AVAILABLE() | |
423 | */ | |
424 | #define COUNTER_DEVICE_ENUM(_name, _e) \ | |
425 | { \ | |
426 | .name = (_name), \ | |
427 | .read = counter_device_enum_read, \ | |
428 | .write = counter_device_enum_write, \ | |
429 | .priv = (_e) \ | |
430 | } | |
431 | ||
432 | /** | |
433 | * COUNTER_DEVICE_ENUM_AVAILABLE() - Initialize Counter enum available extension | |
434 | * @_name: Attribute name ("_available" will be appended to the name) | |
435 | * @_e: Pointer to a counter_device_enum_ext structure | |
436 | * | |
437 | * Creates a read only attribute that lists all the available enum items in a | |
438 | * newline separated list. This should usually be used together with | |
439 | * COUNTER_DEVICE_ENUM() | |
440 | */ | |
441 | #define COUNTER_DEVICE_ENUM_AVAILABLE(_name, _e) \ | |
442 | { \ | |
443 | .name = (_name "_available"), \ | |
444 | .read = counter_device_enum_available_read, \ | |
445 | .priv = (_e) \ | |
446 | } | |
447 | ||
448 | /** | |
449 | * struct counter_device - Counter data structure | |
450 | * @name: name of the device as it appears in the datasheet | |
451 | * @parent: optional parent device providing the counters | |
452 | * @device_state: internal device state container | |
453 | * @ops: callbacks from driver | |
454 | * @signals: array of Signals | |
455 | * @num_signals: number of Signals specified in @signals | |
456 | * @counts: array of Counts | |
457 | * @num_counts: number of Counts specified in @counts | |
458 | * @ext: optional array of Counter device extensions | |
459 | * @num_ext: number of Counter device extensions specified in @ext | |
460 | * @priv: optional private data supplied by driver | |
461 | */ | |
462 | struct counter_device { | |
463 | const char *name; | |
464 | struct device *parent; | |
465 | struct counter_device_state *device_state; | |
466 | ||
467 | const struct counter_ops *ops; | |
468 | ||
469 | struct counter_signal *signals; | |
470 | size_t num_signals; | |
471 | struct counter_count *counts; | |
472 | size_t num_counts; | |
473 | ||
474 | const struct counter_device_ext *ext; | |
475 | size_t num_ext; | |
476 | ||
477 | void *priv; | |
478 | }; | |
479 | ||
480 | enum counter_signal_level { | |
481 | COUNTER_SIGNAL_LEVEL_LOW = 0, | |
482 | COUNTER_SIGNAL_LEVEL_HIGH | |
483 | }; | |
484 | ||
485 | enum counter_signal_value_type { | |
486 | COUNTER_SIGNAL_LEVEL = 0 | |
487 | }; | |
488 | ||
489 | enum counter_count_value_type { | |
490 | COUNTER_COUNT_POSITION = 0, | |
491 | }; | |
492 | ||
493 | void counter_signal_read_value_set(struct counter_signal_read_value *const val, | |
494 | const enum counter_signal_value_type type, | |
495 | void *const data); | |
496 | void counter_count_read_value_set(struct counter_count_read_value *const val, | |
497 | const enum counter_count_value_type type, | |
498 | void *const data); | |
499 | int counter_count_write_value_get(void *const data, | |
500 | const enum counter_count_value_type type, | |
501 | const struct counter_count_write_value *const val); | |
502 | ||
503 | int counter_register(struct counter_device *const counter); | |
504 | void counter_unregister(struct counter_device *const counter); | |
505 | int devm_counter_register(struct device *dev, | |
506 | struct counter_device *const counter); | |
507 | void devm_counter_unregister(struct device *dev, | |
508 | struct counter_device *const counter); | |
509 | ||
510 | #endif /* _COUNTER_H_ */ |