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