@ -13,6 +13,7 @@
# include "musb_core.h"
# include "musb_host.h"
# include "musb_gadget.h"
# include "musb_uboot.h"
# ifdef CONFIG_MUSB_HOST
struct int_queue {
@ -20,9 +21,7 @@ struct int_queue {
struct urb urb ;
} ;
static struct musb * host ;
static struct usb_hcd hcd ;
static enum usb_device_speed host_speed ;
struct musb_host_data musb_host ;
static void musb_host_complete_urb ( struct urb * urb )
{
@ -30,9 +29,6 @@ static void musb_host_complete_urb(struct urb *urb)
urb - > dev - > act_len = urb - > actual_length ;
}
static struct usb_host_endpoint hep ;
static struct urb urb ;
static void construct_urb ( struct urb * urb , struct usb_host_endpoint * hep ,
struct usb_device * dev , int endpoint_type ,
unsigned long pipe , void * buffer , int len ,
@ -90,38 +86,40 @@ static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
return urb - > status ;
}
static int _musb_submit_control_msg ( struct usb_device * dev , unsigned long pipe ,
static int _musb_submit_control_msg ( struct musb_host_data * host ,
struct usb_device * dev , unsigned long pipe ,
void * buffer , int len , struct devrequest * setup )
{
construct_urb ( & urb , & hep , dev , USB_ENDPOINT_XFER_CONTROL , pipe ,
buffer , len , setup , 0 ) ;
construct_urb ( & host - > urb , & host - > h ep , dev , USB_ENDPOINT_XFER_CONTROL ,
pipe , buffer , len , setup , 0 ) ;
/* Fix speed for non hub-attached devices */
if ( ! usb_dev_get_parent ( dev ) )
dev - > speed = host_speed ;
dev - > speed = host - > host _speed;
return submit_urb ( & hcd , & urb ) ;
return submit_urb ( & host - > h cd , & host - > urb ) ;
}
static int _musb_submit_bulk_msg ( struct usb_device * dev , unsigned long pipe ,
void * buffer , int len )
static int _musb_submit_bulk_msg ( struct musb_host_data * host ,
struct usb_device * dev , unsigned long pipe , void * buffer , int len )
{
construct_urb ( & urb , & hep , dev , USB_ENDPOINT_XFER_BULK , pipe ,
buffer , len , NULL , 0 ) ;
return submit_urb ( & hcd , & urb ) ;
construct_urb ( & host - > urb , & host - > h ep , dev , USB_ENDPOINT_XFER_BULK ,
pipe , buffer , len , NULL , 0 ) ;
return submit_urb ( & host - > h cd , & host - > urb ) ;
}
static int _musb_submit_int_msg ( struct usb_device * dev , unsigned long pipe ,
static int _musb_submit_int_msg ( struct musb_host_data * host ,
struct usb_device * dev , unsigned long pipe ,
void * buffer , int len , int interval )
{
construct_urb ( & urb , & hep , dev , USB_ENDPOINT_XFER_INT , pipe ,
construct_urb ( & host - > urb , & host - > hep , dev , USB_ENDPOINT_XFER_INT , pipe ,
buffer , len , NULL , interval ) ;
return submit_urb ( & hcd , & urb ) ;
return submit_urb ( & host - > h cd , & host - > urb ) ;
}
static struct int_queue * _musb_create_int_queue ( struct usb_device * dev ,
unsigned long pipe , int queuesize , int element size ,
void * buffer , int interval )
static struct int_queue * _musb_create_int_queue ( struct musb_host_data * host ,
struct usb_device * dev , unsigned long pipe , int queuesize ,
int elementsize , void * buffer , int interval )
{
struct int_queue * queue ;
int ret , index = usb_pipein ( pipe ) * 16 + usb_pipeendpoint ( pipe ) ;
@ -143,7 +141,7 @@ static struct int_queue *_musb_create_int_queue(struct usb_device *dev,
construct_urb ( & queue - > urb , & queue - > hep , dev , USB_ENDPOINT_XFER_INT ,
pipe , buffer , elementsize , NULL , interval ) ;
ret = musb_urb_enqueue ( & hcd , & queue - > urb , 0 ) ;
ret = musb_urb_enqueue ( & host - > h cd , & queue - > urb , 0 ) ;
if ( ret < 0 ) {
printf ( " Failed to enqueue URB to controller \n " ) ;
free ( queue ) ;
@ -154,27 +152,27 @@ static struct int_queue *_musb_create_int_queue(struct usb_device *dev,
return queue ;
}
static int _musb_destroy_int_queue ( struct usb_device * dev ,
struct int_queue * queue )
static int _musb_destroy_int_queue ( struct musb_host_data * host ,
struct usb_device * dev , struct int_queue * queue )
{
int index = usb_pipein ( queue - > urb . pipe ) * 16 +
usb_pipeendpoint ( queue - > urb . pipe ) ;
if ( queue - > urb . status = = - EINPROGRESS )
musb_urb_dequeue ( & hcd , & queue - > urb , - ETIME ) ;
musb_urb_dequeue ( & host - > h cd , & queue - > urb , - ETIME ) ;
dev - > int_pending & = ~ ( 1 < < index ) ;
free ( queue ) ;
return 0 ;
}
static void * _musb_poll_int_queue ( struct usb_device * dev ,
struct int_queue * queue )
static void * _musb_poll_int_queue ( struct musb_host_data * host ,
struct usb_device * dev , struct int_queue * queue )
{
if ( queue - > urb . status ! = - EINPROGRESS )
return NULL ; /* URB has already completed in a prev. poll */
host - > isr ( 0 , host ) ;
host - > host - > isr ( 0 , host - > host ) ;
if ( queue - > urb . status ! = - EINPROGRESS )
return queue - > urb . transfer_buffer ; /* Done */
@ -182,9 +180,10 @@ static void *_musb_poll_int_queue(struct usb_device *dev,
return NULL ; /* URB still pending */
}
static int _musb_reset_root_port ( struct usb_device * dev )
static int _musb_reset_root_port ( struct musb_host_data * host ,
struct usb_device * dev )
{
void * mbase = host - > mregs ;
void * mbase = host - > host - > mregs ;
u8 power ;
power = musb_readb ( mbase , MUSB_POWER ) ;
@ -204,33 +203,33 @@ static int _musb_reset_root_port(struct usb_device *dev)
# ifdef CONFIG_ARCH_SUNXI
sunxi_usb_phy_enable_squelch_detect ( 0 , 1 ) ;
# endif
host - > isr ( 0 , host ) ;
host_speed = ( musb_readb ( mbase , MUSB_POWER ) & MUSB_POWER_HSMODE ) ?
host - > host - > isr ( 0 , host - > host ) ;
host - > host _speed = ( musb_readb ( mbase , MUSB_POWER ) & MUSB_POWER_HSMODE ) ?
USB_SPEED_HIGH :
( musb_readb ( mbase , MUSB_DEVCTL ) & MUSB_DEVCTL_FSDEV ) ?
USB_SPEED_FULL : USB_SPEED_LOW ;
mdelay ( ( host_speed = = USB_SPEED_LOW ) ? 200 : 50 ) ;
mdelay ( ( host - > host _speed = = USB_SPEED_LOW ) ? 200 : 50 ) ;
return 0 ;
}
int musb_lowlevel_init ( void )
int musb_lowlevel_init ( struct musb_host_data * host )
{
void * mbase ;
/* USB spec says it may take up to 1 second for a device to connect */
unsigned long timeout = get_timer ( 0 ) + 1000 ;
int ret ;
if ( ! host ) {
if ( ! host - > host ) {
printf ( " MUSB host is not registered \n " ) ;
return - ENODEV ;
}
ret = musb_start ( host ) ;
ret = musb_start ( host - > host ) ;
if ( ret )
return ret ;
mbase = host - > mregs ;
mbase = host - > host - > mregs ;
do {
if ( musb_readb ( mbase , MUSB_DEVCTL ) & MUSB_DEVCTL_HM )
break ;
@ -238,68 +237,68 @@ int musb_lowlevel_init(void)
if ( get_timer ( 0 ) > = timeout )
return - ENODEV ;
_musb_reset_root_port ( NULL ) ;
host - > is_active = 1 ;
hcd . hcd_priv = host ;
_musb_reset_root_port ( host , NULL ) ;
host - > host - > is_active = 1 ;
host - > h cd . hcd_priv = host - > host ;
return 0 ;
}
int usb_lowlevel_stop ( int index )
{
if ( ! host ) {
if ( ! musb_host . host ) {
printf ( " MUSB host is not registered \n " ) ;
return - ENODEV ;
}
musb_stop ( host ) ;
musb_stop ( musb_host . host ) ;
return 0 ;
}
int submit_bulk_msg ( struct usb_device * dev , unsigned long pipe ,
void * buffer , int length )
{
return _musb_submit_bulk_msg ( dev , pipe , buffer , length ) ;
return _musb_submit_bulk_msg ( & musb_host , dev , pipe , buffer , length ) ;
}
int submit_control_msg ( struct usb_device * dev , unsigned long pipe ,
void * buffer , int length , struct devrequest * setup )
{
return _musb_submit_control_msg ( dev , pipe , buffer , length , setup ) ;
return _musb_submit_control_msg ( & musb_host , dev , pipe , buffer , length , setup ) ;
}
int submit_int_msg ( struct usb_device * dev , unsigned long pipe ,
void * buffer , int length , int interval )
{
return _musb_submit_int_msg ( dev , pipe , buffer , length , interval ) ;
return _musb_submit_int_msg ( & musb_host , dev , pipe , buffer , length , interval ) ;
}
struct int_queue * create_int_queue ( struct usb_device * dev ,
unsigned long pipe , int queuesize , int elementsize ,
void * buffer , int interval )
{
return _musb_create_int_queue ( dev , pipe , queuesize , elementsize ,
return _musb_create_int_queue ( & musb_host , dev , pipe , queuesize , elementsize ,
buffer , interval ) ;
}
void * poll_int_queue ( struct usb_device * dev , struct int_queue * queue )
{
return _musb_poll_int_queue ( dev , queue ) ;
return _musb_poll_int_queue ( & musb_host , dev , queue ) ;
}
int destroy_int_queue ( struct usb_device * dev , struct int_queue * queue )
{
return _musb_destroy_int_queue ( dev , queue ) ;
return _musb_destroy_int_queue ( & musb_host , dev , queue ) ;
}
int usb_reset_root_port ( struct usb_device * dev )
{
return _musb_reset_root_port ( dev ) ;
return _musb_reset_root_port ( & musb_host , dev ) ;
}
int usb_lowlevel_init ( int index , enum usb_init_type init , void * * controller )
{
return musb_lowlevel_init ( ) ;
return musb_lowlevel_init ( & musb_host ) ;
}
# endif /* CONFIG_MUSB_HOST */
@ -363,7 +362,7 @@ int musb_register(struct musb_hdrc_platform_data *plat, void *bdata,
switch ( plat - > mode ) {
# ifdef CONFIG_MUSB_HOST
case MUSB_HOST :
musbp = & host ;
musbp = & musb_host . host ;
break ;
# endif
# ifdef CONFIG_MUSB_GADGET