linux/drivers/usb/gadget/pxa25x_udc.h
<<
>>
Prefs
   1/*
   2 * Intel PXA25x on-chip full speed USB device controller
   3 *
   4 * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
   5 * Copyright (C) 2003 David Brownell
   6 *
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21 */
  22
  23#ifndef __LINUX_USB_GADGET_PXA25X_H
  24#define __LINUX_USB_GADGET_PXA25X_H
  25
  26#include <linux/types.h>
  27
  28/*-------------------------------------------------------------------------*/
  29
  30/* pxa25x has this (move to include/asm-arm/arch-pxa/pxa-regs.h) */
  31#define UFNRH_SIR       (1 << 7)        /* SOF interrupt request */
  32#define UFNRH_SIM       (1 << 6)        /* SOF interrupt mask */
  33#define UFNRH_IPE14     (1 << 5)        /* ISO packet error, ep14 */
  34#define UFNRH_IPE9      (1 << 4)        /* ISO packet error, ep9 */
  35#define UFNRH_IPE4      (1 << 3)        /* ISO packet error, ep4 */
  36
  37/* pxa255 has this (move to include/asm-arm/arch-pxa/pxa-regs.h) */
  38#define UDCCFR          UDC_RES2        /* UDC Control Function Register */
  39#define UDCCFR_AREN     (1 << 7)        /* ACK response enable (now) */
  40#define UDCCFR_ACM      (1 << 2)        /* ACK control mode (wait for AREN) */
  41
  42/* latest pxa255 errata define new "must be one" bits in UDCCFR */
  43#define UDCCFR_MB1      (0xff & ~(UDCCFR_AREN|UDCCFR_ACM))
  44
  45/*-------------------------------------------------------------------------*/
  46
  47struct pxa25x_udc;
  48
  49struct pxa25x_ep {
  50        struct usb_ep                           ep;
  51        struct pxa25x_udc                       *dev;
  52
  53        const struct usb_endpoint_descriptor    *desc;
  54        struct list_head                        queue;
  55        unsigned long                           pio_irqs;
  56
  57        unsigned short                          fifo_size;
  58        u8                                      bEndpointAddress;
  59        u8                                      bmAttributes;
  60
  61        unsigned                                stopped : 1;
  62        unsigned                                dma_fixup : 1;
  63
  64        /* UDCCS = UDC Control/Status for this EP
  65         * UBCR = UDC Byte Count Remaining (contents of OUT fifo)
  66         * UDDR = UDC Endpoint Data Register (the fifo)
  67         * DRCM = DMA Request Channel Map
  68         */
  69        volatile u32                            *reg_udccs;
  70        volatile u32                            *reg_ubcr;
  71        volatile u32                            *reg_uddr;
  72};
  73
  74struct pxa25x_request {
  75        struct usb_request                      req;
  76        struct list_head                        queue;
  77};
  78
  79enum ep0_state {
  80        EP0_IDLE,
  81        EP0_IN_DATA_PHASE,
  82        EP0_OUT_DATA_PHASE,
  83        EP0_END_XFER,
  84        EP0_STALL,
  85};
  86
  87#define EP0_FIFO_SIZE   ((unsigned)16)
  88#define BULK_FIFO_SIZE  ((unsigned)64)
  89#define ISO_FIFO_SIZE   ((unsigned)256)
  90#define INT_FIFO_SIZE   ((unsigned)8)
  91
  92struct udc_stats {
  93        struct ep0stats {
  94                unsigned long           ops;
  95                unsigned long           bytes;
  96        } read, write;
  97        unsigned long                   irqs;
  98};
  99
 100#ifdef CONFIG_USB_PXA25X_SMALL
 101/* when memory's tight, SMALL config saves code+data.  */
 102#define PXA_UDC_NUM_ENDPOINTS   3
 103#endif
 104
 105#ifndef PXA_UDC_NUM_ENDPOINTS
 106#define PXA_UDC_NUM_ENDPOINTS   16
 107#endif
 108
 109struct pxa25x_udc {
 110        struct usb_gadget                       gadget;
 111        struct usb_gadget_driver                *driver;
 112
 113        enum ep0_state                          ep0state;
 114        struct udc_stats                        stats;
 115        unsigned                                got_irq : 1,
 116                                                vbus : 1,
 117                                                pullup : 1,
 118                                                has_cfr : 1,
 119                                                req_pending : 1,
 120                                                req_std : 1,
 121                                                req_config : 1,
 122                                                suspended : 1,
 123                                                active : 1;
 124
 125#define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200))
 126        struct timer_list                       timer;
 127
 128        struct device                           *dev;
 129        struct clk                              *clk;
 130        struct pxa2xx_udc_mach_info             *mach;
 131        struct otg_transceiver                  *transceiver;
 132        u64                                     dma_mask;
 133        struct pxa25x_ep                        ep [PXA_UDC_NUM_ENDPOINTS];
 134
 135#ifdef CONFIG_USB_GADGET_DEBUG_FS
 136        struct dentry                           *debugfs_udc;
 137#endif
 138};
 139
 140/*-------------------------------------------------------------------------*/
 141
 142#ifdef CONFIG_ARCH_LUBBOCK
 143#include <mach/lubbock.h>
 144/* lubbock can also report usb connect/disconnect irqs */
 145#endif
 146
 147static struct pxa25x_udc *the_controller;
 148
 149/*-------------------------------------------------------------------------*/
 150
 151/*
 152 * Debugging support vanishes in non-debug builds.  DBG_NORMAL should be
 153 * mostly silent during normal use/testing, with no timing side-effects.
 154 */
 155#define DBG_NORMAL      1       /* error paths, device state transitions */
 156#define DBG_VERBOSE     2       /* add some success path trace info */
 157#define DBG_NOISY       3       /* ... even more: request level */
 158#define DBG_VERY_NOISY  4       /* ... even more: packet level */
 159
 160#define DMSG(stuff...)  pr_debug("udc: " stuff)
 161
 162#ifdef DEBUG
 163
 164static int is_vbus_present(void);
 165
 166static const char *state_name[] = {
 167        "EP0_IDLE",
 168        "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE",
 169        "EP0_END_XFER", "EP0_STALL"
 170};
 171
 172#ifdef VERBOSE_DEBUG
 173#    define UDC_DEBUG DBG_VERBOSE
 174#else
 175#    define UDC_DEBUG DBG_NORMAL
 176#endif
 177
 178static void __maybe_unused
 179dump_udccr(const char *label)
 180{
 181        u32     udccr = UDCCR;
 182        DMSG("%s %02X =%s%s%s%s%s%s%s%s\n",
 183                label, udccr,
 184                (udccr & UDCCR_REM) ? " rem" : "",
 185                (udccr & UDCCR_RSTIR) ? " rstir" : "",
 186                (udccr & UDCCR_SRM) ? " srm" : "",
 187                (udccr & UDCCR_SUSIR) ? " susir" : "",
 188                (udccr & UDCCR_RESIR) ? " resir" : "",
 189                (udccr & UDCCR_RSM) ? " rsm" : "",
 190                (udccr & UDCCR_UDA) ? " uda" : "",
 191                (udccr & UDCCR_UDE) ? " ude" : "");
 192}
 193
 194static void __maybe_unused
 195dump_udccs0(const char *label)
 196{
 197        u32             udccs0 = UDCCS0;
 198
 199        DMSG("%s %s %02X =%s%s%s%s%s%s%s%s\n",
 200                label, state_name[the_controller->ep0state], udccs0,
 201                (udccs0 & UDCCS0_SA) ? " sa" : "",
 202                (udccs0 & UDCCS0_RNE) ? " rne" : "",
 203                (udccs0 & UDCCS0_FST) ? " fst" : "",
 204                (udccs0 & UDCCS0_SST) ? " sst" : "",
 205                (udccs0 & UDCCS0_DRWF) ? " dwrf" : "",
 206                (udccs0 & UDCCS0_FTF) ? " ftf" : "",
 207                (udccs0 & UDCCS0_IPR) ? " ipr" : "",
 208                (udccs0 & UDCCS0_OPR) ? " opr" : "");
 209}
 210
 211static void __maybe_unused
 212dump_state(struct pxa25x_udc *dev)
 213{
 214        u32             tmp;
 215        unsigned        i;
 216
 217        DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n",
 218                is_vbus_present() ? "host " : "disconnected",
 219                state_name[dev->ep0state],
 220                UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL);
 221        dump_udccr("udccr");
 222        if (dev->has_cfr) {
 223                tmp = UDCCFR;
 224                DMSG("udccfr %02X =%s%s\n", tmp,
 225                        (tmp & UDCCFR_AREN) ? " aren" : "",
 226                        (tmp & UDCCFR_ACM) ? " acm" : "");
 227        }
 228
 229        if (!dev->driver) {
 230                DMSG("no gadget driver bound\n");
 231                return;
 232        } else
 233                DMSG("ep0 driver '%s'\n", dev->driver->driver.name);
 234
 235        if (!is_vbus_present())
 236                return;
 237
 238        dump_udccs0 ("udccs0");
 239        DMSG("ep0 IN %lu/%lu, OUT %lu/%lu\n",
 240                dev->stats.write.bytes, dev->stats.write.ops,
 241                dev->stats.read.bytes, dev->stats.read.ops);
 242
 243        for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) {
 244                if (dev->ep [i].desc == NULL)
 245                        continue;
 246                DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs);
 247        }
 248}
 249
 250#else
 251
 252#define dump_udccr(x)   do{}while(0)
 253#define dump_udccs0(x)  do{}while(0)
 254#define dump_state(x)   do{}while(0)
 255
 256#define UDC_DEBUG ((unsigned)0)
 257
 258#endif
 259
 260#define DBG(lvl, stuff...) do{if ((lvl) <= UDC_DEBUG) DMSG(stuff);}while(0)
 261
 262#define ERR(stuff...)           pr_err("udc: " stuff)
 263#define WARNING(stuff...)       pr_warning("udc: " stuff)
 264#define INFO(stuff...)          pr_info("udc: " stuff)
 265
 266
 267#endif /* __LINUX_USB_GADGET_PXA25X_H */
 268