diff mbox

[v2,4/5] docs: Add IIO Generic Counter Interface documentation

Message ID 8f6eaae0c39104581d74ff1d1be3cd9a67c6718e.1506353914.git.vilhelm.gray@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

William Breathitt Gray Sept. 25, 2017, 6:09 p.m. UTC
This patch adds top-level documentation about the IIO Generic Counter

Signed-off-by: William Breathitt Gray <vilhelm.gray@gmail.com>
 Documentation/driver-api/iio/generic-counter.txt | 555 +++++++++++++++++++++++
 1 file changed, 555 insertions(+)
 create mode 100644 Documentation/driver-api/iio/generic-counter.txt
diff mbox


diff --git a/Documentation/driver-api/iio/generic-counter.txt b/Documentation/driver-api/iio/generic-counter.txt
new file mode 100644
index 000000000000..31cc5c369d22
--- /dev/null
+++ b/Documentation/driver-api/iio/generic-counter.txt
@@ -0,0 +1,555 @@ 
+Generic Counter Interface
+Counter devices are prevalent within a diverse spectrum of industries.
+The ubiquitous presence of these devices necessitates a common interface
+and standard of interaction and exposure. This driver API attempts to
+resolve the issue of duplicate code found among existing counter device
+drivers by introducing a generic counter interface for consumption. The
+generic counter interface enables drivers to support and expose a common
+set of components and functionality present in counter devices.
+Counter devices can vary greatly in design, but regardless of whether
+some devices are quadrature encoder counters or pedometers, all counter
+devices consist of a core set of components. This core set of
+components, shared by all counter devices, is what forms the essence of
+the generic counter interface.
+There are three core components to a counter:
+        VALUE
+        -----
+        A Value represents the count data for a set of Signals. A Value
+        has a count function mode (e.g. "increment" or "quadrature x4")
+        which respresents the update behavior for the count data. A
+        Value also has a set of one or more associated Signals.
+        SIGNAL
+        ------
+        A Signal represents a count input line. A Signal may be
+	associated to one or more Values.
+        TRIGGER
+	-------
+        A Trigger represents a Value's count function trigger condition
+        mode (e.g. "rising edge" or "double pulse") for an associated
+        Signal.	If a Signal is associated with a Value, a respective
+        Trigger	instance for that association exists -- albeit perhaps
+        with a trigger condition mode of "none."
+A counter is defined as a set of input signals associated to count data
+that are generated by the evaluation of the state of the associated
+input signals as defined by the respective count functions. Within the
+context of the generic counter interface, a counter consists of Values
+each associated to a set of Signals, whose respective Trigger instances
+represent the count function update conditions for the associated
+The most basic counter device may be expressed as a single Value
+associated with a single Signal via a single Trigger. Take for example
+a hypothetical counter device which simply accumulates a count of rising
+edges on a source input line.
+        Value                Trigger        Signal
+        -----                -------        ------
+| Data: Count         |    Rising Edge     ________
+| Function: Increment |  <-------------   / Source \
+|                     |                  ____________
+In this example, the Signal is a source input line with a pulsing
+voltage, while the Value is a persistent count which increments. The
+Signal is associated with the Value via a respective Trigger. The
+increment function is triggered by the condition specified by the
+Triggered -- in this case a rising edge condition. In summary, the
+counter device existence and behavior is aptly represented by respective
+Value, Signal, and Trigger components: a rising edge condition triggers
+an incrementation function on an accumulating count datum.
+A counter device is not limited to a single Signal; in fact, in theory
+an unlimited number of Signals may be associated with a Value. For
+example, a quadrature encoder counter device can keep track of position
+based on the states of two input lines.
+           Value                 Trigger      Signal
+           -----                 -------      ------
+| Data: Position          |    Both Edges      ___
+| Function: Quadrature x4 |  <-------------   / A \
+|                         |                  _______
+|                         |
+|                         |    Both Edges      ___
+|                         |  <-------------   / B \
+|                         |                  _______
+In this example, two Signals (quadrature encoder lines A and B) are
+associated to a single Value: a rising or falling edge on either A or B
+triggers the "Quadrature x4" function which determines the direction of
+movement and updates the respective position data. The "Quadrature x4"
+function is likely implemented in the hardware of the quadrature encoder
+counter device; the Value, Triggers, and Signals simply represent this
+hardware behavior and functionality.
+Signal associated to the same Value can have differing trigger
+conditions. For example, a quadrature encoder counter device operating
+in a non-quadrature mode could have one input line dedicated for
+movement and a second input line dedicated for direction.
+           Value                  Trigger      Signal
+           -----                  -------      ------
++------------------------- +
+| Data: Position           |    Rising Edge     ___
+| Function: Non-quadrature |  <-------------   / A \ (Movement)
+|                          |                  _______
+|                          |
+|                          |       None         ___
+|                          |  <-------------   / B \ (Direction)
+|                          |                  _______
+Only Signal A triggers the "Non-quadrature" update function, but the
+state of Signal B is still required in order to know the direction in
+order to properly update the position data. So in the end, both Signals
+are associated to the same Value via two respective Triggers, but only
+one Trigger has an active trigger condition while the other is left in a
+"None" condition mode to indicate its respective Signal's availability
+for state evaluation despite its non-triggering mode.
+Although the examples thus far have been representations of physical
+devices, this is not a necessity. A counter simply represent the
+evaluation (Value) of input data (Signals) triggered by specific
+conditions (Triggers). A counter can be the representation of more
+abstract components.
+For example, suppose a counter representation is desired for a DNA
+sequence analysizer which detects possible genetic diseases.
+        Value                     Trigger           Signal
+        -----                     -------           ------
+| Data: Diseases      |    Gene Transcript (EST)     _____
+| Function: Cancers   |  <-----------------------   / DNA \ (GAAGTGC...)
+|                     |                            _________
+In this scenario, the Signal is a stream of DNA nucleotide bases (As,
+Ts, Cs, and Gs), the Trigger is expressed sequence tags (ESTs), and the
+Value is a list of diseases discovered (in this case the function is
+evaluating for possible cancers). Note how the Signal in this example
+does not represent a physical voltage line, nor does the Trigger
+represent a physical voltage line state change, nor does the Value
+represent a strictly decimal data value.
+The DNA sequence analysizer example is contrived to illustrate the
+flexibility of the generic counter paradigm by demonstrating its
+capability of representing abstract concepts; however, physical devices
+are likely to be more fitting for such a representation.
+The key concept is that the Signal, Trigger, and Value are abstract
+representations which do not need to be closely married to their
+respective physical sources. This allows the user of a counter to
+divorce themselves from the nuances of physical components (such as
+whether an input line is differential or single-ended) and focus on the
+core idea of what the data and process represent (an accumulated count
+of rising edges).
+Userspace Interface
+Several sysfs attributes are generated by the generic counter interface,
+and reside under the /sys/bus/iio/devices/iio:deviceX directory.
+Each counter has a respective set of countX-Y and signalX-Y prefixed
+attributes, where X is the id set in the counter structure, and Y is the
+id of the respective Value or Signal.
+The generic counter interface sysfs attributes are as follows:
+        countX-Y_function: count function mode
+        countX-Y_function_available: available count function modes
+        countX-Y_name: Value name
+        countX-Y_raw: Value data
+        countX-Y_triggers: Value's associated Signals
+        countX-Y_trigger_signalX-Z: Value Y trigger mode for Signal Z
+        countX-Y_trigger_signalX-Z_available: available Value Y trigger
+                                              modes for Signal Z
+        signalX-Y_name: Signal name
+        signalX-Y_raw: Signal data
+Through these sysfs attributes, programs and scripts may interact with
+the generic counter paradigm Values, Triggers, and Signals of respective
+counter devices.
+Driver API
+Driver authors may utilize the generic counter interface in their code
+by including the include/linux/iio/counter.h header file. This header
+file provides several core data structures and function prototypes for
+defining a generic counter.
+struct iio_counter_signal
+This structure defines a generic counter paradigm Signal component;
+typically this will correlate with an input channel on a physical
+counter device. This structure is the simplest to define with only two
+structure members which require explicit configuration:
+        id:     Unique ID used to identify the Signal
+        name:   Device-specific Signal name (typically the device input
+                channel name)
+struct iio_counter_trigger
+This structure defines a generic counter paradigm Trigger component. To
+properly utilize this structure, trigger modes and an associated Signal
+must be defined:
+        mode:                   Index of the current trigger mode state
+        trigger_modes:          Array of trigger modes each represented
+	                        by a character string
+        num_trigger_modes:      Number of trigger modes provided in
+	                        trigger_modes array
+        signal:                 Pointer to associated Signal
+struct iio_counter_value
+This structure defines a generic counter paradigm Value component;
+typically this will correlate with the read data (the "count" value)
+provided by a physical counter device. This structure requires the
+explicit configuration of an ID, name, function modes (the function
+triggered on a Trigger condition), and optionally a set of initial
+associated Triggers:
+        id:                     Unique ID used to identify the Signal
+        name:                   Device-specific Value name (typically
+	                        the device read channel name)
+        mode:                   Index of the current function mode state
+        function_modes:         Array of function modes each represented
+	                        by a character string
+        num_function_modes:     Number of function modes provided in
+	                        function_modes array
+        init_triggers:          Array of initially associated Triggers
+        num_init_triggers:      Number of Triggers provided in
+	                        init_triggers array
+struct iio_counter_ops
+This structure defines callbacks to interact with the Value, Trigger,
+and Signal components:
+        signal_read:            Function to request a signal value from
+	                        the device. Return value will specify
+				the type of value returned by the
+				device. val and val2 will contain the
+				elements making up the returned value.
+				Note that the counter signal_list_lock
+				is acquired before this function is
+				called, and released after this function
+				returns.
+	signal_write:           Function to write a signal value to the
+	                        device. Parameters and locking behavior
+				are the same as signal_read.
+        trigger_mode_set:       Function to set the trigger mode. mode
+	                        is the index of the requested mode from
+				the value trigger_modes array. Note that
+				the counter value_list_lock and value
+				trigger_list_lock are acquired before
+				this function is called, and released
+				after this function returns.
+        trigger_mode_get:       Function to get the current trigger
+	                        mode. Return value will specify the
+				index of the current mode from the value
+				trigger_modes array. Locking behavior is
+				the same as trigger_mode_set.
+        value_read:             Function to request a value value from
+	                        the device. Return value will specify
+				the type of value returned by the
+				device. val and val2 will contain the
+				elements making up the returned value.
+				Note that the counter value_list_lock is
+				acquired before this function is called,
+				and released after this function
+				returns.
+        value_write:            Function to write a value value to the
+	                        device. Parameters and locking behavior
+				are the same as value_read.
+        value_function_set:     Function to set the value function mode.
+	                        mode is the index of the requested mode
+				from the value function_modes array.
+				Note that the counter value_list_lock is
+				acquired before this function is called,
+				and released after this function
+				returns.
+        value_function_get:     Function to get the current value
+	                        function mode. Return value will specify
+				the index of the current mode from the
+				value function_modes array. Locking
+				behavior is the same as
+				value_function_get.
+struct iio_counter
+This is the main data structure for a counter device; access to all
+respective Values, Triggers, and Signals is possible from this
+structure. This structure allows the configuration of an ID, name,
+function callbacks, initial Signals and initial Values, auxiliary IIO
+core channels and callbacks, and driver-specific data:
+        id:                     Unique ID used to identify the counter
+        name:                   Name of the counter device
+        dev:                    Device structure, which should be
+				assigned a parent and owner
+        ops:                    Function callbacks for counter
+	                        components (Signal, Trigger, Value)
+        init_signals:           Array of initial Signal
+        num_init_signals:       Number of Signals specified in
+	                        init_signals array
+        init_values:            Array of initial Values
+        num_init_values:        Number of Values specified in
+	                        init_values array
+        channels:               Optional IIO core channels specification
+	                        structure table
+        num_channels:           Number of channels specified in channels
+        info:                   IIO core function callbacks and constant
+	                        info from driver
+        driver_data:            Driver-specific data
+Registration functions
+Counters may be registered to the system via the iio_counter_register
+function (and subsequently unregistered via the iio_counter_unregister
+function). An initialized iio_counter structure, which defines the
+Counter, is required to be passed in for registration. Any initial
+Signals or initial Values, passed in via init_signals and init_values
+respectively, are registered as well to the system. If auxiliary IIO
+core channel and functionality are required, IIO core channels and
+callbacks may be passed in via the channels and info members of the
+passed-in iio_counter structure.
+After a Counter is registered, additional Triggers and Values may be
+registered and unregistered via the
+iio_counter_trigger_register/iio_counter_value_register and
+iio_counter_trigger_unregister/iio_counter_value_unregister functions
+respectively. Arrays of Triggers or Values may be registered and
+unregistered via the
+iio_counter_triggers_register/iio_counter_values_register and
+iio_counter_triggers_unregister/iio_counter_values_unregister functions
+Be aware that all Counter Signals are required to be registered at
+Counter registration via the init_signals array; no iio_counter_signal_*
+functions are yet available for driver consumption after Counter
+The IIO generic counter interface piggybacks off of the IIO core. This
+is primarily used to leverage the existing sysfs setup: the IIO_COUNT
+channel attributes represent the "counter value," while the IIO_SIGNAL
+channel attributes represent the "counter signal;" auxilary IIO_COUNT
+attributes represent the "counter signal" connections and their
+respective state change configurations which trigger an associated
+"counter function" evaluation.
+The iio_counter_ops structure serves as a container for driver callbacks
+to communicate with the device; function callbacks are provided to read
+and write various "counter signals" and "counter values," and set and
+get the "trigger mode" and "function mode" for various "counter signals"
+and "counter values" respectively.
+To support a counter device, a driver must first allocate the available
+"counter signals" via iio_counter_signal structures. These "counter
+signals" should be stored as an array and set to the init_signals member
+of an allocated iio_counter structure before the counter is registered.
+"Counter values" may be allocated via iio_counter_value structures, and
+respective "counter signal" associations made via iio_counter_trigger
+structures. Initial associated iio_counter_trigger structures may be
+stored as an array and set to the the init_triggers member of the
+respective iio_counter_value structure. These iio_counter_value
+structures may be set to the init_values member of an allocated
+iio_counter structure before the counter is registered if so desired.
+A counter device is registered to the system by passing the respective
+initialized iio_counter structure to the iio_counter_register function;
+similarly, the iio_counter_unregister function unregisters the
+respective counter.
+Although the IIO Generic Counter Interface utilizes IIO core under the
+hood, driver authors are not necessarily required to interact with IIO
+core data structures and functions directly -- in theory, such details
+of the system are abstracted away. Driver authors only need to concern
+themselves with the Generic Counter specific data structures and
+functions found in the include/linux/iio/counter.h header file.
+In other words, the driver API is intended to expose itself sufficiently
+upon the principles and concepts of the generic counter paradigm (i.e.
+Values, Triggers, Signals, etc.) such that it may be indepedent from its
+underlying implementation; theoretically, the IIO core code in the
+implementation could be replaced away in its entirely by an alternative
+implementation all without the need to update existing drivers utilizing
+the Generic Counter Interface driver API.
+This paradigm separation however does result in some mapping concerns
+between Generic Counter functions to IIO core functions; in particular,
+parameters for the IIO core functions expect IIO core data structures
+(e.g. iio_dev and iio_chan_spec) which are not provided directly by the
+parameters for the respective Generic Counter functions. This results in
+a somewhat opaque pathway from a iio_counter structure to its associated
+iio_dev in order to support the required IIO core calls.
+The following call graphs should help illustrate some of the main IIO
+core dependencies:
+| iio_counter_register |
+  |  |  |
+  |  |  +-----------------------------+
+  |  +------------------+             |
+  |                     |             |
+  V                     V             V
++------------------+  +----------+  +---------------------+
+| iio_device_alloc |  | iio_priv |  | iio_device_register |
++------------------+  +----------+  +---------------------+
+The iio_counter_register function allocates and initializes a new
+iio_dev structure which will serve as the respective Counter's gateway
+to IIO core support. A copy of the parent iio_counter structure is
+stored with the iio_dev structure via iio_priv in order to allow access
+back to the Counter from within the IIO core functions. Finally, the
+iio_dev structure is registered via iio_device_register.
++-----------------------+   +----------------------+
+| iio_read_channel_info |-->| iio_counter_read_raw |
++-----------------------+   +----------------------+
+                              |  |  |
+  +---------------------------+  |  |
+  |                +-------------+  |
+  |                |               ++
+  |                |               |
+  V                V               V
+  IIO_SIGNAL       IIO_COUNT       IIO_*
++-------------+  +------------+  +----------+
+| signal_read |  | value_read |  | read_raw |
++-------------+  +------------+  +----------+
++------------------------+   +-----------------------+
+| iio_write_channel_info |-->| iio_counter_write_raw |
++------------------------+   +-----------------------+
+                               |  |  |
+  +----------------------------+  |  |
+  |                 +-------------+  |
+  |                 |                |
+  |                 |                |
+  V                 V                V
+  IIO_SIGNAL        IIO_COUNT        IIO_*
++--------------+  +-------------+  +-----------+
+| signal_write |  | value_write |  | write_raw |
++--------------+  +-------------+  +-----------+
+Normally, the IIO core iio_read_channel_info and iio_write_channel_info
+functions respectiveluy call the driver-supplied read_raw and write_raw
+callbacks directly. Since the generic counter interface serves as an
+abstraction above IIO core, drive authors do not generally directly
+configure a read_raw/write_raw callback.
+Instead, the IIO Generic Counter Interface hooks on to the
+iio_read_channel_info and iio_write_channel_info expected read_raw and
+write_raw callbacks respectively via iio_counter_read_raw and
+iio_counter_write_raw. The iio_counter_read_raw and
+iio_counter_write_raw functions then call the respective driver-supplied
+signal_read/value_read and signal_write/value_write callbacks
+respectively for the appropriate IIO_SIGNAL OR IIO_COUNT. If an IIO core
+channel that was not part of the generic counter paradigm was supplied
+via the channels member of the iio_counter structure, then the
+respective driver-supplied (via the iio_counter structure info member)
+read_raw and write_raw are called.
++---------------------------+        +----------------------------+
+| iio_read_channel_ext_info |        | iio_write_channel_ext_info |
++---------------------------+        +----------------------------+
+  |                                    |
+  V                                    V
++-------------------------------+    +--------------------------------+
+| iio_counter_trigger_mode_read |    | iio_counter_trigger_mode_write |
++-------------------------------+    +--------------------------------+
+  |                                    |
+  V                                    V
++------------------+                 +------------------+
+| trigger_mode_get |                 | trigger_mode_set |
++------------------+                 +------------------+
++---------------+                     +----------------+
+| iio_enum_read |                     | iio_enum_write |
++---------------+                     +----------------+
+  |                                     |
+  V                                     V
++--------------------------------+    +--------------------------------+
+| iio_counter_value_function_get |    | iio_counter_value_function_set |
++--------------------------------+    +--------------------------------+
+  |                                     |
+  V                                     V
++--------------------+                +--------------------+
+| value_function_get |                | value_function_set |
++--------------------+                +--------------------+
+The driver-supplied trigger_mode_get and trigger_mode_set callbacks hook
+on to the iio_read_channel_ext_info and iio_write_channel_ext_info
+functions respectively via the iio_counter_trigger_mode_read and
+iio_counter_trigger_mode_write functions. Similarly, the driver-supplied
+value_function_get and value_function set callbacks hook on to the
+iio_enum_read and iio_enum_write functions respectively via the
+iio_counter_value_function_get and iio_counter_value_function set