/drivers/usb/gadget/net2280.h
C Header | 317 lines | 212 code | 47 blank | 58 comment | 15 complexity | d936e57b95c0628a806c62493360ef23 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
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, ®s->idxaddr); 39 /* NOTE: synchs device/cpu memory views */ 40 return readl (®s->idxdata); 41} 42 43static inline void 44set_idx_reg (struct net2280_regs __iomem *regs, u32 index, u32 value) 45{ 46 writel (index, ®s->idxaddr); 47 writel (value, ®s->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__ */