uboot/drivers/usb/musb-new/musb_uboot.c
<<
>>
Prefs
   1#include <common.h>
   2#include <console.h>
   3#include <dm.h>
   4#include <malloc.h>
   5#include <watchdog.h>
   6#include <linux/delay.h>
   7#include <linux/err.h>
   8#include <linux/errno.h>
   9#include <linux/usb/ch9.h>
  10#include <linux/usb/gadget.h>
  11
  12#include <usb.h>
  13#include "linux-compat.h"
  14#include "usb-compat.h"
  15#include "musb_core.h"
  16#include "musb_host.h"
  17#include "musb_gadget.h"
  18#include "musb_uboot.h"
  19
  20#ifdef CONFIG_USB_MUSB_HOST
  21struct int_queue {
  22        struct usb_host_endpoint hep;
  23        struct urb urb;
  24};
  25
  26#if !CONFIG_IS_ENABLED(DM_USB)
  27struct musb_host_data musb_host;
  28#endif
  29
  30static void musb_host_complete_urb(struct urb *urb)
  31{
  32        urb->dev->status &= ~USB_ST_NOT_PROC;
  33        urb->dev->act_len = urb->actual_length;
  34}
  35
  36static void construct_urb(struct urb *urb, struct usb_host_endpoint *hep,
  37                          struct usb_device *dev, int endpoint_type,
  38                          unsigned long pipe, void *buffer, int len,
  39                          struct devrequest *setup, int interval)
  40{
  41        int epnum = usb_pipeendpoint(pipe);
  42        int is_in = usb_pipein(pipe);
  43
  44        memset(urb, 0, sizeof(struct urb));
  45        memset(hep, 0, sizeof(struct usb_host_endpoint));
  46        INIT_LIST_HEAD(&hep->urb_list);
  47        INIT_LIST_HEAD(&urb->urb_list);
  48        urb->ep = hep;
  49        urb->complete = musb_host_complete_urb;
  50        urb->status = -EINPROGRESS;
  51        urb->dev = dev;
  52        urb->pipe = pipe;
  53        urb->transfer_buffer = buffer;
  54        urb->transfer_dma = (unsigned long)buffer;
  55        urb->transfer_buffer_length = len;
  56        urb->setup_packet = (unsigned char *)setup;
  57
  58        urb->ep->desc.wMaxPacketSize =
  59                __cpu_to_le16(is_in ? dev->epmaxpacketin[epnum] :
  60                                dev->epmaxpacketout[epnum]);
  61        urb->ep->desc.bmAttributes = endpoint_type;
  62        urb->ep->desc.bEndpointAddress =
  63                (is_in ? USB_DIR_IN : USB_DIR_OUT) | epnum;
  64        urb->ep->desc.bInterval = interval;
  65}
  66
  67static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
  68{
  69        struct musb *host = hcd->hcd_priv;
  70        int ret;
  71        unsigned long timeout;
  72
  73        ret = musb_urb_enqueue(hcd, urb, 0);
  74        if (ret < 0) {
  75                printf("Failed to enqueue URB to controller\n");
  76                return ret;
  77        }
  78
  79        timeout = get_timer(0) + USB_TIMEOUT_MS(urb->pipe);
  80        do {
  81                if (ctrlc())
  82                        return -EIO;
  83                host->isr(0, host);
  84        } while (urb->status == -EINPROGRESS &&
  85                 get_timer(0) < timeout);
  86
  87        if (urb->status == -EINPROGRESS)
  88                musb_urb_dequeue(hcd, urb, -ETIME);
  89
  90        return urb->status;
  91}
  92
  93static int _musb_submit_control_msg(struct musb_host_data *host,
  94        struct usb_device *dev, unsigned long pipe,
  95        void *buffer, int len, struct devrequest *setup)
  96{
  97        construct_urb(&host->urb, &host->hep, dev, USB_ENDPOINT_XFER_CONTROL,
  98                      pipe, buffer, len, setup, 0);
  99
 100        /* Fix speed for non hub-attached devices */
 101        if (!usb_dev_get_parent(dev))
 102                dev->speed = host->host_speed;
 103
 104        return submit_urb(&host->hcd, &host->urb);
 105}
 106
 107static int _musb_submit_bulk_msg(struct musb_host_data *host,
 108        struct usb_device *dev, unsigned long pipe, void *buffer, int len)
 109{
 110        construct_urb(&host->urb, &host->hep, dev, USB_ENDPOINT_XFER_BULK,
 111                      pipe, buffer, len, NULL, 0);
 112        return submit_urb(&host->hcd, &host->urb);
 113}
 114
 115static int _musb_submit_int_msg(struct musb_host_data *host,
 116        struct usb_device *dev, unsigned long pipe,
 117        void *buffer, int len, int interval, bool nonblock)
 118{
 119        construct_urb(&host->urb, &host->hep, dev, USB_ENDPOINT_XFER_INT, pipe,
 120                      buffer, len, NULL, interval);
 121        return submit_urb(&host->hcd, &host->urb);
 122}
 123
 124static struct int_queue *_musb_create_int_queue(struct musb_host_data *host,
 125        struct usb_device *dev, unsigned long pipe, int queuesize,
 126        int elementsize, void *buffer, int interval)
 127{
 128        struct int_queue *queue;
 129        int ret, index = usb_pipein(pipe) * 16 + usb_pipeendpoint(pipe);
 130
 131        if (queuesize != 1) {
 132                printf("ERROR musb int-queues only support queuesize 1\n");
 133                return NULL;
 134        }
 135
 136        if (dev->int_pending & (1 << index)) {
 137                printf("ERROR int-urb is already pending on pipe %lx\n", pipe);
 138                return NULL;
 139        }
 140
 141        queue = malloc(sizeof(*queue));
 142        if (!queue)
 143                return NULL;
 144
 145        construct_urb(&queue->urb, &queue->hep, dev, USB_ENDPOINT_XFER_INT,
 146                      pipe, buffer, elementsize, NULL, interval);
 147
 148        ret = musb_urb_enqueue(&host->hcd, &queue->urb, 0);
 149        if (ret < 0) {
 150                printf("Failed to enqueue URB to controller\n");
 151                free(queue);
 152                return NULL;
 153        }
 154
 155        dev->int_pending |= 1 << index;
 156        return queue;
 157}
 158
 159static int _musb_destroy_int_queue(struct musb_host_data *host,
 160        struct usb_device *dev, struct int_queue *queue)
 161{
 162        int index = usb_pipein(queue->urb.pipe) * 16 +
 163                    usb_pipeendpoint(queue->urb.pipe);
 164
 165        if (queue->urb.status == -EINPROGRESS)
 166                musb_urb_dequeue(&host->hcd, &queue->urb, -ETIME);
 167
 168        dev->int_pending &= ~(1 << index);
 169        free(queue);
 170        return 0;
 171}
 172
 173static void *_musb_poll_int_queue(struct musb_host_data *host,
 174        struct usb_device *dev, struct int_queue *queue)
 175{
 176        if (queue->urb.status != -EINPROGRESS)
 177                return NULL; /* URB has already completed in a prev. poll */
 178
 179        host->host->isr(0, host->host);
 180
 181        if (queue->urb.status != -EINPROGRESS)
 182                return queue->urb.transfer_buffer; /* Done */
 183
 184        return NULL; /* URB still pending */
 185}
 186
 187static int _musb_reset_root_port(struct musb_host_data *host,
 188        struct usb_device *dev)
 189{
 190        void *mbase = host->host->mregs;
 191        u8 power;
 192
 193        power = musb_readb(mbase, MUSB_POWER);
 194        power &= 0xf0;
 195        musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power);
 196        mdelay(50);
 197
 198        if (host->host->ops->pre_root_reset_end)
 199                host->host->ops->pre_root_reset_end(host->host);
 200
 201        power = musb_readb(mbase, MUSB_POWER);
 202        musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power);
 203
 204        if (host->host->ops->post_root_reset_end)
 205                host->host->ops->post_root_reset_end(host->host);
 206
 207        host->host->isr(0, host->host);
 208        host->host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
 209                        USB_SPEED_HIGH :
 210                        (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ?
 211                        USB_SPEED_FULL : USB_SPEED_LOW;
 212        mdelay((host->host_speed == USB_SPEED_LOW) ? 200 : 50);
 213
 214        return 0;
 215}
 216
 217int musb_lowlevel_init(struct musb_host_data *host)
 218{
 219        void *mbase;
 220        /* USB spec says it may take up to 1 second for a device to connect */
 221        unsigned long timeout = get_timer(0) + 1000;
 222        int ret;
 223
 224        if (!host->host) {
 225                printf("MUSB host is not registered\n");
 226                return -ENODEV;
 227        }
 228
 229        ret = musb_start(host->host);
 230        if (ret)
 231                return ret;
 232
 233        mbase = host->host->mregs;
 234        do {
 235                if (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_HM)
 236                        break;
 237        } while (get_timer(0) < timeout);
 238        if (get_timer(0) >= timeout) {
 239                musb_stop(host->host);
 240                return -ENODEV;
 241        }
 242
 243        _musb_reset_root_port(host, NULL);
 244        host->host->is_active = 1;
 245        host->hcd.hcd_priv = host->host;
 246
 247        return 0;
 248}
 249
 250#if !CONFIG_IS_ENABLED(DM_USB)
 251int usb_lowlevel_stop(int index)
 252{
 253        if (!musb_host.host) {
 254                printf("MUSB host is not registered\n");
 255                return -ENODEV;
 256        }
 257
 258        musb_stop(musb_host.host);
 259        return 0;
 260}
 261
 262int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 263                            void *buffer, int length)
 264{
 265        return _musb_submit_bulk_msg(&musb_host, dev, pipe, buffer, length);
 266}
 267
 268int submit_control_msg(struct usb_device *dev, unsigned long pipe,
 269                       void *buffer, int length, struct devrequest *setup)
 270{
 271        return _musb_submit_control_msg(&musb_host, dev, pipe, buffer, length, setup);
 272}
 273
 274int submit_int_msg(struct usb_device *dev, unsigned long pipe,
 275                   void *buffer, int length, int interval, bool nonblock)
 276{
 277        return _musb_submit_int_msg(&musb_host, dev, pipe, buffer, length,
 278                                    interval, nonblock);
 279}
 280
 281struct int_queue *create_int_queue(struct usb_device *dev,
 282                unsigned long pipe, int queuesize, int elementsize,
 283                void *buffer, int interval)
 284{
 285        return _musb_create_int_queue(&musb_host, dev, pipe, queuesize, elementsize,
 286                                      buffer, interval);
 287}
 288
 289void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
 290{
 291        return _musb_poll_int_queue(&musb_host, dev, queue);
 292}
 293
 294int destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
 295{
 296        return _musb_destroy_int_queue(&musb_host, dev, queue);
 297}
 298
 299int usb_reset_root_port(struct usb_device *dev)
 300{
 301        return _musb_reset_root_port(&musb_host, dev);
 302}
 303
 304int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 305{
 306        return musb_lowlevel_init(&musb_host);
 307}
 308#endif /* !CONFIG_IS_ENABLED(DM_USB) */
 309
 310#if CONFIG_IS_ENABLED(DM_USB)
 311static int musb_submit_control_msg(struct udevice *dev, struct usb_device *udev,
 312                                   unsigned long pipe, void *buffer, int length,
 313                                   struct devrequest *setup)
 314{
 315        struct musb_host_data *host = dev_get_priv(dev);
 316        return _musb_submit_control_msg(host, udev, pipe, buffer, length, setup);
 317}
 318
 319static int musb_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
 320                                unsigned long pipe, void *buffer, int length)
 321{
 322        struct musb_host_data *host = dev_get_priv(dev);
 323        return _musb_submit_bulk_msg(host, udev, pipe, buffer, length);
 324}
 325
 326static int musb_submit_int_msg(struct udevice *dev, struct usb_device *udev,
 327                               unsigned long pipe, void *buffer, int length,
 328                               int interval, bool nonblock)
 329{
 330        struct musb_host_data *host = dev_get_priv(dev);
 331        return _musb_submit_int_msg(host, udev, pipe, buffer, length, interval,
 332                                    nonblock);
 333}
 334
 335static struct int_queue *musb_create_int_queue(struct udevice *dev,
 336                struct usb_device *udev, unsigned long pipe, int queuesize,
 337                int elementsize, void *buffer, int interval)
 338{
 339        struct musb_host_data *host = dev_get_priv(dev);
 340        return _musb_create_int_queue(host, udev, pipe, queuesize, elementsize,
 341                                      buffer, interval);
 342}
 343
 344static void *musb_poll_int_queue(struct udevice *dev, struct usb_device *udev,
 345                                 struct int_queue *queue)
 346{
 347        struct musb_host_data *host = dev_get_priv(dev);
 348        return _musb_poll_int_queue(host, udev, queue);
 349}
 350
 351static int musb_destroy_int_queue(struct udevice *dev, struct usb_device *udev,
 352                                  struct int_queue *queue)
 353{
 354        struct musb_host_data *host = dev_get_priv(dev);
 355        return _musb_destroy_int_queue(host, udev, queue);
 356}
 357
 358static int musb_reset_root_port(struct udevice *dev, struct usb_device *udev)
 359{
 360        struct musb_host_data *host = dev_get_priv(dev);
 361        return _musb_reset_root_port(host, udev);
 362}
 363
 364struct dm_usb_ops musb_usb_ops = {
 365        .control = musb_submit_control_msg,
 366        .bulk = musb_submit_bulk_msg,
 367        .interrupt = musb_submit_int_msg,
 368        .create_int_queue = musb_create_int_queue,
 369        .poll_int_queue = musb_poll_int_queue,
 370        .destroy_int_queue = musb_destroy_int_queue,
 371        .reset_root_port = musb_reset_root_port,
 372};
 373#endif /* CONFIG_IS_ENABLED(DM_USB) */
 374#endif /* CONFIG_USB_MUSB_HOST */
 375
 376#if defined(CONFIG_USB_MUSB_GADGET) && !CONFIG_IS_ENABLED(DM_USB_GADGET)
 377static struct musb *gadget;
 378
 379int usb_gadget_handle_interrupts(int index)
 380{
 381        WATCHDOG_RESET();
 382        if (!gadget || !gadget->isr)
 383                return -EINVAL;
 384
 385        return gadget->isr(0, gadget);
 386}
 387
 388int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 389{
 390        int ret;
 391
 392        if (!driver || driver->speed < USB_SPEED_FULL || !driver->bind ||
 393            !driver->setup) {
 394                printf("bad parameter.\n");
 395                return -EINVAL;
 396        }
 397
 398        if (!gadget) {
 399                printf("Controller uninitialized\n");
 400                return -ENXIO;
 401        }
 402
 403        ret = musb_gadget_start(&gadget->g, driver);
 404        if (ret < 0) {
 405                printf("gadget_start failed with %d\n", ret);
 406                return ret;
 407        }
 408
 409        ret = driver->bind(&gadget->g);
 410        if (ret < 0) {
 411                printf("bind failed with %d\n", ret);
 412                return ret;
 413        }
 414
 415        return 0;
 416}
 417
 418int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 419{
 420        if (driver->disconnect)
 421                driver->disconnect(&gadget->g);
 422        if (driver->unbind)
 423                driver->unbind(&gadget->g);
 424        return 0;
 425}
 426#endif /* CONFIG_USB_MUSB_GADGET */
 427
 428struct musb *musb_register(struct musb_hdrc_platform_data *plat, void *bdata,
 429                           void *ctl_regs)
 430{
 431        struct musb **musbp;
 432
 433        switch (plat->mode) {
 434#if defined(CONFIG_USB_MUSB_HOST) && !CONFIG_IS_ENABLED(DM_USB)
 435        case MUSB_HOST:
 436                musbp = &musb_host.host;
 437                break;
 438#endif
 439#if defined(CONFIG_USB_MUSB_GADGET) && !CONFIG_IS_ENABLED(DM_USB_GADGET)
 440        case MUSB_PERIPHERAL:
 441                musbp = &gadget;
 442                break;
 443#endif
 444        default:
 445                return ERR_PTR(-EINVAL);
 446        }
 447
 448        *musbp = musb_init_controller(plat, (struct device *)bdata, ctl_regs);
 449        if (IS_ERR(*musbp)) {
 450                printf("Failed to init the controller\n");
 451                return ERR_CAST(*musbp);
 452        }
 453
 454        return *musbp;
 455}
 456
 457#if CONFIG_IS_ENABLED(DM_USB)
 458struct usb_device *usb_dev_get_parent(struct usb_device *udev)
 459{
 460        struct udevice *parent = udev->dev->parent;
 461
 462        /*
 463         * When called from usb-uclass.c: usb_scan_device() udev->dev points
 464         * to the parent udevice, not the actual udevice belonging to the
 465         * udev as the device is not instantiated yet.
 466         *
 467         * If dev is an usb-bus, then we are called from usb_scan_device() for
 468         * an usb-device plugged directly into the root port, return NULL.
 469         */
 470        if (device_get_uclass_id(udev->dev) == UCLASS_USB)
 471                return NULL;
 472
 473        /*
 474         * If these 2 are not the same we are being called from
 475         * usb_scan_device() and udev itself is the parent.
 476         */
 477        if (dev_get_parent_priv(udev->dev) != udev)
 478                return udev;
 479
 480        /* We are being called normally, use the parent pointer */
 481        if (device_get_uclass_id(parent) == UCLASS_USB_HUB)
 482                return dev_get_parent_priv(parent);
 483
 484        return NULL;
 485}
 486#else
 487struct usb_device *usb_dev_get_parent(struct usb_device *udev)
 488{
 489        return udev->parent;
 490}
 491#endif
 492