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