• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ */
473