I2c子系统将i2c控制器(i2c寄存器所在的那块电路)抽象出来,用adapter(适配器)这个结构来描述,可以说一个适配器就代表一条i2c总线,而挂接在i2c总线上的设备是用client这个结构体来表述,另外i2c_bus上的设备链表挂接的不单单是连接的这条i2c上的client,同样adapter也作为一个设备挂在其所在的i2c_bus,也就是说控制器和设备都作为i2c_bus上的设备连接在设备链表,他们用内嵌的device的type这个成员来区分,适配器的类型为i2c_adapter_type,client的类型为i2c_client_type。
一、i2c相关的描述结构
首先看一下i2c子系统给adapter定义的描述结构:
[cpp]
- struct i2c_adapter { struct module *owner;
- unsigned int id; unsigned int class; // 适配器支持的类型,如传感器,eeprom等
- const struct i2c_algorithm *algo; //该适配器的通信函数 void *algo_data;
- /* data fields that are valid for all devices */ struct rt_mutex bus_lock;
- int timeout; //超时时间限定 int retries; //通信重复次数限定
- /* * 内嵌的标准device,其中dev->type标识该设备
- * 是个adapter,其值为i2c_adapter_type */
- struct device dev;
- int nr; //适配器编号也是bus编号,第几条i2c总线 char name[48]; //名字
- struct completion dev_released; struct mutex userspace_clients_lock;
- struct list_head userspace_clients; };
再来看一下client的描述结构:
[cpp]
- struct i2c_client { unsigned short flags; //设备的标志,如唤醒标志等等
- /* chip address - NOTE: 7bit */
- /* addresses are stored in the */ /* _LOWER_ 7 bits */
- unsigned short addr; //设备的地址 char name[I2C_NAME_SIZE]; //设备的名字
- struct i2c_adapter *adapter; //设备所属的适配器 struct i2c_driver *driver; //设备的driver
- /*
- * 内嵌的标准device模型,其中dev->type标识该设备 * 是个client,其值为i2c_client_type
- */ struct device dev; /* the device structure */
- int irq; //中断号 struct list_head detected; //挂接点,挂接在adapter
- };
下面是driver的表述结构i2c_driver:
[cpp]
- struct i2c_driver { unsigned int class; //支持的类型,与adapter的class相对
- /* Notifies the driver that a new bus has appeared or is about to be * removed. You should avoid using this if you can, it will probably
- * be removed in a near future. */
- int (*attach_adapter)(struct i2c_adapter *); //旧式探测函数
- int (*detach_adapter)(struct i2c_adapter *); /* Standard driver model interfaces */
- int (*probe)(struct i2c_client *, const struct i2c_device_id *); int (*remove)(struct i2c_client *);
- /* driver model interfaces that don't relate to enumeration */ void (*shutdown)(struct i2c_client *);
- int (*suspend)(struct i2c_client *, pm_message_t mesg); int (*resume)(struct i2c_client *);
- /* Alert callback, for example for the SMBus alert protocol. * The format and meaning of the data value depends on the protocol.
- * For the SMBus alert protocol, there is a single bit of data passed * as the alert response's low bit ("event flag").
- */ void (*alert)(struct i2c_client *, unsigned int data);
- /* a ioctl like command that can be used to perform specific functions * with the device.
- */ int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
- /* * 内嵌的标准driver,driver的of_match_table成员也用于标识其支持
- * 的设备,并且优先级高于id_table */
- struct device_driver driver;
- const struct i2c_device_id *id_table; //支持的client信息表 /* Device detection callback for automatic device creation */
- int (*detect)(struct i2c_client *, struct i2c_board_info *); //探测函数
- const unsigned short *address_list; //driver支持的client地址 struct list_head clients; //挂接其探测到的支持的设备
- ;
另外client端有一条全局链表,用于串联所有i2c的client设备,为__i2c_board_list,也就是说client可以静态注册亦可动态
被探测,静态注册挂接在该链表上的结构为:
[cpp]
- struct i2c_devinfo { struct list_head list; //连接指针指向前后设备
- int busnum; //所在bus的编号 struct i2c_board_info board_info; //板级平台信息相关的结构体
- }; //其中 i2c_board_info结构的源码为:
- struct i2c_board_info { char type[I2C_NAME_SIZE]; //名字
- unsigned short flags; //标志 unsigned short addr; //地址
- void *platform_data; //私有特殊数据 struct dev_archdata *archdata;
- #ifdef CONFIG_OF struct device_node *of_node; //节点
- #endi int irq; //中断号
- };
i2c_devinfo结构静态注册的信息最后都会被整合集成到client中,形成一个标准的i2c_client设备并注册。
此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/58036.html