uboot/drivers/usb/musb/musb_udc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2009 Wind River Systems, Inc.
   4 * Tom Rix <Tom.Rix@windriver.com>
   5 *
   6 * This file is a rewrite of the usb device part of
   7 * repository git.omapzoom.org/repo/u-boot.git, branch master,
   8 * file cpu/omap3/fastboot.c
   9 *
  10 * This is the unique part of its copyright :
  11 *
  12 * -------------------------------------------------------------------------
  13 *
  14 * (C) Copyright 2008 - 2009
  15 * Windriver, <www.windriver.com>
  16 * Tom Rix <Tom.Rix@windriver.com>
  17 *
  18 * -------------------------------------------------------------------------
  19 *
  20 * The details of connecting the device to the uboot usb device subsystem
  21 * came from the old omap3 repository www.sakoman.net/u-boot-omap3.git,
  22 * branch omap3-dev-usb, file drivers/usb/usbdcore_musb.c
  23 *
  24 * This is the unique part of its copyright :
  25 *
  26 * -------------------------------------------------------------------------
  27 *
  28 * (C) Copyright 2008 Texas Instruments Incorporated.
  29 *
  30 * Based on
  31 * u-boot OMAP1510 USB drivers (drivers/usbdcore_omap1510.c)
  32 * twl4030 init based on linux (drivers/i2c/chips/twl4030_usb.c)
  33 *
  34 * Author: Diego Dompe (diego.dompe@ridgerun.com)
  35 *         Atin Malaviya (atin.malaviya@gmail.com)
  36 *
  37 * -------------------------------------------------------------------------
  38 */
  39
  40#include <common.h>
  41#include <serial.h>
  42#include <usbdevice.h>
  43#include <usb/udc.h>
  44#include "../gadget/ep0.h"
  45#include "musb_core.h"
  46#if defined(CONFIG_USB_OMAP3)
  47#include "omap3.h"
  48#elif defined(CONFIG_USB_AM35X)
  49#include "am35x.h"
  50#endif
  51
  52/* Define MUSB_DEBUG for debugging */
  53/* #define MUSB_DEBUG */
  54#include "musb_debug.h"
  55
  56#define MAX_ENDPOINT 15
  57
  58#define GET_ENDPOINT(dev,ep)                                            \
  59(((struct usb_device_instance *)(dev))->bus->endpoint_array + ep)
  60
  61#define SET_EP0_STATE(s)                                                \
  62do {                                                                    \
  63        if ((0 <= (s)) && (SET_ADDRESS >= (s))) {                       \
  64                if ((s) != ep0_state) {                                 \
  65                        if ((debug_setup) && (debug_level > 1))         \
  66                                serial_printf("INFO : Changing state "  \
  67                                              "from %s to %s in %s at " \
  68                                              "line %d\n",              \
  69                                              ep0_state_strings[ep0_state],\
  70                                              ep0_state_strings[s],     \
  71                                              __PRETTY_FUNCTION__,      \
  72                                              __LINE__);                \
  73                        ep0_state = s;                                  \
  74                }                                                       \
  75        } else {                                                        \
  76                if (debug_level > 0)                                    \
  77                        serial_printf("Error at %s %d with setting "    \
  78                                      "state %d is invalid\n",          \
  79                                      __PRETTY_FUNCTION__, __LINE__, s); \
  80        }                                                               \
  81} while (0)
  82
  83/* static implies these initialized to 0 or NULL */
  84static int debug_setup;
  85static int debug_level;
  86static struct musb_epinfo epinfo[MAX_ENDPOINT * 2 + 2];
  87static enum ep0_state_enum {
  88        IDLE = 0,
  89        TX,
  90        RX,
  91        SET_ADDRESS
  92} ep0_state = IDLE;
  93static char *ep0_state_strings[4] = {
  94        "IDLE",
  95        "TX",
  96        "RX",
  97        "SET_ADDRESS",
  98};
  99
 100static struct urb *ep0_urb;
 101struct usb_endpoint_instance *ep0_endpoint;
 102static struct usb_device_instance *udc_device;
 103static int enabled;
 104
 105#ifdef MUSB_DEBUG
 106static void musb_db_regs(void)
 107{
 108        u8 b;
 109        u16 w;
 110
 111        b = readb(&musbr->faddr);
 112        serial_printf("\tfaddr   0x%2.2x\n", b);
 113
 114        b = readb(&musbr->power);
 115        musb_print_pwr(b);
 116
 117        w = readw(&musbr->ep[0].ep0.csr0);
 118        musb_print_csr0(w);
 119
 120        b = readb(&musbr->devctl);
 121        musb_print_devctl(b);
 122
 123        b = readb(&musbr->ep[0].ep0.configdata);
 124        musb_print_config(b);
 125
 126        w = readw(&musbr->frame);
 127        serial_printf("\tframe   0x%4.4x\n", w);
 128
 129        b = readb(&musbr->index);
 130        serial_printf("\tindex   0x%2.2x\n", b);
 131
 132        w = readw(&musbr->ep[1].epN.rxmaxp);
 133        musb_print_rxmaxp(w);
 134
 135        w = readw(&musbr->ep[1].epN.rxcsr);
 136        musb_print_rxcsr(w);
 137
 138        w = readw(&musbr->ep[1].epN.txmaxp);
 139        musb_print_txmaxp(w);
 140
 141        w = readw(&musbr->ep[1].epN.txcsr);
 142        musb_print_txcsr(w);
 143}
 144#else
 145#define musb_db_regs()
 146#endif /* DEBUG_MUSB */
 147
 148static void musb_peri_softconnect(void)
 149{
 150        u8 power, devctl;
 151
 152        /* Power off MUSB */
 153        power = readb(&musbr->power);
 154        power &= ~MUSB_POWER_SOFTCONN;
 155        writeb(power, &musbr->power);
 156
 157        /* Read intr to clear */
 158        readb(&musbr->intrusb);
 159        readw(&musbr->intrrx);
 160        readw(&musbr->intrtx);
 161
 162        udelay(1000 * 1000); /* 1 sec */
 163
 164        /* Power on MUSB */
 165        power = readb(&musbr->power);
 166        power |= MUSB_POWER_SOFTCONN;
 167        /*
 168         * The usb device interface is usb 1.1
 169         * Disable 2.0 high speed by clearring the hsenable bit.
 170         */
 171        power &= ~MUSB_POWER_HSENAB;
 172        writeb(power, &musbr->power);
 173
 174        /* Check if device is in b-peripheral mode */
 175        devctl = readb(&musbr->devctl);
 176        if (!(devctl & MUSB_DEVCTL_BDEVICE) ||
 177            (devctl & MUSB_DEVCTL_HM)) {
 178                serial_printf("ERROR : Unsupport USB mode\n");
 179                serial_printf("Check that mini-B USB cable is attached "
 180                              "to the device\n");
 181        }
 182
 183        if (debug_setup && (debug_level > 1))
 184                musb_db_regs();
 185}
 186
 187static void musb_peri_reset(void)
 188{
 189        if ((debug_setup) && (debug_level > 1))
 190                serial_printf("INFO : %s reset\n", __PRETTY_FUNCTION__);
 191
 192        if (ep0_endpoint)
 193                ep0_endpoint->endpoint_address = 0xff;
 194
 195        /* Sync sw and hw addresses */
 196        writeb(udc_device->address, &musbr->faddr);
 197
 198        SET_EP0_STATE(IDLE);
 199}
 200
 201static void musb_peri_resume(void)
 202{
 203        /* noop */
 204}
 205
 206static void musb_peri_ep0_stall(void)
 207{
 208        u16 csr0;
 209
 210        csr0 = readw(&musbr->ep[0].ep0.csr0);
 211        csr0 |= MUSB_CSR0_P_SENDSTALL;
 212        writew(csr0, &musbr->ep[0].ep0.csr0);
 213        if ((debug_setup) && (debug_level > 1))
 214                serial_printf("INFO : %s stall\n", __PRETTY_FUNCTION__);
 215}
 216
 217static void musb_peri_ep0_ack_req(void)
 218{
 219        u16 csr0;
 220
 221        csr0 = readw(&musbr->ep[0].ep0.csr0);
 222        csr0 |= MUSB_CSR0_P_SVDRXPKTRDY;
 223        writew(csr0, &musbr->ep[0].ep0.csr0);
 224}
 225
 226static void musb_ep0_tx_ready(void)
 227{
 228        u16 csr0;
 229
 230        csr0 = readw(&musbr->ep[0].ep0.csr0);
 231        csr0 |= MUSB_CSR0_TXPKTRDY;
 232        writew(csr0, &musbr->ep[0].ep0.csr0);
 233}
 234
 235static void musb_ep0_tx_ready_and_last(void)
 236{
 237        u16 csr0;
 238
 239        csr0 = readw(&musbr->ep[0].ep0.csr0);
 240        csr0 |= (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_P_DATAEND);
 241        writew(csr0, &musbr->ep[0].ep0.csr0);
 242}
 243
 244static void musb_peri_ep0_last(void)
 245{
 246        u16 csr0;
 247
 248        csr0 = readw(&musbr->ep[0].ep0.csr0);
 249        csr0 |= MUSB_CSR0_P_DATAEND;
 250        writew(csr0, &musbr->ep[0].ep0.csr0);
 251}
 252
 253static void musb_peri_ep0_set_address(void)
 254{
 255        u8 faddr;
 256        writeb(udc_device->address, &musbr->faddr);
 257
 258        /* Verify */
 259        faddr = readb(&musbr->faddr);
 260        if (udc_device->address == faddr) {
 261                SET_EP0_STATE(IDLE);
 262                usbd_device_event_irq(udc_device, DEVICE_ADDRESS_ASSIGNED, 0);
 263                if ((debug_setup) && (debug_level > 1))
 264                        serial_printf("INFO : %s Address set to %d\n",
 265                                      __PRETTY_FUNCTION__, udc_device->address);
 266        } else {
 267                if (debug_level > 0)
 268                        serial_printf("ERROR : %s Address missmatch "
 269                                      "sw %d vs hw %d\n",
 270                                      __PRETTY_FUNCTION__,
 271                                      udc_device->address, faddr);
 272        }
 273}
 274
 275static void musb_peri_rx_ack(unsigned int ep)
 276{
 277        u16 peri_rxcsr;
 278
 279        peri_rxcsr = readw(&musbr->ep[ep].epN.rxcsr);
 280        peri_rxcsr &= ~MUSB_RXCSR_RXPKTRDY;
 281        writew(peri_rxcsr, &musbr->ep[ep].epN.rxcsr);
 282}
 283
 284static void musb_peri_tx_ready(unsigned int ep)
 285{
 286        u16 peri_txcsr;
 287
 288        peri_txcsr = readw(&musbr->ep[ep].epN.txcsr);
 289        peri_txcsr |= MUSB_TXCSR_TXPKTRDY;
 290        writew(peri_txcsr, &musbr->ep[ep].epN.txcsr);
 291}
 292
 293static void musb_peri_ep0_zero_data_request(int err)
 294{
 295        musb_peri_ep0_ack_req();
 296
 297        if (err) {
 298                musb_peri_ep0_stall();
 299                SET_EP0_STATE(IDLE);
 300        } else {
 301
 302                musb_peri_ep0_last();
 303
 304                /* USBD state */
 305                switch (ep0_urb->device_request.bRequest) {
 306                case USB_REQ_SET_ADDRESS:
 307                        if ((debug_setup) && (debug_level > 1))
 308                                serial_printf("INFO : %s received set "
 309                                              "address\n", __PRETTY_FUNCTION__);
 310                        break;
 311
 312                case USB_REQ_SET_CONFIGURATION:
 313                        if ((debug_setup) && (debug_level > 1))
 314                                serial_printf("INFO : %s Configured\n",
 315                                              __PRETTY_FUNCTION__);
 316                        usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0);
 317                        break;
 318                }
 319
 320                /* EP0 state */
 321                if (USB_REQ_SET_ADDRESS == ep0_urb->device_request.bRequest) {
 322                        SET_EP0_STATE(SET_ADDRESS);
 323                } else {
 324                        SET_EP0_STATE(IDLE);
 325                }
 326        }
 327}
 328
 329static void musb_peri_ep0_rx_data_request(void)
 330{
 331        /*
 332         * This is the completion of the data OUT / RX
 333         *
 334         * Host is sending data to ep0 that is not
 335         * part of setup.  This comes from the cdc_recv_setup
 336         * op that is device specific.
 337         *
 338         */
 339        musb_peri_ep0_ack_req();
 340
 341        ep0_endpoint->rcv_urb = ep0_urb;
 342        ep0_urb->actual_length = 0;
 343        SET_EP0_STATE(RX);
 344}
 345
 346static void musb_peri_ep0_tx_data_request(int err)
 347{
 348        if (err) {
 349                musb_peri_ep0_stall();
 350                SET_EP0_STATE(IDLE);
 351        } else {
 352                musb_peri_ep0_ack_req();
 353
 354                ep0_endpoint->tx_urb = ep0_urb;
 355                ep0_endpoint->sent = 0;
 356                SET_EP0_STATE(TX);
 357        }
 358}
 359
 360static void musb_peri_ep0_idle(void)
 361{
 362        u16 count0;
 363        int err;
 364        u16 csr0;
 365
 366        /*
 367         * Verify addresses
 368         * A lot of confusion can be caused if the address
 369         * in software, udc layer, does not agree with the
 370         * hardware.  Since the setting of the hardware address
 371         * must be set after the set address request, the
 372         * usb state machine is out of sync for a few frame.
 373         * It is a good idea to run this check when changes
 374         * are made to the state machine.
 375         */
 376        if ((debug_level > 0) &&
 377            (ep0_state != SET_ADDRESS)) {
 378                u8 faddr;
 379
 380                faddr = readb(&musbr->faddr);
 381                if (udc_device->address != faddr) {
 382                        serial_printf("ERROR : %s addresses do not"
 383                                      "match sw %d vs hw %d\n",
 384                                      __PRETTY_FUNCTION__,
 385                                      udc_device->address, faddr);
 386                        udelay(1000 * 1000);
 387                        hang();
 388                }
 389        }
 390
 391        csr0 = readw(&musbr->ep[0].ep0.csr0);
 392
 393        if (!(MUSB_CSR0_RXPKTRDY & csr0))
 394                goto end;
 395
 396        count0 = readw(&musbr->ep[0].ep0.count0);
 397        if (count0 == 0)
 398                goto end;
 399
 400        if (count0 != 8) {
 401                if ((debug_setup) && (debug_level > 1))
 402                        serial_printf("WARN : %s SETUP incorrect size %d\n",
 403                                      __PRETTY_FUNCTION__, count0);
 404                musb_peri_ep0_stall();
 405                goto end;
 406        }
 407
 408        read_fifo(0, count0, &ep0_urb->device_request);
 409
 410        if (debug_level > 2)
 411                print_usb_device_request(&ep0_urb->device_request);
 412
 413        if (ep0_urb->device_request.wLength == 0) {
 414                err = ep0_recv_setup(ep0_urb);
 415
 416                /* Zero data request */
 417                musb_peri_ep0_zero_data_request(err);
 418        } else {
 419                /* Is data coming or going ? */
 420                u8 reqType = ep0_urb->device_request.bmRequestType;
 421
 422                if (USB_REQ_DEVICE2HOST == (reqType & USB_REQ_DIRECTION_MASK)) {
 423                        err = ep0_recv_setup(ep0_urb);
 424                        /* Device to host */
 425                        musb_peri_ep0_tx_data_request(err);
 426                } else {
 427                        /*
 428                         * Host to device
 429                         *
 430                         * The RX routine will call ep0_recv_setup
 431                         * when the data packet has arrived.
 432                         */
 433                        musb_peri_ep0_rx_data_request();
 434                }
 435        }
 436
 437end:
 438        return;
 439}
 440
 441static void musb_peri_ep0_rx(void)
 442{
 443        /*
 444         * This is the completion of the data OUT / RX
 445         *
 446         * Host is sending data to ep0 that is not
 447         * part of setup.  This comes from the cdc_recv_setup
 448         * op that is device specific.
 449         *
 450         * Pass the data back to driver ep0_recv_setup which
 451         * should give the cdc_recv_setup the chance to handle
 452         * the rx
 453         */
 454        u16 csr0;
 455        u16 count0;
 456
 457        if (debug_level > 3) {
 458                if (0 != ep0_urb->actual_length) {
 459                        serial_printf("%s finished ? %d of %d\n",
 460                                      __PRETTY_FUNCTION__,
 461                                      ep0_urb->actual_length,
 462                                      ep0_urb->device_request.wLength);
 463                }
 464        }
 465
 466        if (ep0_urb->device_request.wLength == ep0_urb->actual_length) {
 467                musb_peri_ep0_last();
 468                SET_EP0_STATE(IDLE);
 469                ep0_recv_setup(ep0_urb);
 470                return;
 471        }
 472
 473        csr0 = readw(&musbr->ep[0].ep0.csr0);
 474        if (!(MUSB_CSR0_RXPKTRDY & csr0))
 475                return;
 476
 477        count0 = readw(&musbr->ep[0].ep0.count0);
 478
 479        if (count0) {
 480                struct usb_endpoint_instance *endpoint;
 481                u32 length;
 482                u8 *data;
 483
 484                endpoint = ep0_endpoint;
 485                if (endpoint && endpoint->rcv_urb) {
 486                        struct urb *urb = endpoint->rcv_urb;
 487                        unsigned int remaining_space = urb->buffer_length -
 488                                urb->actual_length;
 489
 490                        if (remaining_space) {
 491                                int urb_bad = 0; /* urb is good */
 492
 493                                if (count0 > remaining_space)
 494                                        length = remaining_space;
 495                                else
 496                                        length = count0;
 497
 498                                data = (u8 *) urb->buffer_data;
 499                                data += urb->actual_length;
 500
 501                                /* The common musb fifo reader */
 502                                read_fifo(0, length, data);
 503
 504                                musb_peri_ep0_ack_req();
 505
 506                                /*
 507                                 * urb's actual_length is updated in
 508                                 * usbd_rcv_complete
 509                                 */
 510                                usbd_rcv_complete(endpoint, length, urb_bad);
 511
 512                        } else {
 513                                if (debug_level > 0)
 514                                        serial_printf("ERROR : %s no space in "
 515                                                      "rcv buffer\n",
 516                                                      __PRETTY_FUNCTION__);
 517                        }
 518                } else {
 519                        if (debug_level > 0)
 520                                serial_printf("ERROR : %s problem with "
 521                                              "endpoint\n",
 522                                              __PRETTY_FUNCTION__);
 523                }
 524        } else {
 525                if (debug_level > 0)
 526                        serial_printf("ERROR : %s with nothing to do\n",
 527                                      __PRETTY_FUNCTION__);
 528        }
 529}
 530
 531static void musb_peri_ep0_tx(void)
 532{
 533        u16 csr0;
 534        int transfer_size = 0;
 535        unsigned int p, pm;
 536
 537        csr0 = readw(&musbr->ep[0].ep0.csr0);
 538
 539        /* Check for pending tx */
 540        if (csr0 & MUSB_CSR0_TXPKTRDY)
 541                goto end;
 542
 543        /* Check if this is the last packet sent */
 544        if (ep0_endpoint->sent >= ep0_urb->actual_length) {
 545                SET_EP0_STATE(IDLE);
 546                goto end;
 547        }
 548
 549        transfer_size = ep0_urb->actual_length - ep0_endpoint->sent;
 550        /* Is the transfer size negative ? */
 551        if (transfer_size <= 0) {
 552                if (debug_level > 0)
 553                        serial_printf("ERROR : %s problem with the"
 554                                      " transfer size %d\n",
 555                                      __PRETTY_FUNCTION__,
 556                                      transfer_size);
 557                SET_EP0_STATE(IDLE);
 558                goto end;
 559        }
 560
 561        /* Truncate large transfers to the fifo size */
 562        if (transfer_size > ep0_endpoint->tx_packetSize)
 563                transfer_size = ep0_endpoint->tx_packetSize;
 564
 565        write_fifo(0, transfer_size, &ep0_urb->buffer[ep0_endpoint->sent]);
 566        ep0_endpoint->sent += transfer_size;
 567
 568        /* Done or more to send ? */
 569        if (ep0_endpoint->sent >= ep0_urb->actual_length)
 570                musb_ep0_tx_ready_and_last();
 571        else
 572                musb_ep0_tx_ready();
 573
 574        /* Wait a bit */
 575        pm = 10;
 576        for (p = 0; p < pm; p++) {
 577                csr0 = readw(&musbr->ep[0].ep0.csr0);
 578                if (!(csr0 & MUSB_CSR0_TXPKTRDY))
 579                        break;
 580
 581                /* Double the delay. */
 582                udelay(1 << pm);
 583        }
 584
 585        if ((ep0_endpoint->sent >= ep0_urb->actual_length) && (p < pm))
 586                SET_EP0_STATE(IDLE);
 587
 588end:
 589        return;
 590}
 591
 592static void musb_peri_ep0(void)
 593{
 594        u16 csr0;
 595
 596        if (SET_ADDRESS == ep0_state)
 597                return;
 598
 599        csr0 = readw(&musbr->ep[0].ep0.csr0);
 600
 601        /* Error conditions */
 602        if (MUSB_CSR0_P_SENTSTALL & csr0) {
 603                csr0 &= ~MUSB_CSR0_P_SENTSTALL;
 604                writew(csr0, &musbr->ep[0].ep0.csr0);
 605                SET_EP0_STATE(IDLE);
 606        }
 607        if (MUSB_CSR0_P_SETUPEND & csr0) {
 608                csr0 |= MUSB_CSR0_P_SVDSETUPEND;
 609                writew(csr0, &musbr->ep[0].ep0.csr0);
 610                SET_EP0_STATE(IDLE);
 611                if ((debug_setup) && (debug_level > 1))
 612                        serial_printf("WARN: %s SETUPEND\n",
 613                                      __PRETTY_FUNCTION__);
 614        }
 615
 616        /* Normal states */
 617        if (IDLE == ep0_state)
 618                musb_peri_ep0_idle();
 619
 620        if (TX == ep0_state)
 621                musb_peri_ep0_tx();
 622
 623        if (RX == ep0_state)
 624                musb_peri_ep0_rx();
 625}
 626
 627static void musb_peri_rx_ep(unsigned int ep)
 628{
 629        u16 peri_rxcount;
 630        u8 peri_rxcsr = readw(&musbr->ep[ep].epN.rxcsr);
 631
 632        if (!(peri_rxcsr & MUSB_RXCSR_RXPKTRDY)) {
 633                if (debug_level > 0)
 634                        serial_printf("ERROR : %s %d without MUSB_RXCSR_RXPKTRDY set\n",
 635                                      __PRETTY_FUNCTION__, ep);
 636                return;
 637        }
 638
 639        peri_rxcount = readw(&musbr->ep[ep].epN.rxcount);
 640        if (peri_rxcount) {
 641                struct usb_endpoint_instance *endpoint;
 642                u32 length;
 643                u8 *data;
 644
 645                endpoint = GET_ENDPOINT(udc_device, ep);
 646                if (endpoint && endpoint->rcv_urb) {
 647                        struct urb *urb = endpoint->rcv_urb;
 648                        unsigned int remaining_space = urb->buffer_length -
 649                                urb->actual_length;
 650
 651                        if (remaining_space) {
 652                                int urb_bad = 0; /* urb is good */
 653
 654                                if (peri_rxcount > remaining_space)
 655                                        length = remaining_space;
 656                                else
 657                                        length = peri_rxcount;
 658
 659                                data = (u8 *) urb->buffer_data;
 660                                data += urb->actual_length;
 661
 662                                /* The common musb fifo reader */
 663                                read_fifo(ep, length, data);
 664
 665                                musb_peri_rx_ack(ep);
 666
 667                                /*
 668                                 * urb's actual_length is updated in
 669                                 * usbd_rcv_complete
 670                                 */
 671                                usbd_rcv_complete(endpoint, length, urb_bad);
 672
 673                        } else {
 674                                if (debug_level > 0)
 675                                        serial_printf("ERROR : %s %d no space "
 676                                                      "in rcv buffer\n",
 677                                                      __PRETTY_FUNCTION__, ep);
 678                        }
 679                } else {
 680                        if (debug_level > 0)
 681                                serial_printf("ERROR : %s %d problem with "
 682                                              "endpoint\n",
 683                                              __PRETTY_FUNCTION__, ep);
 684                }
 685
 686        } else {
 687                if (debug_level > 0)
 688                        serial_printf("ERROR : %s %d with nothing to do\n",
 689                                      __PRETTY_FUNCTION__, ep);
 690        }
 691}
 692
 693static void musb_peri_rx(u16 intr)
 694{
 695        unsigned int ep;
 696
 697        /* Check for EP0 */
 698        if (0x01 & intr)
 699                musb_peri_ep0();
 700
 701        for (ep = 1; ep < 16; ep++) {
 702                if ((1 << ep) & intr)
 703                        musb_peri_rx_ep(ep);
 704        }
 705}
 706
 707static void musb_peri_tx(u16 intr)
 708{
 709        /* Check for EP0 */
 710        if (0x01 & intr)
 711                musb_peri_ep0_tx();
 712
 713        /*
 714         * Use this in the future when handling epN tx
 715         *
 716         * u8 ep;
 717         *
 718         * for (ep = 1; ep < 16; ep++) {
 719         *      if ((1 << ep) & intr) {
 720         *              / * handle tx for this endpoint * /
 721         *      }
 722         * }
 723         */
 724}
 725
 726void udc_irq(void)
 727{
 728        /* This is a high freq called function */
 729        if (enabled) {
 730                u8 intrusb;
 731
 732                intrusb = readb(&musbr->intrusb);
 733
 734                /*
 735                 * See drivers/usb/gadget/mpc8xx_udc.c for
 736                 * state diagram going from detached through
 737                 * configuration.
 738                 */
 739                if (MUSB_INTR_RESUME & intrusb) {
 740                        usbd_device_event_irq(udc_device,
 741                                              DEVICE_BUS_ACTIVITY, 0);
 742                        musb_peri_resume();
 743                }
 744
 745                musb_peri_ep0();
 746
 747                if (MUSB_INTR_RESET & intrusb) {
 748                        usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
 749                        musb_peri_reset();
 750                }
 751
 752                if (MUSB_INTR_DISCONNECT & intrusb) {
 753                        /* cable unplugged from hub/host */
 754                        usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
 755                        musb_peri_reset();
 756                        usbd_device_event_irq(udc_device, DEVICE_HUB_RESET, 0);
 757                }
 758
 759                if (MUSB_INTR_SOF & intrusb) {
 760                        usbd_device_event_irq(udc_device,
 761                                              DEVICE_BUS_ACTIVITY, 0);
 762                        musb_peri_resume();
 763                }
 764
 765                if (MUSB_INTR_SUSPEND & intrusb) {
 766                        usbd_device_event_irq(udc_device,
 767                                              DEVICE_BUS_INACTIVE, 0);
 768                }
 769
 770                if (ep0_state != SET_ADDRESS) {
 771                        u16 intrrx, intrtx;
 772
 773                        intrrx = readw(&musbr->intrrx);
 774                        intrtx = readw(&musbr->intrtx);
 775
 776                        if (intrrx)
 777                                musb_peri_rx(intrrx);
 778
 779                        if (intrtx)
 780                                musb_peri_tx(intrtx);
 781                } else {
 782                        if (MUSB_INTR_SOF & intrusb) {
 783                                u8 faddr;
 784                                faddr = readb(&musbr->faddr);
 785                                /*
 786                                 * Setting of the address can fail.
 787                                 * Normally it succeeds the second time.
 788                                 */
 789                                if (udc_device->address != faddr)
 790                                        musb_peri_ep0_set_address();
 791                        }
 792                }
 793        }
 794}
 795
 796void udc_set_nak(int ep_num)
 797{
 798        /* noop */
 799}
 800
 801void udc_unset_nak(int ep_num)
 802{
 803        /* noop */
 804}
 805
 806int udc_endpoint_write(struct usb_endpoint_instance *endpoint)
 807{
 808        int ret = 0;
 809
 810        /* Transmit only if the hardware is available */
 811        if (endpoint->tx_urb && endpoint->state == 0) {
 812                unsigned int ep = endpoint->endpoint_address &
 813                        USB_ENDPOINT_NUMBER_MASK;
 814
 815                u16 peri_txcsr = readw(&musbr->ep[ep].epN.txcsr);
 816
 817                /* Error conditions */
 818                if (peri_txcsr & MUSB_TXCSR_P_UNDERRUN) {
 819                        peri_txcsr &= ~MUSB_TXCSR_P_UNDERRUN;
 820                        writew(peri_txcsr, &musbr->ep[ep].epN.txcsr);
 821                }
 822
 823                if (debug_level > 1)
 824                        musb_print_txcsr(peri_txcsr);
 825
 826                /* Check if a packet is waiting to be sent */
 827                if (!(peri_txcsr & MUSB_TXCSR_TXPKTRDY)) {
 828                        u32 length;
 829                        u8 *data;
 830                        struct urb *urb = endpoint->tx_urb;
 831                        unsigned int remaining_packet = urb->actual_length -
 832                                endpoint->sent;
 833
 834                        if (endpoint->tx_packetSize < remaining_packet)
 835                                length = endpoint->tx_packetSize;
 836                        else
 837                                length = remaining_packet;
 838
 839                        data = (u8 *) urb->buffer;
 840                        data += endpoint->sent;
 841
 842                        /* common musb fifo function */
 843                        write_fifo(ep, length, data);
 844
 845                        musb_peri_tx_ready(ep);
 846
 847                        endpoint->last = length;
 848                        /* usbd_tx_complete will take care of updating 'sent' */
 849                        usbd_tx_complete(endpoint);
 850                }
 851        } else {
 852                if (debug_level > 0)
 853                        serial_printf("ERROR : %s Problem with urb %p "
 854                                      "or ep state %d\n",
 855                                      __PRETTY_FUNCTION__,
 856                                      endpoint->tx_urb, endpoint->state);
 857        }
 858
 859        return ret;
 860}
 861
 862void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
 863                  struct usb_endpoint_instance *endpoint)
 864{
 865        if (0 == id) {
 866                /* EP0 */
 867                ep0_endpoint = endpoint;
 868                ep0_endpoint->endpoint_address = 0xff;
 869                ep0_urb = usbd_alloc_urb(device, endpoint);
 870        } else if (MAX_ENDPOINT >= id) {
 871                int ep_addr;
 872
 873                /* Check the direction */
 874                ep_addr = endpoint->endpoint_address;
 875                if (USB_DIR_IN == (ep_addr & USB_ENDPOINT_DIR_MASK)) {
 876                        /* IN */
 877                        epinfo[(id * 2) + 1].epsize = endpoint->tx_packetSize;
 878                } else {
 879                        /* OUT */
 880                        epinfo[id * 2].epsize = endpoint->rcv_packetSize;
 881                }
 882
 883                musb_configure_ep(&epinfo[0], ARRAY_SIZE(epinfo));
 884        } else {
 885                if (debug_level > 0)
 886                        serial_printf("ERROR : %s endpoint request %d "
 887                                      "exceeds maximum %d\n",
 888                                      __PRETTY_FUNCTION__, id, MAX_ENDPOINT);
 889        }
 890}
 891
 892void udc_connect(void)
 893{
 894        /* noop */
 895}
 896
 897void udc_disconnect(void)
 898{
 899        /* noop */
 900}
 901
 902void udc_enable(struct usb_device_instance *device)
 903{
 904        /* Save the device structure pointer */
 905        udc_device = device;
 906
 907        enabled = 1;
 908}
 909
 910void udc_disable(void)
 911{
 912        enabled = 0;
 913}
 914
 915void udc_startup_events(struct usb_device_instance *device)
 916{
 917        /* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
 918        usbd_device_event_irq(device, DEVICE_INIT, 0);
 919
 920        /*
 921         * The DEVICE_CREATE event puts the USB device in the state
 922         * STATE_ATTACHED.
 923         */
 924        usbd_device_event_irq(device, DEVICE_CREATE, 0);
 925
 926        /* Resets the address to 0 */
 927        usbd_device_event_irq(device, DEVICE_RESET, 0);
 928
 929        udc_enable(device);
 930}
 931
 932int udc_init(void)
 933{
 934        int ret;
 935        int ep_loop;
 936
 937        ret = musb_platform_init();
 938        if (ret < 0)
 939                goto end;
 940
 941        /* Configure all the endpoint FIFO's and start usb controller */
 942        musbr = musb_cfg.regs;
 943
 944        /* Initialize the endpoints */
 945        for (ep_loop = 0; ep_loop <= MAX_ENDPOINT * 2; ep_loop++) {
 946                epinfo[ep_loop].epnum = (ep_loop / 2) + 1;
 947                epinfo[ep_loop].epdir = ep_loop % 2; /* OUT, IN */
 948                epinfo[ep_loop].epsize = 0;
 949        }
 950
 951        musb_peri_softconnect();
 952
 953        ret = 0;
 954end:
 955
 956        return ret;
 957}
 958