xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/generic-counter.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun=========================
4*4882a593SmuzhiyunGeneric Counter Interface
5*4882a593Smuzhiyun=========================
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunIntroduction
8*4882a593Smuzhiyun============
9*4882a593Smuzhiyun
10*4882a593SmuzhiyunCounter devices are prevalent among a diverse spectrum of industries.
11*4882a593SmuzhiyunThe ubiquitous presence of these devices necessitates a common interface
12*4882a593Smuzhiyunand standard of interaction and exposure. This driver API attempts to
13*4882a593Smuzhiyunresolve the issue of duplicate code found among existing counter device
14*4882a593Smuzhiyundrivers by introducing a generic counter interface for consumption. The
15*4882a593SmuzhiyunGeneric Counter interface enables drivers to support and expose a common
16*4882a593Smuzhiyunset of components and functionality present in counter devices.
17*4882a593Smuzhiyun
18*4882a593SmuzhiyunTheory
19*4882a593Smuzhiyun======
20*4882a593Smuzhiyun
21*4882a593SmuzhiyunCounter devices can vary greatly in design, but regardless of whether
22*4882a593Smuzhiyunsome devices are quadrature encoder counters or tally counters, all
23*4882a593Smuzhiyuncounter devices consist of a core set of components. This core set of
24*4882a593Smuzhiyuncomponents, shared by all counter devices, is what forms the essence of
25*4882a593Smuzhiyunthe Generic Counter interface.
26*4882a593Smuzhiyun
27*4882a593SmuzhiyunThere are three core components to a counter:
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun* Signal:
30*4882a593Smuzhiyun  Stream of data to be evaluated by the counter.
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun* Synapse:
33*4882a593Smuzhiyun  Association of a Signal, and evaluation trigger, with a Count.
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun* Count:
36*4882a593Smuzhiyun  Accumulation of the effects of connected Synapses.
37*4882a593Smuzhiyun
38*4882a593SmuzhiyunSIGNAL
39*4882a593Smuzhiyun------
40*4882a593SmuzhiyunA Signal represents a stream of data. This is the input data that is
41*4882a593Smuzhiyunevaluated by the counter to determine the count data; e.g. a quadrature
42*4882a593Smuzhiyunsignal output line of a rotary encoder. Not all counter devices provide
43*4882a593Smuzhiyunuser access to the Signal data, so exposure is optional for drivers.
44*4882a593Smuzhiyun
45*4882a593SmuzhiyunWhen the Signal data is available for user access, the Generic Counter
46*4882a593Smuzhiyuninterface provides the following available signal values:
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun* SIGNAL_LOW:
49*4882a593Smuzhiyun  Signal line is in a low state.
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun* SIGNAL_HIGH:
52*4882a593Smuzhiyun  Signal line is in a high state.
53*4882a593Smuzhiyun
54*4882a593SmuzhiyunA Signal may be associated with one or more Counts.
55*4882a593Smuzhiyun
56*4882a593SmuzhiyunSYNAPSE
57*4882a593Smuzhiyun-------
58*4882a593SmuzhiyunA Synapse represents the association of a Signal with a Count. Signal
59*4882a593Smuzhiyundata affects respective Count data, and the Synapse represents this
60*4882a593Smuzhiyunrelationship.
61*4882a593Smuzhiyun
62*4882a593SmuzhiyunThe Synapse action mode specifies the Signal data condition that
63*4882a593Smuzhiyuntriggers the respective Count's count function evaluation to update the
64*4882a593Smuzhiyuncount data. The Generic Counter interface provides the following
65*4882a593Smuzhiyunavailable action modes:
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun* None:
68*4882a593Smuzhiyun  Signal does not trigger the count function. In Pulse-Direction count
69*4882a593Smuzhiyun  function mode, this Signal is evaluated as Direction.
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun* Rising Edge:
72*4882a593Smuzhiyun  Low state transitions to high state.
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun* Falling Edge:
75*4882a593Smuzhiyun  High state transitions to low state.
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun* Both Edges:
78*4882a593Smuzhiyun  Any state transition.
79*4882a593Smuzhiyun
80*4882a593SmuzhiyunA counter is defined as a set of input signals associated with count
81*4882a593Smuzhiyundata that are generated by the evaluation of the state of the associated
82*4882a593Smuzhiyuninput signals as defined by the respective count functions. Within the
83*4882a593Smuzhiyuncontext of the Generic Counter interface, a counter consists of Counts
84*4882a593Smuzhiyuneach associated with a set of Signals, whose respective Synapse
85*4882a593Smuzhiyuninstances represent the count function update conditions for the
86*4882a593Smuzhiyunassociated Counts.
87*4882a593Smuzhiyun
88*4882a593SmuzhiyunA Synapse associates one Signal with one Count.
89*4882a593Smuzhiyun
90*4882a593SmuzhiyunCOUNT
91*4882a593Smuzhiyun-----
92*4882a593SmuzhiyunA Count represents the accumulation of the effects of connected
93*4882a593SmuzhiyunSynapses; i.e. the count data for a set of Signals. The Generic
94*4882a593SmuzhiyunCounter interface represents the count data as a natural number.
95*4882a593Smuzhiyun
96*4882a593SmuzhiyunA Count has a count function mode which represents the update behavior
97*4882a593Smuzhiyunfor the count data. The Generic Counter interface provides the following
98*4882a593Smuzhiyunavailable count function modes:
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun* Increase:
101*4882a593Smuzhiyun  Accumulated count is incremented.
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun* Decrease:
104*4882a593Smuzhiyun  Accumulated count is decremented.
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun* Pulse-Direction:
107*4882a593Smuzhiyun  Rising edges on signal A updates the respective count. The input level
108*4882a593Smuzhiyun  of signal B determines direction.
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun* Quadrature:
111*4882a593Smuzhiyun  A pair of quadrature encoding signals are evaluated to determine
112*4882a593Smuzhiyun  position and direction. The following Quadrature modes are available:
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun  - x1 A:
115*4882a593Smuzhiyun    If direction is forward, rising edges on quadrature pair signal A
116*4882a593Smuzhiyun    updates the respective count; if the direction is backward, falling
117*4882a593Smuzhiyun    edges on quadrature pair signal A updates the respective count.
118*4882a593Smuzhiyun    Quadrature encoding determines the direction.
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun  - x1 B:
121*4882a593Smuzhiyun    If direction is forward, rising edges on quadrature pair signal B
122*4882a593Smuzhiyun    updates the respective count; if the direction is backward, falling
123*4882a593Smuzhiyun    edges on quadrature pair signal B updates the respective count.
124*4882a593Smuzhiyun    Quadrature encoding determines the direction.
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun  - x2 A:
127*4882a593Smuzhiyun    Any state transition on quadrature pair signal A updates the
128*4882a593Smuzhiyun    respective count. Quadrature encoding determines the direction.
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun  - x2 B:
131*4882a593Smuzhiyun    Any state transition on quadrature pair signal B updates the
132*4882a593Smuzhiyun    respective count. Quadrature encoding determines the direction.
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun  - x4:
135*4882a593Smuzhiyun    Any state transition on either quadrature pair signals updates the
136*4882a593Smuzhiyun    respective count. Quadrature encoding determines the direction.
137*4882a593Smuzhiyun
138*4882a593SmuzhiyunA Count has a set of one or more associated Synapses.
139*4882a593Smuzhiyun
140*4882a593SmuzhiyunParadigm
141*4882a593Smuzhiyun========
142*4882a593Smuzhiyun
143*4882a593SmuzhiyunThe most basic counter device may be expressed as a single Count
144*4882a593Smuzhiyunassociated with a single Signal via a single Synapse. Take for example
145*4882a593Smuzhiyuna counter device which simply accumulates a count of rising edges on a
146*4882a593Smuzhiyunsource input line::
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun                Count                Synapse        Signal
149*4882a593Smuzhiyun                -----                -------        ------
150*4882a593Smuzhiyun        +---------------------+
151*4882a593Smuzhiyun        | Data: Count         |    Rising Edge     ________
152*4882a593Smuzhiyun        | Function: Increase  |  <-------------   / Source \
153*4882a593Smuzhiyun        |                     |                  ____________
154*4882a593Smuzhiyun        +---------------------+
155*4882a593Smuzhiyun
156*4882a593SmuzhiyunIn this example, the Signal is a source input line with a pulsing
157*4882a593Smuzhiyunvoltage, while the Count is a persistent count value which is repeatedly
158*4882a593Smuzhiyunincremented. The Signal is associated with the respective Count via a
159*4882a593SmuzhiyunSynapse. The increase function is triggered by the Signal data condition
160*4882a593Smuzhiyunspecified by the Synapse -- in this case a rising edge condition on the
161*4882a593Smuzhiyunvoltage input line. In summary, the counter device existence and
162*4882a593Smuzhiyunbehavior is aptly represented by respective Count, Signal, and Synapse
163*4882a593Smuzhiyuncomponents: a rising edge condition triggers an increase function on an
164*4882a593Smuzhiyunaccumulating count datum.
165*4882a593Smuzhiyun
166*4882a593SmuzhiyunA counter device is not limited to a single Signal; in fact, in theory
167*4882a593Smuzhiyunmany Signals may be associated with even a single Count. For example, a
168*4882a593Smuzhiyunquadrature encoder counter device can keep track of position based on
169*4882a593Smuzhiyunthe states of two input lines::
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun                   Count                 Synapse     Signal
172*4882a593Smuzhiyun                   -----                 -------     ------
173*4882a593Smuzhiyun        +-------------------------+
174*4882a593Smuzhiyun        | Data: Position          |    Both Edges     ___
175*4882a593Smuzhiyun        | Function: Quadrature x4 |  <------------   / A \
176*4882a593Smuzhiyun        |                         |                 _______
177*4882a593Smuzhiyun        |                         |
178*4882a593Smuzhiyun        |                         |    Both Edges     ___
179*4882a593Smuzhiyun        |                         |  <------------   / B \
180*4882a593Smuzhiyun        |                         |                 _______
181*4882a593Smuzhiyun        +-------------------------+
182*4882a593Smuzhiyun
183*4882a593SmuzhiyunIn this example, two Signals (quadrature encoder lines A and B) are
184*4882a593Smuzhiyunassociated with a single Count: a rising or falling edge on either A or
185*4882a593SmuzhiyunB triggers the "Quadrature x4" function which determines the direction
186*4882a593Smuzhiyunof movement and updates the respective position data. The "Quadrature
187*4882a593Smuzhiyunx4" function is likely implemented in the hardware of the quadrature
188*4882a593Smuzhiyunencoder counter device; the Count, Signals, and Synapses simply
189*4882a593Smuzhiyunrepresent this hardware behavior and functionality.
190*4882a593Smuzhiyun
191*4882a593SmuzhiyunSignals associated with the same Count can have differing Synapse action
192*4882a593Smuzhiyunmode conditions. For example, a quadrature encoder counter device
193*4882a593Smuzhiyunoperating in a non-quadrature Pulse-Direction mode could have one input
194*4882a593Smuzhiyunline dedicated for movement and a second input line dedicated for
195*4882a593Smuzhiyundirection::
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun                   Count                   Synapse      Signal
198*4882a593Smuzhiyun                   -----                   -------      ------
199*4882a593Smuzhiyun        +---------------------------+
200*4882a593Smuzhiyun        | Data: Position            |    Rising Edge     ___
201*4882a593Smuzhiyun        | Function: Pulse-Direction |  <-------------   / A \ (Movement)
202*4882a593Smuzhiyun        |                           |                  _______
203*4882a593Smuzhiyun        |                           |
204*4882a593Smuzhiyun        |                           |       None         ___
205*4882a593Smuzhiyun        |                           |  <-------------   / B \ (Direction)
206*4882a593Smuzhiyun        |                           |                  _______
207*4882a593Smuzhiyun        +---------------------------+
208*4882a593Smuzhiyun
209*4882a593SmuzhiyunOnly Signal A triggers the "Pulse-Direction" update function, but the
210*4882a593Smuzhiyuninstantaneous state of Signal B is still required in order to know the
211*4882a593Smuzhiyundirection so that the position data may be properly updated. Ultimately,
212*4882a593Smuzhiyunboth Signals are associated with the same Count via two respective
213*4882a593SmuzhiyunSynapses, but only one Synapse has an active action mode condition which
214*4882a593Smuzhiyuntriggers the respective count function while the other is left with a
215*4882a593Smuzhiyun"None" condition action mode to indicate its respective Signal's
216*4882a593Smuzhiyunavailability for state evaluation despite its non-triggering mode.
217*4882a593Smuzhiyun
218*4882a593SmuzhiyunKeep in mind that the Signal, Synapse, and Count are abstract
219*4882a593Smuzhiyunrepresentations which do not need to be closely married to their
220*4882a593Smuzhiyunrespective physical sources. This allows the user of a counter to
221*4882a593Smuzhiyundivorce themselves from the nuances of physical components (such as
222*4882a593Smuzhiyunwhether an input line is differential or single-ended) and instead focus
223*4882a593Smuzhiyunon the core idea of what the data and process represent (e.g. position
224*4882a593Smuzhiyunas interpreted from quadrature encoding data).
225*4882a593Smuzhiyun
226*4882a593SmuzhiyunUserspace Interface
227*4882a593Smuzhiyun===================
228*4882a593Smuzhiyun
229*4882a593SmuzhiyunSeveral sysfs attributes are generated by the Generic Counter interface,
230*4882a593Smuzhiyunand reside under the /sys/bus/counter/devices/counterX directory, where
231*4882a593SmuzhiyuncounterX refers to the respective counter device. Please see
232*4882a593SmuzhiyunDocumentation/ABI/testing/sysfs-bus-counter for detailed
233*4882a593Smuzhiyuninformation on each Generic Counter interface sysfs attribute.
234*4882a593Smuzhiyun
235*4882a593SmuzhiyunThrough these sysfs attributes, programs and scripts may interact with
236*4882a593Smuzhiyunthe Generic Counter paradigm Counts, Signals, and Synapses of respective
237*4882a593Smuzhiyuncounter devices.
238*4882a593Smuzhiyun
239*4882a593SmuzhiyunDriver API
240*4882a593Smuzhiyun==========
241*4882a593Smuzhiyun
242*4882a593SmuzhiyunDriver authors may utilize the Generic Counter interface in their code
243*4882a593Smuzhiyunby including the include/linux/counter.h header file. This header file
244*4882a593Smuzhiyunprovides several core data structures, function prototypes, and macros
245*4882a593Smuzhiyunfor defining a counter device.
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun.. kernel-doc:: include/linux/counter.h
248*4882a593Smuzhiyun   :internal:
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun.. kernel-doc:: drivers/counter/counter.c
251*4882a593Smuzhiyun   :export:
252*4882a593Smuzhiyun
253*4882a593SmuzhiyunImplementation
254*4882a593Smuzhiyun==============
255*4882a593Smuzhiyun
256*4882a593SmuzhiyunTo support a counter device, a driver must first allocate the available
257*4882a593SmuzhiyunCounter Signals via counter_signal structures. These Signals should
258*4882a593Smuzhiyunbe stored as an array and set to the signals array member of an
259*4882a593Smuzhiyunallocated counter_device structure before the Counter is registered to
260*4882a593Smuzhiyunthe system.
261*4882a593Smuzhiyun
262*4882a593SmuzhiyunCounter Counts may be allocated via counter_count structures, and
263*4882a593Smuzhiyunrespective Counter Signal associations (Synapses) made via
264*4882a593Smuzhiyuncounter_synapse structures. Associated counter_synapse structures are
265*4882a593Smuzhiyunstored as an array and set to the synapses array member of the
266*4882a593Smuzhiyunrespective counter_count structure. These counter_count structures are
267*4882a593Smuzhiyunset to the counts array member of an allocated counter_device structure
268*4882a593Smuzhiyunbefore the Counter is registered to the system.
269*4882a593Smuzhiyun
270*4882a593SmuzhiyunDriver callbacks should be provided to the counter_device structure via
271*4882a593Smuzhiyuna constant counter_ops structure in order to communicate with the
272*4882a593Smuzhiyundevice: to read and write various Signals and Counts, and to set and get
273*4882a593Smuzhiyunthe "action mode" and "function mode" for various Synapses and Counts
274*4882a593Smuzhiyunrespectively.
275*4882a593Smuzhiyun
276*4882a593SmuzhiyunA defined counter_device structure may be registered to the system by
277*4882a593Smuzhiyunpassing it to the counter_register function, and unregistered by passing
278*4882a593Smuzhiyunit to the counter_unregister function. Similarly, the
279*4882a593Smuzhiyundevm_counter_register and devm_counter_unregister functions may be used
280*4882a593Smuzhiyunif device memory-managed registration is desired.
281*4882a593Smuzhiyun
282*4882a593SmuzhiyunExtension sysfs attributes can be created for auxiliary functionality
283*4882a593Smuzhiyunand data by passing in defined counter_device_ext, counter_count_ext,
284*4882a593Smuzhiyunand counter_signal_ext structures. In these cases, the
285*4882a593Smuzhiyuncounter_device_ext structure is used for global/miscellaneous exposure
286*4882a593Smuzhiyunand configuration of the respective Counter device, while the
287*4882a593Smuzhiyuncounter_count_ext and counter_signal_ext structures allow for auxiliary
288*4882a593Smuzhiyunexposure and configuration of a specific Count or Signal respectively.
289*4882a593Smuzhiyun
290*4882a593SmuzhiyunDetermining the type of extension to create is a matter of scope.
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun* Signal extensions are attributes that expose information/control
293*4882a593Smuzhiyun  specific to a Signal. These types of attributes will exist under a
294*4882a593Smuzhiyun  Signal's directory in sysfs.
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun  For example, if you have an invert feature for a Signal, you can have
297*4882a593Smuzhiyun  a Signal extension called "invert" that toggles that feature:
298*4882a593Smuzhiyun  /sys/bus/counter/devices/counterX/signalY/invert
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun* Count extensions are attributes that expose information/control
301*4882a593Smuzhiyun  specific to a Count. These type of attributes will exist under a
302*4882a593Smuzhiyun  Count's directory in sysfs.
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun  For example, if you want to pause/unpause a Count from updating, you
305*4882a593Smuzhiyun  can have a Count extension called "enable" that toggles such:
306*4882a593Smuzhiyun  /sys/bus/counter/devices/counterX/countY/enable
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun* Device extensions are attributes that expose information/control
309*4882a593Smuzhiyun  non-specific to a particular Count or Signal. This is where you would
310*4882a593Smuzhiyun  put your global features or other miscellanous functionality.
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun  For example, if your device has an overtemp sensor, you can report the
313*4882a593Smuzhiyun  chip overheated via a device extension called "error_overtemp":
314*4882a593Smuzhiyun  /sys/bus/counter/devices/counterX/error_overtemp
315*4882a593Smuzhiyun
316*4882a593SmuzhiyunArchitecture
317*4882a593Smuzhiyun============
318*4882a593Smuzhiyun
319*4882a593SmuzhiyunWhen the Generic Counter interface counter module is loaded, the
320*4882a593Smuzhiyuncounter_init function is called which registers a bus_type named
321*4882a593Smuzhiyun"counter" to the system. Subsequently, when the module is unloaded, the
322*4882a593Smuzhiyuncounter_exit function is called which unregisters the bus_type named
323*4882a593Smuzhiyun"counter" from the system.
324*4882a593Smuzhiyun
325*4882a593SmuzhiyunCounter devices are registered to the system via the counter_register
326*4882a593Smuzhiyunfunction, and later removed via the counter_unregister function. The
327*4882a593Smuzhiyuncounter_register function establishes a unique ID for the Counter
328*4882a593Smuzhiyundevice and creates a respective sysfs directory, where X is the
329*4882a593Smuzhiyunmentioned unique ID:
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun    /sys/bus/counter/devices/counterX
332*4882a593Smuzhiyun
333*4882a593SmuzhiyunSysfs attributes are created within the counterX directory to expose
334*4882a593Smuzhiyunfunctionality, configurations, and data relating to the Counts, Signals,
335*4882a593Smuzhiyunand Synapses of the Counter device, as well as options and information
336*4882a593Smuzhiyunfor the Counter device itself.
337*4882a593Smuzhiyun
338*4882a593SmuzhiyunEach Signal has a directory created to house its relevant sysfs
339*4882a593Smuzhiyunattributes, where Y is the unique ID of the respective Signal:
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun    /sys/bus/counter/devices/counterX/signalY
342*4882a593Smuzhiyun
343*4882a593SmuzhiyunSimilarly, each Count has a directory created to house its relevant
344*4882a593Smuzhiyunsysfs attributes, where Y is the unique ID of the respective Count:
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun    /sys/bus/counter/devices/counterX/countY
347*4882a593Smuzhiyun
348*4882a593SmuzhiyunFor a more detailed breakdown of the available Generic Counter interface
349*4882a593Smuzhiyunsysfs attributes, please refer to the
350*4882a593SmuzhiyunDocumentation/ABI/testing/sysfs-bus-counter file.
351*4882a593Smuzhiyun
352*4882a593SmuzhiyunThe Signals and Counts associated with the Counter device are registered
353*4882a593Smuzhiyunto the system as well by the counter_register function. The
354*4882a593Smuzhiyunsignal_read/signal_write driver callbacks are associated with their
355*4882a593Smuzhiyunrespective Signal attributes, while the count_read/count_write and
356*4882a593Smuzhiyunfunction_get/function_set driver callbacks are associated with their
357*4882a593Smuzhiyunrespective Count attributes; similarly, the same is true for the
358*4882a593Smuzhiyunaction_get/action_set driver callbacks and their respective Synapse
359*4882a593Smuzhiyunattributes. If a driver callback is left undefined, then the respective
360*4882a593Smuzhiyunread/write permission is left disabled for the relevant attributes.
361*4882a593Smuzhiyun
362*4882a593SmuzhiyunSimilarly, extension sysfs attributes are created for the defined
363*4882a593Smuzhiyuncounter_device_ext, counter_count_ext, and counter_signal_ext
364*4882a593Smuzhiyunstructures that are passed in.
365