Linux 设备树 (DTS):USB-I2C 桥上的 i2c 设备

Linux Device Tree (DTS): i2c device on USB-I2C bridge

我有一个 i2c 设备(触摸控制器)。通常,当它连接到 SoC i2c master(在我的例子中是一个 tegra 芯片)时,我会像这样将它添加到 .dts 文件中:

    i2c@7000c000 {
            st1332: touchscreen@55 {
                    compatible = "sitronix,st1232";
                    reg = <0x55>;
                    interrupt-parent = <&gpio>;
                    interrupts = <189 IRQ_TYPE_EDGE_FALLING>;
            };       
    };

在 SoC 的 .dtsi 文件中定义了 i2c 控制器 i2c@7000c000

    i2c1: i2c@7000c000 {
            #address-cells = <1>;
            #size-cells = <0>;
            compatible = "nvidia,tegra124-i2c";
            reg = <0x0 0x7000c000 0x0 0x100>;
            interrupts = <0 38 0x04>;
            scl-gpio = <&gpio 20 0>; /* gpio PC4 */
            sda-gpio = <&gpio 21 0>; /* gpio PC5 */
            nvidia,memory-clients = <14>;
            status = "okay";
            clock-frequency = <400000>;
    };

但是,我不想将触摸控制器连接到 SoC 的其中一个 i2c 主机。相反,我将它连接到 cp2112 USB 到 i2c 桥。

cp2112 驱动程序工作正常:我可以使用 i2cget 等命令从命令行访问它。但是我如何将它添加到 .dts 文件中,以便触摸控制器驱动程序与它对话?

因为 USB 设备是自动枚举的,所以我的 .dts 文件中没有可用作触摸控制器节点父节点的节点。我假设我需要在 usb 控制器下的 .dts 文件中创建一个占位符节点(在我的例子中是 xusb@70090000),然后内核将其与枚举的 USB 设备相关联,并将触摸控制器移动到这个节点,但我不知道该怎么做。 USB 设备的这种节点会是什么样子?或者有完全不同的解决方案吗?

我是 运行 Linux 3.10.40,带有来自 Linux v4.1.0-rc5.

的 hid-cp2112 的向后移植版本

由于 USB 设备枚举探测 hid-cp2112 驱动程序,它甚至不会尝试在设备树中找到自己。我已经为 hid-cp2112.c 创建了以下补丁,它将找到的 cp2112 设备链接到设备树中的 /i2c@cp2112 节点。 (当然这只适用于USB上只有一颗cp2112芯片的情况。)

diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c
index 2bd7f97..fa88590 100644
--- a/drivers/hid/hid-cp2112.c
+++ b/drivers/hid/hid-cp2112.c
@@ -31,6 +31,8 @@
 #include <linux/module.h>
 #include <linux/nls.h>
 #include <linux/usb/ch9.h>
+#include <linux/of.h>
+#include <linux/of_i2c.h>
 #include "hid-ids.h"

 enum {
@@ -1014,6 +1016,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
    dev->adap.algo      = &smbus_algorithm;
    dev->adap.algo_data = dev;
    dev->adap.dev.parent    = &hdev->dev;
+   dev->adap.dev.of_node   = of_find_node_by_path("/i2c@cp2112");
    snprintf(dev->adap.name, sizeof(dev->adap.name),
         "CP2112 SMBus Bridge on hiddev%d", hdev->minor);
    init_waitqueue_head(&dev->wait);
@@ -1029,6 +1032,8 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)

    hid_dbg(hdev, "adapter registered\n");

+   of_i2c_register_devices(&dev->adap);
+
    dev->gc.label           = "cp2112_gpio";
    dev->gc.direction_input     = cp2112_gpio_direction_input;
    dev->gc.direction_output    = cp2112_gpio_direction_output;

触摸控制器的 .dts 文件中的条目如下所示:

    i2c@cp2112 {
            #address-cells = <1>;
            #size-cells = <0>;
            st1332: touchscreen@55 {
                    compatible = "sitronix,st1232";
                    reg = <0x55>;
                    interrupt-parent = <&gpio>;
                    interrupts = <189 IRQ_TYPE_EDGE_FALLING>;
            };
    };

作为可能遇到类似问题的人的参考,请注意 CliffordbackportingLinux 4+ 回到 v3.10.40cp2112 驱动程序。

如果您查看 i2c 总线的内核源代码,它们似乎必须使用 of_i2c_register_devices 自行注册,但从内核 v3.12 开始,这种需要已被删除。这就是 cp2112 驱动程序不调用 of_i2c_register_devices.

的原因