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

Linux kernel Linux设备树(DTS):USB-i2c桥接器上的i2c设备,linux-kernel,device-tree,Linux Kernel,Device Tree,我有一个i2c设备(触摸控制器)。通常,当它连接到SoC i2c主机(在我的例子中是tegra芯片)时,我会像这样将其添加到.dts文件中: 但是,我不想将触摸控制器连接到SoC中的一个i2c主机。相反,我将其连接到一个cp2112 USB到i2c桥接器。 cp2112驱动程序工作正常:我可以使用诸如i2cget之类的命令从命令行访问它。但是如何将其添加到.dts文件中,以便触摸控制器驱动程序与之对话 因为USB设备是自动枚举的,所以我的.dts文件中没有一个节点可以用作触摸控制器节点的父节点。

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

但是,我不想将触摸控制器连接到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。

由于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
索引2bd7f97..fa88590 100644
---a/drivers/hid/hid-cp2112.c
+++b/drivers/hid/hid-cp2112.c
@@ -31,6 +31,8 @@
#包括
#包括
#包括
+#包括
+#包括
#包括“hid id.h”
枚举{
@@-1014,6+1016,7@@静态int cp2112_探测器(结构hid_设备*hdev,常数结构hid_设备*id*id)
dev->adap.algo=&smbus\u算法;
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),
“hiddev%d上的CP2112 SMBus网桥”,hdev->minor);
初始化等待队列头(&dev->wait);
@@-1029,6+1032,8@@静态int cp2112_探测器(结构hid_设备*hdev,常量结构hid_设备*id*id)
hid_dbg(hdev,“已注册的适配器”);
+i2c寄存器设备的数量(&dev->adap);
+
dev->gc.label=“cp2112\u gpio”;
dev->gc.direction\u input=cp2112\u gpio\u direction\u input;
dev->gc.direction\u output=cp2112\u gpio\u direction\u 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>;
            };
    };
i2c@cp2112 {
#地址单元=;
#大小单元格=;
st1332:touchscreen@55 {
compatible=“sitronix,st1232”;
reg=;
中断父项=;
中断=;
};
};

对于那些可能遇到类似问题的人,请注意,
Clifford
backporting
Linux 4+
返回
v3.10.40
cp2112
驱动程序


如果你看一下i2c总线的内核源代码,它们似乎必须通过使用i2c寄存器设备的
来注册自己,但是这一需求从内核
v3.12
开始就被删除了。这就是为什么
cp2112
驱动程序不调用i2c寄存器设备的
,因为在v3.12之后就不需要了o我找到路径(例如
/i2c@cp2112
)连接到usb的i2c总线?我使用的是i2c微型usb,在
/proc/device tree中找不到对它的任何引用
    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>;
    };
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;
    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>;
            };
    };