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

时间:2015-05-27 12:16:20

标签: 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>;
            };       
    };

在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控制器(在我的情况下为xusb@70090000)下的.dts文件中创建一个占位符节点,然后由内核与枚举的USB设备相关联,并将触摸控制器移动到这个节点,但我不知道该怎么做。 USB设备的这种节点会是什么样子?或者问题有完全不同的解决方案吗?

我正在使用Linux v4.1.0-rc5中的hid-cp2112的backported版本运行Linux 3.10.40。

2 个答案:

答案 0 :(得分:2)

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

/i2c@cp2112

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

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;

答案 1 :(得分:2)

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

如果你查看i2c总线的内核源代码,似乎他们必须使用of_i2c_register_devices注册自己,但是这个需求已从内核v3.12开始删除。这就是cp2112驱动程序不会调用of_i2c_register_devices

的原因