程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)

Rockchip RK3588 - USB基础 & 调试

目录

开发板 :NanoPC-T6开发板
eMMC256GB
LPDDR416GB
显示屏 :15.6英寸HDMI接口显示屏
u-boot2017.09
linux6.1
----------------------------------------------------------------------------------------------------------------------------

有关USB的发展历史,以及接口规范这一节我们就不再重复介绍了,没有相关基础的话可以参考我之前写过的文章:

一、RK3588 USB介绍

1.1 USB控制器

RK3588 支持4个独立的USB控制器,不同控制器相互独立:

  • 两个USB2.0 HOSTEHCI&OHCI);
  • 两个USB3.0 OTGDWC3/xHCI);
  • 一个USB3.0 HOSTxHCI);只支持USB3.0功能,不向下兼容USB2.0;

其中:

  • EHCI/OHCI: 表示该USB控制器集成了EHCI控制器和OHCI控制器;
  • DWC3/xHCI:表示该USB控制器集成了DWC3控制器和 xHCI控制器;
  • USB3.0 物理层传输速率为5GbpsUSB2.0物理层传输速率为480Mbps;
1.1.1 USB2.0 HOSTEHCI/OHCI

支持高速 (480Mbps),全速 (12Mbps) 和低速 (1.5Mbps),USB2.0 Host控制器的框图如下图所示;

img

内部有EHCIOHCI Host Controller

  • OHCI支持USB1.0USB1.1;
  • EHCI支持USB2.0

Port Routing Control: 用于选择用EHCI还是OHCI

USB2.0 Host控制器连接到USB2.0 PHY

EHCIOHCI Rockchip采用linux内核Generic驱动,一般开发时只需要对设备树作相应配置,即可正常工作。

为了同时支持USB1.0USB1.1USB2.0,就需要同时用到EHCIOHCI,因此需要在设备树中把这两个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控制器就使能了,并且同时支持EHCIOHCI

1.1.2 USB3.0 OTGDWC3/xHCI

RK3588 USB3.0 OTG使用Synopsys方案,即xHCI扩展的DWC3控制器,Host功能在xHCI框架下实现,而Device功能由DWC3扩展部分实现。

DWC3具有以下特性:

  • 支持Control/Bulk(including stream)/Interrupt/Isochronous传输方式;
  • USB3.0支持同时执行INOUT传输,带宽达到8Gbps
  • 支持描述符缓存 (Descriptor Caching) 和数据预取 (Data Pre-fetching);
  • Device模式支持的IN端点数量和OUT端点数量请参考芯片手册;
  • 支持硬件自动处理ERDYburst
  • 支持端点批量流传输 (bulk stream);
  • 支持USB3.0 DRD (Dual-Role Device) 特性;
  • 支持根据OTG ID状态切换DeviceHost模式;
  • 对于支持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控制器的框图如下图所示;

img

USB3.0 OTG具有USB3.0 OTGUSB PeripheralUSB Host)功能,且向下兼容USB2.0 OTG功能,大传输速率为5Gbps

由于USB3.0 HOST控制器为xHCI,集成于DWC3 OTG IP中,所以不用单独为其配置设备树,只需要配置DWC3,并且设置DWC3dr_mode属性为dr_mode = otg或者dr_mode = host,即可以使能xHCI控制器。

1.1.3 USB3.0 HOSTxHCI

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:在设备树中分别叫做u2phy0u2phy1u2phy2u2phy3;
  • 2个 USB3.0/DP Combo PHY:在设备树中分别叫做usbdp_phy0usbdp_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.0SATA/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 PHYRK3588使用的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的框图;

img

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 IPInno 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 HOST2USB2.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-CUSB2.0/3.0 Type-AMicro 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,开发板如下图所示;

NanoPC-T6 Layout-L.jpg

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-T6USB3.0/DP Combo PHY0USB2 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_S0VCCA_1V8_S0VDDA_0V75_S0VCCA_3V3_S0,这些电源均是由电源芯片RK806输出。

(1) 电源VDDA_0V85_S0RK806第10号引脚提供的;

(2) 电源VCCA_1V8_S0RK806第60号引脚提供的;

(3) 电源VDDA_0V75_S0RK806第11号引脚提供的;

(4) 电源VCCA_3V3_S0RK806第63号引脚提供的。

2.1.2 Type-C接口接线

其中TYPEC0_SSTX1PTYPEC0_SSTX1NTYPEC0_SSRX1PTYPEC0_SSRX1NTYPEC0_SSTX2PTYPEC0_SSTX2NTYPEC0_SSRX2PTYPEC0_SSRX2NTYPEC0_SBU1TYPEC0_SBU2TYPEC0_USB20_OTG_DMTYPEC0_USB20_OTG_DP连接到开发板上的TYPE-CTYPE-CUSB3.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_TYPECSY6280AAC提供的,其输入端为VCC5V0_SYS。由TYPEC5V_PWREN_H(GPIO1_D2)引脚使能;

2.1.3 fusb302

fusb302是可编程的USB Type-C控制器,支持识别各种USB设备和对应的工作状态,且支持最高100WPD协议。

其具有一下主要特征:

  • 具备自主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连接的是RK3588GPIO0_D3引脚,I2C通信使用的是I2C6

由于这篇文章不是fusb302的专栏,所以就不细说了,具体参考《PD快充 - fusb302驱动调试笔记》

2.2 USB3.0 Type-A

我们使用的开发板NanpiPC-T6USB3.0/DP Combo PHY1USB2 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_SSTX1PTYPEC1_SSTX1NTYPEC1_SSRX1PTYPEC1_SSRX1NTYPEC1_USB20_OTG_DMTYPEC1_USB20_OTG_DP连接到USB3USB3USB3.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_HOST2SY6280AAC提供的,其输入端为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_FRIENDLYELECCONFIG_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 OTG0DWC3/xHCI)、USB2.0 HOST0/1EHCI&OHCI)、USB3.0 HOST2xHCI)的dtsi配置放在arch/arm64/boot/dts/rockchip/rk3588s.dtsi

USB3.0 OTG1DWC3/xHCI)的dtsi配置放在arch/arm64/boot/dts/rockchip/rk3588.dtsi,这个文件包含了rk3588s.dtsi

因为USB DTSI节点配置的是USB控制器和PHY的公共资源和属性,建议开发者不要改动。

#include "rk3588s.dtsi"
3.2.1 USB2.0 HOST0EHCI&OHCI

USB2.0 HOST0控制器设备节点usb_host0_ehciusb_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 HOST1EHCI&OHCI

USB2.0 HOST1控制器设备节点usb_host1_ehciusb_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 OTG0DWC3/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 OTG1DWC3/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 HOST2xHCI

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 HOST0EHCI&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 HOST1EHCI&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 PHYUSB控制器具有一一对应的关系,需要成对配置。在芯片内部,USB PHY和控制器的连接关系,请参考1,3小节。在dtsi节点中,通过USB控制器节点的phys属性关联对应的USB PHY

USB2.0 PHY0/2/3USB3.0/DP Combo PHY0USB3.0/SATA/PCIe Combo PHYdtsi配置放在arch/arm64/boot/dts/rockchip/rk3588s.dtsi

USB2.0 PHY1USB3.0/DP Combo PHY1dtsi配置放在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_dpusbdp_phy0_u3,定义在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_dpusbdp_phy1_u3,定义在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 PHY1USB2.0 PHY03USB3.0/DP Combo PHY1arch/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 PHYUSB3.0/DP Combo PHY0USB2 PHY0

因此对应的设备树配置,包括USB3.0 OTG0(DWC3/xHCI)控制器设备树配置和USB3.0/DP Combo PHY0USB2 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_TYPECSY6280AAC提供的,其输入端为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 PHYUSB3.0/DP Combo PHY1USB2 PHY1

因此对应的设备树配置,包括USB3.0 OTG1(DWC3/xHCI)控制器设备树配置和USB3.0/DP Combo PHY1USB2 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_HOST2SY6280AAC提供的,其输入端为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是双角色(即同时支持HostDevice模式,可以动态切换):

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 PHY0USB2.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 LayerUSB协议栈中的一个组件,用于支持 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 LayerLinux内核的一个通用输入设备管理层,它与各种输入设备进行交互,并将输入数据传递给应用程序;

  • 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设备还有很多,如GPSPrinter等,有可能需要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 烧录内核

亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。

日期姓名金额
2023-09-06*源19
2023-09-11*朝科88
2023-09-21*号5
2023-09-16*真60
2023-10-26*通9.9
2023-11-04*慎0.66
2023-11-24*恩0.01
2023-12-30I*B1
2024-01-28*兴20
2024-02-01QYing20
2024-02-11*督6
2024-02-18一*x1
2024-02-20c*l18.88
2024-01-01*I5
2024-04-08*程150
2024-04-18*超20
2024-04-26.*V30
2024-05-08D*W5
2024-05-29*辉20
2024-05-30*雄10
2024-06-08*:10
2024-06-23小狮子666
2024-06-28*s6.66
2024-06-29*炼1
2024-06-30*!1
2024-07-08*方20
2024-07-18A*16.66
2024-07-31*北12
2024-08-13*基1
2024-08-23n*s2
2024-09-02*源50
2024-09-04*J2
2024-09-06*强8.8
2024-09-09*波1
2024-09-10*口1
2024-09-10*波1
2024-09-12*波10
2024-09-18*明1.68
2024-09-26B*h10
2024-09-3010
2024-10-02M*i1
2024-10-14*朋10
2024-10-22*海10
2024-10-23*南10
2024-10-26*节6.66
2024-10-27*o5
2024-10-28W*F6.66
2024-10-29R*n6.66
2024-11-02*球6
2024-11-021*鑫6.66
2024-11-25*沙5
2024-11-29C*n2.88
posted @   大奥特曼打小怪兽  阅读(8142)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
如果有任何技术小问题,欢迎大家交流沟通,共同进步

公告 & 打赏

>>

欢迎打赏支持我 ^_^

最新公告

程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)。

了解更多

点击右上角即可分享
微信分享提示