Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965405AbdIYSJf (ORCPT ); Mon, 25 Sep 2017 14:09:35 -0400 Received: from mail-yw0-f194.google.com ([209.85.161.194]:35469 "EHLO mail-yw0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934898AbdIYSJa (ORCPT ); Mon, 25 Sep 2017 14:09:30 -0400 X-Google-Smtp-Source: AOwi7QB7bdj6sMG85HJHRAFewNU/MjmHvy6hkW/Svcyfg9QfSEnFvR+rRzLu2/wq5Kz0UbrRZmJraw== From: William Breathitt Gray To: benjamin.gaignard@linaro.org, jic23@kernel.org, knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, William Breathitt Gray Subject: [PATCH v2 4/5] docs: Add IIO Generic Counter Interface documentation Date: Mon, 25 Sep 2017 14:09:21 -0400 Message-Id: <8f6eaae0c39104581d74ff1d1be3cd9a67c6718e.1506353914.git.vilhelm.gray@gmail.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 25846 Lines: 572 This patch adds top-level documentation about the IIO Generic Counter Interface. Signed-off-by: William Breathitt Gray --- 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