mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
A slightly quieter cycle for documentation this time around.
Three more DocBook template files have been converted to RST; only 21 to go. There are various build improvements and the usual array of documentation improvements and fixes. -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJYriFXAAoJEI3ONVYwIuV6iTMP/iV7ownq9IK1f8askcXKM76i NoRdj4/JywAPQ73vLhOSDVELGdVJNRBjdyOdBRzxPgsqAhFmm79lVYV2eLIffQ2k 7LcVbEQR77I+4z9SwqIVbIWNCBry7Hu8aWh7moDL3I6yeuay408yr5YW2lIlsqHZ V/LZgkTWDe+iQPeXNA4Djzylx0lcRlAy4yMSLjN1+gb9/uBnXb9J0eGJzgfZfrL8 fiIhymg3bv8vB99l6LMR5vT343QLWXf1yS31A7rPQvwkDo6zFehUJA0XNfIsl2dw VQYsvl9vp9wy3e6Y0qKXPn1XhAhCrm64P3crBxK31MMvcKZVCfeRSZ78wrvpvewy MVLlXdqop1bHPHowtRfA5jwxr1NqcYp+Jg0+YGX3iXpPi1Jfk36DNUy9iWvtvIzr lWgQcIKsdCwwYUcvPR8Kt8T/3q/AHbYlI6mimWlkmbZwncQcgCrH5xSG+c2BIPfV fn3W6eLHBn8RyVsxlaXlA0Y9TNtI/Cm85b3Ri10pFvhl868ppWfJxXHi7UtcbU58 sQzahISCTXOH/NQwkkh7kFMtczbB43rAcChvF7EUYpazVBpJ4P4HxKFg3eIzIdc6 VlBSaMu1hxUGoYxNNYuKr/nYstuczLOKzK7q4j/JOExY3RgTWP+T3bF02wgubvoa D/9WfScewkgCJRoA7i17 =C5nd -----END PGP SIGNATURE----- Merge tag 'docs-4.11' of git://git.lwn.net/linux Pull documentation updates from Jonathan Corbet: "A slightly quieter cycle for documentation this time around. Three more DocBook template files have been converted to RST; only 21 to go. There are various build improvements and the usual array of documentation improvements and fixes" * tag 'docs-4.11' of git://git.lwn.net/linux: (44 commits) docs / driver-api: Fix structure references in device_link.rst PM / docs: Fix structure references in device.rst Add a target to check broken external links in the Documentation Documentation: Fix linux-api list typo Documentation: DocBook/Makefile comment typo Improve sparse documentation Documentation: make Makefile.sphinx no-ops quieter Documentation: DMA-ISA-LPC.txt Documentation: input: fix path to input code definitions docs: Remove the copyright year from conf.py docs: Fix a warning in the Korean HOWTO.rst translation PM / sleep / docs: Convert PM notifiers document to reST PM / core / docs: Convert sleep states API document to reST PM / core: Update kerneldoc comments in pm.h doc-rst: Fix recursive make invocation from macros doc-rst: Delete output of failed dot-SVG conversion doc-rst: Break shell command sequences on failure Documentation/sphinx: make targets independent of Sphinx work for HAVE_SPHINX=0 doc-rst: fixed cleandoc target when used with O=dir Documentation/sphinx: prevent generation of .pyc files in the source tree ...
This commit is contained in:
commit
c1aac62f36
56 changed files with 3288 additions and 3510 deletions
|
|
@ -13,7 +13,7 @@ DOCBOOKS := z8530book.xml \
|
|||
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
|
||||
genericirq.xml s390-drivers.xml scsi.xml \
|
||||
sh.xml regulator.xml w1.xml \
|
||||
writing_musb_glue_layer.xml iio.xml
|
||||
writing_musb_glue_layer.xml
|
||||
|
||||
ifeq ($(DOCBOOKS),)
|
||||
|
||||
|
|
@ -71,6 +71,7 @@ installmandocs: mandocs
|
|||
# no-op for the DocBook toolchain
|
||||
epubdocs:
|
||||
latexdocs:
|
||||
linkcheckdocs:
|
||||
|
||||
###
|
||||
#External programs used
|
||||
|
|
@ -272,6 +273,6 @@ cleandocs:
|
|||
$(Q)rm -rf $(call objectify, $(clean-dirs))
|
||||
|
||||
# Declare the contents of the .PHONY variable as phony. We keep that
|
||||
# information in a variable se we can use it in if_changed and friends.
|
||||
# information in a variable so we can use it in if_changed and friends.
|
||||
|
||||
.PHONY: $(PHONY)
|
||||
|
|
|
|||
|
|
@ -1,323 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
||||
|
||||
<book id="DoingIO">
|
||||
<bookinfo>
|
||||
<title>Bus-Independent Device Accesses</title>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Matthew</firstname>
|
||||
<surname>Wilcox</surname>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>[email protected]</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Alan</firstname>
|
||||
<surname>Cox</surname>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>[email protected]</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<copyright>
|
||||
<year>2001</year>
|
||||
<holder>Matthew Wilcox</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
This documentation is free software; you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
MA 02111-1307 USA
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For more details see the file COPYING in the source
|
||||
distribution of Linux.
|
||||
</para>
|
||||
</legalnotice>
|
||||
</bookinfo>
|
||||
|
||||
<toc></toc>
|
||||
|
||||
<chapter id="intro">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
Linux provides an API which abstracts performing IO across all busses
|
||||
and devices, allowing device drivers to be written independently of
|
||||
bus type.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="bugs">
|
||||
<title>Known Bugs And Assumptions</title>
|
||||
<para>
|
||||
None.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="mmio">
|
||||
<title>Memory Mapped IO</title>
|
||||
<sect1 id="getting_access_to_the_device">
|
||||
<title>Getting Access to the Device</title>
|
||||
<para>
|
||||
The most widely supported form of IO is memory mapped IO.
|
||||
That is, a part of the CPU's address space is interpreted
|
||||
not as accesses to memory, but as accesses to a device. Some
|
||||
architectures define devices to be at a fixed address, but most
|
||||
have some method of discovering devices. The PCI bus walk is a
|
||||
good example of such a scheme. This document does not cover how
|
||||
to receive such an address, but assumes you are starting with one.
|
||||
Physical addresses are of type unsigned long.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This address should not be used directly. Instead, to get an
|
||||
address suitable for passing to the accessor functions described
|
||||
below, you should call <function>ioremap</function>.
|
||||
An address suitable for accessing the device will be returned to you.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
After you've finished using the device (say, in your module's
|
||||
exit routine), call <function>iounmap</function> in order to return
|
||||
the address space to the kernel. Most architectures allocate new
|
||||
address space each time you call <function>ioremap</function>, and
|
||||
they can run out unless you call <function>iounmap</function>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="accessing_the_device">
|
||||
<title>Accessing the device</title>
|
||||
<para>
|
||||
The part of the interface most used by drivers is reading and
|
||||
writing memory-mapped registers on the device. Linux provides
|
||||
interfaces to read and write 8-bit, 16-bit, 32-bit and 64-bit
|
||||
quantities. Due to a historical accident, these are named byte,
|
||||
word, long and quad accesses. Both read and write accesses are
|
||||
supported; there is no prefetch support at this time.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The functions are named <function>readb</function>,
|
||||
<function>readw</function>, <function>readl</function>,
|
||||
<function>readq</function>, <function>readb_relaxed</function>,
|
||||
<function>readw_relaxed</function>, <function>readl_relaxed</function>,
|
||||
<function>readq_relaxed</function>, <function>writeb</function>,
|
||||
<function>writew</function>, <function>writel</function> and
|
||||
<function>writeq</function>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Some devices (such as framebuffers) would like to use larger
|
||||
transfers than 8 bytes at a time. For these devices, the
|
||||
<function>memcpy_toio</function>, <function>memcpy_fromio</function>
|
||||
and <function>memset_io</function> functions are provided.
|
||||
Do not use memset or memcpy on IO addresses; they
|
||||
are not guaranteed to copy data in order.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The read and write functions are defined to be ordered. That is the
|
||||
compiler is not permitted to reorder the I/O sequence. When the
|
||||
ordering can be compiler optimised, you can use <function>
|
||||
__readb</function> and friends to indicate the relaxed ordering. Use
|
||||
this with care.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
While the basic functions are defined to be synchronous with respect
|
||||
to each other and ordered with respect to each other the busses the
|
||||
devices sit on may themselves have asynchronicity. In particular many
|
||||
authors are burned by the fact that PCI bus writes are posted
|
||||
asynchronously. A driver author must issue a read from the same
|
||||
device to ensure that writes have occurred in the specific cases the
|
||||
author cares. This kind of property cannot be hidden from driver
|
||||
writers in the API. In some cases, the read used to flush the device
|
||||
may be expected to fail (if the card is resetting, for example). In
|
||||
that case, the read should be done from config space, which is
|
||||
guaranteed to soft-fail if the card doesn't respond.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following is an example of flushing a write to a device when
|
||||
the driver would like to ensure the write's effects are visible prior
|
||||
to continuing execution.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
static inline void
|
||||
qla1280_disable_intrs(struct scsi_qla_host *ha)
|
||||
{
|
||||
struct device_reg *reg;
|
||||
|
||||
reg = ha->iobase;
|
||||
/* disable risc and host interrupts */
|
||||
WRT_REG_WORD(&reg->ictrl, 0);
|
||||
/*
|
||||
* The following read will ensure that the above write
|
||||
* has been received by the device before we return from this
|
||||
* function.
|
||||
*/
|
||||
RD_REG_WORD(&reg->ictrl);
|
||||
ha->flags.ints_enabled = 0;
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
In addition to write posting, on some large multiprocessing systems
|
||||
(e.g. SGI Challenge, Origin and Altix machines) posted writes won't
|
||||
be strongly ordered coming from different CPUs. Thus it's important
|
||||
to properly protect parts of your driver that do memory-mapped writes
|
||||
with locks and use the <function>mmiowb</function> to make sure they
|
||||
arrive in the order intended. Issuing a regular <function>readX
|
||||
</function> will also ensure write ordering, but should only be used
|
||||
when the driver has to be sure that the write has actually arrived
|
||||
at the device (not that it's simply ordered with respect to other
|
||||
writes), since a full <function>readX</function> is a relatively
|
||||
expensive operation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Generally, one should use <function>mmiowb</function> prior to
|
||||
releasing a spinlock that protects regions using <function>writeb
|
||||
</function> or similar functions that aren't surrounded by <function>
|
||||
readb</function> calls, which will ensure ordering and flushing. The
|
||||
following pseudocode illustrates what might occur if write ordering
|
||||
isn't guaranteed via <function>mmiowb</function> or one of the
|
||||
<function>readX</function> functions.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
CPU A: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU A: ...
|
||||
CPU A: writel(newval, ring_ptr);
|
||||
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
...
|
||||
CPU B: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU B: writel(newval2, ring_ptr);
|
||||
CPU B: ...
|
||||
CPU B: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
In the case above, newval2 could be written to ring_ptr before
|
||||
newval. Fixing it is easy though:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
CPU A: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU A: ...
|
||||
CPU A: writel(newval, ring_ptr);
|
||||
CPU A: mmiowb(); /* ensure no other writes beat us to the device */
|
||||
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
...
|
||||
CPU B: spin_lock_irqsave(&dev_lock, flags)
|
||||
CPU B: writel(newval2, ring_ptr);
|
||||
CPU B: ...
|
||||
CPU B: mmiowb();
|
||||
CPU B: spin_unlock_irqrestore(&dev_lock, flags)
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
See tg3.c for a real world example of how to use <function>mmiowb
|
||||
</function>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
PCI ordering rules also guarantee that PIO read responses arrive
|
||||
after any outstanding DMA writes from that bus, since for some devices
|
||||
the result of a <function>readb</function> call may signal to the
|
||||
driver that a DMA transaction is complete. In many cases, however,
|
||||
the driver may want to indicate that the next
|
||||
<function>readb</function> call has no relation to any previous DMA
|
||||
writes performed by the device. The driver can use
|
||||
<function>readb_relaxed</function> for these cases, although only
|
||||
some platforms will honor the relaxed semantics. Using the relaxed
|
||||
read functions will provide significant performance benefits on
|
||||
platforms that support it. The qla2xxx driver provides examples
|
||||
of how to use <function>readX_relaxed</function>. In many cases,
|
||||
a majority of the driver's <function>readX</function> calls can
|
||||
safely be converted to <function>readX_relaxed</function> calls, since
|
||||
only a few will indicate or depend on DMA completion.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter id="port_space_accesses">
|
||||
<title>Port Space Accesses</title>
|
||||
<sect1 id="port_space_explained">
|
||||
<title>Port Space Explained</title>
|
||||
|
||||
<para>
|
||||
Another form of IO commonly supported is Port Space. This is a
|
||||
range of addresses separate to the normal memory address space.
|
||||
Access to these addresses is generally not as fast as accesses
|
||||
to the memory mapped addresses, and it also has a potentially
|
||||
smaller address space.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Unlike memory mapped IO, no preparation is required
|
||||
to access port space.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
<sect1 id="accessing_port_space">
|
||||
<title>Accessing Port Space</title>
|
||||
<para>
|
||||
Accesses to this space are provided through a set of functions
|
||||
which allow 8-bit, 16-bit and 32-bit accesses; also
|
||||
known as byte, word and long. These functions are
|
||||
<function>inb</function>, <function>inw</function>,
|
||||
<function>inl</function>, <function>outb</function>,
|
||||
<function>outw</function> and <function>outl</function>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Some variants are provided for these functions. Some devices
|
||||
require that accesses to their ports are slowed down. This
|
||||
functionality is provided by appending a <function>_p</function>
|
||||
to the end of the function. There are also equivalents to memcpy.
|
||||
The <function>ins</function> and <function>outs</function>
|
||||
functions copy bytes, words or longs to the given port.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter id="pubfunctions">
|
||||
<title>Public Functions Provided</title>
|
||||
!Iarch/x86/include/asm/io.h
|
||||
!Elib/pci_iomap.c
|
||||
</chapter>
|
||||
|
||||
</book>
|
||||
|
|
@ -1,697 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
||||
|
||||
<book id="iioid">
|
||||
<bookinfo>
|
||||
<title>Industrial I/O driver developer's guide </title>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Daniel</firstname>
|
||||
<surname>Baluta</surname>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>[email protected]</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<copyright>
|
||||
<year>2015</year>
|
||||
<holder>Intel Corporation</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
This documentation is free software; you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public
|
||||
License version 2.
|
||||
</para>
|
||||
</legalnotice>
|
||||
</bookinfo>
|
||||
|
||||
<toc></toc>
|
||||
|
||||
<chapter id="intro">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
The main purpose of the Industrial I/O subsystem (IIO) is to provide
|
||||
support for devices that in some sense perform either analog-to-digital
|
||||
conversion (ADC) or digital-to-analog conversion (DAC) or both. The aim
|
||||
is to fill the gap between the somewhat similar hwmon and input
|
||||
subsystems.
|
||||
Hwmon is directed at low sample rate sensors used to monitor and
|
||||
control the system itself, like fan speed control or temperature
|
||||
measurement. Input is, as its name suggests, focused on human interaction
|
||||
input devices (keyboard, mouse, touchscreen). In some cases there is
|
||||
considerable overlap between these and IIO.
|
||||
</para>
|
||||
<para>
|
||||
Devices that fall into this category include:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
analog to digital converters (ADCs)
|
||||
</listitem>
|
||||
<listitem>
|
||||
accelerometers
|
||||
</listitem>
|
||||
<listitem>
|
||||
capacitance to digital converters (CDCs)
|
||||
</listitem>
|
||||
<listitem>
|
||||
digital to analog converters (DACs)
|
||||
</listitem>
|
||||
<listitem>
|
||||
gyroscopes
|
||||
</listitem>
|
||||
<listitem>
|
||||
inertial measurement units (IMUs)
|
||||
</listitem>
|
||||
<listitem>
|
||||
color and light sensors
|
||||
</listitem>
|
||||
<listitem>
|
||||
magnetometers
|
||||
</listitem>
|
||||
<listitem>
|
||||
pressure sensors
|
||||
</listitem>
|
||||
<listitem>
|
||||
proximity sensors
|
||||
</listitem>
|
||||
<listitem>
|
||||
temperature sensors
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
Usually these sensors are connected via SPI or I2C. A common use case of the
|
||||
sensors devices is to have combined functionality (e.g. light plus proximity
|
||||
sensor).
|
||||
</para>
|
||||
</chapter>
|
||||
<chapter id='iiosubsys'>
|
||||
<title>Industrial I/O core</title>
|
||||
<para>
|
||||
The Industrial I/O core offers:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
a unified framework for writing drivers for many different types of
|
||||
embedded sensors.
|
||||
</listitem>
|
||||
<listitem>
|
||||
a standard interface to user space applications manipulating sensors.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
The implementation can be found under <filename>
|
||||
drivers/iio/industrialio-*</filename>
|
||||
</para>
|
||||
<sect1 id="iiodevice">
|
||||
<title> Industrial I/O devices </title>
|
||||
|
||||
!Finclude/linux/iio/iio.h iio_dev
|
||||
!Fdrivers/iio/industrialio-core.c iio_device_alloc
|
||||
!Fdrivers/iio/industrialio-core.c iio_device_free
|
||||
!Fdrivers/iio/industrialio-core.c iio_device_register
|
||||
!Fdrivers/iio/industrialio-core.c iio_device_unregister
|
||||
|
||||
<para>
|
||||
An IIO device usually corresponds to a single hardware sensor and it
|
||||
provides all the information needed by a driver handling a device.
|
||||
Let's first have a look at the functionality embedded in an IIO
|
||||
device then we will show how a device driver makes use of an IIO
|
||||
device.
|
||||
</para>
|
||||
<para>
|
||||
There are two ways for a user space application to interact
|
||||
with an IIO driver.
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<filename>/sys/bus/iio/iio:deviceX/</filename>, this
|
||||
represents a hardware sensor and groups together the data
|
||||
channels of the same chip.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<filename>/dev/iio:deviceX</filename>, character device node
|
||||
interface used for buffered data transfer and for events information
|
||||
retrieval.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
A typical IIO driver will register itself as an I2C or SPI driver and will
|
||||
create two routines, <function> probe </function> and <function> remove
|
||||
</function>. At <function>probe</function>:
|
||||
<itemizedlist>
|
||||
<listitem>call <function>iio_device_alloc</function>, which allocates memory
|
||||
for an IIO device.
|
||||
</listitem>
|
||||
<listitem> initialize IIO device fields with driver specific information
|
||||
(e.g. device name, device channels).
|
||||
</listitem>
|
||||
<listitem>call <function> iio_device_register</function>, this registers the
|
||||
device with the IIO core. After this call the device is ready to accept
|
||||
requests from user space applications.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
At <function>remove</function>, we free the resources allocated in
|
||||
<function>probe</function> in reverse order:
|
||||
<itemizedlist>
|
||||
<listitem><function>iio_device_unregister</function>, unregister the device
|
||||
from the IIO core.
|
||||
</listitem>
|
||||
<listitem><function>iio_device_free</function>, free the memory allocated
|
||||
for the IIO device.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<sect2 id="iioattr"> <title> IIO device sysfs interface </title>
|
||||
<para>
|
||||
Attributes are sysfs files used to expose chip info and also allowing
|
||||
applications to set various configuration parameters. For device
|
||||
with index X, attributes can be found under
|
||||
<filename>/sys/bus/iio/iio:deviceX/ </filename> directory.
|
||||
Common attributes are:
|
||||
<itemizedlist>
|
||||
<listitem><filename>name</filename>, description of the physical
|
||||
chip.
|
||||
</listitem>
|
||||
<listitem><filename>dev</filename>, shows the major:minor pair
|
||||
associated with <filename>/dev/iio:deviceX</filename> node.
|
||||
</listitem>
|
||||
<listitem><filename>sampling_frequency_available</filename>,
|
||||
available discrete set of sampling frequency values for
|
||||
device.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
Available standard attributes for IIO devices are described in the
|
||||
<filename>Documentation/ABI/testing/sysfs-bus-iio </filename> file
|
||||
in the Linux kernel sources.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="iiochannel"> <title> IIO device channels </title>
|
||||
!Finclude/linux/iio/iio.h iio_chan_spec structure.
|
||||
<para>
|
||||
An IIO device channel is a representation of a data channel. An
|
||||
IIO device can have one or multiple channels. For example:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
a thermometer sensor has one channel representing the
|
||||
temperature measurement.
|
||||
</listitem>
|
||||
<listitem>
|
||||
a light sensor with two channels indicating the measurements in
|
||||
the visible and infrared spectrum.
|
||||
</listitem>
|
||||
<listitem>
|
||||
an accelerometer can have up to 3 channels representing
|
||||
acceleration on X, Y and Z axes.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
An IIO channel is described by the <type> struct iio_chan_spec
|
||||
</type>. A thermometer driver for the temperature sensor in the
|
||||
example above would have to describe its channel as follows:
|
||||
<programlisting>
|
||||
static const struct iio_chan_spec temp_channel[] = {
|
||||
{
|
||||
.type = IIO_TEMP,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
|
||||
},
|
||||
};
|
||||
|
||||
</programlisting>
|
||||
Channel sysfs attributes exposed to userspace are specified in
|
||||
the form of <emphasis>bitmasks</emphasis>. Depending on their
|
||||
shared info, attributes can be set in one of the following masks:
|
||||
<itemizedlist>
|
||||
<listitem><emphasis>info_mask_separate</emphasis>, attributes will
|
||||
be specific to this channel</listitem>
|
||||
<listitem><emphasis>info_mask_shared_by_type</emphasis>,
|
||||
attributes are shared by all channels of the same type</listitem>
|
||||
<listitem><emphasis>info_mask_shared_by_dir</emphasis>, attributes
|
||||
are shared by all channels of the same direction </listitem>
|
||||
<listitem><emphasis>info_mask_shared_by_all</emphasis>,
|
||||
attributes are shared by all channels</listitem>
|
||||
</itemizedlist>
|
||||
When there are multiple data channels per channel type we have two
|
||||
ways to distinguish between them:
|
||||
<itemizedlist>
|
||||
<listitem> set <emphasis> .modified</emphasis> field of <type>
|
||||
iio_chan_spec</type> to 1. Modifiers are specified using
|
||||
<emphasis>.channel2</emphasis> field of the same
|
||||
<type>iio_chan_spec</type> structure and are used to indicate a
|
||||
physically unique characteristic of the channel such as its direction
|
||||
or spectral response. For example, a light sensor can have two channels,
|
||||
one for infrared light and one for both infrared and visible light.
|
||||
</listitem>
|
||||
<listitem> set <emphasis>.indexed </emphasis> field of
|
||||
<type>iio_chan_spec</type> to 1. In this case the channel is
|
||||
simply another instance with an index specified by the
|
||||
<emphasis>.channel</emphasis> field.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
Here is how we can make use of the channel's modifiers:
|
||||
<programlisting>
|
||||
static const struct iio_chan_spec light_channels[] = {
|
||||
{
|
||||
.type = IIO_INTENSITY,
|
||||
.modified = 1,
|
||||
.channel2 = IIO_MOD_LIGHT_IR,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||
.info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||
},
|
||||
{
|
||||
.type = IIO_INTENSITY,
|
||||
.modified = 1,
|
||||
.channel2 = IIO_MOD_LIGHT_BOTH,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||
.info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||
},
|
||||
{
|
||||
.type = IIO_LIGHT,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
|
||||
.info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||
},
|
||||
|
||||
}
|
||||
</programlisting>
|
||||
This channel's definition will generate two separate sysfs files
|
||||
for raw data retrieval:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<filename>/sys/bus/iio/iio:deviceX/in_intensity_ir_raw</filename>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<filename>/sys/bus/iio/iio:deviceX/in_intensity_both_raw</filename>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
one file for processed data:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<filename>/sys/bus/iio/iio:deviceX/in_illuminance_input
|
||||
</filename>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
and one shared sysfs file for sampling frequency:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<filename>/sys/bus/iio/iio:deviceX/sampling_frequency.
|
||||
</filename>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
Here is how we can make use of the channel's indexing:
|
||||
<programlisting>
|
||||
static const struct iio_chan_spec light_channels[] = {
|
||||
{
|
||||
.type = IIO_VOLTAGE,
|
||||
.indexed = 1,
|
||||
.channel = 0,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||
},
|
||||
{
|
||||
.type = IIO_VOLTAGE,
|
||||
.indexed = 1,
|
||||
.channel = 1,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||
},
|
||||
}
|
||||
</programlisting>
|
||||
This will generate two separate attributes files for raw data
|
||||
retrieval:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<filename>/sys/bus/iio/devices/iio:deviceX/in_voltage0_raw</filename>,
|
||||
representing voltage measurement for channel 0.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<filename>/sys/bus/iio/devices/iio:deviceX/in_voltage1_raw</filename>,
|
||||
representing voltage measurement for channel 1.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="iiobuffer"> <title> Industrial I/O buffers </title>
|
||||
!Finclude/linux/iio/buffer.h iio_buffer
|
||||
!Edrivers/iio/industrialio-buffer.c
|
||||
|
||||
<para>
|
||||
The Industrial I/O core offers a way for continuous data capture
|
||||
based on a trigger source. Multiple data channels can be read at once
|
||||
from <filename>/dev/iio:deviceX</filename> character device node,
|
||||
thus reducing the CPU load.
|
||||
</para>
|
||||
|
||||
<sect2 id="iiobuffersysfs">
|
||||
<title>IIO buffer sysfs interface </title>
|
||||
<para>
|
||||
An IIO buffer has an associated attributes directory under <filename>
|
||||
/sys/bus/iio/iio:deviceX/buffer/</filename>. Here are the existing
|
||||
attributes:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<emphasis>length</emphasis>, the total number of data samples
|
||||
(capacity) that can be stored by the buffer.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<emphasis>enable</emphasis>, activate buffer capture.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="iiobuffersetup"> <title> IIO buffer setup </title>
|
||||
<para>The meta information associated with a channel reading
|
||||
placed in a buffer is called a <emphasis> scan element </emphasis>.
|
||||
The important bits configuring scan elements are exposed to
|
||||
userspace applications via the <filename>
|
||||
/sys/bus/iio/iio:deviceX/scan_elements/</filename> directory. This
|
||||
file contains attributes of the following form:
|
||||
<itemizedlist>
|
||||
<listitem><emphasis>enable</emphasis>, used for enabling a channel.
|
||||
If and only if its attribute is non zero, then a triggered capture
|
||||
will contain data samples for this channel.
|
||||
</listitem>
|
||||
<listitem><emphasis>type</emphasis>, description of the scan element
|
||||
data storage within the buffer and hence the form in which it is
|
||||
read from user space. Format is <emphasis>
|
||||
[be|le]:[s|u]bits/storagebitsXrepeat[>>shift] </emphasis>.
|
||||
<itemizedlist>
|
||||
<listitem> <emphasis>be</emphasis> or <emphasis>le</emphasis>, specifies
|
||||
big or little endian.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<emphasis>s </emphasis>or <emphasis>u</emphasis>, specifies if
|
||||
signed (2's complement) or unsigned.
|
||||
</listitem>
|
||||
<listitem><emphasis>bits</emphasis>, is the number of valid data
|
||||
bits.
|
||||
</listitem>
|
||||
<listitem><emphasis>storagebits</emphasis>, is the number of bits
|
||||
(after padding) that it occupies in the buffer.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<emphasis>shift</emphasis>, if specified, is the shift that needs
|
||||
to be applied prior to masking out unused bits.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<emphasis>repeat</emphasis>, specifies the number of bits/storagebits
|
||||
repetitions. When the repeat element is 0 or 1, then the repeat
|
||||
value is omitted.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
For example, a driver for a 3-axis accelerometer with 12 bit
|
||||
resolution where data is stored in two 8-bits registers as
|
||||
follows:
|
||||
<programlisting>
|
||||
7 6 5 4 3 2 1 0
|
||||
+---+---+---+---+---+---+---+---+
|
||||
|D3 |D2 |D1 |D0 | X | X | X | X | (LOW byte, address 0x06)
|
||||
+---+---+---+---+---+---+---+---+
|
||||
|
||||
7 6 5 4 3 2 1 0
|
||||
+---+---+---+---+---+---+---+---+
|
||||
|D11|D10|D9 |D8 |D7 |D6 |D5 |D4 | (HIGH byte, address 0x07)
|
||||
+---+---+---+---+---+---+---+---+
|
||||
</programlisting>
|
||||
|
||||
will have the following scan element type for each axis:
|
||||
<programlisting>
|
||||
$ cat /sys/bus/iio/devices/iio:device0/scan_elements/in_accel_y_type
|
||||
le:s12/16>>4
|
||||
</programlisting>
|
||||
A user space application will interpret data samples read from the
|
||||
buffer as two byte little endian signed data, that needs a 4 bits
|
||||
right shift before masking out the 12 valid bits of data.
|
||||
</para>
|
||||
<para>
|
||||
For implementing buffer support a driver should initialize the following
|
||||
fields in <type>iio_chan_spec</type> definition:
|
||||
<programlisting>
|
||||
struct iio_chan_spec {
|
||||
/* other members */
|
||||
int scan_index
|
||||
struct {
|
||||
char sign;
|
||||
u8 realbits;
|
||||
u8 storagebits;
|
||||
u8 shift;
|
||||
u8 repeat;
|
||||
enum iio_endian endianness;
|
||||
} scan_type;
|
||||
};
|
||||
</programlisting>
|
||||
The driver implementing the accelerometer described above will
|
||||
have the following channel definition:
|
||||
<programlisting>
|
||||
struct struct iio_chan_spec accel_channels[] = {
|
||||
{
|
||||
.type = IIO_ACCEL,
|
||||
.modified = 1,
|
||||
.channel2 = IIO_MOD_X,
|
||||
/* other stuff here */
|
||||
.scan_index = 0,
|
||||
.scan_type = {
|
||||
.sign = 's',
|
||||
.realbits = 12,
|
||||
.storagebits = 16,
|
||||
.shift = 4,
|
||||
.endianness = IIO_LE,
|
||||
},
|
||||
}
|
||||
/* similar for Y (with channel2 = IIO_MOD_Y, scan_index = 1)
|
||||
* and Z (with channel2 = IIO_MOD_Z, scan_index = 2) axis
|
||||
*/
|
||||
}
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Here <emphasis> scan_index </emphasis> defines the order in which
|
||||
the enabled channels are placed inside the buffer. Channels with a lower
|
||||
scan_index will be placed before channels with a higher index. Each
|
||||
channel needs to have a unique scan_index.
|
||||
</para>
|
||||
<para>
|
||||
Setting scan_index to -1 can be used to indicate that the specific
|
||||
channel does not support buffered capture. In this case no entries will
|
||||
be created for the channel in the scan_elements directory.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="iiotrigger"> <title> Industrial I/O triggers </title>
|
||||
!Finclude/linux/iio/trigger.h iio_trigger
|
||||
!Edrivers/iio/industrialio-trigger.c
|
||||
<para>
|
||||
In many situations it is useful for a driver to be able to
|
||||
capture data based on some external event (trigger) as opposed
|
||||
to periodically polling for data. An IIO trigger can be provided
|
||||
by a device driver that also has an IIO device based on hardware
|
||||
generated events (e.g. data ready or threshold exceeded) or
|
||||
provided by a separate driver from an independent interrupt
|
||||
source (e.g. GPIO line connected to some external system, timer
|
||||
interrupt or user space writing a specific file in sysfs). A
|
||||
trigger may initiate data capture for a number of sensors and
|
||||
also it may be completely unrelated to the sensor itself.
|
||||
</para>
|
||||
|
||||
<sect2 id="iiotrigsysfs"> <title> IIO trigger sysfs interface </title>
|
||||
There are two locations in sysfs related to triggers:
|
||||
<itemizedlist>
|
||||
<listitem><filename>/sys/bus/iio/devices/triggerY</filename>,
|
||||
this file is created once an IIO trigger is registered with
|
||||
the IIO core and corresponds to trigger with index Y. Because
|
||||
triggers can be very different depending on type there are few
|
||||
standard attributes that we can describe here:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<emphasis>name</emphasis>, trigger name that can be later
|
||||
used for association with a device.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<emphasis>sampling_frequency</emphasis>, some timer based
|
||||
triggers use this attribute to specify the frequency for
|
||||
trigger calls.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<filename>/sys/bus/iio/devices/iio:deviceX/trigger/</filename>, this
|
||||
directory is created once the device supports a triggered
|
||||
buffer. We can associate a trigger with our device by writing
|
||||
the trigger's name in the <filename>current_trigger</filename> file.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="iiotrigattr"> <title> IIO trigger setup</title>
|
||||
|
||||
<para>
|
||||
Let's see a simple example of how to setup a trigger to be used
|
||||
by a driver.
|
||||
|
||||
<programlisting>
|
||||
struct iio_trigger_ops trigger_ops = {
|
||||
.set_trigger_state = sample_trigger_state,
|
||||
.validate_device = sample_validate_device,
|
||||
}
|
||||
|
||||
struct iio_trigger *trig;
|
||||
|
||||
/* first, allocate memory for our trigger */
|
||||
trig = iio_trigger_alloc(dev, "trig-%s-%d", name, idx);
|
||||
|
||||
/* setup trigger operations field */
|
||||
trig->ops = &trigger_ops;
|
||||
|
||||
/* now register the trigger with the IIO core */
|
||||
iio_trigger_register(trig);
|
||||
</programlisting>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="iiotrigsetup"> <title> IIO trigger ops</title>
|
||||
!Finclude/linux/iio/trigger.h iio_trigger_ops
|
||||
<para>
|
||||
Notice that a trigger has a set of operations attached:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<function>set_trigger_state</function>, switch the trigger on/off
|
||||
on demand.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<function>validate_device</function>, function to validate the
|
||||
device when the current trigger gets changed.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="iiotriggered_buffer">
|
||||
<title> Industrial I/O triggered buffers </title>
|
||||
<para>
|
||||
Now that we know what buffers and triggers are let's see how they
|
||||
work together.
|
||||
</para>
|
||||
<sect2 id="iiotrigbufsetup"> <title> IIO triggered buffer setup</title>
|
||||
!Edrivers/iio/buffer/industrialio-triggered-buffer.c
|
||||
!Finclude/linux/iio/iio.h iio_buffer_setup_ops
|
||||
|
||||
|
||||
<para>
|
||||
A typical triggered buffer setup looks like this:
|
||||
<programlisting>
|
||||
const struct iio_buffer_setup_ops sensor_buffer_setup_ops = {
|
||||
.preenable = sensor_buffer_preenable,
|
||||
.postenable = sensor_buffer_postenable,
|
||||
.postdisable = sensor_buffer_postdisable,
|
||||
.predisable = sensor_buffer_predisable,
|
||||
};
|
||||
|
||||
irqreturn_t sensor_iio_pollfunc(int irq, void *p)
|
||||
{
|
||||
pf->timestamp = iio_get_time_ns((struct indio_dev *)p);
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
irqreturn_t sensor_trigger_handler(int irq, void *p)
|
||||
{
|
||||
u16 buf[8];
|
||||
int i = 0;
|
||||
|
||||
/* read data for each active channel */
|
||||
for_each_set_bit(bit, active_scan_mask, masklength)
|
||||
buf[i++] = sensor_get_data(bit)
|
||||
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, buf, timestamp);
|
||||
|
||||
iio_trigger_notify_done(trigger);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* setup triggered buffer, usually in probe function */
|
||||
iio_triggered_buffer_setup(indio_dev, sensor_iio_polfunc,
|
||||
sensor_trigger_handler,
|
||||
sensor_buffer_setup_ops);
|
||||
</programlisting>
|
||||
</para>
|
||||
The important things to notice here are:
|
||||
<itemizedlist>
|
||||
<listitem><function> iio_buffer_setup_ops</function>, the buffer setup
|
||||
functions to be called at predefined points in the buffer configuration
|
||||
sequence (e.g. before enable, after disable). If not specified, the
|
||||
IIO core uses the default <type>iio_triggered_buffer_setup_ops</type>.
|
||||
</listitem>
|
||||
<listitem><function>sensor_iio_pollfunc</function>, the function that
|
||||
will be used as top half of poll function. It should do as little
|
||||
processing as possible, because it runs in interrupt context. The most
|
||||
common operation is recording of the current timestamp and for this reason
|
||||
one can use the IIO core defined <function>iio_pollfunc_store_time
|
||||
</function> function.
|
||||
</listitem>
|
||||
<listitem><function>sensor_trigger_handler</function>, the function that
|
||||
will be used as bottom half of the poll function. This runs in the
|
||||
context of a kernel thread and all the processing takes place here.
|
||||
It usually reads data from the device and stores it in the internal
|
||||
buffer together with the timestamp recorded in the top half.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
<chapter id='iioresources'>
|
||||
<title> Resources </title>
|
||||
IIO core may change during time so the best documentation to read is the
|
||||
source code. There are several locations where you should look:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<filename>drivers/iio/</filename>, contains the IIO core plus
|
||||
and directories for each sensor type (e.g. accel, magnetometer,
|
||||
etc.)
|
||||
</listitem>
|
||||
<listitem>
|
||||
<filename>include/linux/iio/</filename>, contains the header
|
||||
files, nice to read for the internal kernel interfaces.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<filename>include/uapi/linux/iio/</filename>, contains files to be
|
||||
used by user space applications.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<filename>tools/iio/</filename>, contains tools for rapidly
|
||||
testing buffers, events and device creation.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<filename>drivers/staging/iio/</filename>, contains code for some
|
||||
drivers or experimental features that are not yet mature enough
|
||||
to be moved out.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
Besides the code, there are some good online documentation sources:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="http://marc.info/?l=linux-iio"> Industrial I/O mailing
|
||||
list </ulink>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<ulink url="http://wiki.analog.com/software/linux/docs/iio/iio">
|
||||
Analog Device IIO wiki page </ulink>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<ulink url="https://fosdem.org/2015/schedule/event/iiosdr/">
|
||||
Using the Linux IIO framework for SDR, Lars-Peter Clausen's
|
||||
presentation at FOSDEM </ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</chapter>
|
||||
</book>
|
||||
|
||||
<!--
|
||||
vim: softtabstop=2:shiftwidth=2:expandtab:textwidth=72
|
||||
-->
|
||||
|
|
@ -1,304 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
||||
|
||||
<book id="regulator-api">
|
||||
<bookinfo>
|
||||
<title>Voltage and current regulator API</title>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Liam</firstname>
|
||||
<surname>Girdwood</surname>
|
||||
<affiliation>
|
||||
<address>
|
||||
<email>[email protected]</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Mark</firstname>
|
||||
<surname>Brown</surname>
|
||||
<affiliation>
|
||||
<orgname>Wolfson Microelectronics</orgname>
|
||||
<address>
|
||||
<email>[email protected]</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<copyright>
|
||||
<year>2007-2008</year>
|
||||
<holder>Wolfson Microelectronics</holder>
|
||||
</copyright>
|
||||
<copyright>
|
||||
<year>2008</year>
|
||||
<holder>Liam Girdwood</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
This documentation is free software; you can redistribute
|
||||
it and/or modify it under the terms of the GNU General Public
|
||||
License version 2 as published by the Free Software Foundation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
MA 02111-1307 USA
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For more details see the file COPYING in the source
|
||||
distribution of Linux.
|
||||
</para>
|
||||
</legalnotice>
|
||||
</bookinfo>
|
||||
|
||||
<toc></toc>
|
||||
|
||||
<chapter id="intro">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
This framework is designed to provide a standard kernel
|
||||
interface to control voltage and current regulators.
|
||||
</para>
|
||||
<para>
|
||||
The intention is to allow systems to dynamically control
|
||||
regulator power output in order to save power and prolong
|
||||
battery life. This applies to both voltage regulators (where
|
||||
voltage output is controllable) and current sinks (where current
|
||||
limit is controllable).
|
||||
</para>
|
||||
<para>
|
||||
Note that additional (and currently more complete) documentation
|
||||
is available in the Linux kernel source under
|
||||
<filename>Documentation/power/regulator</filename>.
|
||||
</para>
|
||||
|
||||
<sect1 id="glossary">
|
||||
<title>Glossary</title>
|
||||
<para>
|
||||
The regulator API uses a number of terms which may not be
|
||||
familiar:
|
||||
</para>
|
||||
<glossary>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Regulator</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
Electronic device that supplies power to other devices. Most
|
||||
regulators can enable and disable their output and some can also
|
||||
control their output voltage or current.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Consumer</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
Electronic device which consumes power provided by a regulator.
|
||||
These may either be static, requiring only a fixed supply, or
|
||||
dynamic, requiring active management of the regulator at
|
||||
runtime.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Power Domain</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
The electronic circuit supplied by a given regulator, including
|
||||
the regulator and all consumer devices. The configuration of
|
||||
the regulator is shared between all the components in the
|
||||
circuit.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Power Management Integrated Circuit</glossterm>
|
||||
<acronym>PMIC</acronym>
|
||||
<glossdef>
|
||||
<para>
|
||||
An IC which contains numerous regulators and often also other
|
||||
subsystems. In an embedded system the primary PMIC is often
|
||||
equivalent to a combination of the PSU and southbridge in a
|
||||
desktop system.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossary>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="consumer">
|
||||
<title>Consumer driver interface</title>
|
||||
<para>
|
||||
This offers a similar API to the kernel clock framework.
|
||||
Consumer drivers use <link
|
||||
linkend='API-regulator-get'>get</link> and <link
|
||||
linkend='API-regulator-put'>put</link> operations to acquire and
|
||||
release regulators. Functions are
|
||||
provided to <link linkend='API-regulator-enable'>enable</link>
|
||||
and <link linkend='API-regulator-disable'>disable</link> the
|
||||
regulator and to get and set the runtime parameters of the
|
||||
regulator.
|
||||
</para>
|
||||
<para>
|
||||
When requesting regulators consumers use symbolic names for their
|
||||
supplies, such as "Vcc", which are mapped into actual regulator
|
||||
devices by the machine interface.
|
||||
</para>
|
||||
<para>
|
||||
A stub version of this API is provided when the regulator
|
||||
framework is not in use in order to minimise the need to use
|
||||
ifdefs.
|
||||
</para>
|
||||
|
||||
<sect1 id="consumer-enable">
|
||||
<title>Enabling and disabling</title>
|
||||
<para>
|
||||
The regulator API provides reference counted enabling and
|
||||
disabling of regulators. Consumer devices use the <function><link
|
||||
linkend='API-regulator-enable'>regulator_enable</link></function>
|
||||
and <function><link
|
||||
linkend='API-regulator-disable'>regulator_disable</link>
|
||||
</function> functions to enable and disable regulators. Calls
|
||||
to the two functions must be balanced.
|
||||
</para>
|
||||
<para>
|
||||
Note that since multiple consumers may be using a regulator and
|
||||
machine constraints may not allow the regulator to be disabled
|
||||
there is no guarantee that calling
|
||||
<function>regulator_disable</function> will actually cause the
|
||||
supply provided by the regulator to be disabled. Consumer
|
||||
drivers should assume that the regulator may be enabled at all
|
||||
times.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="consumer-config">
|
||||
<title>Configuration</title>
|
||||
<para>
|
||||
Some consumer devices may need to be able to dynamically
|
||||
configure their supplies. For example, MMC drivers may need to
|
||||
select the correct operating voltage for their cards. This may
|
||||
be done while the regulator is enabled or disabled.
|
||||
</para>
|
||||
<para>
|
||||
The <function><link
|
||||
linkend='API-regulator-set-voltage'>regulator_set_voltage</link>
|
||||
</function> and <function><link
|
||||
linkend='API-regulator-set-current-limit'
|
||||
>regulator_set_current_limit</link>
|
||||
</function> functions provide the primary interface for this.
|
||||
Both take ranges of voltages and currents, supporting drivers
|
||||
that do not require a specific value (eg, CPU frequency scaling
|
||||
normally permits the CPU to use a wider range of supply
|
||||
voltages at lower frequencies but does not require that the
|
||||
supply voltage be lowered). Where an exact value is required
|
||||
both minimum and maximum values should be identical.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="consumer-callback">
|
||||
<title>Callbacks</title>
|
||||
<para>
|
||||
Callbacks may also be <link
|
||||
linkend='API-regulator-register-notifier'>registered</link>
|
||||
for events such as regulation failures.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="driver">
|
||||
<title>Regulator driver interface</title>
|
||||
<para>
|
||||
Drivers for regulator chips <link
|
||||
linkend='API-regulator-register'>register</link> the regulators
|
||||
with the regulator core, providing operations structures to the
|
||||
core. A <link
|
||||
linkend='API-regulator-notifier-call-chain'>notifier</link> interface
|
||||
allows error conditions to be reported to the core.
|
||||
</para>
|
||||
<para>
|
||||
Registration should be triggered by explicit setup done by the
|
||||
platform, supplying a <link
|
||||
linkend='API-struct-regulator-init-data'>struct
|
||||
regulator_init_data</link> for the regulator containing
|
||||
<link linkend='machine-constraint'>constraint</link> and
|
||||
<link linkend='machine-supply'>supply</link> information.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="machine">
|
||||
<title>Machine interface</title>
|
||||
<para>
|
||||
This interface provides a way to define how regulators are
|
||||
connected to consumers on a given system and what the valid
|
||||
operating parameters are for the system.
|
||||
</para>
|
||||
|
||||
<sect1 id="machine-supply">
|
||||
<title>Supplies</title>
|
||||
<para>
|
||||
Regulator supplies are specified using <link
|
||||
linkend='API-struct-regulator-consumer-supply'>struct
|
||||
regulator_consumer_supply</link>. This is done at
|
||||
<link linkend='driver'>driver registration
|
||||
time</link> as part of the machine constraints.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="machine-constraint">
|
||||
<title>Constraints</title>
|
||||
<para>
|
||||
As well as defining the connections the machine interface
|
||||
also provides constraints defining the operations that
|
||||
clients are allowed to perform and the parameters that may be
|
||||
set. This is required since generally regulator devices will
|
||||
offer more flexibility than it is safe to use on a given
|
||||
system, for example supporting higher supply voltages than the
|
||||
consumers are rated for.
|
||||
</para>
|
||||
<para>
|
||||
This is done at <link linkend='driver'>driver
|
||||
registration time</link> by providing a <link
|
||||
linkend='API-struct-regulation-constraints'>struct
|
||||
regulation_constraints</link>.
|
||||
</para>
|
||||
<para>
|
||||
The constraints may also specify an initial configuration for the
|
||||
regulator in the constraints, which is particularly useful for
|
||||
use with static consumers.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="api">
|
||||
<title>API reference</title>
|
||||
<para>
|
||||
Due to limitations of the kernel documentation framework and the
|
||||
existing layout of the source code the entire regulator API is
|
||||
documented here.
|
||||
</para>
|
||||
!Iinclude/linux/regulator/consumer.h
|
||||
!Iinclude/linux/regulator/machine.h
|
||||
!Iinclude/linux/regulator/driver.h
|
||||
!Edrivers/regulator/core.c
|
||||
</chapter>
|
||||
</book>
|
||||
Loading…
Reference in a new issue