我的阅读习惯,转帖他人技术笔记。
一:前言
I2c是philips提出的外设总线.I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL.正因为这样,它方便了工程人员 的布线.另外,I2C是一种多主机控制总线.它和USB总线不同,USB是基于master-slave机制,任何设备的通信必须由主机发起才可以.而 I2C 是基于multi master机制.一同总线上可允许多个master.
三:adapter注册
在 kernel中提供了两个adapter注册接口,分别为i2c_add_adapter()和 i2c_add_numbered_adapter().由于在系统中可能存在多个adapter,因为将每一条I2C总线对应一个编号,下文中称为 I2C总线号.这个总线号的PCI中的总线号不同.它和硬件无关,只是软件上便于区分而已.
对于i2c_add_adapter()而言,它使用的是动态总线号,即由系统给其分析一个总线号,而i2c_add_numbered_adapter()则是自己指定总线号,如果这个总线号非法或者是被占用,就会注册失败.
分别来看一下这两个函数的代码: 略!详见:http://blog.csdn.net/hongjiujing/article/details/4098547
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//以apapter的总线号从i2c_adapter_idr中找到adapter
adap = i2c_get_adapter(i2c_dev->adap->nr);
if (!adap)
return -ENODEV;
/* This creates an anonymous i2c_client, which may later be
* pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE.
*
* This client is ** NEVER REGISTERED ** with the driver model
* or I2C core code!! It just holds private copies of addressing
* information and maybe a PEC flag.
*/
//分配并初始化一个i2c_client结构
client = kzalloc(sizeof(*client), GFP_KERNEL);
if (!client) {
i2c_put_adapter(adap);
return -ENOMEM;
}
snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
client->driver = &i2cdev_driver;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
adapter = i2c_get_adapter( i2c_set_data->i2c_bus);
if (!adapter) {
printk("%s: can't get i2c adapter %d\n",
__func__, i2c_set_data->i2c_bus);
err = -ENODEV;
goto err_driver;
}
client = i2c_new_device(adapter, &info);
if (!client) {
printk("%s: can't add i2c device at 0x%x\n",
__func__, (unsigned int)info.addr);
err = -ENODEV;
goto err_driver;
}
i2c_put_adapter(adapter);
ret = i2c_add_driver(driver);
if (ret != 0) {
printk("%s: can't add i2c driver\n", __func__);
err = -ENODEV;
goto err_driver;
}
return 0;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~