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