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>;
};
};
作为可能遇到类似问题的人的参考,请注意 Clifford
是 backporting
从 Linux 4+
回到 v3.10.40
的 cp2112
驱动程序。
如果您查看 i2c 总线的内核源代码,它们似乎必须使用 of_i2c_register_devices
自行注册,但从内核 v3.12
开始,这种需要已被删除。这就是 cp2112
驱动程序不调用 of_i2c_register_devices
.
的原因
我有一个 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>;
};
};
作为可能遇到类似问题的人的参考,请注意 Clifford
是 backporting
从 Linux 4+
回到 v3.10.40
的 cp2112
驱动程序。
如果您查看 i2c 总线的内核源代码,它们似乎必须使用 of_i2c_register_devices
自行注册,但从内核 v3.12
开始,这种需要已被删除。这就是 cp2112
驱动程序不调用 of_i2c_register_devices
.