Linux I2C设备驱动升级指南:如何在新绑定模型中指定设备地址


阅读 8 次

从传统模式到新绑定模型的转变

在Linux内核的早期版本中,I2C设备驱动的编写方式相对简单直接。开发者通常会使用类似以下的代码来声明设备地址:

static unsigned short normal_i2c[] = { 0x67, I2C_CLIENT_END };
I2C_CLIENT_INSMOD;

但随着内核的发展,这种直接指定地址的方式已被更现代化的设备树(DTS)和ACPI绑定模型所取代。这种变化带来了更好的硬件抽象和配置灵活性,但也让不少习惯了旧方式的开发者感到困惑。

新模型下的地址指定方法

在新绑定模型中,设备地址主要通过以下几种方式指定:

1. 设备树(DTS)绑定方式

对于支持设备树的平台,最推荐的方式是通过.dts文件配置:

i2c1 {
    compatible = "vendor,i2c-controller";
    #address-cells = <1>;
    #size-cells = <0>;
    
    mydevice@67 {
        compatible = "vendor,mydevice";
        reg = <0x67>;
    };
};

2. ACPI绑定方式

对于使用ACPI的系统,可以在驱动中这样定义:

static struct i2c_device_id mydevice_id[] = {
    { "MYDEV", 0 },
    { }
};
MODULE_DEVICE_TABLE(i2c, mydevice_id);

3. 平台数据方式

如果设备不支持自动检测,也可以通过平台数据指定:

static struct i2c_board_info mydevice_info = {
    I2C_BOARD_INFO("mydevice", 0x67),
};

static struct i2c_client *client;
client = i2c_new_device(adapter, &mydevice_info);

实际驱动代码示例

下面是一个完整的新模型驱动示例:

#include 
#include 
#include 

static int mydevice_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
{
    /* 驱动初始化代码 */
    return 0;
}

static int mydevice_remove(struct i2c_client *client)
{
    /* 驱动卸载代码 */
    return 0;
}

static const struct of_device_id mydevice_of_match[] = {
    { .compatible = "vendor,mydevice" },
    { }
};
MODULE_DEVICE_TABLE(of, mydevice_of_match);

static const struct i2c_device_id mydevice_id[] = {
    { "mydevice", 0 },
    { }
};
MODULE_DEVICE_TABLE(i2c, mydevice_id);

static struct i2c_driver mydevice_driver = {
    .driver = {
        .name = "mydevice",
        .of_match_table = of_match_ptr(mydevice_of_match),
    },
    .probe = mydevice_probe,
    .remove = mydevice_remove,
    .id_table = mydevice_id,
};

module_i2c_driver(mydevice_driver);

MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("MyDevice I2C Driver");
MODULE_LICENSE("GPL");

常见问题解决

Q: 如何确认设备地址是否正确绑定?
A: 可以检查/sys/bus/i2c/devices目录下的设备节点,或使用dmesg查看内核日志。

Q: 设备不支持自动检测怎么办?
A: 这种情况下必须使用平台数据方式或设备树方式明确指定地址,不能依赖自动检测机制。

Q: 新旧驱动模型可以混用吗?
A: 不建议混用,新内核版本可能会逐步淘汰旧API,应该完全迁移到新模型。