i2c 设备
drivers/i2c/i2c-core.c
static int i2c_device_match(struct device *dev, struct device_driver *drv);
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_driver *driver;
1. 前提
client 必须为非NULL
client->name为 设备节点中 compatible 属性的 第一个值 compatible = "xxx", "yyy"; 中的 "xxx"
2 共支持3种匹配方式
2.1 OF
of_driver_match_device(dev, drv)
2.2 ACPI
acpi_driver_match_device(dev, drv)
2.3 id table
driver->id_table
i2c_match_id(driver->id_table, client)
2.1 举例
node-i2c@40{
compatible = "xxx","yyy";
}
static const struct of_device_id ids[] = {
{ .compatible = "xxx"},
{ },
};
static const struct i2c_device_id i2c_ids[] = { { },
};
static struct i2c_driver i2c_device_driver = {
.driver = {
.name = "something_SUIBIAN_BUT_MUST_HAVE",
.owner = THIS_MODULE,
.of_match_table = ids,
},
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.id_table = i2c_ids,
};
2.3 举例
node-i2c@40{
compatible = "xxx","yyy";
}
static const struct i2c_device_id i2c_ids[] = {
{ .name = "xxx", },
{ },
};
static struct i2c_driver i2c_device_driver = {
.driver = {
.name = "something_SUIBIAN_BUT_MUST_HAVE",
.owner = THIS_MODULE,
},
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.id_table = i2c_ids,
};
匹配成功之后,也不一定回最终执行 probe 函数
匹配成功之后,还要检查 driver->id_table 是否为空, 注意 driver->id_table 不能为空
/sys/bus/i2c/devices/i2c-1 // i2c 控制器
/sys/bus/i2c/drivers/something_SUIBIAN_BUT_MUST_HAVE // i2c 驱动
sysfs_create_group 在 /sys/bus/i2c/devices/i2c-1 连接目录的 1-0040 下面
wit@vexpress:/sys/devices/platform/smb/smb:motherboard/smb:motherboard:iofpga@7,00000000/10002000.i2c/i2c-1/1-0040 # ls -l -R
.:
total 0
lrwxrwxrwx 1 0 0 0 Apr 20 14:04 driver -> ../../../../../../../../bus/i2c/drivers/something_SUIBIAN_BUT_MUST_HAVE
-r--r--r-- 1 0 0 4096 Apr 20 14:04 modalias
-r--r--r-- 1 0 0 4096 Apr 20 14:04 name
-rw-r--r-- 1 0 0 4096 Apr 20 14:04 node_one
-r--r--r-- 1 0 0 4096 Apr 20 14:04 node_two
drwxr-xr-x 2 0 0 0 Apr 20 14:04 power
lrwxrwxrwx 1 0 0 0 Apr 20 14:04 subsystem -> ../../../../../../../../bus/i2c
-rw-r--r-- 1 0 0 4096 Apr 20 14:04 uevent
./power:
total 0
-rw-r--r-- 1 0 0 4096 Apr 20 14:05 autosuspend_delay_ms
-rw-r--r-- 1 0 0 4096 Apr 20 14:05 control
-r--r--r-- 1 0 0 4096 Apr 20 14:05 runtime_active_time
-r--r--r-- 1 0 0 4096 Apr 20 14:05 runtime_status
-r--r--r-- 1 0 0 4096 Apr 20 14:05 runtime_suspended_time
wit@vexpress:/sys/bus/i2c/drivers/something_SUIBIAN_BUT_MUST_HAVE # ls -l
total 0
lrwxrwxrwx 1 0 0 0 Apr 20 14:08 1-0040 -> ../../../../devices/platform/smb/smb:motherboard/smb:motherboard:iofpga@7,00000000/10002000.i2c/i2c-1/1-0040
--w------- 1 0 0 4096 Apr 20 14:08 bind
--w------- 1 0 0 4096 Apr 20 14:08 uevent
--w------- 1 0 0 4096 Apr 20 14:08 unbind
static int i2c_device_probe (struct i2c_client *client, const struct i2c_device_id *id);
id->name:chip-name-i2c
id->driver_data:0
client->flags:0
client->addr:64
client->name:chip-name-i2c
client->irq:40
static int i2c_device_probe (struct i2c_client *client, const struct i2c_device_id *id);
client 到其他
获取 dev :client->dev
获取 设备树节点 :client->dev.of_node
获取驱动 :client->dev->driver
dev 到其他
struct i2c_client *client = to_i2c_client(dev);
client 这一层
bu21013_data->client = client;
i2c_set_clientdata(client, bu21013_data);
struct bu21013_ts_data *bu21013_data = i2c_get_clientdata(client);
struct i2c_client * client = bu21013_data->client;
device 这一层
dev->driver_data = bu21013_data;
struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev);
dev_get_platdata