drivers/i2c/algos/i2c-algo-bit.c 中有两个函数都是用来添加adapter的,
一个是动态添加i2c_add_adapter(),
一个是静态添加i2c_add_numbered_adapter(), numbered就是已经定好了adapter id号了的意思。
int i2c_bit_add_bus(struct i2c_adapter *adap)
{
int err;
err = i2c_bit_prepare_bus(adap);
if (err)
return err;
return i2c_add_adapter(adap);
}
EXPORT_SYMBOL(i2c_bit_add_bus);
int i2c_bit_add_numbered_bus(struct i2c_adapter *adap)
{
int err;
err = i2c_bit_prepare_bus(adap);
if (err)
return err;
return i2c_add_numbered_adapter(adap);
}
EXPORT_SYMBOL(i2c_bit_add_numbered_bus);
i2c_add_adapter() 的工作就是向系统,向/sys 注册i2c_adapter,以备后面的i2c操作。
/**
* i2c_add_adapter - declare i2c adapter, use dynamic bus number
* @adapter: the adapter to add
*
* This routine is used to declare an I2C adapter when its bus number
* doesn't matter. Examples: for I2C adapters dynamically added by
* USB links or PCI plugin cards.
*
* When this returns zero, a new bus number was allocated and stored
* in adap->nr, and the specified adapter became available for clients.
* Otherwise, a negative errno value is returned.
*/
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_lists);
/* "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_lists);
if (res < 0) {
if (res == -EAGAIN)
goto retry;
return res;
}
adapter->nr = id;
return i2c_register_adapter(adapter);
}
EXPORT_SYMBOL(i2c_add_adapter);
idr 机制是linux系统中的一种数据结构,一种方便检索的机制,idr的要完成的任务是给要管理的对象分配一个数字,可以通过这个数字找到要管理的对象。
网上一堆介绍idr的。
i2c_add_numbered_adapter() 也差不多,不过他的adapter->nr 不是动态申请的,是原先就静态分配好的。
/**
* i2c_add_numbered_adapter - declare i2c adapter, use static bus number
* @adap: the adapter to register (with adap->nr initialized)
*
* This routine is used to declare an I2C adapter when its bus number
* matters. Example: for I2C adapters from system-on-chip CPUs, or
* otherwise built in to the system's mainboard, and where i2c_board_info
* is used to properly configure I2C devices.
*
* If no devices have pre-been declared for this bus, then be sure to
* register the adapter before any dynamically allocated ones. Otherwise
* the required bus ID may not be available.
*
* When this returns zero, the specified adapter became available for
* clients using the bus number provided in adap->nr. Also, the table
* of I2C devices pre-declared using i2c_register_board_info() is scanned,
* and the appropriate driver model device nodes are created. Otherwise, a
* negative errno value is returned.
*/
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_lists);
/* "above&#