234 * struct i2c_board_info - template for device creation
235 * @type: chip type, to initialize i2c_client.name
236 * @flags: to initialize i2c_client.flags
237 * @addr: stored in i2c_client.addr
238 * @platform_data: stored in i2c_client.dev.platform_data
239 * @archdata: copied into i2c_client.dev.archdata
240 * @of_node: pointer to OpenFirmware device node
241 * @irq: stored in i2c_client.irq
242 *
243 * I2C doesn't actually support hardware probing, although controllers and
244 * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's
245 * a device at a given address. Drivers commonly need more information than
246 * that, such as chip type, configuration, associated IRQ, and so on.
247 *
248 * i2c_board_info is used to build tables of information listing I2C devices
249 * that are present. This information is used to grow the driver model tree.
250 * For mainboards this is done statically using i2c_register_board_info();
251 * bus numbers identify adapters that aren't yet available. For add-on boards,
252 * i2c_new_device() does this dynamically with the adapter already known.
253 */
254 struct i2c_board_info {
255 char type[I2C_NAME_SIZE];
256 unsigned short flags;
257 unsigned short addr;
258 void *platform_data;
259 struct dev_archdata *archdata;
260 struct device_node *of_node;
261 int irq;
262 };
263
264 /**
265 * I2C_BOARD_INFO - macro used to list an i2c device and its address
266 * @dev_type: identifies the device type
267 * @dev_addr: the device's address on the bus.
268 *
269 * This macro initializes essential fields of a struct i2c_board_info,
270 * declaring what has been provided on a particular board. Optional
271 * fields (such as associated irq, or device-specific platform_data)
272 * are provided using conventional syntax.
273 */
274 #define I2C_BOARD_INFO(dev_type, dev_addr) \
275 .type = dev_type, .addr = (dev_addr)
Probe方式(new style)
● 构建i2c_driver
和LEGACY方式一样,也需要构建i2c_driver,但是内容有所不同。
static struct i2c_driver pca953x_driver = {
.driver = {
.name= "pca953x",
},
.probe= pca953x_probe, //当有i2c_client和i2c_driver匹配时调用
.remove= pca953x_remove,//注销时调用
.id_table= pca953x_id,//匹配规则
};
● 注册i2c_driver
static int __init pca953x_init(void)
{
return i2c_add_driver(&pca953x_driver);
}
module_init(pca953x_init);
在注册i2c_driver的过程中,是将driver注册到了i2c_bus_type的总线上。此总线的匹配规则是:
static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
const struct i2c_client *client)
{
while (id->name[0]) {
if (strcmp(client->name, id->name) == 0)
return id;
id++;
}
return NULL;
}
可以看出是利用i2c_client的名称和id_table中的名称做匹配的。本驱动中的id_table为
static const struct i2c_device_id pca953x_id[] = {
{ "pca9534", 8, },
{ "pca9535", 16, },
{ "pca9536", 4, },
{ "pca9537", 4, },
{ "pca9538", 8, },
{ "pca9539", 16, },
{ "pca9554", 8, },
{ "pca9555", 16, },
{ "pca9557", 8, },
{ "max7310", 8, },
{ }
};
看到现在我们应该会有这样的疑问,在Adapter模式中,i2c_client是我们自己构造出来的,而现在的i2c_client是从哪来的呢?看看下面的解释
● 注册i2c_board_info
对于Probe模式,通常在平台代码中要完成i2c_board_info的注册。方法如下:
static struct i2c_board_info __initdata test_i2c_devices[] = {
{
I2C_BOARD_INFO("pca9555", 0x27),//pca9555为芯片名称,0x27为芯片地址
.platform_data = &pca9555_data,
},
{
I2C_BOARD_INFO("mt9v022", 0x48),
.platform_data = &iclink[0], /* With extender */
},
{
I2C_BOARD_INFO("mt9m001", 0x5d),
.platform_data = &iclink[0], /* With extender */
},
};
i2c_register_board_info(0, test_i2c_devices,ARRAY_SIZE(test_i2c_devices)); //注册
上面申请这个数组表示i2c总线上面有这么些设备,包含驱动名称,从地址地址,中断号什么的,还有私有数据结构
i2c_client就是在注册过程中构建的。但有一点需要注意的是i2c_register_board_info并没有EXPORT_SYMBOL给模块使用。
● 字符驱动注册
在Probe方式下,添加字符驱动的位置在pca953x_probe中。
static int __devinit pca953x_probe(struct i2c_client *client,const struct i2c_device_id *id)
{
……
/****字符设备驱动注册位置****/
……
return 0;
}
● 注销i2c_driver
static void __exit pca953x_exit(void)
{
i2c_del_driver(&pca953x_driver);
}
module_exit(pca953x_exit);
● 注销字符设备驱动
在Probe方式下,注销字符驱动的位置在pca953x_remove中。
static int __devinit pca953x_remove (struct i2c_client *client)
{
……
/****字符设备驱动注销的位置****/
……
return 0;
}
● I2C设备的数据交互方法(即:调用适配器操作设备的方法)和Adapter方式下相同。
函数初始化函数
i2c_register_board_info(0, msm_i2c_board_info,ARRAY_SIZE(msm_i2c_board_info));
这个函数相当于就会去注册i2c设备信息实现如下
int __init
i2c_register_board_info(int busnum,
struct i2c_board_info const *info, unsigned len)
{
int status;
mutex_lock(&__i2c_board_lock);
/* 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;
for (status = 0; len; len--, info++) {
struct i2c_devinfo *devinfo;
devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
if (!devinfo) {
pr_debug("i2c-core: can't register boardinfo!\n");
status = -ENOMEM;
break;
}
devinfo->busnum = busnum;
devinfo->board_info = *info;
list_add_tail(&devinfo->list, &__i2c_board_list);
}
mutex_unlock(&__i2c_board_lock);
return status;
}
现在回到函数i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len)中
list_add_tail(&devinfo->list, &__i2c_board_list);
这句话会将i2c设备添加到全局链表__i2c_board_list上面去
实际上到这里如果我们在arch这边的board——info里面定义了设备的话,那么这是i2c设别在这条链表上面了,
static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
{
struct i2c_devinfo *devinfo;
mutex_lock(&__i2c_board_lock);
list_for_each_entry(devinfo, &__i2c_board_list, list) {
if (devinfo->busnum == adapter->nr
&& !i2c_new_device(adapter,
&devinfo->board_info))
printk(KERN_ERR "i2c-core: can't create i2c%d-%04x\n",
i2c_adapter_id(adapter),
devinfo->board_info.addr);
}
mutex_unlock(&__i2c_board_lock);
}