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設備並注冊。