X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fusb%2Fmusb-new%2Fmusb_uboot.c;h=9c8cc6e584439850310ee126c268346cadcbc613;hb=cf8dcc5d02c32173b74bf1b7600dd2b990a90b13;hp=d1ee5f8d0651eac8532fcda026e3ce2cc64d5054;hpb=2aacc4239c32aa732621f3a432d576c68c3016d8;p=oweals%2Fu-boot.git diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c index d1ee5f8d06..9c8cc6e584 100644 --- a/drivers/usb/musb-new/musb_uboot.c +++ b/drivers/usb/musb-new/musb_uboot.c @@ -1,9 +1,7 @@ #include +#include #include -#ifdef CONFIG_ARCH_SUNXI -#include -#endif -#include +#include #include #include @@ -13,16 +11,17 @@ #include "musb_core.h" #include "musb_host.h" #include "musb_gadget.h" +#include "musb_uboot.h" -#ifdef CONFIG_MUSB_HOST +#ifdef CONFIG_USB_MUSB_HOST struct int_queue { struct usb_host_endpoint hep; struct urb urb; }; -static struct musb *host; -static struct usb_hcd hcd; -static enum usb_device_speed host_speed; +#if !CONFIG_IS_ENABLED(DM_USB) +struct musb_host_data musb_host; +#endif 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; } -int submit_control_msg(struct usb_device *dev, unsigned long pipe, - void *buffer, int len, struct devrequest *setup) +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->hep, dev, USB_ENDPOINT_XFER_CONTROL, + pipe, buffer, len, setup, 0); /* Fix speed for non hub-attached devices */ - if (!dev->parent) - dev->speed = host_speed; + if (!usb_dev_get_parent(dev)) + dev->speed = host->host_speed; - return submit_urb(&hcd, &urb); + return submit_urb(&host->hcd, &host->urb); } - -int 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->hep, dev, USB_ENDPOINT_XFER_BULK, + pipe, buffer, len, NULL, 0); + return submit_urb(&host->hcd, &host->urb); } -int submit_int_msg(struct usb_device *dev, unsigned long pipe, - void *buffer, int len, int interval) +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->hcd, &host->urb); } -struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe, - int queuesize, int elementsize, 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 @@ struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe, 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->hcd, &queue->urb, 0); if (ret < 0) { printf("Failed to enqueue URB to controller\n"); free(queue); @@ -154,25 +152,27 @@ struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe, return queue; } -int 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->hcd, &queue->urb, -ETIME); dev->int_pending &= ~(1 << index); free(queue); return 0; } -void *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 */ @@ -180,78 +180,194 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue) return NULL; /* URB still pending */ } -int usb_reset_root_port(void) +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); power &= 0xf0; musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power); mdelay(50); -#ifdef CONFIG_ARCH_SUNXI - /* - * sunxi phy has a bug and it will wrongly detect high speed squelch - * when clearing reset on low-speed devices, temporary disable - * squelch detection to work around this. - */ - sunxi_usb_phy_enable_squelch_detect(0, 0); -#endif + + if (host->host->ops->pre_root_reset_end) + host->host->ops->pre_root_reset_end(host->host); + power = musb_readb(mbase, MUSB_POWER); musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power); -#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) ? + + if (host->host->ops->post_root_reset_end) + host->host->ops->post_root_reset_end(host->host); + + 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 usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +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; } - musb_start(host); - mbase = host->mregs; + ret = musb_start(host->host); + if (ret) + return ret; + + mbase = host->host->mregs; do { if (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_HM) break; } while (get_timer(0) < timeout); - if (get_timer(0) >= timeout) + if (get_timer(0) >= timeout) { + musb_stop(host->host); return -ENODEV; + } - usb_reset_root_port(); - host->is_active = 1; - hcd.hcd_priv = host; + _musb_reset_root_port(host, NULL); + host->host->is_active = 1; + host->hcd.hcd_priv = host->host; return 0; } +#if !CONFIG_IS_ENABLED(DM_USB) 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; } -#endif /* CONFIG_MUSB_HOST */ -#ifdef CONFIG_MUSB_GADGET +int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int 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(&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(&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(&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(&musb_host, dev, queue); +} + +int destroy_int_queue(struct usb_device *dev, struct int_queue *queue) +{ + return _musb_destroy_int_queue(&musb_host, dev, queue); +} + +int usb_reset_root_port(struct usb_device *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(&musb_host); +} +#endif /* !CONFIG_IS_ENABLED(DM_USB) */ + +#if CONFIG_IS_ENABLED(DM_USB) +static int musb_submit_control_msg(struct udevice *dev, struct usb_device *udev, + unsigned long pipe, void *buffer, int length, + struct devrequest *setup) +{ + struct musb_host_data *host = dev_get_priv(dev); + return _musb_submit_control_msg(host, udev, pipe, buffer, length, setup); +} + +static int musb_submit_bulk_msg(struct udevice *dev, struct usb_device *udev, + unsigned long pipe, void *buffer, int length) +{ + struct musb_host_data *host = dev_get_priv(dev); + return _musb_submit_bulk_msg(host, udev, pipe, buffer, length); +} + +static int musb_submit_int_msg(struct udevice *dev, struct usb_device *udev, + unsigned long pipe, void *buffer, int length, + int interval) +{ + struct musb_host_data *host = dev_get_priv(dev); + return _musb_submit_int_msg(host, udev, pipe, buffer, length, interval); +} + +static struct int_queue *musb_create_int_queue(struct udevice *dev, + struct usb_device *udev, unsigned long pipe, int queuesize, + int elementsize, void *buffer, int interval) +{ + struct musb_host_data *host = dev_get_priv(dev); + return _musb_create_int_queue(host, udev, pipe, queuesize, elementsize, + buffer, interval); +} + +static void *musb_poll_int_queue(struct udevice *dev, struct usb_device *udev, + struct int_queue *queue) +{ + struct musb_host_data *host = dev_get_priv(dev); + return _musb_poll_int_queue(host, udev, queue); +} + +static int musb_destroy_int_queue(struct udevice *dev, struct usb_device *udev, + struct int_queue *queue) +{ + struct musb_host_data *host = dev_get_priv(dev); + return _musb_destroy_int_queue(host, udev, queue); +} + +static int musb_reset_root_port(struct udevice *dev, struct usb_device *udev) +{ + struct musb_host_data *host = dev_get_priv(dev); + return _musb_reset_root_port(host, udev); +} + +struct dm_usb_ops musb_usb_ops = { + .control = musb_submit_control_msg, + .bulk = musb_submit_bulk_msg, + .interrupt = musb_submit_int_msg, + .create_int_queue = musb_create_int_queue, + .poll_int_queue = musb_poll_int_queue, + .destroy_int_queue = musb_destroy_int_queue, + .reset_root_port = musb_reset_root_port, +}; +#endif /* CONFIG_IS_ENABLED(DM_USB) */ +#endif /* CONFIG_USB_MUSB_HOST */ + +#if defined(CONFIG_USB_MUSB_GADGET) && !CONFIG_IS_ENABLED(DM_USB_GADGET) static struct musb *gadget; int usb_gadget_handle_interrupts(int index) @@ -301,33 +417,33 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) driver->unbind(&gadget->g); return 0; } -#endif /* CONFIG_MUSB_GADGET */ +#endif /* CONFIG_USB_MUSB_GADGET */ -int musb_register(struct musb_hdrc_platform_data *plat, void *bdata, - void *ctl_regs) +struct musb *musb_register(struct musb_hdrc_platform_data *plat, void *bdata, + void *ctl_regs) { struct musb **musbp; switch (plat->mode) { -#ifdef CONFIG_MUSB_HOST +#if defined(CONFIG_USB_MUSB_HOST) && !CONFIG_IS_ENABLED(DM_USB) case MUSB_HOST: - musbp = &host; + musbp = &musb_host.host; break; #endif -#ifdef CONFIG_MUSB_GADGET +#if defined(CONFIG_USB_MUSB_GADGET) && !CONFIG_IS_ENABLED(DM_USB_GADGET) case MUSB_PERIPHERAL: musbp = &gadget; break; #endif default: - return -EINVAL; + return ERR_PTR(-EINVAL); } *musbp = musb_init_controller(plat, (struct device *)bdata, ctl_regs); - if (!musbp) { + if (IS_ERR(*musbp)) { printf("Failed to init the controller\n"); - return -EIO; + return ERR_CAST(*musbp); } - return 0; + return *musbp; }