| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Toshiba TC86C001 ("Goku-S") USB Device Controller driver | 
 | 3 |  * | 
 | 4 |  * Copyright (C) 2000-2002 Lineo | 
 | 5 |  *      by Stuart Lynne, Tom Rushworth, and Bruce Balden | 
 | 6 |  * Copyright (C) 2002 Toshiba Corporation | 
 | 7 |  * Copyright (C) 2003 MontaVista Software (source@mvista.com) | 
 | 8 |  * | 
 | 9 |  * This file is licensed under the terms of the GNU General Public | 
 | 10 |  * License version 2.  This program is licensed "as is" without any | 
 | 11 |  * warranty of any kind, whether express or implied. | 
 | 12 |  */ | 
 | 13 |  | 
 | 14 | /* | 
 | 15 |  * PCI BAR 0 points to these registers. | 
 | 16 |  */ | 
 | 17 | struct goku_udc_regs { | 
 | 18 | 	/* irq management */ | 
 | 19 | 	u32	int_status;		/* 0x000 */ | 
 | 20 | 	u32	int_enable; | 
 | 21 | #define INT_SUSPEND		0x00001		/* or resume */ | 
 | 22 | #define INT_USBRESET		0x00002 | 
 | 23 | #define INT_ENDPOINT0		0x00004 | 
 | 24 | #define INT_SETUP		0x00008 | 
 | 25 | #define INT_STATUS		0x00010 | 
 | 26 | #define INT_STATUSNAK		0x00020 | 
 | 27 | #define INT_EPxDATASET(n)	(0x00020 << (n))	/* 0 < n < 4 */ | 
 | 28 | #	define INT_EP1DATASET		0x00040 | 
 | 29 | #	define INT_EP2DATASET		0x00080 | 
 | 30 | #	define INT_EP3DATASET		0x00100 | 
 | 31 | #define INT_EPnNAK(n)		(0x00100 < (n))		/* 0 < n < 4 */ | 
 | 32 | #	define INT_EP1NAK		0x00200 | 
 | 33 | #	define INT_EP2NAK		0x00400 | 
 | 34 | #	define INT_EP3NAK		0x00800 | 
 | 35 | #define INT_SOF			0x01000 | 
 | 36 | #define INT_ERR			0x02000 | 
 | 37 | #define INT_MSTWRSET		0x04000 | 
 | 38 | #define INT_MSTWREND		0x08000 | 
 | 39 | #define INT_MSTWRTMOUT		0x10000 | 
 | 40 | #define INT_MSTRDEND		0x20000 | 
 | 41 | #define INT_SYSERROR		0x40000 | 
 | 42 | #define INT_PWRDETECT		0x80000 | 
 | 43 |  | 
| David Brownell | 2d70c99 | 2007-07-01 17:55:50 -0700 | [diff] [blame] | 44 | #define	INT_DEVWIDE \ | 
 | 45 | 	(INT_PWRDETECT|INT_SYSERROR/*|INT_ERR*/|INT_USBRESET|INT_SUSPEND) | 
 | 46 | #define	INT_EP0 \ | 
 | 47 | 	(INT_SETUP|INT_ENDPOINT0/*|INT_STATUS*/|INT_STATUSNAK) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 48 |  | 
 | 49 | 	u32	dma_master; | 
 | 50 | #define MST_EOPB_DIS		0x0800 | 
 | 51 | #define MST_EOPB_ENA		0x0400 | 
 | 52 | #define MST_TIMEOUT_DIS		0x0200 | 
 | 53 | #define MST_TIMEOUT_ENA		0x0100 | 
 | 54 | #define MST_RD_EOPB		0x0080		/* write-only */ | 
 | 55 | #define MST_RD_RESET		0x0040 | 
 | 56 | #define MST_WR_RESET		0x0020 | 
 | 57 | #define MST_RD_ENA		0x0004		/* 1:start, 0:ignore */ | 
 | 58 | #define MST_WR_ENA		0x0002		/* 1:start, 0:ignore */ | 
 | 59 | #define MST_CONNECTION		0x0001		/* 0 for ep1out/ep2in */ | 
 | 60 |  | 
 | 61 | #define MST_R_BITS		(MST_EOPB_DIS|MST_EOPB_ENA \ | 
 | 62 | 					|MST_RD_ENA|MST_RD_RESET) | 
 | 63 | #define MST_W_BITS		(MST_TIMEOUT_DIS|MST_TIMEOUT_ENA \ | 
 | 64 | 					|MST_WR_ENA|MST_WR_RESET) | 
 | 65 | #define MST_RW_BITS		(MST_R_BITS|MST_W_BITS \ | 
 | 66 | 					|MST_CONNECTION) | 
 | 67 |  | 
 | 68 | /* these values assume (dma_master & MST_CONNECTION) == 0 */ | 
 | 69 | #define UDC_MSTWR_ENDPOINT        1 | 
 | 70 | #define UDC_MSTRD_ENDPOINT        2 | 
 | 71 |  | 
 | 72 | 	/* dma master write */ | 
 | 73 | 	u32	out_dma_start; | 
 | 74 | 	u32	out_dma_end; | 
 | 75 | 	u32	out_dma_current; | 
 | 76 |  | 
 | 77 | 	/* dma master read */ | 
 | 78 | 	u32	in_dma_start; | 
 | 79 | 	u32	in_dma_end; | 
 | 80 | 	u32	in_dma_current; | 
 | 81 |  | 
 | 82 | 	u32	power_detect; | 
 | 83 | #define PW_DETECT		0x04 | 
 | 84 | #define PW_RESETB		0x02 | 
 | 85 | #define PW_PULLUP		0x01 | 
 | 86 |  | 
 | 87 | 	u8	_reserved0 [0x1d8]; | 
 | 88 |  | 
 | 89 | 	/* endpoint registers */ | 
 | 90 | 	u32	ep_fifo [4];		/* 0x200 */ | 
 | 91 | 	u8	_reserved1 [0x10]; | 
 | 92 | 	u32	ep_mode [4];		/* only 1-3 valid */ | 
 | 93 | 	u8	_reserved2 [0x10]; | 
 | 94 |  | 
 | 95 | 	u32	ep_status [4]; | 
 | 96 | #define EPxSTATUS_TOGGLE	0x40 | 
 | 97 | #define EPxSTATUS_SUSPEND	0x20 | 
 | 98 | #define EPxSTATUS_EP_MASK	(0x07<<2) | 
 | 99 | #	define EPxSTATUS_EP_READY	(0<<2) | 
 | 100 | #	define EPxSTATUS_EP_DATAIN	(1<<2) | 
 | 101 | #	define EPxSTATUS_EP_FULL	(2<<2) | 
 | 102 | #	define EPxSTATUS_EP_TX_ERR	(3<<2) | 
 | 103 | #	define EPxSTATUS_EP_RX_ERR	(4<<2) | 
 | 104 | #	define EPxSTATUS_EP_BUSY	(5<<2) | 
 | 105 | #	define EPxSTATUS_EP_STALL	(6<<2) | 
 | 106 | #	define EPxSTATUS_EP_INVALID	(7<<2) | 
 | 107 | #define EPxSTATUS_FIFO_DISABLE	0x02 | 
 | 108 | #define EPxSTATUS_STAGE_ERROR	0x01 | 
 | 109 |  | 
 | 110 | 	u8	_reserved3 [0x10]; | 
 | 111 | 	u32	EPxSizeLA[4]; | 
 | 112 | #define PACKET_ACTIVE		(1<<7) | 
 | 113 | #define DATASIZE		0x7f | 
 | 114 | 	u8	_reserved3a [0x10]; | 
 | 115 | 	u32	EPxSizeLB[4];		/* only 1,2 valid */ | 
 | 116 | 	u8	_reserved3b [0x10]; | 
 | 117 | 	u32	EPxSizeHA[4];		/* only 1-3 valid */ | 
 | 118 | 	u8	_reserved3c [0x10]; | 
 | 119 | 	u32	EPxSizeHB[4];		/* only 1,2 valid */ | 
 | 120 | 	u8	_reserved4[0x30]; | 
 | 121 |  | 
 | 122 | 	/* SETUP packet contents */ | 
 | 123 | 	u32	bRequestType;		/* 0x300 */ | 
 | 124 | 	u32	bRequest; | 
 | 125 | 	u32	wValueL; | 
 | 126 | 	u32	wValueH; | 
 | 127 | 	u32	wIndexL; | 
 | 128 | 	u32	wIndexH; | 
 | 129 | 	u32	wLengthL; | 
 | 130 | 	u32	wLengthH; | 
 | 131 |  | 
 | 132 | 	/* command interaction/handshaking */ | 
 | 133 | 	u32	SetupRecv;		/* 0x320 */ | 
 | 134 | 	u32	CurrConfig; | 
 | 135 | 	u32	StdRequest; | 
 | 136 | 	u32	Request; | 
 | 137 | 	u32	DataSet; | 
 | 138 | #define DATASET_A(epnum)	(1<<(2*(epnum))) | 
 | 139 | #define DATASET_B(epnum)	(2<<(2*(epnum))) | 
 | 140 | #define DATASET_AB(epnum)	(3<<(2*(epnum))) | 
 | 141 | 	u8	_reserved5[4]; | 
 | 142 |  | 
 | 143 | 	u32	UsbState; | 
 | 144 | #define USBSTATE_CONFIGURED	0x04 | 
 | 145 | #define USBSTATE_ADDRESSED	0x02 | 
 | 146 | #define USBSTATE_DEFAULT	0x01 | 
 | 147 |  | 
 | 148 | 	u32	EOP; | 
 | 149 |  | 
 | 150 | 	u32	Command;		/* 0x340 */ | 
 | 151 | #define COMMAND_SETDATA0	2 | 
 | 152 | #define COMMAND_RESET		3 | 
 | 153 | #define COMMAND_STALL		4 | 
 | 154 | #define COMMAND_INVALID		5 | 
 | 155 | #define COMMAND_FIFO_DISABLE	7 | 
 | 156 | #define COMMAND_FIFO_ENABLE	8 | 
 | 157 | #define COMMAND_INIT_DESCRIPTOR	9 | 
 | 158 | #define COMMAND_FIFO_CLEAR	10	/* also stall */ | 
 | 159 | #define COMMAND_STALL_CLEAR	11 | 
 | 160 | #define COMMAND_EP(n)		((n) << 4) | 
 | 161 |  | 
 | 162 | 	u32	EPxSingle; | 
 | 163 | 	u8	_reserved6[4]; | 
 | 164 | 	u32	EPxBCS; | 
 | 165 | 	u8	_reserved7[8]; | 
 | 166 | 	u32	IntControl; | 
 | 167 | #define ICONTROL_STATUSNAK	1 | 
 | 168 | 	u8	_reserved8[4]; | 
 | 169 |  | 
 | 170 | 	u32	reqmode;	// 0x360 standard request mode, low 8 bits | 
 | 171 | #define G_REQMODE_SET_INTF	(1<<7) | 
 | 172 | #define G_REQMODE_GET_INTF	(1<<6) | 
 | 173 | #define G_REQMODE_SET_CONF	(1<<5) | 
 | 174 | #define G_REQMODE_GET_CONF	(1<<4) | 
 | 175 | #define G_REQMODE_GET_DESC	(1<<3) | 
 | 176 | #define G_REQMODE_SET_FEAT	(1<<2) | 
 | 177 | #define G_REQMODE_CLEAR_FEAT	(1<<1) | 
 | 178 | #define G_REQMODE_GET_STATUS	(1<<0) | 
 | 179 |  | 
 | 180 | 	u32	ReqMode; | 
 | 181 | 	u8	_reserved9[0x18]; | 
 | 182 | 	u32	PortStatus;		/* 0x380 */ | 
 | 183 | 	u8	_reserved10[8]; | 
 | 184 | 	u32	address; | 
 | 185 | 	u32	buff_test; | 
 | 186 | 	u8	_reserved11[4]; | 
 | 187 | 	u32	UsbReady; | 
 | 188 | 	u8	_reserved12[4]; | 
 | 189 | 	u32	SetDescStall;		/* 0x3a0 */ | 
 | 190 | 	u8	_reserved13[0x45c]; | 
 | 191 |  | 
 | 192 | 	/* hardware could handle limited GET_DESCRIPTOR duties */ | 
 | 193 | #define	DESC_LEN	0x80 | 
 | 194 | 	u32	descriptors[DESC_LEN];	/* 0x800 */ | 
 | 195 | 	u8	_reserved14[0x600]; | 
 | 196 |  | 
 | 197 | } __attribute__ ((packed)); | 
 | 198 |  | 
 | 199 | #define	MAX_FIFO_SIZE	64 | 
 | 200 | #define	MAX_EP0_SIZE	8		/* ep0 fifo is bigger, though */ | 
 | 201 |  | 
 | 202 |  | 
 | 203 | /*-------------------------------------------------------------------------*/ | 
 | 204 |  | 
 | 205 | /* DRIVER DATA STRUCTURES and UTILITIES */ | 
 | 206 |  | 
 | 207 | struct goku_ep { | 
 | 208 | 	struct usb_ep				ep; | 
 | 209 | 	struct goku_udc				*dev; | 
 | 210 | 	unsigned long				irqs; | 
 | 211 |  | 
 | 212 | 	unsigned				num:8, | 
 | 213 | 						dma:1, | 
 | 214 | 						is_in:1, | 
 | 215 | 						stopped:1; | 
 | 216 |  | 
 | 217 | 	/* analogous to a host-side qh */ | 
 | 218 | 	struct list_head			queue; | 
 | 219 | 	const struct usb_endpoint_descriptor	*desc; | 
 | 220 |  | 
 | 221 | 	u32 __iomem				*reg_fifo; | 
 | 222 | 	u32 __iomem				*reg_mode; | 
 | 223 | 	u32 __iomem				*reg_status; | 
 | 224 | }; | 
 | 225 |  | 
 | 226 | struct goku_request { | 
 | 227 | 	struct usb_request		req; | 
 | 228 | 	struct list_head		queue; | 
 | 229 |  | 
 | 230 | 	unsigned			mapped:1; | 
 | 231 | }; | 
 | 232 |  | 
 | 233 | enum ep0state { | 
 | 234 | 	EP0_DISCONNECT,		/* no host */ | 
 | 235 | 	EP0_IDLE,		/* between STATUS ack and SETUP report */ | 
| David Brownell | 2d70c99 | 2007-07-01 17:55:50 -0700 | [diff] [blame] | 236 | 	EP0_IN, EP0_OUT,	/* data stage */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 237 | 	EP0_STATUS,		/* status stage */ | 
 | 238 | 	EP0_STALL,		/* data or status stages */ | 
 | 239 | 	EP0_SUSPEND,		/* usb suspend */ | 
 | 240 | }; | 
 | 241 |  | 
 | 242 | struct goku_udc { | 
 | 243 | 	/* each pci device provides one gadget, several endpoints */ | 
 | 244 | 	struct usb_gadget		gadget; | 
 | 245 | 	spinlock_t			lock; | 
 | 246 | 	struct goku_ep			ep[4]; | 
| David Brownell | 2d70c99 | 2007-07-01 17:55:50 -0700 | [diff] [blame] | 247 | 	struct usb_gadget_driver	*driver; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 248 |  | 
 | 249 | 	enum ep0state			ep0state; | 
 | 250 | 	unsigned			got_irq:1, | 
 | 251 | 					got_region:1, | 
 | 252 | 					req_config:1, | 
 | 253 | 					configured:1, | 
 | 254 | 					enabled:1; | 
 | 255 |  | 
 | 256 | 	/* pci state used to access those endpoints */ | 
 | 257 | 	struct pci_dev			*pdev; | 
 | 258 | 	struct goku_udc_regs __iomem	*regs; | 
 | 259 | 	u32				int_enable; | 
 | 260 |  | 
 | 261 | 	/* statistics... */ | 
 | 262 | 	unsigned long			irqs; | 
 | 263 | }; | 
 | 264 |  | 
 | 265 | /*-------------------------------------------------------------------------*/ | 
 | 266 |  | 
 | 267 | #define xprintk(dev,level,fmt,args...) \ | 
 | 268 | 	printk(level "%s %s: " fmt , driver_name , \ | 
 | 269 | 			pci_name(dev->pdev) , ## args) | 
 | 270 |  | 
 | 271 | #ifdef DEBUG | 
 | 272 | #define DBG(dev,fmt,args...) \ | 
 | 273 | 	xprintk(dev , KERN_DEBUG , fmt , ## args) | 
 | 274 | #else | 
 | 275 | #define DBG(dev,fmt,args...) \ | 
 | 276 | 	do { } while (0) | 
 | 277 | #endif /* DEBUG */ | 
 | 278 |  | 
 | 279 | #ifdef VERBOSE | 
 | 280 | #define VDBG DBG | 
 | 281 | #else | 
 | 282 | #define VDBG(dev,fmt,args...) \ | 
 | 283 | 	do { } while (0) | 
 | 284 | #endif	/* VERBOSE */ | 
 | 285 |  | 
 | 286 | #define ERROR(dev,fmt,args...) \ | 
 | 287 | 	xprintk(dev , KERN_ERR , fmt , ## args) | 
| Arjan van de Ven | b6c6393 | 2008-07-25 01:45:52 -0700 | [diff] [blame] | 288 | #define WARNING(dev,fmt,args...) \ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 289 | 	xprintk(dev , KERN_WARNING , fmt , ## args) | 
 | 290 | #define INFO(dev,fmt,args...) \ | 
 | 291 | 	xprintk(dev , KERN_INFO , fmt , ## args) | 
 | 292 |  |