162306a36Sopenharmony_ci=============
262306a36Sopenharmony_ciCore elements
362306a36Sopenharmony_ci=============
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciThe Industrial I/O core offers both a unified framework for writing drivers for
662306a36Sopenharmony_cimany different types of embedded sensors and a standard interface to user space
762306a36Sopenharmony_ciapplications manipulating sensors. The implementation can be found under
862306a36Sopenharmony_ci:file:`drivers/iio/industrialio-*`
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciIndustrial I/O Devices
1162306a36Sopenharmony_ci----------------------
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci* struct iio_dev - industrial I/O device
1462306a36Sopenharmony_ci* iio_device_alloc() - allocate an :c:type:`iio_dev` from a driver
1562306a36Sopenharmony_ci* iio_device_free() - free an :c:type:`iio_dev` from a driver
1662306a36Sopenharmony_ci* iio_device_register() - register a device with the IIO subsystem
1762306a36Sopenharmony_ci* iio_device_unregister() - unregister a device from the IIO
1862306a36Sopenharmony_ci  subsystem
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ciAn IIO device usually corresponds to a single hardware sensor and it
2162306a36Sopenharmony_ciprovides all the information needed by a driver handling a device.
2262306a36Sopenharmony_ciLet's first have a look at the functionality embedded in an IIO device
2362306a36Sopenharmony_cithen we will show how a device driver makes use of an IIO device.
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ciThere are two ways for a user space application to interact with an IIO driver.
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci1. :file:`/sys/bus/iio/iio:device{X}/`, this represents a hardware sensor
2862306a36Sopenharmony_ci   and groups together the data channels of the same chip.
2962306a36Sopenharmony_ci2. :file:`/dev/iio:device{X}`, character device node interface used for
3062306a36Sopenharmony_ci   buffered data transfer and for events information retrieval.
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciA typical IIO driver will register itself as an :doc:`I2C <../i2c>` or
3362306a36Sopenharmony_ci:doc:`SPI <../spi>` driver and will create two routines, probe and remove.
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ciAt probe:
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci1. Call iio_device_alloc(), which allocates memory for an IIO device.
3862306a36Sopenharmony_ci2. Initialize IIO device fields with driver specific information (e.g.
3962306a36Sopenharmony_ci   device name, device channels).
4062306a36Sopenharmony_ci3. Call iio_device_register(), this registers the device with the
4162306a36Sopenharmony_ci   IIO core. After this call the device is ready to accept requests from user
4262306a36Sopenharmony_ci   space applications.
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ciAt remove, we free the resources allocated in probe in reverse order:
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci1. iio_device_unregister(), unregister the device from the IIO core.
4762306a36Sopenharmony_ci2. iio_device_free(), free the memory allocated for the IIO device.
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciIIO device sysfs interface
5062306a36Sopenharmony_ci==========================
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ciAttributes are sysfs files used to expose chip info and also allowing
5362306a36Sopenharmony_ciapplications to set various configuration parameters. For device with
5462306a36Sopenharmony_ciindex X, attributes can be found under /sys/bus/iio/iio:deviceX/ directory.
5562306a36Sopenharmony_ciCommon attributes are:
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci* :file:`name`, description of the physical chip.
5862306a36Sopenharmony_ci* :file:`dev`, shows the major:minor pair associated with
5962306a36Sopenharmony_ci  :file:`/dev/iio:deviceX` node.
6062306a36Sopenharmony_ci* :file:`sampling_frequency_available`, available discrete set of sampling
6162306a36Sopenharmony_ci  frequency values for device.
6262306a36Sopenharmony_ci* Available standard attributes for IIO devices are described in the
6362306a36Sopenharmony_ci  :file:`Documentation/ABI/testing/sysfs-bus-iio` file in the Linux kernel
6462306a36Sopenharmony_ci  sources.
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ciIIO device channels
6762306a36Sopenharmony_ci===================
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistruct iio_chan_spec - specification of a single channel
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ciAn IIO device channel is a representation of a data channel. An IIO device can
7262306a36Sopenharmony_cihave one or multiple channels. For example:
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci* a thermometer sensor has one channel representing the temperature measurement.
7562306a36Sopenharmony_ci* a light sensor with two channels indicating the measurements in the visible
7662306a36Sopenharmony_ci  and infrared spectrum.
7762306a36Sopenharmony_ci* an accelerometer can have up to 3 channels representing acceleration on X, Y
7862306a36Sopenharmony_ci  and Z axes.
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciAn IIO channel is described by the struct iio_chan_spec.
8162306a36Sopenharmony_ciA thermometer driver for the temperature sensor in the example above would
8262306a36Sopenharmony_cihave to describe its channel as follows::
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci   static const struct iio_chan_spec temp_channel[] = {
8562306a36Sopenharmony_ci        {
8662306a36Sopenharmony_ci            .type = IIO_TEMP,
8762306a36Sopenharmony_ci            .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
8862306a36Sopenharmony_ci        },
8962306a36Sopenharmony_ci   };
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ciChannel sysfs attributes exposed to userspace are specified in the form of
9262306a36Sopenharmony_cibitmasks. Depending on their shared info, attributes can be set in one of the
9362306a36Sopenharmony_cifollowing masks:
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci* **info_mask_separate**, attributes will be specific to
9662306a36Sopenharmony_ci  this channel
9762306a36Sopenharmony_ci* **info_mask_shared_by_type**, attributes are shared by all channels of the
9862306a36Sopenharmony_ci  same type
9962306a36Sopenharmony_ci* **info_mask_shared_by_dir**, attributes are shared by all channels of the same
10062306a36Sopenharmony_ci  direction
10162306a36Sopenharmony_ci* **info_mask_shared_by_all**, attributes are shared by all channels
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ciWhen there are multiple data channels per channel type we have two ways to
10462306a36Sopenharmony_cidistinguish between them:
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci* set **.modified** field of :c:type:`iio_chan_spec` to 1. Modifiers are
10762306a36Sopenharmony_ci  specified using **.channel2** field of the same :c:type:`iio_chan_spec`
10862306a36Sopenharmony_ci  structure and are used to indicate a physically unique characteristic of the
10962306a36Sopenharmony_ci  channel such as its direction or spectral response. For example, a light
11062306a36Sopenharmony_ci  sensor can have two channels, one for infrared light and one for both
11162306a36Sopenharmony_ci  infrared and visible light.
11262306a36Sopenharmony_ci* set **.indexed** field of :c:type:`iio_chan_spec` to 1. In this case the
11362306a36Sopenharmony_ci  channel is simply another instance with an index specified by the **.channel**
11462306a36Sopenharmony_ci  field.
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ciHere is how we can make use of the channel's modifiers::
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci   static const struct iio_chan_spec light_channels[] = {
11962306a36Sopenharmony_ci           {
12062306a36Sopenharmony_ci                   .type = IIO_INTENSITY,
12162306a36Sopenharmony_ci                   .modified = 1,
12262306a36Sopenharmony_ci                   .channel2 = IIO_MOD_LIGHT_IR,
12362306a36Sopenharmony_ci                   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
12462306a36Sopenharmony_ci                   .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
12562306a36Sopenharmony_ci           },
12662306a36Sopenharmony_ci           {
12762306a36Sopenharmony_ci                   .type = IIO_INTENSITY,
12862306a36Sopenharmony_ci                   .modified = 1,
12962306a36Sopenharmony_ci                   .channel2 = IIO_MOD_LIGHT_BOTH,
13062306a36Sopenharmony_ci                   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
13162306a36Sopenharmony_ci                   .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
13262306a36Sopenharmony_ci           },
13362306a36Sopenharmony_ci           {
13462306a36Sopenharmony_ci                   .type = IIO_LIGHT,
13562306a36Sopenharmony_ci                   .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
13662306a36Sopenharmony_ci                   .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
13762306a36Sopenharmony_ci           },
13862306a36Sopenharmony_ci      }
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ciThis channel's definition will generate two separate sysfs files for raw data
14162306a36Sopenharmony_ciretrieval:
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci* :file:`/sys/bus/iio/iio:device{X}/in_intensity_ir_raw`
14462306a36Sopenharmony_ci* :file:`/sys/bus/iio/iio:device{X}/in_intensity_both_raw`
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_cione file for processed data:
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci* :file:`/sys/bus/iio/iio:device{X}/in_illuminance_input`
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ciand one shared sysfs file for sampling frequency:
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci* :file:`/sys/bus/iio/iio:device{X}/sampling_frequency`.
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ciHere is how we can make use of the channel's indexing::
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci   static const struct iio_chan_spec light_channels[] = {
15762306a36Sopenharmony_ci           {
15862306a36Sopenharmony_ci                   .type = IIO_VOLTAGE,
15962306a36Sopenharmony_ci		   .indexed = 1,
16062306a36Sopenharmony_ci		   .channel = 0,
16162306a36Sopenharmony_ci		   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
16262306a36Sopenharmony_ci	   },
16362306a36Sopenharmony_ci           {
16462306a36Sopenharmony_ci	           .type = IIO_VOLTAGE,
16562306a36Sopenharmony_ci                   .indexed = 1,
16662306a36Sopenharmony_ci                   .channel = 1,
16762306a36Sopenharmony_ci                   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
16862306a36Sopenharmony_ci           },
16962306a36Sopenharmony_ci   }
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ciThis will generate two separate attributes files for raw data retrieval:
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci* :file:`/sys/bus/iio/devices/iio:device{X}/in_voltage0_raw`, representing
17462306a36Sopenharmony_ci  voltage measurement for channel 0.
17562306a36Sopenharmony_ci* :file:`/sys/bus/iio/devices/iio:device{X}/in_voltage1_raw`, representing
17662306a36Sopenharmony_ci  voltage measurement for channel 1.
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ciMore details
17962306a36Sopenharmony_ci============
18062306a36Sopenharmony_ci.. kernel-doc:: include/linux/iio/iio.h
18162306a36Sopenharmony_ci.. kernel-doc:: drivers/iio/industrialio-core.c
18262306a36Sopenharmony_ci   :export:
183