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