Back to home page

OSCL-LXR

 
 

    


0001 =============
0002 Core elements
0003 =============
0004 
0005 The Industrial I/O core offers both a unified framework for writing drivers for
0006 many different types of embedded sensors and a standard interface to user space
0007 applications manipulating sensors. The implementation can be found under
0008 :file:`drivers/iio/industrialio-*`
0009 
0010 Industrial I/O Devices
0011 ----------------------
0012 
0013 * struct iio_dev - industrial I/O device
0014 * iio_device_alloc() - allocate an :c:type:`iio_dev` from a driver
0015 * iio_device_free() - free an :c:type:`iio_dev` from a driver
0016 * iio_device_register() - register a device with the IIO subsystem
0017 * iio_device_unregister() - unregister a device from the IIO
0018   subsystem
0019 
0020 An IIO device usually corresponds to a single hardware sensor and it
0021 provides all the information needed by a driver handling a device.
0022 Let's first have a look at the functionality embedded in an IIO device
0023 then we will show how a device driver makes use of an IIO device.
0024 
0025 There are two ways for a user space application to interact with an IIO driver.
0026 
0027 1. :file:`/sys/bus/iio/iio:device{X}/`, this represents a hardware sensor
0028    and groups together the data channels of the same chip.
0029 2. :file:`/dev/iio:device{X}`, character device node interface used for
0030    buffered data transfer and for events information retrieval.
0031 
0032 A typical IIO driver will register itself as an :doc:`I2C <../i2c>` or
0033 :doc:`SPI <../spi>` driver and will create two routines, probe and remove.
0034 
0035 At probe:
0036 
0037 1. Call iio_device_alloc(), which allocates memory for an IIO device.
0038 2. Initialize IIO device fields with driver specific information (e.g.
0039    device name, device channels).
0040 3. Call iio_device_register(), this registers the device with the
0041    IIO core. After this call the device is ready to accept requests from user
0042    space applications.
0043 
0044 At remove, we free the resources allocated in probe in reverse order:
0045 
0046 1. iio_device_unregister(), unregister the device from the IIO core.
0047 2. iio_device_free(), free the memory allocated for the IIO device.
0048 
0049 IIO device sysfs interface
0050 ==========================
0051 
0052 Attributes are sysfs files used to expose chip info and also allowing
0053 applications to set various configuration parameters. For device with
0054 index X, attributes can be found under /sys/bus/iio/iio:deviceX/ directory.
0055 Common attributes are:
0056 
0057 * :file:`name`, description of the physical chip.
0058 * :file:`dev`, shows the major:minor pair associated with
0059   :file:`/dev/iio:deviceX` node.
0060 * :file:`sampling_frequency_available`, available discrete set of sampling
0061   frequency values for device.
0062 * Available standard attributes for IIO devices are described in the
0063   :file:`Documentation/ABI/testing/sysfs-bus-iio` file in the Linux kernel
0064   sources.
0065 
0066 IIO device channels
0067 ===================
0068 
0069 struct iio_chan_spec - specification of a single channel
0070 
0071 An IIO device channel is a representation of a data channel. An IIO device can
0072 have one or multiple channels. For example:
0073 
0074 * a thermometer sensor has one channel representing the temperature measurement.
0075 * a light sensor with two channels indicating the measurements in the visible
0076   and infrared spectrum.
0077 * an accelerometer can have up to 3 channels representing acceleration on X, Y
0078   and Z axes.
0079 
0080 An IIO channel is described by the struct iio_chan_spec.
0081 A thermometer driver for the temperature sensor in the example above would
0082 have to describe its channel as follows::
0083 
0084    static const struct iio_chan_spec temp_channel[] = {
0085         {
0086             .type = IIO_TEMP,
0087             .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
0088         },
0089    };
0090 
0091 Channel sysfs attributes exposed to userspace are specified in the form of
0092 bitmasks. Depending on their shared info, attributes can be set in one of the
0093 following masks:
0094 
0095 * **info_mask_separate**, attributes will be specific to
0096   this channel
0097 * **info_mask_shared_by_type**, attributes are shared by all channels of the
0098   same type
0099 * **info_mask_shared_by_dir**, attributes are shared by all channels of the same
0100   direction
0101 * **info_mask_shared_by_all**, attributes are shared by all channels
0102 
0103 When there are multiple data channels per channel type we have two ways to
0104 distinguish between them:
0105 
0106 * set **.modified** field of :c:type:`iio_chan_spec` to 1. Modifiers are
0107   specified using **.channel2** field of the same :c:type:`iio_chan_spec`
0108   structure and are used to indicate a physically unique characteristic of the
0109   channel such as its direction or spectral response. For example, a light
0110   sensor can have two channels, one for infrared light and one for both
0111   infrared and visible light.
0112 * set **.indexed** field of :c:type:`iio_chan_spec` to 1. In this case the
0113   channel is simply another instance with an index specified by the **.channel**
0114   field.
0115 
0116 Here is how we can make use of the channel's modifiers::
0117 
0118    static const struct iio_chan_spec light_channels[] = {
0119            {
0120                    .type = IIO_INTENSITY,
0121                    .modified = 1,
0122                    .channel2 = IIO_MOD_LIGHT_IR,
0123                    .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0124                    .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0125            },
0126            {
0127                    .type = IIO_INTENSITY,
0128                    .modified = 1,
0129                    .channel2 = IIO_MOD_LIGHT_BOTH,
0130                    .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0131                    .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0132            },
0133            {
0134                    .type = IIO_LIGHT,
0135                    .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
0136                    .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0137            },
0138       }
0139 
0140 This channel's definition will generate two separate sysfs files for raw data
0141 retrieval:
0142 
0143 * :file:`/sys/bus/iio/iio:device{X}/in_intensity_ir_raw`
0144 * :file:`/sys/bus/iio/iio:device{X}/in_intensity_both_raw`
0145 
0146 one file for processed data:
0147 
0148 * :file:`/sys/bus/iio/iio:device{X}/in_illuminance_input`
0149 
0150 and one shared sysfs file for sampling frequency:
0151 
0152 * :file:`/sys/bus/iio/iio:device{X}/sampling_frequency`.
0153 
0154 Here is how we can make use of the channel's indexing::
0155 
0156    static const struct iio_chan_spec light_channels[] = {
0157            {
0158                    .type = IIO_VOLTAGE,
0159                    .indexed = 1,
0160                    .channel = 0,
0161                    .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0162            },
0163            {
0164                    .type = IIO_VOLTAGE,
0165                    .indexed = 1,
0166                    .channel = 1,
0167                    .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0168            },
0169    }
0170 
0171 This will generate two separate attributes files for raw data retrieval:
0172 
0173 * :file:`/sys/bus/iio/devices/iio:device{X}/in_voltage0_raw`, representing
0174   voltage measurement for channel 0.
0175 * :file:`/sys/bus/iio/devices/iio:device{X}/in_voltage1_raw`, representing
0176   voltage measurement for channel 1.
0177 
0178 More details
0179 ============
0180 .. kernel-doc:: include/linux/iio/iio.h
0181 .. kernel-doc:: drivers/iio/industrialio-core.c
0182    :export: