1*4882a593Smuzhiyun============= 2*4882a593SmuzhiyunCore elements 3*4882a593Smuzhiyun============= 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunThe Industrial I/O core offers both a unified framework for writing drivers for 6*4882a593Smuzhiyunmany different types of embedded sensors and a standard interface to user space 7*4882a593Smuzhiyunapplications manipulating sensors. The implementation can be found under 8*4882a593Smuzhiyun:file:`drivers/iio/industrialio-*` 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunIndustrial I/O Devices 11*4882a593Smuzhiyun---------------------- 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun* struct iio_dev - industrial I/O device 14*4882a593Smuzhiyun* iio_device_alloc() - allocate an :c:type:`iio_dev` from a driver 15*4882a593Smuzhiyun* iio_device_free() - free an :c:type:`iio_dev` from a driver 16*4882a593Smuzhiyun* iio_device_register() - register a device with the IIO subsystem 17*4882a593Smuzhiyun* iio_device_unregister() - unregister a device from the IIO 18*4882a593Smuzhiyun subsystem 19*4882a593Smuzhiyun 20*4882a593SmuzhiyunAn IIO device usually corresponds to a single hardware sensor and it 21*4882a593Smuzhiyunprovides all the information needed by a driver handling a device. 22*4882a593SmuzhiyunLet's first have a look at the functionality embedded in an IIO device 23*4882a593Smuzhiyunthen we will show how a device driver makes use of an IIO device. 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunThere are two ways for a user space application to interact with an IIO driver. 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun1. :file:`/sys/bus/iio/iio:device{X}/`, this represents a hardware sensor 28*4882a593Smuzhiyun and groups together the data channels of the same chip. 29*4882a593Smuzhiyun2. :file:`/dev/iio:device{X}`, character device node interface used for 30*4882a593Smuzhiyun buffered data transfer and for events information retrieval. 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunA typical IIO driver will register itself as an :doc:`I2C <../i2c>` or 33*4882a593Smuzhiyun:doc:`SPI <../spi>` driver and will create two routines, probe and remove. 34*4882a593Smuzhiyun 35*4882a593SmuzhiyunAt probe: 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun1. Call iio_device_alloc(), which allocates memory for an IIO device. 38*4882a593Smuzhiyun2. Initialize IIO device fields with driver specific information (e.g. 39*4882a593Smuzhiyun device name, device channels). 40*4882a593Smuzhiyun3. Call iio_device_register(), this registers the device with the 41*4882a593Smuzhiyun IIO core. After this call the device is ready to accept requests from user 42*4882a593Smuzhiyun space applications. 43*4882a593Smuzhiyun 44*4882a593SmuzhiyunAt remove, we free the resources allocated in probe in reverse order: 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun1. iio_device_unregister(), unregister the device from the IIO core. 47*4882a593Smuzhiyun2. iio_device_free(), free the memory allocated for the IIO device. 48*4882a593Smuzhiyun 49*4882a593SmuzhiyunIIO device sysfs interface 50*4882a593Smuzhiyun========================== 51*4882a593Smuzhiyun 52*4882a593SmuzhiyunAttributes are sysfs files used to expose chip info and also allowing 53*4882a593Smuzhiyunapplications to set various configuration parameters. For device with 54*4882a593Smuzhiyunindex X, attributes can be found under /sys/bus/iio/iio:deviceX/ directory. 55*4882a593SmuzhiyunCommon attributes are: 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun* :file:`name`, description of the physical chip. 58*4882a593Smuzhiyun* :file:`dev`, shows the major:minor pair associated with 59*4882a593Smuzhiyun :file:`/dev/iio:deviceX` node. 60*4882a593Smuzhiyun* :file:`sampling_frequency_available`, available discrete set of sampling 61*4882a593Smuzhiyun frequency values for device. 62*4882a593Smuzhiyun* Available standard attributes for IIO devices are described in the 63*4882a593Smuzhiyun :file:`Documentation/ABI/testing/sysfs-bus-iio` file in the Linux kernel 64*4882a593Smuzhiyun sources. 65*4882a593Smuzhiyun 66*4882a593SmuzhiyunIIO device channels 67*4882a593Smuzhiyun=================== 68*4882a593Smuzhiyun 69*4882a593Smuzhiyunstruct iio_chan_spec - specification of a single channel 70*4882a593Smuzhiyun 71*4882a593SmuzhiyunAn IIO device channel is a representation of a data channel. An IIO device can 72*4882a593Smuzhiyunhave one or multiple channels. For example: 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun* a thermometer sensor has one channel representing the temperature measurement. 75*4882a593Smuzhiyun* a light sensor with two channels indicating the measurements in the visible 76*4882a593Smuzhiyun and infrared spectrum. 77*4882a593Smuzhiyun* an accelerometer can have up to 3 channels representing acceleration on X, Y 78*4882a593Smuzhiyun and Z axes. 79*4882a593Smuzhiyun 80*4882a593SmuzhiyunAn IIO channel is described by the struct iio_chan_spec. 81*4882a593SmuzhiyunA thermometer driver for the temperature sensor in the example above would 82*4882a593Smuzhiyunhave to describe its channel as follows:: 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun static const struct iio_chan_spec temp_channel[] = { 85*4882a593Smuzhiyun { 86*4882a593Smuzhiyun .type = IIO_TEMP, 87*4882a593Smuzhiyun .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), 88*4882a593Smuzhiyun }, 89*4882a593Smuzhiyun }; 90*4882a593Smuzhiyun 91*4882a593SmuzhiyunChannel sysfs attributes exposed to userspace are specified in the form of 92*4882a593Smuzhiyunbitmasks. Depending on their shared info, attributes can be set in one of the 93*4882a593Smuzhiyunfollowing masks: 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun* **info_mask_separate**, attributes will be specific to 96*4882a593Smuzhiyun this channel 97*4882a593Smuzhiyun* **info_mask_shared_by_type**, attributes are shared by all channels of the 98*4882a593Smuzhiyun same type 99*4882a593Smuzhiyun* **info_mask_shared_by_dir**, attributes are shared by all channels of the same 100*4882a593Smuzhiyun direction 101*4882a593Smuzhiyun* **info_mask_shared_by_all**, attributes are shared by all channels 102*4882a593Smuzhiyun 103*4882a593SmuzhiyunWhen there are multiple data channels per channel type we have two ways to 104*4882a593Smuzhiyundistinguish between them: 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun* set **.modified** field of :c:type:`iio_chan_spec` to 1. Modifiers are 107*4882a593Smuzhiyun specified using **.channel2** field of the same :c:type:`iio_chan_spec` 108*4882a593Smuzhiyun structure and are used to indicate a physically unique characteristic of the 109*4882a593Smuzhiyun channel such as its direction or spectral response. For example, a light 110*4882a593Smuzhiyun sensor can have two channels, one for infrared light and one for both 111*4882a593Smuzhiyun infrared and visible light. 112*4882a593Smuzhiyun* set **.indexed** field of :c:type:`iio_chan_spec` to 1. In this case the 113*4882a593Smuzhiyun channel is simply another instance with an index specified by the **.channel** 114*4882a593Smuzhiyun field. 115*4882a593Smuzhiyun 116*4882a593SmuzhiyunHere is how we can make use of the channel's modifiers:: 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun static const struct iio_chan_spec light_channels[] = { 119*4882a593Smuzhiyun { 120*4882a593Smuzhiyun .type = IIO_INTENSITY, 121*4882a593Smuzhiyun .modified = 1, 122*4882a593Smuzhiyun .channel2 = IIO_MOD_LIGHT_IR, 123*4882a593Smuzhiyun .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 124*4882a593Smuzhiyun .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ), 125*4882a593Smuzhiyun }, 126*4882a593Smuzhiyun { 127*4882a593Smuzhiyun .type = IIO_INTENSITY, 128*4882a593Smuzhiyun .modified = 1, 129*4882a593Smuzhiyun .channel2 = IIO_MOD_LIGHT_BOTH, 130*4882a593Smuzhiyun .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 131*4882a593Smuzhiyun .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ), 132*4882a593Smuzhiyun }, 133*4882a593Smuzhiyun { 134*4882a593Smuzhiyun .type = IIO_LIGHT, 135*4882a593Smuzhiyun .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), 136*4882a593Smuzhiyun .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ), 137*4882a593Smuzhiyun }, 138*4882a593Smuzhiyun } 139*4882a593Smuzhiyun 140*4882a593SmuzhiyunThis channel's definition will generate two separate sysfs files for raw data 141*4882a593Smuzhiyunretrieval: 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun* :file:`/sys/bus/iio/iio:device{X}/in_intensity_ir_raw` 144*4882a593Smuzhiyun* :file:`/sys/bus/iio/iio:device{X}/in_intensity_both_raw` 145*4882a593Smuzhiyun 146*4882a593Smuzhiyunone file for processed data: 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun* :file:`/sys/bus/iio/iio:device{X}/in_illuminance_input` 149*4882a593Smuzhiyun 150*4882a593Smuzhiyunand one shared sysfs file for sampling frequency: 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun* :file:`/sys/bus/iio/iio:device{X}/sampling_frequency`. 153*4882a593Smuzhiyun 154*4882a593SmuzhiyunHere is how we can make use of the channel's indexing:: 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun static const struct iio_chan_spec light_channels[] = { 157*4882a593Smuzhiyun { 158*4882a593Smuzhiyun .type = IIO_VOLTAGE, 159*4882a593Smuzhiyun .indexed = 1, 160*4882a593Smuzhiyun .channel = 0, 161*4882a593Smuzhiyun .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 162*4882a593Smuzhiyun }, 163*4882a593Smuzhiyun { 164*4882a593Smuzhiyun .type = IIO_VOLTAGE, 165*4882a593Smuzhiyun .indexed = 1, 166*4882a593Smuzhiyun .channel = 1, 167*4882a593Smuzhiyun .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 168*4882a593Smuzhiyun }, 169*4882a593Smuzhiyun } 170*4882a593Smuzhiyun 171*4882a593SmuzhiyunThis will generate two separate attributes files for raw data retrieval: 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun* :file:`/sys/bus/iio/devices/iio:device{X}/in_voltage0_raw`, representing 174*4882a593Smuzhiyun voltage measurement for channel 0. 175*4882a593Smuzhiyun* :file:`/sys/bus/iio/devices/iio:device{X}/in_voltage1_raw`, representing 176*4882a593Smuzhiyun voltage measurement for channel 1. 177*4882a593Smuzhiyun 178*4882a593SmuzhiyunMore details 179*4882a593Smuzhiyun============ 180*4882a593Smuzhiyun.. kernel-doc:: include/linux/iio/iio.h 181*4882a593Smuzhiyun.. kernel-doc:: drivers/iio/industrialio-core.c 182*4882a593Smuzhiyun :export: 183