goku_udc.h 7.2 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
/*
 * Toshiba TC86C001 ("Goku-S") USB Device Controller driver
 *
 * Copyright (C) 2000-2002 Lineo
 *      by Stuart Lynne, Tom Rushworth, and Bruce Balden
 * Copyright (C) 2002 Toshiba Corporation
 * Copyright (C) 2003 MontaVista Software (source@mvista.com)
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

/*
 * PCI BAR 0 points to these registers.
 */
struct goku_udc_regs {
	/* irq management */
	u32	int_status;		/* 0x000 */
	u32	int_enable;
#define INT_SUSPEND		0x00001		/* or resume */
#define INT_USBRESET		0x00002
#define INT_ENDPOINT0		0x00004
#define INT_SETUP		0x00008
#define INT_STATUS		0x00010
#define INT_STATUSNAK		0x00020
#define INT_EPxDATASET(n)	(0x00020 << (n))	/* 0 < n < 4 */
#	define INT_EP1DATASET		0x00040
#	define INT_EP2DATASET		0x00080
#	define INT_EP3DATASET		0x00100
#define INT_EPnNAK(n)		(0x00100 < (n))		/* 0 < n < 4 */
#	define INT_EP1NAK		0x00200
#	define INT_EP2NAK		0x00400
#	define INT_EP3NAK		0x00800
#define INT_SOF			0x01000
#define INT_ERR			0x02000
#define INT_MSTWRSET		0x04000
#define INT_MSTWREND		0x08000
#define INT_MSTWRTMOUT		0x10000
#define INT_MSTRDEND		0x20000
#define INT_SYSERROR		0x40000
#define INT_PWRDETECT		0x80000

D
David Brownell 已提交
44 45 46 47
#define	INT_DEVWIDE \
	(INT_PWRDETECT|INT_SYSERROR/*|INT_ERR*/|INT_USBRESET|INT_SUSPEND)
#define	INT_EP0 \
	(INT_SETUP|INT_ENDPOINT0/*|INT_STATUS*/|INT_STATUSNAK)
L
Linus Torvalds 已提交
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234

	u32	dma_master;
#define MST_EOPB_DIS		0x0800
#define MST_EOPB_ENA		0x0400
#define MST_TIMEOUT_DIS		0x0200
#define MST_TIMEOUT_ENA		0x0100
#define MST_RD_EOPB		0x0080		/* write-only */
#define MST_RD_RESET		0x0040
#define MST_WR_RESET		0x0020
#define MST_RD_ENA		0x0004		/* 1:start, 0:ignore */
#define MST_WR_ENA		0x0002		/* 1:start, 0:ignore */
#define MST_CONNECTION		0x0001		/* 0 for ep1out/ep2in */

#define MST_R_BITS		(MST_EOPB_DIS|MST_EOPB_ENA \
					|MST_RD_ENA|MST_RD_RESET)
#define MST_W_BITS		(MST_TIMEOUT_DIS|MST_TIMEOUT_ENA \
					|MST_WR_ENA|MST_WR_RESET)
#define MST_RW_BITS		(MST_R_BITS|MST_W_BITS \
					|MST_CONNECTION)

/* these values assume (dma_master & MST_CONNECTION) == 0 */
#define UDC_MSTWR_ENDPOINT        1
#define UDC_MSTRD_ENDPOINT        2

	/* dma master write */
	u32	out_dma_start;
	u32	out_dma_end;
	u32	out_dma_current;

	/* dma master read */
	u32	in_dma_start;
	u32	in_dma_end;
	u32	in_dma_current;

	u32	power_detect;
#define PW_DETECT		0x04
#define PW_RESETB		0x02
#define PW_PULLUP		0x01

	u8	_reserved0 [0x1d8];

	/* endpoint registers */
	u32	ep_fifo [4];		/* 0x200 */
	u8	_reserved1 [0x10];
	u32	ep_mode [4];		/* only 1-3 valid */
	u8	_reserved2 [0x10];

	u32	ep_status [4];
#define EPxSTATUS_TOGGLE	0x40
#define EPxSTATUS_SUSPEND	0x20
#define EPxSTATUS_EP_MASK	(0x07<<2)
#	define EPxSTATUS_EP_READY	(0<<2)
#	define EPxSTATUS_EP_DATAIN	(1<<2)
#	define EPxSTATUS_EP_FULL	(2<<2)
#	define EPxSTATUS_EP_TX_ERR	(3<<2)
#	define EPxSTATUS_EP_RX_ERR	(4<<2)
#	define EPxSTATUS_EP_BUSY	(5<<2)
#	define EPxSTATUS_EP_STALL	(6<<2)
#	define EPxSTATUS_EP_INVALID	(7<<2)
#define EPxSTATUS_FIFO_DISABLE	0x02
#define EPxSTATUS_STAGE_ERROR	0x01

	u8	_reserved3 [0x10];
	u32	EPxSizeLA[4];
#define PACKET_ACTIVE		(1<<7)
#define DATASIZE		0x7f
	u8	_reserved3a [0x10];
	u32	EPxSizeLB[4];		/* only 1,2 valid */
	u8	_reserved3b [0x10];
	u32	EPxSizeHA[4];		/* only 1-3 valid */
	u8	_reserved3c [0x10];
	u32	EPxSizeHB[4];		/* only 1,2 valid */
	u8	_reserved4[0x30];

	/* SETUP packet contents */
	u32	bRequestType;		/* 0x300 */
	u32	bRequest;
	u32	wValueL;
	u32	wValueH;
	u32	wIndexL;
	u32	wIndexH;
	u32	wLengthL;
	u32	wLengthH;

	/* command interaction/handshaking */
	u32	SetupRecv;		/* 0x320 */
	u32	CurrConfig;
	u32	StdRequest;
	u32	Request;
	u32	DataSet;
#define DATASET_A(epnum)	(1<<(2*(epnum)))
#define DATASET_B(epnum)	(2<<(2*(epnum)))
#define DATASET_AB(epnum)	(3<<(2*(epnum)))
	u8	_reserved5[4];

	u32	UsbState;
#define USBSTATE_CONFIGURED	0x04
#define USBSTATE_ADDRESSED	0x02
#define USBSTATE_DEFAULT	0x01

	u32	EOP;

	u32	Command;		/* 0x340 */
#define COMMAND_SETDATA0	2
#define COMMAND_RESET		3
#define COMMAND_STALL		4
#define COMMAND_INVALID		5
#define COMMAND_FIFO_DISABLE	7
#define COMMAND_FIFO_ENABLE	8
#define COMMAND_INIT_DESCRIPTOR	9
#define COMMAND_FIFO_CLEAR	10	/* also stall */
#define COMMAND_STALL_CLEAR	11
#define COMMAND_EP(n)		((n) << 4)

	u32	EPxSingle;
	u8	_reserved6[4];
	u32	EPxBCS;
	u8	_reserved7[8];
	u32	IntControl;
#define ICONTROL_STATUSNAK	1
	u8	_reserved8[4];

	u32	reqmode;	// 0x360 standard request mode, low 8 bits
#define G_REQMODE_SET_INTF	(1<<7)
#define G_REQMODE_GET_INTF	(1<<6)
#define G_REQMODE_SET_CONF	(1<<5)
#define G_REQMODE_GET_CONF	(1<<4)
#define G_REQMODE_GET_DESC	(1<<3)
#define G_REQMODE_SET_FEAT	(1<<2)
#define G_REQMODE_CLEAR_FEAT	(1<<1)
#define G_REQMODE_GET_STATUS	(1<<0)

	u32	ReqMode;
	u8	_reserved9[0x18];
	u32	PortStatus;		/* 0x380 */
	u8	_reserved10[8];
	u32	address;
	u32	buff_test;
	u8	_reserved11[4];
	u32	UsbReady;
	u8	_reserved12[4];
	u32	SetDescStall;		/* 0x3a0 */
	u8	_reserved13[0x45c];

	/* hardware could handle limited GET_DESCRIPTOR duties */
#define	DESC_LEN	0x80
	u32	descriptors[DESC_LEN];	/* 0x800 */
	u8	_reserved14[0x600];

} __attribute__ ((packed));

#define	MAX_FIFO_SIZE	64
#define	MAX_EP0_SIZE	8		/* ep0 fifo is bigger, though */


/*-------------------------------------------------------------------------*/

/* DRIVER DATA STRUCTURES and UTILITIES */

struct goku_ep {
	struct usb_ep				ep;
	struct goku_udc				*dev;
	unsigned long				irqs;

	unsigned				num:8,
						dma:1,
						is_in:1,
						stopped:1;

	/* analogous to a host-side qh */
	struct list_head			queue;

	u32 __iomem				*reg_fifo;
	u32 __iomem				*reg_mode;
	u32 __iomem				*reg_status;
};

struct goku_request {
	struct usb_request		req;
	struct list_head		queue;

	unsigned			mapped:1;
};

enum ep0state {
	EP0_DISCONNECT,		/* no host */
	EP0_IDLE,		/* between STATUS ack and SETUP report */
D
David Brownell 已提交
235
	EP0_IN, EP0_OUT,	/* data stage */
L
Linus Torvalds 已提交
236 237 238 239 240 241 242 243 244 245
	EP0_STATUS,		/* status stage */
	EP0_STALL,		/* data or status stages */
	EP0_SUSPEND,		/* usb suspend */
};

struct goku_udc {
	/* each pci device provides one gadget, several endpoints */
	struct usb_gadget		gadget;
	spinlock_t			lock;
	struct goku_ep			ep[4];
D
David Brownell 已提交
246
	struct usb_gadget_driver	*driver;
L
Linus Torvalds 已提交
247 248 249 250 251 252

	enum ep0state			ep0state;
	unsigned			got_irq:1,
					got_region:1,
					req_config:1,
					configured:1,
253 254
					enabled:1,
					registered:1;
L
Linus Torvalds 已提交
255 256 257 258 259 260 261 262 263

	/* pci state used to access those endpoints */
	struct pci_dev			*pdev;
	struct goku_udc_regs __iomem	*regs;
	u32				int_enable;

	/* statistics... */
	unsigned long			irqs;
};
264
#define to_goku_udc(g)		(container_of((g), struct goku_udc, gadget))
L
Linus Torvalds 已提交
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288

/*-------------------------------------------------------------------------*/

#define xprintk(dev,level,fmt,args...) \
	printk(level "%s %s: " fmt , driver_name , \
			pci_name(dev->pdev) , ## args)

#ifdef DEBUG
#define DBG(dev,fmt,args...) \
	xprintk(dev , KERN_DEBUG , fmt , ## args)
#else
#define DBG(dev,fmt,args...) \
	do { } while (0)
#endif /* DEBUG */

#ifdef VERBOSE
#define VDBG DBG
#else
#define VDBG(dev,fmt,args...) \
	do { } while (0)
#endif	/* VERBOSE */

#define ERROR(dev,fmt,args...) \
	xprintk(dev , KERN_ERR , fmt , ## args)
289
#define WARNING(dev,fmt,args...) \
L
Linus Torvalds 已提交
290 291 292 293
	xprintk(dev , KERN_WARNING , fmt , ## args)
#define INFO(dev,fmt,args...) \
	xprintk(dev , KERN_INFO , fmt , ## args)