1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/spinlock.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/dma-mapping.h>
20#include <linux/delay.h>
21#include <linux/io.h>
22#include <linux/slab.h>
23#include <linux/clk.h>
24#include <linux/err.h>
25#include <linux/usb/ch9.h>
26#include <linux/usb/gadget.h>
27#include <linux/usb/otg.h>
28#include <linux/prefetch.h>
29#include <linux/platform_data/s3c-hsudc.h>
30#include <linux/regulator/consumer.h>
31#include <linux/pm_runtime.h>
32
33#include <mach/regs-s3c2443-clock.h>
34
35#define S3C_HSUDC_REG(x) (x)
36
37
38#define S3C_IR S3C_HSUDC_REG(0x00)
39#define S3C_EIR S3C_HSUDC_REG(0x04)
40#define S3C_EIR_EP0 (1<<0)
41#define S3C_EIER S3C_HSUDC_REG(0x08)
42#define S3C_FAR S3C_HSUDC_REG(0x0c)
43#define S3C_FNR S3C_HSUDC_REG(0x10)
44#define S3C_EDR S3C_HSUDC_REG(0x14)
45#define S3C_TR S3C_HSUDC_REG(0x18)
46#define S3C_SSR S3C_HSUDC_REG(0x1c)
47#define S3C_SSR_DTZIEN_EN (0xff8f)
48#define S3C_SSR_ERR (0xff80)
49#define S3C_SSR_VBUSON (1 << 8)
50#define S3C_SSR_HSP (1 << 4)
51#define S3C_SSR_SDE (1 << 3)
52#define S3C_SSR_RESUME (1 << 2)
53#define S3C_SSR_SUSPEND (1 << 1)
54#define S3C_SSR_RESET (1 << 0)
55#define S3C_SCR S3C_HSUDC_REG(0x20)
56#define S3C_SCR_DTZIEN_EN (1 << 14)
57#define S3C_SCR_RRD_EN (1 << 5)
58#define S3C_SCR_SUS_EN (1 << 1)
59#define S3C_SCR_RST_EN (1 << 0)
60#define S3C_EP0SR S3C_HSUDC_REG(0x24)
61#define S3C_EP0SR_EP0_LWO (1 << 6)
62#define S3C_EP0SR_STALL (1 << 4)
63#define S3C_EP0SR_TX_SUCCESS (1 << 1)
64#define S3C_EP0SR_RX_SUCCESS (1 << 0)
65#define S3C_EP0CR S3C_HSUDC_REG(0x28)
66#define S3C_BR(_x) S3C_HSUDC_REG(0x60 + (_x * 4))
67
68
69#define S3C_ESR S3C_HSUDC_REG(0x2c)
70#define S3C_ESR_FLUSH (1 << 6)
71#define S3C_ESR_STALL (1 << 5)
72#define S3C_ESR_LWO (1 << 4)
73#define S3C_ESR_PSIF_ONE (1 << 2)
74#define S3C_ESR_PSIF_TWO (2 << 2)
75#define S3C_ESR_TX_SUCCESS (1 << 1)
76#define S3C_ESR_RX_SUCCESS (1 << 0)
77#define S3C_ECR S3C_HSUDC_REG(0x30)
78#define S3C_ECR_DUEN (1 << 7)
79#define S3C_ECR_FLUSH (1 << 6)
80#define S3C_ECR_STALL (1 << 1)
81#define S3C_ECR_IEMS (1 << 0)
82#define S3C_BRCR S3C_HSUDC_REG(0x34)
83#define S3C_BWCR S3C_HSUDC_REG(0x38)
84#define S3C_MPR S3C_HSUDC_REG(0x3c)
85
86#define WAIT_FOR_SETUP (0)
87#define DATA_STATE_XMIT (1)
88#define DATA_STATE_RECV (2)
89
90static const char * const s3c_hsudc_supply_names[] = {
91 "vdda",
92 "vddi",
93 "vddosc",
94};
95
96
97
98
99
100
101
102
103
104
105
106
107struct s3c_hsudc_ep {
108 struct usb_ep ep;
109 char name[20];
110 struct s3c_hsudc *dev;
111 struct list_head queue;
112 u8 stopped;
113 u8 wedge;
114 u8 bEndpointAddress;
115 void __iomem *fifo;
116};
117
118
119
120
121
122
123struct s3c_hsudc_req {
124 struct usb_request req;
125 struct list_head queue;
126};
127
128
129
130
131
132
133
134
135
136
137
138
139
140struct s3c_hsudc {
141 struct usb_gadget gadget;
142 struct usb_gadget_driver *driver;
143 struct device *dev;
144 struct s3c24xx_hsudc_platdata *pd;
145 struct usb_phy *transceiver;
146 struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsudc_supply_names)];
147 spinlock_t lock;
148 void __iomem *regs;
149 int irq;
150 struct clk *uclk;
151 int ep0state;
152 struct s3c_hsudc_ep ep[];
153};
154
155#define ep_maxpacket(_ep) ((_ep)->ep.maxpacket)
156#define ep_is_in(_ep) ((_ep)->bEndpointAddress & USB_DIR_IN)
157#define ep_index(_ep) ((_ep)->bEndpointAddress & \
158 USB_ENDPOINT_NUMBER_MASK)
159
160static const char driver_name[] = "s3c-udc";
161static const char ep0name[] = "ep0-control";
162
163static inline struct s3c_hsudc_req *our_req(struct usb_request *req)
164{
165 return container_of(req, struct s3c_hsudc_req, req);
166}
167
168static inline struct s3c_hsudc_ep *our_ep(struct usb_ep *ep)
169{
170 return container_of(ep, struct s3c_hsudc_ep, ep);
171}
172
173static inline struct s3c_hsudc *to_hsudc(struct usb_gadget *gadget)
174{
175 return container_of(gadget, struct s3c_hsudc, gadget);
176}
177
178static inline void set_index(struct s3c_hsudc *hsudc, int ep_addr)
179{
180 ep_addr &= USB_ENDPOINT_NUMBER_MASK;
181 writel(ep_addr, hsudc->regs + S3C_IR);
182}
183
184static inline void __orr32(void __iomem *ptr, u32 val)
185{
186 writel(readl(ptr) | val, ptr);
187}
188
189static void s3c_hsudc_init_phy(void)
190{
191 u32 cfg;
192
193 cfg = readl(S3C2443_PWRCFG) | S3C2443_PWRCFG_USBPHY;
194 writel(cfg, S3C2443_PWRCFG);
195
196 cfg = readl(S3C2443_URSTCON);
197 cfg |= (S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST);
198 writel(cfg, S3C2443_URSTCON);
199 mdelay(1);
200
201 cfg = readl(S3C2443_URSTCON);
202 cfg &= ~(S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST);
203 writel(cfg, S3C2443_URSTCON);
204
205 cfg = readl(S3C2443_PHYCTRL);
206 cfg &= ~(S3C2443_PHYCTRL_CLKSEL | S3C2443_PHYCTRL_DSPORT);
207 cfg |= (S3C2443_PHYCTRL_EXTCLK | S3C2443_PHYCTRL_PLLSEL);
208 writel(cfg, S3C2443_PHYCTRL);
209
210 cfg = readl(S3C2443_PHYPWR);
211 cfg &= ~(S3C2443_PHYPWR_FSUSPEND | S3C2443_PHYPWR_PLL_PWRDN |
212 S3C2443_PHYPWR_XO_ON | S3C2443_PHYPWR_PLL_REFCLK |
213 S3C2443_PHYPWR_ANALOG_PD);
214 cfg |= S3C2443_PHYPWR_COMMON_ON;
215 writel(cfg, S3C2443_PHYPWR);
216
217 cfg = readl(S3C2443_UCLKCON);
218 cfg |= (S3C2443_UCLKCON_DETECT_VBUS | S3C2443_UCLKCON_FUNC_CLKEN |
219 S3C2443_UCLKCON_TCLKEN);
220 writel(cfg, S3C2443_UCLKCON);
221}
222
223static void s3c_hsudc_uninit_phy(void)
224{
225 u32 cfg;
226
227 cfg = readl(S3C2443_PWRCFG) & ~S3C2443_PWRCFG_USBPHY;
228 writel(cfg, S3C2443_PWRCFG);
229
230 writel(S3C2443_PHYPWR_FSUSPEND, S3C2443_PHYPWR);
231
232 cfg = readl(S3C2443_UCLKCON) & ~S3C2443_UCLKCON_FUNC_CLKEN;
233 writel(cfg, S3C2443_UCLKCON);
234}
235
236
237
238
239
240
241
242static void s3c_hsudc_complete_request(struct s3c_hsudc_ep *hsep,
243 struct s3c_hsudc_req *hsreq, int status)
244{
245 unsigned int stopped = hsep->stopped;
246 struct s3c_hsudc *hsudc = hsep->dev;
247
248 list_del_init(&hsreq->queue);
249 hsreq->req.status = status;
250
251 if (!ep_index(hsep)) {
252 hsudc->ep0state = WAIT_FOR_SETUP;
253 hsep->bEndpointAddress &= ~USB_DIR_IN;
254 }
255
256 hsep->stopped = 1;
257 spin_unlock(&hsudc->lock);
258 usb_gadget_giveback_request(&hsep->ep, &hsreq->req);
259 spin_lock(&hsudc->lock);
260 hsep->stopped = stopped;
261}
262
263
264
265
266
267
268static void s3c_hsudc_nuke_ep(struct s3c_hsudc_ep *hsep, int status)
269{
270 struct s3c_hsudc_req *hsreq;
271
272 while (!list_empty(&hsep->queue)) {
273 hsreq = list_entry(hsep->queue.next,
274 struct s3c_hsudc_req, queue);
275 s3c_hsudc_complete_request(hsep, hsreq, status);
276 }
277}
278
279
280
281
282
283
284
285
286static void s3c_hsudc_stop_activity(struct s3c_hsudc *hsudc)
287{
288 struct s3c_hsudc_ep *hsep;
289 int epnum;
290
291 hsudc->gadget.speed = USB_SPEED_UNKNOWN;
292
293 for (epnum = 0; epnum < hsudc->pd->epnum; epnum++) {
294 hsep = &hsudc->ep[epnum];
295 hsep->stopped = 1;
296 s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN);
297 }
298}
299
300
301
302
303
304
305
306
307
308
309static void s3c_hsudc_read_setup_pkt(struct s3c_hsudc *hsudc, u16 *buf)
310{
311 int count;
312
313 count = readl(hsudc->regs + S3C_BRCR);
314 while (count--)
315 *buf++ = (u16)readl(hsudc->regs + S3C_BR(0));
316
317 writel(S3C_EP0SR_RX_SUCCESS, hsudc->regs + S3C_EP0SR);
318}
319
320
321
322
323
324
325
326
327
328static int s3c_hsudc_write_fifo(struct s3c_hsudc_ep *hsep,
329 struct s3c_hsudc_req *hsreq)
330{
331 u16 *buf;
332 u32 max = ep_maxpacket(hsep);
333 u32 count, length;
334 bool is_last;
335 void __iomem *fifo = hsep->fifo;
336
337 buf = hsreq->req.buf + hsreq->req.actual;
338 prefetch(buf);
339
340 length = hsreq->req.length - hsreq->req.actual;
341 length = min(length, max);
342 hsreq->req.actual += length;
343
344 writel(length, hsep->dev->regs + S3C_BWCR);
345 for (count = 0; count < length; count += 2)
346 writel(*buf++, fifo);
347
348 if (count != max) {
349 is_last = true;
350 } else {
351 if (hsreq->req.length != hsreq->req.actual || hsreq->req.zero)
352 is_last = false;
353 else
354 is_last = true;
355 }
356
357 if (is_last) {
358 s3c_hsudc_complete_request(hsep, hsreq, 0);
359 return 1;
360 }
361
362 return 0;
363}
364
365
366
367
368
369
370
371
372
373
374static int s3c_hsudc_read_fifo(struct s3c_hsudc_ep *hsep,
375 struct s3c_hsudc_req *hsreq)
376{
377 struct s3c_hsudc *hsudc = hsep->dev;
378 u32 csr, offset;
379 u16 *buf, word;
380 u32 buflen, rcnt, rlen;
381 void __iomem *fifo = hsep->fifo;
382 u32 is_short = 0;
383
384 offset = (ep_index(hsep)) ? S3C_ESR : S3C_EP0SR;
385 csr = readl(hsudc->regs + offset);
386 if (!(csr & S3C_ESR_RX_SUCCESS))
387 return -EINVAL;
388
389 buf = hsreq->req.buf + hsreq->req.actual;
390 prefetchw(buf);
391 buflen = hsreq->req.length - hsreq->req.actual;
392
393 rcnt = readl(hsudc->regs + S3C_BRCR);
394 rlen = (csr & S3C_ESR_LWO) ? (rcnt * 2 - 1) : (rcnt * 2);
395
396 hsreq->req.actual += min(rlen, buflen);
397 is_short = (rlen < hsep->ep.maxpacket);
398
399 while (rcnt-- != 0) {
400 word = (u16)readl(fifo);
401 if (buflen) {
402 *buf++ = word;
403 buflen--;
404 } else {
405 hsreq->req.status = -EOVERFLOW;
406 }
407 }
408
409 writel(S3C_ESR_RX_SUCCESS, hsudc->regs + offset);
410
411 if (is_short || hsreq->req.actual == hsreq->req.length) {
412 s3c_hsudc_complete_request(hsep, hsreq, 0);
413 return 1;
414 }
415
416 return 0;
417}
418
419
420
421
422
423
424
425
426
427static void s3c_hsudc_epin_intr(struct s3c_hsudc *hsudc, u32 ep_idx)
428{
429 struct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx];
430 struct s3c_hsudc_req *hsreq;
431 u32 csr;
432
433 csr = readl(hsudc->regs + S3C_ESR);
434 if (csr & S3C_ESR_STALL) {
435 writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR);
436 return;
437 }
438
439 if (csr & S3C_ESR_TX_SUCCESS) {
440 writel(S3C_ESR_TX_SUCCESS, hsudc->regs + S3C_ESR);
441 if (list_empty(&hsep->queue))
442 return;
443
444 hsreq = list_entry(hsep->queue.next,
445 struct s3c_hsudc_req, queue);
446 if ((s3c_hsudc_write_fifo(hsep, hsreq) == 0) &&
447 (csr & S3C_ESR_PSIF_TWO))
448 s3c_hsudc_write_fifo(hsep, hsreq);
449 }
450}
451
452
453
454
455
456
457
458
459
460static void s3c_hsudc_epout_intr(struct s3c_hsudc *hsudc, u32 ep_idx)
461{
462 struct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx];
463 struct s3c_hsudc_req *hsreq;
464 u32 csr;
465
466 csr = readl(hsudc->regs + S3C_ESR);
467 if (csr & S3C_ESR_STALL) {
468 writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR);
469 return;
470 }
471
472 if (csr & S3C_ESR_FLUSH) {
473 __orr32(hsudc->regs + S3C_ECR, S3C_ECR_FLUSH);
474 return;
475 }
476
477 if (csr & S3C_ESR_RX_SUCCESS) {
478 if (list_empty(&hsep->queue))
479 return;
480
481 hsreq = list_entry(hsep->queue.next,
482 struct s3c_hsudc_req, queue);
483 if (((s3c_hsudc_read_fifo(hsep, hsreq)) == 0) &&
484 (csr & S3C_ESR_PSIF_TWO))
485 s3c_hsudc_read_fifo(hsep, hsreq);
486 }
487}
488
489
490
491
492
493
494
495
496
497static int s3c_hsudc_set_halt(struct usb_ep *_ep, int value)
498{
499 struct s3c_hsudc_ep *hsep = our_ep(_ep);
500 struct s3c_hsudc *hsudc = hsep->dev;
501 struct s3c_hsudc_req *hsreq;
502 unsigned long irqflags;
503 u32 ecr;
504 u32 offset;
505
506 if (value && ep_is_in(hsep) && !list_empty(&hsep->queue))
507 return -EAGAIN;
508
509 spin_lock_irqsave(&hsudc->lock, irqflags);
510 set_index(hsudc, ep_index(hsep));
511 offset = (ep_index(hsep)) ? S3C_ECR : S3C_EP0CR;
512 ecr = readl(hsudc->regs + offset);
513
514 if (value) {
515 ecr |= S3C_ECR_STALL;
516 if (ep_index(hsep))
517 ecr |= S3C_ECR_FLUSH;
518 hsep->stopped = 1;
519 } else {
520 ecr &= ~S3C_ECR_STALL;
521 hsep->stopped = hsep->wedge = 0;
522 }
523 writel(ecr, hsudc->regs + offset);
524
525 if (ep_is_in(hsep) && !list_empty(&hsep->queue) && !value) {
526 hsreq = list_entry(hsep->queue.next,
527 struct s3c_hsudc_req, queue);
528 if (hsreq)
529 s3c_hsudc_write_fifo(hsep, hsreq);
530 }
531
532 spin_unlock_irqrestore(&hsudc->lock, irqflags);
533 return 0;
534}
535
536
537
538
539
540
541static int s3c_hsudc_set_wedge(struct usb_ep *_ep)
542{
543 struct s3c_hsudc_ep *hsep = our_ep(_ep);
544
545 if (!hsep)
546 return -EINVAL;
547
548 hsep->wedge = 1;
549 return usb_ep_set_halt(_ep);
550}
551
552
553
554
555
556
557
558static int s3c_hsudc_handle_reqfeat(struct s3c_hsudc *hsudc,
559 struct usb_ctrlrequest *ctrl)
560{
561 struct s3c_hsudc_ep *hsep;
562 bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE);
563 u8 ep_num = ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK;
564
565 if (ctrl->bRequestType == USB_RECIP_ENDPOINT) {
566 hsep = &hsudc->ep[ep_num];
567 switch (le16_to_cpu(ctrl->wValue)) {
568 case USB_ENDPOINT_HALT:
569 if (set || !hsep->wedge)
570 s3c_hsudc_set_halt(&hsep->ep, set);
571 return 0;
572 }
573 }
574
575 return -ENOENT;
576}
577
578
579
580
581
582
583
584
585static void s3c_hsudc_process_req_status(struct s3c_hsudc *hsudc,
586 struct usb_ctrlrequest *ctrl)
587{
588 struct s3c_hsudc_ep *hsep0 = &hsudc->ep[0];
589 struct s3c_hsudc_req hsreq;
590 struct s3c_hsudc_ep *hsep;
591 __le16 reply;
592 u8 epnum;
593
594 switch (ctrl->bRequestType & USB_RECIP_MASK) {
595 case USB_RECIP_DEVICE:
596 reply = cpu_to_le16(0);
597 break;
598
599 case USB_RECIP_INTERFACE:
600 reply = cpu_to_le16(0);
601 break;
602
603 case USB_RECIP_ENDPOINT:
604 epnum = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK;
605 hsep = &hsudc->ep[epnum];
606 reply = cpu_to_le16(hsep->stopped ? 1 : 0);
607 break;
608 }
609
610 INIT_LIST_HEAD(&hsreq.queue);
611 hsreq.req.length = 2;
612 hsreq.req.buf = &reply;
613 hsreq.req.actual = 0;
614 hsreq.req.complete = NULL;
615 s3c_hsudc_write_fifo(hsep0, &hsreq);
616}
617
618
619
620
621
622
623
624
625static void s3c_hsudc_process_setup(struct s3c_hsudc *hsudc)
626{
627 struct s3c_hsudc_ep *hsep = &hsudc->ep[0];
628 struct usb_ctrlrequest ctrl = {0};
629 int ret;
630
631 s3c_hsudc_nuke_ep(hsep, -EPROTO);
632 s3c_hsudc_read_setup_pkt(hsudc, (u16 *)&ctrl);
633
634 if (ctrl.bRequestType & USB_DIR_IN) {
635 hsep->bEndpointAddress |= USB_DIR_IN;
636 hsudc->ep0state = DATA_STATE_XMIT;
637 } else {
638 hsep->bEndpointAddress &= ~USB_DIR_IN;
639 hsudc->ep0state = DATA_STATE_RECV;
640 }
641
642 switch (ctrl.bRequest) {
643 case USB_REQ_SET_ADDRESS:
644 if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE))
645 break;
646 hsudc->ep0state = WAIT_FOR_SETUP;
647 return;
648
649 case USB_REQ_GET_STATUS:
650 if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD)
651 break;
652 s3c_hsudc_process_req_status(hsudc, &ctrl);
653 return;
654
655 case USB_REQ_SET_FEATURE:
656 case USB_REQ_CLEAR_FEATURE:
657 if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD)
658 break;
659 s3c_hsudc_handle_reqfeat(hsudc, &ctrl);
660 hsudc->ep0state = WAIT_FOR_SETUP;
661 return;
662 }
663
664 if (hsudc->driver) {
665 spin_unlock(&hsudc->lock);
666 ret = hsudc->driver->setup(&hsudc->gadget, &ctrl);
667 spin_lock(&hsudc->lock);
668
669 if (ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
670 hsep->bEndpointAddress &= ~USB_DIR_IN;
671 hsudc->ep0state = WAIT_FOR_SETUP;
672 }
673
674 if (ret < 0) {
675 dev_err(hsudc->dev, "setup failed, returned %d\n",
676 ret);
677 s3c_hsudc_set_halt(&hsep->ep, 1);
678 hsudc->ep0state = WAIT_FOR_SETUP;
679 hsep->bEndpointAddress &= ~USB_DIR_IN;
680 }
681 }
682}
683
684
685
686
687
688
689
690
691static void s3c_hsudc_handle_ep0_intr(struct s3c_hsudc *hsudc)
692{
693 struct s3c_hsudc_ep *hsep = &hsudc->ep[0];
694 struct s3c_hsudc_req *hsreq;
695 u32 csr = readl(hsudc->regs + S3C_EP0SR);
696 u32 ecr;
697
698 if (csr & S3C_EP0SR_STALL) {
699 ecr = readl(hsudc->regs + S3C_EP0CR);
700 ecr &= ~(S3C_ECR_STALL | S3C_ECR_FLUSH);
701 writel(ecr, hsudc->regs + S3C_EP0CR);
702
703 writel(S3C_EP0SR_STALL, hsudc->regs + S3C_EP0SR);
704 hsep->stopped = 0;
705
706 s3c_hsudc_nuke_ep(hsep, -ECONNABORTED);
707 hsudc->ep0state = WAIT_FOR_SETUP;
708 hsep->bEndpointAddress &= ~USB_DIR_IN;
709 return;
710 }
711
712 if (csr & S3C_EP0SR_TX_SUCCESS) {
713 writel(S3C_EP0SR_TX_SUCCESS, hsudc->regs + S3C_EP0SR);
714 if (ep_is_in(hsep)) {
715 if (list_empty(&hsep->queue))
716 return;
717
718 hsreq = list_entry(hsep->queue.next,
719 struct s3c_hsudc_req, queue);
720 s3c_hsudc_write_fifo(hsep, hsreq);
721 }
722 }
723
724 if (csr & S3C_EP0SR_RX_SUCCESS) {
725 if (hsudc->ep0state == WAIT_FOR_SETUP)
726 s3c_hsudc_process_setup(hsudc);
727 else {
728 if (!ep_is_in(hsep)) {
729 if (list_empty(&hsep->queue))
730 return;
731 hsreq = list_entry(hsep->queue.next,
732 struct s3c_hsudc_req, queue);
733 s3c_hsudc_read_fifo(hsep, hsreq);
734 }
735 }
736 }
737}
738
739
740
741
742
743
744
745
746
747
748static int s3c_hsudc_ep_enable(struct usb_ep *_ep,
749 const struct usb_endpoint_descriptor *desc)
750{
751 struct s3c_hsudc_ep *hsep;
752 struct s3c_hsudc *hsudc;
753 unsigned long flags;
754 u32 ecr = 0;
755
756 hsep = our_ep(_ep);
757 if (!_ep || !desc || _ep->name == ep0name
758 || desc->bDescriptorType != USB_DT_ENDPOINT
759 || hsep->bEndpointAddress != desc->bEndpointAddress
760 || ep_maxpacket(hsep) < usb_endpoint_maxp(desc))
761 return -EINVAL;
762
763 if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
764 && usb_endpoint_maxp(desc) != ep_maxpacket(hsep))
765 || !desc->wMaxPacketSize)
766 return -ERANGE;
767
768 hsudc = hsep->dev;
769 if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN)
770 return -ESHUTDOWN;
771
772 spin_lock_irqsave(&hsudc->lock, flags);
773
774 set_index(hsudc, hsep->bEndpointAddress);
775 ecr |= ((usb_endpoint_xfer_int(desc)) ? S3C_ECR_IEMS : S3C_ECR_DUEN);
776 writel(ecr, hsudc->regs + S3C_ECR);
777
778 hsep->stopped = hsep->wedge = 0;
779 hsep->ep.desc = desc;
780 hsep->ep.maxpacket = usb_endpoint_maxp(desc);
781
782 s3c_hsudc_set_halt(_ep, 0);
783 __set_bit(ep_index(hsep), hsudc->regs + S3C_EIER);
784
785 spin_unlock_irqrestore(&hsudc->lock, flags);
786 return 0;
787}
788
789
790
791
792
793
794
795
796static int s3c_hsudc_ep_disable(struct usb_ep *_ep)
797{
798 struct s3c_hsudc_ep *hsep = our_ep(_ep);
799 struct s3c_hsudc *hsudc = hsep->dev;
800 unsigned long flags;
801
802 if (!_ep || !hsep->ep.desc)
803 return -EINVAL;
804
805 spin_lock_irqsave(&hsudc->lock, flags);
806
807 set_index(hsudc, hsep->bEndpointAddress);
808 __clear_bit(ep_index(hsep), hsudc->regs + S3C_EIER);
809
810 s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN);
811
812 hsep->ep.desc = NULL;
813 hsep->stopped = 1;
814
815 spin_unlock_irqrestore(&hsudc->lock, flags);
816 return 0;
817}
818
819
820
821
822
823
824
825
826static struct usb_request *s3c_hsudc_alloc_request(struct usb_ep *_ep,
827 gfp_t gfp_flags)
828{
829 struct s3c_hsudc_req *hsreq;
830
831 hsreq = kzalloc(sizeof(*hsreq), gfp_flags);
832 if (!hsreq)
833 return NULL;
834
835 INIT_LIST_HEAD(&hsreq->queue);
836 return &hsreq->req;
837}
838
839
840
841
842
843
844
845
846static void s3c_hsudc_free_request(struct usb_ep *ep, struct usb_request *_req)
847{
848 struct s3c_hsudc_req *hsreq;
849
850 hsreq = our_req(_req);
851 WARN_ON(!list_empty(&hsreq->queue));
852 kfree(hsreq);
853}
854
855
856
857
858
859
860
861
862
863static int s3c_hsudc_queue(struct usb_ep *_ep, struct usb_request *_req,
864 gfp_t gfp_flags)
865{
866 struct s3c_hsudc_req *hsreq;
867 struct s3c_hsudc_ep *hsep;
868 struct s3c_hsudc *hsudc;
869 unsigned long flags;
870 u32 offset;
871 u32 csr;
872
873 hsreq = our_req(_req);
874 if ((!_req || !_req->complete || !_req->buf ||
875 !list_empty(&hsreq->queue)))
876 return -EINVAL;
877
878 hsep = our_ep(_ep);
879 hsudc = hsep->dev;
880 if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN)
881 return -ESHUTDOWN;
882
883 spin_lock_irqsave(&hsudc->lock, flags);
884 set_index(hsudc, hsep->bEndpointAddress);
885
886 _req->status = -EINPROGRESS;
887 _req->actual = 0;
888
889 if (!ep_index(hsep) && _req->length == 0) {
890 hsudc->ep0state = WAIT_FOR_SETUP;
891 s3c_hsudc_complete_request(hsep, hsreq, 0);
892 spin_unlock_irqrestore(&hsudc->lock, flags);
893 return 0;
894 }
895
896 if (list_empty(&hsep->queue) && !hsep->stopped) {
897 offset = (ep_index(hsep)) ? S3C_ESR : S3C_EP0SR;
898 if (ep_is_in(hsep)) {
899 csr = readl(hsudc->regs + offset);
900 if (!(csr & S3C_ESR_TX_SUCCESS) &&
901 (s3c_hsudc_write_fifo(hsep, hsreq) == 1))
902 hsreq = NULL;
903 } else {
904 csr = readl(hsudc->regs + offset);
905 if ((csr & S3C_ESR_RX_SUCCESS)
906 && (s3c_hsudc_read_fifo(hsep, hsreq) == 1))
907 hsreq = NULL;
908 }
909 }
910
911 if (hsreq)
912 list_add_tail(&hsreq->queue, &hsep->queue);
913
914 spin_unlock_irqrestore(&hsudc->lock, flags);
915 return 0;
916}
917
918
919
920
921
922
923
924
925static int s3c_hsudc_dequeue(struct usb_ep *_ep, struct usb_request *_req)
926{
927 struct s3c_hsudc_ep *hsep = our_ep(_ep);
928 struct s3c_hsudc *hsudc = hsep->dev;
929 struct s3c_hsudc_req *hsreq;
930 unsigned long flags;
931
932 hsep = our_ep(_ep);
933 if (!_ep || hsep->ep.name == ep0name)
934 return -EINVAL;
935
936 spin_lock_irqsave(&hsudc->lock, flags);
937
938 list_for_each_entry(hsreq, &hsep->queue, queue) {
939 if (&hsreq->req == _req)
940 break;
941 }
942 if (&hsreq->req != _req) {
943 spin_unlock_irqrestore(&hsudc->lock, flags);
944 return -EINVAL;
945 }
946
947 set_index(hsudc, hsep->bEndpointAddress);
948 s3c_hsudc_complete_request(hsep, hsreq, -ECONNRESET);
949
950 spin_unlock_irqrestore(&hsudc->lock, flags);
951 return 0;
952}
953
954static const struct usb_ep_ops s3c_hsudc_ep_ops = {
955 .enable = s3c_hsudc_ep_enable,
956 .disable = s3c_hsudc_ep_disable,
957 .alloc_request = s3c_hsudc_alloc_request,
958 .free_request = s3c_hsudc_free_request,
959 .queue = s3c_hsudc_queue,
960 .dequeue = s3c_hsudc_dequeue,
961 .set_halt = s3c_hsudc_set_halt,
962 .set_wedge = s3c_hsudc_set_wedge,
963};
964
965
966
967
968
969
970
971
972
973static void s3c_hsudc_initep(struct s3c_hsudc *hsudc,
974 struct s3c_hsudc_ep *hsep, int epnum)
975{
976 char *dir;
977
978 if ((epnum % 2) == 0) {
979 dir = "out";
980 } else {
981 dir = "in";
982 hsep->bEndpointAddress = USB_DIR_IN;
983 }
984
985 hsep->bEndpointAddress |= epnum;
986 if (epnum)
987 snprintf(hsep->name, sizeof(hsep->name), "ep%d%s", epnum, dir);
988 else
989 snprintf(hsep->name, sizeof(hsep->name), "%s", ep0name);
990
991 INIT_LIST_HEAD(&hsep->queue);
992 INIT_LIST_HEAD(&hsep->ep.ep_list);
993 if (epnum)
994 list_add_tail(&hsep->ep.ep_list, &hsudc->gadget.ep_list);
995
996 hsep->dev = hsudc;
997 hsep->ep.name = hsep->name;
998 usb_ep_set_maxpacket_limit(&hsep->ep, epnum ? 512 : 64);
999 hsep->ep.ops = &s3c_hsudc_ep_ops;
1000 hsep->fifo = hsudc->regs + S3C_BR(epnum);
1001 hsep->ep.desc = NULL;
1002 hsep->stopped = 0;
1003 hsep->wedge = 0;
1004
1005 if (epnum == 0) {
1006 hsep->ep.caps.type_control = true;
1007 hsep->ep.caps.dir_in = true;
1008 hsep->ep.caps.dir_out = true;
1009 } else {
1010 hsep->ep.caps.type_iso = true;
1011 hsep->ep.caps.type_bulk = true;
1012 hsep->ep.caps.type_int = true;
1013 }
1014
1015 if (epnum & 1)
1016 hsep->ep.caps.dir_in = true;
1017 else
1018 hsep->ep.caps.dir_out = true;
1019
1020 set_index(hsudc, epnum);
1021 writel(hsep->ep.maxpacket, hsudc->regs + S3C_MPR);
1022}
1023
1024
1025
1026
1027
1028
1029
1030static void s3c_hsudc_setup_ep(struct s3c_hsudc *hsudc)
1031{
1032 int epnum;
1033
1034 hsudc->ep0state = WAIT_FOR_SETUP;
1035 INIT_LIST_HEAD(&hsudc->gadget.ep_list);
1036 for (epnum = 0; epnum < hsudc->pd->epnum; epnum++)
1037 s3c_hsudc_initep(hsudc, &hsudc->ep[epnum], epnum);
1038}
1039
1040
1041
1042
1043
1044
1045
1046static void s3c_hsudc_reconfig(struct s3c_hsudc *hsudc)
1047{
1048 writel(0xAA, hsudc->regs + S3C_EDR);
1049 writel(1, hsudc->regs + S3C_EIER);
1050 writel(0, hsudc->regs + S3C_TR);
1051 writel(S3C_SCR_DTZIEN_EN | S3C_SCR_RRD_EN | S3C_SCR_SUS_EN |
1052 S3C_SCR_RST_EN, hsudc->regs + S3C_SCR);
1053 writel(0, hsudc->regs + S3C_EP0CR);
1054
1055 s3c_hsudc_setup_ep(hsudc);
1056}
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066static irqreturn_t s3c_hsudc_irq(int irq, void *_dev)
1067{
1068 struct s3c_hsudc *hsudc = _dev;
1069 struct s3c_hsudc_ep *hsep;
1070 u32 ep_intr;
1071 u32 sys_status;
1072 u32 ep_idx;
1073
1074 spin_lock(&hsudc->lock);
1075
1076 sys_status = readl(hsudc->regs + S3C_SSR);
1077 ep_intr = readl(hsudc->regs + S3C_EIR) & 0x3FF;
1078
1079 if (!ep_intr && !(sys_status & S3C_SSR_DTZIEN_EN)) {
1080 spin_unlock(&hsudc->lock);
1081 return IRQ_HANDLED;
1082 }
1083
1084 if (sys_status) {
1085 if (sys_status & S3C_SSR_VBUSON)
1086 writel(S3C_SSR_VBUSON, hsudc->regs + S3C_SSR);
1087
1088 if (sys_status & S3C_SSR_ERR)
1089 writel(S3C_SSR_ERR, hsudc->regs + S3C_SSR);
1090
1091 if (sys_status & S3C_SSR_SDE) {
1092 writel(S3C_SSR_SDE, hsudc->regs + S3C_SSR);
1093 hsudc->gadget.speed = (sys_status & S3C_SSR_HSP) ?
1094 USB_SPEED_HIGH : USB_SPEED_FULL;
1095 }
1096
1097 if (sys_status & S3C_SSR_SUSPEND) {
1098 writel(S3C_SSR_SUSPEND, hsudc->regs + S3C_SSR);
1099 if (hsudc->gadget.speed != USB_SPEED_UNKNOWN
1100 && hsudc->driver && hsudc->driver->suspend)
1101 hsudc->driver->suspend(&hsudc->gadget);
1102 }
1103
1104 if (sys_status & S3C_SSR_RESUME) {
1105 writel(S3C_SSR_RESUME, hsudc->regs + S3C_SSR);
1106 if (hsudc->gadget.speed != USB_SPEED_UNKNOWN
1107 && hsudc->driver && hsudc->driver->resume)
1108 hsudc->driver->resume(&hsudc->gadget);
1109 }
1110
1111 if (sys_status & S3C_SSR_RESET) {
1112 writel(S3C_SSR_RESET, hsudc->regs + S3C_SSR);
1113 for (ep_idx = 0; ep_idx < hsudc->pd->epnum; ep_idx++) {
1114 hsep = &hsudc->ep[ep_idx];
1115 hsep->stopped = 1;
1116 s3c_hsudc_nuke_ep(hsep, -ECONNRESET);
1117 }
1118 s3c_hsudc_reconfig(hsudc);
1119 hsudc->ep0state = WAIT_FOR_SETUP;
1120 }
1121 }
1122
1123 if (ep_intr & S3C_EIR_EP0) {
1124 writel(S3C_EIR_EP0, hsudc->regs + S3C_EIR);
1125 set_index(hsudc, 0);
1126 s3c_hsudc_handle_ep0_intr(hsudc);
1127 }
1128
1129 ep_intr >>= 1;
1130 ep_idx = 1;
1131 while (ep_intr) {
1132 if (ep_intr & 1) {
1133 hsep = &hsudc->ep[ep_idx];
1134 set_index(hsudc, ep_idx);
1135 writel(1 << ep_idx, hsudc->regs + S3C_EIR);
1136 if (ep_is_in(hsep))
1137 s3c_hsudc_epin_intr(hsudc, ep_idx);
1138 else
1139 s3c_hsudc_epout_intr(hsudc, ep_idx);
1140 }
1141 ep_intr >>= 1;
1142 ep_idx++;
1143 }
1144
1145 spin_unlock(&hsudc->lock);
1146 return IRQ_HANDLED;
1147}
1148
1149static int s3c_hsudc_start(struct usb_gadget *gadget,
1150 struct usb_gadget_driver *driver)
1151{
1152 struct s3c_hsudc *hsudc = to_hsudc(gadget);
1153 int ret;
1154
1155 if (!driver
1156 || driver->max_speed < USB_SPEED_FULL
1157 || !driver->setup)
1158 return -EINVAL;
1159
1160 if (!hsudc)
1161 return -ENODEV;
1162
1163 if (hsudc->driver)
1164 return -EBUSY;
1165
1166 hsudc->driver = driver;
1167
1168 ret = regulator_bulk_enable(ARRAY_SIZE(hsudc->supplies),
1169 hsudc->supplies);
1170 if (ret != 0) {
1171 dev_err(hsudc->dev, "failed to enable supplies: %d\n", ret);
1172 goto err_supplies;
1173 }
1174
1175
1176 if (!IS_ERR_OR_NULL(hsudc->transceiver)) {
1177 ret = otg_set_peripheral(hsudc->transceiver->otg,
1178 &hsudc->gadget);
1179 if (ret) {
1180 dev_err(hsudc->dev, "%s: can't bind to transceiver\n",
1181 hsudc->gadget.name);
1182 goto err_otg;
1183 }
1184 }
1185
1186 enable_irq(hsudc->irq);
1187 s3c_hsudc_reconfig(hsudc);
1188
1189 pm_runtime_get_sync(hsudc->dev);
1190
1191 s3c_hsudc_init_phy();
1192 if (hsudc->pd->gpio_init)
1193 hsudc->pd->gpio_init();
1194
1195 return 0;
1196err_otg:
1197 regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies);
1198err_supplies:
1199 hsudc->driver = NULL;
1200 return ret;
1201}
1202
1203static int s3c_hsudc_stop(struct usb_gadget *gadget)
1204{
1205 struct s3c_hsudc *hsudc = to_hsudc(gadget);
1206 unsigned long flags;
1207
1208 if (!hsudc)
1209 return -ENODEV;
1210
1211 spin_lock_irqsave(&hsudc->lock, flags);
1212 hsudc->gadget.speed = USB_SPEED_UNKNOWN;
1213 s3c_hsudc_uninit_phy();
1214
1215 pm_runtime_put(hsudc->dev);
1216
1217 if (hsudc->pd->gpio_uninit)
1218 hsudc->pd->gpio_uninit();
1219 s3c_hsudc_stop_activity(hsudc);
1220 spin_unlock_irqrestore(&hsudc->lock, flags);
1221
1222 if (!IS_ERR_OR_NULL(hsudc->transceiver))
1223 (void) otg_set_peripheral(hsudc->transceiver->otg, NULL);
1224
1225 disable_irq(hsudc->irq);
1226
1227 regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies);
1228 hsudc->driver = NULL;
1229
1230 return 0;
1231}
1232
1233static inline u32 s3c_hsudc_read_frameno(struct s3c_hsudc *hsudc)
1234{
1235 return readl(hsudc->regs + S3C_FNR) & 0x3FF;
1236}
1237
1238static int s3c_hsudc_gadget_getframe(struct usb_gadget *gadget)
1239{
1240 return s3c_hsudc_read_frameno(to_hsudc(gadget));
1241}
1242
1243static int s3c_hsudc_vbus_draw(struct usb_gadget *gadget, unsigned mA)
1244{
1245 struct s3c_hsudc *hsudc = to_hsudc(gadget);
1246
1247 if (!hsudc)
1248 return -ENODEV;
1249
1250 if (!IS_ERR_OR_NULL(hsudc->transceiver))
1251 return usb_phy_set_power(hsudc->transceiver, mA);
1252
1253 return -EOPNOTSUPP;
1254}
1255
1256static const struct usb_gadget_ops s3c_hsudc_gadget_ops = {
1257 .get_frame = s3c_hsudc_gadget_getframe,
1258 .udc_start = s3c_hsudc_start,
1259 .udc_stop = s3c_hsudc_stop,
1260 .vbus_draw = s3c_hsudc_vbus_draw,
1261};
1262
1263static int s3c_hsudc_probe(struct platform_device *pdev)
1264{
1265 struct device *dev = &pdev->dev;
1266 struct resource *res;
1267 struct s3c_hsudc *hsudc;
1268 struct s3c24xx_hsudc_platdata *pd = dev_get_platdata(&pdev->dev);
1269 int ret, i;
1270
1271 hsudc = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsudc) +
1272 sizeof(struct s3c_hsudc_ep) * pd->epnum,
1273 GFP_KERNEL);
1274 if (!hsudc)
1275 return -ENOMEM;
1276
1277 platform_set_drvdata(pdev, dev);
1278 hsudc->dev = dev;
1279 hsudc->pd = dev_get_platdata(&pdev->dev);
1280
1281 hsudc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
1282
1283 for (i = 0; i < ARRAY_SIZE(hsudc->supplies); i++)
1284 hsudc->supplies[i].supply = s3c_hsudc_supply_names[i];
1285
1286 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsudc->supplies),
1287 hsudc->supplies);
1288 if (ret != 0) {
1289 dev_err(dev, "failed to request supplies: %d\n", ret);
1290 goto err_supplies;
1291 }
1292
1293 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1294
1295 hsudc->regs = devm_ioremap_resource(&pdev->dev, res);
1296 if (IS_ERR(hsudc->regs)) {
1297 ret = PTR_ERR(hsudc->regs);
1298 goto err_res;
1299 }
1300
1301 spin_lock_init(&hsudc->lock);
1302
1303 hsudc->gadget.max_speed = USB_SPEED_HIGH;
1304 hsudc->gadget.ops = &s3c_hsudc_gadget_ops;
1305 hsudc->gadget.name = dev_name(dev);
1306 hsudc->gadget.ep0 = &hsudc->ep[0].ep;
1307 hsudc->gadget.is_otg = 0;
1308 hsudc->gadget.is_a_peripheral = 0;
1309 hsudc->gadget.speed = USB_SPEED_UNKNOWN;
1310
1311 s3c_hsudc_setup_ep(hsudc);
1312
1313 ret = platform_get_irq(pdev, 0);
1314 if (ret < 0) {
1315 dev_err(dev, "unable to obtain IRQ number\n");
1316 goto err_res;
1317 }
1318 hsudc->irq = ret;
1319
1320 ret = devm_request_irq(&pdev->dev, hsudc->irq, s3c_hsudc_irq, 0,
1321 driver_name, hsudc);
1322 if (ret < 0) {
1323 dev_err(dev, "irq request failed\n");
1324 goto err_res;
1325 }
1326
1327 hsudc->uclk = devm_clk_get(&pdev->dev, "usb-device");
1328 if (IS_ERR(hsudc->uclk)) {
1329 dev_err(dev, "failed to find usb-device clock source\n");
1330 ret = PTR_ERR(hsudc->uclk);
1331 goto err_res;
1332 }
1333 clk_enable(hsudc->uclk);
1334
1335 local_irq_disable();
1336
1337 disable_irq(hsudc->irq);
1338 local_irq_enable();
1339
1340 ret = usb_add_gadget_udc(&pdev->dev, &hsudc->gadget);
1341 if (ret)
1342 goto err_add_udc;
1343
1344 pm_runtime_enable(dev);
1345
1346 return 0;
1347err_add_udc:
1348 clk_disable(hsudc->uclk);
1349err_res:
1350 if (!IS_ERR_OR_NULL(hsudc->transceiver))
1351 usb_put_phy(hsudc->transceiver);
1352
1353err_supplies:
1354 return ret;
1355}
1356
1357static struct platform_driver s3c_hsudc_driver = {
1358 .driver = {
1359 .name = "s3c-hsudc",
1360 },
1361 .probe = s3c_hsudc_probe,
1362};
1363
1364module_platform_driver(s3c_hsudc_driver);
1365
1366MODULE_DESCRIPTION("Samsung S3C24XX USB high-speed controller driver");
1367MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
1368MODULE_LICENSE("GPL");
1369MODULE_ALIAS("platform:s3c-hsudc");
1370