Commit | Line | Data |
---|---|---|
09e7d4ed WBG |
1 | .. SPDX-License-Identifier: GPL-2.0 |
2 | ||
3 | ========================= | |
4 | Generic Counter Interface | |
5 | ========================= | |
6 | ||
7 | Introduction | |
8 | ============ | |
9 | ||
10 | Counter devices are prevalent within a diverse spectrum of industries. | |
11 | The ubiquitous presence of these devices necessitates a common interface | |
12 | and standard of interaction and exposure. This driver API attempts to | |
13 | resolve the issue of duplicate code found among existing counter device | |
14 | drivers by introducing a generic counter interface for consumption. The | |
15 | Generic Counter interface enables drivers to support and expose a common | |
16 | set of components and functionality present in counter devices. | |
17 | ||
18 | Theory | |
19 | ====== | |
20 | ||
21 | Counter devices can vary greatly in design, but regardless of whether | |
22 | some devices are quadrature encoder counters or tally counters, all | |
23 | counter devices consist of a core set of components. This core set of | |
24 | components, shared by all counter devices, is what forms the essence of | |
25 | the Generic Counter interface. | |
26 | ||
27 | There are three core components to a counter: | |
28 | ||
29 | * Count: | |
30 | Count data for a set of Signals. | |
31 | ||
32 | * Signal: | |
33 | Input data that is evaluated by the counter to determine the count | |
34 | data. | |
35 | ||
36 | * Synapse: | |
37 | The association of a Signal with a respective Count. | |
38 | ||
39 | COUNT | |
40 | ----- | |
41 | A Count represents the count data for a set of Signals. The Generic | |
42 | Counter interface provides the following available count data types: | |
43 | ||
44 | * COUNT_POSITION: | |
45 | Unsigned integer value representing position. | |
46 | ||
47 | A Count has a count function mode which represents the update behavior | |
48 | for the count data. The Generic Counter interface provides the following | |
49 | available count function modes: | |
50 | ||
51 | * Increase: | |
52 | Accumulated count is incremented. | |
53 | ||
54 | * Decrease: | |
55 | Accumulated count is decremented. | |
56 | ||
57 | * Pulse-Direction: | |
58 | Rising edges on signal A updates the respective count. The input level | |
59 | of signal B determines direction. | |
60 | ||
61 | * Quadrature: | |
62 | A pair of quadrature encoding signals are evaluated to determine | |
63 | position and direction. The following Quadrature modes are available: | |
64 | ||
65 | - x1 A: | |
66 | If direction is forward, rising edges on quadrature pair signal A | |
67 | updates the respective count; if the direction is backward, falling | |
68 | edges on quadrature pair signal A updates the respective count. | |
69 | Quadrature encoding determines the direction. | |
70 | ||
71 | - x1 B: | |
72 | If direction is forward, rising edges on quadrature pair signal B | |
73 | updates the respective count; if the direction is backward, falling | |
74 | edges on quadrature pair signal B updates the respective count. | |
75 | Quadrature encoding determines the direction. | |
76 | ||
77 | - x2 A: | |
78 | Any state transition on quadrature pair signal A updates the | |
79 | respective count. Quadrature encoding determines the direction. | |
80 | ||
81 | - x2 B: | |
82 | Any state transition on quadrature pair signal B updates the | |
83 | respective count. Quadrature encoding determines the direction. | |
84 | ||
85 | - x4: | |
86 | Any state transition on either quadrature pair signals updates the | |
87 | respective count. Quadrature encoding determines the direction. | |
88 | ||
89 | A Count has a set of one or more associated Signals. | |
90 | ||
91 | SIGNAL | |
92 | ------ | |
93 | A Signal represents a counter input data; this is the input data that is | |
94 | evaluated by the counter to determine the count data; e.g. a quadrature | |
95 | signal output line of a rotary encoder. Not all counter devices provide | |
96 | user access to the Signal data. | |
97 | ||
98 | The Generic Counter interface provides the following available signal | |
99 | data types for when the Signal data is available for user access: | |
100 | ||
101 | * SIGNAL_LEVEL: | |
102 | Signal line state level. The following states are possible: | |
103 | ||
104 | - SIGNAL_LEVEL_LOW: | |
105 | Signal line is in a low state. | |
106 | ||
107 | - SIGNAL_LEVEL_HIGH: | |
108 | Signal line is in a high state. | |
109 | ||
110 | A Signal may be associated with one or more Counts. | |
111 | ||
112 | SYNAPSE | |
113 | ------- | |
114 | A Synapse represents the association of a Signal with a respective | |
115 | Count. Signal data affects respective Count data, and the Synapse | |
116 | represents this relationship. | |
117 | ||
118 | The Synapse action mode specifies the Signal data condition which | |
119 | triggers the respective Count's count function evaluation to update the | |
120 | count data. The Generic Counter interface provides the following | |
121 | available action modes: | |
122 | ||
123 | * None: | |
124 | Signal does not trigger the count function. In Pulse-Direction count | |
125 | function mode, this Signal is evaluated as Direction. | |
126 | ||
127 | * Rising Edge: | |
128 | Low state transitions to high state. | |
129 | ||
130 | * Falling Edge: | |
131 | High state transitions to low state. | |
132 | ||
133 | * Both Edges: | |
134 | Any state transition. | |
135 | ||
136 | A counter is defined as a set of input signals associated with count | |
137 | data that are generated by the evaluation of the state of the associated | |
138 | input signals as defined by the respective count functions. Within the | |
139 | context of the Generic Counter interface, a counter consists of Counts | |
140 | each associated with a set of Signals, whose respective Synapse | |
141 | instances represent the count function update conditions for the | |
142 | associated Counts. | |
143 | ||
144 | Paradigm | |
145 | ======== | |
146 | ||
147 | The most basic counter device may be expressed as a single Count | |
148 | associated with a single Signal via a single Synapse. Take for example | |
149 | a counter device which simply accumulates a count of rising edges on a | |
150 | source input line:: | |
151 | ||
152 | Count Synapse Signal | |
153 | ----- ------- ------ | |
154 | +---------------------+ | |
155 | | Data: Count | Rising Edge ________ | |
156 | | Function: Increase | <------------- / Source \ | |
157 | | | ____________ | |
158 | +---------------------+ | |
159 | ||
160 | In this example, the Signal is a source input line with a pulsing | |
161 | voltage, while the Count is a persistent count value which is repeatedly | |
162 | incremented. The Signal is associated with the respective Count via a | |
163 | Synapse. The increase function is triggered by the Signal data condition | |
164 | specified by the Synapse -- in this case a rising edge condition on the | |
165 | voltage input line. In summary, the counter device existence and | |
166 | behavior is aptly represented by respective Count, Signal, and Synapse | |
167 | components: a rising edge condition triggers an increase function on an | |
168 | accumulating count datum. | |
169 | ||
170 | A counter device is not limited to a single Signal; in fact, in theory | |
171 | many Signals may be associated with even a single Count. For example, a | |
172 | quadrature encoder counter device can keep track of position based on | |
173 | the states of two input lines:: | |
174 | ||
175 | Count Synapse Signal | |
176 | ----- ------- ------ | |
177 | +-------------------------+ | |
178 | | Data: Position | Both Edges ___ | |
179 | | Function: Quadrature x4 | <------------ / A \ | |
180 | | | _______ | |
181 | | | | |
182 | | | Both Edges ___ | |
183 | | | <------------ / B \ | |
184 | | | _______ | |
185 | +-------------------------+ | |
186 | ||
187 | In this example, two Signals (quadrature encoder lines A and B) are | |
188 | associated with a single Count: a rising or falling edge on either A or | |
189 | B triggers the "Quadrature x4" function which determines the direction | |
190 | of movement and updates the respective position data. The "Quadrature | |
191 | x4" function is likely implemented in the hardware of the quadrature | |
192 | encoder counter device; the Count, Signals, and Synapses simply | |
193 | represent this hardware behavior and functionality. | |
194 | ||
195 | Signals associated with the same Count can have differing Synapse action | |
196 | mode conditions. For example, a quadrature encoder counter device | |
197 | operating in a non-quadrature Pulse-Direction mode could have one input | |
198 | line dedicated for movement and a second input line dedicated for | |
199 | direction:: | |
200 | ||
201 | Count Synapse Signal | |
202 | ----- ------- ------ | |
203 | +---------------------------+ | |
204 | | Data: Position | Rising Edge ___ | |
205 | | Function: Pulse-Direction | <------------- / A \ (Movement) | |
206 | | | _______ | |
207 | | | | |
208 | | | None ___ | |
209 | | | <------------- / B \ (Direction) | |
210 | | | _______ | |
211 | +---------------------------+ | |
212 | ||
213 | Only Signal A triggers the "Pulse-Direction" update function, but the | |
214 | instantaneous state of Signal B is still required in order to know the | |
215 | direction so that the position data may be properly updated. Ultimately, | |
216 | both Signals are associated with the same Count via two respective | |
217 | Synapses, but only one Synapse has an active action mode condition which | |
218 | triggers the respective count function while the other is left with a | |
219 | "None" condition action mode to indicate its respective Signal's | |
220 | availability for state evaluation despite its non-triggering mode. | |
221 | ||
222 | Keep in mind that the Signal, Synapse, and Count are abstract | |
223 | representations which do not need to be closely married to their | |
224 | respective physical sources. This allows the user of a counter to | |
225 | divorce themselves from the nuances of physical components (such as | |
226 | whether an input line is differential or single-ended) and instead focus | |
227 | on the core idea of what the data and process represent (e.g. position | |
228 | as interpreted from quadrature encoding data). | |
229 | ||
230 | Userspace Interface | |
231 | =================== | |
232 | ||
233 | Several sysfs attributes are generated by the Generic Counter interface, | |
234 | and reside under the /sys/bus/counter/devices/counterX directory, where | |
235 | counterX refers to the respective counter device. Please see | |
224d5fd4 | 236 | Documentation/ABI/testing/sysfs-bus-counter for detailed |
09e7d4ed WBG |
237 | information on each Generic Counter interface sysfs attribute. |
238 | ||
239 | Through these sysfs attributes, programs and scripts may interact with | |
240 | the Generic Counter paradigm Counts, Signals, and Synapses of respective | |
241 | counter devices. | |
242 | ||
243 | Driver API | |
244 | ========== | |
245 | ||
246 | Driver authors may utilize the Generic Counter interface in their code | |
247 | by including the include/linux/counter.h header file. This header file | |
248 | provides several core data structures, function prototypes, and macros | |
249 | for defining a counter device. | |
250 | ||
251 | .. kernel-doc:: include/linux/counter.h | |
252 | :internal: | |
253 | ||
fba38803 | 254 | .. kernel-doc:: drivers/counter/counter.c |
09e7d4ed WBG |
255 | :export: |
256 | ||
257 | Implementation | |
258 | ============== | |
259 | ||
260 | To support a counter device, a driver must first allocate the available | |
261 | Counter Signals via counter_signal structures. These Signals should | |
262 | be stored as an array and set to the signals array member of an | |
263 | allocated counter_device structure before the Counter is registered to | |
264 | the system. | |
265 | ||
266 | Counter Counts may be allocated via counter_count structures, and | |
267 | respective Counter Signal associations (Synapses) made via | |
268 | counter_synapse structures. Associated counter_synapse structures are | |
269 | stored as an array and set to the the synapses array member of the | |
270 | respective counter_count structure. These counter_count structures are | |
271 | set to the counts array member of an allocated counter_device structure | |
272 | before the Counter is registered to the system. | |
273 | ||
274 | Driver callbacks should be provided to the counter_device structure via | |
275 | a constant counter_ops structure in order to communicate with the | |
276 | device: to read and write various Signals and Counts, and to set and get | |
277 | the "action mode" and "function mode" for various Synapses and Counts | |
278 | respectively. | |
279 | ||
280 | A defined counter_device structure may be registered to the system by | |
281 | passing it to the counter_register function, and unregistered by passing | |
282 | it to the counter_unregister function. Similarly, the | |
283 | devm_counter_register and devm_counter_unregister functions may be used | |
284 | if device memory-managed registration is desired. | |
285 | ||
286 | Extension sysfs attributes can be created for auxiliary functionality | |
287 | and data by passing in defined counter_device_ext, counter_count_ext, | |
288 | and counter_signal_ext structures. In these cases, the | |
289 | counter_device_ext structure is used for global configuration of the | |
290 | respective Counter device, while the counter_count_ext and | |
291 | counter_signal_ext structures allow for auxiliary exposure and | |
292 | configuration of a specific Count or Signal respectively. | |
293 | ||
294 | Architecture | |
295 | ============ | |
296 | ||
297 | When the Generic Counter interface counter module is loaded, the | |
298 | counter_init function is called which registers a bus_type named | |
299 | "counter" to the system. Subsequently, when the module is unloaded, the | |
300 | counter_exit function is called which unregisters the bus_type named | |
301 | "counter" from the system. | |
302 | ||
303 | Counter devices are registered to the system via the counter_register | |
304 | function, and later removed via the counter_unregister function. The | |
305 | counter_register function establishes a unique ID for the Counter | |
306 | device and creates a respective sysfs directory, where X is the | |
307 | mentioned unique ID: | |
308 | ||
309 | /sys/bus/counter/devices/counterX | |
310 | ||
311 | Sysfs attributes are created within the counterX directory to expose | |
312 | functionality, configurations, and data relating to the Counts, Signals, | |
313 | and Synapses of the Counter device, as well as options and information | |
314 | for the Counter device itself. | |
315 | ||
316 | Each Signal has a directory created to house its relevant sysfs | |
317 | attributes, where Y is the unique ID of the respective Signal: | |
318 | ||
319 | /sys/bus/counter/devices/counterX/signalY | |
320 | ||
321 | Similarly, each Count has a directory created to house its relevant | |
322 | sysfs attributes, where Y is the unique ID of the respective Count: | |
323 | ||
324 | /sys/bus/counter/devices/counterX/countY | |
325 | ||
326 | For a more detailed breakdown of the available Generic Counter interface | |
327 | sysfs attributes, please refer to the | |
224d5fd4 | 328 | Documentation/ABI/testing/sysfs-bus-counter file. |
09e7d4ed WBG |
329 | |
330 | The Signals and Counts associated with the Counter device are registered | |
331 | to the system as well by the counter_register function. The | |
332 | signal_read/signal_write driver callbacks are associated with their | |
333 | respective Signal attributes, while the count_read/count_write and | |
334 | function_get/function_set driver callbacks are associated with their | |
335 | respective Count attributes; similarly, the same is true for the | |
336 | action_get/action_set driver callbacks and their respective Synapse | |
337 | attributes. If a driver callback is left undefined, then the respective | |
338 | read/write permission is left disabled for the relevant attributes. | |
339 | ||
340 | Similarly, extension sysfs attributes are created for the defined | |
341 | counter_device_ext, counter_count_ext, and counter_signal_ext | |
342 | structures that are passed in. |