关于i2c_register_board_info()函数

  • Post author:
  • Post category:其他


i2c_register_board_info()函数用于往__i2c_board_list这条链表添加一条i2c设备信息,在i2c adapter注册的时候,会扫描__i2c_board_list链表,然后调用i2c_new_device()函数来注册i2c设备,注意,要先于i2c adapter注册之前就添加好i2c设备信息,否则会出现调用了i2c_register_board_info()函数,而设备不能注册的情况。

i2c_register_board_info()函数如下:

int __init
i2c_register_board_info(int busnum,
	struct i2c_board_info const *info, unsigned len)
{
	int status;

	down_write(&__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);
	}

	up_write(&__i2c_board_lock);

	return status;
}

注册i2c总线流程如下:

i2c_add_numbered_adapter()->i2c_register_adapter()

在i2c_register_adapter()函数中调用了i2c_scan_static_board_info()函数,代码如下:

static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
{
	struct i2c_devinfo	*devinfo;

	down_read(&__i2c_board_lock);
	list_for_each_entry(devinfo, &__i2c_board_list, list) {
		if (devinfo->busnum == adapter->nr
				&& !i2c_new_device(adapter,
						&devinfo->board_info))
			dev_err(&adapter->dev,
				"Can't create device at 0x%02x\n",
				devinfo->board_info.addr);
	}
	up_read(&__i2c_board_lock);
}

i2c_scan_static_board_info()函数先扫描__i2c_board_list,然后调用i2c_new_device()函数来注册i2c设备。这就是静态注册i2c设备的方法,一般在板级的初始化函数中调用i2c_register_board_info()函数来完成i2c设备信息的添加。

除了这种方法外,Linux还提供了另外的方法来注册i2c设备。例如:

static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };

static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
{
	(...)
	struct i2c_adapter *i2c_adap;
	struct i2c_board_info i2c_info;

	(...)
	i2c_adap = i2c_get_adapter(2);
	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
	strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE);
	isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
						   normal_i2c);
	i2c_put_adapter(i2c_adap);
	(...)
}

来自Documentation/i2c/instantiating-devices。



版权声明:本文为mcgrady_tracy原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。