aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/Kconfig21
-rw-r--r--drivers/usb/gadget/Makefile1
-rw-r--r--drivers/usb/gadget/s3c2410_udc.c2078
-rw-r--r--drivers/usb/gadget/s3c2410_udc.h110
4 files changed, 2210 insertions, 0 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 05768889497b..74eaa7de525f 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -208,6 +208,27 @@ config USB_OTG
208 208
209 Select this only if your OMAP board has a Mini-AB connector. 209 Select this only if your OMAP board has a Mini-AB connector.
210 210
211config USB_GADGET_S3C2410
212 boolean "S3C2410 USB Device Controller"
213 depends on ARCH_S3C2410
214 help
215 Samsung's S3C2410 is an ARM-4 processor with an integrated
216 full speed USB 1.1 device controller. It has 4 configurable
217 endpoints, as well as endpoint zero (for control transfers).
218
219 This driver has been tested on the S3C2410, S3C2412, and
220 S3C2440 processors.
221
222config USB_S3C2410
223 tristate
224 depends on USB_GADGET_S3C2410
225 default USB_GADGET
226 select USB_GADGET_SELECTED
227
228config USB_S3C2410_DEBUG
229 boolean "S3C2410 udc debug messages"
230 depends on USB_GADGET_S3C2410
231
211config USB_GADGET_AT91 232config USB_GADGET_AT91
212 boolean "AT91 USB Device Port" 233 boolean "AT91 USB Device Port"
213 depends on ARCH_AT91 && !ARCH_AT91SAM9RL 234 depends on ARCH_AT91 && !ARCH_AT91SAM9RL
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 2d41e849c9ee..bff27832779b 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o
7obj-$(CONFIG_USB_GOKU) += goku_udc.o 7obj-$(CONFIG_USB_GOKU) += goku_udc.o
8obj-$(CONFIG_USB_OMAP) += omap_udc.o 8obj-$(CONFIG_USB_OMAP) += omap_udc.o
9obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o 9obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o
10obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o
10obj-$(CONFIG_USB_AT91) += at91_udc.o 11obj-$(CONFIG_USB_AT91) += at91_udc.o
11obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o 12obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o
12obj-$(CONFIG_USB_M66592) += m66592-udc.o 13obj-$(CONFIG_USB_M66592) += m66592-udc.o
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
new file mode 100644
index 000000000000..d60748add325
--- /dev/null
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -0,0 +1,2078 @@
1/*
2 * linux/drivers/usb/gadget/s3c2410_udc.c
3 *
4 * Samsung S3C24xx series on-chip full speed USB device controllers
5 *
6 * Copyright (C) 2004-2007 Herbert Pötzl - Arnaud Patard
7 * Additional cleanups by Ben Dooks <ben-linux@fluff.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/delay.h>
28#include <linux/ioport.h>
29#include <linux/sched.h>
30#include <linux/slab.h>
31#include <linux/smp_lock.h>
32#include <linux/errno.h>
33#include <linux/init.h>
34#include <linux/timer.h>
35#include <linux/list.h>
36#include <linux/interrupt.h>
37#include <linux/platform_device.h>
38#include <linux/version.h>
39#include <linux/clk.h>
40
41#include <linux/debugfs.h>
42#include <linux/seq_file.h>
43
44#include <linux/usb.h>
45#include <linux/usb_gadget.h>
46
47#include <asm/byteorder.h>
48#include <asm/io.h>
49#include <asm/irq.h>
50#include <asm/system.h>
51#include <asm/unaligned.h>
52#include <asm/arch/irqs.h>
53
54#include <asm/arch/hardware.h>
55#include <asm/arch/regs-clock.h>
56#include <asm/arch/regs-gpio.h>
57#include <asm/arch/regs-udc.h>
58#include <asm/arch/udc.h>
59
60#include <asm/mach-types.h>
61
62#include "s3c2410_udc.h"
63
64#define DRIVER_DESC "S3C2410 USB Device Controller Gadget"
65#define DRIVER_VERSION "29 Apr 2007"
66#define DRIVER_AUTHOR "Herbert Pötzl <herbert@13thfloor.at>, " \
67 "Arnaud Patard <arnaud.patard@rtp-net.org>"
68
69static const char gadget_name[] = "s3c2410_udc";
70static const char driver_desc[] = DRIVER_DESC;
71
72static struct s3c2410_udc *the_controller;
73static struct clk *udc_clock;
74static struct clk *usb_bus_clock;
75static void __iomem *base_addr;
76static u64 rsrc_start;
77static u64 rsrc_len;
78static struct dentry *s3c2410_udc_debugfs_root;
79
80static inline u32 udc_read(u32 reg)
81{
82 return readb(base_addr + reg);
83}
84
85static inline void udc_write(u32 value, u32 reg)
86{
87 writeb(value, base_addr + reg);
88}
89
90static inline void udc_writeb(void __iomem *base, u32 value, u32 reg)
91{
92 writeb(value, base + reg);
93}
94
95static struct s3c2410_udc_mach_info *udc_info;
96
97/*************************** DEBUG FUNCTION ***************************/
98#define DEBUG_NORMAL 1
99#define DEBUG_VERBOSE 2
100
101#ifdef CONFIG_USB_S3C2410_DEBUG
102#define USB_S3C2410_DEBUG_LEVEL 0
103
104static uint32_t s3c2410_ticks = 0;
105
106static int dprintk(int level, const char *fmt, ...)
107{
108 static char printk_buf[1024];
109 static long prevticks;
110 static int invocation;
111 va_list args;
112 int len;
113
114 if (level > USB_S3C2410_DEBUG_LEVEL)
115 return 0;
116
117 if (s3c2410_ticks != prevticks) {
118 prevticks = s3c2410_ticks;
119 invocation = 0;
120 }
121
122 len = scnprintf(printk_buf,
123 sizeof(printk_buf), "%1lu.%02d USB: ",
124 prevticks, invocation++);
125
126 va_start(args, fmt);
127 len = vscnprintf(printk_buf+len,
128 sizeof(printk_buf)-len, fmt, args);
129 va_end(args);
130
131 return printk(KERN_DEBUG "%s", printk_buf);
132}
133#else
134static int dprintk(int level, const char *fmt, ...)
135{
136 return 0;
137}
138#endif
139static int s3c2410_udc_debugfs_seq_show(struct seq_file *m, void *p)
140{
141 u32 addr_reg,pwr_reg,ep_int_reg,usb_int_reg;
142 u32 ep_int_en_reg, usb_int_en_reg, ep0_csr;
143 u32 ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2;
144 u32 ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2;
145
146 addr_reg = udc_read(S3C2410_UDC_FUNC_ADDR_REG);
147 pwr_reg = udc_read(S3C2410_UDC_PWR_REG);
148 ep_int_reg = udc_read(S3C2410_UDC_EP_INT_REG);
149 usb_int_reg = udc_read(S3C2410_UDC_USB_INT_REG);
150 ep_int_en_reg = udc_read(S3C2410_UDC_EP_INT_EN_REG);
151 usb_int_en_reg = udc_read(S3C2410_UDC_USB_INT_EN_REG);
152 udc_write(0, S3C2410_UDC_INDEX_REG);
153 ep0_csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
154 udc_write(1, S3C2410_UDC_INDEX_REG);
155 ep1_i_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG);
156 ep1_i_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG);
157 ep1_o_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG);
158 ep1_o_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG);
159 udc_write(2, S3C2410_UDC_INDEX_REG);
160 ep2_i_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG);
161 ep2_i_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG);
162 ep2_o_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG);
163 ep2_o_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG);
164
165 seq_printf(m, "FUNC_ADDR_REG : 0x%04X\n"
166 "PWR_REG : 0x%04X\n"
167 "EP_INT_REG : 0x%04X\n"
168 "USB_INT_REG : 0x%04X\n"
169 "EP_INT_EN_REG : 0x%04X\n"
170 "USB_INT_EN_REG : 0x%04X\n"
171 "EP0_CSR : 0x%04X\n"
172 "EP1_I_CSR1 : 0x%04X\n"
173 "EP1_I_CSR2 : 0x%04X\n"
174 "EP1_O_CSR1 : 0x%04X\n"
175 "EP1_O_CSR2 : 0x%04X\n"
176 "EP2_I_CSR1 : 0x%04X\n"
177 "EP2_I_CSR2 : 0x%04X\n"
178 "EP2_O_CSR1 : 0x%04X\n"
179 "EP2_O_CSR2 : 0x%04X\n",
180 addr_reg,pwr_reg,ep_int_reg,usb_int_reg,
181 ep_int_en_reg, usb_int_en_reg, ep0_csr,
182 ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2,
183 ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2
184 );
185
186 return 0;
187}
188
189static int s3c2410_udc_debugfs_fops_open(struct inode *inode,
190 struct file *file)
191{
192 return single_open(file, s3c2410_udc_debugfs_seq_show, NULL);
193}
194
195static const struct file_operations s3c2410_udc_debugfs_fops = {
196 .open = s3c2410_udc_debugfs_fops_open,
197 .read = seq_read,
198 .llseek = seq_lseek,
199 .release = single_release,
200 .owner = THIS_MODULE,
201};
202
203/* io macros */
204
205static inline void s3c2410_udc_clear_ep0_opr(void __iomem *base)
206{
207 udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
208 udc_writeb(base, S3C2410_UDC_EP0_CSR_SOPKTRDY,
209 S3C2410_UDC_EP0_CSR_REG);
210}
211
212static inline void s3c2410_udc_clear_ep0_sst(void __iomem *base)
213{
214 udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
215 writeb(0x00, base + S3C2410_UDC_EP0_CSR_REG);
216}
217
218static inline void s3c2410_udc_clear_ep0_se(void __iomem *base)
219{
220 udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
221 udc_writeb(base, S3C2410_UDC_EP0_CSR_SSE, S3C2410_UDC_EP0_CSR_REG);
222}
223
224static inline void s3c2410_udc_set_ep0_ipr(void __iomem *base)
225{
226 udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
227 udc_writeb(base, S3C2410_UDC_EP0_CSR_IPKRDY, S3C2410_UDC_EP0_CSR_REG);
228}
229
230static inline void s3c2410_udc_set_ep0_de(void __iomem *base)
231{
232 udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
233 udc_writeb(base, S3C2410_UDC_EP0_CSR_DE, S3C2410_UDC_EP0_CSR_REG);
234}
235
236inline void s3c2410_udc_set_ep0_ss(void __iomem *b)
237{
238 udc_writeb(b, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
239 udc_writeb(b, S3C2410_UDC_EP0_CSR_SENDSTL, S3C2410_UDC_EP0_CSR_REG);
240}
241
242static inline void s3c2410_udc_set_ep0_de_out(void __iomem *base)
243{
244 udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
245
246 udc_writeb(base,(S3C2410_UDC_EP0_CSR_SOPKTRDY
247 | S3C2410_UDC_EP0_CSR_DE),
248 S3C2410_UDC_EP0_CSR_REG);
249}
250
251static inline void s3c2410_udc_set_ep0_sse_out(void __iomem *base)
252{
253 udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
254 udc_writeb(base, (S3C2410_UDC_EP0_CSR_SOPKTRDY
255 | S3C2410_UDC_EP0_CSR_SSE),
256 S3C2410_UDC_EP0_CSR_REG);
257}
258
259static inline void s3c2410_udc_set_ep0_de_in(void __iomem *base)
260{
261 udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
262 udc_writeb(base, (S3C2410_UDC_EP0_CSR_IPKRDY
263 | S3C2410_UDC_EP0_CSR_DE),
264 S3C2410_UDC_EP0_CSR_REG);
265}
266
267/*------------------------- I/O ----------------------------------*/
268
269/*
270 * s3c2410_udc_done
271 */
272static void s3c2410_udc_done(struct s3c2410_ep *ep,
273 struct s3c2410_request *req, int status)
274{
275 unsigned halted = ep->halted;
276
277 list_del_init(&req->queue);
278
279 if (likely (req->req.status == -EINPROGRESS))
280 req->req.status = status;
281 else
282 status = req->req.status;
283
284 ep->halted = 1;
285 req->req.complete(&ep->ep, &req->req);
286 ep->halted = halted;
287}
288
289static void s3c2410_udc_nuke(struct s3c2410_udc *udc,
290 struct s3c2410_ep *ep, int status)
291{
292 /* Sanity check */
293 if (&ep->queue == NULL)
294 return;
295
296 while (!list_empty (&ep->queue)) {
297 struct s3c2410_request *req;
298 req = list_entry (ep->queue.next, struct s3c2410_request,
299 queue);
300 s3c2410_udc_done(ep, req, status);
301 }
302}
303
304static inline void s3c2410_udc_clear_ep_state(struct s3c2410_udc *dev)
305{
306 unsigned i;
307
308 /* hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint
309 * fifos, and pending transactions mustn't be continued in any case.
310 */
311
312 for (i = 1; i < S3C2410_ENDPOINTS; i++)
313 s3c2410_udc_nuke(dev, &dev->ep[i], -ECONNABORTED);
314}
315
316static inline int s3c2410_udc_fifo_count_out(void)
317{
318 int tmp;
319
320 tmp = udc_read(S3C2410_UDC_OUT_FIFO_CNT2_REG) << 8;
321 tmp |= udc_read(S3C2410_UDC_OUT_FIFO_CNT1_REG);
322 return tmp;
323}
324
325/*
326 * s3c2410_udc_write_packet
327 */
328static inline int s3c2410_udc_write_packet(int fifo,
329 struct s3c2410_request *req,
330 unsigned max)
331{
332 unsigned len = min(req->req.length - req->req.actual, max);
333 u8 *buf = req->req.buf + req->req.actual;
334
335 prefetch(buf);
336
337 dprintk(DEBUG_VERBOSE, "%s %d %d %d %d\n", __func__,
338 req->req.actual, req->req.length, len, req->req.actual + len);
339
340 req->req.actual += len;
341
342 udelay(5);
343 writesb(base_addr + fifo, buf, len);
344 return len;
345}
346
347/*
348 * s3c2410_udc_write_fifo
349 *
350 * return: 0 = still running, 1 = completed, negative = errno
351 */
352static int s3c2410_udc_write_fifo(struct s3c2410_ep *ep,
353 struct s3c2410_request *req)
354{
355 unsigned count;
356 int is_last;
357 u32 idx;
358 int fifo_reg;
359 u32 ep_csr;
360
361 idx = ep->bEndpointAddress & 0x7F;
362 switch (idx) {
363 default:
364 idx = 0;
365 case 0:
366 fifo_reg = S3C2410_UDC_EP0_FIFO_REG;
367 break;
368 case 1:
369 fifo_reg = S3C2410_UDC_EP1_FIFO_REG;
370 break;
371 case 2:
372 fifo_reg = S3C2410_UDC_EP2_FIFO_REG;
373 break;
374 case 3:
375 fifo_reg = S3C2410_UDC_EP3_FIFO_REG;
376 break;
377 case 4:
378 fifo_reg = S3C2410_UDC_EP4_FIFO_REG;
379 break;
380 }
381
382 count = s3c2410_udc_write_packet(fifo_reg, req, ep->ep.maxpacket);
383
384 /* last packet is often short (sometimes a zlp) */
385 if (count != ep->ep.maxpacket)
386 is_last = 1;
387 else if (req->req.length != req->req.actual || req->req.zero)
388 is_last = 0;
389 else
390 is_last = 2;
391
392 /* Only ep0 debug messages are interesting */
393 if (idx == 0)
394 dprintk(DEBUG_NORMAL,
395 "Written ep%d %d.%d of %d b [last %d,z %d]\n",
396 idx, count, req->req.actual, req->req.length,
397 is_last, req->req.zero);
398
399 if (is_last) {
400 /* The order is important. It prevents sending 2 packets
401 * at the same time */
402
403 if (idx == 0) {
404 /* Reset signal => no need to say 'data sent' */
405 if (! (udc_read(S3C2410_UDC_USB_INT_REG)
406 & S3C2410_UDC_USBINT_RESET))
407 s3c2410_udc_set_ep0_de_in(base_addr);
408 ep->dev->ep0state=EP0_IDLE;
409 } else {
410 udc_write(idx, S3C2410_UDC_INDEX_REG);
411 ep_csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
412 udc_write(idx, S3C2410_UDC_INDEX_REG);
413 udc_write(ep_csr | S3C2410_UDC_ICSR1_PKTRDY,
414 S3C2410_UDC_IN_CSR1_REG);
415 }
416
417 s3c2410_udc_done(ep, req, 0);
418 is_last = 1;
419 } else {
420 if (idx == 0) {
421 /* Reset signal => no need to say 'data sent' */
422 if (! (udc_read(S3C2410_UDC_USB_INT_REG)
423 & S3C2410_UDC_USBINT_RESET))
424 s3c2410_udc_set_ep0_ipr(base_addr);
425 } else {
426 udc_write(idx, S3C2410_UDC_INDEX_REG);
427 ep_csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
428 udc_write(idx, S3C2410_UDC_INDEX_REG);
429 udc_write(ep_csr | S3C2410_UDC_ICSR1_PKTRDY,
430 S3C2410_UDC_IN_CSR1_REG);
431 }
432 }
433
434 return is_last;
435}
436
437static inline int s3c2410_udc_read_packet(int fifo, u8 *buf,
438 struct s3c2410_request *req, unsigned avail)
439{
440 unsigned len;
441
442 len = min(req->req.length - req->req.actual, avail);
443 req->req.actual += len;
444
445 readsb(fifo + base_addr, buf, len);
446 return len;
447}
448
449/*
450 * return: 0 = still running, 1 = queue empty, negative = errno
451 */
452static int s3c2410_udc_read_fifo(struct s3c2410_ep *ep,
453 struct s3c2410_request *req)
454{
455 u8 *buf;
456 u32 ep_csr;
457 unsigned bufferspace;
458 int is_last=1;
459 unsigned avail;
460 int fifo_count = 0;
461 u32 idx;
462 int fifo_reg;
463
464 idx = ep->bEndpointAddress & 0x7F;
465
466 switch (idx) {
467 default:
468 idx = 0;
469 case 0:
470 fifo_reg = S3C2410_UDC_EP0_FIFO_REG;
471 break;
472 case 1:
473 fifo_reg = S3C2410_UDC_EP1_FIFO_REG;
474 break;
475 case 2:
476 fifo_reg = S3C2410_UDC_EP2_FIFO_REG;
477 break;
478 case 3:
479 fifo_reg = S3C2410_UDC_EP3_FIFO_REG;
480 break;
481 case 4:
482 fifo_reg = S3C2410_UDC_EP4_FIFO_REG;
483 break;
484 }
485
486 if (!req->req.length)
487 return 1;
488
489 buf = req->req.buf + req->req.actual;
490 bufferspace = req->req.length - req->req.actual;
491 if (!bufferspace) {
492 dprintk(DEBUG_NORMAL, "%s: buffer full!\n", __func__);
493 return -1;
494 }
495
496 udc_write(idx, S3C2410_UDC_INDEX_REG);
497
498 fifo_count = s3c2410_udc_fifo_count_out();
499 dprintk(DEBUG_NORMAL, "%s fifo count : %d\n", __func__, fifo_count);
500
501 if (fifo_count > ep->ep.maxpacket)
502 avail = ep->ep.maxpacket;
503 else
504 avail = fifo_count;
505
506 fifo_count = s3c2410_udc_read_packet(fifo_reg, buf, req, avail);
507
508 /* checking this with ep0 is not accurate as we already
509 * read a control request
510 **/
511 if (idx != 0 && fifo_count < ep->ep.maxpacket) {
512 is_last = 1;
513 /* overflowed this request? flush extra data */
514 if (fifo_count != avail)
515 req->req.status = -EOVERFLOW;
516 } else {
517 is_last = (req->req.length <= req->req.actual) ? 1 : 0;
518 }
519
520 udc_write(idx, S3C2410_UDC_INDEX_REG);
521 fifo_count = s3c2410_udc_fifo_count_out();
522
523 /* Only ep0 debug messages are interesting */
524 if (idx == 0)
525 dprintk(DEBUG_VERBOSE, "%s fifo count : %d [last %d]\n",
526 __func__, fifo_count,is_last);
527
528 if (is_last) {
529 if (idx == 0) {
530 s3c2410_udc_set_ep0_de_out(base_addr);
531 ep->dev->ep0state = EP0_IDLE;
532 } else {
533 udc_write(idx, S3C2410_UDC_INDEX_REG);
534 ep_csr = udc_read(S3C2410_UDC_OUT_CSR1_REG);
535 udc_write(idx, S3C2410_UDC_INDEX_REG);
536 udc_write(ep_csr & ~S3C2410_UDC_OCSR1_PKTRDY,
537 S3C2410_UDC_OUT_CSR1_REG);
538 }
539
540 s3c2410_udc_done(ep, req, 0);
541 } else {
542 if (idx == 0) {
543 s3c2410_udc_clear_ep0_opr(base_addr);
544 } else {
545 udc_write(idx, S3C2410_UDC_INDEX_REG);
546 ep_csr = udc_read(S3C2410_UDC_OUT_CSR1_REG);
547 udc_write(idx, S3C2410_UDC_INDEX_REG);
548 udc_write(ep_csr & ~S3C2410_UDC_OCSR1_PKTRDY,
549 S3C2410_UDC_OUT_CSR1_REG);
550 }
551 }
552
553 return is_last;
554}
555
556static int s3c2410_udc_read_fifo_crq(struct usb_ctrlrequest *crq)
557{
558 unsigned char *outbuf = (unsigned char*)crq;
559 int bytes_read = 0;
560
561 udc_write(0, S3C2410_UDC_INDEX_REG);
562
563 bytes_read = s3c2410_udc_fifo_count_out();
564
565 dprintk(DEBUG_NORMAL, "%s: fifo_count=%d\n", __func__, bytes_read);
566
567 if (bytes_read > sizeof(struct usb_ctrlrequest))
568 bytes_read = sizeof(struct usb_ctrlrequest);
569
570 readsb(S3C2410_UDC_EP0_FIFO_REG + base_addr, outbuf, bytes_read);
571
572 dprintk(DEBUG_VERBOSE, "%s: len=%d %02x:%02x {%x,%x,%x}\n", __func__,
573 bytes_read, crq->bRequest, crq->bRequestType,
574 crq->wValue, crq->wIndex, crq->wLength);
575
576 return bytes_read;
577}
578
579static int s3c2410_udc_get_status(struct s3c2410_udc *dev,
580 struct usb_ctrlrequest *crq)
581{
582 u16 status = 0;
583 u8 ep_num = crq->wIndex & 0x7F;
584 u8 is_in = crq->wIndex & USB_DIR_IN;
585
586 switch (crq->bRequestType & USB_RECIP_MASK) {
587 case USB_RECIP_INTERFACE:
588 break;
589
590 case USB_RECIP_DEVICE:
591 status = dev->devstatus;
592 break;
593
594 case USB_RECIP_ENDPOINT:
595 if (ep_num > 4 || crq->wLength > 2)
596 return 1;
597
598 if (ep_num == 0) {
599 udc_write(0, S3C2410_UDC_INDEX_REG);
600 status = udc_read(S3C2410_UDC_IN_CSR1_REG);
601 status = status & S3C2410_UDC_EP0_CSR_SENDSTL;
602 } else {
603 udc_write(ep_num, S3C2410_UDC_INDEX_REG);
604 if (is_in) {
605 status = udc_read(S3C2410_UDC_IN_CSR1_REG);
606 status = status & S3C2410_UDC_ICSR1_SENDSTL;
607 } else {
608 status = udc_read(S3C2410_UDC_OUT_CSR1_REG);
609 status = status & S3C2410_UDC_OCSR1_SENDSTL;
610 }
611 }
612
613 status = status ? 1 : 0;
614 break;
615
616 default:
617 return 1;
618 }
619
620 /* Seems to be needed to get it working. ouch :( */
621 udelay(5);
622 udc_write(status & 0xFF, S3C2410_UDC_EP0_FIFO_REG);
623 udc_write(status >> 8, S3C2410_UDC_EP0_FIFO_REG);
624 s3c2410_udc_set_ep0_de_in(base_addr);
625
626 return 0;
627}
628/*------------------------- usb state machine -------------------------------*/
629static int s3c2410_udc_set_halt(struct usb_ep *_ep, int value);
630
631static void s3c2410_udc_handle_ep0_idle(struct s3c2410_udc *dev,
632 struct s3c2410_ep *ep,
633 struct usb_ctrlrequest *crq,
634 u32 ep0csr)
635{
636 int len, ret, tmp;
637
638 /* start control request? */
639 if (!(ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY))
640 return;
641
642 s3c2410_udc_nuke(dev, ep, -EPROTO);
643
644 len = s3c2410_udc_read_fifo_crq(crq);
645 if (len != sizeof(*crq)) {
646 dprintk(DEBUG_NORMAL, "setup begin: fifo READ ERROR"
647 " wanted %d bytes got %d. Stalling out...\n",
648 sizeof(*crq), len);
649 s3c2410_udc_set_ep0_ss(base_addr);
650 return;
651 }
652
653 dprintk(DEBUG_NORMAL, "bRequest = %d bRequestType %d wLength = %d\n",
654 crq->bRequest, crq->bRequestType, crq->wLength);
655
656 /* cope with automagic for some standard requests. */
657 dev->req_std = (crq->bRequestType & USB_TYPE_MASK)
658 == USB_TYPE_STANDARD;
659 dev->req_config = 0;
660 dev->req_pending = 1;
661
662 switch (crq->bRequest) {
663 case USB_REQ_SET_CONFIGURATION:
664 dprintk(DEBUG_NORMAL, "USB_REQ_SET_CONFIGURATION ... \n");
665
666 if (crq->bRequestType == USB_RECIP_DEVICE) {
667 dev->req_config = 1;
668 s3c2410_udc_set_ep0_de_out(base_addr);
669 }
670 break;
671
672 case USB_REQ_SET_INTERFACE:
673 dprintk(DEBUG_NORMAL, "USB_REQ_SET_INTERFACE ... \n");
674
675 if (crq->bRequestType == USB_RECIP_INTERFACE) {
676 dev->req_config = 1;
677 s3c2410_udc_set_ep0_de_out(base_addr);
678 }
679 break;
680
681 case USB_REQ_SET_ADDRESS:
682 dprintk(DEBUG_NORMAL, "USB_REQ_SET_ADDRESS ... \n");
683
684 if (crq->bRequestType == USB_RECIP_DEVICE) {
685 tmp = crq->wValue & 0x7F;
686 dev->address = tmp;
687 udc_write((tmp | S3C2410_UDC_FUNCADDR_UPDATE),
688 S3C2410_UDC_FUNC_ADDR_REG);
689 s3c2410_udc_set_ep0_de_out(base_addr);
690 return;
691 }
692 break;
693
694 case USB_REQ_GET_STATUS:
695 dprintk(DEBUG_NORMAL, "USB_REQ_GET_STATUS ... \n");
696 s3c2410_udc_clear_ep0_opr(base_addr);
697
698 if (dev->req_std) {
699 if (!s3c2410_udc_get_status(dev, crq)) {
700 return;
701 }
702 }
703 break;
704
705 case USB_REQ_CLEAR_FEATURE:
706 s3c2410_udc_clear_ep0_opr(base_addr);
707
708 if (crq->bRequestType != USB_RECIP_ENDPOINT)
709 break;
710
711 if (crq->wValue != USB_ENDPOINT_HALT || crq->wLength != 0)
712 break;
713
714 s3c2410_udc_set_halt(&dev->ep[crq->wIndex & 0x7f].ep, 0);
715 s3c2410_udc_set_ep0_de_out(base_addr);
716 return;
717
718 case USB_REQ_SET_FEATURE:
719 s3c2410_udc_clear_ep0_opr(base_addr);
720
721 if (crq->bRequestType != USB_RECIP_ENDPOINT)
722 break;
723
724 if (crq->wValue != USB_ENDPOINT_HALT || crq->wLength != 0)
725 break;
726
727 s3c2410_udc_set_halt(&dev->ep[crq->wIndex & 0x7f].ep, 1);
728 s3c2410_udc_set_ep0_de_out(base_addr);
729 return;
730
731 default:
732 s3c2410_udc_clear_ep0_opr(base_addr);
733 break;
734 }
735
736 if (crq->bRequestType & USB_DIR_IN)
737 dev->ep0state = EP0_IN_DATA_PHASE;
738 else
739 dev->ep0state = EP0_OUT_DATA_PHASE;
740
741 ret = dev->driver->setup(&dev->gadget, crq);
742 if (ret < 0) {
743 if (dev->req_config) {
744 dprintk(DEBUG_NORMAL, "config change %02x fail %d?\n",
745 crq->bRequest, ret);
746 return;
747 }
748
749 if (ret == -EOPNOTSUPP)
750 dprintk(DEBUG_NORMAL, "Operation not supported\n");
751 else
752 dprintk(DEBUG_NORMAL,
753 "dev->driver->setup failed. (%d)\n", ret);
754
755 udelay(5);
756 s3c2410_udc_set_ep0_ss(base_addr);
757 s3c2410_udc_set_ep0_de_out(base_addr);
758 dev->ep0state = EP0_IDLE;
759 /* deferred i/o == no response yet */
760 } else if (dev->req_pending) {
761 dprintk(DEBUG_VERBOSE, "dev->req_pending... what now?\n");
762 dev->req_pending=0;
763 }
764
765 dprintk(DEBUG_VERBOSE, "ep0state %s\n", ep0states[dev->ep0state]);
766}
767
768static void s3c2410_udc_handle_ep0(struct s3c2410_udc *dev)
769{
770 u32 ep0csr;
771 struct s3c2410_ep *ep = &dev->ep[0];
772 struct s3c2410_request *req;
773 struct usb_ctrlrequest crq;
774
775 if (list_empty(&ep->queue))
776 req = NULL;
777 else
778 req = list_entry(ep->queue.next, struct s3c2410_request, queue);
779
780 /* We make the assumption that S3C2410_UDC_IN_CSR1_REG equal to
781 * S3C2410_UDC_EP0_CSR_REG when index is zero */
782
783 udc_write(0, S3C2410_UDC_INDEX_REG);
784 ep0csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
785
786 dprintk(DEBUG_NORMAL, "ep0csr %x ep0state %s\n",
787 ep0csr, ep0states[dev->ep0state]);
788
789 /* clear stall status */
790 if (ep0csr & S3C2410_UDC_EP0_CSR_SENTSTL) {
791 s3c2410_udc_nuke(dev, ep, -EPIPE);
792 dprintk(DEBUG_NORMAL, "... clear SENT_STALL ...\n");
793 s3c2410_udc_clear_ep0_sst(base_addr);
794 dev->ep0state = EP0_IDLE;
795 return;
796 }
797
798 /* clear setup end */
799 if (ep0csr & S3C2410_UDC_EP0_CSR_SE) {
800 dprintk(DEBUG_NORMAL, "... serviced SETUP_END ...\n");
801 s3c2410_udc_nuke(dev, ep, 0);
802 s3c2410_udc_clear_ep0_se(base_addr);
803 dev->ep0state = EP0_IDLE;
804 }
805
806 switch (dev->ep0state) {
807 case EP0_IDLE:
808 s3c2410_udc_handle_ep0_idle(dev, ep, &crq, ep0csr);
809 break;
810
811 case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR etc */
812 dprintk(DEBUG_NORMAL, "EP0_IN_DATA_PHASE ... what now?\n");
813 if (!(ep0csr & S3C2410_UDC_EP0_CSR_IPKRDY) && req) {
814 s3c2410_udc_write_fifo(ep, req);
815 }
816 break;
817
818 case EP0_OUT_DATA_PHASE: /* SET_DESCRIPTOR etc */
819 dprintk(DEBUG_NORMAL, "EP0_OUT_DATA_PHASE ... what now?\n");
820 if ((ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY) && req ) {
821 s3c2410_udc_read_fifo(ep,req);
822 }
823 break;
824
825 case EP0_END_XFER:
826 dprintk(DEBUG_NORMAL, "EP0_END_XFER ... what now?\n");
827 dev->ep0state = EP0_IDLE;
828 break;
829
830 case EP0_STALL:
831 dprintk(DEBUG_NORMAL, "EP0_STALL ... what now?\n");
832 dev->ep0state = EP0_IDLE;
833 break;
834 }
835}
836
837/*
838 * handle_ep - Manage I/O endpoints
839 */
840
841static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep)
842{
843 struct s3c2410_request *req;
844 int is_in = ep->bEndpointAddress & USB_DIR_IN;
845 u32 ep_csr1;
846 u32 idx;
847
848 if (likely (!list_empty(&ep->queue)))
849 req = list_entry(ep->queue.next,
850 struct s3c2410_request, queue);
851 else
852 req = NULL;
853
854 idx = ep->bEndpointAddress & 0x7F;
855
856 if (is_in) {
857 udc_write(idx, S3C2410_UDC_INDEX_REG);
858 ep_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG);
859 dprintk(DEBUG_VERBOSE, "ep%01d write csr:%02x %d\n",
860 idx, ep_csr1, req ? 1 : 0);
861
862 if (ep_csr1 & S3C2410_UDC_ICSR1_SENTSTL) {
863 dprintk(DEBUG_VERBOSE, "st\n");
864 udc_write(idx, S3C2410_UDC_INDEX_REG);
865 udc_write(ep_csr1 & ~S3C2410_UDC_ICSR1_SENTSTL,
866 S3C2410_UDC_IN_CSR1_REG);
867 return;
868 }
869
870 if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && req) {
871 s3c2410_udc_write_fifo(ep,req);
872 }
873 } else {
874 udc_write(idx, S3C2410_UDC_INDEX_REG);
875 ep_csr1 = udc_read(S3C2410_UDC_OUT_CSR1_REG);
876 dprintk(DEBUG_VERBOSE, "ep%01d rd csr:%02x\n", idx, ep_csr1);
877
878 if (ep_csr1 & S3C2410_UDC_OCSR1_SENTSTL) {
879 udc_write(idx, S3C2410_UDC_INDEX_REG);
880 udc_write(ep_csr1 & ~S3C2410_UDC_OCSR1_SENTSTL,
881 S3C2410_UDC_OUT_CSR1_REG);
882 return;
883 }
884
885 if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) {
886 s3c2410_udc_read_fifo(ep,req);
887 }
888 }
889}
890
891#include <asm/arch/regs-irq.h>
892
893/*
894 * s3c2410_udc_irq - interrupt handler
895 */
896static irqreturn_t s3c2410_udc_irq(int irq, void *_dev)
897{
898 struct s3c2410_udc *dev = _dev;
899 int usb_status;
900 int usbd_status;
901 int pwr_reg;
902 int ep0csr;
903 int i;
904 u32 idx;
905 unsigned long flags;
906
907 spin_lock_irqsave(&dev->lock, flags);
908
909 /* Driver connected ? */
910 if (!dev->driver) {
911 /* Clear interrupts */
912 udc_write(udc_read(S3C2410_UDC_USB_INT_REG),
913 S3C2410_UDC_USB_INT_REG);
914 udc_write(udc_read(S3C2410_UDC_EP_INT_REG),
915 S3C2410_UDC_EP_INT_REG);
916 }
917
918 /* Save index */
919 idx = udc_read(S3C2410_UDC_INDEX_REG);
920
921 /* Read status registers */
922 usb_status = udc_read(S3C2410_UDC_USB_INT_REG);
923 usbd_status = udc_read(S3C2410_UDC_EP_INT_REG);
924 pwr_reg = udc_read(S3C2410_UDC_PWR_REG);
925
926 udc_writeb(base_addr, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
927 ep0csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
928
929 dprintk(DEBUG_NORMAL, "usbs=%02x, usbds=%02x, pwr=%02x ep0csr=%02x\n",
930 usb_status, usbd_status, pwr_reg, ep0csr);
931
932 /*
933 * Now, handle interrupts. There's two types :
934 * - Reset, Resume, Suspend coming -> usb_int_reg
935 * - EP -> ep_int_reg
936 */
937
938 /* RESET */
939 if (usb_status & S3C2410_UDC_USBINT_RESET) {
940 /* two kind of reset :
941 * - reset start -> pwr reg = 8
942 * - reset end -> pwr reg = 0
943 **/
944 dprintk(DEBUG_NORMAL, "USB reset csr %x pwr %x\n",
945 ep0csr, pwr_reg);
946
947 dev->gadget.speed = USB_SPEED_UNKNOWN;
948 udc_write(0x00, S3C2410_UDC_INDEX_REG);
949 udc_write((dev->ep[0].ep.maxpacket & 0x7ff) >> 3,
950 S3C2410_UDC_MAXP_REG);
951 dev->address = 0;
952
953 dev->ep0state = EP0_IDLE;
954 dev->gadget.speed = USB_SPEED_FULL;
955
956 /* clear interrupt */
957 udc_write(S3C2410_UDC_USBINT_RESET,
958 S3C2410_UDC_USB_INT_REG);
959
960 udc_write(idx, S3C2410_UDC_INDEX_REG);
961 spin_unlock_irqrestore(&dev->lock, flags);
962 return IRQ_HANDLED;
963 }
964
965 /* RESUME */
966 if (usb_status & S3C2410_UDC_USBINT_RESUME) {
967 dprintk(DEBUG_NORMAL, "USB resume\n");
968
969 /* clear interrupt */
970 udc_write(S3C2410_UDC_USBINT_RESUME,
971 S3C2410_UDC_USB_INT_REG);
972
973 if (dev->gadget.speed != USB_SPEED_UNKNOWN
974 && dev->driver
975 && dev->driver->resume)
976 dev->driver->resume(&dev->gadget);
977 }
978
979 /* SUSPEND */
980 if (usb_status & S3C2410_UDC_USBINT_SUSPEND) {
981 dprintk(DEBUG_NORMAL, "USB suspend\n");
982
983 /* clear interrupt */
984 udc_write(S3C2410_UDC_USBINT_SUSPEND,
985 S3C2410_UDC_USB_INT_REG);
986
987 if (dev->gadget.speed != USB_SPEED_UNKNOWN
988 && dev->driver
989 && dev->driver->suspend)
990 dev->driver->suspend(&dev->gadget);
991
992 dev->ep0state = EP0_IDLE;
993 }
994
995 /* EP */
996 /* control traffic */
997 /* check on ep0csr != 0 is not a good idea as clearing in_pkt_ready
998 * generate an interrupt
999 */
1000 if (usbd_status & S3C2410_UDC_INT_EP0) {
1001 dprintk(DEBUG_VERBOSE, "USB ep0 irq\n");
1002 /* Clear the interrupt bit by setting it to 1 */
1003 udc_write(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_REG);
1004 s3c2410_udc_handle_ep0(dev);
1005 }
1006
1007 /* endpoint data transfers */
1008 for (i = 1; i < S3C2410_ENDPOINTS; i++) {
1009 u32 tmp = 1 << i;
1010 if (usbd_status & tmp) {
1011 dprintk(DEBUG_VERBOSE, "USB ep%d irq\n", i);
1012
1013 /* Clear the interrupt bit by setting it to 1 */
1014 udc_write(tmp, S3C2410_UDC_EP_INT_REG);
1015 s3c2410_udc_handle_ep(&dev->ep[i]);
1016 }
1017 }
1018
1019 dprintk(DEBUG_VERBOSE, "irq: %d s3c2410_udc_done.\n", irq);
1020
1021 /* Restore old index */
1022 udc_write(idx, S3C2410_UDC_INDEX_REG);
1023
1024 spin_unlock_irqrestore(&dev->lock, flags);
1025
1026 return IRQ_HANDLED;
1027}
1028/*------------------------- s3c2410_ep_ops ----------------------------------*/
1029
1030static inline struct s3c2410_ep *to_s3c2410_ep(struct usb_ep *ep)
1031{
1032 return container_of(ep, struct s3c2410_ep, ep);
1033}
1034
1035static inline struct s3c2410_udc *to_s3c2410_udc(struct usb_gadget *gadget)
1036{
1037 return container_of(gadget, struct s3c2410_udc, gadget);
1038}
1039
1040static inline struct s3c2410_request *to_s3c2410_req(struct usb_request *req)
1041{
1042 return container_of(req, struct s3c2410_request, req);
1043}
1044
1045/*
1046 * s3c2410_udc_ep_enable
1047 */
1048static int s3c2410_udc_ep_enable(struct usb_ep *_ep,
1049 const struct usb_endpoint_descriptor *desc)
1050{
1051 struct s3c2410_udc *dev;
1052 struct s3c2410_ep *ep;
1053 u32 max, tmp;
1054 unsigned long flags;
1055 u32 csr1,csr2;
1056 u32 int_en_reg;
1057
1058 ep = to_s3c2410_ep(_ep);
1059
1060 if (!_ep || !desc || ep->desc
1061 || _ep->name == ep0name
1062 || desc->bDescriptorType != USB_DT_ENDPOINT)
1063 return -EINVAL;
1064
1065 dev = ep->dev;
1066 if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
1067 return -ESHUTDOWN;
1068
1069 max = le16_to_cpu(desc->wMaxPacketSize) & 0x1fff;
1070
1071 local_irq_save (flags);
1072 _ep->maxpacket = max & 0x7ff;
1073 ep->desc = desc;
1074 ep->halted = 0;
1075 ep->bEndpointAddress = desc->bEndpointAddress;
1076
1077 /* set max packet */
1078 udc_write(ep->num, S3C2410_UDC_INDEX_REG);
1079 udc_write(max >> 3, S3C2410_UDC_MAXP_REG);
1080
1081 /* set type, direction, address; reset fifo counters */
1082 if (desc->bEndpointAddress & USB_DIR_IN) {
1083 csr1 = S3C2410_UDC_ICSR1_FFLUSH|S3C2410_UDC_ICSR1_CLRDT;
1084 csr2 = S3C2410_UDC_ICSR2_MODEIN|S3C2410_UDC_ICSR2_DMAIEN;
1085
1086 udc_write(ep->num, S3C2410_UDC_INDEX_REG);
1087 udc_write(csr1, S3C2410_UDC_IN_CSR1_REG);
1088 udc_write(ep->num, S3C2410_UDC_INDEX_REG);
1089 udc_write(csr2, S3C2410_UDC_IN_CSR2_REG);
1090 } else {
1091 /* don't flush in fifo or it will cause endpoint interrupt */
1092 csr1 = S3C2410_UDC_ICSR1_CLRDT;
1093 csr2 = S3C2410_UDC_ICSR2_DMAIEN;
1094
1095 udc_write(ep->num, S3C2410_UDC_INDEX_REG);
1096 udc_write(csr1, S3C2410_UDC_IN_CSR1_REG);
1097 udc_write(ep->num, S3C2410_UDC_INDEX_REG);
1098 udc_write(csr2, S3C2410_UDC_IN_CSR2_REG);
1099
1100 csr1 = S3C2410_UDC_OCSR1_FFLUSH | S3C2410_UDC_OCSR1_CLRDT;
1101 csr2 = S3C2410_UDC_OCSR2_DMAIEN;
1102
1103 udc_write(ep->num, S3C2410_UDC_INDEX_REG);
1104 udc_write(csr1, S3C2410_UDC_OUT_CSR1_REG);
1105 udc_write(ep->num, S3C2410_UDC_INDEX_REG);
1106 udc_write(csr2, S3C2410_UDC_OUT_CSR2_REG);
1107 }
1108
1109 /* enable irqs */
1110 int_en_reg = udc_read(S3C2410_UDC_EP_INT_EN_REG);
1111 udc_write(int_en_reg | (1 << ep->num), S3C2410_UDC_EP_INT_EN_REG);
1112
1113 /* print some debug message */
1114 tmp = desc->bEndpointAddress;
1115 dprintk (DEBUG_NORMAL, "enable %s(%d) ep%x%s-blk max %02x\n",
1116 _ep->name,ep->num, tmp,
1117 desc->bEndpointAddress & USB_DIR_IN ? "in" : "out", max);
1118
1119 local_irq_restore (flags);
1120 s3c2410_udc_set_halt(_ep, 0);
1121
1122 return 0;
1123}
1124
1125/*
1126 * s3c2410_udc_ep_disable
1127 */
1128static int s3c2410_udc_ep_disable(struct usb_ep *_ep)
1129{
1130 struct s3c2410_ep *ep = to_s3c2410_ep(_ep);
1131 unsigned long flags;
1132 u32 int_en_reg;
1133
1134 if (!_ep || !ep->desc) {
1135 dprintk(DEBUG_NORMAL, "%s not enabled\n",
1136 _ep ? ep->ep.name : NULL);
1137 return -EINVAL;
1138 }
1139
1140 local_irq_save(flags);
1141
1142 dprintk(DEBUG_NORMAL, "ep_disable: %s\n", _ep->name);
1143
1144 ep->desc = NULL;
1145 ep->halted = 1;
1146
1147 s3c2410_udc_nuke (ep->dev, ep, -ESHUTDOWN);
1148
1149 /* disable irqs */
1150 int_en_reg = udc_read(S3C2410_UDC_EP_INT_EN_REG);
1151 udc_write(int_en_reg & ~(1<<ep->num), S3C2410_UDC_EP_INT_EN_REG);
1152
1153 local_irq_restore(flags);
1154
1155 dprintk(DEBUG_NORMAL, "%s disabled\n", _ep->name);
1156
1157 return 0;
1158}
1159
1160/*
1161 * s3c2410_udc_alloc_request
1162 */
1163static struct usb_request *
1164s3c2410_udc_alloc_request(struct usb_ep *_ep, gfp_t mem_flags)
1165{
1166 struct s3c2410_request *req;
1167
1168 dprintk(DEBUG_VERBOSE,"%s(%p,%d)\n", __func__, _ep, mem_flags);
1169
1170 if (!_ep)
1171 return NULL;
1172
1173 req = kzalloc (sizeof(struct s3c2410_request), mem_flags);
1174 if (!req)
1175 return NULL;
1176
1177 INIT_LIST_HEAD (&req->queue);
1178 return &req->req;
1179}
1180
1181/*
1182 * s3c2410_udc_free_request
1183 */
1184static void
1185s3c2410_udc_free_request(struct usb_ep *_ep, struct usb_request *_req)
1186{
1187 struct s3c2410_ep *ep = to_s3c2410_ep(_ep);
1188 struct s3c2410_request *req = to_s3c2410_req(_req);
1189
1190 dprintk(DEBUG_VERBOSE, "%s(%p,%p)\n", __func__, _ep, _req);
1191
1192 if (!ep || !_req || (!ep->desc && _ep->name != ep0name))
1193 return;
1194
1195 WARN_ON (!list_empty (&req->queue));
1196 kfree(req);
1197}
1198
1199/*
1200 * s3c2410_udc_alloc_buffer
1201 */
1202static void *s3c2410_udc_alloc_buffer(struct usb_ep *_ep,
1203 unsigned bytes, dma_addr_t *dma, gfp_t mem_flags)
1204{
1205 char *retval;
1206
1207 dprintk(DEBUG_VERBOSE, "%s()\n", __func__);
1208
1209 if (!the_controller->driver)
1210 return NULL;
1211
1212 retval = kmalloc (bytes, mem_flags);
1213 *dma = (dma_addr_t) retval;
1214 return retval;
1215}
1216
1217/*
1218 * s3c2410_udc_free_buffer
1219 */
1220static void s3c2410_udc_free_buffer (struct usb_ep *_ep, void *buf,
1221 dma_addr_t dma, unsigned bytes)
1222{
1223 dprintk(DEBUG_VERBOSE, "%s()\n", __func__);
1224
1225 if (bytes)
1226 kfree (buf);
1227}
1228
1229/*
1230 * s3c2410_udc_queue
1231 */
1232static int s3c2410_udc_queue(struct usb_ep *_ep, struct usb_request *_req,
1233 gfp_t gfp_flags)
1234{
1235 struct s3c2410_request *req = to_s3c2410_req(_req);
1236 struct s3c2410_ep *ep = to_s3c2410_ep(_ep);
1237 struct s3c2410_udc *dev;
1238 u32 ep_csr = 0;
1239 int fifo_count = 0;
1240 unsigned long flags;
1241
1242 if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
1243 dprintk(DEBUG_NORMAL, "%s: invalid args\n", __func__);
1244 return -EINVAL;
1245 }
1246
1247 dev = ep->dev;
1248 if (unlikely (!dev->driver
1249 || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
1250 return -ESHUTDOWN;
1251 }
1252
1253 local_irq_save (flags);
1254
1255 if (unlikely(!_req || !_req->complete
1256 || !_req->buf || !list_empty(&req->queue))) {
1257 if (!_req)
1258 dprintk(DEBUG_NORMAL, "%s: 1 X X X\n", __func__);
1259 else {
1260 dprintk(DEBUG_NORMAL, "%s: 0 %01d %01d %01d\n",
1261 __func__, !_req->complete,!_req->buf,
1262 !list_empty(&req->queue));
1263 }
1264
1265 local_irq_restore(flags);
1266 return -EINVAL;
1267 }
1268
1269 _req->status = -EINPROGRESS;
1270 _req->actual = 0;
1271
1272 dprintk(DEBUG_VERBOSE, "%s: ep%x len %d\n",
1273 __func__, ep->bEndpointAddress, _req->length);
1274
1275 if (ep->bEndpointAddress) {
1276 udc_write(ep->bEndpointAddress & 0x7F, S3C2410_UDC_INDEX_REG);
1277
1278 ep_csr = udc_read((ep->bEndpointAddress & USB_DIR_IN)
1279 ? S3C2410_UDC_IN_CSR1_REG
1280 : S3C2410_UDC_OUT_CSR1_REG);
1281 fifo_count = s3c2410_udc_fifo_count_out();
1282 } else {
1283 udc_write(0, S3C2410_UDC_INDEX_REG);
1284 ep_csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
1285 fifo_count = s3c2410_udc_fifo_count_out();
1286 }
1287
1288 /* kickstart this i/o queue? */
1289 if (list_empty(&ep->queue) && !ep->halted) {
1290 if (ep->bEndpointAddress == 0 /* ep0 */) {
1291 switch (dev->ep0state) {
1292 case EP0_IN_DATA_PHASE:
1293 if (!(ep_csr&S3C2410_UDC_EP0_CSR_IPKRDY)
1294 && s3c2410_udc_write_fifo(ep,
1295 req)) {
1296 dev->ep0state = EP0_IDLE;
1297 req = NULL;
1298 }
1299 break;
1300
1301 case EP0_OUT_DATA_PHASE:
1302 if ((!_req->length)
1303 || ((ep_csr & S3C2410_UDC_OCSR1_PKTRDY)
1304 && s3c2410_udc_read_fifo(ep,
1305 req))) {
1306 dev->ep0state = EP0_IDLE;
1307 req = NULL;
1308 }
1309 break;
1310
1311 default:
1312 local_irq_restore(flags);
1313 return -EL2HLT;
1314 }
1315 } else if ((ep->bEndpointAddress & USB_DIR_IN) != 0
1316 && (!(ep_csr&S3C2410_UDC_OCSR1_PKTRDY))
1317 && s3c2410_udc_write_fifo(ep, req)) {
1318 req = NULL;
1319 } else if ((ep_csr & S3C2410_UDC_OCSR1_PKTRDY)
1320 && fifo_count
1321 && s3c2410_udc_read_fifo(ep, req)) {
1322 req = NULL;
1323 }
1324 }
1325
1326 /* pio or dma irq handler advances the queue. */
1327 if (likely (req != 0))
1328 list_add_tail(&req->queue, &ep->queue);
1329
1330 local_irq_restore(flags);
1331
1332 dprintk(DEBUG_VERBOSE, "%s ok\n", __func__);
1333 return 0;
1334}
1335
1336/*
1337 * s3c2410_udc_dequeue
1338 */
1339static int s3c2410_udc_dequeue(struct usb_ep *_ep, struct usb_request *_req)
1340{
1341 struct s3c2410_ep *ep = to_s3c2410_ep(_ep);
1342 struct s3c2410_udc *udc;
1343 int retval = -EINVAL;
1344 unsigned long flags;
1345 struct s3c2410_request *req = NULL;
1346
1347 dprintk(DEBUG_VERBOSE, "%s(%p,%p)\n", __func__, _ep, _req);
1348
1349 if (!the_controller->driver)
1350 return -ESHUTDOWN;
1351
1352 if (!_ep || !_req)
1353 return retval;
1354
1355 udc = to_s3c2410_udc(ep->gadget);
1356
1357 local_irq_save (flags);
1358
1359 list_for_each_entry (req, &ep->queue, queue) {
1360 if (&req->req == _req) {
1361 list_del_init (&req->queue);
1362 _req->status = -ECONNRESET;
1363 retval = 0;
1364 break;
1365 }
1366 }
1367
1368 if (retval == 0) {
1369 dprintk(DEBUG_VERBOSE,
1370 "dequeued req %p from %s, len %d buf %p\n",
1371 req, _ep->name, _req->length, _req->buf);
1372
1373 s3c2410_udc_done(ep, req, -ECONNRESET);
1374 }
1375
1376 local_irq_restore (flags);
1377 return retval;
1378}
1379
1380/*
1381 * s3c2410_udc_set_halt
1382 */
1383static int s3c2410_udc_set_halt(struct usb_ep *_ep, int value)
1384{
1385 struct s3c2410_ep *ep = to_s3c2410_ep(_ep);
1386 u32 ep_csr = 0;
1387 unsigned long flags;
1388 u32 idx;
1389
1390 if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
1391 dprintk(DEBUG_NORMAL, "%s: inval 2\n", __func__);
1392 return -EINVAL;
1393 }
1394
1395 local_irq_save (flags);
1396
1397 idx = ep->bEndpointAddress & 0x7F;
1398
1399 if (idx == 0) {
1400 s3c2410_udc_set_ep0_ss(base_addr);
1401 s3c2410_udc_set_ep0_de_out(base_addr);
1402 } else {
1403 udc_write(idx, S3C2410_UDC_INDEX_REG);
1404 ep_csr = udc_read((ep->bEndpointAddress &USB_DIR_IN)
1405 ? S3C2410_UDC_IN_CSR1_REG
1406 : S3C2410_UDC_OUT_CSR1_REG);
1407
1408 if ((ep->bEndpointAddress & USB_DIR_IN) != 0) {
1409 if (value)
1410 udc_write(ep_csr | S3C2410_UDC_ICSR1_SENDSTL,
1411 S3C2410_UDC_IN_CSR1_REG);
1412 else {
1413 ep_csr &= ~S3C2410_UDC_ICSR1_SENDSTL;
1414 udc_write(ep_csr, S3C2410_UDC_IN_CSR1_REG);
1415 ep_csr |= S3C2410_UDC_ICSR1_CLRDT;
1416 udc_write(ep_csr, S3C2410_UDC_IN_CSR1_REG);
1417 }
1418 } else {
1419 if (value)
1420 udc_write(ep_csr | S3C2410_UDC_OCSR1_SENDSTL,
1421 S3C2410_UDC_OUT_CSR1_REG);
1422 else {
1423 ep_csr &= ~S3C2410_UDC_OCSR1_SENDSTL;
1424 udc_write(ep_csr, S3C2410_UDC_OUT_CSR1_REG);
1425 ep_csr |= S3C2410_UDC_OCSR1_CLRDT;
1426 udc_write(ep_csr, S3C2410_UDC_OUT_CSR1_REG);
1427 }
1428 }
1429 }
1430
1431 ep->halted = value ? 1 : 0;
1432 local_irq_restore (flags);
1433
1434 return 0;
1435}
1436
1437static const struct usb_ep_ops s3c2410_ep_ops = {
1438 .enable = s3c2410_udc_ep_enable,
1439 .disable = s3c2410_udc_ep_disable,
1440
1441 .alloc_request = s3c2410_udc_alloc_request,
1442 .free_request = s3c2410_udc_free_request,
1443
1444 .alloc_buffer = s3c2410_udc_alloc_buffer,
1445 .free_buffer = s3c2410_udc_free_buffer,
1446
1447 .queue = s3c2410_udc_queue,
1448 .dequeue = s3c2410_udc_dequeue,
1449
1450 .set_halt = s3c2410_udc_set_halt,
1451};
1452
1453/*------------------------- usb_gadget_ops ----------------------------------*/
1454
1455/*
1456 * s3c2410_udc_get_frame
1457 */
1458static int s3c2410_udc_get_frame(struct usb_gadget *_gadget)
1459{
1460 int tmp;
1461
1462 dprintk(DEBUG_VERBOSE, "%s()\n", __func__);
1463
1464 tmp = udc_read(S3C2410_UDC_FRAME_NUM2_REG) << 8;
1465 tmp |= udc_read(S3C2410_UDC_FRAME_NUM1_REG);
1466 return tmp;
1467}
1468
1469/*
1470 * s3c2410_udc_wakeup
1471 */
1472static int s3c2410_udc_wakeup(struct usb_gadget *_gadget)
1473{
1474 dprintk(DEBUG_NORMAL, "%s()\n", __func__);
1475 return 0;
1476}
1477
1478/*
1479 * s3c2410_udc_set_selfpowered
1480 */
1481static int s3c2410_udc_set_selfpowered(struct usb_gadget *gadget, int value)
1482{
1483 struct s3c2410_udc *udc = to_s3c2410_udc(gadget);
1484
1485 dprintk(DEBUG_NORMAL, "%s()\n", __func__);
1486
1487 if (value)
1488 udc->devstatus |= (1 << USB_DEVICE_SELF_POWERED);
1489 else
1490 udc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED);
1491
1492 return 0;
1493}
1494
1495static void s3c2410_udc_disable(struct s3c2410_udc *dev);
1496static void s3c2410_udc_enable(struct s3c2410_udc *dev);
1497
1498static int s3c2410_udc_set_pullup(struct s3c2410_udc *udc, int is_on)
1499{
1500 dprintk(DEBUG_NORMAL, "%s()\n", __func__);
1501
1502 if (udc_info && udc_info->udc_command) {
1503 if (is_on)
1504 s3c2410_udc_enable(udc);
1505 else {
1506 if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
1507 if (udc->driver && udc->driver->disconnect)
1508 udc->driver->disconnect(&udc->gadget);
1509
1510 }
1511 s3c2410_udc_disable(udc);
1512 }
1513 }
1514 else
1515 return -EOPNOTSUPP;
1516
1517 return 0;
1518}
1519
1520static int s3c2410_udc_vbus_session(struct usb_gadget *gadget, int is_active)
1521{
1522 struct s3c2410_udc *udc = to_s3c2410_udc(gadget);
1523
1524 dprintk(DEBUG_NORMAL, "%s()\n", __func__);
1525
1526 udc->vbus = (is_active != 0);
1527 s3c2410_udc_set_pullup(udc, is_active);
1528 return 0;
1529}
1530
1531static int s3c2410_udc_pullup(struct usb_gadget *gadget, int is_on)
1532{
1533 struct s3c2410_udc *udc = to_s3c2410_udc(gadget);
1534
1535 dprintk(DEBUG_NORMAL, "%s()\n", __func__);
1536
1537 s3c2410_udc_set_pullup(udc, is_on ? 0 : 1);
1538 return 0;
1539}
1540
1541static irqreturn_t s3c2410_udc_vbus_irq(int irq, void *_dev)
1542{
1543 struct s3c2410_udc *dev = _dev;
1544 unsigned int value;
1545
1546 dprintk(DEBUG_NORMAL, "%s()\n", __func__);
1547 value = s3c2410_gpio_getpin(udc_info->vbus_pin);
1548
1549 if (udc_info->vbus_pin_inverted)
1550 value = !value;
1551
1552 if (value != dev->vbus)
1553 s3c2410_udc_vbus_session(&dev->gadget, value);
1554
1555 return IRQ_HANDLED;
1556}
1557
1558static int s3c2410_vbus_draw(struct usb_gadget *_gadget, unsigned ma)
1559{
1560 dprintk(DEBUG_NORMAL, "%s()\n", __func__);
1561
1562 if (udc_info && udc_info->vbus_draw) {
1563 udc_info->vbus_draw(ma);
1564 return 0;
1565 }
1566
1567 return -ENOTSUPP;
1568}
1569
1570static const struct usb_gadget_ops s3c2410_ops = {
1571 .get_frame = s3c2410_udc_get_frame,
1572 .wakeup = s3c2410_udc_wakeup,
1573 .set_selfpowered = s3c2410_udc_set_selfpowered,
1574 .pullup = s3c2410_udc_pullup,
1575 .vbus_session = s3c2410_udc_vbus_session,
1576 .vbus_draw = s3c2410_vbus_draw,
1577};
1578
1579/*------------------------- gadget driver handling---------------------------*/
1580/*
1581 * s3c2410_udc_disable
1582 */
1583static void s3c2410_udc_disable(struct s3c2410_udc *dev)
1584{
1585 dprintk(DEBUG_NORMAL, "%s()\n", __func__);
1586
1587 /* Disable all interrupts */
1588 udc_write(0x00, S3C2410_UDC_USB_INT_EN_REG);
1589 udc_write(0x00, S3C2410_UDC_EP_INT_EN_REG);
1590
1591 /* Clear the interrupt registers */
1592 udc_write(S3C2410_UDC_USBINT_RESET
1593 | S3C2410_UDC_USBINT_RESUME
1594 | S3C2410_UDC_USBINT_SUSPEND,
1595 S3C2410_UDC_USB_INT_REG);
1596
1597 udc_write(0x1F, S3C2410_UDC_EP_INT_REG);
1598
1599 /* Good bye, cruel world */
1600 if (udc_info && udc_info->udc_command)
1601 udc_info->udc_command(S3C2410_UDC_P_DISABLE);
1602
1603 /* Set speed to unknown */
1604 dev->gadget.speed = USB_SPEED_UNKNOWN;
1605}
1606
1607/*
1608 * s3c2410_udc_reinit
1609 */
1610static void s3c2410_udc_reinit(struct s3c2410_udc *dev)
1611{
1612 u32 i;
1613
1614 /* device/ep0 records init */
1615 INIT_LIST_HEAD (&dev->gadget.ep_list);
1616 INIT_LIST_HEAD (&dev->gadget.ep0->ep_list);
1617 dev->ep0state = EP0_IDLE;
1618
1619 for (i = 0; i < S3C2410_ENDPOINTS; i++) {
1620 struct s3c2410_ep *ep = &dev->ep[i];
1621
1622 if (i != 0)
1623 list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list);
1624
1625 ep->dev = dev;
1626 ep->desc = NULL;
1627 ep->halted = 0;
1628 INIT_LIST_HEAD (&ep->queue);
1629 }
1630}
1631
1632/*
1633 * s3c2410_udc_enable
1634 */
1635static void s3c2410_udc_enable(struct s3c2410_udc *dev)
1636{
1637 int i;
1638
1639 dprintk(DEBUG_NORMAL, "s3c2410_udc_enable called\n");
1640
1641 /* dev->gadget.speed = USB_SPEED_UNKNOWN; */
1642 dev->gadget.speed = USB_SPEED_FULL;
1643
1644 /* Set MAXP for all endpoints */
1645 for (i = 0; i < S3C2410_ENDPOINTS; i++) {
1646 udc_write(i, S3C2410_UDC_INDEX_REG);
1647 udc_write((dev->ep[i].ep.maxpacket & 0x7ff) >> 3,
1648 S3C2410_UDC_MAXP_REG);
1649 }
1650
1651 /* Set default power state */
1652 udc_write(DEFAULT_POWER_STATE, S3C2410_UDC_PWR_REG);
1653
1654 /* Enable reset and suspend interrupt interrupts */
1655 udc_write(S3C2410_UDC_USBINT_RESET | S3C2410_UDC_USBINT_SUSPEND,
1656 S3C2410_UDC_USB_INT_EN_REG);
1657
1658 /* Enable ep0 interrupt */
1659 udc_write(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_EN_REG);
1660
1661 /* time to say "hello, world" */
1662 if (udc_info && udc_info->udc_command)
1663 udc_info->udc_command(S3C2410_UDC_P_ENABLE);
1664}
1665
1666/*
1667 * usb_gadget_register_driver
1668 */
1669int usb_gadget_register_driver(struct usb_gadget_driver *driver)
1670{
1671 struct s3c2410_udc *udc = the_controller;
1672 int retval;
1673
1674 dprintk(DEBUG_NORMAL, "usb_gadget_register_driver() '%s'\n",
1675 driver->driver.name);
1676
1677 /* Sanity checks */
1678 if (!udc)
1679 return -ENODEV;
1680
1681 if (udc->driver)
1682 return -EBUSY;
1683
1684 if (!driver->bind || !driver->setup
1685 || driver->speed != USB_SPEED_FULL) {
1686 printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n",
1687 driver->bind, driver->setup, driver->speed);
1688 return -EINVAL;
1689 }
1690#if defined(MODULE)
1691 if (!driver->unbind) {
1692 printk(KERN_ERR "Invalid driver: no unbind method\n");
1693 return -EINVAL;
1694 }
1695#endif
1696
1697 /* Hook the driver */
1698 udc->driver = driver;
1699 udc->gadget.dev.driver = &driver->driver;
1700
1701 /* Bind the driver */
1702 if ((retval = device_add(&udc->gadget.dev)) != 0) {
1703 printk(KERN_ERR "Error in device_add() : %d\n",retval);
1704 goto register_error;
1705 }
1706
1707 dprintk(DEBUG_NORMAL, "binding gadget driver '%s'\n",
1708 driver->driver.name);
1709
1710 if ((retval = driver->bind (&udc->gadget)) != 0) {
1711 device_del(&udc->gadget.dev);
1712 goto register_error;
1713 }
1714
1715 /* Enable udc */
1716 s3c2410_udc_enable(udc);
1717
1718 return 0;
1719
1720register_error:
1721 udc->driver = NULL;
1722 udc->gadget.dev.driver = NULL;
1723 return retval;
1724}
1725
1726/*
1727 * usb_gadget_unregister_driver
1728 */
1729int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1730{
1731 struct s3c2410_udc *udc = the_controller;
1732
1733 if (!udc)
1734 return -ENODEV;
1735
1736 if (!driver || driver != udc->driver || !driver->unbind)
1737 return -EINVAL;
1738
1739 dprintk(DEBUG_NORMAL,"usb_gadget_register_driver() '%s'\n",
1740 driver->driver.name);
1741
1742 if (driver->disconnect)
1743 driver->disconnect(&udc->gadget);
1744
1745 device_del(&udc->gadget.dev);
1746 udc->driver = NULL;
1747
1748 /* Disable udc */
1749 s3c2410_udc_disable(udc);
1750
1751 return 0;
1752}
1753
1754/*---------------------------------------------------------------------------*/
1755static struct s3c2410_udc memory = {
1756 .gadget = {
1757 .ops = &s3c2410_ops,
1758 .ep0 = &memory.ep[0].ep,
1759 .name = gadget_name,
1760 .dev = {
1761 .bus_id = "gadget",
1762 },
1763 },
1764
1765 /* control endpoint */
1766 .ep[0] = {
1767 .num = 0,
1768 .ep = {
1769 .name = ep0name,
1770 .ops = &s3c2410_ep_ops,
1771 .maxpacket = EP0_FIFO_SIZE,
1772 },
1773 .dev = &memory,
1774 },
1775
1776 /* first group of endpoints */
1777 .ep[1] = {
1778 .num = 1,
1779 .ep = {
1780 .name = "ep1-bulk",
1781 .ops = &s3c2410_ep_ops,
1782 .maxpacket = EP_FIFO_SIZE,
1783 },
1784 .dev = &memory,
1785 .fifo_size = EP_FIFO_SIZE,
1786 .bEndpointAddress = 1,
1787 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1788 },
1789 .ep[2] = {
1790 .num = 2,
1791 .ep = {
1792 .name = "ep2-bulk",
1793 .ops = &s3c2410_ep_ops,
1794 .maxpacket = EP_FIFO_SIZE,
1795 },
1796 .dev = &memory,
1797 .fifo_size = EP_FIFO_SIZE,
1798 .bEndpointAddress = 2,
1799 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1800 },
1801 .ep[3] = {
1802 .num = 3,
1803 .ep = {
1804 .name = "ep3-bulk",
1805 .ops = &s3c2410_ep_ops,
1806 .maxpacket = EP_FIFO_SIZE,
1807 },
1808 .dev = &memory,
1809 .fifo_size = EP_FIFO_SIZE,
1810 .bEndpointAddress = 3,
1811 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1812 },
1813 .ep[4] = {
1814 .num = 4,
1815 .ep = {
1816 .name = "ep4-bulk",
1817 .ops = &s3c2410_ep_ops,
1818 .maxpacket = EP_FIFO_SIZE,
1819 },
1820 .dev = &memory,
1821 .fifo_size = EP_FIFO_SIZE,
1822 .bEndpointAddress = 4,
1823 .bmAttributes = USB_ENDPOINT_XFER_BULK,
1824 }
1825
1826};
1827
1828/*
1829 * probe - binds to the platform device
1830 */
1831static int s3c2410_udc_probe(struct platform_device *pdev)
1832{
1833 struct s3c2410_udc *udc = &memory;
1834 struct device *dev = &pdev->dev;
1835 int retval;
1836 unsigned int irq;
1837
1838 dev_dbg(dev, "%s()\n", __func__);
1839
1840 usb_bus_clock = clk_get(NULL, "usb-bus-gadget");
1841 if (IS_ERR(usb_bus_clock)) {
1842 dev_err(dev, "failed to get usb bus clock source\n");
1843 return PTR_ERR(usb_bus_clock);
1844 }
1845
1846 clk_enable(usb_bus_clock);
1847
1848 udc_clock = clk_get(NULL, "usb-device");
1849 if (IS_ERR(udc_clock)) {
1850 dev_err(dev, "failed to get udc clock source\n");
1851 return PTR_ERR(udc_clock);
1852 }
1853
1854 clk_enable(udc_clock);
1855
1856 mdelay(10);
1857
1858 dev_dbg(dev, "got and enabled clocks\n");
1859
1860 if (strncmp(pdev->name, "s3c2440", 7) == 0) {
1861 dev_info(dev, "S3C2440: increasing FIFO to 128 bytes\n");
1862 memory.ep[1].fifo_size = S3C2440_EP_FIFO_SIZE;
1863 memory.ep[2].fifo_size = S3C2440_EP_FIFO_SIZE;
1864 memory.ep[3].fifo_size = S3C2440_EP_FIFO_SIZE;
1865 memory.ep[4].fifo_size = S3C2440_EP_FIFO_SIZE;
1866 }
1867
1868 spin_lock_init (&udc->lock);
1869 udc_info = pdev->dev.platform_data;
1870
1871 rsrc_start = S3C2410_PA_USBDEV;
1872 rsrc_len = S3C24XX_SZ_USBDEV;
1873
1874 if (!request_mem_region(rsrc_start, rsrc_len, gadget_name))
1875 return -EBUSY;
1876
1877 base_addr = ioremap(rsrc_start, rsrc_len);
1878 if (!base_addr) {
1879 retval = -ENOMEM;
1880 goto err_mem;
1881 }
1882
1883 device_initialize(&udc->gadget.dev);
1884 udc->gadget.dev.parent = &pdev->dev;
1885 udc->gadget.dev.dma_mask = pdev->dev.dma_mask;
1886
1887 the_controller = udc;
1888 platform_set_drvdata(pdev, udc);
1889
1890 s3c2410_udc_disable(udc);
1891 s3c2410_udc_reinit(udc);
1892
1893 /* irq setup after old hardware state is cleaned up */
1894 retval = request_irq(IRQ_USBD, s3c2410_udc_irq,
1895 IRQF_DISABLED, gadget_name, udc);
1896
1897 if (retval != 0) {
1898 dev_err(dev, "cannot get irq %i, err %d\n", IRQ_USBD, retval);
1899 retval = -EBUSY;
1900 goto err_map;
1901 }
1902
1903 dev_dbg(dev, "got irq %i\n", IRQ_USBD);
1904
1905 if (udc_info && udc_info->vbus_pin > 0) {
1906 irq = s3c2410_gpio_getirq(udc_info->vbus_pin);
1907 retval = request_irq(irq, s3c2410_udc_vbus_irq,
1908 IRQF_DISABLED | IRQF_TRIGGER_RISING
1909 | IRQF_TRIGGER_FALLING,
1910 gadget_name, udc);
1911
1912 if (retval != 0) {
1913 dev_err(dev, "can't get vbus irq %i, err %d\n",
1914 irq, retval);
1915 retval = -EBUSY;
1916 goto err_int;
1917 }
1918
1919 dev_dbg(dev, "got irq %i\n", irq);
1920 } else {
1921 udc->vbus = 1;
1922 }
1923
1924 if (s3c2410_udc_debugfs_root) {
1925 udc->regs_info = debugfs_create_file("registers", S_IRUGO,
1926 s3c2410_udc_debugfs_root,
1927 udc, &s3c2410_udc_debugfs_fops);
1928 if (IS_ERR(udc->regs_info)) {
1929 dev_warn(dev, "debugfs file creation failed %ld\n",
1930 PTR_ERR(udc->regs_info));
1931 udc->regs_info = NULL;
1932 }
1933 }
1934
1935 dev_dbg(dev, "probe ok\n");
1936
1937 return 0;
1938
1939err_int:
1940 free_irq(IRQ_USBD, udc);
1941err_map:
1942 iounmap(base_addr);
1943err_mem:
1944 release_mem_region(rsrc_start, rsrc_len);
1945
1946 return retval;
1947}
1948
1949/*
1950 * s3c2410_udc_remove
1951 */
1952static int s3c2410_udc_remove(struct platform_device *pdev)
1953{
1954 struct s3c2410_udc *udc = platform_get_drvdata(pdev);
1955 unsigned int irq;
1956
1957 dev_dbg(&pdev->dev, "%s()\n", __func__);
1958 if (udc->driver)
1959 return -EBUSY;
1960
1961 debugfs_remove(udc->regs_info);
1962
1963 if (udc_info && udc_info->vbus_pin > 0) {
1964 irq = s3c2410_gpio_getirq(udc_info->vbus_pin);
1965 free_irq(irq, udc);
1966 }
1967
1968 free_irq(IRQ_USBD, udc);
1969
1970 iounmap(base_addr);
1971 release_mem_region(rsrc_start, rsrc_len);
1972
1973 platform_set_drvdata(pdev, NULL);
1974
1975 if (!IS_ERR(udc_clock) && udc_clock != NULL) {
1976 clk_disable(udc_clock);
1977 clk_put(udc_clock);
1978 udc_clock = NULL;
1979 }
1980
1981 if (!IS_ERR(usb_bus_clock) && usb_bus_clock != NULL) {
1982 clk_disable(usb_bus_clock);
1983 clk_put(usb_bus_clock);
1984 usb_bus_clock = NULL;
1985 }
1986
1987 dev_dbg(&pdev->dev, "%s: remove ok\n", __func__);
1988 return 0;
1989}
1990
1991#ifdef CONFIG_PM
1992static int s3c2410_udc_suspend(struct platform_device *pdev, pm_message_t message)
1993{
1994 if (udc_info && udc_info->udc_command)
1995 udc_info->udc_command(S3C2410_UDC_P_DISABLE);
1996
1997 return 0;
1998}
1999
2000static int s3c2410_udc_resume(struct platform_device *pdev)
2001{
2002 if (udc_info && udc_info->udc_command)
2003 udc_info->udc_command(S3C2410_UDC_P_ENABLE);
2004
2005 return 0;
2006}
2007#else
2008#define s3c2410_udc_suspend NULL
2009#define s3c2410_udc_resume NULL
2010#endif
2011
2012static struct platform_driver udc_driver_2410 = {
2013 .driver = {
2014 .name = "s3c2410-usbgadget",
2015 .owner = THIS_MODULE,
2016 },
2017 .probe = s3c2410_udc_probe,
2018 .remove = s3c2410_udc_remove,
2019 .suspend = s3c2410_udc_suspend,
2020 .resume = s3c2410_udc_resume,
2021};
2022
2023static struct platform_driver udc_driver_2440 = {
2024 .driver = {
2025 .name = "s3c2440-usbgadget",
2026 .owner = THIS_MODULE,
2027 },
2028 .probe = s3c2410_udc_probe,
2029 .remove = s3c2410_udc_remove,
2030 .suspend = s3c2410_udc_suspend,
2031 .resume = s3c2410_udc_resume,
2032};
2033
2034static int __init udc_init(void)
2035{
2036 int retval;
2037
2038 dprintk(DEBUG_NORMAL, "%s: version %s\n", gadget_name, DRIVER_VERSION);
2039
2040 s3c2410_udc_debugfs_root = debugfs_create_dir(gadget_name, NULL);
2041 if (IS_ERR(s3c2410_udc_debugfs_root)) {
2042 printk(KERN_ERR "%s: debugfs dir creation failed %ld\n",
2043 gadget_name, PTR_ERR(s3c2410_udc_debugfs_root));
2044 s3c2410_udc_debugfs_root = NULL;
2045 }
2046
2047 retval = platform_driver_register(&udc_driver_2410);
2048 if (retval)
2049 goto err;
2050
2051 retval = platform_driver_register(&udc_driver_2440);
2052 if (retval)
2053 goto err;
2054
2055 return 0;
2056
2057err:
2058 debugfs_remove(s3c2410_udc_debugfs_root);
2059 return retval;
2060}
2061
2062static void __exit udc_exit(void)
2063{
2064 platform_driver_unregister(&udc_driver_2410);
2065 platform_driver_unregister(&udc_driver_2440);
2066 debugfs_remove(s3c2410_udc_debugfs_root);
2067}
2068
2069EXPORT_SYMBOL(usb_gadget_unregister_driver);
2070EXPORT_SYMBOL(usb_gadget_register_driver);
2071
2072module_init(udc_init);
2073module_exit(udc_exit);
2074
2075MODULE_AUTHOR(DRIVER_AUTHOR);
2076MODULE_DESCRIPTION(DRIVER_DESC);
2077MODULE_VERSION(DRIVER_VERSION);
2078MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/s3c2410_udc.h b/drivers/usb/gadget/s3c2410_udc.h
new file mode 100644
index 000000000000..9e0bece4f241
--- /dev/null
+++ b/drivers/usb/gadget/s3c2410_udc.h
@@ -0,0 +1,110 @@
1/*
2 * linux/drivers/usb/gadget/s3c2410_udc.h
3 * Samsung on-chip full speed USB device controllers
4 *
5 * Copyright (C) 2004-2007 Herbert Pötzl - Arnaud Patard
6 * Additional cleanups by Ben Dooks <ben-linux@fluff.org>
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
24#ifndef _S3C2410_UDC_H
25#define _S3C2410_UDC_H
26
27struct s3c2410_ep {
28 struct list_head queue;
29 unsigned long last_io; /* jiffies timestamp */
30 struct usb_gadget *gadget;
31 struct s3c2410_udc *dev;
32 const struct usb_endpoint_descriptor *desc;
33 struct usb_ep ep;
34 u8 num;
35
36 unsigned short fifo_size;
37 u8 bEndpointAddress;
38 u8 bmAttributes;
39
40 unsigned halted : 1;
41 unsigned already_seen : 1;
42 unsigned setup_stage : 1;
43};
44
45
46/* Warning : ep0 has a fifo of 16 bytes */
47/* Don't try to set 32 or 64 */
48/* also testusb 14 fails wit 16 but is */
49/* fine with 8 */
50#define EP0_FIFO_SIZE 8
51#define EP_FIFO_SIZE 64
52#define DEFAULT_POWER_STATE 0x00
53
54#define S3C2440_EP_FIFO_SIZE 128
55
56static const char ep0name [] = "ep0";
57
58static const char *const ep_name[] = {
59 ep0name, /* everyone has ep0 */
60 /* s3c2410 four bidirectional bulk endpoints */
61 "ep1-bulk", "ep2-bulk", "ep3-bulk", "ep4-bulk",
62};
63
64#define S3C2410_ENDPOINTS ARRAY_SIZE(ep_name)
65
66struct s3c2410_request {
67 struct list_head queue; /* ep's requests */
68 struct usb_request req;
69};
70
71enum ep0_state {
72 EP0_IDLE,
73 EP0_IN_DATA_PHASE,
74 EP0_OUT_DATA_PHASE,
75 EP0_END_XFER,
76 EP0_STALL,
77};
78
79static const char *ep0states[]= {
80 "EP0_IDLE",
81 "EP0_IN_DATA_PHASE",
82 "EP0_OUT_DATA_PHASE",
83 "EP0_END_XFER",
84 "EP0_STALL",
85};
86
87struct s3c2410_udc {
88 spinlock_t lock;
89
90 struct s3c2410_ep ep[S3C2410_ENDPOINTS];
91 int address;
92 struct usb_gadget gadget;
93 struct usb_gadget_driver *driver;
94 struct s3c2410_request fifo_req;
95 u8 fifo_buf[EP_FIFO_SIZE];
96 u16 devstatus;
97
98 u32 port_status;
99 int ep0state;
100
101 unsigned got_irq : 1;
102
103 unsigned req_std : 1;
104 unsigned req_config : 1;
105 unsigned req_pending : 1;
106 u8 vbus;
107 struct dentry *regs_info;
108};
109
110#endif