You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单I2C总线中同地址双I2C设备的DTS配置及适配问题求助

解决同I2C地址不同设备的绑定与检测问题

核心问题分析

同一I2C总线上无法同时注册两个相同地址的设备,这是Linux I2C子系统的固有限制。你当前的DTS同时声明device1@30和device2@30,会直接导致总线初始化时设备绑定冲突,其中一个设备必然无法完成绑定,后续的寄存器读取自然会失败。


解决方案

1. 针对不同电路板拆分DTS配置

如果两块电路板使用独立固件,最直接的方式是通过条件编译或设备树覆盖(overlay),仅在对应板子的固件中声明当前存在的设备:

条件编译示例(DTS)

#ifdef CONFIG_BOARD_DEVICE1
device1@30 {
        compatible = "device1";
        reg = <0x30>;
        clock-mode = /bits/ 8 <1>;
        // 其他设备属性
};
#endif

#ifdef CONFIG_BOARD_DEVICE2
device2@30 {
        compatible = "device2";
        reg = <0x30>;
        clock-mode = /bits/ 8 <1>;
        // 其他设备属性
};
#endif

编译固件时,针对不同板子开启对应的CONFIG_BOARD_DEVICE1或CONFIG_BOARD_DEVICE2宏即可。

2. 单固件自动识别设备(通用驱动方案)

如果需要用同一份固件适配两块板子,不要在DTS中同时声明两个设备,而是声明一个通用占位节点,再在驱动中动态检测设备类型:

通用DTS节点

generic_i2c_device@30 {
        compatible = "generic-i2c-device";
        reg = <0x30>;
        clock-mode = /bits/ 8 <1>;
};

通用驱动实现(核心逻辑)

#include <linux/i2c.h>
#include <linux/module.h>

#define DEVICE_ID_REG_ADDR 0x00 // 根据实际设备的ID寄存器地址调整
#define DEVICE1_ID 0xAB         // device1的ID值
#define DEVICE2_ID 0xCD         // device2的ID值

static int generic_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
        int ret;
        u8 device_id;

        // 读取设备ID寄存器
        ret = i2c_smbus_read_byte_data(client, DEVICE_ID_REG_ADDR);
        if (ret < 0) {
                dev_err(&client->dev, "Failed to read device ID\n");
                return ret;
        }
        device_id = ret;

        // 根据ID绑定对应设备逻辑
        if (device_id == DEVICE1_ID) {
                dev_info(&client->dev, "Detected device1, initializing...");
                // 执行device1的初始化、注册字符设备等操作
        } else if (device_id == DEVICE2_ID) {
                dev_info(&client->dev, "Detected device2, initializing...");
                // 执行device2的初始化、注册字符设备等操作
        } else {
                dev_err(&client->dev, "Unknown device with ID 0x%x", device_id);
                return -ENODEV;
        }

        return 0;
}

static const struct of_device_id generic_i2c_of_match[] = {
        { .compatible = "generic-i2c-device" },
        { /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, generic_i2c_of_match);

static struct i2c_driver generic_i2c_driver = {
        .driver = {
                .name = "generic-i2c-device",
                .of_match_table = generic_i2c_of_match,
        },
        .probe = generic_i2c_probe,
};
module_i2c_driver(generic_i2c_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Generic I2C driver for device1/device2");

3. 排查检测失败的额外注意事项

你之前的驱动检测失败,本质是DTS地址冲突导致其中一个驱动的probe函数根本无法执行。修正DTS后,需单独验证每个设备的ID读取逻辑:

  • 确认ID寄存器地址、读取方式(SMBus字节读/I2C块读)与设备手册一致
  • 检查I2C总线的电气连接(上拉电阻、电平匹配)是否正常

内容的提问来源于stack exchange,提问作者Adil Saidi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:25:52