tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / usb / gadget / dwc_otg / dwc_otg_pcd_linux.c
1  /* ==========================================================================
2   * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_linux.c $
3   * $Revision: #6 $
4   * $Date: 2009/02/18 $
5   * $Change: 1190679 $
6   *
7   * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8   * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9   * otherwise expressly agreed to in writing between Synopsys and you.
10   *
11   * The Software IS NOT an item of Licensed Software or Licensed Product under
12   * any End User Software License Agreement or Agreement for Licensed Product
13   * with Synopsys or any supplement thereto. You are permitted to use and
14   * redistribute this Software in source and binary forms, with or without
15   * modification, provided that redistributions of source code must retain this
16   * notice. You may not view, use, disclose, copy or distribute this file or
17   * any information contained herein except pursuant to this license grant from
18   * Synopsys. If you do not agree with this notice, including the disclaimer
19   * below, then you are not authorized to use the Software.
20   *
21   * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
22   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24   * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
25   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31   * DAMAGE.
32   * ========================================================================== */
33 #ifndef DWC_HOST_ONLY
34
35 /** @file
36  * This file implements the Peripheral Controller Driver.
37  *
38  * The Peripheral Controller Driver (PCD) is responsible for
39  * translating requests from the Function Driver into the appropriate
40  * actions on the DWC_otg controller. It isolates the Function Driver
41  * from the specifics of the controller by providing an API to the
42  * Function Driver.
43  *
44  * The Peripheral Controller Driver for Linux will implement the
45  * Gadget API, so that the existing Gadget drivers can be used.
46  * (Gadget Driver is the Linux terminology for a Function Driver.)
47  *
48  * The Linux Gadget API is defined in the header file
49  * <code><linux/usb_gadget.h></code>.  The USB EP operations API is
50  * defined in the structure <code>usb_ep_ops</code> and the USB
51  * Controller API is defined in the structure
52  * <code>usb_gadget_ops</code>.
53  *
54  */
55
56 #include <asm/errno.h>
57 #include <linux/list.h>
58 #include <linux/string.h>
59 #include <version.h>
60 #include <common.h>
61
62 #include <asm/io.h>
63 #include <asm/arch/ldo.h>
64 #include <linux/usb/ch9.h>
65 #include <linux/usb/gadget.h>
66
67 #include "dwc_otg_driver.h"
68 #include "dwc_otg_pcd_if.h"
69 #include "dwc_otg_dbg.h"
70
71 static struct gadget_wrapper {
72         dwc_otg_pcd_t *pcd;
73
74         struct usb_gadget gadget;
75         struct usb_gadget_driver *driver;
76
77         struct usb_ep ep0;
78         struct usb_ep in_ep[16];
79         struct usb_ep out_ep[16];
80
81 } *gadget_wrapper;
82
83 /* Display the contents of the buffer */
84 extern void dump_msg(const u8 * buf, unsigned int length);
85
86 /* USB Endpoint Operations */
87 /*
88  * The following sections briefly describe the behavior of the Gadget
89  * API endpoint operations implemented in the DWC_otg driver
90  * software. Detailed descriptions of the generic behavior of each of
91  * these functions can be found in the Linux header file
92  * include/linux/usb_gadget.h.
93  *
94  * The Gadget API provides wrapper functions for each of the function
95  * pointers defined in usb_ep_ops. The Gadget Driver calls the wrapper
96  * function, which then calls the underlying PCD function. The
97  * following sections are named according to the wrapper
98  * functions. Within each section, the corresponding DWC_otg PCD
99  * function name is specified.
100  *
101  */
102
103 /**
104  * This function is called by the Gadget Driver for each EP to be
105  * configured for the current configuration (SET_CONFIGURATION).
106  *
107  * This function initializes the dwc_otg_ep_t data structure, and then
108  * calls dwc_otg_ep_activate.
109  */
110 static int ep_enable(struct usb_ep *usb_ep,
111                      const struct usb_endpoint_descriptor *ep_desc)
112 {
113         int retval;
114
115         DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, usb_ep, ep_desc);
116
117         if (!usb_ep || !ep_desc || ep_desc->bDescriptorType != USB_DT_ENDPOINT) {
118                 DWC_WARN("%s, bad ep or descriptor\n", __func__);
119                 return -EINVAL;
120         }
121         if (usb_ep == &gadget_wrapper->ep0) {
122                 DWC_WARN("%s, bad ep(0)\n", __func__);
123                 return -EINVAL;
124         }
125
126         /* Check FIFO size? */
127         if (!ep_desc->wMaxPacketSize) {
128                 DWC_WARN("%s, bad %s maxpacket\n", __func__, usb_ep->name);
129                 return -ERANGE;
130         }
131
132         if (!gadget_wrapper->driver ||
133             gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
134                 DWC_WARN("%s, bogus device state\n", __func__);
135                 return -ESHUTDOWN;
136         }
137
138         retval = dwc_otg_pcd_ep_enable(gadget_wrapper->pcd,
139                                        (const uint8_t *)ep_desc,
140                                        (void *)usb_ep);
141         if (retval) {
142                 DWC_WARN("dwc_otg_pcd_ep_enable failed\n");
143                 return -EINVAL;
144         }
145
146         usb_ep->maxpacket = le16_to_cpu(ep_desc->wMaxPacketSize);
147
148         return 0;
149 }
150
151 /**
152  * This function is called when an EP is disabled due to disconnect or
153  * change in configuration. Any pending requests will terminate with a
154  * status of -ESHUTDOWN.
155  *
156  * This function modifies the dwc_otg_ep_t data structure for this EP,
157  * and then calls dwc_otg_ep_deactivate.
158  */
159 static int ep_disable(struct usb_ep *usb_ep)
160 {
161         int retval;
162
163         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, usb_ep);
164         if (!usb_ep) {
165                 DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__,
166                             usb_ep ? usb_ep->name : NULL);
167                 return -EINVAL;
168         }
169
170         retval = dwc_otg_pcd_ep_disable(gadget_wrapper->pcd, usb_ep);
171         if (retval) {
172                 retval = -EINVAL;
173         }
174
175         return retval;
176 }
177
178 /**
179  * This function allocates a request object to use with the specified
180  * endpoint.
181  *
182  * @param ep The endpoint to be used with with the request
183  * @param gfp_flags the GFP_* flags to use.
184  */
185 static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *ep,
186                                                      gfp_t gfp_flags)
187 {
188         struct usb_request *usb_req;
189
190         DWC_DEBUGPL(DBG_PCDV, "%s(%p,%d)\n", __func__, ep, gfp_flags);
191         if (0 == ep) {
192                 DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n");
193                 return 0;
194         }
195         usb_req = dwc_alloc(sizeof(*usb_req));
196         if (0 == usb_req) {
197                 DWC_WARN("%s() %s\n", __func__, "request allocation failed!\n");
198                 return 0;
199         }
200         memset(usb_req, 0, sizeof(*usb_req));
201         usb_req->dma = DWC_INVALID_DMA_ADDR;
202
203         return usb_req;
204 }
205
206 /**
207  * This function frees a request object.
208  *
209  * @param ep The endpoint associated with the request
210  * @param req The request being freed
211  */
212 static void dwc_otg_pcd_free_request(struct usb_ep *ep, struct usb_request *req)
213 {
214         DWC_DEBUGPL(DBG_PCDV, "%s(%p,%p)\n", __func__, ep, req);
215
216         if (0 == ep || 0 == req) {
217                 DWC_WARN("%s() %s\n", __func__,
218                          "Invalid ep or req argument!\n");
219                 return;
220         }
221
222         dwc_free(req);
223 }
224
225 /**
226  * This function is used to submit an I/O Request to an EP.
227  *
228  *      - When the request completes the request's completion callback
229  *        is called to return the request to the driver.
230  *      - An EP, except control EPs, may have multiple requests
231  *        pending.
232  *      - Once submitted the request cannot be examined or modified.
233  *      - Each request is turned into one or more packets.
234  *      - A BULK EP can queue any amount of data; the transfer is
235  *        packetized.
236  *      - Zero length Packets are specified with the request 'zero'
237  *        flag.
238  */
239 static int ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req,
240                     gfp_t gfp_flags)
241 {
242         dwc_otg_pcd_t *pcd;
243         int retval;
244
245         //dwc_debug("(%p,%p,%d)\n",
246         //          usb_ep, usb_req, gfp_flags);
247
248         if (!usb_req || !usb_req->complete || !usb_req->buf) {
249                 DWC_WARN("bad params\n");
250                 return -EINVAL;
251         }
252
253         if (!usb_ep) {
254                 DWC_WARN("bad ep\n");
255                 return -EINVAL;
256         }
257
258         pcd = gadget_wrapper->pcd;
259         if (!gadget_wrapper->driver ||
260             gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
261                 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
262                             gadget_wrapper->gadget.speed);
263                 DWC_WARN("bogus device state\n");
264                 return -ESHUTDOWN;
265         }
266
267         DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n",
268                     usb_ep->name, usb_req, usb_req->length, usb_req->buf);
269         usb_req->status = -EINPROGRESS;
270         usb_req->actual = 0;
271
272         retval = dwc_otg_pcd_ep_queue(pcd, usb_ep, usb_req->buf, usb_req->dma,
273                                       usb_req->length, usb_req->zero, usb_req,
274                                       1);
275                                       //gfp_flags == GFP_ATOMIC ? 1 : 0);
276         if (retval) {
277                 return -EINVAL;
278         }
279
280         return 0;
281 }
282
283 /**
284  * This function cancels an I/O request from an EP.
285  */
286 static int ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req)
287 {
288
289         if (!usb_ep || !usb_req) {
290                 DWC_WARN("bad argument\n");
291                 return -EINVAL;
292         }
293         if (!gadget_wrapper->driver ||
294             gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
295                 DWC_WARN("bogus device state\n");
296                 return -ESHUTDOWN;
297         }
298         if (dwc_otg_pcd_ep_dequeue(gadget_wrapper->pcd, usb_ep, usb_req)) {
299                 return -EINVAL;
300         }
301
302         return 0;
303 }
304
305 /**
306  * usb_ep_set_halt stalls an endpoint.
307  *
308  * usb_ep_clear_halt clears an endpoint halt and resets its data
309  * toggle.
310  *
311  * Both of these functions are implemented with the same underlying
312  * function. The behavior depends on the value argument.
313  *
314  * @param[in] usb_ep the Endpoint to halt or clear halt.
315  * @param[in] value
316  *      - 0 means clear_halt.
317  *      - 1 means set_halt,
318  *      - 2 means clear stall lock flag.
319  *      - 3 means set  stall lock flag.
320  */
321 static int ep_halt(struct usb_ep *usb_ep, int value)
322 {
323         int retval = 0;
324
325         DWC_DEBUGPL(DBG_PCD, "HALT %s %d\n", usb_ep->name, value);
326
327         if (!usb_ep) {
328                 DWC_WARN("bad ep\n");
329                 return -EINVAL;
330         }
331
332         retval = dwc_otg_pcd_ep_halt(gadget_wrapper->pcd, usb_ep, value);
333         if (retval == -DWC_E_AGAIN) {
334                 return -EAGAIN;
335         } else if (retval) {
336                 retval = -EINVAL;
337         }
338
339         return retval;
340 }
341
342 #ifdef DWC_EN_ISOC
343 /**
344  * This function is used to submit an ISOC Transfer Request to an EP.
345  *
346  *      - Every time a sync period completes the request's completion callback
347  *        is called to provide data to the gadget driver.
348  *      - Once submitted the request cannot be modified.
349  *      - Each request is turned into periodic data packets untill ISO
350  *        Transfer is stopped..
351  */
352 static int iso_ep_start(struct usb_ep *usb_ep, struct usb_iso_request *req,
353                         gfp_t gfp_flags)
354 {
355         int retval = 0;
356
357         if (!req || !req->process_buffer || !req->buf0 || !req->buf1) {
358                 DWC_WARN("bad params\n");
359                 return -EINVAL;
360         }
361
362         if (!usb_ep) {
363                 DWC_DEBUGPL(DBG_CIL,"bad params\n");
364                 return -EINVAL;
365         }
366
367         req->status = -EINPROGRESS;
368
369         retval =
370             dwc_otg_pcd_iso_ep_start(gadget_wrapper->pcd, usb_ep, req->buf0,
371                                      req->buf1, req->dma0, req->dma1,
372                                      req->sync_frame, req->data_pattern_frame,
373                                      req->data_per_frame,
374                                      req->flags & USB_REQ_ISO_ASAP ? -1 : req->
375                                      start_frame, req->buf_proc_intrvl, req,
376                                      gfp_flags == GFP_ATOMIC ? 1 : 0);
377
378         if (retval) {
379                 return -EINVAL;
380         }
381
382         return retval;
383 }
384
385 /**
386  * This function stops ISO EP Periodic Data Transfer.
387  */
388 static int iso_ep_stop(struct usb_ep *usb_ep, struct usb_iso_request *req)
389 {
390         int retval = 0;
391         if (!usb_ep) {
392                 DWC_WARN("bad ep\n");
393         }
394
395         if (!gadget_wrapper->driver ||
396             gadget_wrapper->gadget.speed == USB_SPEED_UNKNOWN) {
397                 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n",
398                             gadget_wrapper->gadget.speed);
399                 DWC_WARN("bogus device state\n");
400         }
401
402         dwc_otg_pcd_iso_ep_stop(gadget_wrapper->pcd, usb_ep, req);
403         if (retval) {
404                 retval = -EINVAL;
405         }
406
407         return retval;
408 }
409
410 static struct usb_iso_request *alloc_iso_request(struct usb_ep *ep,
411                                                  int packets, gfp_t gfp_flags)
412 {
413         struct usb_iso_request *pReq = NULL;
414         uint32_t req_size;
415
416         req_size = sizeof(struct usb_iso_request);
417         req_size +=
418             (2 * packets * (sizeof(struct usb_gadget_iso_packet_descriptor)));
419
420         pReq = dwc_alloc(req_size);
421         if (!pReq) {
422                 DWC_WARN("Can't allocate Iso Request\n");
423                 return 0;
424         }
425         pReq->iso_packet_desc0 = (void *)(pReq + 1);
426
427         pReq->iso_packet_desc1 = pReq->iso_packet_desc0 + packets;
428
429         return pReq;
430 }
431
432 static void free_iso_request(struct usb_ep *ep, struct usb_iso_request *req)
433 {
434         kfree(req);
435 }
436
437 static struct usb_isoc_ep_ops dwc_otg_pcd_ep_ops = {
438         .ep_ops = {
439                    .enable = ep_enable,
440                    .disable = ep_disable,
441
442                    .alloc_request = dwc_otg_pcd_alloc_request,
443                    .free_request = dwc_otg_pcd_free_request,
444
445                    .alloc_buffer = dwc_otg_pcd_alloc_buffer,
446                    .free_buffer = dwc_otg_pcd_free_buffer,
447
448                    .queue = ep_queue,
449                    .dequeue = ep_dequeue,
450
451                    .set_halt = ep_halt,
452                    .fifo_status = 0,
453                    .fifo_flush = 0,
454                    },
455         .iso_ep_start = iso_ep_start,
456         .iso_ep_stop = iso_ep_stop,
457         .alloc_iso_request = alloc_iso_request,
458         .free_iso_request = free_iso_request,
459 };
460
461 #else
462
463 static struct usb_ep_ops dwc_otg_pcd_ep_ops = {
464         .enable = ep_enable,
465         .disable = ep_disable,
466
467         .alloc_request = dwc_otg_pcd_alloc_request,
468         .free_request = dwc_otg_pcd_free_request,
469
470         .queue = ep_queue,
471         .dequeue = ep_dequeue,
472
473         .set_halt = ep_halt,
474         .fifo_status = 0,
475         .fifo_flush = 0,
476
477 };
478
479 #endif                          /* _EN_ISOC_ */
480 /*      Gadget Operations */
481 /**
482  * The following gadget operations will be implemented in the DWC_otg
483  * PCD. Functions in the API that are not described below are not
484  * implemented.
485  *
486  * The Gadget API provides wrapper functions for each of the function
487  * pointers defined in usb_gadget_ops. The Gadget Driver calls the
488  * wrapper function, which then calls the underlying PCD function. The
489  * following sections are named according to the wrapper functions
490  * (except for ioctl, which doesn't have a wrapper function). Within
491  * each section, the corresponding DWC_otg PCD function name is
492  * specified.
493  *
494  */
495
496 /**
497  *Gets the USB Frame number of the last SOF.
498  */
499 static int get_frame_number(struct usb_gadget *gadget)
500 {
501         struct gadget_wrapper *d;
502
503         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
504
505         if (gadget == 0) {
506                 return -ENODEV;
507         }
508
509         d = container_of(gadget, struct gadget_wrapper, gadget);
510         return dwc_otg_pcd_get_frame_number(d->pcd);
511 }
512
513 #ifdef CONFIG_USB_DWC_OTG_LPM
514 static int test_lpm_enabled(struct usb_gadget *gadget)
515 {
516         struct gadget_wrapper *d;
517
518         d = container_of(gadget, struct gadget_wrapper, gadget);
519
520         return dwc_otg_pcd_is_lpm_enabled(d->pcd);
521 }
522 #endif
523
524 #include <common.h>
525 #include <asm/arch/regs_ahb.h>
526 #include <asm/arch/ldo.h>
527 #include <asm/arch/regs_global.h>
528
529
530 static void __raw_bits_and(unsigned int v, unsigned int a)
531 {
532         __raw_writel((__raw_readl(a) & v), a);
533         
534 }
535
536 static void __raw_bits_or(unsigned int v, unsigned int a)
537 {
538         __raw_writel((__raw_readl(a) | v), a);
539 }
540
541 extern void __udelay (unsigned long usec);
542 static inline
543 void    usb_ldo_switch(int flag)
544 {
545         if(flag){
546             LDO_TurnOnLDO(LDO_LDO_USB);
547             __udelay (200);
548         } else {
549             LDO_TurnOffLDO(LDO_LDO_USB);
550         }
551 }
552
553 static void usb_enable_module(int en)
554 {
555         if (en){
556 #if defined( CONFIG_SC8830) || defined(CONFIG_SC9630)
557                 __raw_bits_or(BIT_4, AHB_CTL0);
558 #else
559                 __raw_bits_or(BIT_6, AHB_CTL3);
560                 __raw_bits_and(~BIT_9, GR_CLK_GEN5);
561 #endif
562                 //__raw_bits_or(BIT_5, AHB_CTL0);
563         }else {
564 #if defined( CONFIG_SC8830) || defined(CONFIG_SC9630)
565                 __raw_bits_and(~BIT_4, AHB_CTL0);
566 #else
567                 __raw_bits_and(~BIT_6, AHB_CTL3);
568                 __raw_bits_or(BIT_9, GR_CLK_GEN5);
569                 __raw_bits_and(~BIT_5, AHB_CTL0);
570 #endif
571         }
572 }
573 static void usb_startup(void)
574 {
575         usb_enable_module(1);
576         dwc_mdelay(10);
577         usb_ldo_switch(0);
578 #if defined( CONFIG_SC8830) || defined(CONFIG_SC9630)
579 #else
580         __raw_bits_and(~BIT_1, AHB_CTL3);
581         __raw_bits_and(~BIT_2, AHB_CTL3);
582 #endif
583         usb_ldo_switch(1);
584 #if defined(CONFIG_SPX20)
585         dwc_mdelay(10);
586 #endif
587
588 #if defined( CONFIG_SC8830) || defined(CONFIG_SC9630)
589 #if defined(CONFIG_SPX20)
590         __raw_bits_or(BIT_4, AHB_CTL0);
591         __raw_bits_or(BIT_5|BIT_6, AHB_SOFT_RST);
592         dwc_mdelay(5);
593         __raw_bits_and(~(BIT_5|BIT_6), AHB_SOFT_RST);
594
595         __raw_bits_or(BIT_3, USB_GUSBCFG);//SPRD USB PHY width: 16 bit
596
597         __raw_bits_and(~BIT_0, AP_TOP_USB_PHY_RST_PIN_CTL);//utmi_porn
598         __raw_bits_or(BIT_7, AHB_SOFT_RST);//utmi_rst
599         dwc_mdelay(5);
600         __raw_bits_or(BIT_0, AP_TOP_USB_PHY_RST_PIN_CTL);
601         __raw_bits_and(~BIT_7, AHB_SOFT_RST);
602 #else
603         __raw_bits_or(BIT_4, AHB_CTL0);
604         __raw_bits_or(BIT_5|BIT_6|BIT_7, AHB_SOFT_RST);
605         __udelay (50);
606         __raw_bits_and(~(BIT_5|BIT_6|BIT_7), AHB_SOFT_RST);
607 #endif
608
609 #else
610         __raw_bits_or(BIT_6, AHB_CTL3);
611         __raw_bits_or(BIT_6|BIT_7, AHB_SOFT_RST);
612         dwc_mdelay(5);
613         __raw_bits_and(~(BIT_6|BIT_7), AHB_SOFT_RST);
614
615         __raw_bits_or(BIT_5, AHB_CTL0);
616 #endif
617         dwc_mdelay(3);
618 }
619
620 static void udc_disable(void)
621 {
622         usb_enable_module(0);
623         usb_ldo_switch(0);
624 }
625
626 void udc_power_on(void)
627 {
628         if(readl(CHIP_ID) == 0x88100001){
629                 /*SMIC chip id == 0x88100001*/
630                 __raw_bits_or(BIT_9, USB_PHY_CTRL);
631                 __raw_bits_and(~(BIT_15 | BIT_14), USB_PHY_CTRL);
632                 __raw_bits_or(BIT_13 | BIT_12, USB_PHY_CTRL);
633                 writel(0x28,USB_SPR_REG);
634         }else{
635                 /*
636                  * config usb phy controller
637                  */
638                 /*SMIC chip id == 0x88100001*/
639 #ifdef  CONFIG_SC7710G2
640                 __raw_bits_or(BIT_9, USB_PHY_CTRL);
641                 __raw_bits_and(~(BIT_15 | BIT_14), USB_PHY_CTRL);
642                 __raw_bits_or(BIT_13 | BIT_12, USB_PHY_CTRL);
643                 writel(0x28,USB_SPR_REG);
644 #else
645                 __raw_bits_or(BIT_8, USB_PHY_CTRL);
646                 __raw_bits_or(BIT_17, USB_PHY_CTRL);
647                 __raw_bits_and(~BIT_16, USB_PHY_CTRL);
648                 __raw_bits_and(~(BIT_13 | BIT_12), USB_PHY_CTRL);
649                 __raw_bits_or(BIT_15 | BIT_14, USB_PHY_CTRL);
650 #endif
651         }
652
653         usb_startup();
654 }
655
656 void udc_power_off(void)
657 {
658         udc_disable();
659 }
660 /**
661  * Initiates Session Request Protocol (SRP) to wakeup the host if no
662  * session is in progress. If a session is already in progress, but
663  * the device is suspended, remote wakeup signaling is started.
664  *
665  */
666 static int wakeup(struct usb_gadget *gadget)
667 {
668         struct gadget_wrapper *d;
669
670         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, gadget);
671
672         if (gadget == 0) {
673                 return -ENODEV;
674         } else {
675                 d = container_of(gadget, struct gadget_wrapper, gadget);
676         }
677         dwc_otg_pcd_wakeup(d->pcd);
678         return 0;
679 }
680
681 static const struct usb_gadget_ops dwc_otg_pcd_ops = {
682         .get_frame = get_frame_number,
683         .wakeup = wakeup,
684         // current versions must always be self-powered
685 };
686
687 static int _setup(dwc_otg_pcd_t * pcd, uint8_t * bytes)
688 {
689         int retval = -DWC_E_NOT_SUPPORTED;
690         if (gadget_wrapper->driver && gadget_wrapper->driver->setup) {
691                 retval = gadget_wrapper->driver->setup(&gadget_wrapper->gadget,
692                                                        (struct usb_ctrlrequest
693                                                         *)bytes);
694         }
695
696         //sword
697         //if (retval == -ENOTSUPP) {
698         if (retval == -EOPNOTSUPP) {
699                 retval = -DWC_E_NOT_SUPPORTED;
700         } else if (retval < 0) {
701                 retval = -DWC_E_INVALID;
702         }
703
704         return retval;
705 }
706
707 #ifdef DWC_EN_ISOC
708 static int _isoc_complete(dwc_otg_pcd_t * pcd, void *ep_handle,
709                           void *req_handle, int proc_buf_num)
710 {
711         int i, packet_count;
712         struct usb_gadget_iso_packet_descriptor *iso_packet = 0;
713         struct usb_iso_request *iso_req = req_handle;
714
715         if (proc_buf_num) {
716                 iso_packet = iso_req->iso_packet_desc1;
717         } else {
718                 iso_packet = iso_req->iso_packet_desc0;
719         }
720         packet_count =
721             dwc_otg_pcd_get_iso_packet_count(pcd, ep_handle, req_handle);
722         for (i = 0; i < packet_count; ++i) {
723                 int status;
724                 int actual;
725                 int offset;
726                 dwc_otg_pcd_get_iso_packet_params(pcd, ep_handle, req_handle,
727                                                   i, &status, &actual, &offset);
728                 switch (status) {
729                 case -DWC_E_NO_DATA:
730                         status = -ENODATA;
731                         break;
732                 default:
733                         if (status) {
734                                 DWC_DEBUGPL(DBG_CIL,"unknown status in isoc packet\n");
735                         }
736
737                 }
738                 iso_packet[i].status = status;
739                 iso_packet[i].offset = offset;
740                 iso_packet[i].actual_length = actual;
741         }
742
743         iso_req->status = 0;
744         iso_req->process_buffer(ep_handle, iso_req);
745
746         return 0;
747 }
748 #endif                          /* DWC_EN_ISOC */
749
750 static int _complete(dwc_otg_pcd_t * pcd, void *ep_handle,
751                      void *req_handle, int32_t status, uint32_t actual)
752 {
753         struct usb_request *req = (struct usb_request *)req_handle;
754
755         if (req && req->complete) {
756                 switch (status) {
757                 case -DWC_E_SHUTDOWN:
758                         req->status = -ESHUTDOWN;
759                         break;
760                 case -DWC_E_RESTART:
761                         req->status = -ECONNRESET;
762                         break;
763                 case -DWC_E_INVALID:
764                         req->status = -EINVAL;
765                         break;
766                 case -DWC_E_TIMEOUT:
767                         req->status = -ETIMEDOUT;
768                         break;
769                 default:
770                         req->status = status;
771
772                 }
773                 req->actual = actual;
774                 req->complete(ep_handle, req);
775         }
776
777         return 0;
778 }
779
780 static int _connect(dwc_otg_pcd_t * pcd, int speed)
781 {
782         gadget_wrapper->gadget.speed = speed;
783         return 0;
784 }
785
786 static int _disconnect(dwc_otg_pcd_t * pcd)
787 {
788         if (gadget_wrapper->driver && gadget_wrapper->driver->disconnect) {
789                 gadget_wrapper->driver->disconnect(&gadget_wrapper->gadget);
790         }
791         return 0;
792 }
793
794 static int _resume(dwc_otg_pcd_t * pcd)
795 {
796         if (gadget_wrapper->driver && gadget_wrapper->driver->resume) {
797                 gadget_wrapper->driver->resume(&gadget_wrapper->gadget);
798         }
799
800         return 0;
801 }
802
803 static int _suspend(dwc_otg_pcd_t * pcd)
804 {
805         if (gadget_wrapper->driver && gadget_wrapper->driver->suspend) {
806                 gadget_wrapper->driver->suspend(&gadget_wrapper->gadget);
807         }
808         return 0;
809 }
810
811 /**
812  * This function updates the otg values in the gadget structure.
813  */
814 static int _hnp_changed(dwc_otg_pcd_t * pcd)
815 {
816
817         if (!gadget_wrapper->gadget.is_otg)
818                 return 0;
819
820         gadget_wrapper->gadget.b_hnp_enable = get_b_hnp_enable(pcd);
821         gadget_wrapper->gadget.a_hnp_support = get_a_hnp_support(pcd);
822         gadget_wrapper->gadget.a_alt_hnp_support = get_a_alt_hnp_support(pcd);
823         return 0;
824 }
825
826 static int _reset(dwc_otg_pcd_t * pcd)
827 {
828         return 0;
829 }
830
831 #ifdef DWC_UTE_CFI
832 static int _cfi_setup(dwc_otg_pcd_t * pcd, void *cfi_req)
833 {
834         int retval = -DWC_E_INVALID;
835         if (gadget_wrapper->driver->cfi_feature_setup) {
836                 retval =
837                     gadget_wrapper->driver->cfi_feature_setup(&gadget_wrapper->
838                                                               gadget,
839                                                               (struct
840                                                                cfi_usb_ctrlrequest
841                                                                *)cfi_req);
842         }
843
844         return retval;
845 }
846 #endif
847
848 static const struct dwc_otg_pcd_function_ops fops = {
849         .complete = _complete,
850 #ifdef DWC_EN_ISOC
851         .isoc_complete = _isoc_complete,
852 #endif
853         .setup = _setup,
854         .disconnect = _disconnect,
855         .connect = _connect,
856         .resume = _resume,
857         .suspend = _suspend,
858         .hnp_changed = _hnp_changed,
859         .reset = _reset,
860 #ifdef DWC_UTE_CFI
861         .cfi_setup = _cfi_setup,
862 #endif
863 };
864
865 static dwc_otg_pcd_t *sprd_pcd;
866 /**
867  * This function is the top level PCD interrupt handler.
868  */
869 static int dwc_otg_pcd_irq(int irq, void *dev)
870 {
871         dwc_otg_pcd_t *pcd = dev;
872         int32_t retval = 0;
873
874         retval = dwc_otg_pcd_handle_intr(pcd);
875         if (retval != 0) {
876                 S3C2410X_CLEAR_EINTPEND();
877         }
878
879         return 0;
880         //return IRQ_RETVAL(retval);
881 }
882
883 /**
884  * This function initialized the usb_ep structures to there default
885  * state.
886  *
887  * @param d Pointer on gadget_wrapper.
888  */
889 void gadget_add_eps(struct gadget_wrapper *d)
890 {
891         static const char *names[] = {
892
893                 "ep0",
894                 "ep1in",
895                 "ep2in",
896                 "ep3in",
897                 "ep4in",
898                 "ep5in",
899                 "ep6in",
900                 "ep7in",
901                 "ep8in",
902                 "ep9in",
903                 "ep10in",
904                 "ep11in",
905                 "ep12in",
906                 "ep13in",
907                 "ep14in",
908                 "ep15in",
909                 "ep1out",
910                 "ep2out",
911                 "ep3out",
912                 "ep4out",
913                 "ep5out",
914                 "ep6out",
915                 "ep7out",
916                 "ep8out",
917                 "ep9out",
918                 "ep10out",
919                 "ep11out",
920                 "ep12out",
921                 "ep13out",
922                 "ep14out",
923                 "ep15out"
924         };
925
926         int i;
927         struct usb_ep *ep;
928
929         DWC_DEBUGPL(DBG_PCDV, "%s\n", __func__);
930
931         INIT_LIST_HEAD(&d->gadget.ep_list);
932         d->gadget.ep0 = &d->ep0;
933         d->gadget.speed = USB_SPEED_UNKNOWN;
934
935         INIT_LIST_HEAD(&d->gadget.ep0->ep_list);
936
937         /**
938          * Initialize the EP0 structure.
939          */
940         ep = &d->ep0;
941
942         /* Init the usb_ep structure. */
943         ep->name = names[0];
944         ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
945
946         /**
947          * @todo NGS: What should the max packet size be set to
948          * here?  Before EP type is set?
949          */
950         ep->maxpacket = MAX_PACKET_SIZE;
951         dwc_otg_pcd_ep_enable(d->pcd, NULL, ep);
952
953         list_add_tail(&ep->ep_list, &d->gadget.ep_list);
954
955         /**
956          * Initialize the EP structures.
957          */
958
959         for (i = 0; i < 15; i++) {
960                 ep = &d->in_ep[i];
961
962                 /* Init the usb_ep structure. */
963                 ep->name = names[i + 1];
964                 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
965
966                 /**
967                  * @todo NGS: What should the max packet size be set to
968                  * here?  Before EP type is set?
969                  */
970                 ep->maxpacket = MAX_PACKET_SIZE;
971                 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
972         }
973
974         for (i = 0; i < 15; i++) {
975                 ep = &d->out_ep[i];
976
977                 /* Init the usb_ep structure. */
978                 ep->name = names[15 + i + 1];
979                 ep->ops = (struct usb_ep_ops *)&dwc_otg_pcd_ep_ops;
980
981                 /**
982                  * @todo NGS: What should the max packet size be set to
983                  * here?  Before EP type is set?
984                  */
985                 ep->maxpacket = MAX_PACKET_SIZE;
986
987                 list_add_tail(&ep->ep_list, &d->gadget.ep_list);
988         }
989
990         /* remove ep0 from the list.  There is a ep0 pointer. */
991         list_del_init(&d->ep0.ep_list);
992
993         d->ep0.maxpacket = MAX_EP0_SIZE;
994 }
995
996 /**
997  * This function releases the Gadget device.
998  * required by device_unregister().
999  *
1000  * @todo Should this do something?      Should it free the PCD?
1001  */
1002 static void dwc_otg_pcd_gadget_release(struct device *dev)
1003 {
1004         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
1005 }
1006
1007 static struct gadget_wrapper *alloc_wrapper(
1008         struct dwc_otg_device *_dev
1009         )
1010 {
1011         static char pcd_name[] = "dwc_otg";
1012         //dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev);
1013         dwc_otg_device_t *otg_dev = _dev;
1014         struct gadget_wrapper *d;
1015         int retval;
1016
1017         d = dwc_alloc(sizeof(*d));
1018         if (d == NULL) {
1019                 return NULL;
1020         }
1021
1022         memset(d, 0, sizeof(*d));
1023
1024         d->gadget.name = pcd_name;
1025         d->pcd = otg_dev->pcd;
1026         //sword
1027         /*
1028         strcpy(d->gadget.dev.bus_id, "gadget");
1029         */
1030         #if 0
1031         dev_set_name(&d->gadget.dev, "gadget");
1032         d->gadget.dev.parent = &_dev->dev;
1033         d->gadget.dev.release = dwc_otg_pcd_gadget_release;
1034         #endif
1035         d->gadget.ops = &dwc_otg_pcd_ops;
1036         d->gadget.is_dualspeed = dwc_otg_pcd_is_dualspeed(otg_dev->pcd);
1037         d->gadget.is_otg = dwc_otg_pcd_is_otg(otg_dev->pcd);
1038
1039         d->driver = 0;
1040         /* Register the gadget device */
1041         #if 0
1042         retval = device_register(&d->gadget.dev);
1043         if (retval != 0) {
1044                 DWC_ERROR("device_register failed\n");
1045                 dwc_free(d);
1046                 return NULL;
1047         }
1048         #endif
1049         
1050         return d;
1051 }
1052
1053 static void free_wrapper(struct gadget_wrapper *d)
1054 {
1055         if (d->driver) {
1056                 /* should have been done already by driver model core */
1057                 DWC_WARN("driver  is still registered\n");
1058                 usb_gadget_unregister_driver(d->driver);
1059         }
1060
1061         //device_unregister(&d->gadget.dev);
1062         dwc_free(d);
1063 }
1064
1065 /**
1066  * This function initialized the PCD portion of the driver.
1067  *
1068  */
1069 int pcd_init(
1070         struct dwc_otg_device *_dev
1071         )
1072 {
1073        //dwc_otg_device_t *otg_dev = platform_get_drvdata(_dev);
1074        dwc_otg_device_t *otg_dev = _dev;
1075         int retval = 0;
1076         int irq;
1077
1078         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1079
1080         otg_dev->pcd = dwc_otg_pcd_init(otg_dev->core_if);
1081
1082         if (!otg_dev->pcd) {
1083                 DWC_ERROR("dwc_otg_pcd_init failed\n");
1084                 return -ENOMEM;
1085         }
1086
1087         gadget_wrapper = alloc_wrapper(_dev);
1088
1089         /*
1090          * Initialize EP structures
1091          */
1092         gadget_add_eps(gadget_wrapper);
1093
1094         /*
1095          * Setup interupt handler
1096          */
1097          
1098         #if 0
1099         irq = platform_get_irq(_dev, 0);
1100         DWC_DEBUGPL(DBG_ANY, "registering handler for irq%d\n", irq);
1101         retval = request_irq(irq, dwc_otg_pcd_irq,
1102                              0, gadget_wrapper->gadget.name,
1103                              otg_dev->pcd);
1104                              //SA_SHIRQ, gadget_wrapper->gadget.name,
1105         if (retval != 0) {
1106                 DWC_ERROR("request of irq%d failed\n", irq);
1107                 free_wrapper(gadget_wrapper);
1108                 return -EBUSY;
1109         }
1110         #endif
1111         sprd_pcd = otg_dev->pcd;
1112         
1113         dwc_otg_pcd_start(gadget_wrapper->pcd, &fops);
1114
1115         return retval;
1116 }
1117
1118 /**
1119  * Cleanup the PCD.
1120  */
1121
1122 void pcd_remove(
1123         struct dwc_otg_device *_dev
1124
1125         )
1126 {
1127        dwc_otg_device_t *otg_dev = _dev;
1128         dwc_otg_pcd_t *pcd = otg_dev->pcd;
1129
1130         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _dev);
1131
1132         /*
1133          * Free the IRQ
1134          */
1135         //free_irq(_dev->irq, pcd);
1136         dwc_otg_pcd_remove(otg_dev->pcd);
1137         free_wrapper(gadget_wrapper);
1138         otg_dev->pcd = 0;
1139 }
1140
1141 /**
1142  * This function registers a gadget driver with the PCD.
1143  *
1144  * When a driver is successfully registered, it will receive control
1145  * requests including set_configuration(), which enables non-control
1146  * requests.  then usb traffic follows until a disconnect is reported.
1147  * then a host may connect again, or the driver might get unbound.
1148  *
1149  * @param driver The driver being registered
1150  */
1151 int usb_gadget_register_driver(struct usb_gadget_driver *driver)
1152 {
1153         int retval;
1154
1155         DWC_DEBUGPL(DBG_PCD, "registering gadget driver \n");
1156
1157         if (!driver || driver->speed == USB_SPEED_UNKNOWN ||
1158             !driver->bind ||
1159             !driver->disconnect || !driver->setup) {
1160             //!driver->unbind || !driver->disconnect || !driver->setup) {
1161                 DWC_DEBUGPL(DBG_PCDV, "EINVAL\n");
1162                 return -EINVAL;
1163         }
1164         if (gadget_wrapper == 0) {
1165                 DWC_DEBUGPL(DBG_PCDV, "ENODEV\n");
1166                 return -ENODEV;
1167         }
1168         if (gadget_wrapper->driver != 0) {
1169                 DWC_DEBUGPL(DBG_PCDV, "EBUSY (%p)\n", gadget_wrapper->driver);
1170                 return -EBUSY;
1171         }
1172
1173         /* hook up the driver */
1174         gadget_wrapper->driver = driver;
1175         //gadget_wrapper->gadget.dev.driver = &driver->driver;
1176
1177         DWC_DEBUGPL(DBG_PCD, "bind to driver \n");
1178         retval = driver->bind(&gadget_wrapper->gadget);
1179         if (retval) {
1180                 DWC_ERROR("bind to driver --> error %d\n",
1181                           retval);
1182                 gadget_wrapper->driver = 0;
1183                 //gadget_wrapper->gadget.dev.driver = 0;
1184                 return retval;
1185         }
1186         /*
1187         DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n",
1188                     driver->driver.name);
1189         */
1190         return 0;
1191 }
1192
1193
1194 /**
1195  * This function unregisters a gadget driver
1196  *
1197  * @param driver The driver being unregistered
1198  */
1199 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1200 {
1201         //DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver);
1202
1203         if (gadget_wrapper == 0) {
1204                 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__,
1205                             -ENODEV);
1206                 return -ENODEV;
1207         }
1208         if (driver == 0 || driver != gadget_wrapper->driver) {
1209                 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): driver?\n", __func__,
1210                             -EINVAL);
1211                 return -EINVAL;
1212         }
1213
1214         driver->unbind(&gadget_wrapper->gadget);
1215         gadget_wrapper->driver = 0;
1216
1217         DWC_DEBUGPL(DBG_ANY, "unregistered driver \n");
1218         return 0;
1219 }
1220
1221 int usb_gadget_handle_interrupts(void)
1222 {
1223         dwc_otg_pcd_irq(0, sprd_pcd);
1224        return 0;
1225 }
1226         
1227 #endif                          /* DWC_HOST_ONLY */
1228