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/array_size.h>
10  #include <linux/cdev.h>
11  #include <linux/device.h>
12  #include <linux/kfifo.h>
13  #include <linux/mutex.h>
14  #include <linux/spinlock_types.h>
15  #include <linux/types.h>
16  #include <linux/wait.h>
17  
18  #include <uapi/linux/counter.h>
19  
20  struct counter_device;
21  struct counter_count;
22  struct counter_synapse;
23  struct counter_signal;
24  
25  enum counter_comp_type {
26  	COUNTER_COMP_U8,
27  	COUNTER_COMP_U64,
28  	COUNTER_COMP_BOOL,
29  	COUNTER_COMP_SIGNAL_LEVEL,
30  	COUNTER_COMP_FUNCTION,
31  	COUNTER_COMP_SYNAPSE_ACTION,
32  	COUNTER_COMP_ENUM,
33  	COUNTER_COMP_COUNT_DIRECTION,
34  	COUNTER_COMP_COUNT_MODE,
35  	COUNTER_COMP_SIGNAL_POLARITY,
36  	COUNTER_COMP_ARRAY,
37  };
38  
39  /**
40   * struct counter_comp - Counter component node
41   * @type:		Counter component data type
42   * @name:		device-specific component name
43   * @priv:		component-relevant data
44   * @action_read:	Synapse action mode read callback. The read value of the
45   *			respective Synapse action mode should be passed back via
46   *			the action parameter.
47   * @device_u8_read:	Device u8 component read callback. The read value of the
48   *			respective Device u8 component should be passed back via
49   *			the val parameter.
50   * @count_u8_read:	Count u8 component read callback. The read value of the
51   *			respective Count u8 component should be passed back via
52   *			the val parameter.
53   * @signal_u8_read:	Signal u8 component read callback. The read value of the
54   *			respective Signal u8 component should be passed back via
55   *			the val parameter.
56   * @device_u32_read:	Device u32 component read callback. The read value of
57   *			the respective Device u32 component should be passed
58   *			back via the val parameter.
59   * @count_u32_read:	Count u32 component read callback. The read value of the
60   *			respective Count u32 component should be passed back via
61   *			the val parameter.
62   * @signal_u32_read:	Signal u32 component read callback. The read value of
63   *			the respective Signal u32 component should be passed
64   *			back via the val parameter.
65   * @device_u64_read:	Device u64 component read callback. The read value of
66   *			the respective Device u64 component should be passed
67   *			back via the val parameter.
68   * @count_u64_read:	Count u64 component read callback. The read value of the
69   *			respective Count u64 component should be passed back via
70   *			the val parameter.
71   * @signal_u64_read:	Signal u64 component read callback. The read value of
72   *			the respective Signal u64 component should be passed
73   *			back via the val parameter.
74   * @signal_array_u32_read:	Signal u32 array component read callback. The
75   *				index of the respective Count u32 array
76   *				component element is passed via the idx
77   *				parameter. The read value of the respective
78   *				Count u32 array component element should be
79   *				passed back via the val parameter.
80   * @device_array_u64_read:	Device u64 array component read callback. The
81   *				index of the respective Device u64 array
82   *				component element is passed via the idx
83   *				parameter. The read value of the respective
84   *				Device u64 array component element should be
85   *				passed back via the val parameter.
86   * @count_array_u64_read:	Count u64 array component read callback. The
87   *				index of the respective Count u64 array
88   *				component element is passed via the idx
89   *				parameter. The read value of the respective
90   *				Count u64 array component element should be
91   *				passed back via the val parameter.
92   * @signal_array_u64_read:	Signal u64 array component read callback. The
93   *				index of the respective Count u64 array
94   *				component element is passed via the idx
95   *				parameter. The read value of the respective
96   *				Count u64 array component element should be
97   *				passed back via the val parameter.
98   * @action_write:	Synapse action mode write callback. The write value of
99   *			the respective Synapse action mode is passed via the
100   *			action parameter.
101   * @device_u8_write:	Device u8 component write callback. The write value of
102   *			the respective Device u8 component is passed via the val
103   *			parameter.
104   * @count_u8_write:	Count u8 component write callback. The write value of
105   *			the respective Count u8 component is passed via the val
106   *			parameter.
107   * @signal_u8_write:	Signal u8 component write callback. The write value of
108   *			the respective Signal u8 component is passed via the val
109   *			parameter.
110   * @device_u32_write:	Device u32 component write callback. The write value of
111   *			the respective Device u32 component is passed via the
112   *			val parameter.
113   * @count_u32_write:	Count u32 component write callback. The write value of
114   *			the respective Count u32 component is passed via the val
115   *			parameter.
116   * @signal_u32_write:	Signal u32 component write callback. The write value of
117   *			the respective Signal u32 component is passed via the
118   *			val parameter.
119   * @device_u64_write:	Device u64 component write callback. The write value of
120   *			the respective Device u64 component is passed via the
121   *			val parameter.
122   * @count_u64_write:	Count u64 component write callback. The write value of
123   *			the respective Count u64 component is passed via the val
124   *			parameter.
125   * @signal_u64_write:	Signal u64 component write callback. The write value of
126   *			the respective Signal u64 component is passed via the
127   *			val parameter.
128   * @signal_array_u32_write:	Signal u32 array component write callback. The
129   *				index of the respective Signal u32 array
130   *				component element is passed via the idx
131   *				parameter. The write value of the respective
132   *				Signal u32 array component element is passed via
133   *				the val parameter.
134   * @device_array_u64_write:	Device u64 array component write callback. The
135   *				index of the respective Device u64 array
136   *				component element is passed via the idx
137   *				parameter. The write value of the respective
138   *				Device u64 array component element is passed via
139   *				the val parameter.
140   * @count_array_u64_write:	Count u64 array component write callback. The
141   *				index of the respective Count u64 array
142   *				component element is passed via the idx
143   *				parameter. The write value of the respective
144   *				Count u64 array component element is passed via
145   *				the val parameter.
146   * @signal_array_u64_write:	Signal u64 array component write callback. The
147   *				index of the respective Signal u64 array
148   *				component element is passed via the idx
149   *				parameter. The write value of the respective
150   *				Signal u64 array component element is passed via
151   *				the val parameter.
152   */
153  struct counter_comp {
154  	enum counter_comp_type type;
155  	const char *name;
156  	void *priv;
157  	union {
158  		int (*action_read)(struct counter_device *counter,
159  				   struct counter_count *count,
160  				   struct counter_synapse *synapse,
161  				   enum counter_synapse_action *action);
162  		int (*device_u8_read)(struct counter_device *counter, u8 *val);
163  		int (*count_u8_read)(struct counter_device *counter,
164  				     struct counter_count *count, u8 *val);
165  		int (*signal_u8_read)(struct counter_device *counter,
166  				      struct counter_signal *signal, u8 *val);
167  		int (*device_u32_read)(struct counter_device *counter,
168  				       u32 *val);
169  		int (*count_u32_read)(struct counter_device *counter,
170  				      struct counter_count *count, u32 *val);
171  		int (*signal_u32_read)(struct counter_device *counter,
172  				       struct counter_signal *signal, u32 *val);
173  		int (*device_u64_read)(struct counter_device *counter,
174  				       u64 *val);
175  		int (*count_u64_read)(struct counter_device *counter,
176  				      struct counter_count *count, u64 *val);
177  		int (*signal_u64_read)(struct counter_device *counter,
178  				       struct counter_signal *signal, u64 *val);
179  		int (*signal_array_u32_read)(struct counter_device *counter,
180  					     struct counter_signal *signal,
181  					     size_t idx, u32 *val);
182  		int (*device_array_u64_read)(struct counter_device *counter,
183  					     size_t idx, u64 *val);
184  		int (*count_array_u64_read)(struct counter_device *counter,
185  					    struct counter_count *count,
186  					    size_t idx, u64 *val);
187  		int (*signal_array_u64_read)(struct counter_device *counter,
188  					     struct counter_signal *signal,
189  					     size_t idx, u64 *val);
190  	};
191  	union {
192  		int (*action_write)(struct counter_device *counter,
193  				    struct counter_count *count,
194  				    struct counter_synapse *synapse,
195  				    enum counter_synapse_action action);
196  		int (*device_u8_write)(struct counter_device *counter, u8 val);
197  		int (*count_u8_write)(struct counter_device *counter,
198  				      struct counter_count *count, u8 val);
199  		int (*signal_u8_write)(struct counter_device *counter,
200  				       struct counter_signal *signal, u8 val);
201  		int (*device_u32_write)(struct counter_device *counter,
202  					u32 val);
203  		int (*count_u32_write)(struct counter_device *counter,
204  				       struct counter_count *count, u32 val);
205  		int (*signal_u32_write)(struct counter_device *counter,
206  					struct counter_signal *signal, u32 val);
207  		int (*device_u64_write)(struct counter_device *counter,
208  					u64 val);
209  		int (*count_u64_write)(struct counter_device *counter,
210  				       struct counter_count *count, u64 val);
211  		int (*signal_u64_write)(struct counter_device *counter,
212  					struct counter_signal *signal, u64 val);
213  		int (*signal_array_u32_write)(struct counter_device *counter,
214  					      struct counter_signal *signal,
215  					      size_t idx, u32 val);
216  		int (*device_array_u64_write)(struct counter_device *counter,
217  					      size_t idx, u64 val);
218  		int (*count_array_u64_write)(struct counter_device *counter,
219  					     struct counter_count *count,
220  					     size_t idx, u64 val);
221  		int (*signal_array_u64_write)(struct counter_device *counter,
222  					      struct counter_signal *signal,
223  					      size_t idx, u64 val);
224  	};
225  };
226  
227  /**
228   * struct counter_signal - Counter Signal node
229   * @id:		unique ID used to identify the Signal
230   * @name:	device-specific Signal name
231   * @ext:	optional array of Signal extensions
232   * @num_ext:	number of Signal extensions specified in @ext
233   */
234  struct counter_signal {
235  	int id;
236  	const char *name;
237  
238  	struct counter_comp *ext;
239  	size_t num_ext;
240  };
241  
242  /**
243   * struct counter_synapse - Counter Synapse node
244   * @actions_list:	array of available action modes
245   * @num_actions:	number of action modes specified in @actions_list
246   * @signal:		pointer to the associated Signal
247   */
248  struct counter_synapse {
249  	const enum counter_synapse_action *actions_list;
250  	size_t num_actions;
251  
252  	struct counter_signal *signal;
253  };
254  
255  /**
256   * struct counter_count - Counter Count node
257   * @id:			unique ID used to identify the Count
258   * @name:		device-specific Count name
259   * @functions_list:	array of available function modes
260   * @num_functions:	number of function modes specified in @functions_list
261   * @synapses:		array of Synapses for initialization
262   * @num_synapses:	number of Synapses specified in @synapses
263   * @ext:		optional array of Count extensions
264   * @num_ext:		number of Count extensions specified in @ext
265   */
266  struct counter_count {
267  	int id;
268  	const char *name;
269  
270  	const enum counter_function *functions_list;
271  	size_t num_functions;
272  
273  	struct counter_synapse *synapses;
274  	size_t num_synapses;
275  
276  	struct counter_comp *ext;
277  	size_t num_ext;
278  };
279  
280  /**
281   * struct counter_event_node - Counter Event node
282   * @l:		list of current watching Counter events
283   * @event:	event that triggers
284   * @channel:	event channel
285   * @comp_list:	list of components to watch when event triggers
286   */
287  struct counter_event_node {
288  	struct list_head l;
289  	u8 event;
290  	u8 channel;
291  	struct list_head comp_list;
292  };
293  
294  /**
295   * struct counter_ops - Callbacks from driver
296   * @signal_read:	optional read callback for Signals. The read level of
297   *			the respective Signal should be passed back via the
298   *			level parameter.
299   * @count_read:		read callback for Counts. The read value of the
300   *			respective Count should be passed back via the value
301   *			parameter.
302   * @count_write:	optional write callback for Counts. The write value for
303   *			the respective Count is passed in via the value
304   *			parameter.
305   * @function_read:	read callback the Count function modes. The read
306   *			function mode of the respective Count should be passed
307   *			back via the function parameter.
308   * @function_write:	optional write callback for Count function modes. The
309   *			function mode to write for the respective Count is
310   *			passed in via the function parameter.
311   * @action_read:	optional read callback the Synapse action modes. The
312   *			read action mode of the respective Synapse should be
313   *			passed back via the action parameter.
314   * @action_write:	optional write callback for Synapse action modes. The
315   *			action mode to write for the respective Synapse is
316   *			passed in via the action parameter.
317   * @events_configure:	optional write callback to configure events. The list of
318   *			struct counter_event_node may be accessed via the
319   *			events_list member of the counter parameter.
320   * @watch_validate:	optional callback to validate a watch. The Counter
321   *			component watch configuration is passed in via the watch
322   *			parameter. A return value of 0 indicates a valid Counter
323   *			component watch configuration.
324   */
325  struct counter_ops {
326  	int (*signal_read)(struct counter_device *counter,
327  			   struct counter_signal *signal,
328  			   enum counter_signal_level *level);
329  	int (*count_read)(struct counter_device *counter,
330  			  struct counter_count *count, u64 *value);
331  	int (*count_write)(struct counter_device *counter,
332  			   struct counter_count *count, u64 value);
333  	int (*function_read)(struct counter_device *counter,
334  			     struct counter_count *count,
335  			     enum counter_function *function);
336  	int (*function_write)(struct counter_device *counter,
337  			      struct counter_count *count,
338  			      enum counter_function function);
339  	int (*action_read)(struct counter_device *counter,
340  			   struct counter_count *count,
341  			   struct counter_synapse *synapse,
342  			   enum counter_synapse_action *action);
343  	int (*action_write)(struct counter_device *counter,
344  			    struct counter_count *count,
345  			    struct counter_synapse *synapse,
346  			    enum counter_synapse_action action);
347  	int (*events_configure)(struct counter_device *counter);
348  	int (*watch_validate)(struct counter_device *counter,
349  			      const struct counter_watch *watch);
350  };
351  
352  /**
353   * struct counter_device - Counter data structure
354   * @name:		name of the device
355   * @parent:		optional parent device providing the counters
356   * @ops:		callbacks from driver
357   * @signals:		array of Signals
358   * @num_signals:	number of Signals specified in @signals
359   * @counts:		array of Counts
360   * @num_counts:		number of Counts specified in @counts
361   * @ext:		optional array of Counter device extensions
362   * @num_ext:		number of Counter device extensions specified in @ext
363   * @dev:		internal device structure
364   * @chrdev:		internal character device structure
365   * @events_list:	list of current watching Counter events
366   * @events_list_lock:	lock to protect Counter events list operations
367   * @next_events_list:	list of next watching Counter events
368   * @n_events_list_lock:	lock to protect Counter next events list operations
369   * @events:		queue of detected Counter events
370   * @events_wait:	wait queue to allow blocking reads of Counter events
371   * @events_in_lock:	lock to protect Counter events queue in operations
372   * @events_out_lock:	lock to protect Counter events queue out operations
373   * @ops_exist_lock:	lock to prevent use during removal
374   */
375  struct counter_device {
376  	const char *name;
377  	struct device *parent;
378  
379  	const struct counter_ops *ops;
380  
381  	struct counter_signal *signals;
382  	size_t num_signals;
383  	struct counter_count *counts;
384  	size_t num_counts;
385  
386  	struct counter_comp *ext;
387  	size_t num_ext;
388  
389  	struct device dev;
390  	struct cdev chrdev;
391  	struct list_head events_list;
392  	spinlock_t events_list_lock;
393  	struct list_head next_events_list;
394  	struct mutex n_events_list_lock;
395  	DECLARE_KFIFO_PTR(events, struct counter_event);
396  	wait_queue_head_t events_wait;
397  	spinlock_t events_in_lock;
398  	struct mutex events_out_lock;
399  	struct mutex ops_exist_lock;
400  };
401  
402  void *counter_priv(const struct counter_device *const counter) __attribute_const__;
403  
404  struct counter_device *counter_alloc(size_t sizeof_priv);
405  void counter_put(struct counter_device *const counter);
406  int counter_add(struct counter_device *const counter);
407  
408  void counter_unregister(struct counter_device *const counter);
409  struct counter_device *devm_counter_alloc(struct device *dev,
410  					  size_t sizeof_priv);
411  int devm_counter_add(struct device *dev,
412  		     struct counter_device *const counter);
413  void counter_push_event(struct counter_device *const counter, const u8 event,
414  			const u8 channel);
415  
416  #define COUNTER_COMP_DEVICE_U8(_name, _read, _write) \
417  { \
418  	.type = COUNTER_COMP_U8, \
419  	.name = (_name), \
420  	.device_u8_read = (_read), \
421  	.device_u8_write = (_write), \
422  }
423  #define COUNTER_COMP_COUNT_U8(_name, _read, _write) \
424  { \
425  	.type = COUNTER_COMP_U8, \
426  	.name = (_name), \
427  	.count_u8_read = (_read), \
428  	.count_u8_write = (_write), \
429  }
430  #define COUNTER_COMP_SIGNAL_U8(_name, _read, _write) \
431  { \
432  	.type = COUNTER_COMP_U8, \
433  	.name = (_name), \
434  	.signal_u8_read = (_read), \
435  	.signal_u8_write = (_write), \
436  }
437  
438  #define COUNTER_COMP_DEVICE_U64(_name, _read, _write) \
439  { \
440  	.type = COUNTER_COMP_U64, \
441  	.name = (_name), \
442  	.device_u64_read = (_read), \
443  	.device_u64_write = (_write), \
444  }
445  #define COUNTER_COMP_COUNT_U64(_name, _read, _write) \
446  { \
447  	.type = COUNTER_COMP_U64, \
448  	.name = (_name), \
449  	.count_u64_read = (_read), \
450  	.count_u64_write = (_write), \
451  }
452  #define COUNTER_COMP_SIGNAL_U64(_name, _read, _write) \
453  { \
454  	.type = COUNTER_COMP_U64, \
455  	.name = (_name), \
456  	.signal_u64_read = (_read), \
457  	.signal_u64_write = (_write), \
458  }
459  
460  #define COUNTER_COMP_DEVICE_BOOL(_name, _read, _write) \
461  { \
462  	.type = COUNTER_COMP_BOOL, \
463  	.name = (_name), \
464  	.device_u8_read = (_read), \
465  	.device_u8_write = (_write), \
466  }
467  #define COUNTER_COMP_COUNT_BOOL(_name, _read, _write) \
468  { \
469  	.type = COUNTER_COMP_BOOL, \
470  	.name = (_name), \
471  	.count_u8_read = (_read), \
472  	.count_u8_write = (_write), \
473  }
474  #define COUNTER_COMP_SIGNAL_BOOL(_name, _read, _write) \
475  { \
476  	.type = COUNTER_COMP_BOOL, \
477  	.name = (_name), \
478  	.signal_u8_read = (_read), \
479  	.signal_u8_write = (_write), \
480  }
481  
482  struct counter_available {
483  	union {
484  		const u32 *enums;
485  		const char *const *strs;
486  	};
487  	size_t num_items;
488  };
489  
490  #define DEFINE_COUNTER_AVAILABLE(_name, _enums) \
491  	struct counter_available _name = { \
492  		.enums = (_enums), \
493  		.num_items = ARRAY_SIZE(_enums), \
494  	}
495  
496  #define DEFINE_COUNTER_ENUM(_name, _strs) \
497  	struct counter_available _name = { \
498  		.strs = (_strs), \
499  		.num_items = ARRAY_SIZE(_strs), \
500  	}
501  
502  #define COUNTER_COMP_DEVICE_ENUM(_name, _get, _set, _available) \
503  { \
504  	.type = COUNTER_COMP_ENUM, \
505  	.name = (_name), \
506  	.device_u32_read = (_get), \
507  	.device_u32_write = (_set), \
508  	.priv = &(_available), \
509  }
510  #define COUNTER_COMP_COUNT_ENUM(_name, _get, _set, _available) \
511  { \
512  	.type = COUNTER_COMP_ENUM, \
513  	.name = (_name), \
514  	.count_u32_read = (_get), \
515  	.count_u32_write = (_set), \
516  	.priv = &(_available), \
517  }
518  #define COUNTER_COMP_SIGNAL_ENUM(_name, _get, _set, _available) \
519  { \
520  	.type = COUNTER_COMP_ENUM, \
521  	.name = (_name), \
522  	.signal_u32_read = (_get), \
523  	.signal_u32_write = (_set), \
524  	.priv = &(_available), \
525  }
526  
527  struct counter_array {
528  	enum counter_comp_type type;
529  	const struct counter_available *avail;
530  	union {
531  		size_t length;
532  		size_t idx;
533  	};
534  };
535  
536  #define DEFINE_COUNTER_ARRAY_U64(_name, _length) \
537  	struct counter_array _name = { \
538  		.type = COUNTER_COMP_U64, \
539  		.length = (_length), \
540  	}
541  
542  #define DEFINE_COUNTER_ARRAY_CAPTURE(_name, _length) \
543  	DEFINE_COUNTER_ARRAY_U64(_name, _length)
544  
545  #define DEFINE_COUNTER_ARRAY_POLARITY(_name, _available, _length) \
546  	struct counter_array _name = { \
547  		.type = COUNTER_COMP_SIGNAL_POLARITY, \
548  		.avail = &(_available), \
549  		.length = (_length), \
550  	}
551  
552  #define COUNTER_COMP_DEVICE_ARRAY_U64(_name, _read, _write, _array) \
553  { \
554  	.type = COUNTER_COMP_ARRAY, \
555  	.name = (_name), \
556  	.device_array_u64_read = (_read), \
557  	.device_array_u64_write = (_write), \
558  	.priv = &(_array), \
559  }
560  #define COUNTER_COMP_COUNT_ARRAY_U64(_name, _read, _write, _array) \
561  { \
562  	.type = COUNTER_COMP_ARRAY, \
563  	.name = (_name), \
564  	.count_array_u64_read = (_read), \
565  	.count_array_u64_write = (_write), \
566  	.priv = &(_array), \
567  }
568  #define COUNTER_COMP_SIGNAL_ARRAY_U64(_name, _read, _write, _array) \
569  { \
570  	.type = COUNTER_COMP_ARRAY, \
571  	.name = (_name), \
572  	.signal_array_u64_read = (_read), \
573  	.signal_array_u64_write = (_write), \
574  	.priv = &(_array), \
575  }
576  
577  #define COUNTER_COMP_CAPTURE(_read, _write) \
578  	COUNTER_COMP_COUNT_U64("capture", _read, _write)
579  
580  #define COUNTER_COMP_CEILING(_read, _write) \
581  	COUNTER_COMP_COUNT_U64("ceiling", _read, _write)
582  
583  #define COUNTER_COMP_COUNT_MODE(_read, _write, _available) \
584  { \
585  	.type = COUNTER_COMP_COUNT_MODE, \
586  	.name = "count_mode", \
587  	.count_u32_read = (_read), \
588  	.count_u32_write = (_write), \
589  	.priv = &(_available), \
590  }
591  
592  #define COUNTER_COMP_DIRECTION(_read) \
593  { \
594  	.type = COUNTER_COMP_COUNT_DIRECTION, \
595  	.name = "direction", \
596  	.count_u32_read = (_read), \
597  }
598  
599  #define COUNTER_COMP_ENABLE(_read, _write) \
600  	COUNTER_COMP_COUNT_BOOL("enable", _read, _write)
601  
602  #define COUNTER_COMP_FLOOR(_read, _write) \
603  	COUNTER_COMP_COUNT_U64("floor", _read, _write)
604  
605  #define COUNTER_COMP_FREQUENCY(_read) \
606  	COUNTER_COMP_SIGNAL_U64("frequency", _read, NULL)
607  
608  #define COUNTER_COMP_POLARITY(_read, _write, _available) \
609  { \
610  	.type = COUNTER_COMP_SIGNAL_POLARITY, \
611  	.name = "polarity", \
612  	.signal_u32_read = (_read), \
613  	.signal_u32_write = (_write), \
614  	.priv = &(_available), \
615  }
616  
617  #define COUNTER_COMP_PRESET(_read, _write) \
618  	COUNTER_COMP_COUNT_U64("preset", _read, _write)
619  
620  #define COUNTER_COMP_PRESET_ENABLE(_read, _write) \
621  	COUNTER_COMP_COUNT_BOOL("preset_enable", _read, _write)
622  
623  #define COUNTER_COMP_ARRAY_CAPTURE(_read, _write, _array) \
624  	COUNTER_COMP_COUNT_ARRAY_U64("capture", _read, _write, _array)
625  
626  #define COUNTER_COMP_ARRAY_POLARITY(_read, _write, _array) \
627  { \
628  	.type = COUNTER_COMP_ARRAY, \
629  	.name = "polarity", \
630  	.signal_array_u32_read = (_read), \
631  	.signal_array_u32_write = (_write), \
632  	.priv = &(_array), \
633  }
634  
635  #endif /* _COUNTER_H_ */
636