您的位置 首页 观点

2440/2410大将usb device改成usb host

之前的开发,要在2440上使用两个usbhost口,一个接摄像头,一个接无线网卡。但友善之臂mini2440板子只有一个usbhost口,曾想通过外接一…

之前的开发,要在2440上运用两个usb host口,一个接摄像头,一个接无线网卡。但友善之臂mini2440板子只要一个usb host口,曾想经过外接一个usb hub来处理,无线网卡接hub没有问题,可是摄像头插到hub上总是有过错:

usb 1-1: reset full speed USB device using s3c2410-ohci and address 3
usb 1-1.2: new full speed USB device using s3c2410-ohci and address 4
usb 1-1.2: device descriptor read/64, error -62
usb 1-1.2: device descriptor read/64, error -62
usb 1-1.2: new full speed USB device using s3c2410-ohci and address 5
usb 1-1.2: device descriptor read/64, error -62
usb 1-1.2: device descriptor read/64, error -62
usb 1-1.2: new full speed USB device using s3c2410-ohci and address 6
usb 1-1.2: device not accepting address 6, error -62
usb 1-1.2: new full speed USB device using s3c2410-ohci and address 7
usb 1-1.2: device not accepting address 7, error -62
hub 1-1:1.0: unable to enumerate USB device on port 2

本来想试着修正内核中关于hub.c和ohci-s3c2410中的代码,看看能不能好使,但后来在PC机上的hub下运用摄像头也不好使,看来是我运用的zc301摄像头对hub不支撑吧。(估量一般的摄像头都对hub不支撑,我又试了另一款也是这样的)。

所以抛弃了在usb hub上运用摄像头的主意。记住曾经看过关于s3c2410的手册,它应该是支撑2个usb host通道的啊,2440应该也是如此。所以细心看了下s3c2440的手册,发现第二个usb hos通道的管脚和usb device的管脚是复用的。所以感觉将usb device改成host应该是可行的,深入研讨研讨。(如同一些板子现已规划出来能够跳线挑选,友善之臂的没这么规划)

要将usb device改成host,不只是硬件上需求改动,软件驱动上必定也需求改动,所以分为硬件和软件两个部分。

硬件上:细心看了mini2440的手册中的关于usb电路图,其实硬件电路上host和device没什么实质区别,一些外拉电阻不相同,VBUS的提供者不相同。将device改成host感觉外拉电阻不相同应该也不会影响运用,所以就没有改动,防止在板子上做手脚。其它的便是要给VBUS一个5v的电源,而不是像device相同电脑供电了。其它的就没什么改动了。自己着手做了一个usb host口。

软件上:实质便是对寄存器MISCCR的设置改动一下,为了今后改动便利,我参阅了网上的一些《关于阳初2440 超值版只能运用一个 USB Host 问题的处理》的办法。以下首要参照了一些关于这个办法的帖子博客之类的。(转载一些)

第一篇:

修正linux-2.6.20.3/drivers/usb/host/Kconfig,增加:

config MAX_ROOT_PORTS

int “Maximum port(s) of RootHub”

depends on USB_OHCI_HCD && ARCH_S3C2410

default 1

—help—

pls select usb host number,default one host and one device.so We select one normally

修正/linux-2.6.20.3/drivers/usb/host/ohci-s3c2410.c

static int usb_hcd_s3c2410_probe (const struct hc_driver *driver,

struct platform_device *dev)

{

struct usb_hcd *hcd = NULL;

int retval;

//add by hiboy

unsigned long tmp;

#if CONFIG_MAX_ROOT_PORTS < 2

/* 1 host port, 1 slave port*/

tmp = __raw_readl(S3C2410_MISCCR);

tmp &= ~S3C2410_MISCCR_USBHOST;

__raw_writel(tmp, S3C2410_MISCCR);

s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);

#else

/* 2 host port */

tmp = __raw_readl(S3C2410_MISCCR);

tmp |= S3C2410_MISCCR_USBHOST;

__raw_writel(tmp, S3C2410_MISCCR);

s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);

s3c2410_usb_set_power(dev->dev.platform_data, 2, 1);

#endif

//s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);

//s3c2410_usb_set_power(dev->dev.platform_data, 2, 1);

……

修正/linux-2.6.20.3/drivers/usb/core/hub.c

static int hub_configure(struct usb_hub *hub,

struct usb_endpoint_descriptor *endpoint)

{

struct usb_device *hdev = hub->hdev;

struct device *hub_dev = hub->intfdev;

u16 hubstatus, hubchange;

u16 wHubCharacteristics;

unsigned int pipe;

int maxp, ret;

char *message;

hub->buffer = usb_buffer_alloc(hdev, sizeof(*hub->buffer), GFP_KERNEL,

&hub->buffer_dma);

if (!hub->buffer) {

message = “cant allocate hub irq buffer”;

ret = -ENOMEM;

goto fail;

}

hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL);

if (!hub->status) {

message = “cant kmalloc hub status buffer”;

ret = -ENOMEM;

goto fail;

}

mutex_init(&hub->status_mutex);

hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);

if (!hub->descriptor) {

message = “cant kmalloc hub descriptor”;

ret = -ENOMEM;

goto fail;

}

/* Request the entire hub descriptor.

* hub->descriptor can handle USB_MAXCHILDREN ports,

* but the hub can/will return fewer bytes here.

*/

ret = get_hub_descriptor(hdev, hub->descriptor,

sizeof(*hub->descriptor));

if (ret < 0) {

message = “cant read hub descriptor”;

goto fail;

} else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {

message = “hub has too many ports!”;

ret = -ENODEV;

goto fail;

}

/********************************************/

/*add by hiboy */

#ifdef CONFIG_ARCH_S3C2410

if ((hdev->devnum == 1) // Root Hub

&& hub->descriptor->bNbrPorts > CONFIG_MAX_ROOT_PORTS) {

int j;

for (j=hub->descriptor->bNbrPorts-1; j>=0; j–) {

printk(“port #%d “, j);

if (j > CONFIG_MAX_ROOT_PORTS-1) {

printk(“suspened!\n”);

} else {

printk(“alived!\n”);

}

}

hub->descriptor->bNbrPorts = CONFIG_MAX_ROOT_PORTS;

}

#endif

/*********************************************/

第二篇:

是由于MISCCR寄存器没有正确设置的原因,我在mach-2410.c中增加了设置MISCCR寄存器的内容,HOST0就能够正常运用了

/*add by seigpao*/

int usb_seigpao_init(void)

{

unsigned long upllvalue;

unsigned long misccr;

//设置UPLLCON

upllvalue = (0x78<<12)|(0x02<<4)|(0x03);

__raw_writel(upllvalue,S3C2410_UPLLCON);

//设置MISCCR

misccr = __raw_readl(S3C2410_MISCCR);

misccr |= S3C2410_MISCCR_USBHOST;

misccr &= ~(S3C2410_MISCCR_USBSUSPND0 | S3C2410_MISCCR_USBSUSPND1);

__raw_writel(misccr,S3C2410_MISCCR);

return 1;

}

/* end by seigpao */

static void __init smdk2410_map_io(void)

{

s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));

s3c24xx_init_clocks(0);

s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));

s3c24xx_set_board(&smdk2410_board);

/*add by seigpao*/

//设置2410触摸屏

set_s3c2410ts_info(&sbc2410_ts_cfg);

//设置USB相关寄存器

usb_seigpao_init();

/* end by seigpao */

}

不知道为什么会有第二篇,感觉不适合,所以又重网上找了另一篇文章。

修正ohci-s3c2440.c文件(含头文件):

#include

#include

#include

/*add here*/

#include

#include

#include

#include

/*end here*/

#define valid_port(idx) ((idx) == 1 || (idx) == 2)

/*add here*/

static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd)

{

unsigned long upllvalue = (0x78<<12)|(0x02<<4)|(0x03); //add upllvalue

unsigned long misccr; //add misccr

struct s3c2410_hcd_info *info = dev->dev.platform_data;

while (upllvalue != __raw_readl(S3C2410_UPLLCON)) //setup UPLLCON

{

__raw_writel(upllvalue, S3C2410_UPLLCON);

mdelay(1);

}

misccr = __raw_readl(S3C2410_MISCCR); //MISCCR

misccr |= S3C2410_MISCCR_USBHOST;

misccr&=~(S3C2410_MISCCR_USBSUSPND0|S3C2410_MISCCR_USBSUSPND1);

__raw_writel(misccr,S3C2410_MISCCR);

dev_dbg(&dev->dev, “s3c2410_start_hc:\n”);

clk_enable(clk);

if (info != NULL) {

info->hcd = hcd;

info->report_oc = s3c2410_hcd_oc;

if (info->enable_oc != NULL) {

(info->enable_oc)(info, 1);

}

}

}

运用了这篇文章的改动。头文件方位或许依据内核不同做相应改动。我的2.6.29内核中的regs-clock.h和regs-gpio.h是在arch\arm\mach-s3c2410\include\mach中。我复制两个头文件到本地drivers/usb/host/,include 变成””。

然后make zImage,之后Kconfig会从头挑选,

USB support (USB_SUPPORT) [Y/n/?] y

Support for Host-side USB (USB) [Y/n/m/?] y

USB verbose debug messages (USB_DEBUG) [N/y/?] n

USB announce new devices (USB_ANNOUNCE_NEW_DEVICES) [Y/n/?] y

*

* Miscellaneous USB options

*

USB device filesystem (USB_DEVICEFS) [Y/n/?] y

USB device class-devices (DEPRECATED) (USB_DEVICE_CLASS) [N/y/?] n

Dynamic USB minor allocation (USB_DYNAMIC_MINORS) [N/y/?] n

USB Monitor (USB_MON) [N/m/y/?] n

Enable Wireless USB extensions (EXPERIMENTAL) (USB_WUSB) [N/m/y/?] n

Support WUSB Cable Based Association (CBA) (USB_WUSB_CBAF) [N/m/y/?] n

*

* USB Host Controller Drivers

*

Cypress C67x00 HCD support (USB_C67X00_HCD) [N/m/y/?] n

OXU210HP HCD support (USB_OXU210HP_HCD) [N/m/y/?] n

ISP116X HCD support (USB_ISP116X_HCD) [N/m/y/?] n

OHCI HCD support (USB_OHCI_HCD) [Y/n/m/?] y

SL811HS HCD support (USB_SL811_HCD) [N/m/y/?] n

R8A66597 HCD support (USB_R8A66597_HCD) [N/m/y/?] n

Host Wire Adapter (HWA) driver (EXPERIMENTAL) (USB_HWA_HCD) [N/m/y/?] n

Maximum port(s) of RootHub (MAX_ROOT_PORTS) [2] (NEW)

最终一项选的时分选成2就行了,由于config MAX_ROOT_PORTS为2代表运用两个host。

烧写生成的内核,成果大失人望,发动后在自己焊出的usb host口上插上设备没反应。不过抑郁重启之时,发现先在这之上插上设备发动时,设备就能辨认出来了。并且刺进无线网卡能够装备运用。不过运用摄像头确呈现过错:

gspca: ISOC data error: [1] len=318, status=-84

gspca: ISOC data error: [4] len=274, status=-84

gspca: ISOC data error: [25] len=144, status=-84

gspca: ISOC data error: [1] len=240, status=-84

等等。这是又回到对内核的改动上,当改动内核时就感觉帖子文章中第二篇没什么用,跟第一篇有些重复之嫌,后来代替的在static void s3c2410_start_hc中的改动也是,感觉有些重复static int usb_hcd_s3c2410_probe中的内容,所以从头编译内核,将对static void s3c2410_start_hc的改动去掉,即不改s3c2410_start_hc,从头编译内核烧写,成果运用摄像头正常。

也便是说,usb device现已改成了usb host,能够当成usb host运用了,只不过,必需先刺进设备再发动板子,剖析这种状况的原因或许是由于bootloader中必定有对usb部分的设置驱动之类的,(Nor Flash的时分能够运用usb device进行下载传输,阐明必定现已驱上了usb device),vivi的设置跟从头编译的内核对usb设置不相同,或许就导致了这种状况,我也不确定是不是这个原因。不插设备的时分发动信息改的usb 1-2提示:

usb 1-2: new full speed USB device using s3c2410-ohci and address 3

usb 1-2: device descriptor read/64, error -62

usb 1-2: device descriptor read/64, error -62

usb 1-2: new full speed USB device using s3c2410-ohci and address 4

usb 1-2: device descriptor read/64, error -62

usb 1-2: device descriptor read/64, error -62

usb 1-2: new full speed US. device using s3c2410-ohci and address 5

usb 1-2: device not accepting addre髎 5, error -62

usb 1-2: new full speed USB device using s3c2410-ohci and address 6

usb 1-2: device not accepting address 6, error -62

hub 1-0:1.0: unable to enumerate USB device on port 2

可是,插上设备比方无线网卡,就能找到设备,提示:

usb 1-2: new full speed USB device using s3c2410-o鑓i and address 3

usb 1-2: New USB device found, idVen鋙r=0ace, idProduct=1215

usb 1-2: New USB device strings: Mfr=16, Product=32, SerialNumber=0

usb 1-2: Product: USB2.0 WLAN

usb 1-2: Manufacturer: ZyDAS

usb 1-2: configuration #1 chosen from 1 choice

usb 1-2: reset full speed USB device using s3c2410-ohci and address 3

wmaster0 (zd1211rw): not using net_device_ops yet

wlan0 (zd1211rw): not using net_device_ops yet

zd1211rw 1-2:1.0: phy0

关于这种状况,上网搜了一下,如同修正vivi中的upll设置,在main中增加了ChangeUPllValue(56,2,2)一句后,问题能够处理。详细没有再试,先如此的用着吧。
我是在友善之臂的mini2440上完成的,根据2410与2440没有实质不同,2410上应该也能够。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/guandian/276500.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部