一、kernel/include/linux/iio/iio.h
1.iio_dev结构体
struct iio_dev {
int id;
struct module *driver_module;
int modes;//表示设备支持的不同操作模式
int currentmode;//表示设备实际使用的模式
struct device dev;//表示IIO设备所依赖的struct设备(根据Linux设备型号)
struct iio_event_interface *event_interface;
struct iio_buffer *buffer;//数据缓冲区,在使用触发缓冲区模式时会推送到用户空间
struct list_head buffer_list;
int scan_bytes;//这是捕获并馈送到缓冲区的字节数。
struct mutex mlock;
const unsigned long *available_scan_masks;//允许的位掩码的可选数组
unsigned masklength;
const unsigned long *active_scan_mask;//启用通道的位掩码,只有来自这些通道的数据能被推入缓冲区
bool scan_timestamp;//否将捕获时间戳推入缓冲区
unsigned scan_index_timestamp;
struct iio_trigger *trig;//当前设备触发器(支持缓冲模式时)
bool trig_readonly;
struct iio_poll_func *pollfunc;//在接收的触发器上运行的函数
struct iio_poll_func *pollfunc_event;
struct iio_chan_spec const *channels;//表示通道规范结构,用于描述设备具有的每个通道
int num_channels;//表示通道中指定的通道数
struct list_head channel_attr_list;
struct attribute_group chan_attr_group;
const char *name;//表示设备名称
const struct iio_info *info;//来自驱动程序的回调和持续信息
clockid_t clock_id;
struct mutex info_exist_lock;
const struct iio_buffer_setup_ops *setup_ops;//启用/禁用缓冲区之前和之后调用的回调函数集
struct cdev chrdev;//由IIO核心创建的关联字符设备
#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
};
enum max3012_led_idx {
MAX30102_LED_RED,
MAX30102_LED_IR,
MAX30105_LED_GREEN,
};
//可选
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;
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;
}
2.iio_info结构体
//kernel/include/linux/iio/iio.h
struct iio_info {
const struct attribute_group *event_attrs;
const struct attribute_group *attrs;//表示设备属性
//用户读取设备sysfs文件属性时的回调运行
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);
//用于将值写入设备的回调
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);
};
//示例
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结构体
//通道代表单条采集线
struct iio_chan_spec {
enum iio_chan_type type;//指定了通道的测量类型
int channel;//指定.indexed设置为1时的通道索引
int channel2;//指定.modified设置为1时的通道修饰
unsigned long address;
//scan_index and scan_type: 当使用缓冲区触发器时,这些字段用于标识缓冲区中的元素
int scan_index;//设置缓冲区内捕获的通道的位置,.scan_index=-1将阻止通道缓冲捕获
struct {
char sign; //'s' or 'u'描述有符号和无符号
u8 realbits;//有效位数
u8 storagebits;//Realbits + padding
u8 shift;
u8 repeat;
enum iio_endian endianness; //little or big endian,字节序
} scan_type;
long info_mask_separate;//将属性标记为特定于此通道
long info_mask_separate_available;
long info_mask_shared_by_type;//将该属性标记为由相同类型的所有通道共享
long info_mask_shared_by_type_available;
long info_mask_shared_by_dir;//将属性标记为由同一方向的所有通道共享
long info_mask_shared_by_dir_available;
long info_mask_shared_by_all;//将属性标记为所有通道共享
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;//描述一个channel扩展属性相关的信息,包括属性名称、读写接口等
const char *extend_name;
const char *datasheet_name;
unsigned modified:1;//指定是否将修饰符应用于此通道属性名称,饰符设置在.channel2中
unsigned indexed:1;//指定通道属性名称是否具有索引,若是,在.channel字段中指定索引
unsigned output:1; //channel是输出
unsigned differential:1;
};
//type对应的通道类型根据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",
};
//channel2字段根据modifier=1时iio_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取决于char数组iio_chan_info_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",
};
参考链接请点击而此处
IIO子系统概述请点击此处
在学习中进步,如有错误,请多多批评指正