Linux Kernel I2C 控制器驱动开发指南
本文档旨在指导开发者如何在 Linux 内核中编写和注册 I2C 控制器驱动。
1. I2C 控制器驱动代码位置
在 Linux 内核中,I2C 控制器的驱动代码通常位于以下路径:
drivers/i2c/busses/
在这个目录中,每个 I2C 控制器的驱动通常都有一个独立的 C 文件。例如,i2c-bcm2835.c
、i2c-imx.c
等。
2. 将 I2C 控制器驱动注册进 Linux 框架
要将 I2C 控制器驱动注册进 Linux 框架,通常需要完成以下步骤:
2.1 定义并初始化 I2C 控制器的 i2c_adapter
结构体
static struct i2c_adapter my_i2c_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
.algo = &my_i2c_algorithm,
.dev.parent = &pdev->dev,
.nr = my_i2c_bus_number,
.name = "My I2C Adapter",
};
2.2 实现 I2C 控制器的操作函数
这些操作函数包括 master_xfer
、functionality
等,通常在 i2c_algorithm
结构体中定义。
static struct i2c_algorithm my_i2c_algorithm = {
.master_xfer = my_i2c_master_xfer,
.functionality = my_i2c_functionality,
};
2.3 注册 I2C 适配器
在驱动的 probe
函数中调用 i2c_add_adapter
将 I2C 适配器注册到 I2C 核心框架中。
static int my_i2c_probe(struct platform_device *pdev)
{
// 设备初始化代码
...
// 注册 I2C 适配器
ret = i2c_add_adapter(&my_i2c_adapter);
if (ret)
return ret;
...
}
2.4 注销 I2C 适配器
在驱动的 remove
函数中调用 i2c_del_adapter
注销 I2C 适配器。
static int my_i2c_remove(struct platform_device *pdev)
{
i2c_del_adapter(&my_i2c_adapter);
...
}
2.5 定义平台驱动结构体
包含 probe
和 remove
函数,并通过 module_platform_driver
宏进行注册。
static struct platform_driver my_i2c_driver = {
.probe = my_i2c_probe,
.remove = my_i2c_remove,
.driver = {
.name = "my_i2c",
.of_match_table = of_match_ptr(my_i2c_dt_ids),
},
};
module_platform_driver(my_i2c_driver);
3. my_i2c_functionality
函数的作用
my_i2c_functionality
函数在 I2C 控制器驱动中用于返回该 I2C 控制器所支持的功能。这些功能定义在 I2C 核心框架中,并以一组标志(flags)的形式表示。这些标志可以是对 I2C 核心框架提供的一些标准功能的支持,比如 10-bit 地址模式、多主模式等。
3.1 常见的功能标志
以下是一些常见的 I2C 功能标志,它们定义在 include/linux/i2c.h
文件中:
I2C_FUNC_I2C
: 标准 I2C-level 功能(读写传输)。I2C_FUNC_10BIT_ADDR
: 支持 10-bit 地址。I2C_FUNC_PROTOCOL_MANGLING
: 支持协议转换。I2C_FUNC_SMBUS_EMUL
: 支持 SMBus 仿真。I2C_FUNC_SMBUS_QUICK
: 支持 SMBus Quick 命令。I2C_FUNC_SMBUS_READ_BYTE
: 支持 SMBus 读字节命令。I2C_FUNC_SMBUS_WRITE_BYTE
: 支持 SMBus 写字节命令。I2C_FUNC_SMBUS_READ_BYTE_DATA
: 支持 SMBus 读字节数据命令。I2C_FUNC_SMBUS_WRITE_BYTE_DATA
: 支持 SMBus 写字节数据命令。I2C_FUNC_SMBUS_READ_WORD_DATA
: 支持 SMBus 读字数据命令。I2C_FUNC_SMBUS_WRITE_WORD_DATA
: 支持 SMBus 写字数据命令。I2C_FUNC_SMBUS_BLOCK_DATA
: 支持 SMBus 块数据传输。
3.2 示例
假设我们的 I2C 控制器支持标准 I2C 功能和 SMBus 仿真功能,那么 my_i2c_functionality
函数可以这样实现:
static u32 my_i2c_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
这个函数返回一个 32-bit 的整数,其中每个 bit 表示一个支持的功能。I2C 核心框架调用这个函数以了解该 I2C 控制器的能力,然后可以相应地执行不同的操作。