将 USB DWC3 控制器从主机模式切换到设备模式

问题描述 投票:0回答:2

我需要使用嵌入式 Linux 平台作为 USB 设备,以便从智能手机传输音频和视频。该平台有一个 USB A 插座,不支持 OTG(USB_ID 引脚未连接到主机控制器上)。

现在我尝试使用 DWC3 控制器和 debugfs 接口从主机模式切换到设备模式。因此我在内核配置中激活了DWC3控制器并将其设置为“双角色模式”。安装文件系统后,我用

/sys/kernel/debug/xxxxxxxx.usb3/mode
检查了
cat mode
中的当前模式,并按预期获得了主机。但不幸的是我无法将设备写入模式文件。输入命令
echo device > mode
后,它仍然是主机并且不会改变。有谁知道是什么原因造成的?

usb embedded-linux usb-otg
2个回答
0
投票

我知道这曾经是开箱即用的,但对于我在嵌入式平台(5.4.0)中使用的内核版本,它却不能。 为了使它工作,我必须修补内核中的一个错误:

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index bf1a7a9da..a78990664 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -110,9 +110,6 @@ static void __dwc3_set_mode(struct work_struct *work)
    unsigned long flags;
    int ret;
 
-   if (dwc->dr_mode != USB_DR_MODE_OTG)
-       return;
-
    if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
        dwc3_otg_update(dwc, 0);
 
@@ -192,6 +189,12 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
    dwc->desired_dr_role = mode;
    spin_unlock_irqrestore(&dwc->lock, flags);
 
+   if (dwc->dr_mode != USB_DR_MODE_OTG)
+   {
+       __dwc3_set_mode(&dwc->drd_work);
+       return;
+   }
+
    queue_work(system_freezable_wq, &dwc->drd_work);
 }

应用上述补丁后,重新启动到新内核,然后运行:

echo "host" | sudo tee /sys/kernel/debug/*.usb3/mode

我能够像我期望的那样切换模式(注意:上面命令中我使用的是 *.dwc3 而不是 *.usb3)。


0
投票

在较新的内核(5.10+)上,dwc3 内核驱动程序使用更标准化的“USB 角色切换机制”。 我发现配置这个机制可能有点棘手。 之前您只是在设备树中设置

dr_mode
,现在您需要进行一些设置:

&dwc3_0 {
    hnp-disable;
    srp-disable;
    adp-disable;
    dr_mode = "otg";
    usb-role-switch;
    snps,dis_enblslpm_quirk;
    snps,dis_u2_susphy_quirk;
    snps,dis_u3_susphy_quirk;
    role-switch-default-mode = "peripheral";
};

完成后,您可以使用旧模式切换机制:

echo "host" > /sys/kernel/debug/usb/*.dwc3/mode

但是要使用官方机制,您可能需要修补内核以允许用户空间控制。 如果您已经这样做了,那么您可以使用:

echo "host" > /sys/class/usb_role/*.dwc3-role-switch/role
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.