下面继续看咱们的adapter吧,有点枯燥,不过慢慢看,后面的路还长着呢,坚持哈!
下面这个函数是用静态的bus number来向系统增加一个adapter。在kernel中提供了两个adapter注册接口,分别为i2c_add_adapter()和i2c_add_numbered_adapter().由于在系统中可能存在多个adapter,因为将每一条I2C总线对应一个编号,下文中称为I2C总线号。对于i2c_add_adapter()而言,它使用的是动态总线号,即由系统给其分配一个总线号,而i2c_add_numbered_adapter()则是自己指定总线号,如果这个总线号非法或者是被占用,就会注册失败。高通的adapter驱动使用了i2c_add_numbered_adapter()注册,总线号最初保存在platform_data中。
int i2c_add_numbered_adapter(struct i2c_adapter *adap)
{
/*在这里涉及到一个idr结构.idr结构本来是为了配合page cache中的radix tree而设计的.在这里我们只需要知道,它是一种高效的搜索树,且这个树预先存放了一些内存.避免在内存不够的时候出现问题.所在,在往idr中插入结构的时候,首先要调用idr_pre_get()为它预留足够的空闲内存,然后再调用idr_get_new_above()将结构插入idr中,该函数以参数的形式返回一个id.以后凭这个id就可以在idr中找到相对应的结构了.注意一下idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id)的参数的含义,它是将adapter结构插入到i2c_adapter_idr中,存放位置的id必须要大于或者等于adap->nr,然后将对应的id号存放在adapter->nr中.调用i2c_register_adapter(adapter)对这个adapter进行进一步注册.
idr_pre_get(&i2c_adapter_idr, GFP_KERNEL)
status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id);
/*对adapter进一步注册*/
status = i2c_register_adapter(adap);
}
继续往下跟踪这个函数:
static int i2c_register_adapter(struct i2c_adapter *adap)
{
/*初始化adapter的一些成员变量*/
rt_mutex_init(&adap->bus_lock);
INIT_LIST_HEAD(&adap->userspace_clients);
/* Set default timeout to 1 second if not already set */
if (adap->timeout == 0)
adap->timeout = HZ;
/*初始化adapter dev成员,然后注册该dev*/
dev_set_name(&adap->dev, "i2c-%d", adap->nr);
adap->dev.bus = &i2c_bus_type;
adap->dev.type = &i2c_adapter_type;
res = device_register(&adap->dev);
/*扫描属于该总线的板级的i2C设备*/
if (adap->nr < __i2c_first_dynamic_bus_num)
i2c_scan_static_board_info(adap);
/*探测总线上的所有i2c设备驱动,同时完成client、driver、device、adapter的绑定*/
dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
__process_new_adapter);
}
这篇就分析到这里,下篇重点分析i2c_scan_static_board_info(adap);函数,该函数用到的内容在板级时进行了注册。