linux/drivers/usb/gadget/net2280.h
<<
>>
Prefs
   1/*
   2 * NetChip 2280 high/full speed USB device controller.
   3 * Unlike many such controllers, this one talks PCI.
   4 */
   5
   6/*
   7 * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com)
   8 * Copyright (C) 2003 David Brownell
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2 of the License, or
  13 * (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23 */
  24
  25#include <linux/usb/net2280.h>
  26
  27/*-------------------------------------------------------------------------*/
  28
  29#ifdef  __KERNEL__
  30
  31/* indexed registers [11.10] are accessed indirectly
  32 * caller must own the device lock.
  33 */
  34
  35static inline u32
  36get_idx_reg (struct net2280_regs __iomem *regs, u32 index)
  37{
  38        writel (index, &regs->idxaddr);
  39        /* NOTE:  synchs device/cpu memory views */
  40        return readl (&regs->idxdata);
  41}
  42
  43static inline void
  44set_idx_reg (struct net2280_regs __iomem *regs, u32 index, u32 value)
  45{
  46        writel (index, &regs->idxaddr);
  47        writel (value, &regs->idxdata);
  48        /* posted, may not be visible yet */
  49}
  50
  51#endif  /* __KERNEL__ */
  52
  53
  54#define REG_DIAG                0x0
  55#define     RETRY_COUNTER                                       16
  56#define     FORCE_PCI_SERR                                      11
  57#define     FORCE_PCI_INTERRUPT                                 10
  58#define     FORCE_USB_INTERRUPT                                 9
  59#define     FORCE_CPU_INTERRUPT                                 8
  60#define     ILLEGAL_BYTE_ENABLES                                5
  61#define     FAST_TIMES                                          4
  62#define     FORCE_RECEIVE_ERROR                                 2
  63#define     FORCE_TRANSMIT_CRC_ERROR                            0
  64#define REG_FRAME               0x02    /* from last sof */
  65#define REG_CHIPREV             0x03    /* in bcd */
  66#define REG_HS_NAK_RATE         0x0a    /* NAK per N uframes */
  67
  68#define CHIPREV_1       0x0100
  69#define CHIPREV_1A      0x0110
  70
  71#ifdef  __KERNEL__
  72
  73/* ep a-f highspeed and fullspeed maxpacket, addresses
  74 * computed from ep->num
  75 */
  76#define REG_EP_MAXPKT(dev,num) (((num) + 1) * 0x10 + \
  77                (((dev)->gadget.speed == USB_SPEED_HIGH) ? 0 : 1))
  78
  79/*-------------------------------------------------------------------------*/
  80
  81/* [8.3] for scatter/gather i/o
  82 * use struct net2280_dma_regs bitfields
  83 */
  84struct net2280_dma {
  85        __le32          dmacount;
  86        __le32          dmaaddr;                /* the buffer */
  87        __le32          dmadesc;                /* next dma descriptor */
  88        __le32          _reserved;
  89} __attribute__ ((aligned (16)));
  90
  91/*-------------------------------------------------------------------------*/
  92
  93/* DRIVER DATA STRUCTURES and UTILITIES */
  94
  95struct net2280_ep {
  96        struct usb_ep                           ep;
  97        struct net2280_ep_regs                  __iomem *regs;
  98        struct net2280_dma_regs                 __iomem *dma;
  99        struct net2280_dma                      *dummy;
 100        dma_addr_t                              td_dma; /* of dummy */
 101        struct net2280                          *dev;
 102        unsigned long                           irqs;
 103
 104        /* analogous to a host-side qh */
 105        struct list_head                        queue;
 106        const struct usb_endpoint_descriptor    *desc;
 107        unsigned                                num : 8,
 108                                                fifo_size : 12,
 109                                                in_fifo_validate : 1,
 110                                                out_overflow : 1,
 111                                                stopped : 1,
 112                                                wedged : 1,
 113                                                is_in : 1,
 114                                                is_iso : 1,
 115                                                responded : 1;
 116};
 117
 118static inline void allow_status (struct net2280_ep *ep)
 119{
 120        /* ep0 only */
 121        writel (  (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)
 122                | (1 << CLEAR_NAK_OUT_PACKETS)
 123                | (1 << CLEAR_NAK_OUT_PACKETS_MODE)
 124                , &ep->regs->ep_rsp);
 125        ep->stopped = 1;
 126}
 127
 128/* count (<= 4) bytes in the next fifo write will be valid */
 129static inline void set_fifo_bytecount (struct net2280_ep *ep, unsigned count)
 130{
 131        writeb (count, 2 + (u8 __iomem *) &ep->regs->ep_cfg);
 132}
 133
 134struct net2280_request {
 135        struct usb_request              req;
 136        struct net2280_dma              *td;
 137        dma_addr_t                      td_dma;
 138        struct list_head                queue;
 139        unsigned                        mapped : 1,
 140                                        valid : 1;
 141};
 142
 143struct net2280 {
 144        /* each pci device provides one gadget, several endpoints */
 145        struct usb_gadget               gadget;
 146        spinlock_t                      lock;
 147        struct net2280_ep               ep [7];
 148        struct usb_gadget_driver        *driver;
 149        unsigned                        enabled : 1,
 150                                        protocol_stall : 1,
 151                                        softconnect : 1,
 152                                        got_irq : 1,
 153                                        region : 1;
 154        u16                             chiprev;
 155
 156        /* pci state used to access those endpoints */
 157        struct pci_dev                  *pdev;
 158        struct net2280_regs             __iomem *regs;
 159        struct net2280_usb_regs         __iomem *usb;
 160        struct net2280_pci_regs         __iomem *pci;
 161        struct net2280_dma_regs         __iomem *dma;
 162        struct net2280_dep_regs         __iomem *dep;
 163        struct net2280_ep_regs          __iomem *epregs;
 164
 165        struct pci_pool                 *requests;
 166        // statistics...
 167};
 168
 169static inline void set_halt (struct net2280_ep *ep)
 170{
 171        /* ep0 and bulk/intr endpoints */
 172        writel (  (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)
 173                    /* set NAK_OUT for erratum 0114 */
 174                | ((ep->dev->chiprev == CHIPREV_1) << SET_NAK_OUT_PACKETS)
 175                | (1 << SET_ENDPOINT_HALT)
 176                , &ep->regs->ep_rsp);
 177}
 178
 179static inline void clear_halt (struct net2280_ep *ep)
 180{
 181        /* ep0 and bulk/intr endpoints */
 182        writel (  (1 << CLEAR_ENDPOINT_HALT)
 183                | (1 << CLEAR_ENDPOINT_TOGGLE)
 184                    /* unless the gadget driver left a short packet in the
 185                     * fifo, this reverses the erratum 0114 workaround.
 186                     */
 187                | ((ep->dev->chiprev == CHIPREV_1) << CLEAR_NAK_OUT_PACKETS)
 188                , &ep->regs->ep_rsp);
 189}
 190
 191#ifdef USE_RDK_LEDS
 192
 193static inline void net2280_led_init (struct net2280 *dev)
 194{
 195        /* LED3 (green) is on during USB activity. note erratum 0113. */
 196        writel ((1 << GPIO3_LED_SELECT)
 197                | (1 << GPIO3_OUTPUT_ENABLE)
 198                | (1 << GPIO2_OUTPUT_ENABLE)
 199                | (1 << GPIO1_OUTPUT_ENABLE)
 200                | (1 << GPIO0_OUTPUT_ENABLE)
 201                , &dev->regs->gpioctl);
 202}
 203
 204/* indicate speed with bi-color LED 0/1 */
 205static inline
 206void net2280_led_speed (struct net2280 *dev, enum usb_device_speed speed)
 207{
 208        u32     val = readl (&dev->regs->gpioctl);
 209        switch (speed) {
 210        case USB_SPEED_HIGH:            /* green */
 211                val &= ~(1 << GPIO0_DATA);
 212                val |= (1 << GPIO1_DATA);
 213                break;
 214        case USB_SPEED_FULL:            /* red */
 215                val &= ~(1 << GPIO1_DATA);
 216                val |= (1 << GPIO0_DATA);
 217                break;
 218        default:                        /* (off/black) */
 219                val &= ~((1 << GPIO1_DATA) | (1 << GPIO0_DATA));
 220                break;
 221        }
 222        writel (val, &dev->regs->gpioctl);
 223}
 224
 225/* indicate power with LED 2 */
 226static inline void net2280_led_active (struct net2280 *dev, int is_active)
 227{
 228        u32     val = readl (&dev->regs->gpioctl);
 229
 230        // FIXME this LED never seems to turn on.
 231        if (is_active)
 232                val |= GPIO2_DATA;
 233        else
 234                val &= ~GPIO2_DATA;
 235        writel (val, &dev->regs->gpioctl);
 236}
 237static inline void net2280_led_shutdown (struct net2280 *dev)
 238{
 239        /* turn off all four GPIO*_DATA bits */
 240        writel (readl (&dev->regs->gpioctl) & ~0x0f,
 241                        &dev->regs->gpioctl);
 242}
 243
 244#else
 245
 246#define net2280_led_init(dev)           do { } while (0)
 247#define net2280_led_speed(dev, speed)   do { } while (0)
 248#define net2280_led_shutdown(dev)       do { } while (0)
 249
 250#endif
 251
 252/*-------------------------------------------------------------------------*/
 253
 254#define xprintk(dev,level,fmt,args...) \
 255        printk(level "%s %s: " fmt , driver_name , \
 256                        pci_name(dev->pdev) , ## args)
 257
 258#ifdef DEBUG
 259#undef DEBUG
 260#define DEBUG(dev,fmt,args...) \
 261        xprintk(dev , KERN_DEBUG , fmt , ## args)
 262#else
 263#define DEBUG(dev,fmt,args...) \
 264        do { } while (0)
 265#endif /* DEBUG */
 266
 267#ifdef VERBOSE
 268#define VDEBUG DEBUG
 269#else
 270#define VDEBUG(dev,fmt,args...) \
 271        do { } while (0)
 272#endif  /* VERBOSE */
 273
 274#define ERROR(dev,fmt,args...) \
 275        xprintk(dev , KERN_ERR , fmt , ## args)
 276#define WARNING(dev,fmt,args...) \
 277        xprintk(dev , KERN_WARNING , fmt , ## args)
 278#define INFO(dev,fmt,args...) \
 279        xprintk(dev , KERN_INFO , fmt , ## args)
 280
 281/*-------------------------------------------------------------------------*/
 282
 283static inline void start_out_naking (struct net2280_ep *ep)
 284{
 285        /* NOTE:  hardware races lurk here, and PING protocol issues */
 286        writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
 287        /* synch with device */
 288        readl (&ep->regs->ep_rsp);
 289}
 290
 291#ifdef DEBUG
 292static inline void assert_out_naking (struct net2280_ep *ep, const char *where)
 293{
 294        u32     tmp = readl (&ep->regs->ep_stat);
 295
 296        if ((tmp & (1 << NAK_OUT_PACKETS)) == 0) {
 297                DEBUG (ep->dev, "%s %s %08x !NAK\n",
 298                                ep->ep.name, where, tmp);
 299                writel ((1 << SET_NAK_OUT_PACKETS),
 300                        &ep->regs->ep_rsp);
 301        }
 302}
 303#define ASSERT_OUT_NAKING(ep) assert_out_naking(ep,__func__)
 304#else
 305#define ASSERT_OUT_NAKING(ep) do {} while (0)
 306#endif
 307
 308static inline void stop_out_naking (struct net2280_ep *ep)
 309{
 310        u32     tmp;
 311
 312        tmp = readl (&ep->regs->ep_stat);
 313        if ((tmp & (1 << NAK_OUT_PACKETS)) != 0)
 314                writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
 315}
 316
 317#endif  /* __KERNEL__ */
 318