在没有dts配置I2C硬件信息的情况下要怎么去适配I2C设备和对应的驱动匹配让驱动探测到设备并且让probe函数跑起来硬件信息CPU:海光平台Hygon3490I2C芯片at24c eep芯片 从设备地址0x57【可以跳电阻改地址】I2C总线I2C1在内核没有设备树DTS的情况下要加载 at24 驱动并指定硬件资源主要有两种标准方法。根据硬件信息的情况硬件连接在 I2C1设备地址 0x57我推荐使用 方法一。首先不能忘记把对应驱动编译进内核或者模块#以下宏定义二选一即可在对应defconfig文件配置 #eep驱动编译进内核 CONFIG_EEPROM_AT24y #或者编译成模块即ko CONFIG_EEPROM_AT24m方法一使用 i2c_board_info (推荐)这是在没有设备树的传统内核中最标准的方法。其核心思想是在板级初始化代码中通过 i2c_board_info 结构体静态描述设备信息。1. 定义 i2c_board_info 结构体你需要在板级初始化文件通常是 arch/xxx/mach-xxx/board-xxx.c 或类似文件中添加如下代码。这个结构体告诉内核“在名为 24c256 的设备其从设备地址是 0x57”。#include linux/i2c.h #include linux/platform_data/at24.h /* 如果驱动需要额外的平台数据可以在这里定义 */ static struct at24_platform_data eeprom_pdata { .byte_len 256 * 1024 / 8, /* 根据你的 EEPROM 型号设置例如 24c256 */ .page_size 64, /* 根据你的 EEPROM 型号设置 */ .flags AT24_FLAG_ADDR16, /* 根据你的 EEPROM 型号设置例如 16-bit 地址 */ }; static struct i2c_board_info __initdata my_i2c_board_info[] { { I2C_BOARD_INFO(24c256, 0x57), /* 驱动名称与设备地址 */ .platform_data eeprom_pdata, /* 可选如果需要 */ }, };2. 注册设备到 I2C 总线在同一个文件的板级初始化函数中例如 xxx_init(void)调用 i2c_register_board_info() 函数将上述设备信息注册到特定的 I2C 总线这里是 I2C1上。/* * 第一个参数是总线号对于 I2C1通常是 1。 * 具体编号需参考你的硬件手册或内核中 I2C 控制器的注册顺序。 */ i2c_register_board_info(1, my_i2c_board_info, ARRAY_SIZE(my_i2c_board_info));3. 重新编译内核并烧写完成上述修改后需要重新编译内核并将新生成的内核镜像烧写或者更新到海光平台上。重启后当 at24 驱动加载时它应该就能正确匹配到这个设备并执行 probe 函数了。或者如果没有板级配置文件或者不知道使用哪个板级配置文件也可以直接改到驱动里面去参考如下.flags I2C_DRV_ACPI_WAIVE_D0_PROBE, }; static struct i2c_client *at24_device_client; static int __init at24_init(void) { - if (!at24_io_limit) { - pr_err(at24: at24_io_limit must not be 0!\n); - return -EINVAL; - } struct i2c_adapter *adap; struct i2c_board_info info { .type 24c64, /* 匹配 at24_ids[] 中的 name */ .addr 0x57, /* 根据实际硬件修改24c64 常见 0x50~0x57 */ .flags 0, }; int ret; at24_io_limit rounddown_pow_of_two(at24_io_limit); - return i2c_add_driver(at24_driver); /* 1. 注册驱动 */ ret i2c_add_driver(at24_driver); if (ret) { pr_err(at24: driver registration failed (%d)\n, ret); return ret; } /* 2. 获取 I2C adapter总线号 1用 i2cdetect -l 确认你的总线号 */ adap i2c_get_adapter(1); if (!adap) { pr_err(at24: i2c adapter 1 not found\n); i2c_del_driver(at24_driver); return -ENODEV; } /* 3. 强行在总线上创建设备 */ at24_device_client i2c_new_client_device(adap, info); i2c_put_adapter(adap); if (IS_ERR(at24_device_client)) { ret PTR_ERR(at24_device_client); pr_err(at24: failed to create i2c client (%d)\n, ret); at24_device_client NULL; i2c_del_driver(at24_driver); return ret; } pr_info(at24: go to probe 24c64 at 0x%02x on i2c-%d\n,info.addr, adap-nr); return 0; } module_init(at24_init); static void __exit at24_exit(void) { if (at24_device_client) { i2c_unregister_device(at24_device_client); at24_device_client NULL; } i2c_del_driver(at24_driver); } module_exit(at24_exit);方法二通过 /sys 文件系统动态创建 (调试/临时)此方法适用于调试或临时测试不需要修改和编译内核。1. 加载驱动首先确保 at24 驱动模块已加载。insmod at24.ko # 或者如果已经编译进内核则此步可跳过2. 动态创建设备使用 echo 命令向 /sys/bus/i2c/devices/i2c-1/new_device 文件写入设备信息格式为 设备名称 设备地址。echo 24c256 0x57 /sys/bus/i2c/devices/i2c-1/new_device执行后内核会尝试在 I2C1 总线上创建一个地址为 0x57 的 24c256 设备并尝试与 at24 驱动进行匹配。方法三使用设备树覆盖层 (Device Tree Overlay)如果你的海光平台使用设备树但你想在不修改基础 DTS 的情况下添加设备可以使用设备树覆盖层 (DT Overlay)。创建一个 .dts 文件例如 eeprom-overlay.dts内容如下dts/dts-v1/; /plugin/; / { fragment1 { target i2c1; /* 假设 I2C1 在基础 DTS 中的标签是 i2c1 */ __overlay__ { #address-cells 1; #size-cells 0; eeprom57 { compatible atmel,24c256; /* 需要与驱动匹配 */ reg 0x57; }; }; }; };然后编译并加载这个 overlaydtc - -I dts -O dtb -o eeprom-overlay.dtbo eeprom-overlay.dts # 加载 overlay (具体命令可能因平台而异)关于at24驱动加载函数at24_init 函数使用 i2c_add_driver(at24_driver) 来注册驱动。这个操作本身只是告诉内核“我这里有 at24 这个驱动”。驱动与设备的匹配即 probe 函数的调用发生在内核遍历 I2C 设备列表时。因此关键在于“如何将这个设备信息放入内核的 I2C 设备列表”中这正是上面三种方法要解决的问题。重要检查与注意事项1. 确认 I2C 总线编号务必确认 I2C1 在内核中对应的总线编号是 1。可以通过 i2cdetect -l 命令查看系统中所有 I2C 总线及其编号。2. 确保驱动兼容at24 驱动是一个通用驱动它通过 compatible 或 i2c_device_id 来匹配设备。请确保 I2C_BOARD_INFO 中的名称如 24c256存在于 at24 驱动的 i2c_device_id 列表中。通常at24 驱动支持 24c256、atmel,24c256 等多种名称。3. 验证设备地址0x57 是标准的 7 位 I2C 设备地址不包含读写位。4. 检查 at24_io_limit你的 at24_init 函数中检查了 at24_io_limit如果它为 0 则加载失败。请确保在加载驱动前通过模块参数或其他方式正确设置了该值。总结一下最可靠的方法是修改板级文件使用 i2c_register_board_info 进行静态注册。如果只是想快速验证可以使用 /sys 文件系统接口。选择哪种方法取决于你的需求是永久性的解决方案还是临时性的调试。