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