一,Struct i2c_board_info :创建设备的模板,这个结构体用来创造一个i2c设备的信息列表。由i2c_register_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;
#endif
int irq; };
解析:
type:芯片的类型,用来初始化i2c_client.name. flags:用来初始化i2c_cllient.flags.
addr:存储i2c_client.addr.
platform_data:存储i2c_client.dev.platform_data archdata:拷贝到i2c_client.dev.archdata irq:保存i2c_client.irq.
二,Struct i2c_adapter 是一个用于物理i2c总线的结构体,包括算法
struct i2c_adapter {
struct module *owner;
unsigned int id; //algorithm的类型,以I2C_ALGO_开始
unsigned int class; /* classes to allow probing for */
const struct i2c_algorithm *algo; /* the algorithm to access the bus */
void *algo_data; //algorithm数据
/* data fields that are valid for all devices */
struct rt_mutex bus_lock;
int timeout; /* in jiffies */
int retries; //重试次数
struct device dev; /* the adapter device */
int nr;
char name[48]; //适配器的名字
struct completion dev_released;//用于同步
struct list_head userspace_clients; };
三,struct i2c_client:表示一个i2c从设备。指定了一个单一的设备(比如一个芯片)连接到一个I2 c总线上。
struct i2c_client {
unsigned short flags; /* div., see below */
unsigned short addr; /* chip address - NOTE: 7bit */
/* addresses are stored in the */
/* _LOWER_ 7 bits */
char name[I2C_NAME_SIZE];
struct i2c_adapter *adapter; /* the adapter we sit on */
struct i2c_driver *driver; /* and our access routines */
struct device dev; /* the device structure */
int irq; /* irq issued by device */
struct list_head detected; };
解析:
flags:I2C_CLIENT_TEN:表示设备使用十位芯片寻址;I2C_CLIENT_PEC:表示使用SMBus错误检测包
addr:用于在I2C总线上连接当前适配器的地址。 name:指示设备的类型,通常是芯片的名字。 adapter:拥有这个设备的总线适配器 driver:设备的驱动 dev:从设备的驱动设备
irq:指定由该设备产生的IRQ
detected:i2c_driver.client列表的数字
I2C设备(BMA150)注册到I2C总线上的过程:(kernel/drivers/input/misc/bma150.c)
BMA150_init() → bma150_attach_adapter();
进入bma150_attach_adapter()进行分析,原型代码如下:
int bma150_attach_adapter(void) {
struct i2c_board_info info;
struct i2c_adapter *adapter;
struct i2c_client *client;
printk(\
adapter = i2c_get_adapter(I2C_BUS_NUM);
//I2C_BUS_NUM是210板卡上面的I2C总线的号码,选择要挂载的I2C总线
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, SENSOR_NAME, I2C_NAME_SIZE);//将BMA150名字放入i2c_board_info中
info.addr = BMA150_I2C_ADDR; //地址填充
client = i2c_new_device(adapter, &info);//创建一个新的I2C设备,bind在I2C上
if (!client)
{
printk(\
return -ENODEV;
}
return 0; }
i2c_get_adapter(I2C_BUS_NUM);得到I2C_BUS_NUM上的适配器,它的原型为:
struct i2c_adapter *i2c_get_adapter(int id)
{
struct i2c_adapter *adapter;
mutex_lock(&core_lock);
adapter = idr_find(&i2c_adapter_idr, id);
if (adapter && !try_module_get(adapter->owner))
adapter = NULL;
mutex_unlock(&core_lock);
return adapter; }
i2c_new_device(adapter, &info);的原型为:
(创建一个i2c设备,当我们从这个函数返回时,驱动可能绑定了这个设备) struct i2c_client *
i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) {
struct i2c_client *client;
int status;
client = kzalloc(sizeof *client, GFP_KERNEL);
if (!client)
return NULL;
client->adapter = adap;
//将选择的I2C总线适配器填充到client。
client->dev.platform_data = info->platform_data;//进行衔接