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

Cli*_*nna 5 linux-kernel device-tree

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

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

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

    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>;
    };
Run Code Online (Sandbox Code Playgroud)

但是,我不想将触摸控制器连接到来自 SoC 的 i2c 主控之一。相反,我将它连接到 cp2112 USB 到 i2c 桥接器。

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

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

我正在使用 Linux v4.1.0-rc5 的 hid-cp2112 向后移植版本运行 Linux 3.10.40。

Cli*_*nna 3

由于 hid-cp2112 驱动程序由 USB 设备枚举探测,因此它甚至不会尝试在设备树中查找自身。我创建了以下补丁,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;
Run Code Online (Sandbox Code Playgroud)

触摸控制器的 .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>;
            };
    };
Run Code Online (Sandbox Code Playgroud)