我对此的理解相当少,所以请耐心等待。根据我目前收集到的信息,Linux 上的 i2c 子系统识别出设备附加的,然后以某种方式将它们与加载的驱动程序模块进行匹配。当它识别到匹配时,它会调用该驱动程序的探测函数,该函数实际上会启动驱动程序设置。
我正在努力调试无法正常工作的相机;我可以看到 i2c 子系统发现它存在并在 中为其构建了目录/sys/bus/i2c/i2c-7
,并且我可以看出.probe_new()
该驱动程序的功能是不是调用,因为我向其中添加了一堆调试消息。因此,我猜测设备链接到驱动程序的步骤丢失了,但我无法弄清楚它是如何工作的。
谁能解释一下 i2c 子系统如何执行设备 -> 驱动程序匹配?
编辑:
为了清楚起见;我知道驱动程序声明它的名称为“ov2680”:
static const struct i2c_device_id ov2680[] = {
{"ov2680", 0},
{},
};
MODULE_DEVICE_TABLE(i2c, ov2680_id);
我不知道的是 i2c 子系统如何从设备尝试将其与驱动程序中声明的设备 ID 进行匹配?
答案1
I²C不支持设备枚举,因此内核提供初始化 I²C 设备的四种不同方法:
- 将它们列在设备树中(Warp i.MX7 板使用
ov2680
)、ACPI 表或板文件(忽略后者,它只是为了向后兼容而提供); - 当硬件“知道”它们存在时,显式地实例化它们(例如,这在电视适配器上很常见,它使用内部 I²C 总线来连接其各种组件);
- 在总线初始化期间探测它们;
- 从用户空间设置它们。
如果您知道总线上的地址,后者应该允许您强制探测设备:
echo ov2680 0x50 > /sys/bus/i2c/devices/i2c-7/new_device
一旦您验证了该方法有效,您就可以使用设备树或基于总线的探测找出需要在哪里添加设备自动初始化信息。内核文档(请参阅上面的第一个链接)应该可以帮助您朝着正确的方向前进。
根据您提到的评论OVTI2680
,我怀疑这里的问题是有两个 OmniVision OV2680 驱动程序,drivers/media/i2c/ov2680.c
和drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
。前者是使用 devicetree 找到的,后者是使用 ACPI 找到的,并且目录OVTI2680
中存在文件i2c
表明正在加载后者。