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

From: William Breathitt Gray
Date: Mon Sep 25 2017 - 14:09:40 EST


This patch adds top-level documentation about the IIO Generic Counter
Interface.

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

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
+=========================
+
+Introduction
+============
+
+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.
+
+Theory
+======
+
+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
+Values.
+
+Paradigm
+========
+
+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
+respectively.
+
+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
+registration.
+
+Implementation
+==============
+
+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.
+
+Architecture
+============
+
+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
+functions.
--
2.14.1