文章目录
- I2C设备驱动开发
- I2C设备驱动的三种匹配方式
- (1)通用的匹配方式:OF style match
- (2)电源管理专用的匹配方式:ACPI style match
- (3)I2C专用的匹配方式:I2C id table
参考:
Linux驱动框架之i2c驱动框架解析
I2C设备驱动开发
我总结的图如下:
- 主要两个C文件:
- xxx.device.c:主要是实现
i2c_client
结构体,将这个文件编译出来的.ko文件称之为"设备驱动" - xxx.driver.c:主要是实现
i2c_driver
结构体,将这个文件编译出来的.ko文件称之为"主机驱动" - 主机驱动需要完成与硬件设备的匹配(设备树),然后实现字符设备接口(open,read,write,release,ioct…)一般会用MISC设备接口实现简单一点,就会在系统目录/dev/下生成对应的设备节点。
- 应用层软件和设备驱动就是通过上述的字符设备驱动生成的设备节点进行各种基本操作。
- xxx.device.c:主要是实现
我的实现的I2C设备驱动:
【RV1126】IIC驱动–EEPROM
【RV1126】IIC驱动–MAX30102
I2C设备驱动的三种匹配方式
文件地址:kernel/drivers/i2c/i2c-core-base.c
在线Linux源码位置查看:https://elixir.bootlin.com/linux/latest/source/drivers/i2c/i2c-core-base.c#L117
static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
struct i2c_client *client = i2c_verify_client(dev);
struct i2c_driver *driver;
/* Attempt an OF style match */
if (i2c_of_match_device(drv->of_match_table, client))
return 1;
/* Then ACPI style match */
if (acpi_driver_match_device(dev, drv))
return 1;
driver = to_i2c_driver(drv);
/* Finally an I2C match */
if (i2c_match_id(driver->id_table, client))
return 1;
return 0;
}
(1)通用的匹配方式:OF style match
这是所有的设备驱动匹配都适用的一种匹配方式,不仅限于I2C设备匹配,利用设备树(.dts,.dtsi)节点的字段进行配备。一般使用compatible
字段来进行匹配。
定义位置:kernel/include/linux/mod_devicetable.h
/*
* Struct used for matching a device
*/
struct of_device_id {
char name[32];
char type[32];
char compatible[128];
const void *data;
};
算法中,只要name或type,或compatible任一个匹配,就算匹配.
使用实例:
设备树中的:
&i2c4 {
status = "okay";
maxim@57 {
status = "okay";
compatible = "maxim,max30102";
reg = <0x57>;
};
};
驱动代码中的:
static const struct of_device_id max30102_of_match[] = {
{ .compatible = "maxim,max30102" },
{}
};
static struct i2c_driver driver =
{
.probe = rv1126_probe,
.remove = rv1126_remove,
.driver =
{
.name = "max30102",
.of_match_table = of_match_ptr(max30102_of_match),
},
};
由上可知,设备树中的compatible字段和结构体对象中的compatible成员是一致的,所以可以完成匹配。
(2)电源管理专用的匹配方式:ACPI style match
对于ACPI主要是用于电源管理的,需要有acpi对应的id。
定义位置:kernel/include/linux/mod_devicetable.h
struct acpi_device_id {
__u8 id[ACPI_ID_LEN];
kernel_ulong_t driver_data;
__u32 cls;
__u32 cls_msk;
};
这个平时用得少,略过。
(3)I2C专用的匹配方式:I2C id table
相比于OF style的设备匹配,I2C id表匹配是i2c专有的匹配方式: id_table方式:
定义位置:kernel/include/linux/mod_devicetable.h
struct i2c_device_id {
char name[I2C_NAME_SIZE];
kernel_ulong_t driver_data; /* Data private to the driver */
};
这种方式是比较常用的,有设备树后就用的少了。
使用实例:
&i2c4 {
status = "okay";
eeprom@50 {
status = "okay";
compatible = "atmel,at24c256B";
reg = <0x50>;
};
};
static struct i2c_device_id id_table[]=
{
{"eeprom", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, id_table);
static struct i2c_driver drv=
{
.probe=rv1126_probe,
.remove=rv1126_remove,
.driver=
{
.name="at24c256B",
},
.id_table=id_table
};