1, Kernel / include / Linux / IIO / IIO h
1.iio_dev structure
struct iio_dev { int id; struct module *driver_module; int modes;//Indicates the different operating modes supported by the device int currentmode;//Indicates the mode in which the device is actually used struct device dev;//Represents the struct device on which the IIO device depends (according to the Linux device model) struct iio_event_interface *event_interface; struct iio_buffer *buffer;//Data buffer, which will be pushed to user space when using trigger buffer mode struct list_head buffer_list; int scan_bytes;//This is the number of bytes captured and fed to the buffer. struct mutex mlock; const unsigned long *available_scan_masks;//An optional array of bitmasks allowed unsigned masklength; const unsigned long *active_scan_mask;//Enable the bitmask of channels. Only data from these channels can be pushed into the buffer bool scan_timestamp;//No push capture timestamp into buffer unsigned scan_index_timestamp; struct iio_trigger *trig;//Current device trigger (when buffer mode is supported) bool trig_readonly; struct iio_poll_func *pollfunc;//A function that runs on a received trigger struct iio_poll_func *pollfunc_event; struct iio_chan_spec const *channels;//Represents the channel specification structure, which is used to describe each channel that the device has int num_channels;//Indicates the number of channels specified in the channel struct list_head channel_attr_list; struct attribute_group chan_attr_group; const char *name;//Indicates the device name const struct iio_info *info;//Callback and persistence information from driver clockid_t clock_id; struct mutex info_exist_lock; const struct iio_buffer_setup_ops *setup_ops;//Callback function set invoked before and after the buffer is enabled / disabled struct cdev chrdev;//Associated character device created by IIO core #define IIO_MAX_GROUPS 6 const struct attribute_group *groups[IIO_MAX_GROUPS + 1]; int groupcounter; unsigned long flags; #if defined(CONFIG_DEBUG_FS) struct dentry *debugfs_dentry; unsigned cached_reg_addr; #endif };
- Modes: the supported modes are
INDIO_DIRECT_MODE indicates the sysfs interface provided by the device.
INDIO_BUFFER_TRIGGERED indicates that the device supports hardware triggers. Using IIO_ triggered_ buffer_ When the setup() function sets the trigger buffer, this mode is automatically added to the device.
INDIO_BUFFER_HARDWARE indicates that the device has a hardware buffer.
INDIO_ALL_BUFFER_MODES is a combination of the above two - Buffer: use IIO_ triggered_ buffer_ When the setup function enables trigger buffer support, it is automatically allocated and associated with your device
- scan_bytes: when the trigger buffer is used from user space, the buffer should be at least Indio - > scan_bytes large
- available_scan_masks: when using the trigger buffer, you can enable channel capture and feed it into the IIO buffer. If some channels are not allowed to be enabled, only the allowed channels are used to fill this array
enum max3012_led_idx { MAX30102_LED_RED, MAX30102_LED_IR, MAX30105_LED_GREEN, }; //Optional static const unsigned long max30102_scan_masks[] = { BIT(MAX30102_LED_RED) | BIT(MAX30102_LED_IR), 0 }; static const unsigned long max30105_scan_masks[] = { BIT(MAX30102_LED_RED) | BIT(MAX30102_LED_IR), BIT(MAX30102_LED_RED) | BIT(MAX30102_LED_IR) | BIT(MAX30105_LED_GREEN), 0 }; indio_dev->available_scan_masks = max30105_scan_masks;
- active_scan_mask: enables the bitmask of the channel. Only data from these channels can be pushed into the buffer. For example, for an 8-channel ADC converter, if only the first (0), third (2) and last (7) channels are enabled, the bitmask will be 0b10000101(0x85). active_ scan_ Set mask to 0x85. The driver can then use for_ each_ set_ The bit macro traverses each setting bit, obtains data according to the channel, and fills the buffer
for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { ret = kmx61_read_measurement(data, base, bit); if (ret < 0) { mutex_unlock(&data->lock); goto err; } buffer[i++] = ret; }
- scan_timestamp: whether to push the capture timestamp into the buffer. If true, the timestamp is used as the last element of the buffer. Timestamp large 8 bytes (64 bits)
2.iio_info structure
//kernel/include/linux/iio/iio.h struct iio_info { const struct attribute_group *event_attrs; const struct attribute_group *attrs;//Represents the device properties //Callback operation when the user reads the sysfs file properties of the device int (*read_raw)(struct iio_dev *indio_dev,struct iio_chan_spec const *chan, int *val,int *val2,long mask); int (*read_raw_multi)(struct iio_dev *indio_dev,struct iio_chan_spec const *chan, int max_len,int *vals,int *val_len,long mask); int (*read_avail)(struct iio_dev *indio_dev,struct iio_chan_spec const *chan, const int **vals,int *type,int *length,long mask); //Callback for writing values to the device int (*write_raw)(struct iio_dev *indio_dev,struct iio_chan_spec const *chan, int val,int val2,long mask); int (*write_raw_get_fmt)(struct iio_dev *indio_dev,struct iio_chan_spec const *chan, long mask); int (*read_event_config)(struct iio_dev *indio_dev,const struct iio_chan_spec *chan, enum iio_event_type type,enum iio_event_direction dir); int (*write_event_config)(struct iio_dev *indio_dev,const struct iio_chan_spec *chan, enum iio_event_type type,enum iio_event_direction dir,int state); int (*read_event_value)(struct iio_dev *indio_dev,const struct iio_chan_spec *chan, enum iio_event_type type,enum iio_event_direction dir, enum iio_event_info info, int *val, int *val2); int (*write_event_value)(struct iio_dev *indio_dev,const struct iio_chan_spec *chan, enum iio_event_type type,enum iio_event_direction dir, enum iio_event_info info, int val, int val2); int (*validate_trigger)(struct iio_dev *indio_dev,struct iio_trigger *trig); int (*update_scan_mode)(struct iio_dev *indio_dev,const unsigned long *scan_mask); int (*debugfs_reg_access)(struct iio_dev *indio_dev,unsigned reg, unsigned writeval, unsigned *readval); int (*of_xlate)(struct iio_dev *indio_dev,const struct of_phandle_args *iiospec); int (*hwfifo_set_watermark)(struct iio_dev *indio_dev, unsigned val); int (*hwfifo_flush_to_buffer)(struct iio_dev *indio_dev,unsigned count); }; //Example static const struct iio_info kmx61_acc_info = { .read_raw = kmx61_read_raw, .write_raw = kmx61_write_raw, .attrs = &kmx61_acc_attribute_group, .read_event_value = kmx61_read_event, .write_event_value = kmx61_write_event, .read_event_config = kmx61_read_event_config, .write_event_config = kmx61_write_event_config, .validate_trigger = kmx61_acc_validate_trigger, }; indio_dev->info = &kmx61_acc_info;
3.iio_chan_spec structure
//The channel represents a single acquisition line struct iio_chan_spec { enum iio_chan_type type;//Specifies the measurement type of the channel int channel;//appoint. Channel index when indexed is set to 1 int channel2;//appoint. Channel modification when modified is set to 1 unsigned long address; //scan_index and scan_type: when using buffer triggers, these fields are used to identify elements in the buffer int scan_index;//Set the location of the channel captured in the buffer scan_index=-1 will prevent channel buffer capture struct { char sign; //'s' or 'u' describes signed and unsigned u8 realbits;//Significant digits u8 storagebits;//Realbits + padding u8 shift; u8 repeat; enum iio_endian endianness; //little or big endian } scan_type; long info_mask_separate;//Mark attributes specific to this channel long info_mask_separate_available; long info_mask_shared_by_type;//Mark this attribute as shared by all channels of the same type long info_mask_shared_by_type_available; long info_mask_shared_by_dir;//Mark attributes as shared by all channels in the same direction long info_mask_shared_by_dir_available; long info_mask_shared_by_all;//Mark attribute as shared by all channels long info_mask_shared_by_all_available; const struct iio_event_spec *event_spec; unsigned int num_event_specs; const struct iio_chan_spec_ext_info *ext_info;//Describes information related to a channel extension attribute, including attribute name, read-write interface, etc const char *extend_name; const char *datasheet_name; unsigned modified:1;//Specifies whether to apply a modifier to this channel property name, which is set at In channel2 unsigned indexed:1;//Specifies whether the channel attribute name has an index. If so, in Specify the index in the channel field unsigned output:1; //channel is the output unsigned differential:1; };
- Type: Specifies the measurement type of the channel. In the case of voltage measurement, it should be IIO_VOLTAGE. For optical sensors, it is IIO_LIGHT. For accelerometers, use IIO_ACCEL. All available types are in include / UAPI / Linux / IIO / types H, such as enum iio_chan_type. To write a driver for a given converter, review the file to see what type each channel belongs to
//The channel type corresponding to type depends on iio_chan_type_name_spec static const char * const iio_chan_type_name_spec[] = { [IIO_VOLTAGE] = "voltage", [IIO_CURRENT] = "current", [IIO_POWER] = "power", [IIO_ACCEL] = "accel", }; //The channel2 field is based on IIO when modifier=1_ modifier_ names static const char * const iio_modifier_names[] = { [IIO_MOD_X] = "x", [IIO_MOD_Y] = "y", [IIO_MOD_Z] = "z", [IIO_MOD_X_AND_Y] = "x&y", }; //info_mask depends on char array IIO_ chan_ info_ Channel information mask in postfix static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_RAW] = "raw", [IIO_CHAN_INFO_PROCESSED] = "input", [IIO_CHAN_INFO_SCALE] = "scale", [IIO_CHAN_INFO_OFFSET] = "offset", };
Please click here for reference links
Make progress in your study. If you have any mistakes, please criticize and correct them