linux中i2c驱动的匹配方式

linux中i2c驱动的匹配方式

内核中匹配方式有3种:

OF style match
ACPI style match
i2c id table

先直接上代码: linux 3.10.y分支:

static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
	struct i2c_client	*client = i2c_verify_client(dev);
	struct i2c_driver	*driver;

	if (!client)
		return 0;

	/* Attempt an OF style match */
	if (of_driver_match_device(dev, drv))
		return 1;

	/* Then ACPI style match */
	if (acpi_driver_match_device(dev, drv))
		return 1;

	driver = to_i2c_driver(drv);
	/* match on an id table if there is one */
	if (driver->id_table)
		return i2c_match_id(driver->id_table, client) != NULL;

	return 0;
}

1.OF style match

这是所有驱动通用的匹配方式:对应的是驱动和器件需要做,如下器件结构体的匹配.  最常见的是:compatible部分字符.

这在dts, dsti中最常见.  

struct of_device_id
{
    char    name[32];
    char    type[32];
    char    compatible[128];
    const void *data;
};

算法中,只要name或type,或compatible任一个匹配,就算匹配.

对应的driver需要有of_device_id, deice需要有of_node才能用这种方式.

匹配算法原代码如下面

struct of_device_id *of_match_device(const struct of_device_id *matches, const struct device *dev)
{
    if ((!matches) || (!dev->of_node))
        return NULL;
    return of_match_node(matches, dev->of_node);

}

const struct of_device_id *of_match_node(const struct of_device_id *matches, const struct         device_node *node)
{
    if (!matches)
        return NULL;

    while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
        int match = 1;

        if (matches->name[0])
            match &= node->name && !strcmp(matches->name, node->name);

        if (matches->type[0])
            match &= node->type && !strcmp(matches->type, node->type);

        if (matches->compatible[0])
            match &= of_device_is_compatible(node, matches->compatible);

        if (match)
            return matches;

        matches++;
    }
return NULL;
}

对于ACPI主要是用于电源管理的,需要有acpi对应的id,

struct acpi_device_id {
    __u8 id[ACPI_ID_LEN];
    kernel_ulong_t driver_data;
};

这个平时用得少,略过.

再看一下i2c专有的: id_table方式:

这种式方式:需要驱动有:id_table, 

struct i2c_device_id {
    char name[I2C_NAME_SIZE];
    kernel_ulong_t driver_data;    /* Data private to the driver */
};

匹配方式如下: 只需要匹配name 就行.  id表中的driver_data,只是一个参数,不参与匹配,只是在驱动运行时会使用.

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;
}

 

你可能感兴趣的:(linux,系统,driver)