Rockchip RK3588 - USB基础 & 调试
开发板 :NanoPC-T6
开发板
eMMC
:256GB
LPDDR4
:16GB
显示屏 :15.6
英寸HDMI
接口显示屏
u-boot
:2017.09
linux
:6.1
----------------------------------------------------------------------------------------------------------------------------
有关USB
的发展历史,以及接口规范这一节我们就不再重复介绍了,没有相关基础的话可以参考我之前写过的文章:
一、RK3588 USB
介绍
1.1 USB
控制器
RK3588
支持4个独立的USB
控制器,不同控制器相互独立:
- 两个
USB2.0 HOST
(EHCI
&OHCI
); - 两个
USB3.0 OTG
(DWC3/xHCI
); - 一个
USB3.0 HOST
(xHCI
);只支持USB3.0
功能,不向下兼容USB2.0
;
其中:
EHCI/OHCI
: 表示该USB
控制器集成了EHCI
控制器和OHCI
控制器;DWC3/xHCI
:表示该USB
控制器集成了DWC3
控制器和xHCI
控制器;USB3.0
物理层传输速率为5Gbps
,USB2.0
物理层传输速率为480Mbps
;
1.1.1 USB2.0 HOST
(EHCI
/OHCI
)
支持高速 (480Mbps
),全速 (12Mbps
) 和低速 (1.5Mbps
),USB2.0 Host
控制器的框图如下图所示;
内部有EHCI
和OHCI
Host Controller
:
OHCI
支持USB1.0
和USB1.1
;EHCI
支持USB2.0
;
Port Routing Control
: 用于选择用EHCI
还是OHCI
。
USB2.0 Host
控制器连接到USB2.0 PHY
。
EHCI
和OHCI Rockchip
采用linux
内核Generic
驱动,一般开发时只需要对设备树作相应配置,即可正常工作。
为了同时支持USB1.0
、USB1.1
和USB2.0
,就需要同时用到EHCI
和OHCI
,因此需要在设备树中把这两个USB
控制器都打开,如:
&usb_host0_ehci {
status = "okay";
};
&usb_host0_ohci {
status = "okay";
}
&usb_host1_ehci {
status = "okay";
};
&usb_host1_ohci {
status = "okay";
};
这样配置之后,RK3588
的两个USB2.0 HOST
控制器就使能了,并且同时支持EHCI
和OHCI
。
1.1.2 USB3.0 OTG
(DWC3
/xHCI
)
RK3588 USB3.0 OTG
使用Synopsys
方案,即xHCI
扩展的DWC3
控制器,Host
功能在xHCI
框架下实现,而Device
功能由DWC3
扩展部分实现。
DWC3
具有以下特性:
- 支持
Control
/Bulk
(including stream
)/Interrupt
/Isochronous
传输方式; USB3.0
支持同时执行IN
和OUT
传输,带宽达到8Gbps
;- 支持描述符缓存 (
Descriptor Caching
) 和数据预取 (Data Pre-fetching
); Device
模式支持的IN
端点数量和OUT
端点数量请参考芯片手册;- 支持硬件自动处理
ERDY
和burst
; - 支持端点批量流传输 (
bulk stream
); - 支持
USB3.0 DRD
(Dual-Role Device
) 特性; - 支持根据
OTG ID
状态切换Device
和Host
模式; - 对于支持
Type-C
的芯片,支持UFP/DFP
角色交换; - 不支持
SRP
(session request protocol
),HNP
(hostnegotiation protocol
)和RSP
(Role Swap Protocol
);
USB3.0 xHCI Host
特性:
- 最多可以连接
64
个外设; - 支持一个中断器;
- 支持一个
USB2.0
端口和一个USB3.0
端口; - 支持
USB3.0/USB2.0
并发传输,带宽达到8Gbps
; - 支持标准和开源的
xHCI
驱动; - 部分芯片支持
xHCI Debug Capability
;
USB3.0 OTG
控制器的框图如下图所示;
USB3.0 OTG
具有USB3.0 OTG
(USB Peripheral
和USB Host
)功能,且向下兼容USB2.0 OTG
功能,大传输速率为5Gbps
。
由于USB3.0 HOST
控制器为xHCI
,集成于DWC3 OTG IP
中,所以不用单独为其配置设备树,只需要配置DWC3
,并且设置DWC3
的dr_mode
属性为dr_mode
= otg
或者dr_mode
= host
,即可以使能xHCI
控制器。
1.1.3 USB3.0 HOST
(xHCI
)
USB3.0 HOST
控制器只支持USB3.0
功能,无法支持USB2.0
(因为没有带USB2.0 PHY
)。因此,USB3.0 HOST
需要与USB2.0 HOST
控制器组合,以支持完整的USB3.0
协议功能。
1.2 USB PHY
RK3588
支持7个独立的USB PHY
:
- 4个
USB2.0 PHY
:在设备树中分别叫做u2phy0
、u2phy1
、u2phy2
、u2phy3
; - 2个
USB3.0/DP Combo PHY
:在设备树中分别叫做usbdp_phy0
和usbdp_phy1
; - 1 个
USB3.0/SATA/PCIe Combo PHY
:在设备树中叫做combphy2_psu
;
其中:
USB3.0/DP Combo PHY
支持4 x lanes
,可以同时支持USB3.0 + DP 2 x lanes
;USB3.0/SATA/PCIe Combo PHY
在同一时刻,只能支持一种工作模式,也即USB3.0
与SATA/PCIe
接口是互斥的;
Rockchip
采⽤的USB PHY
主要有如下几种:
USB2.0 PHY
[Vendor: Innosilicon
];RK3588
使用的4个USB2.0 PHY
正是采用这个;USB2.0 PHY
[Vendor: Synopsys
];Synopsys USB2.0 PHY
只⽤于较早的⼏款芯⽚(RK3066
/RK3188
/RK3288
),当前的主流芯⽚和后续的芯⽚USB2.0 PHY
都是采⽤Innosilicon
提供的IP
;USB3.0 PHY
[Vendor: Innosilicon
];Inno USB3.0 PHY
只⽀持Super-speed
,没有向下兼容High-Speed
,所以需要和Inno USB2.0 PHY
组成⼀个Combo PHY
;RK3588
使用的2个USB3.0/DP Combo PHY
正是采用这个;USB3.0 PHY
[Vendor: naneng
]:RK3588
使用的USB3.0/SATA/PCIe Combo PHY
正是采用这个;Type-C PHY
[Vendor: Cadence
]。
1.2.1 USB2.0 PHY
USB2.0 PHY
支持1个port
和2个port
两种设计,如下图是支持2个port
的框图;
Host Port
:通过UTMI+
连接到USB2.0 Host
控制器;
OTG Port
:通过UTMI+
连接USB3.0/2.0 OTG
控制器的USB2.0
逻辑模块;
以RK3588
为例,使用的4个USB2.0 PHY
均是采用Innosilicon IP
,每个USB2.0 PHY
都只有1个port
端口;
u2phy0
:包含u2phy0_otg
;u2phy1
:包含u2phy1_otg
;u2phy2
:包含u2phy2_host
;u2phy3
:包含u2phy3_host
;
1.2.2 USB3.0/DP Combo PHY
RK3588
使用的2个 USB3.0/DP Combo PHY
均是采用Innosilicon IP
。Inno USB3.0 PHY
只⽀持Super-speed
,没有向下兼容High-Speed
,所以需要和Inno USB2.0 PHY
组成⼀个Combo PHY
。如下图是⼀个典型的USB3.0 OTG
控制器架构图;
注意:图中由下方的USB3.0 PHY
可以看做是个 USB3.0/DP Combo PHY
。
1.2.3 USB3.0/SATA/PCIe Combo PHY
RK3588
使用的 USB3.0/SATA/PCIe Combo PHY
采用NaNeng IP
。只能支持USB3.0
,不向下兼容USB2.0
。并且,在芯片内部设计时,没有与USB2.0 PHY
组合。
1.3 USB
控制器和USB PHY
关系
1.3.1 连接示意
RK3588 USB
控制器和USB PHY
的连接示意图如下:
USB 接口类型(仅仅示例,接口类型可调整) | USB 控制器 | USB PHY |
---|---|---|
USB3.0 Type-C0 | USB3.0 OTG0 (DWC3&xHCI) | USB3.0/DP Combo PHY0 + USB2.0 PHY0 |
USB3.0 Type-C1 | USB3.0 OTG1 (DWC3&xHCI) | USB3.0/DP Combo PHY1 + USB2.0 PHY1 |
USB2.0 HOST0 Type-A | USB2.0 HOST0(EHCI&OHCI) | USB2.0 PHY2 |
USB2.0 HOST1 Type-A | USB2.0 HOST1(EHCI&OHCI) | USB2.0 PHY3 |
USB3.0 HOST2 Type-A | USB3.0 HOST2 (xHCI) | USB3.0/SATA/PCIe Combo PHY2 |
可视化如下:
由图可以看出,RK3588
最多可以同时支持2个全功能的USB3.0 Type-C
接口,2个USB2.0 Type-A
接口,1 个 USB3.0 Type-A
接口(不向下兼容USB2.0
);
USB3.0 OTG
控制器 与DP
控制器复用USB3.1/DP Combo PHY
,可组成全功能的Type-C
接口,也可以拆分独立使用(如:常见的USB3.0 Type-A
接口 +DP
接口[2 x lanes
]);USB3.0/DP Combo PHY
只能支持USB3.0
,不向下兼容USB2.0
。所以,它们在芯片内部设计时,实际是与USB2.0 PHY
组合,以支持完整的USB3.0
协议功能。其中:USB3.0/DP Combo PHY0
固定与USB2 PHY0
组合;USB3.0/DP Combo PHY1
固定与USB2 PHY1
组合;
USB3.0 HOST2
控制器只支持USB3.0
功能,无法支持USB2.0
(因为没有带USB2.0 PHY
)。可以将USB3.0 HOST2
与USB2.0 HOST0
或USB2.0 HOST1
组合,作为一个完整的USB3.0 Type-A
接口;USB3.0/SATA/PCIe Combo PHY
只能支持USB3.0
,不向下兼容USB2.0
。并且,在芯片内部设计时,没有与USB2.0 PHY
组合。因此,USB3.0 HOST2
需要与USB2.0 HOST0/1
接口(二选一)组合,以支持完整的USB3.0
协议功能;
需要注意的是,RK3588 USB
支持的接口类型并不局限于图中所描述的USB Type-C/A
接口类型,而是可以支持所有常见的USB
接口,包括USB2.0/3.0 Type-C
,USB2.0/3.0 Type-A
,Micro USB2.0/3.0
等,具体信息请参考RK3588 USB
支持的接口类型。
为了适配不同的USB
电路设计和接口类型,Linux
内核USB
驱动已经做了软件兼容,开发者只需要根据产品的USB
硬件电路,对Linux USB DTS
进行正确配置,即可使能对应的USB
接口功能。
1.3.2 引脚定义
RK3588 USB
控制器和芯片端USB
传输数据的pin
脚的对应关系如下表所示:
USB控制器/Pin脚 | RK3588 USB data pin |
---|---|
USB2.0 HOST0 | USB20_HOST0_DP/USB20_HOST0_DM |
USB2.0 HOST1 | USB20_HOST1_DP/USB20_HOST1_DM |
USB3.0 OTG0 | TYPEC0_USB20_OTG_DP/TYPEC0_USB20_OTG_DM, TYPEC0_SSRX1P/TYPEC0_SSRX1N, TYPEC0_SSTX1P/TYPEC0_SSTX1N, TYPEC0_SSRX2P/TYPEC0_SSRX2N, TYPEC0_SSTX2P/TYPEC0_SSTX2N |
USB3.0 OTG1 | TYPEC1_USB20_OTG_DP/TYPEC1_USB20_OTG_DM, TYPEC1_SSRX1P/TYPEC1_SSRX1N, TYPEC1_SSTX1P/TYPEC1_SSTX1N TYPEC1_SSRX2P/TYPEC1_SSRX2N, TYPEC1_SSTX2P/TYPEC1_SSTX2N |
USB3.0 HOST2 | USB30_2_SSTXP/USB30_2_SSTXN USB30_2_SSRXP/USB30_2_SSRXN |
二、硬件原理图
这里我使用的开发板型号是NanoPC-T6
,开发板如下图所示;
USB
资源如下:
-
USB-C/DP
: 一个全功能USB3.0 Type‑C
接口, 支持USB3.0
数据传输和DP
显示输出,分辨率高达4Kp60
; -
USB3.0:
一个USB3.0 Type-A
;
2.1 USB3.0 Type‑C
我们使用的开发板NanpiPC-T6
,USB3.0/DP Combo PHY0
与USB2 PHY0
物理接口被设计为USB3.0 Type-C
,如下图所示:
友善的这块电路实际上是参考Rockchip
官方的Type-C USB3.0/DP
全功能硬件电路。
需要注意的是这里TYPEC0_USB20_VBUSDET
引脚是连接到VCCA_3V3_S0
。至于为啥这么设计,官方给出了说明:
- 为了支持高压充电功能,同时降低硬件电路的风险,
TYPEC0_USB20_VBUSDET
不要连接Type-C
接口的VBUS
,固定上拉到3.3V
即可(TYPEC0_USB20_VBUSDET
连接到VCCA_3V3_S0
),但不能悬空; - 当
Type-C0
设计为支持PD
功能的Type-C
接口时,即支持外置Type-C
控制器芯片(如:FUSB302
或者HUSB311
),则TYPEC0_USB20_VBUSDET
固定上拉到VCCA_3V3_S0
,软件驱动可以通过Type-C
控制器芯片的CC
检测USB Device
的连接和
断开;
2.1.1 电源接线
上图中供电依次为VDDA_0V85_S0
、VCCA_1V8_S0
、VDDA_0V75_S0
、VCCA_3V3_S0
,这些电源均是由电源芯片RK806
输出。
(1) 电源VDDA_0V85_S0
由RK806
第10号引脚提供的;
(2) 电源VCCA_1V8_S0
由RK806
第60号引脚提供的;
(3) 电源VDDA_0V75_S0
由RK806
第11号引脚提供的;
(4) 电源VCCA_3V3_S0
由RK806
第63号引脚提供的。
2.1.2 Type-C
接口接线
其中TYPEC0_SSTX1P
、TYPEC0_SSTX1N
、TYPEC0_SSRX1P
、TYPEC0_SSRX1N
、TYPEC0_SSTX2P
、TYPEC0_SSTX2N
、TYPEC0_SSRX2P
、TYPEC0_SSRX2N
、TYPEC0_SBU1
、TYPEC0_SBU2
、TYPEC0_USB20_OTG_DM
、TYPEC0_USB20_OTG_DP
连接到开发板上的TYPE-C
,TYPE-C
为USB3.0 Type-C
接口;
RK3588 | USB3.0/DP Combo PHY0 | USB2.0 PHY0 | USB3.0 Type-C |
---|---|---|---|
TYPEC0_SSTX1P/DP0_TX1P | TYPEC0_SSTX1P | SSTX1_P | |
TYPEC0_SSTX1N/DP0_TX1N | TYPEC0_SSTX1N | SSTX1_N | |
TYPEC0_SSRX1P/DP0_TX0P | TYPEC0_SSRX1P | SSRX1_P | |
TYPEC0_SSRX1N/DP0_TX0N | TYPEC0_SSRX1N | SSRX1_N | |
TYPEC0_SSTX2P/DP0_TX3P | TYPEC0_SSTX2P | SSTX2_P | |
TYPEC0_SSTX2N/DP0_TX3N | TYPEC0_SSTX2N | SSTX2_N | |
TYPEC0_SSRX2P/DP0_TX2P | TYPEC0_SSRX2P | SSRX2_P | |
TYPEC0_SSRX2N/DP0_TX2N | TYPEC0_SSRX2N | SSRX2_N | |
TYPEC0_SBU1/DP0_AUXP | TYPEC0_SBU1 | SBU1 | |
TYPEC0_SBU2/DP0_AUXN | TYPEC0_SBU2 | SBU2 | |
GPIO4_A6 | TYPEC0_SBU1_DC | SBU1 | |
GPIO4_A7 | TYPEC0_SBU2_DC | SBU2 | |
TYPEC0_USB20_OTG_DM | TYPEC0_OTG_DM | D- | |
TYPEC0_USB20_OTG_DP | TYPEC0_OTG_DP | D+ | |
TYPEC0_USB20_OTG_DM | TYPEC0_OTG_DM | DM | |
TYPEC0_USB20_OTG_DP | TYPEC0_OTG_DP | DP | |
USB20_AVDD_3V3 | TYPEC0_USB20_VBUSDET | ||
TYPEC_CC1 | |||
TYPEC_CC2 |
如下图所示:
电源VBUS5V0_TYPEC
由SY6280AAC
提供的,其输入端为VCC5V0_SYS
。由TYPEC5V_PWREN_H
(GPIO1_D2
)引脚使能;
2.1.3 fusb302
fusb302
是可编程的USB Type-C
控制器,支持识别各种USB
设备和对应的工作状态,且支持最高100W
的PD
协议。
其具有一下主要特征:
- 具备自主
DRP
切换的双重角色功能; - 根据已连接的设备选择作为
Host
(主机)或Device
(设备)进行连接; - 通过软件配置为
Host
(主机)、Device
(设备)或双重角色; - 支持
USB
功率传递(PD
)2.0:
其引脚如下:
引脚 | 类型 | 功能 |
---|---|---|
CC1/CC2 | I/O | Type-C连接器的配置通道(CC)引脚。最初用于确定插入事件发生以及插入的方向。连接后的功能取决于检测到的操作模式。 作为主机运行时: 1)设置可被连接设备感知的VBUS的允许充电电流; 2)用于与使用USB BMC Power Delivery的设备进行通信; 3)用于检测已发生的拔出事件 作为设备运行时: 4)指示来自连接的主机的允许下沉电流。用于与使用USB BMC Power Delivery的设备进行通信主要用来 PD协议通信或其他: |
VBUS | Input | 当作为面向上行端口(设备)运行时,该引脚可用于设备插入和拔出的检测。 |
VCONN | Power Switch | 要将调节输入电源切换到正确的CC引脚作为VCONN以为USB3.1完整功能电缆和其他配件供电。 |
INIT | Open-Drain Output | 中断输出,当有事件发生时,用于通知处理器读取I2C寄存器数据。如:插入/拔出typeC,INIT_N都会拉低一下。 |
SCL | Input | I2C时钟 |
SDA | Open-Drain I/O | I2C数据引脚 |
INT
连接的是RK3588
的GPIO0_D3
引脚,I2C
通信使用的是I2C6
。
由于这篇文章不是fusb302
的专栏,所以就不细说了,具体参考《PD
快充 - fusb302
驱动调试笔记》。
2.2 USB3.0 Type-A
我们使用的开发板NanpiPC-T6
,USB3.0/DP Combo PHY1
与USB2 PHY1
物理接口被设计为USB3.0 Type-A
,如下图所示:
友善的这块电路实际上是参考Rockchip
官方的Type-C to Type-A USB 3.1/DP
硬件电路。
需要注意的是这里TYPEC1_USB20_VBUSDET
引脚是悬空的,至于为啥这么设计,官方给出了说明:
- 如果
USB OTG
有作Device/HOST
的应用场景,建议TYPEC0_OTG_VBUSDET
通过30KΩ
的电阻串联到USB Type-A
接口的VBUS
; - 然而友善这里将
TYPEC1_USB20_VBUSDET
引脚悬空处理,USB Type-A
接口大概率只能作为HOST mode
使用。
2.2.1 Type-A
接口接线
其中TYPEC1_SSTX1P
、TYPEC1_SSTX1N
、TYPEC1_SSRX1P
、TYPEC1_SSRX1N
、TYPEC1_USB20_OTG_DM
、TYPEC1_USB20_OTG_DP
连接到USB3
,USB3
为USB3.0 Type-A
接口;
RK3588 | USB3.0 Type-C PHY1 | USB2.0 PHY1 | USB3.0 Type-A |
---|---|---|---|
TYPEC1_SSTX1P/DP1_TX1P | TYPEC1_SSTX1P | TX+ | |
TYPEC1_SSTX1N/DP1_TX1N | TYPEC1_SSTX1N | TX- | |
TYPEC1_SSRX1P/DP1_TX0P | TYPEC1_SSRX1P | RX+ | |
TYPEC1_SSRX1N/DP1_TX0N | TYPEC1_SSRX1N | RX- | |
TYPEC1_USB20_OTG_DM | TYPEC1_OTG_DM | D- | |
TYPEC1_USB20_OTG_DP | TYPEC1_OTG_DP | D+ |
如下图所示:
电源VCC5V0_USB30_HOST2
由SY6280AAC
提供的,其输入端为VCC5V0_SYS
。由USB_HOST_PWREN_H
(GPIO4_B0
)引脚使能。
当USB3.0 OTG
控制器工作在Device mode
,关闭VBUS
输出。当USB3.0 OTG
控制器工作在HOST mode
,打开VBUS
输出。此外,稳压芯片SY6280AAC
的输出电流由OCB pin
连接的电阻决定,最大电流Ilim(A)=6800/Rset(ohm)
,VBUS
输出限流为1A
.
三、设备树
设备树配置参考文档:
Documentation/devicetree/bindings/usb/snps,dwc3.yaml
;Documentation/devicetree/bindings/usb/generic-ohci.yaml
;Documentation/devicetree/bindings/usb/generic-ehci.yaml
;Documentation/devicetree/bindings/connector/usb-connector.yaml
;Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
;Documentation/devicetree/bindings/phy/phy-rockchip-usbdp.yaml
;Documentation/devicetree/bindings/phy/phy/phy-rockchip-naneng-combphy.txt
;
RK3588 USB
接口和USB dts
节点的对应关系:
USB 接口类型(仅仅示例) | USB控制器DTS 节点 | USB PHY DTS 节点 |
---|---|---|
USB3.0 Type-C0 对应开发板上标号为USB-C/DP的接口 |
USB3.0 OTG0 (DWC3&xHCI) - usbdrd3_0 - usbdrd_dwc3_0 |
USB3.0/DP Combo PHY0 + USB2.0 PHY0 - u2phy0 - u2phy0_otg - usbdp_phy0 - usbdp_phy0_u3 |
USB3.0 Type-C1 对应开发板上标号为USB3.0的接口,只不过接口类型被做成了Type-A |
USB3.0 OTG1 (DWC3&xHCI) - usbdrd3_1 - usbdrd_dwc3_1 |
USB3.0/DP Combo PHY1 + USB2.0 PHY1 - u2phy1 - u2phy1_otg - usbdp_phy1 - usbdp_phy1_u3 |
USB2.0 HOST0 Type-A | USB2.0 HOST0(EHCI&OHCI) - usb_host0_ehci - usb_host0_ohci |
USB2.0 PHY2 - u2phy2 - u2phy2_host |
USB2.0 HOST1 Type-A | USB2.0 HOST1(EHCI&OHCI) - usb_host1_ehci - usb_host1_ohci |
USB2.0 PHY3 - u2phy3 - u2phy3_host |
USB3.0 HOST2 Type-A | USB3.0 HOST2 (xHCI) - usbhost3_0 - usbhost_dwc3_0 |
USB3.0/SATA/PCIe Combo PHY2 - combphy2_psu |
3.1 NaniPC-T6
设备树
在《Rockchip RK3588
- 移植uboot 2017.09 & linux 6.1
(友善之家脚本方式)》我们介绍了友善内核编译过程,在arch/arm64/Makefile
文件指定了如何生成resource.img
文件。
DTBS := rk3*-nanopi*-rev*.dtb
# 调用scripts/resource_tool编译生成resource.img(由设备树、图片资源文件组成,不包含内核)
nanopi4-images: dtbs kernel.img $(LOGO) $(LOGO_KERNEL)
$(Q)$(srctree)/scripts/mkimg --dtb $(DTBS) --keep-dtb-name
其中dtb
生成规则如下:
%.dtb: dtbs_prepare
$(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@
# include/config/kernel.release is actually needed when installing DTBs because
# INSTALL_DTBS_PATH contains $(KERNELRELEASE). However, we do not want to make
# dtbs_install depend on it as dtbs_install may run as root.
dtbs_prepare: include/config/kernel.release scripts_dtc
可以看到NaniPC-T6
友善提供的内核源码默认编译使用的设备树文件包括rk3*-nanopi*-rev*.dtb
,对于RK3588
而言具体包含以下文件:
root@zhengyang:/work/sambashare/rk3588/friendly/sd-fuse_rk3588/kernel-rk3588# ls arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev*.dtb
arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dtb arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev04.dtb
arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev02.dtb arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev05.dtb
arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev03.dtb arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev09.dtb
需要注意的是:这里虽然存在多个设备树文件,但对于Nanipc-T6
开发板uboot
在加载设备树的时候默认使用的是rk3588-nanopi6-rev01.dtb
,这个后面会介绍。
以rk3588-nanopi6-rev01.dts
为例,文件引入了rk3588.dtsi
以及rk3588-nanopi6-common.dtsi
:
#include "rk3588.dtsi"
#include "rk3588-nanopi6-common.dtsi"
3.1.1 rk3588-nanopi6-revzy.dts
这里我们拷贝一份设备树命名为rk3588-nanopi6-revzy.dts
,如果后面需要调整,我们修改我们这个即可:
root@zhengyang:/work/sambashare/rk3588/friendly/sd-fuse_rk3588# cp kernel-rk3588/arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts kernel-rk3588/arch/arm64/boot/dts/rockchip/rk3588-nanopi6-revzy.dts
注意:不要拷贝rk3588-nanopi6-rev09.dts
,这个我在测试的时候发现内核无法启动,如果有兴趣可以对比一下设备树的差异。
修改Makefile
:
root@zhengyang:/work/sambashare/rk3588/friendly/sd-fuse_rk3588/kernel-rk3588# vim arch/arm64/boot/dts/rockchip/Makefile
ifeq ($(CONFIG_VENDOR_FRIENDLYELEC),y)
dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3399-nanopi4-rev00.dtb \
rk3399-nanopi4-rev01.dtb \
rk3399-nanopi4-rev04.dtb \
rk3399-nanopi4-rev06.dtb \
rk3399-nanopi4-rev07.dtb \
rk3399-nanopi4-rev09.dtb \
rk3399-nanopi4-rev0a.dtb \
rk3399-nanopi4-rev0b.dtb \
rk3399-nanopi4-rev21.dtb \
rk3399-nanopi4-rev22.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3568-nanopi5-rev01.dtb \
rk3568-nanopi5-rev02.dtb \
rk3568-nanopi5-rev03.dtb \
rk3568-nanopi5-rev04.dtb \
rk3568-nanopi5-rev07.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3588-nanopi6-rev01.dtb \
rk3588-nanopi6-rev02.dtb \
rk3588-nanopi6-rev03.dtb \
rk3588-nanopi6-rev04.dtb \
rk3588-nanopi6-rev05.dtb \
rk3588-nanopi6-rev09.dtb \
rk3588-nanopi6-revzy.dtb
else
dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-ctouch2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-ctouch2-of10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-engicam-px30-core-edimm2.2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb-ddr3-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb-ddr3-v10-avb.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb-ddr3-v10-linux.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-mini-evb-ddr3-v11.dtb
......
由于CONFIG_VENDOR_FRIENDLYELEC
、CONFIG_ARCH_ROCKCHIP
被定义,编译内核的时候就会编译rk3588-nanopi6-revzy.dts
。
3.1.2 编译烧录resource.img
在宿主机重新编译内核:
root@zhengyang:/work/sambashare/rk3588/friendly/sd-fuse_rk3588# KERNEL_SRC=$PWD/kernel-rk3588 ./build-kernel.sh debian-bullseye-desktop-arm64
更新resource.img
:
root@NanoPC-T6:/opt# sudo scp root@192.168.0.200:/work/sambashare/rk3588/friendly/sd-fuse_rk3588/debian-bullseye-desktop-arm64/resource.img ./
root@NanoPC-T6:/opt# sudo dd if=resource.img of=/dev/mmcblk2p4 bs=1M
重启开发板,uboot
启动默认会去加载rk3588-nanopi6-rev01.dtb
,那uboot
是如何知道要加载resource.img
中哪一个dts
的呢?
实际上是通过uboot-rockchip/board/rockchip/nanopi6/board.c
实现的,具体可以参考:《瑞芯微RK3399
设备树传递分析》;
void set_dtb_name(void)
{
char info[64] = {0, };
#ifndef CONFIG_ENV_IS_NOWHERE // 配置为y
if (env_get_yesno("lockdown") == 1 &&
env_get("dtb_name"))
return;
#endif
snprintf(info, ARRAY_SIZE(info),
"rk3588-nanopi6-rev%02x.dtb", get_board_rev());
env_set("dtb_name", info);
}
static const int id_readings[] = {
81, 150, 211, 274, 342, 411, 477, 545,
613, 675, 733, 795, 861, 925, 989, 1023
};
static int cached_board_id = -1;
static uint32_t get_adc_index(int chn) // 5
{
int i;
u32 adc_reading = 0;
if (cached_board_id != -1)
return cached_board_id;
adc_channel_single_shot("saradc", chn, &adc_reading);
/* rockchip-saradc-v2 */
adc_reading >>= 2;
for (i = 0; i < ARRAY_SIZE(id_readings); i++) {
if (adc_reading <= id_readings[i]) {
debug("ADC reading %d, ID %d\n", adc_reading, i);
cached_board_id = i;
return i;
}
}
/* should die for impossible value */
return 0;
}
/*
* Board revision by ADC_IN5
* 0b01 - NanoPi-R6S
*/
static int pcb_rev = -1;
void bd_hwrev_init(void)
{
if (pcb_rev >= 0)
return;
pcb_rev = get_adc_index(5);
}
/* To override __weak symbols */
u32 get_board_rev(void)
{
return pcb_rev;
}
我们因此知道了,友善的nanopi
系列板子,是通过板ADC
脚的输入电压来判断载入什么dtb
的。
因此,我们可以在开发板启动时,在串口终端按下CTRL+C
,进入uboot
命令行模式,查看默认使用的dtb
文件:
=> print dtb_name
dtb_name=rk3588-nanopi6-rev01.dtb
我们修改默认使用的dtb
文件:
=> setenv dtb_name rk3588-nanopi6-revzy.dtb
=> save
=> boot
但是这种改法,开发板重新上电,就失效了,因此需要把uboot
配置CONFIG_ENV_IS_NOWHERE
配置为n
;
CONFIG_ENV_IS_NOWHERE=n
3.2 USB
控制器
USB3.0 OTG0
(DWC3
/xHCI
)、USB2.0 HOST0/1
(EHCI&OHCI
)、USB3.0 HOST2
(xHCI
)的dtsi
配置放在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
USB3.0 OTG1
(DWC3
/xHCI
)的dtsi
配置放在arch/arm64/boot/dts/rockchip/rk3588.dtsi
,这个文件包含了rk3588s.dtsi
:
因为USB DTSI
节点配置的是USB
控制器和PHY
的公共资源和属性,建议开发者不要改动。
#include "rk3588s.dtsi"
3.2.1 USB2.0 HOST0
(EHCI&OHCI
)
USB2.0 HOST0
控制器设备节点usb_host0_ehci
、usb_host0_ohci
定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usb_host0_ehci: usb@fc800000 {
compatible = "rockchip,rk3588-ehci", "generic-ehci";
reg = <0x0 0xfc800000 0x0 0x40000>;
interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&u2phy2>;
clock-names = "usbhost", "arbiter", "utmi";
companion = <&usb_host0_ohci>;
phys = <&u2phy2_host>;
phy-names = "usb2-phy";
power-domains = <&power RK3588_PD_USB>;
status = "disabled";
};
usb_host0_ohci: usb@fc840000 {
compatible = "generic-ohci";
reg = <0x0 0xfc840000 0x0 0x40000>;
interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&u2phy2>;
clock-names = "usbhost", "arbiter", "utmi";
phys = <&u2phy2_host>;
phy-names = "usb2-phy";
power-domains = <&power RK3588_PD_USB>;
status = "disabled";
};
3.2.2 USB2.0 HOST1
(EHCI&OHCI
)
USB2.0 HOST1
控制器设备节点usb_host1_ehci
、usb_host1_ohci
定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usb_host1_ehci: usb@fc880000 {
compatible = "rockchip,rk3588-ehci", "generic-ehci";
reg = <0x0 0xfc880000 0x0 0x40000>;
interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&u2phy3>;
clock-names = "usbhost", "arbiter", "utmi";
companion = <&usb_host1_ohci>;
phys = <&u2phy3_host>;
phy-names = "usb2-phy";
power-domains = <&power RK3588_PD_USB>;
status = "disabled";
};
usb_host1_ohci: usb@fc8c0000 {
compatible = "generic-ohci";
reg = <0x0 0xfc8c0000 0x0 0x40000>;
interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&u2phy3>;
clock-names = "usbhost", "arbiter", "utmi";
phys = <&u2phy3_host>;
phy-names = "usb2-phy";
power-domains = <&power RK3588_PD_USB>;
status = "disabled";
};
3.2.3 USB3.0 OTG0
(DWC3
/xHCI
)
USB3.0 OTG0(DWC3/xHCI)
控制器设备节点usbdrd3_0
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usbdrd3_0: usbdrd3_0 {
compatible = "rockchip,rk3588-dwc3", "rockchip,rk3399-dwc3";
clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>,
<&cru ACLK_USB3OTG0>;
clock-names = "ref", "suspend", "bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
status = "disabled";
usbdrd_dwc3_0: usb@fc000000 {
compatible = "snps,dwc3";
reg = <0x0 0xfc000000 0x0 0x400000>;
interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&power RK3588_PD_USB>;
resets = <&cru SRST_A_USB3OTG0>;
reset-names = "usb3-otg";
dr_mode = "otg";
phys = <&u2phy0_otg>, <&usbdp_phy0_u3>;
phy-names = "usb2-phy", "usb3-phy";
phy_type = "utmi_wide";
snps,dis_enblslpm_quirk;
snps,dis-u1-entry-quirk;
snps,dis-u2-entry-quirk;
snps,dis-u2-freeclk-exists-quirk;
snps,dis-del-phy-power-chg-quirk;
snps,dis-tx-ipgap-linecheck-quirk;
snps,parkmode-disable-ss-quirk;
quirk-skip-phy-init;
status = "disabled";
};
};
3.2.4 USB3.0 OTG1
(DWC3
/xHCI
)
USB3.0 OTG1(DWC3/xHCI)
控制器设备节点usbdrd3_1
,定义在arch/arm64/boot/dts/rockchip/rk3588.dtsi
;
usbdrd3_1: usbdrd3_1 {
compatible = "rockchip,rk3588-dwc3", "rockchip,rk3399-dwc3";
clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>,
<&cru ACLK_USB3OTG1>;
clock-names = "ref", "suspend", "bus";
#address-cells = <2>;
#size-cells = <2>;
ranges;
status = "disabled";
usbdrd_dwc3_1: usb@fc400000 {
compatible = "snps,dwc3";
reg = <0x0 0xfc400000 0x0 0x400000>;
interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&power RK3588_PD_USB>;
resets = <&cru SRST_A_USB3OTG1>;
reset-names = "usb3-otg";
dr_mode = "host";
phys = <&u2phy1_otg>, <&usbdp_phy1_u3>;
phy-names = "usb2-phy", "usb3-phy";
phy_type = "utmi_wide";
snps,dis_enblslpm_quirk;
snps,dis-u1-entry-quirk;
snps,dis-u2-entry-quirk;
snps,dis-u2-freeclk-exists-quirk;
snps,dis-del-phy-power-chg-quirk;
snps,dis-tx-ipgap-linecheck-quirk;
snps,parkmode-disable-ss-quirk;
status = "disabled";
};
};
3.2.5 USB3.0 HOST2
(xHCI
)
USB3.0 HOST2(xHCI)
控制器设备节点usbhost3_0
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usbhost3_0: usbhost3_0 {
compatible = "rockchip,rk3588-dwc3", "rockchip,rk3399-dwc3";
clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>,
<&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>,
<&cru PCLK_PHP_ROOT>, <&cru CLK_PIPEPHY2_PIPE_U3_G>;
clock-names = "ref", "suspend", "bus", "utmi", "php", "pipe";
#address-cells = <2>;
#size-cells = <2>;
ranges;
status = "disabled";
usbhost_dwc3_0: usb@fcd00000 {
compatible = "snps,dwc3";
reg = <0x0 0xfcd00000 0x0 0x400000>;
interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
resets = <&cru SRST_A_USB3OTG2>;
reset-names = "usb3-host";
dr_mode = "host";
phys = <&combphy2_psu PHY_TYPE_USB3>;
phy-names = "usb3-phy";
phy_type = "utmi_wide";
snps,dis_enblslpm_quirk;
snps,dis-u2-freeclk-exists-quirk;
snps,dis-del-phy-power-chg-quirk;
snps,dis-tx-ipgap-linecheck-quirk;
snps,dis_rxdet_inp3_quirk;
snps,parkmode-disable-ss-quirk;
status = "disabled";
};
};
3.2.6 使能
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-common.dtsi
中,使能了:
-
USB2.0 HOST0
(EHCI&OHCI
); -
USB3.0 OTG0(DWC3/xHCI)
;
同时禁止了:
USB3.0 HOST2(xHCI)
;
# USB2.0 HOST0(EHCI&OHCI)
&usb_host0_ehci {
status = "okay";
};
&usb_host0_ohci {
status = "okay";
};
# USB3.0 OTG0(DWC3/xHCI)
&usbdrd3_0 {
status = "okay";
};
&usbdrd_dwc3_0 {
....
status = "okay";
};
# USB3.0 HOST2(xHCI)
&usbhost3_0 {
status = "disabled";
};
&usbhost_dwc3_0 {
status = "disabled";
};
而USB2.0 HOST1
(EHCI&OHCI
)、USB3.0 OTG1(DWC3/xHCI)
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts
中有使能:
# USB2.0 HOST1(EHCI&OHCI)
&usb_host1_ehci {
status = "okay";
};
&usb_host1_ohci {
status = "okay";
};
# USB3.0 OTG1(DWC3/xHCI)
&usbdrd3_1 {
status = "okay";
};
&usbdrd_dwc3_1 {
dr_mode = "host";
status = "okay";
};
而USB3.0 HOST2(xHCI)
并未使能,如果需要使能,则添加配置:
# USB3.0 HOST2(xHCI)
&usbhost3_0 {
status = "okay";
};
&usbhost_dwc3_0 {
dr_mode = "host";
status = "okay";
};
3.3 USB PHY
USB PHY
和USB
控制器具有一一对应的关系,需要成对配置。在芯片内部,USB PHY
和控制器的连接关系,请参考1,3
小节。在dtsi
节点中,通过USB
控制器节点的phys
属性关联对应的USB PHY
。
USB2.0 PHY0/2/3
、USB3.0/DP Combo PHY0
、USB3.0/SATA/PCIe Combo PHY
的dtsi
配置放在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
USB2.0 PHY1
、USB3.0/DP Combo PHY1
的dtsi
配置放在arch/arm64/boot/dts/rockchip/rk3588.dtsi
;
3.3.1 USB2.0 PHY0
USB2.0 PHY0
包含1个端口设备节点为u2phy0_otg
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usb2phy0_grf: syscon@fd5d0000 {
compatible = "rockchip,rk3588-usb2phy-grf", "syscon",
"simple-mfd";
reg = <0x0 0xfd5d0000 0x0 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
u2phy0: usb2-phy@0 {
compatible = "rockchip,rk3588-usb2phy";
reg = <0x0 0x10>;
interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>;
resets = <&cru SRST_OTGPHY_U3_0>, <&cru SRST_P_USB2PHY_U3_0_GRF0>;
reset-names = "phy", "apb";
clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
clock-names = "phyclk";
clock-output-names = "usb480m_phy0";
#clock-cells = <0>;
rockchip,usbctrl-grf = <&usb_grf>;
status = "disabled";
u2phy0_otg: otg-port {
#phy-cells = <0>;
status = "disabled";
};
};
};
3.3.2 USB2.0 PHY1
USB2.0 PHY1
包含1个端口设备节点为u2phy1_otg
,定义在arch/arm64/boot/dts/rockchip/rk3588.dtsi
;
usb2phy1_grf: syscon@fd5d4000 {
compatible = "rockchip,rk3588-usb2phy-grf", "syscon",
"simple-mfd";
reg = <0x0 0xfd5d4000 0x0 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
u2phy1: usb2-phy@4000 {
compatible = "rockchip,rk3588-usb2phy";
reg = <0x4000 0x10>;
interrupts = <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH>;
resets = <&cru SRST_OTGPHY_U3_1>, <&cru SRST_P_USB2PHY_U3_1_GRF0>;
reset-names = "phy", "apb";
clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
clock-names = "phyclk";
clock-output-names = "usb480m_phy1";
#clock-cells = <0>;
rockchip,usbctrl-grf = <&usb_grf>;
status = "disabled";
u2phy1_otg: otg-port {
#phy-cells = <0>;
status = "disabled";
};
};
};
3.3.3 USB2.0 PHY2
USB2.0 PHY2
包含1个端口设备节点为u2phy2_host
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usb2phy2_grf: syscon@fd5d8000 {
compatible = "rockchip,rk3588-usb2phy-grf", "syscon",
"simple-mfd";
reg = <0x0 0xfd5d8000 0x0 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
u2phy2: usb2-phy@8000 {
compatible = "rockchip,rk3588-usb2phy";
reg = <0x8000 0x10>;
interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH>;
resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
reset-names = "phy", "apb";
clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
clock-names = "phyclk";
clock-output-names = "usb480m_phy2";
#clock-cells = <0>;
status = "disabled";
u2phy2_host: host-port {
#phy-cells = <0>;
status = "disabled";
};
};
};
3.3.4 USB2.0 PHY3
USB2.0 PHY3
包含1个端口设备节点为u3phy3_host
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usb2phy3_grf: syscon@fd5dc000 {
compatible = "rockchip,rk3588-usb2phy-grf", "syscon",
"simple-mfd";
reg = <0x0 0xfd5dc000 0x0 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
u2phy3: usb2-phy@c000 {
compatible = "rockchip,rk3588-usb2phy";
reg = <0xc000 0x10>;
interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH>;
resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
reset-names = "phy", "apb";
clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
clock-names = "phyclk";
clock-output-names = "usb480m_phy3";
#clock-cells = <0>;
status = "disabled";
u2phy3_host: host-port {
#phy-cells = <0>;
status = "disabled";
};
};
};
3.3.5 USB3.0/DP Combo PHY0
USB3.0/DP Combo PHY0
包含2个端口,对应设备节点分别为usbdp_phy0_dp
、usbdp_phy0_u1
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
usbdp_phy0: phy@fed80000 {
compatible = "rockchip,rk3588-usbdp-phy";
reg = <0x0 0xfed80000 0x0 0x10000>;
rockchip,u2phy-grf = <&usb2phy0_grf>;
rockchip,usb-grf = <&usb_grf>;
rockchip,usbdpphy-grf = <&usbdpphy0_grf>;
rockchip,vo-grf = <&vo0_grf>;
clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
<&cru CLK_USBDP_PHY0_IMMORTAL>,
<&cru PCLK_USBDPPHY0>,
<&u2phy0>;
clock-names = "refclk", "immortal", "pclk", "utmi";
resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>,
<&cru SRST_USBDP_COMBO_PHY0_CMN>,
<&cru SRST_USBDP_COMBO_PHY0_LANE>,
<&cru SRST_USBDP_COMBO_PHY0_PCS>,
<&cru SRST_P_USBDPPHY0>;
reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
status = "disabled";
usbdp_phy0_dp: dp-port {
#phy-cells = <0>;
status = "disabled";
};
usbdp_phy0_u3: u3-port {
#phy-cells = <0>;
status = "disabled";
};
};
3.3.6 USB3.0/DP Combo PHY1
USB3.0/DP Combo PHY1
包含2个端口,对应设备节点分别为usbdp_phy1_dp
、usbdp_phy1_u1
,定义在arch/arm64/boot/dts/rockchip/rk3588.dtsi
;
usbdp_phy1: phy@fed90000 {
compatible = "rockchip,rk3588-usbdp-phy";
reg = <0x0 0xfed90000 0x0 0x10000>;
rockchip,u2phy-grf = <&usb2phy1_grf>;
rockchip,usb-grf = <&usb_grf>;
rockchip,usbdpphy-grf = <&usbdpphy1_grf>;
rockchip,vo-grf = <&vo0_grf>;
clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
<&cru CLK_USBDP_PHY1_IMMORTAL>,
<&cru PCLK_USBDPPHY1>,
<&u2phy1>;
clock-names = "refclk", "immortal", "pclk", "utmi";
resets = <&cru SRST_USBDP_COMBO_PHY1_INIT>,
<&cru SRST_USBDP_COMBO_PHY1_CMN>,
<&cru SRST_USBDP_COMBO_PHY1_LANE>,
<&cru SRST_USBDP_COMBO_PHY1_PCS>,
<&cru SRST_P_USBDPPHY1>;
reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
status = "disabled";
usbdp_phy1_dp: dp-port {
#phy-cells = <0>;
status = "disabled";
};
usbdp_phy1_u3: u3-port {
#phy-cells = <0>;
status = "disabled";
};
};
3.3.7 USB3.0/SATA/PCIe Combo PHY
USB3.0/SATA/PCIe Combo PHY
对应的设备节点为combphy2_psu
,定义在arch/arm64/boot/dts/rockchip/rk3588s.dtsi
;
combphy2_psu: phy@fee20000 {
compatible = "rockchip,rk3588-naneng-combphy";
reg = <0x0 0xfee20000 0x0 0x100>;
#phy-cells = <1>;
clocks = <&cru CLK_REF_PIPE_PHY2>, <&cru PCLK_PCIE_COMBO_PIPE_PHY2>,
<&cru PCLK_PHP_ROOT>;
clock-names = "refclk", "apbclk", "phpclk";
assigned-clocks = <&cru CLK_REF_PIPE_PHY2>;
assigned-clock-rates = <100000000>;
resets = <&cru SRST_P_PCIE2_PHY2>, <&cru SRST_REF_PIPE_PHY2>;
reset-names = "combphy-apb", "combphy";
rockchip,pipe-grf = <&php_grf>;
rockchip,pipe-phy-grf = <&pipe_phy2_grf>;
rockchip,pcie1ln-sel-bits = <0x100 1 1 0>;
status = "disabled";
};
3.3.8 使能
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-common.dtsi
中,使能了:
-
USB2.0 PHY0
; -
USB2.0 PHY2
; -
USB3.0/DP Combo PHY0
; -
USB3.0/SATA/PCIe Combo PHY
# USB2.0 PHY0
&u2phy0 {
status = "okay";
};
&u2phy0_otg {
status = "okay";
};
# USB2.0 PHY2
&u2phy2 {
status = "okay";
};
&u2phy2_host {
status = "okay";
};
# USB3.0/DP Combo PHY0
&usbdp_phy0 {
status = "okay";
};
&usbdp_phy0_u3 {
status = "okay";
};
# USB3.0/SATA/PCIe Combo PHY
&combphy2_psu {
status = "okay";
};
而USB2.0 PHY1
、USB2.0 PHY03
、USB3.0/DP Combo PHY1
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts
中有使能:
# USB2.0 PHY1
&u2phy1 {
status = "okay";
};
&u2phy1_otg {
phy-supply = <&vcc5v0_host_30>;
status = "okay";
};
# USB2.0 PHY3
&u2phy3 {
status = "okay";
};
&u2phy3_host {
phy-supply = <&vcc3v3_host_32>;
status = "okay";
};
# USB3.0/DP Combo PHY1
&usbdp_phy1 {
status = "okay";
};
&usbdp_phy1_u3 {
status = "okay";
};
3.4 USB3.0 Type-C
NanoPC-T6
开发板支持1个USB3.0 Type-C
接口,对应的USB
控制器为USB3.0 OTG0(DWC3/xHCI)
、对应的USB PHY
为USB3.0/DP Combo PHY0
和USB2 PHY0
;
因此对应的设备树配置,包括USB3.0 OTG0(DWC3/xHCI)
控制器设备树配置和USB3.0/DP Combo PHY0
、USB2 PHY0
设备树配置。
3.4.1 使能usbdrd3_0
通过dr_mode
属性设置USB
控制器的模式,一共有三种模式:otg
(同时支持主机/设备)、host
(主机)、peripheral
(设备),这里配置为otg
;
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts
配置:
# USB3.0 OTG0(DWC3/xHCI)
&usbdrd3_0 {
status = "okay";
};
&usbdrd_dwc3_0 {
dr_mode = "otg";
usb-role-switch;
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
dwc3_0_role_switch: endpoint@0 {
reg = <0>;
remote-endpoint = <&usbc0_role_sw>;
};
};
};
3.4.2 使能u2phy0_otg
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts
配置:
# USB2.0 PHY0
&u2phy0 {
status = "okay";
};
&u2phy0_otg {
rockchip,typec-vbus-det;
status = "okay";
};
3.4.3 使能usbdp_phy0_u3
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts
配置:
# USB3.0/DP Combo PHY0
&usbdp_phy0 {
orientation-switch;
rockchip,dp-lane-mux = <0 1 2 3 >;
svid = <0xff01>;
# 根据硬件设计,配置属性"sbu1-dc-gpios"和"sbu2-dc-gpios"
sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
usbdp_phy0_orientation_switch: endpoint@0 {
reg = <0>;
remote-endpoint = <&usbc0_orien_sw>;
};
usbdp_phy0_dp_altmode_mux: endpoint@1 {
reg = <1>;
remote-endpoint = <&dp_altmode_mux>;
};
};
};
&usbdp_phy0_u3 {
status = "okay";
};
3.4.4 电源配置
USB3.0 Type-C
电源VBUS5V0_TYPEC
由SY6280AAC
提供的,其输入端为VCC5V0_SYS
。由TYPEC5V_PWREN_H
(GPIO1_D2
)引脚使能,高电平有效;
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-common.dtsi
配置vbus5v0_typec
;
vbus5v0_typec: vbus5v0-typec {
compatible = "regulator-fixed";
enable-active-high;
# GPIO1_D2控制
gpio = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&typec5v_pwren>;
regulator-name = "vbus5v0_typec";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc5v0_usb>;
};
3.4.5 FUSB302
配置
配置外置Type-C
控制器芯片FUSB302
,设备节点fusb302@22
配置在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts
;
&i2c6 {
clock-frequency = <200000>;
status = "okay";
eeprom@53 {
compatible = "microchip,24c02", "atmel,24c02";
reg = <0x53>;
#address-cells = <2>;
#size-cells = <0>;
pagesize = <16>;
size = <256>;
eui_48: eui-48@fa {
reg = <0xfa 0x06>;
};
};
usbc0: fusb302@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
interrupt-parent = <&gpio0>;
interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
# 中断GPIO0_D3
int-n-gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&usbc0_int>;
vbus-supply = <&vbus5v0_typec>;
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
usbc0_role_sw: endpoint@0 {
remote-endpoint = <&dwc3_0_role_switch>;
};
};
};
usb_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
data-role = "dual";
power-role = "dual";
try-power-role = "sink";
op-sink-microwatt = <1000000>;
sink-pdos =
<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
source-pdos =
<PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>;
altmodes {
#address-cells = <1>;
#size-cells = <0>;
altmode@0 {
reg = <0>;
svid = <0xff01>;
vdo = <0xffffffff>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
usbc0_orien_sw: endpoint {
remote-endpoint = <&usbdp_phy0_orientation_switch>;
};
};
port@1 {
reg = <1>;
dp_altmode_mux: endpoint {
remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
};
};
};
};
};
};
具体配置可以参考:
Documentation/devicetree/bindings/usb/fcs,fusb302.txt
;Documentation/devicetree/bindings/connector/usb-connector.yaml
。
3.5 USB3.0 Type-A
NanoPC-T6
开发板支持1个USB3.0 Type-A
接口,对应的USB
控制器为USB3.0 OTG1(DWC3/xHCI)
、对应的USB PHY
为USB3.0/DP Combo PHY1
和USB2 PHY1
;
因此对应的设备树配置,包括USB3.0 OTG1(DWC3/xHCI)
控制器设备树配置和USB3.0/DP Combo PHY1
、USB2 PHY1
设备树配置。
3.5.1 使能usbdrd3_0
通过dr_mode
属性设置USB
控制器的模式,这里配置为host
。
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts
中配置:
# USB3.0 OTG1(DWC3/xHCI)
&usbdrd3_1 {
status = "okay";
};
# 如果配置dr_mode为otg,同时配置extcon = <&u2phy1>属性,才能支持软件切换Device/Host mode
&usbdrd_dwc3_1 {
dr_mode = "host";
status = "okay";
};
注意:NanoPC-T6
开发板大概率不支持USB3.0 Type-A
作为Device mode
使用,如果非要作为Device mode
使用,可以尝试将工作模式dr_mode
配置为otg
。
3.5.2 使能u2phy1_otg
USB3.0 Type-A
工作为主机模式时,可以外接USB
设备,比如鼠标,键盘,并为所连接的USB
设备提供VBUS
电源;因此需要配置phy-supply
,用于控制VBUS
输出5V
。
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts
配置:
# USB2.0 PHY1
&u2phy1 {
status = "okay";
};
&u2phy1_otg {
phy-supply = <&vcc5v0_host_30>;
status = "okay";
};
注意:使用phy-supply
,无法实现VBUS
的动态开关。如果工作模式dr_mode
配置为otg
(支持Device/HOST
),并且OTG
独占GPIO
,不与其它HOST
共用,则应该配置为vbus-supply = <&vcc5v0_host_30>
,才能实现VBUS
动态开关.
3.5.3 使能usbdp_phy1_u3
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts
配置:
# USB3.0/DP Combo PHY1
&usbdp_phy1 {
status = "okay";
};
&usbdp_phy1_u3 {
status = "okay";
};
3.5.4 电源配置
USB3.0 Type-A
电源VCC5V0_USB30_HOST2
由SY6280AAC
提供的,其输入端为VCC5V0_SYS
。由USB_HOST_PWREN_H
(GPIO4_B0
)引脚使能,,高电平有效;
在arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts
配置vcc5v0_host_30
;
vcc5v0_host_30: vcc5v0-host-30 {
compatible = "regulator-fixed";
enable-active-high;
# GPIO4_B0控制
gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_host30_en>;
regulator-name = "vcc5v0_host_30";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc5v0_usb>;
};
四、 配置内核
我们在《Rockchip RK3588
- 移植uboot 2017.09 & linux 6.1
(友善之家脚本方式)》中介绍了内核的编译是通过build-kernel.sh
脚本完成的,其主要包含两个流程:
- 配置内核:配置文件为
nanopi6_linux_defconfig
,位于./arch/arm64/configs/
目录下;
root@zhengyang:/work/sambashare/rk3588/friendly/sd-fuse_rk3588/kernel-rk3588# ll ./arch/arm64/configs/
-rw-r--r-- 1 root root 32510 12月 4 21:48 defconfig
-rw-r--r-- 1 root root 248 12月 4 21:48 friendlywrt.config
-rw-r--r-- 1 root root 45458 12月 4 21:48 nanopi4_linux_defconfig
-rw-r--r-- 1 root root 23865 12月 4 21:48 nanopi5_android_defconfig
-rw-r--r-- 1 root root 45436 12月 4 21:48 nanopi5_linux_defconfig
-rw-r--r-- 1 root root 23987 12月 4 21:48 nanopi6_android_defconfig
-rw-r--r-- 1 root root 45494 12月 4 21:48 nanopi6_linux_defconfig
-rw-r--r-- 1 root root 10741 12月 4 21:48 px30_linux_defconfig
-rw-r--r-- 1 root root 8901 12月 4 21:48 px30_linux_robot_defconfig
-rw-r--r-- 1 root root 10684 12月 4 21:48 rk1808_linux_defconfig
-rw-r--r-- 1 root root 5977 12月 4 21:48 rk1808_x4_linux_defconfig
-rw-r--r-- 1 root root 9271 12月 4 21:48 rk3308_linux_defconfig
-rw-r--r-- 1 root root 438 12月 4 21:48 rk3326_linux.config
-rw-r--r-- 1 root root 8901 12月 4 21:48 rk3326_linux_robot_defconfig
-rw-r--r-- 1 root root 32 12月 4 21:48 rk3358_linux.config
-rw-r--r-- 1 root root 4431 12月 4 21:48 rk3399pro_npu_defconfig
-rw-r--r-- 1 root root 9031 12月 4 21:48 rk3562_linux_dictpen_defconfig
-rw-r--r-- 1 root root 9673 12月 4 21:48 rk3562_robot.config
-rw-r--r-- 1 root root 166 12月 4 21:48 rk3568_nvr.config
-rw-r--r-- 1 root root 387 12月 4 21:48 rk3588_edge.config
-rw-r--r-- 1 root root 111 12月 4 21:48 rk3588_ipc_linux.config
-rw-r--r-- 1 root root 81 12月 4 21:48 rk3588_linux.config
-rw-r--r-- 1 root root 2440 12月 4 21:48 rk3588_nvr.config
-rw-r--r-- 1 root root 26948 12月 4 21:48 rockchip_defconfig
-rw-r--r-- 1 root root 14670 12月 4 21:48 rockchip_electric_defconfig
-rw-r--r-- 1 root root 9080 12月 4 21:48 rockchip_gki.config
-rw-r--r-- 1 root root 16747 12月 4 21:48 rockchip_linux_defconfig
-rw-r--r-- 1 root root 7457 12月 4 21:48 rockchip_linux_docker.config
-rw-r--r-- 1 root root 137 12月 4 21:48 rockchip_rt.config
- 编译内核;
注意:接下来介绍的内核配置在nanopi6_linux_defconfig
中默认情况下是已经配置了,所以我们不需要再次配置。
4.1 配置USB PHY
USB2.0 PHY
使用的是Innosilicon IP
,应选择Rockchip INNO USB2PHY Driver
,驱动位于drivers/phy/rockchip/phy-rockchip-inno-usb2.c
;
USB3.0/DP Combo PHY
使用的是Innosilicon IP
,应选择Rockchip USBDP COMBO PHY Driver
,驱动位于drivers/phy/rockchip/phy-rockchip-usbdp.c
;
SB3.0/SATA/PCIe Combo PHY
使用的是NaNeng IP
,应选择Rockchip NANENG COMBO PHY Driver
,驱动位于drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
;
所以需要配置:
CONFIG_PHY_ROCKCHIP_INNO_USB2=y
CONFIG_PHY_ROCKCHIP_USBDP=y
CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y
官方内核在配置了ARCH_ROCKCHIP
以及USB_SUPPORT
等配置的的情景下,会配置了这些配置项。更多细节可以参考:drivers/phy/rockchip/Kconfig
。
4.2 配置USB
控制器
在linux
内核根目录下执行make menuconfig
配置以下选项:
Device Drivers --->
[*] USB support --->
<*> xHCI HCD (USB 3.0) support
-*- Generic xHCI driver for a platform device
<*> EHCI HCD (USB 2.0) support
-*- Root Hub Transaction Translators
[*] Improved Transaction Translator scheduling
<*> Generic EHCI driver for a platform device
<*> OHCI HCD (USB 1.1) support
<*> Generic OHCI driver for a platform device
[*] USB announce new devices(输出识别的每个usb设备的基本信息,比如idVendor、idProduct、制造商、产品、和序列号等)
OHCI HCD (USB 1.1)
选择OHCI Driver
配置;
EHCI HCD (USB 2.0)
选择EHCI Driver
配置;
xHCI HCD (USB 3.0)
选择xHCI Driver
配置。
4.3 配置USB OTG
默认情况下dw3
是双角色(即同时支持Host
和Device
模式,可以动态切换):
Device Drivers --->
[*] USB support --->
<*> DesignWare USB2 DRD Core Support
DWC2 Mode Selection (Dual Role mode)
<*> DesignWare USB3 DRD Core Support
DWC3 Mode Selection (Dual Role mode)
RK3588 USB3.0 OTG
使用Synopsys
方案,即xHCI
扩展的DWC3
控制器,因此需要配置DesignWare USB3 DRD Core Support
。
4.4 配置USB Gadget
我们使用的开发板USB3.0 Type-C PHY0
、USB2.0 OTG PHY0
物理接口被设计为USB3.0 Type-C
,并且外置了Type-C
控制器芯片(FUSB302
)支持软件自动切换Deivice/Host mode
。
如果我们将该物理接口配置USB device
(丛机)使用,我们可以将开发板模拟成一个存储设备、或者声卡、鼠标等设备,然后可以通过开发板上的USB3.0 Type-C
接口将PC
和开发板连接在一起。
在linux
内核根目录下执行make menuconfig
配置以下选项:
File systems --->
Pseudo filesystems --->
/* 配置CONFIG_CONFIGFS_FS,为用户空间提供访问配置内核驱动的configfs文件系统 */
-*- Userspace-driven configuration filesystem
Device Drivers --->
[*] USB support --->
<*> USB Gadget Support --->
/* 配置了CONFIG_USB_CONFIGFS、同时会自动配置CONFIG_USB_LIBCOMPOSITE(生成libcomposite.ko,提供USB Gadget Composite框架) */
<*> USB Gadget functions configurable through configfs
[*] Uevent notification of Gadget state
[ ] Generic serial bulk in/out /* usb_f_serial.ko */
[*] Abstract Control Model (CDC ACM) /* usb_f_acm.ko */
[ ] Object Exchange Model (CDC OBEX) /* usb_f_obex.ko */
[*] Network Control Model (CDC NCM) /* usb_f_ncm.ko */
[ ] Ethernet Control Model (CDC ECM) /* usb_f_ecm.ko */
[ ] Ethernet Control Model (CDC ECM) subset /* usb_f_ecm_subset.ko */
[*] RNDIS /* usb_f_rndis.ko */
[ ] Ethernet Emulation Model (EEM) /* usb_f_eem.ko */
[*] Mass storage (大容量存储功能) /* usb_f_mass_storage.ko */
[ ] Loopback and sourcesink function (for testing)
/* 文件系统功能(FunctionFS)可以让用户在用户空间中创建USB复合功能,就像GadgetFS可以让用户在用户空间中创建USB设备一样 */
[*] Function filesystem (FunctionFS) /* usb_f_fs.ko */
[ ] Audio Class 1.0 (音频功能 1.0) /* usb_f_uac1.ko */
[ ] Audio Class 1.0 (legacy implementation) /* usb_f_uac1_legacy.ko */
[ ] Audio Class 2.0 (音频功能 2.0) /* usb_f_uac2.ko */
[*] MIDI function
[*] HID function (HID功能) /* usb_f_hid.ko */
[*] USB Webcam functio (USB摄像头功能) /* usb_f_uvc.ko */
[ ] Printer function
USB Gadget precomposed configurations ---> /* USB Gadget预配置(位于drivers/usb/gadget/legacy) */
< > Gadget Zero (DEVELOPMENT)
< > Audio Gadget (音频设备) /* g_audio.ko */
< > Ethernet Gadget (with CDC Ethernet support) (网络设备)
< > Network Control Model (NCM) support
< > Gadget Filesystem /* 配置CONFIG_USB_GADGETFS */
< > Function Filesystem /* 配置CONFIG_USB_FUNCTIONFS */
< > Mass Storage Gadget (大容量存储设备) /* g_mass_storage.ko */
< > Serial Gadget (with CDC ACM and CDC OBEX support) (串口设备)
< > MIDI Gadget
< > Printer Gadget (打印机)
< > CDC Composite Device (Ethernet and ACM)
< > CDC Composite Device (ACM and mass storage)
< > Multifunction Composite Gadget
< > HID Gadget (hid设备) /* g_hid.ko */
< > EHCI Debug Device Gadget
< > USB Webcam Gadget (USB摄像头)
< > USB Raw Gadget (生成设备节点/dev/raw-gadget)
USB Gadget
驱动主要包括两大块:
-
USB Gadget functions
:各种USB
子类设备功能接口驱动,位于drivers/usb/gadget/function
目录下,里面给出了对应的sample
。其作用是配置USB
子类协议的接口描述以及其它子类协议,比如uvc
协议,hid
等;比如我们配置了大容量存储设备驱动,编译完之后,就会在function
目录下生成usb_f_mass_storage.ko
; -
USB Gadget Legacy
:整个gadget
设备驱动的入口,位于drivers/usb/gadget/legacy
目录下,这个目录下的驱动目前已经过时了,不再建议使用了,以后的linux
版本或许会消失:里面给出了常用的USB
类设备的驱动sample
,其作用就是配置USB
设备描述符信息,提供一个usb_composite_driver
, 然后注册到composite
层;比如我们配置了大容量存储设备驱动,编译完之后,就会在legacy
目录下生成g_mass_storage.ko
;
有关USB Gadget
驱动更加具体内容参考《一文搞懂 USB
设备端驱动框架》、《Rockchip RK3399 - USB
调试》。
4.5 配置USB
外设
根据开发板硬件情况,配置支持各种USB
设备。
4.5.1 配置大容量存储设备
移动硬盘属于SCSI
设备,所以在配置USB
模块之前需要配置SCSI
选项;
Device Drivers --->
SCSI device support --->
<*> SCSI device support
[*] legacy /proc/scsi/ support
*** SCSI support type (disk, tape, CD-ROM) ***
<*> SCSI disk support
<M> SCSI tape support
<M> SCSI CDROM support
<M> SCSI generic support
[*] /dev/bsg support (SG v4)
<M> SCSI media changer support
[*] Verbose SCSI error reporting (kernel size +=75K)
[*] SCSI logging facility
[*] Asynchronous SCSI scanning
SCSI Transports --->
[*] SCSI low-level drivers --->
[ ] SCSI Device Handlers ----
配置完SCSI Device Support
后,可以在USB Support
中找到如下选项,选上即可
Device Driver --->
[*] USB support --->
<*> USB Mass Storage support
4.5.2 配置USB
转串口
(1) 支持USB 3G Modem
USB 3G Modem
使用的是USB
转串口,使用时需要选上如下选项:
Device Driver --->
[*] USB support --->
<*> USB Serial Converter support --->
<*> USB driver for GSM and CDMA modems
此外,USB 3G Modem
还需要使能PPP
拨号的相关配置项:
Device Driver --->
[*] Network device support --->
<M> PPP (point-to-point protocol) support
<M> PPP BSD-Compress compression
<*> PPP Deflate compression
[M] PPP filtering
<*> PPP MPPE compression (encryption)
[*] PPP multilink support
< > PPP over Ethernet
<M> PPP over L2TP
<M> PPP on L2TP Access Concentrator
<M> PPP on PPTP Network Server
<M> PPP support for async serial ports
<M> PPP support for sync tty ports
(2) 支持PL2303
如果要使用PL2303
输出数据到串口,需要选择如下选项,同时需要禁用 USB driver for GSM and CDMA modems
,否则,PL2303
可能会被误识别为USB 3G modem
;
Device Driver --->
[*] USB support --->
<*> USB Serial Converter support --->
<*> USB Prolific 2303 Single Port Serial Driver
(3) 支持USB GPS
如果要支持USB GPS
,如u-blox 6-GPS Receiver
设备,需要选择如下选项:
Device Drivers --->
[*] USB support --->
[*] USB Modem (CDC ACM) support
4.5.3 配置HID
在内核中,配置USB
键盘、鼠标、触摸屏驱动有多种方式,我们采用其中一种即可。
(1) 通用HID
驱动程序
如果要使用USB
接口的keyboards
(键盘)、mice
(鼠标)、joysticks
(摇杆)、graphic tablets
(绘图板)等其他的HID
设备,那么就需要配置USB HID Transport layer
(USB
人机接口设备传输层)。
USB HID transport layer
此选项对应配置项就是CONFIG_USB_HID
,也就是通用HID
驱动程序。
Device Drivers --->
HID support --->
[*] HID bus support
-*- HID bus core support
<*> Generic HID driver
USB HID support --->
<*> USB HID transport layer
[*] PID device support
[*] /dev/hiddev raw HID device support
USB HID Transport Layer
是USB
协议栈中的一个组件,用于支持 HID
类型的设备与计算机之间的通信。USB HID
传输层负责解析来自HID
设备的数据,并将其转换为适当的格式,以便应用程序可以理解和使用。
通用HID
驱动程序在内核源码的drivers/hid/usbhid/
目录下,如下所示:
root@zhengyang:/work/sambashare/rk3588/friendly/sd-fuse_rk3588/kernel-rk3588# ls drivers/hid/usbhid/
built-in.a hid-core.o hiddev.o hid-pidff.o Makefile usbhid.h usbmouse.c
hid-core.c hiddev.c hid-pidff.c Kconfig modules.order usbkbd.c
在drivers/hid/usbhid/Makefile
:
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the USB input drivers
#
usbhid-y := hid-core.o
usbhid-$(CONFIG_USB_HIDDEV) += hiddev.o
usbhid-$(CONFIG_HID_PID) += hid-pidff.o
obj-$(CONFIG_USB_HID) += usbhid.o
obj-$(CONFIG_USB_KBD) += usbkbd.o
obj-$(CONFIG_USB_MOUSE) += usbmouse.o
如上面Makefile
所示,根据Kconfig
文件里CONFIG_USB_HID=y
或者m
,通用HID
驱动程序可以编译进内核,也可以编译成usbhid.ko
模块,usbhid.ko
可以由hid-core.c+hiddev.c+hid-pidff.c
组成。
当我们把USB
接口的鼠标/键盘接入到设备上时,在/dev/input
目录下会生成event*
设备,用evtest
工具打开/dev/input/event*
设备,移动鼠标和点击左/右键或者敲击键盘时会显示出相应的鼠标/键盘事件。
在某些嵌入式设备上,如果不想为USB
鼠标、键盘使用通用的HID
驱动程序,而更喜欢在其有限的Boot Protocol
模式下使用鼠标/键盘时,可以使用usbmouse.c/usbkbd.c
作为鼠标和键盘驱动程序。
关于USB
鼠标我们之前有单独的文章介绍:《linux
驱动移植-usb
鼠标接口驱动》。
关于USB
键盘我们之前有单独的文章介绍:《驱动移植-键盘接口驱动》。
(2) Generic input layer
实际上在linux
中还有一个通用输入层子系统,用于处理和管理各种输入设备,例如键盘、鼠标、触摸屏和游戏手柄等。通用输入层提供了一个统一的接口,使应用程序可以以一致的方式与不同类型的输入设备进行交互,配置如下:
Device Drivers --->
Input device support
-*- Generic input layer (needed for keyboard, mouse, ...)
那他们之间有什么区别呢?
区别在于:
-
Generic Input Layer
是Linux
内核的一个通用输入设备管理层,它与各种输入设备进行交互,并将输入数据传递给应用程序; -
USB HID Transport Layer
则是USB
协议栈中的一个特定组件,专门用于处理HID
设备的通信和数据传输;
通用输入层可以与各种输入设备一起使用(不仅限于USB HID
设备),而USB HID
传输层则专注于USB HID
设备的通信协议。针对于USB
输入设备,我们配置USB HID transport layer
即可。
4.5.4 配置USB
摄像头
Device Drivers -->
<*> Multimedia support --->
[ ] Filter media drivers
Media core support --->
<*> Video4Linux core
-*- Media Controller API
Media drivers --->
[*] Media USB Adapters(启用usb总线的媒体驱动程序,drivers/media/usb)
<M> USB Video Class(UVC)(我使用摄像头支持UVC,选择这个驱动即可)
[ ] UVC input events device support
< > GSPCA based webcams ---- (GSPCA 是一个法国程序员在业余时间制作的一个万能USB 摄像头驱动程序,在此可以选择对应类型USB摄像头的支持)
< > ....
[*] Media platform devices --->
[*] V4L platform devices
关于USB
摄像头我们之前有单独的文章介绍:《linux
驱动移植-usb
摄像头uvc
驱动》。
4.5.5 配置USB
音频
Device Driver --->
<*> Sound card support --->
<*> Advanced Linux Sound Architecture --->
[*] USB sound devices --->
[M] USB Audio/MIDI driver
4.5.6 配置USB HUB
如果要支持USB HUB
,请将Disable external hubs
配置选项去掉;
Device Drivers --->
[*] USB support --->
[ ] Disable external hubs
其它有可能用到的USB
设备还有很多,如GPS
,Printer
等,有可能需要Vendor
定制的驱动,也有可能
是标准的 设备类驱动,如需支持这类设备,可直接在网络上搜索linux
对该设备支持要做的工作。
4.6 配置extcon
配置Fairchild FUSB302 Type-C chip driver
驱动,将drivers/usb/typec/tcpm/fusb302.c
编译到内核;
Device Driver --->
<*> External Connector Class (extcon) support --->
<*> USB support --->
<*> USB Type-C Support --->
[*] USB Type-C Port Controller Manager --->
[*] Fairchild FUSB302 Type-C chip driver
4.7 保存配置
配置完内核之后记得保存配置,名称为nanopi6_linux_defconfig
。存档:
oot@zhengyang:/work/sambashare/rk3588/friendly/sd-fuse_rk3588/kernel-rk3588# mv nanopi6_linux_defconfig ./arch/arm64/configs/
4.8 烧录内核
接着按照《Rockchip RK3588
- 移植uboot 2017.09 & linux 6.1
(友善之家脚本方式)》教程进行编译烧录内核。
五、调试接口
5.1 sysfs
5.1.1 USB
设备
所有USB
设备可以在/sys/bus/usb/devices
下找到;
root@NanoPC-T6:~# ls -l /sys/bus/usb/devices
总用量 0
lrwxrwxrwx 1 root root 0 12月 18 23:56 1-0:1.0 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-0:1.0 # USB3.0 OTG1
lrwxrwxrwx 1 root root 0 12月 18 23:56 2-0:1.0 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb2/2-0:1.0 # USB3.0 OTG1
lrwxrwxrwx 1 root root 0 12月 18 23:56 3-0:1.0 -> ../../../devices/platform/fc800000.usb/usb3/3-0:1.0 # USB2.0 HOST0 EHCI
lrwxrwxrwx 1 root root 0 12月 18 23:56 4-0:1.0 -> ../../../devices/platform/fc840000.usb/usb4/4-0:1.0 # USB2.0 HOST0 OHCI
lrwxrwxrwx 1 root root 0 12月 18 23:56 5-0:1.0 -> ../../../devices/platform/fc880000.usb/usb5/5-0:1.0 # USB2.0 HOST1 EHCI
lrwxrwxrwx 1 root root 0 12月 18 23:56 6-0:1.0 -> ../../../devices/platform/fc8c0000.usb/usb6/6-0:1.0 # USB2.0 HOST1 OHCI
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb1 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb2 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb2
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb3 -> ../../../devices/platform/fc800000.usb/usb3
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb4 -> ../../../devices/platform/fc840000.usb/usb4
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb5 -> ../../../devices/platform/fc880000.usb/usb5
lrwxrwxrwx 1 root root 0 12月 18 23:56 usb6 -> ../../../devices/platform/fc8c0000.usb/usb6
如上图所示,可以看到大量的USB
设备。取名规则如下:
bus-port[.port]:configuration.interface
其中:
bus
:表示USB
控制器所连接的总线编号;从1开始编号;port
:表示总线上的硬件端口号;从0开始编号;比如1-0
是根hub
自身信息,当hub
上有插入设备时,就会出现1-1
了。port
:如果总线上的硬件端口连接的设备是一个HUB
,那么该port
表示连接在hub
上的硬件端口号;从1开始编号;configuration
:表示设备的配置值;从1开始编号;interface
:表示设备的接口号;从0开始编号;
比如1-1:1.1
具有以下含义:
1-1
:表示连接到第一个USB
控制器的编号为1的硬件端口;1.1
:表示设备的第一个配置(configuration
)编号为1接口(interface
)。
7-1.2:1.0
具有以下含义:
7-1.2
:表示连接到第7个USB
控制器的编号为1的硬件端口连接了一个hub
,hub
编号为2的硬件端口上连接了一个设备;1.0
:表示设备的第一个配置(configuration
)编号为0接口(interface
)。
如果仔细看上面的USB
信息,我们发现缺少了缺了 USB3.0 OTG0
、USB3.0 HOST2
(xHCI
)。
对于USB3.0 HOST2
(xHCI
)我们查看一下设备节点usbhost3_0
的配置:
root@NanoPC-T6:~# cat /sys/firmware/devicetree/base/usbhost3_0/status
disabled
这里我们发现该USB
控制器处于禁用状态,这是因为设备树配置中将其禁用了。
我们可以使用 dtc
(device tree compiler
)工具将设备树二进制文件转换为可读的文本格式,以更方便地查看设备树配置:
root@NanoPC-T6:~# aptitude install device-tree-compiler
root@NanoPC-T6:~# dtc -I fs -O dts -o output.dts /sys/firmware/devicetree/base/
5.1.2 USB
设备信息
由于当前开发板的USB
接口没有介入任何设备,因此看到都是USB
控制器上连接的root hub
;
root@NanoPC-T6:~# cd /sys/bus/usb/devices
root@NanoPC-T6:/sys/bus/usb/devices# ls
1-0:1.0 2-0:1.0 3-0:1.0 4-0:1.0 5-0:1.0 6-0:1.0 usb1 usb2 usb3 usb4 usb5 usb6
root@NanoPC-T6:/sys/bus/usb/devices# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
接着我们向开发板USB3.0 Type-A
接口插入一个鼠标,再次查看:
root@NanoPC-T6:/sys/bus/usb/devices# ls
1-0:1.0 1-1 1-1:1.0 1-1:1.1 1-1:1.2 2-0:1.0 3-0:1.0 4-0:1.0 5-0:1.0 6-0:1.0 usb1 usb2 usb3 usb4 usb5 usb6
可以看到多出了目录1-1 1-1:1.0 1-1:1.1 1-1:1.2
;
lrwxrwxrwx 1 root root 0 12月 23 12:05 1-1 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1
lrwxrwxrwx 1 root root 0 12月 23 12:05 1-1:1.0 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1/1-1:1.0
lrwxrwxrwx 1 root root 0 12月 23 12:05 1-1:1.1 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1/1-1:1.1
lrwxrwxrwx 1 root root 0 12月 23 12:05 1-1:1.2 -> ../../../devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1/1-1:1.2
实际上后面三个都是链接文件都是指向1-1
目录下的子文件。1-1
表示连接到第一个USB
控制器的编号为1的硬件端口;
1-1:1.0
:表示设备的第一个配置(configuration
)编号为0接口(interface
);1-1:1.1
:表示设备的第一个配置(configuration
)编号为1接口(interface
);1-1:1.2
:表示设备的第一个配置(configuration
)编号为2接口(interface
);
我们查看一下USB
鼠标的信息:
root@NanoPC-T6:/sys/bus/usb/devices# cat 1-1/idProduct
c52b
root@NanoPC-T6:/sys/bus/usb/devices# cat 1-1/idVendor
046d
root@NanoPC-T6:/sys/bus/usb/devices# cat 1-1/product
USB Receiver
root@NanoPC-T6:/sys/bus/usb/devices# cat 1-1/manufacturer
Logitech
实际上这个信息在内核日志也是可以看到的:
[389322.004486] usb 1-1: new full-speed USB device number 9 using xhci-hcd
[389322.147736] usb 1-1: New USB device found, idVendor=046d, idProduct=c52b, bcdDevice=24.11
[389322.147753] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[389322.147762] usb 1-1: Product: USB Receiver
[389322.147769] usb 1-1: Manufacturer: Logitech
[389322.189271] logitech-djreceiver 0003:046D:C52B.0015: hiddev96,hidraw0: USB HID v1.11 Device [Logitech USB Receiver] on usb-xhci-hcd.9.auto-1/input2
[389322.311793] input: Logitech M545/M546 as /devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1/1-1:1.2/0003:046D:C52B.0015/0003:046D:4052.0016/input/input28
[389322.312977] logitech-hidpp-device 0003:046D:4052.0016: input,hidraw1: USB HID v1.11 Mouse [Logitech M545/M546] on usb-xhci-hcd.9.auto-1/input2:1
[389343.419592] logitech-hidpp-device 0003:046D:4052.0016: HID++ 4.5 device connected.
USB
鼠标工作在全速模式下,xHCI
控制器,USB1.1
通信协议,使用的USB
总线编号为1,设备编号为9。
5.2 debugfs
USB
调试信息位于/sys/kernel/debug/usb
;
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/
总用量 0
-r--r--r-- 1 root root 0 1月 1 1970 devices
drwxr-xr-x 4 root root 0 1月 1 1970 ehci
drwxr-xr-x 18 root root 0 1月 1 1970 fc000000.usb
drwxr-xr-x 2 root root 0 1月 1 1970 fc400000.usb
drwxr-xr-x 2 root root 0 12月 18 23:56 fusb302-6-0022
drwxr-xr-x 4 root root 0 1月 1 1970 ohci
drwxr-xr-x 2 root root 0 12月 18 23:56 tcpm-6-0022
drwxr-xr-x 3 root root 0 1月 1 1970 xhci
其中:
devices
:该文件列出了当前系统中已连接的USB
设备的详细信息;ehci
:该目录包含EHCI
主机控制器接口的调试信息;fc000000.usb
:该目录包含与fc000000.usb
控制器相关的调试信息,即USB3.0 OTG0
控制器;fc400000.usb
:该目录包含与fe900000.usb
控制器相关的调试信息,即USB3.0 OTG1
控制器;fusb302-6-0022
:该目录包含与fusb302-6-0022
设备相关的调试信息,6为I2C
总线编号,0022为I2C
设备地址;ohci
:该目录包含OHCI
主机控制器接口的调试信息;tcpm-6-0022
:该目录包含与tcpm-6-0022
设备相关的调试信息,4为I2C
总线编号,0022为I2C
设备地址;xhci
:该目录包含XHCI
主机控制器的调试信息;
5.2.1 查看USB3.0 OTG0
工作模式
查看USB3.0 OTG0(DWC3/xHCI)
控制器工作模式,USB3.0 OTG0(DWC3/xHCI)
控制器对应设备节点usbdrd3_0: usb@fc000000
:
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/fc000000.usb/
总用量 0
drwxr-xr-x 2 root root 0 12月 18 23:56 ep0in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep0out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep1in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep1out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep2in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep2out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep3in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep3out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep4in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep4out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep5in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep5out
drwxr-xr-x 2 root root 0 12月 18 23:56 ep6in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep7in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep8in
drwxr-xr-x 2 root root 0 12月 18 23:56 ep9in
-rw-r--r-- 1 root root 0 1月 1 1970 link_state
-rw-r--r-- 1 root root 0 1月 1 1970 lsp_dump
-rw-r--r-- 1 root root 0 1月 1 1970 mode
-r--r--r-- 1 root root 0 1月 1 1970 regdump
-rw-r--r-- 1 root root 0 1月 1 1970 testmode
其中:
link_state
:打印DWC3
的链路状态;regdump
:打印DWC3
控制器的寄存器状态信息;mode
:打印DWC3
的工作模式;testmode
:设置DWC3
进HighSpeed
的测试模式;
此外,DWC3
控制器驱动还实现了基于内核trace
框架的tracepoint
,支持动态使能并保存DWC3
驱动关键信息。
(1) 设备模式
我们通过Type-C
连接线将USB3.0 Type-C
接口与PC
连接在一起,我们可以查看USB3.0 OTG0
控制器的工作模式:
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fc000000.usb/mode
device
可以看到USB3.0 OTG0
控制器工作在Device
(设备)模式。
(2) 主机模式
如果我们将Type-C
接口的U
盘连接到USB3.0 Type-C
接口,可以看到内核日志如下:
[348278.750101] phy phy-fd5d0000.syscon:usb2-phy@0.0: illegal mode
[348278.750125] xhci-hcd xhci-hcd.13.auto: xHCI Host Controller
[348278.750143] xhci-hcd xhci-hcd.13.auto: new USB bus registered, assigned bus number 7
[348278.750245] xhci-hcd xhci-hcd.13.auto: hcc params 0x0220fe64 hci version 0x110 quirks 0x0000202002010010
[348278.750273] xhci-hcd xhci-hcd.13.auto: irq 90, io mem 0xfc000000
[348278.750376] xhci-hcd xhci-hcd.13.auto: xHCI Host Controller
[348278.750387] xhci-hcd xhci-hcd.13.auto: new USB bus registered, assigned bus number 8
[348278.750398] xhci-hcd xhci-hcd.13.auto: Host supports USB 3.0 SuperSpeed
[348278.750499] usb usb7: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.01
[348278.750509] usb usb7: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[348278.750517] usb usb7: Product: xHCI Host Controller
[348278.750524] usb usb7: Manufacturer: Linux 6.1.25 xhci-hcd
[348278.750530] usb usb7: SerialNumber: xhci-hcd.13.auto
[348278.750822] hub 7-0:1.0: USB hub found
[348278.750848] hub 7-0:1.0: 1 port detected
[348278.751081] usb usb8: We don't know the algorithms for LPM for this host, disabling LPM.
[348278.751155] usb usb8: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 6.01
[348278.751165] usb usb8: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[348278.751173] usb usb8: Product: xHCI Host Controller
[348278.751179] usb usb8: Manufacturer: Linux 6.1.25 xhci-hcd
[348278.751186] usb usb8: SerialNumber: xhci-hcd.13.auto
[348278.751444] hub 8-0:1.0: USB hub found
[348278.751467] hub 8-0:1.0: 1 port detected
[348278.999777] usb 7-1: new high-speed USB device number 2 using xhci-hcd
[348279.140469] usb 7-1: New USB device found, idVendor=14cd, idProduct=1212, bcdDevice= 1.00
[348279.140494] usb 7-1: New USB device strings: Mfr=1, Product=3, SerialNumber=2
[348279.140502] usb 7-1: Product: Mass Storage Device
[348279.140509] usb 7-1: Manufacturer: Generic
[348279.140516] usb 7-1: SerialNumber: 121220160204
[348279.141207] usb-storage 7-1:1.0: USB Mass Storage device detected
[348279.141451] scsi host0: usb-storage 7-1:1.0
[348280.146932] scsi 0:0:0:0: Direct-Access Mass Storage Device 1.00 PQ: 0 ANSI: 0 CCS
[348280.147312] sd 0:0:0:0: Attached scsi generic sg0 type 0
[348280.301906] sd 0:0:0:0: [sda] 30277632 512-byte logical blocks: (15.5 GB/14.4 GiB)
[348280.302047] sd 0:0:0:0: [sda] Write Protect is off
[348280.302057] sd 0:0:0:0: [sda] Mode Sense: 03 00 00 00
[348280.302184] sd 0:0:0:0: [sda] No Caching mode page found
[348280.302193] sd 0:0:0:0: [sda] Assuming drive cache: write through
[348280.308888] sda: sda1 sda2 sda3 sda4 sda5 sda6 sda7 sda8 sda9
[348280.309574] sd 0:0:0:0: [sda] Attached SCSI removable disk
同时USB3.0 OTG0
控制器工作在Host
(主机)模式;
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fc000000.usb/mode
host
5.2.2 查看USB3.0 OTG1
工作模式
查看USB3.0 OTG1(DWC3/xHCI)
控制器工作模式,USB3.0 OTG1(DWC3/xHCI)
控制器对应设备节点usbdrd3_1: usb@fc400000
:
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fc400000.usb/mode
host
可以看到USB3.0 OTG1
控制器工作在Host
(主机)模式。
5.2.3 查看xhci
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/xhci/
总用量 0
drwxr-xr-x 6 root root 0 1月 1 1970 xhci-hcd.9.auto
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/xhci/xhci-hcd.9.auto/
总用量 0
drwxr-xr-x 2 root root 0 1月 1 1970 command-ring
drwxr-xr-x 3 root root 0 12月 23 00:57 devices
drwxr-xr-x 2 root root 0 1月 1 1970 event-ring
drwxr-xr-x 4 root root 0 1月 1 1970 ports
-r--r--r-- 1 root root 0 1月 1 1970 reg-cap
-r--r--r-- 1 root root 0 1月 1 1970 reg-ext-legsup:00
-r--r--r-- 1 root root 0 1月 1 1970 reg-ext-protocol:00
-r--r--r-- 1 root root 0 1月 1 1970 reg-ext-protocol:01
-r--r--r-- 1 root root 0 1月 1 1970 reg-op
-r--r--r-- 1 root root 0 1月 1 1970 reg-runtime
5.2.4 查看ehci
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/ehci/
总用量 0
drwxr-xr-x 2 root root 0 1月 1 1970 fc800000.usb
drwxr-xr-x 2 root root 0 1月 1 1970 fc880000.usb
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/ehci/fc800000.usb/
总用量 0
-r--r--r-- 1 root root 0 1月 1 1970 async
-r--r--r-- 1 root root 0 1月 1 1970 bandwidth
-r--r--r-- 1 root root 0 1月 1 1970 periodic
-r--r--r-- 1 root root 0 1月 1 1970 registers
5.2.5 查看fusb302-6-0022
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/fusb302-6-0022/
总用量 0
-r--r--r-- 1 root root 0 12月 18 23:56 log
该文件会记录USB3.0 Type-C
接口设备插拔时以及角色切换的信息,以USB3.0 Type-C
接口有USB
鼠标接入的日志为例;
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fusb302-6-0022/log
[392786.091210] IRQ: 0x21, a: 0x40, b: 0x00, status0: 0x01
[392786.091216] IRQ: TOGDONE
[392786.091810] get_src_cc_status switches: 0x44
[392786.092295] get_src_cc_status rd_mda status0: 0x1
[392786.092778] get_src_cc_status ra_mda status0: 0x21
[392786.094659] get_src_cc_status switches: 0x88
[392786.095143] get_src_cc_status rd_mda status0: 0x23
[392786.096222] detected cc1=Rd, cc2=Open
[392786.096231] cc1=Rd, cc2=Open
[392786.097099] IRQ: 0x21, a: 0x00, b: 0x00, status0: 0x01
[392786.097103] IRQ: COMP_CHNG, comp=false
[392786.296268] cc := Rd
[392786.299776] IRQ: 0x01, a: 0x00, b: 0x00, status0: 0x00
[392786.299779] IRQ: BC_LVL, handler pending
[392786.331880] BC_LVL handler, status0=0x00
[392786.398930] cc := Rp-1.5
[392786.504005] start drp toggling
[392786.553159] IRQ: 0x01, a: 0x40, b: 0x00, status0: 0x01
[392786.553166] IRQ: TOGDONE
[392786.553760] get_src_cc_status switches: 0x44
[392786.554244] get_src_cc_status rd_mda status0: 0x1
[392786.554728] get_src_cc_status ra_mda status0: 0x21
[392786.556609] get_src_cc_status switches: 0x88
[392786.557092] get_src_cc_status rd_mda status0: 0x23
[392786.558168] detected cc1=Rd, cc2=Open # 检测到对方是Rd下拉,因此USB3.0 Type-C接口作为供电方
[392786.558176] cc1=Rd, cc2=Open
[392786.559045] IRQ: 0x20, a: 0x00, b: 0x00, status0: 0x01
[392786.559048] IRQ: COMP_CHNG, comp=false
[392786.758666] pd header := Source, Host # 工作为主机模式
[392786.761053] pd := on
[392786.761069] vbus := On
[392786.761071] charge is already Off
[392786.762222] IRQ: 0x80, a: 0x00, b: 0x00, status0: 0x81
[392786.762226] IRQ: VBUS_OK, vbus=On # VBUS供电开启,为连接的USB设备提供VBUS电源
[392786.762248] cc := Rp-1.5
[392786.766246] sending PD message header: 11a1
[392786.766249] sending PD message len: 4
[392786.773617] IRQ: 0x41, a: 0x10, b: 0x00, status0: 0x82
[392786.773621] IRQ: PD retry failed
......
当USB
鼠标从USB3.0 Type-C
接口移除:
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fusb302-6-0022/log
[392791.999035] cc := Rp-1.5
[393000.156208] IRQ: 0x21, a: 0x00, b: 0x00, status0: 0xa3
[393000.156213] IRQ: COMP_CHNG, comp=true
[393000.156227] cc1=Open, cc2=Open
[393000.158609] pd := off
[393000.158623] vbus := Off
[393000.158625] charge is already Off
[393000.158627] vconn is already Off
[393000.159121] pd header := Source, Host
[393000.160014] IRQ: 0x80, a: 0x00, b: 0x00, status0: 0x23
[393000.160018] IRQ: VBUS_OK, vbus=Off # VBUS供电关闭
[393000.162340] start drp toggling
如果USB3.0 Type-C
接口连接到PC
:
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fusb302-6-0022/log
[394208.588702] IRQ: 0xa0, a: 0x00, b: 0x00, status0: 0x83
[394208.588708] IRQ: VBUS_OK, vbus=On
[394208.639880] IRQ: 0x01, a: 0x40, b: 0x00, status0: 0x81
[394208.639883] IRQ: TOGDONE
[394208.642732] detected cc1=Rp-def, cc2=Open # 检测到对方是Rp上拉,因此USB3.0 Type-C接口作为耗电方
[394208.642741] cc1=Rp-def, cc2=Open
[394208.843243] pd header := Sink, Device # 工作为设备模式
[394208.843304] vbus is already Off # VBUS供电关闭
[394208.845588] pd := on
[394209.157028] IRQ: 0x41, a: 0x08, b: 0x00, status0: 0x81
[394209.157033] IRQ: BC_LVL, handler pending
[394209.157035] IRQ: PD hardreset sent
[394209.159680] pd := off
[394209.160553] IRQ: 0x41, a: 0x00, b: 0x00, status0: 0x81
[394209.160556] IRQ: BC_LVL, handler pending
[394209.160564] vconn is already Off
[394209.161001] pd header := Sink, Device
[394209.193529] BC_LVL handler, status0=0x81
[394209.811430] pd header := Sink, Device
[394209.813727] pd := on
[394210.125174] IRQ: 0x41, a: 0x08, b: 0x00, status0: 0x81
[394210.125178] IRQ: BC_LVL, handler pending
[394210.125180] IRQ: PD hardreset sent
[394210.127826] pd := off
[394210.127834] vconn is already Off
[394210.128705] IRQ: 0x41, a: 0x00, b: 0x00, status0: 0x81
[394210.128709] IRQ: BC_LVL, handler pending
[394210.129098] pd header := Sink, Device
[394210.160249] BC_LVL handler, status0=0x81
当Type-C
连接线从USB3.0 Type-C
接口移除:
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/fusb302-6-0022/log
[394417.434921] IRQ: 0x01, a: 0x00, b: 0x00, status0: 0x80
[394417.434926] IRQ: BC_LVL, handler pending
[394417.436373] IRQ: 0x80, a: 0x00, b: 0x00, status0: 0x00
[394417.436377] IRQ: VBUS_OK, vbus=Off
[394417.438761] pd := off
[394417.438763] vbus is already Off
[394417.438765] vconn is already Off
[394417.439232] pd header := Sink, Device
[394417.441507] start drp toggling
[394417.466218] BC_LVL interrupt is turned off, abort
5.2.6 查看tcpm-6-0022
root@NanoPC-T6:~# ls -l /sys/kernel/debug/usb/tcpm-6-0022
总用量 0
-r--r--r-- 1 root root 0 12月 18 23:56 log
root@NanoPC-T6:~# cat /sys/kernel/debug/usb/tcpm-6-0022/log
[394482.036794] CC1: 3 -> 0, CC2: 0 -> 2 [state TOGGLING, polarity 0, connected]
[394482.036799] state change TOGGLING -> SRC_ATTACH_WAIT [rev3 NONE_AMS]
[394482.036803] pending state change SRC_ATTACH_WAIT -> SNK_TRY @ 200 ms [rev3 NONE_AMS]
[394482.236822] state change SRC_ATTACH_WAIT -> SNK_TRY [delayed 200 ms]
[394482.236824] cc:=2
[394482.239467] pending state change SNK_TRY -> SNK_TRY_WAIT @ 100 ms [rev3 NONE_AMS]
[394482.339481] state change SNK_TRY -> SNK_TRY_WAIT [delayed 100 ms]
[394482.339483] state change SNK_TRY_WAIT -> SRC_TRYWAIT [rev3 NONE_AMS]
[394482.339486] cc:=4
[394482.342281] pending state change SRC_TRYWAIT -> SRC_TRYWAIT_UNATTACHED @ 100 ms [rev3 NONE_AMS]
[394482.442295] state change SRC_TRYWAIT -> SRC_TRYWAIT_UNATTACHED [delayed 100 ms]
[394482.442297] state change SRC_TRYWAIT_UNATTACHED -> SNK_UNATTACHED [rev3 NONE_AMS]
[394482.442300] Start toggling
[394482.444558] state change SNK_UNATTACHED -> TOGGLING [rev3 NONE_AMS]
[394482.501840] CC1: 0 -> 0, CC2: 2 -> 2 [state TOGGLING, polarity 0, connected]
[394482.501843] state change TOGGLING -> SRC_ATTACH_WAIT [rev3 NONE_AMS]
[394482.501846] pending state change SRC_ATTACH_WAIT -> SRC_ATTACHED @ 200 ms [rev3 NONE_AMS]
[394482.701864] state change SRC_ATTACH_WAIT -> SRC_ATTACHED [delayed 200 ms]
[394482.701866] polarity 1
[394482.701868] Requesting mux state 1, usb-role 1, orientation 2
[394482.704678] vbus:=1 charge=0
[394482.704693] pending state change SRC_ATTACHED -> SRC_UNATTACHED @ 480 ms [rev3 NONE_AMS]
[394482.705850] VBUS on
[394482.705852] state change SRC_ATTACHED -> SRC_STARTUP [rev3 NONE_AMS]
[394482.705888] AMS POWER_NEGOTIATION start
[394482.705890] cc:=4
[394482.708702] state change SRC_STARTUP -> AMS_START [rev3 POWER_NEGOTIATION]
[394482.708707] state change AMS_START -> SRC_SEND_CAPABILITIES [rev3 POWER_NEGOTIATION]
[394482.708710] PD TX, header: 0x11a1
[394482.717265] PD TX complete, status: 2
[394482.717274] pending state change SRC_SEND_CAPABILITIES -> SRC_SEND_CAPABILITIES @ 150 ms [rev3 POWER_NEGOTIATION]
......
5.3 切换USB3.0 OTG
工作模式
我们使用的开发板USB3.0 Type-C PHY0
、USB2.0 OTG PHY0
物理接口被设计为USB3.0 Type-C
,并且外置了Type-C
控制器芯片(FUSB302
)支持软件自动切换Deivice/Host mode
。
而USB3.0 Type-C PHY1
、USB2.0 OTG PHY1
物理接口被设计为USB3.0 Type-A
,并且TYPEC1_USB20_VBUSDET
引脚悬空处理,USB3.0 Type-A
接口只能作为HOST mode
使用。
RK3588
支持通过软件方法,强制设置USB OTG
控制器切换到Host mode
或者Device mode
,而不受USB
硬件电路的OTG ID
电平或者 Type-C
接口的影响。具体有如下两种方式:
- 方式1依赖于
USB dts
的正确配置,只能用于非Type-C
接口的硬件电路设计; - 方式2没有限制。因此,在不确定软硬件是否正确适配时,推荐优先使用方式2。
5.3.1 方式一
查看工作模式:
root@NanoPC-T6:~# cat /sys/devices/platform/fd5d0000.syscon/fd5d0000.syscon:usb2-phy@0/otg_mode
otg
root@NanoPC-T6:~# cat /sys/devices/platform/fd5d4000.syscon/fd5d4000.syscon:usb2-phy@4000/otg_mode
host
更改USB3.0 OTG0
为主机模式;
root@NanoPC-T6:~# echo host > /sys/devices/platform/fd5d0000.syscon/fd5d0000.syscon:usb2-phy@0/otg_mode
更改USB3.0 OTG0
为设备模式;
root@NanoPC-T6:~# echo peripheral > /sys/devices/platform/fd5d0000.syscon/fd5d0000.syscon:usb2-phy@0/otg_mode
注意:对于Type-C
接口硬件电路设置不会生效,Type-C
控制器(Fusb302
)会自动检测连接的USB
设备,软件自行将USB3.0 OTG0
控制器配置为Host
(主机)、Device
(从机)或双重角色。
5.3.2 方式二
更改USB3.0 OTG0
为主机模式:
# Force host mode
root@NanoPC-T6:~# echo host > /sys/kernel/debug/usb/fc000000.usb/mode
更改USB3.0 OTG0
为设备模式:
# Force device mode
root@NanoPC-T6:~# echo device > /sys/kernel/debug/usb/fc000000.usb/mode
当然,我们也可以尝试更改USB3.0 OTG1
为主机模式:
# Force host mode
root@NanoPC-T6:~# echo host > /sys/kernel/debug/usb/fc400000.usb/mode
更改USB3.0 OTG1
为设备模式:
root@NanoPC-T6:~# echo device > /sys/kernel/debug/usb/fc400000.usb/mode
该设置会强制将USB3.0 OTG0
控制器配置为指定的工作模式。比如USB3.0 Type-C
接口当前连接着鼠标设备并且工作为主机模式,如果将其设置为设备模式,鼠标将无法工作。
5.4 作为主机模式测试
无论是开发板上的USB3.0 Type-C
接口、还是USB3.0 Type-A
接口作为主机模式测试都是很简单,将USB3.0 OTG
工作模式切换为主机模式,然后在相应USB
接口插入鼠标设备,看看鼠标设备能不能正常工作就可以了;
root@NanoPC-T6:~# echo host > /sys/kernel/debug/usb/fc000000.usb/mode # USB3.0 Type-C接口
root@NanoPC-T6:~# echo host > /sys/kernel/debug/usb/fc400000.usb/mode # USB3.0 Type-A接口
很显然,测试结果鼠标无论插到哪个USB
接口都可以正常工作。
5.5 作为设备模式测试
在进行模拟之前,我们需要将/bin/usbdevice
文件移动到/opt/hid
目录下,这个是官方提供的用于模拟各种usb
设备的脚本,系统系统会自动执行,默认还是将开发板模拟成adb
终端(通过/etc/profile.d/usbdevice.sh
配置的)。
这里我们不使用官方提供的脚本,主要是这个脚本支持模拟的设备种类比较多,并且代码比较复杂,有兴趣可以自己研究。
root@NanoPC-T6:/# mkdir /opt/hid
root@NanoPC-T6:/# cd /opt/hid
root@NanoPC-T6:/opt/hid# mv /bin/usbdevice /opt/hid
接下来我们会通过USB3.0 Type-C
接口进行模拟触摸屏设备,如果想模拟鼠标,键盘可以参考文章:《四、 模拟USB
设备》。
5.5.1 hid_touch
脚本
下面我们创建一个触摸屏设备,然后编写hid_touch.sh
脚本,文件存放在开发板debian
系统/opt/hid
路径下;
#!/bin/bash
gadget=g2
do_start(){
has_mount=$(mount -l | grep /sys/kernel/config)
if [[ -z $has_mount ]];then
mount -t configfs none /sys/kernel/config
fi
cd /sys/kernel/config/usb_gadget
# 当我们创建完这个文件夹之后,系统自动的在这个文件夹中创建usb相关的内容 ,这些内容需要由创建者自己填写
if [[ ! -d ${gadget} ]]; then
mkdir ${gadget}
fi
cd ${gadget}
#设置USB协议版本USB2.0
echo 0x0200 > bcdUSB
#定义产品的VendorID和ProductID
echo "0x0525" > idVendor
echo "0xa4ac" > idProduct
#实例化"英语"ID:
mkdir strings/0x409
#将开发商、产品和序列号字符串写入内核
echo "76543210" > strings/0x409/serialnumber
echo "mkelehk" > strings/0x409/manufacturer
echo "touch_screen" > strings/0x409/product
#创建一个USB配置实例
if [[ ! -d configs/c.1 ]]; then
mkdir configs/c.1
fi
#定义配置描述符使用的字符串
if [[ ! -d configs/c.1/strings/0x409 ]]; then
mkdir configs/c.1/strings/0x409
fi
echo "hid" > configs/c.1/strings/0x409/configuration
#创建接口
mkdir functions/hid.0
#接口配置,模拟触摸屏
echo 0 > functions/hid.0/subclass
echo 0 > functions/hid.0/protocol
echo 5 > functions/hid.0/report_length #标识该hid设备每次发送的报表长度为5字节
echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x05\\x15\\x00\\x25\\x01\\x95\\x05\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x03\\x81\\x01\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x00\\x26\\xff\\x7f\\x35\\x00\\x46\\xff\\x7f\\x75\\x10\\x95\\x02\\x81\\x02\\xc0\\xc0 > functions/hid.0/report_desc
#捆绑接口到配置config.1
ln -s functions/hid.0 configs/c.1
#配置USB3.0 OTG0的工作模式为Device(设备):
echo device > /sys/kernel/debug/usb/fc000000.usb/mode
echo "sleep 3s"
sleep 3s
#将gadget驱动注册到UDC上,插上USB线到电脑上,电脑就会枚举USB设备。
echo fc000000.usb > UDC # 可以通过 ls /sys/class/udc/命令查看USB设备控制器
}
do_stop() {
cd /sys/kernel/config/usb_gadget/${gadaget}
echo "" > UDC
}
case $1 in
start)
echo "Start hid gadget "
do_start
;;
stop)
echo "Stop hid gadget"
do_stop
;;
*)
echo "Usage: $0 (stop | start)"
;;
esac
对于触摸屏设备,我们配置:
subclass
:接口子类,配置为0;protocol
:接口协议,配置为0;report_length
:报告长度配置为5,触摸屏与鼠标的不同点是鼠标的上报值是相对坐标,触摸屏是绝对坐标,鼠标x、y
轴分别需要一个字节,而触摸屏一般为16bit
即两个字节;
在开发板debian
系统运行命令模拟触摸屏:
root@NanoPC-T6:/opt/hid# echo device > /sys/kernel/debug/usb/fc000000.usb/mode
root@NanoPC-T6:/opt/hid# ls /sys/kernel/config/usb_gadget/
root@NanoPC-T6:/opt/hid# bash hid_touch.sh start
Start hid gadget
sleep 3s
root@NanoPC-T6:/opt/hid# ls /sys/kernel/config/usb_gadget/
g2
root@NanoPC-T6:/opt/hid# ls /sys/kernel/config/usb_gadget/g2
UDC bDeviceProtocol bMaxPacketSize0 bcdUSB functions idVendor strings
bDeviceClass bDeviceSubClass bcdDevice configs idProduct os_desc
此时会在/dev
目录下生成了设备节点/dev/hidg0
;
root@NanoPC-T6:/opt/hid# ls -l /dev/hidg*
crw------- 1 root root 511, 0 12月 23 13:54 /dev/hidg0
如果需卸载触摸屏,执行如下命令:
root@NanoPC-T6:/opt/hid# bash hid_touch.sh stop
如果卸载不能生效,尝试重启系统。
5.5.2 编写应用程序
然后我们通过设备节点/dev/hidg0
、就可以模拟触摸屏实现与PC
的通信。
编写测试应用程序hid_touch_control.c
,文件存放在debian
开发板/opt/hid
路径下;
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
/**
* 触摸屏每次发送5字节报告
* report[0]的D0就是左键,D1就是右键,D2就是中键
* report[1]为X轴低字节
* report[2]为X轴高字节
* report[3]为Y轴低字节
* report[4]为Y轴高字节,
*/
/**
* @brief 将焦点移动到指定位置
*
* @param fd 文件描述符
* @param x x轴坐标
* @param y y轴坐标
*/
void move_To(int fd ,int x, int y)
{
char report[5]={0,0,0,0,0};
report[0] = 0x00;
report[1] = x & 0xFF;
report[2] = (x >> 8) & 0xFF;
report[3] = y & 0xFF;
report[4] = (y >> 8) & 0xFF;
// 写入失败
if (write(fd, report, 5) != 5) {
perror("move_To error");
return;
}
usleep(50000);
}
/**
* @brief 函数功能:画线段的函数。
*
*@param fd 文件描述符
* @param x x轴坐标
* @param y y轴坐标
*/
void line_to(int fd, int x, int y)
{
char report[5]={0,0,0,0,0};
report[0] = 0x01; //左键按下
report[1] = x & 0xFF;
report[2] = (x >> 8) & 0xFF;
report[3] = y & 0xFF;
report[4] = (y >> 8) & 0xFF;
if (write(fd, report, 5) != 5) {
perror("line_to error");
return;
}
usleep(50000);
}
int main(int argc, char const *argv[])
{
const char *filename = NULL;
int fd = 0;
if (argc != 3)
{
fprintf(stderr, "Usage: %s devname a/l\n",
argv[0]);
return 1;
}
filename = argv[1];
if ((fd = open(filename, O_RDWR, 0666)) == -1) {
perror(filename);
return 1;
}
if(argv[2][0] == 'a')
{
printf("Draw Tri-angle begin\n");
move_To(fd, 8888, 8888); //移动到(8888,8888)
line_to(fd, 8888, 8888); //开始画线
line_to(fd, 12000, 12000); //画线到(12000,12000)
move_To(fd, 12000, 12000); //松开鼠标左键
move_To(fd, 12000, 12000); //移动到(12000,12000)
line_to(fd, 12000, 12000); //开始画线
line_to(fd ,8888, 12000); //画线到(8888,12000)
move_To(fd, 8888, 12000); //松开鼠标左键
move_To(fd, 8888, 12000); //移动到(8888,12000)
line_to(fd, 8888, 12000); //开始画线
line_to(fd ,8888, 8888); //画线到(8888,8888)
move_To(fd, 8888, 8888); //松开鼠标左键
printf("Draw Tri-angle end\n");
}
if(argv[2][0] == 'l'){
printf("Draw line begin\n");
move_To(fd, 10000, 10000); // 移动到(10000,10000)
line_to(fd, 10000, 10000); // 开始画线
line_to(fd, 20000, 10000); // 画线到(20000,10000)
move_To(fd, 20000, 10000); // 松开鼠标左键
printf("Draw line end\n");
}
close(fd);
return 0;
}
直接在开发板编译应用程序:
root@NanoPC-T6:/opt/hid# gcc -o hid_touch_control hid_touch_control.c
root@NanoPC-T6:/opt/hid# ls -l
-rwxr-xr-x 1 root root 13872 12月 23 13:55 hid_touch_control
-rw-r--r-- 1 root root 2911 12月 23 13:55 hid_touch_control.c
-rwxr-xr-x 1 root root 2668 12月 23 13:47 hid_touch.sh
-rwxrwxr-x 1 pi pi 13170 5月 19 2023 usbdevice
5.5.3 测试触摸屏
(1) 这里我们和鼠标测试一样,使用Type-C
连接线将开发板USB3.0 Type-C
接口与开发板上的USB3.0 Type-A
接口连接起来;内核日志信息如下:
[ 1255.881053] dwc3 fc000000.usb: device reset
[ 1256.004255] usb 1-1: new high-speed USB device number 12 using xhci-hcd
[ 1256.004407] android_work: sent uevent USB_STATE=CONNECTED
[ 1256.007939] dwc3 fc000000.usb: device reset
[ 1256.145009] usb 1-1: New USB device found, idVendor=0525, idProduct=a4ac, bcdDevice= 6.01
[ 1256.145026] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 1256.145035] usb 1-1: Product: touch_screen
[ 1256.145042] usb 1-1: Manufacturer: mkelehk
[ 1256.145048] usb 1-1: SerialNumber: 76543210
[ 1256.150185] android_work: sent uevent USB_STATE=CONFIGURED
[ 1256.151169] input: mkelehk touch_screen as /devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.9.auto/usb1/1-1/1-1:1.0/0003:0525:A4AC.0017/input/input28
[ 1256.207775] hid-generic 0003:0525:A4AC.0017: input,hidraw0: USB HID v1.01 Mouse [mkelehk touch_screen] on usb-xhci-hcd.9.auto-1/input0
USB
触摸屏工作在高速模式下,xHCI
控制器,USB2.0
通信协议,使用的USB
总线编号为1,设备编号为1。
其中Product
=touch_screen
,Manufacturer=mkelehk
,SerialNumber=76543210
、idVendor=0525
、idProduct=a4ac
,这个就是我们在hid_touch.sh
脚本下配置的。
(2) 在开发板ubuntu
桌面安装画图软件,并运行程序;
root@rk3588:/shell/hid# sudo aptitude install -y kolourpaint
root@rk3588:/shell/hid# kolourpaint
我们将画布调到最大,并且选择左侧的直线;
(3) 打开一个开发板终端(非桌面终端)输入如下命令:
root@rk3588:/shell/hid# ./hid_touch_control /dev/hidg0 a
Draw Tri-angle begin
Draw Tri-angle end
root@rk3588:/shell/hid# ./hid_touch_control /dev/hidg0 l
Draw line begin
Draw line end
最终得到如下图:
参考文章
[1] Rockchip_Developer_Guide_USB_CN.pdf
[2] Rockchip RK3588 USB
开发指南
[3] [Rockchip_Developer_Guide_Linux_USB_PHY_CN
]
[5] Rockchip RK3399
- 移植uboot 2017.09 & linux 4.19
(友善之家脚本方式)