- Android系统移植和驱动开发
- 华清远见移动互联网学院 郑萌等编著
- 498字
- 2020-08-28 23:31:35
1.5.5 USB驱动修改
初始化结束后,插上USB就报如下错误:
/ # usb 1-1: new full speed USB device using s3c2410-ohci and address 2 usb 1-1: device descriptor read/64, error -62 usb 1-1: device descriptor read/64, error -62 usb 1-1: new full speed USB device using s3c2410-ohci and address 3 usb 1-1: device descriptor read/64, error -62 usb 1-1: new full speed USB device using s3c2410-ohci and address 4 usb 1-1: device not accepting address 4, error -62 usb 1-1: new full speed USB device using s3c2410-ohci and address 5 usb 1-1: device not accepting address 5, error -62 hub 1-0:1.0: unable to enumerate USB device on port 1
解决方法:
问题就在ohci-s3c2410.c中,时钟设置出了问题,原来是USB Host的48MHz时钟没有起来。
s3c2410支持3个PLL,分别是APLL、MPLL和EPLL。APLL为ARM提供时钟,产生ARMCLK;MPLL为所有和AXI/AHB/APB相连的模块提供时钟,产生HCLK和PCLK;EPLL为特殊的外设提供时钟,产生SCLK。
如图1.7所示为EPLL_CON的M、P和S的取值。
图1.7 EPLL_CON的M、P和S的取值
图1.8描述的是用于IrDA和USB Host的时钟发生器,通常USB接口需要48MHz的操作时钟。
图1.8 USB原理图
从图1.8中可以看出,HCLK_GATE、PCLK_GATE和SCL_GATE控制时钟操作。如果设置一个位,则通过每个时钟分频器相应的时钟将会被提供,否则,将被屏蔽。
HCLK_GATE 控制HCLK,用于每个Ips。每个IP的AHB接口逻辑被独立地屏蔽,以减少动态电力消耗。PCLK_GATE控制PCLK,通过SCLK_GATE时钟被控制。
根据图1.8中的EPLL通道写出以下程序:
#define EPLL_CON00 ((1<<31)|(0x20<<16)|(1<<8)|(3<<0)) #define EPLL_CON01 0 #define UPLL_SRC_MASK ((1<<2)|(3<<5)) #define UPLL_SRC ((1<<2)|(1<<5)) #define UPLL_DIV1_MASK (0xf<<20) #define UPLL_DIV1 (0<<20) #define UPLL_GATE_MASK (1<<30) #define UPLL_GATE (1<<30) void set_upll(void) { unsigned int tmp; while(__raw_readl(S3C_EPLL_CON0)!=EPLL_CON00) __raw_writel(EPLL_CON00,S3C_EPLL_CON0); while(__raw_readl(S3C_EPLL_CON1)!=EPLL_CON01) __raw_writel(EPLL_CON01,S3C_EPLL_CON1); while(((tmp= __raw_readl(S3C_CLK_SRC))&UPLL_SRC_MASK)!=UPLL_SRC) __raw_writel((tmp&UPLL_SRC_MASK)|UPLL_SRC,S3C_CLK_SRC); while(((tmp=__raw_readl(S3C_CLK_DIV1))&UPLL_DIV1_MASK)!=UPLL_DIV1) __raw_writel((tmp&UPLL_DIV1_MASK)|UPLL_DIV1,S3C_CLK_DIV1); while(((tmp=__raw_readl(S3C_SCLK_GATE))&UPLL_GATE_MASK)!=UPLL_GATE) __raw_writel((tmp&UPLL_GATE_MASK)|UPLL_GATE,S3C_SCLK_GATE); }
在probe中加入上面的函数,修改USB Host的时钟:
set_upll();
然后编译内核。
USB不能识别的错误就解决了。