三:adapter注册 在 kernel中提供了两个adapter注册接口,分别为i2c_add_adapter()和 i2c_add_numbered_adapter().由于在系统中可能存在多个adapter,因为将每一条I2C总线对应一个编号,下文中称为 I2C总线号.这个总线号的PCI中的总线号不同.它和硬件无关,只是软件上便于区分而已. 对于i2c_add_adapter()而言,它使用的是动态总线号,即由系统给其分析一个总线号,而i2c_add_numbered_adapter()则是自己指定总线号,如果这个总线号非法或者是被占用,就会注册失败. 分别来看一下这两个函数的代码: int i2c_add_adapter(struct i2c_adapter *adapter) { int id, res = 0;
retry: if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) return -ENOMEM;
mutex_lock(&core_lock); /* "above" here means "above or equal to", sigh */ res = idr_get_new_above(&i2c_adapter_idr, adapter, __i2c_first_dynamic_bus_num, &id); mutex_unlock(&core_lock);
if (res < 0) { if (res == -EAGAIN) goto retry; return res; }
看一下另外一人注册函数: i2c_add_numbered_adapter( ),如下所示: int i2c_add_numbered_adapter(struct i2c_adapter *adap) { int id; int status;
if (adap->nr & ~MAX_ID_MASK) return -EINVAL;
retry: if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) return -ENOMEM;
mutex_lock(&core_lock); /* "above" here means "above or equal to", sigh; * we need the "equal to" result to force the result */ status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id); if (status == 0 && id != adap->nr) { status = -EBUSY; idr_remove(&i2c_adapter_idr, id); } mutex_unlock(&core_lock); if (status == -EAGAIN) goto retry;
if (status == 0) status = i2c_register_adapter(adap); return status; } 对比一下就知道差别了,在这里它已经指定好了adapter->nr了.如果分配的id不和指定的相等,便返回错误.
过一步跟踪i2c_register_adapter().代码如下: static int i2c_register_adapter(struct i2c_adapter *adap) { int res = 0, dummy;
/* Add the adapter to the driver core. * If the parent pointer is not set up, * we add this adapter to the host bus. */ if (adap->dev.parent == NULL) { adap->dev.parent = &platform_bus; pr_debug("I2C adapter driver [%s] forgot to specify " "physical device\n", adap->name); } sprintf(adap->dev.bus_id, "i2c-%d", adap->nr); adap->dev.release = &i2c_adapter_dev_release; adap->dev.class = &i2c_adapter_class; res = device_register(&adap->dev); if (res) goto out_list;
/* dynamic bus numbers will be assigned after the last static one */ if (busnum >= __i2c_first_dynamic_bus_num) __i2c_first_dynamic_bus_num = busnum + 1;
/* a new style driver may be bound to this device when we * return from this function, or any later moment (e.g. maybe * hotplugging will load the driver module). and the device * refcount model is the standard driver model one. */ status = i2c_attach_client(client); if (status < 0) { kfree(client); client = NULL; } return client; } 我们又遇到了一个新的结构:struct i2c_client,不要被这个结构吓倒了,其实它就是一个嵌入struct device的I2C设备的封装.它和我们之前遇到的struct usb_device结构的作用是一样的. 首先,在clinet里保存该设备的相关消息.特别的, client->adapter指向了它所在的adapter. 特别的,clinet->name为info->name.也是指定好了的. 一切初始化完成之后,便会调用i2c_attach_client( ).看这个函数的字面意思,是将clinet关联起来.到底怎么样关联呢?继续往下看: int i2c_attach_client(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; int res = 0;
dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n", client->name, client->dev.bus_id); //如果adapter->cleinet_reqister存在,就调用它 if (adapter->client_register) { if (adapter->client_register(client)) { dev_dbg(&adapter->dev, "client_register " "failed for client [%s] at 0x%02x\n", client->name, client->addr); } }
if (driver->attach_adapter) { /* We ignore the return code; if it fails, too bad */ driver->attach_adapter(adap); } return 0; } 该函数很简单,就是调用driver的attach_adapter()接口. 到此为止,adapter的注册已经分析完了.
四:i2c driver注册 在分析i2c driver的时候,有必要先分析一下i2c架构的初始化 代码如下: static int __init i2c_init(void) { int retval;
retval = bus_register(&i2c_bus_type); if (retval) return retval; retval = class_register(&i2c_adapter_class); if (retval) goto bus_err; retval = i2c_add_driver(&dummy_driver); if (retval) goto class_err; return 0;
这个结构先放在这里吧,以后还会用到里面的信息的. 从上面的初始化函数里也看到了,注册i2c driver的接口为i2c_add_driver().代码如下: static inline int i2c_add_driver(struct i2c_driver *driver) { return i2c_register_driver(THIS_MODULE, driver); } 继续跟踪: int i2c_register_driver(struct module *owner, struct i2c_driver *driver) { int res;
/* new style driver methods can't mix with legacy ones */ //如果是一个newstyle的driver.但又定义了attach_adapter/detach_adapter.非法 if (is_newstyle_driver(driver)) { if (driver->attach_adapter || driver->detach_adapter || driver->detach_client) { printk(KERN_WARNING "i2c-core: driver [%s] is confused\n", driver->driver.name); return -EINVAL; } }
/* add the driver to the list of i2c drivers in the driver core */ //关联到i2c_bus_types driver->driver.owner = owner; driver->driver.bus = &i2c_bus_type;
/* for new style drivers, when registration returns the driver core * will have called probe() for all matching-but-unbound devices. */ //注册内嵌的driver res = driver_register(&driver->driver); if (res) return res;
/* make legacy i2c drivers bypass driver model probing entirely; * such drivers scan each i2c adapter/bus themselves. */ if (!is_newstyle_driver(driver)) return 0;
/* match on an id table if there is one */ if (driver->id_table) return i2c_match_id(driver->id_table, client) != NULL;
if (!driver->probe) return -ENODEV; client->driver = driver; dev_dbg(dev, "probe\n");
if (driver->id_table) id = i2c_match_id(driver->id_table, client); else id = NULL; status = driver->probe(client, id); if (status) client->driver = NULL; return status; } 这个函数也很简单,就是将probe流程回溯到i2c driver的probe()
#define I2C_CLIENT_MODULE_PARM_FORCE(name) \ I2C_CLIENT_MODULE_PARM(force_##name, \ "List of adapter,address pairs which are " \ "unquestionably assumed to contain a `" \ # name "' chip")
#define I2C_CLIENT_INSMOD_COMMON \ I2C_CLIENT_MODULE_PARM(probe, "List of adapter,address pairs to scan " \ "additionally"); \ I2C_CLIENT_MODULE_PARM(ignore, "List of adapter,address pairs not to " \ "scan"); \ static const struct i2c_client_address_data addr_data = { \ .normal_i2c = normal_i2c, \ .probe = probe, \ .ignore = ignore, \ .forces = forces, \ }
#define I2C_CLIENT_FORCE_TEXT \ "List of adapter,address pairs to boldly assume to be present" 由此可知道,addr_data中的三个成员都是模块参数.在加载模块的时候可以用参数的方式对其赋值.三个模块参数为别为probe,ignore,force.另外需要指出的是normal_i2c不能以模块参数的方式对其赋值,只能在驱动内部静态指定. 从模块参数的模述看来, probe是指"List of adapter,address pairs to scan additionally" Ignore是指"List of adapter,address pairs not to scan " Force是指"List of adapter,address pairs to boldly assume to be present" 事实上,它们里面的数据都是成对出现的.前面一部份表示所在的总线号,ANY_I2C_BUS表示任一总线.后一部份表示设备的地址. 现在可以来跟踪i2c_probe()的代码了.如下: int i2c_probe(struct i2c_adapter *adapter, const struct i2c_client_address_data *address_data, int (*found_proc) (struct i2c_adapter *, int, int)) { int i, err; int adap_id = i2c_adapter_id(adapter);
/* Force entries are done first, and are not affected by ignore entries */ //先扫描force里面的信息,注意它是一个二级指针.ignore里的信息对它是无效的 if (address_data->forces) { const unsigned short * const *forces = address_data->forces; int kind;
for (kind = 0; forces[kind]; kind++) { for (i = 0; forces[kind] != I2C_CLIENT_END; i += 2) { if (forces[kind] == adap_id || forces[kind] == ANY_I2C_BUS) { dev_dbg(&adapter->dev, "found force " "parameter for adapter %d, " "addr 0x%02x, kind %d\n", adap_id, forces[kind][i + 1], kind); err = i2c_probe_address(adapter, forces[kind][i + 1], kind, found_proc); if (err) return err; } } } }
/* Stop here if we can't use SMBUS_QUICK */ //如果adapter不支持quick.不能够遍历这个adapter上面的设备 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) { if (address_data->probe[0] == I2C_CLIENT_END && address_data->normal_i2c[0] == I2C_CLIENT_END) return 0;
dev_warn(&adapter->dev, "SMBus Quick command not supported, " "can't probe for chips\n"); return -1; }
/* Probe entries are done second, and are not affected by ignore entries either */ //遍历probe上面的信息.ignore上的信息也对它是没有影响的 for (i = 0; address_data->probe != I2C_CLIENT_END; i += 2) { if (address_data->probe == adap_id || address_data->probe == ANY_I2C_BUS) { dev_dbg(&adapter->dev, "found probe parameter for " "adapter %d, addr 0x%02x\n", adap_id, address_data->probe[i + 1]); err = i2c_probe_address(adapter, address_data->probe[i + 1], -1, found_proc); if (err) return err; } }
/* Normal entries are done last, unless shadowed by an ignore entry */ //最后遍历normal_i2c上面的信息.它上面的信息不能在ignore中. for (i = 0; address_data->normal_i2c != I2C_CLIENT_END; i += 1) { int j, ignore;
dev_dbg(&adapter->dev, "found normal entry for adapter %d, " "addr 0x%02x\n", adap_id, address_data->normal_i2c); err = i2c_probe_address(adapter, address_data->normal_i2c, -1, found_proc); if (err) return err; }
return 0; } 这段代码很简单,结合代码上面添加的注释应该很好理解.如果匹配成功,则会调用i2c_probe_address ().这个函数代码如下: static int i2c_probe_address(struct i2c_adapter *adapter, int addr, int kind, int (*found_proc) (struct i2c_adapter *, int, int)) { int err;
/* Make sure the address is valid */ //地址小于0x03或者大于0x77都是不合法的 if (addr < 0x03 || addr > 0x77) { dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n", addr); return -EINVAL; }
/* Skip if already in use */ //adapter上已经有这个设备了 if (i2c_check_addr(adapter, addr)) return 0;
/* Make sure there is something at this address, unless forced */ //如果kind小于0.检查adapter上是否有这个设备 if (kind < 0) { if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0) return 0;
/* Finally call the custom detection function */ //调用回调函数 err = found_proc(adapter, addr, kind); /* -ENODEV can be returned if there is a chip at the given address but it isn't supported by this chip driver. We catch it here as this isn't an error. */ if (err == -ENODEV) err = 0;
在上面涉及到了IIC的传输方式,有疑问的可以参考intel ICH5手册的有关smbus部份. 跟踪i2c_smbus_xfer().代码如下: s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) { s32 res;
flags &= I2C_M_TEN | I2C_CLIENT_PEC;
if (adapter->algo->smbus_xfer) { mutex_lock(&adapter->bus_lock); res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, command,size,data); mutex_unlock(&adapter->bus_lock); } else res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, command,size,data);
return res; } 如果adapter有smbus_xfer()函数,则直接调用它发送,否则,也就是在adapter不支持smbus协议的情况下,调用i2c_smbus_xfer_emulated()继续处理. 跟进i2c_smbus_xfer_emulated().代码如下: static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data) { /* So we need to generate a series of msgs. In the case of writing, we need to use only one message; when reading, we need two. We initialize most things with sane defaults, to keep the code below somewhat simpler. */ //写操作只会进行一次交互,而读操作,有时会有两次操作. //因为有时候读操作要先写command,再从总线上读数据 //在这里为了代码的简洁.使用了两个缓存区,将两种情况统一起来. unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; //一般来说,读操作要交互两次.例外的情况我们在下面会接着分析 int num = read_write == I2C_SMBUS_READ?2:1; //与设备交互的数据,一般在msg[0]存放写入设备的信息,在msb[1]里存放接收到的 //信息.不过也有例外的 //msg[2]的初始化,默认发送缓存区占一个字节,无接收缓存 struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, { addr, flags | I2C_M_RD, 0, msgbuf1 } }; int i; u8 partial_pec = 0;
//将要发送的信息copy到发送缓存区的第一字节 msgbuf0[0] = command; switch(size) { //quick类型的,其它并不传输有效数据,只是将地址写到总线上,等待应答即可 //所以将发送缓存区长度置为0 .再根据读/写操作,调整msg[0]的标志位 //这类传输只需要一次总线交互 case I2C_SMBUS_QUICK: msg[0].len = 0; /* Special case: The read/write field is used as data */ msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0; num = 1; break; case I2C_SMBUS_BYTE: //BYTE类型指一次写和读只有一个字节.这种情况下,读和写都只会交互一次 //这种类型的读有例外,它读取出来的数据不是放在msg[1]中的,而是存放在msg[0] if (read_write == I2C_SMBUS_READ) { /* Special case: only a read! */ msg[0].flags = I2C_M_RD | flags; num = 1; } break; case I2C_SMBUS_BYTE_DATA: //Byte_Data是指命令+数据的传输形式.在这种情况下,写只需要一次交互,读却要两次 //第一次将command写到总线上,第二次要转换方向.要将设备地址和read标志写入总线. //应回答之后再进行read操作 //写操作占两字节,分别是command+data.读操作的有效数据只有一个字节 //交互次数用初始化值就可以了 if (read_write == I2C_SMBUS_READ) msg[1].len = 1; else { msg[0].len = 2; msgbuf0[1] = data->byte; } break; case I2C_SMBUS_WORD_DATA: //Word_Data是指命令+双字节的形式.这种情况跟Byte_Data的情况类似 //两者相比只是交互的数据大小不同 if (read_write == I2C_SMBUS_READ) msg[1].len = 2; else { msg[0].len=3; msgbuf0[1] = data->word & 0xff; msgbuf0[2] = data->word >> 8; } break; case I2C_SMBUS_PROC_CALL: //Proc_Call的方式与write 的Word_Data相似,只不过写完Word_Data之后,要等待它的应答 //应该它需要交互两次,一次写一次读 num = 2; /* Special case */ read_write = I2C_SMBUS_READ; msg[0].len = 3; msg[1].len = 2; msgbuf0[1] = data->word & 0xff; msgbuf0[2] = data->word >> 8; break; case I2C_SMBUS_BLOCK_DATA: //Block_Data:指command+N段数据的情况. //如果是读操作,它首先要写command到总线,然后再读N段数据.要写的command已经 //放在msg[0]了.现在只需要将msg[1]的标志置I2C_M_RECV_LEN位,msg[1]有效长度为1字节.因为 //adapter驱动会处理好的.现在现在还不知道要传多少段数据.
//对于写的情况:msg[1]照例不需要.将要写的数据全部都放到msb[0]中.相应的也要更新 //msg[0]中的缓存区长度 if (read_write == I2C_SMBUS_READ) { msg[1].flags |= I2C_M_RECV_LEN; msg[1].len = 1; /* block length will be added by the underlying bus driver */ } else { //data->block[0]表示后面有多少段数据.总长度要加2是因为command+count+N段数据 msg[0].len = data->block[0] + 2; if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { dev_err(&adapter->dev, "smbus_access called with " "invalid block write size (%d)\n", data->block[0]); return -1; } for (i = 1; i < msg[0].len; i++) msgbuf0 = data->block[i-1]; } break; case I2C_SMBUS_BLOCK_PROC_CALL: //Proc_Call:表示写完Block_Data之后,要等它的应答消息它和Block_Data相比,只是多了一部份应答而已 num = 2; /* Another special case */ read_write = I2C_SMBUS_READ; if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { dev_err(&adapter->dev, "%s called with invalid " "block proc call size (%d)\n", __func__, data->block[0]); return -1; } msg[0].len = data->block[0] + 2; for (i = 1; i < msg[0].len; i++) msgbuf0 = data->block[i-1]; msg[1].flags |= I2C_M_RECV_LEN; msg[1].len = 1; /* block length will be added by the underlying bus driver */ break; case I2C_SMBUS_I2C_BLOCK_DATA: //I2c Block_Data与Block_Data相似,只不过read的时候,数据长度是预先定义好了的.另外 //与Block_Data相比,中间不需要传输Count字段.(Count表示数据段数目) if (read_write == I2C_SMBUS_READ) { msg[1].len = data->block[0]; } else { msg[0].len = data->block[0] + 1; if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) { dev_err(&adapter->dev, "i2c_smbus_xfer_emulated called with " "invalid block write size (%d)\n", data->block[0]); return -1; } for (i = 1; i <= data->block[0]; i++) msgbuf0 = data->block; } break; default: dev_err(&adapter->dev, "smbus_access called with invalid size (%d)\n", size); return -1; }
//如果启用了PEC.Quick和I2c Block_Data是不支持PEC的 i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA); if (i) { /* Compute PEC if first message is a write */ //如果第一个操作是写操作 if (!(msg[0].flags & I2C_M_RD)) { //如果只是写操作 if (num == 1) /* Write only */ //如果只有写操作,写缓存区要扩充一个字节,用来存放计算出来的PEC i2c_smbus_add_pec(&msg[0]); else /* Write followed by read */ //如果后面还有读操作,先计算前面写部份的PEC(注意这种情况下不需要 //扩充写缓存区,因为不需要发送PEC.只会接收到PEC) partial_pec = i2c_smbus_msg_pec(0, &msg[0]); } /* Ask for PEC if last message is a read */ //如果最后一次是读消息.还要接收到来自slave的PEC.所以接收缓存区要扩充一个字节 if (msg[num-1].flags & I2C_M_RD) msg[num-1].len++; }
if (i2c_transfer(adapter, msg, num) < 0) return -1;
/* Check PEC if last message is a read */ //操作完了之后,如果最后一个操作是PEC的读操作.检验后面的PEC是否正确 if (i && (msg[num-1].flags & I2C_M_RD)) { if (i2c_smbus_check_pec(partial_pec, &msg[num-1]) < 0) return -1; }
//操作完了,现在可以将数据放到data部份返回了. if (read_write == I2C_SMBUS_READ) switch(size) { case I2C_SMBUS_BYTE: data->byte = msgbuf0[0]; break; case I2C_SMBUS_BYTE_DATA: data->byte = msgbuf1[0]; break; case I2C_SMBUS_WORD_DATA: case I2C_SMBUS_PROC_CALL: data->word = msgbuf1[0] | (msgbuf1[1] << 8); break; case I2C_SMBUS_I2C_BLOCK_DATA: for (i = 0; i < data->block[0]; i++) data->block[i+1] = msgbuf1; break; case I2C_SMBUS_BLOCK_DATA: case I2C_SMBUS_BLOCK_PROC_CALL: for (i = 0; i < msgbuf1[0] + 1; i++) data->block = msgbuf1; break; } return 0; } 在这个函数添上了很详细的注释,配和intel的datasheet,应该很容易看懂.在上面的交互过程中,调用了子函数i2c_transfer().它的代码如下所示: int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) { int ret;
i2c_dev = get_free_i2c_dev(adap); if (IS_ERR(i2c_dev)) return PTR_ERR(i2c_dev);
/* register this i2c device with the driver core */ i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, MKDEV(I2C_MAJOR, adap->nr), "i2c-%d", adap->nr); if (IS_ERR(i2c_dev->dev)) { res = PTR_ERR(i2c_dev->dev); goto error; } res = device_create_file(i2c_dev->dev, &dev_attr_name); if (res) goto error_destroy;
static int i2cdev_open(struct inode *inode, struct file *file) { unsigned int minor = iminor(inode); struct i2c_client *client; struct i2c_adapter *adap; struct i2c_dev *i2c_dev;
//以次设备号从i2c_dev_list链表中取得i2c_dev i2c_dev = i2c_dev_get_by_minor(minor); if (!i2c_dev) return -ENODEV;
//以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;
/* If everything went ok (i.e. 1 msg transmitted), return #bytes transmitted, else error code. */ return (ret == 1) ? count : ret; } 看 完前面的代码之后,这个函数应该很简单了,就是为读操作初始化了一个i2c_msg.然后调用i2c_tanster().代码中的 client->flags & I2C_M_TEN表示adapter是否采用10位寻址的方式.在这里就不再详细分析了. 另 外,有人可能看出了一个问题.这里clinet->addr是从哪来的呢?对,在read之前应该还要有一步操作来设置 clinet->addr的值.这个过程是ioctl的操作.ioctl可以设置PEC标志,重试次数,超时时间,和发送接收数据等,我们在这里只 看一下clinet->addr的设置.代码片段如下示: static int i2cdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { ...... ...... switch ( cmd ) { case I2C_SLAVE: case I2C_SLAVE_FORCE: /* NOTE: devices set up to work with "new style" drivers * can't use I2C_SLAVE, even when the device node is not * bound to a driver. Only I2C_SLAVE_FORCE will work. * * Setting the PEC flag here won't affect kernel drivers, * which will be using the i2c_client node registered with * the driver model core. Likewise, when that client has * the PEC flag already set, the i2c-dev driver won't see * (or use) this setting. */ if ((arg > 0x3ff) || (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) return -EINVAL; if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg)) return -EBUSY; /* REVISIT: address could become busy later */ client->addr = arg; return 0; ...... ...... } 由 此可见,调用I2C_SLAVE或者I2C_SLAVE_FORCE的Ioctl就会设置clinet->addr.另外,注释中也说得很清楚了. 如果是I2C_SLAVE的话,还会调用其所长i2cdev_check_addr().进行地址检查,如果adapter已经关联到这个地址的设备,就 会检查失败.