]>
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 | ||
493b938a WBG |
293 | enum counter_signal_level { |
294 | COUNTER_SIGNAL_LEVEL_LOW, | |
295 | COUNTER_SIGNAL_LEVEL_HIGH, | |
0040a390 WBG |
296 | }; |
297 | ||
298 | /** | |
299 | * struct counter_ops - Callbacks from driver | |
300 | * @signal_read: optional read callback for Signal attribute. The read | |
493b938a WBG |
301 | * level of the respective Signal should be passed back via |
302 | * the level parameter. | |
0040a390 WBG |
303 | * @count_read: optional read callback for Count attribute. The read |
304 | * value of the respective Count should be passed back via | |
d49e6ee2 | 305 | * the val parameter. |
0040a390 WBG |
306 | * @count_write: optional write callback for Count attribute. The write |
307 | * value for the respective Count is passed in via the val | |
d49e6ee2 | 308 | * parameter. |
0040a390 WBG |
309 | * @function_get: function to get the current count function mode. Returns |
310 | * 0 on success and negative error code on error. The index | |
311 | * of the respective Count's returned function mode should | |
312 | * be passed back via the function parameter. | |
313 | * @function_set: function to set the count function mode. function is the | |
314 | * index of the requested function mode from the respective | |
315 | * Count's functions_list array. | |
316 | * @action_get: function to get the current action mode. Returns 0 on | |
317 | * success and negative error code on error. The index of | |
c5d550fb | 318 | * the respective Synapse's returned action mode should be |
0040a390 WBG |
319 | * passed back via the action parameter. |
320 | * @action_set: function to set the action mode. action is the index of | |
321 | * the requested action mode from the respective Synapse's | |
322 | * actions_list array. | |
323 | */ | |
324 | struct counter_ops { | |
325 | int (*signal_read)(struct counter_device *counter, | |
326 | struct counter_signal *signal, | |
493b938a | 327 | enum counter_signal_level *level); |
0040a390 | 328 | int (*count_read)(struct counter_device *counter, |
d49e6ee2 | 329 | struct counter_count *count, unsigned long *val); |
0040a390 | 330 | int (*count_write)(struct counter_device *counter, |
d49e6ee2 | 331 | struct counter_count *count, unsigned long val); |
0040a390 WBG |
332 | int (*function_get)(struct counter_device *counter, |
333 | struct counter_count *count, size_t *function); | |
334 | int (*function_set)(struct counter_device *counter, | |
335 | struct counter_count *count, size_t function); | |
336 | int (*action_get)(struct counter_device *counter, | |
337 | struct counter_count *count, | |
338 | struct counter_synapse *synapse, size_t *action); | |
339 | int (*action_set)(struct counter_device *counter, | |
340 | struct counter_count *count, | |
341 | struct counter_synapse *synapse, size_t action); | |
342 | }; | |
343 | ||
344 | /** | |
345 | * struct counter_device_ext - Counter device extension | |
346 | * @name: attribute name | |
347 | * @read: read callback for this attribute; may be NULL | |
348 | * @write: write callback for this attribute; may be NULL | |
349 | * @priv: data private to the driver | |
350 | */ | |
351 | struct counter_device_ext { | |
352 | const char *name; | |
353 | ssize_t (*read)(struct counter_device *counter, void *priv, char *buf); | |
354 | ssize_t (*write)(struct counter_device *counter, void *priv, | |
355 | const char *buf, size_t len); | |
356 | void *priv; | |
357 | }; | |
358 | ||
359 | /** | |
360 | * struct counter_device_enum_ext - Counter enum extension attribute | |
361 | * @items: Array of strings | |
362 | * @num_items: Number of items specified in @items | |
363 | * @set: Set callback function; may be NULL | |
364 | * @get: Get callback function; may be NULL | |
365 | * | |
366 | * The counter_device_enum_ext structure can be used to implement enum style | |
367 | * Counter extension attributes. Enum style attributes are those which have a | |
368 | * set of strings that map to unsigned integer values. The Generic Counter enum | |
369 | * extension helper code takes care of mapping between value and string, as well | |
370 | * as generating a "_available" file which contains a list of all available | |
371 | * items. The get callback is used to query the currently active item; the index | |
372 | * of the item within the respective items array is returned via the 'item' | |
373 | * parameter. The set callback is called when the attribute is updated; the | |
374 | * 'item' parameter contains the index of the newly activated item within the | |
375 | * respective items array. | |
376 | */ | |
377 | struct counter_device_enum_ext { | |
378 | const char * const *items; | |
379 | size_t num_items; | |
380 | int (*get)(struct counter_device *counter, size_t *item); | |
381 | int (*set)(struct counter_device *counter, size_t item); | |
382 | }; | |
383 | ||
384 | /** | |
385 | * COUNTER_DEVICE_ENUM() - Initialize Counter enum extension | |
386 | * @_name: Attribute name | |
387 | * @_e: Pointer to a counter_device_enum_ext structure | |
388 | * | |
389 | * This should usually be used together with COUNTER_DEVICE_ENUM_AVAILABLE() | |
390 | */ | |
391 | #define COUNTER_DEVICE_ENUM(_name, _e) \ | |
392 | { \ | |
393 | .name = (_name), \ | |
394 | .read = counter_device_enum_read, \ | |
395 | .write = counter_device_enum_write, \ | |
396 | .priv = (_e) \ | |
397 | } | |
398 | ||
399 | /** | |
400 | * COUNTER_DEVICE_ENUM_AVAILABLE() - Initialize Counter enum available extension | |
401 | * @_name: Attribute name ("_available" will be appended to the name) | |
402 | * @_e: Pointer to a counter_device_enum_ext structure | |
403 | * | |
404 | * Creates a read only attribute that lists all the available enum items in a | |
405 | * newline separated list. This should usually be used together with | |
406 | * COUNTER_DEVICE_ENUM() | |
407 | */ | |
408 | #define COUNTER_DEVICE_ENUM_AVAILABLE(_name, _e) \ | |
409 | { \ | |
410 | .name = (_name "_available"), \ | |
411 | .read = counter_device_enum_available_read, \ | |
412 | .priv = (_e) \ | |
413 | } | |
414 | ||
415 | /** | |
416 | * struct counter_device - Counter data structure | |
417 | * @name: name of the device as it appears in the datasheet | |
418 | * @parent: optional parent device providing the counters | |
419 | * @device_state: internal device state container | |
420 | * @ops: callbacks from driver | |
421 | * @signals: array of Signals | |
422 | * @num_signals: number of Signals specified in @signals | |
423 | * @counts: array of Counts | |
424 | * @num_counts: number of Counts specified in @counts | |
425 | * @ext: optional array of Counter device extensions | |
426 | * @num_ext: number of Counter device extensions specified in @ext | |
427 | * @priv: optional private data supplied by driver | |
428 | */ | |
429 | struct counter_device { | |
430 | const char *name; | |
431 | struct device *parent; | |
432 | struct counter_device_state *device_state; | |
433 | ||
434 | const struct counter_ops *ops; | |
435 | ||
436 | struct counter_signal *signals; | |
437 | size_t num_signals; | |
438 | struct counter_count *counts; | |
439 | size_t num_counts; | |
440 | ||
441 | const struct counter_device_ext *ext; | |
442 | size_t num_ext; | |
443 | ||
444 | void *priv; | |
445 | }; | |
446 | ||
0040a390 WBG |
447 | int counter_register(struct counter_device *const counter); |
448 | void counter_unregister(struct counter_device *const counter); | |
449 | int devm_counter_register(struct device *dev, | |
450 | struct counter_device *const counter); | |
451 | void devm_counter_unregister(struct device *dev, | |
452 | struct counter_device *const counter); | |
453 | ||
454 | #endif /* _COUNTER_H_ */ |