gitignore: ignore scripts/bmptologo
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg / dwc_otg_pcd.c
1  /* ==========================================================================
2  * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_pcd.c $
3  * $Revision: #18 $
4  * $Date: 2007/02/07 $
5  * $Change: 791271 $
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  * An important function of the PCD is managing interrupts generated
55  * by the DWC_otg controller. The implementation of the DWC_otg device
56  * mode interrupt service routines is in dwc_otg_pcd_intr.c.
57  *
58  * @todo Add Device Mode test modes (Test J mode, Test K mode, etc).
59  * @todo Does it work when the request size is greater than DEPTSIZ
60  * transfer size
61  *
62  */
63
64 #include <linux/clk.h>
65 #include <linux/kernel.h>
66 #include <linux/module.h>
67 #include <linux/moduleparam.h>
68 #include <linux/init.h>
69 #include <linux/device.h>
70 #include <linux/errno.h>
71 #include <linux/list.h>
72 #include <linux/interrupt.h>
73 #include <linux/string.h>
74 #include <linux/dma-mapping.h>
75 #include <linux/irq.h>
76 #include <linux/kallsyms.h>
77
78 #include <linux/usb/ch9.h>
79 #include <linux/usb/gadget.h>
80 #include <linux/platform_device.h>
81
82 #include "dwc_otg_driver.h"
83 #include "dwc_otg_pcd.h"
84 #include "dwc_otg_regs.h"
85
86 #include <linux/usb/composite.h>
87 #ifdef CONFIG_ARCH_RK29
88 #include <mach/cru.h>
89 #endif
90 /**
91  * Static PCD pointer for use in usb_gadget_register_driver and
92  * usb_gadget_unregister_driver.  Initialized in dwc_otg_pcd_init.
93  */
94  static 
95  dwc_otg_pcd_t *s_pcd = 0;
96
97
98 /* Display the contents of the buffer */
99 extern void dump_msg(const u8 *buf, unsigned int length);
100
101
102 /**
103  * This function completes a request.  It call's the request call back.
104  */
105 void request_done(dwc_otg_pcd_ep_t *_ep, dwc_otg_pcd_request_t *_req, 
106                                   int _status)
107 {
108         unsigned stopped = _ep->stopped;
109     
110         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _ep);
111         list_del_init(&_req->queue);
112
113         if (_req->req.status == -EINPROGRESS) 
114         {
115                 _req->req.status = _status;
116         } 
117         else 
118         {       
119                 _status = _req->req.status;
120         }
121 #if 1
122     if (_req->req.dma != DMA_ADDR_INVALID){
123         if (_req->mapped) {
124                 dma_unmap_single(_ep->pcd->gadget.dev.parent,
125                         _req->req.dma, _req->req.length,
126                         _ep->dwc_ep.is_in
127                                 ? DMA_TO_DEVICE
128                                 : DMA_FROM_DEVICE);
129                 _req->req.dma = DMA_ADDR_INVALID;
130                 _req->mapped = 0;
131         } else
132                 dma_sync_single_for_cpu(_ep->pcd->gadget.dev.parent,
133                         _req->req.dma, _req->req.length,
134                         _ep->dwc_ep.is_in
135                                 ? DMA_TO_DEVICE
136                                 : DMA_FROM_DEVICE);
137         }
138 #endif
139         /* don't modify queue heads during completion callback */
140         _ep->stopped = 1;
141         SPIN_UNLOCK(&_ep->pcd->lock);
142         _req->req.complete(&_ep->ep, &_req->req);
143         SPIN_LOCK(&_ep->pcd->lock);
144
145         if (_ep->pcd->request_pending > 0)
146         {
147                 --_ep->pcd->request_pending;
148         }
149                 
150         _ep->stopped = stopped;
151 }
152
153 /**
154  * This function terminates all the requsts in the EP request queue.
155  */
156 void request_nuke( dwc_otg_pcd_ep_t *_ep )
157 {
158         dwc_otg_pcd_request_t *req;
159
160         _ep->stopped = 1;
161
162         /* called with irqs blocked?? */
163         while (!list_empty(&_ep->queue)) 
164         {
165                 req = list_entry(_ep->queue.next, dwc_otg_pcd_request_t,
166                                  queue);
167                 request_done(_ep, req, -ESHUTDOWN );
168         }
169 }
170
171 /* USB Endpoint Operations */
172 /* 
173  * The following sections briefly describe the behavior of the Gadget
174  * API endpoint operations implemented in the DWC_otg driver
175  * software. Detailed descriptions of the generic behavior of each of
176  * these functions can be found in the Linux header file
177  * include/linux/usb_gadget.h.
178  *
179  * The Gadget API provides wrapper functions for each of the function
180  * pointers defined in usb_ep_ops. The Gadget Driver calls the wrapper
181  * function, which then calls the underlying PCD function. The
182  * following sections are named according to the wrapper
183  * functions. Within each section, the corresponding DWC_otg PCD
184  * function name is specified.
185  *
186  */
187
188 /**
189  * This function assigns periodic Tx FIFO to an periodic EP
190  * in shared Tx FIFO mode
191  */
192  #if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
193 static uint32_t assign_perio_tx_fifo(dwc_otg_core_if_t  *core_if)
194 {
195         uint32_t PerTxMsk = 1;
196         int i;
197         for(i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; ++i)
198         {
199                 if((PerTxMsk & core_if->p_tx_msk) == 0)
200                 {
201                         core_if->p_tx_msk |= PerTxMsk;
202                         return i + 1;
203                 }
204                 PerTxMsk <<= 1;
205         }
206         return 0;
207 }
208 #endif
209 /**
210  * This function releases periodic Tx FIFO 
211  * in shared Tx FIFO mode
212  */
213 static void release_perio_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num)
214 {
215         core_if->p_tx_msk = (core_if->p_tx_msk & (1 << (fifo_num - 1))) ^ core_if->p_tx_msk;
216 }
217 /**
218  * This function assigns periodic Tx FIFO to an periodic EP
219  * in Dedicated FIFOs mode
220  */
221 #if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
222 static uint32_t assign_tx_fifo(dwc_otg_core_if_t *core_if)
223 {
224         uint32_t TxMsk = 1;
225         int i;
226         
227         for(i = 0; i < core_if->hwcfg4.b.num_in_eps; ++i)
228         {
229                 if((TxMsk & core_if->tx_msk) == 0)
230                 {
231                         core_if->tx_msk |= TxMsk;
232                         return i + 1;
233                 }
234                 TxMsk <<= 1;
235         }
236         return 0;
237 }
238 #endif
239 /**
240  * This function releases periodic Tx FIFO 
241  * in Dedicated FIFOs mode
242  */
243 static void release_tx_fifo(dwc_otg_core_if_t   *core_if, uint32_t fifo_num)
244 {
245         core_if->tx_msk = (core_if->tx_msk & (1 << (fifo_num - 1))) ^ core_if->tx_msk;
246 }
247 /**
248  * This function is called by the Gadget Driver for each EP to be
249  * configured for the current configuration (SET_CONFIGURATION).  
250  * 
251  * This function initializes the dwc_otg_ep_t data structure, and then
252  * calls dwc_otg_ep_activate.
253  */
254 static int dwc_otg_pcd_ep_enable(struct usb_ep *_ep, 
255                                                                  const struct usb_endpoint_descriptor *_desc)
256 {
257         dwc_otg_pcd_ep_t *ep = 0;
258         dwc_otg_pcd_t *pcd = 0;
259         unsigned long flags;
260         
261         DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, _ep, _desc );
262              
263         ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
264         if (!_ep || !_desc || ep->desc || 
265                         _desc->bDescriptorType != USB_DT_ENDPOINT) 
266         {
267                 DWC_WARN( "%s, bad ep or descriptor\n", __func__);
268                 return -EINVAL;
269         }
270         if (ep == &ep->pcd->ep0)
271         {
272                 DWC_WARN("%s, bad ep(0)\n", __func__);
273                 return -EINVAL;
274         }
275                 
276         /* Check FIFO size? */
277         if (!_desc->wMaxPacketSize) 
278         {
279                 DWC_WARN("%s, bad %s maxpacket\n", __func__, _ep->name);
280                 return -ERANGE;
281         }
282
283         pcd = ep->pcd;
284         if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) 
285         {
286                 DWC_WARN("%s, bogus device state\n", __func__);
287                 return -ESHUTDOWN;
288         }
289
290         SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
291                 
292         ep->desc = _desc;
293         ep->ep.maxpacket = le16_to_cpu (_desc->wMaxPacketSize);
294                 
295         /*
296          * Activate the EP
297          */
298         ep->stopped = 0;
299                 
300         ep->dwc_ep.is_in = (USB_DIR_IN & _desc->bEndpointAddress) != 0;
301         ep->dwc_ep.maxpacket = ep->ep.maxpacket;
302         
303         ep->dwc_ep.type = _desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
304
305         if(ep->dwc_ep.is_in)
306         {
307 #if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
308                 if(!pcd->otg_dev->core_if->en_multiple_tx_fifo)
309                 {
310                         ep->dwc_ep.tx_fifo_num = 0;
311                 
312                         if ((_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 
313                                 USB_ENDPOINT_XFER_ISOC ) 
314                         {
315                                 /* 
316                                  * if ISOC EP then assign a Periodic Tx FIFO.
317                                  */
318                                 ep->dwc_ep.tx_fifo_num = assign_perio_tx_fifo(pcd->otg_dev->core_if);
319                          }
320                 }
321                 else
322                 {
323                         /* 
324                          * if Dedicated FIFOs mode is on then assign a Tx FIFO.
325                          */
326                         ep->dwc_ep.tx_fifo_num = assign_tx_fifo(pcd->otg_dev->core_if);
327                 }
328 #else
329         /* yk@rk
330          * ep0 -- tx fifo 0
331          * ep1 -- tx fifo 1
332          * ep3 -- tx fifo 3
333          * ep5 -- tx fifo 2
334          */
335         if(ep->dwc_ep.num == 0)
336                 ep->dwc_ep.tx_fifo_num = 0;
337         else if(ep->dwc_ep.num == 1)
338                 ep->dwc_ep.tx_fifo_num = 1;
339         else if(ep->dwc_ep.num == 3)
340                 ep->dwc_ep.tx_fifo_num = 3;
341         else if(ep->dwc_ep.num == 5)
342                 ep->dwc_ep.tx_fifo_num = 2;
343         else
344             ep->dwc_ep.tx_fifo_num = (ep->dwc_ep.num>>1)+1 ; /* 1,3,5 */
345 #endif
346         }                
347         /* Set initial data PID. */
348         if ((_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 
349                         USB_ENDPOINT_XFER_BULK ) 
350         {
351                 ep->dwc_ep.data_pid_start = 0;  
352         }
353                 
354         DWC_DEBUGPL(DBG_PCD, "Activate %s-%s: type=%d, mps=%d desc=%p\n", 
355                                         ep->ep.name, (ep->dwc_ep.is_in ?"IN":"OUT"),
356                                         ep->dwc_ep.type, ep->dwc_ep.maxpacket, ep->desc );
357                 
358         dwc_otg_ep_activate( GET_CORE_IF(pcd), &ep->dwc_ep );
359         SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
360         return 0;
361 }
362
363 /** 
364  * This function is called when an EP is disabled due to disconnect or
365  * change in configuration. Any pending requests will terminate with a
366  * status of -ESHUTDOWN.
367  *
368  * This function modifies the dwc_otg_ep_t data structure for this EP,
369  * and then calls dwc_otg_ep_deactivate.
370  */
371 static int dwc_otg_pcd_ep_disable(struct usb_ep *_ep)
372 {
373         dwc_otg_pcd_ep_t *ep;
374         unsigned long flags;
375
376              
377         DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _ep);
378         ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
379         if (!_ep || !ep->desc) 
380         {
381                 DWC_DEBUGPL(DBG_PCD, "%s, %s not enabled\n", __func__,
382                         _ep ? ep->ep.name : NULL);
383                 return -EINVAL;
384         }
385                 
386         SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
387         request_nuke( ep );                
388
389         dwc_otg_ep_deactivate( GET_CORE_IF(ep->pcd), &ep->dwc_ep );
390         ep->desc = 0;
391         ep->stopped = 1;
392         
393         if(ep->dwc_ep.is_in)
394         {
395                 release_perio_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
396                 release_tx_fifo(GET_CORE_IF(ep->pcd), ep->dwc_ep.tx_fifo_num);
397         }       
398         
399         SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
400
401         DWC_DEBUGPL(DBG_PCD, "%s disabled\n", _ep->name);
402         return 0;
403 }
404
405 /**
406  * This function allocates a request object to use with the specified
407  * endpoint.
408  *
409  * @param _ep The endpoint to be used with with the request
410  * @param _gfp_flags the GFP_* flags to use.
411  */
412 static struct usb_request *dwc_otg_pcd_alloc_request(struct usb_ep *_ep,
413                                                                                                          gfp_t _gfp_flags)
414 {
415         dwc_otg_pcd_request_t *req;
416         DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d)\n", __func__, _ep, _gfp_flags);
417         if (0 == _ep ) 
418         {
419                 DWC_WARN("%s() %s\n", __func__, "Invalid EP!\n");
420                 return 0;
421         }
422         req = kmalloc( sizeof(dwc_otg_pcd_request_t), _gfp_flags);
423         if (0 == req)
424         {
425                 DWC_WARN("%s() %s\n", __func__, 
426                                  "request allocation failed!\n");
427                 return 0;
428         }
429         memset(req, 0, sizeof(dwc_otg_pcd_request_t));
430         req->req.dma = DMA_ADDR_INVALID;
431         INIT_LIST_HEAD(&req->queue);
432         return &req->req;
433 }
434
435 /**
436  * This function frees a request object.
437  *
438  * @param _ep The endpoint associated with the request
439  * @param _req The request being freed
440  */
441 static void dwc_otg_pcd_free_request(struct usb_ep *_ep,
442                                                                          struct usb_request *_req)
443 {
444         dwc_otg_pcd_request_t *req;
445         DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, _ep, _req);
446
447         if (0 == _ep || 0 == _req) 
448         {
449                 DWC_WARN("%s() %s\n", __func__, 
450                                  "Invalid ep or req argument!\n");
451                 return;
452         }
453                 
454         req = container_of(_req, dwc_otg_pcd_request_t, req);
455         kfree(req);
456 }
457 #if 0
458 /**
459  * This function allocates an I/O buffer to be used for a transfer
460  * to/from the specified endpoint.
461  * 
462  * @param _ep The endpoint to be used with with the request
463  * @param _bytes The desired number of bytes for the buffer
464  * @param _dma Pointer to the buffer's DMA address; must be valid
465  * @param _gfp_flags the GFP_* flags to use.
466  * @return address of a new buffer or null is buffer could not be allocated.
467  */
468 static void *dwc_otg_pcd_alloc_buffer(struct usb_ep *_ep, unsigned _bytes,
469                                                                           dma_addr_t *_dma, int _gfp_flags)
470 {
471         void *buf;
472         dwc_otg_pcd_ep_t *ep;
473         dwc_otg_pcd_t *pcd = 0;
474
475         ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
476         pcd = ep->pcd;
477
478         DWC_DEBUGPL(DBG_PCDV,"%s(%p,%d,%p,%0x)\n", __func__, _ep, _bytes, 
479                                 _dma, _gfp_flags);
480
481         /* Check dword alignment */
482         if ((_bytes & 0x3UL) != 0) 
483         {
484                 DWC_WARN("%s() Buffer size is not a multiple of" 
485                                  "DWORD size (%d)",__func__, _bytes);
486         }
487
488         if (GET_CORE_IF(pcd)->dma_enable) 
489         {
490                 buf = dma_alloc_coherent (NULL, _bytes, _dma, _gfp_flags);
491         }
492         else 
493         {
494                 buf = kmalloc( _bytes, _gfp_flags);
495         }
496
497         /* Check dword alignment */
498         if (((int)buf & 0x3UL) != 0) 
499         {
500                 DWC_WARN("%s() Buffer is not DWORD aligned (%p)",
501                                         __func__, buf);
502         }
503                 
504         return buf;
505 }
506
507 /**
508  * This function frees an I/O buffer that was allocated by alloc_buffer.
509  *
510  * @param _ep the endpoint associated with the buffer
511  * @param _buf address of the buffer
512  * @param _dma The buffer's DMA address
513  * @param _bytes The number of bytes of the buffer
514  */
515 static void dwc_otg_pcd_free_buffer(struct usb_ep *_ep, void *_buf,
516                                                                         dma_addr_t _dma, unsigned _bytes)
517 {
518         dwc_otg_pcd_ep_t *ep;
519         dwc_otg_pcd_t *pcd = 0;
520
521         ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
522         pcd = ep->pcd;
523
524         DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p,%0x,%d)\n", __func__, _ep, _buf, _dma, _bytes);
525         
526         if (GET_CORE_IF(pcd)->dma_enable) 
527         {
528                 dma_free_coherent (NULL, _bytes, _buf, _dma);
529         }
530         else 
531         {
532                 kfree( _buf );
533         }
534 }
535 #endif
536 /**
537  * This function is used to submit an I/O Request to an EP.
538  *
539  *      - When the request completes the request's completion callback
540  *        is called to return the request to the driver.
541  *      - An EP, except control EPs, may have multiple requests
542  *        pending.
543  *      - Once submitted the request cannot be examined or modified.
544  *      - Each request is turned into one or more packets.
545  *      - A BULK EP can queue any amount of data; the transfer is
546  *        packetized.
547  *      - Zero length Packets are specified with the request 'zero'
548  *        flag.
549  */
550 static int dwc_otg_pcd_ep_queue(struct usb_ep *_ep, 
551                                                                 struct usb_request *_req, gfp_t _gfp_flags)
552 {
553         int prevented = 0;
554         dwc_otg_pcd_request_t *req;
555         dwc_otg_pcd_ep_t *ep;
556         dwc_otg_pcd_t   *pcd;
557         unsigned long flags = 0;
558
559         DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p,%d)\n", 
560                                 __func__, _ep, _req, _gfp_flags);
561         
562         req = container_of(_req, dwc_otg_pcd_request_t, req);
563         if (!_req || !_req->complete || !_req->buf ) 
564         {
565                 DWC_WARN("%s, bad params\n", __func__);
566                 return -EINVAL;
567         }
568
569         /* 20091226,HSL@RK */
570         if ( !list_empty(&req->queue) ) 
571         {
572         while(!list_empty(&req->queue) ) {
573                 ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
574                 request_done(ep, req, -ECONNABORTED);
575         DWC_PRINT("%s::ep %s req not empty,done it error!\n" , __func__, _ep->name);
576         }
577                 return -EINVAL;
578         }
579         
580         ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
581         if (!_ep || (!ep->desc && ep->dwc_ep.num != 0)) 
582         {
583                 DWC_WARN("%s, bad ep\n", __func__);
584                 return -EINVAL;
585         }
586         pcd = ep->pcd;
587         if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) 
588         {
589                 DWC_DEBUGPL(DBG_PCDV, "gadget.speed=%d\n", pcd->gadget.speed);
590                 DWC_WARN("%s, bogus device state\n", __func__);
591                 return -ESHUTDOWN;
592         }
593
594
595         DWC_DEBUGPL(DBG_PCD, "%s queue req %p, len %d buf %p\n",
596                                    _ep->name, _req, _req->length, _req->buf);
597
598         if (!GET_CORE_IF(pcd)->core_params->opt) 
599         {
600                 if (ep->dwc_ep.num != 0) 
601                 {
602                         DWC_ERROR("%s queue req %p, len %d buf %p\n",
603                                           _ep->name, _req, _req->length, _req->buf);
604                 }
605         }
606
607
608 #if defined(DEBUG) & defined(VERBOSE)
609         dump_msg(_req->buf, _req->length);
610 #endif  
611         /* map virtual address to hardware */
612         if (req->req.dma == DMA_ADDR_INVALID) {
613                 req->req.dma = dma_map_single(ep->pcd->gadget.dev.parent,
614                                         req->req.buf,
615                                         req->req.length, ep->dwc_ep.is_in
616                                                 ? DMA_TO_DEVICE
617                                                 : DMA_FROM_DEVICE);
618                 req->mapped = 1;
619         } else {
620                 dma_sync_single_for_device(ep->pcd->gadget.dev.parent,
621                                         req->req.dma, req->req.length,
622                                         ep->dwc_ep.is_in
623                                                 ? DMA_TO_DEVICE
624                                                 : DMA_FROM_DEVICE);
625                 req->mapped = 0;
626         }
627         SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
628         
629         _req->status = -EINPROGRESS;
630         _req->actual = 0;
631
632         /* 
633          * For EP0 IN without premature status, zlp is required?
634          */
635         if (ep->dwc_ep.num == 0 && ep->dwc_ep.is_in) 
636         {
637                 DWC_DEBUGPL(DBG_PCDV, "%s-OUT ZLP\n", _ep->name);
638 //              _req->zero = 1;
639         }
640
641         /* Start the transfer */
642         if (list_empty(&ep->queue) && !ep->stopped) 
643         {
644                 /* EP0 Transfer? */
645                 if (ep->dwc_ep.num == 0) 
646                 {
647                         switch (pcd->ep0state) 
648                         {
649                         case EP0_IN_DATA_PHASE:
650                                 DWC_DEBUGPL(DBG_PCD, 
651                                                                 "%s ep0: EP0_IN_DATA_PHASE\n", 
652                                                                 __func__);
653                                 break;
654
655                         case EP0_OUT_DATA_PHASE:
656                                 DWC_DEBUGPL(DBG_PCD, 
657                                                                 "%s ep0: EP0_OUT_DATA_PHASE\n", 
658                                                                 __func__);
659                                 if (pcd->request_config) 
660                                 { 
661                                         /* Complete STATUS PHASE */
662                                         ep->dwc_ep.is_in = 1;
663                                         pcd->ep0state = EP0_STATUS;
664                                 }
665                                 break;
666                                                 
667                         default:
668                                 DWC_DEBUGPL(DBG_ANY, "ep0: odd state %d\n", 
669                                                                                         pcd->ep0state);
670                                 SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
671                                 return -EL2HLT;
672                         }
673
674                         ep->dwc_ep.dma_addr = _req->dma;
675                         ep->dwc_ep.start_xfer_buff = _req->buf;
676                         ep->dwc_ep.xfer_buff = _req->buf;
677                         ep->dwc_ep.xfer_len = _req->length;
678                         ep->dwc_ep.xfer_count = 0;
679                         ep->dwc_ep.sent_zlp = 0;
680                         ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;
681                         dwc_otg_ep0_start_transfer( GET_CORE_IF(pcd), 
682                                                                                 &ep->dwc_ep );
683                 } 
684                 else 
685                 {
686                         /* Setup and start the Transfer */
687                         ep->dwc_ep.dma_addr = _req->dma;
688                         ep->dwc_ep.start_xfer_buff = _req->buf;
689                         ep->dwc_ep.xfer_buff = _req->buf;
690                         ep->dwc_ep.xfer_len = _req->length;
691                         ep->dwc_ep.xfer_count = 0;
692                         ep->dwc_ep.sent_zlp = 0;
693                         ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;
694                         dwc_otg_ep_start_transfer( GET_CORE_IF(pcd), 
695                                                                            &ep->dwc_ep );
696                 }
697         }
698
699         if ((req != 0) || prevented) 
700         {
701                 ++pcd->request_pending;
702                 list_add_tail(&req->queue, &ep->queue);
703                 if (ep->dwc_ep.is_in && ep->stopped && !(GET_CORE_IF(pcd)->dma_enable)) 
704                 {
705                         /** @todo NGS Create a function for this. */
706                         diepmsk_data_t diepmsk = { .d32 = 0};
707                         diepmsk.b.intktxfemp = 1;
708                         dwc_modify_reg32( &GET_CORE_IF(pcd)->dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32 );
709                 }
710         }
711                 
712         SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
713         return 0;
714 }
715
716 /**
717  * This function cancels an I/O request from an EP.
718  */
719 static int dwc_otg_pcd_ep_dequeue(struct usb_ep *_ep,
720                                                                   struct usb_request *_req)
721 {
722         dwc_otg_pcd_request_t *req;
723         dwc_otg_pcd_ep_t *ep;
724         dwc_otg_pcd_t   *pcd;
725         unsigned long flags;
726     volatile depctl_data_t depctl = {.d32 = 0};
727     
728     dwc_otg_dev_out_ep_regs_t *out_regs;
729
730         DWC_DEBUGPL(DBG_PCDV,"%s(%p,%p)\n", __func__, _ep, _req);
731                 
732         ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
733         if (!_ep || !_req || (!ep->desc && ep->dwc_ep.num != 0)) 
734         {
735                 DWC_WARN("%s, bad argument\n", __func__);
736                 return -EINVAL;
737         }
738         pcd = ep->pcd;
739         if (!pcd->driver || pcd->gadget.speed == USB_SPEED_UNKNOWN) 
740         {
741                 DWC_WARN("%s, bogus device state, %p, speed %d\n", __func__, pcd->driver, pcd->gadget.speed);
742                 return -ESHUTDOWN;
743         }
744
745         SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
746         DWC_DEBUGPL(DBG_PCDV, "%s %s %s %p\n", __func__, _ep->name,
747                                         ep->dwc_ep.is_in ? "IN" : "OUT",
748                                         _req);
749
750         /* make sure it's actually queued on this endpoint */
751         list_for_each_entry( req, &ep->queue, queue) 
752         {
753                 if (&req->req == _req) 
754                 {
755                         break;
756                 }
757         }
758
759         if (&req->req != _req) 
760         {
761                 SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
762                 return -EINVAL;
763         }
764
765         if (!list_empty(&req->queue)) 
766         {                
767                 request_done(ep, req, -ECONNRESET);
768         } 
769         else 
770         {
771                 req = 0;
772         }
773
774         // kevery@20120602 NAK out request before new queue request
775         if(!ep->dwc_ep.is_in){
776         out_regs = GET_CORE_IF(pcd)->dev_if->out_ep_regs[ep->dwc_ep.num];
777         depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
778         depctl.b.snak = 1;
779         dwc_write_reg32( &(out_regs->doepctl), depctl.d32 );
780     }
781         SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
782
783         return req ? 0 : -EOPNOTSUPP;
784 }
785
786 /**
787  * usb_ep_set_halt stalls an endpoint. 
788  *
789  * usb_ep_clear_halt clears an endpoint halt and resets its data
790  * toggle.
791  *
792  * Both of these functions are implemented with the same underlying
793  * function. The behavior depends on the value argument.
794  * 
795  * @param[in] _ep the Endpoint to halt or clear halt.
796  * @param[in] _value 
797  *      - 0 means clear_halt.
798  *      - 1 means set_halt, 
799  *      - 2 means clear stall lock flag.
800  *      - 3 means set  stall lock flag.
801  */
802 static int dwc_otg_pcd_ep_set_halt(struct usb_ep *_ep, int _value)
803 {
804         int retval = 0;
805         unsigned long flags;
806         dwc_otg_pcd_ep_t *ep = 0;
807                 
808                 
809         DWC_DEBUGPL(DBG_PCD,"HALT %s %d\n", _ep->name, _value);
810
811         ep = container_of(_ep, dwc_otg_pcd_ep_t, ep);
812
813         if (!_ep || (!ep->desc && ep != &ep->pcd->ep0) ||
814                         ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) 
815         {
816                 DWC_WARN("%s, bad ep\n", __func__);
817                 return -EINVAL;
818         }
819                 
820         SPIN_LOCK_IRQSAVE(&ep->pcd->lock, flags);
821         if (!list_empty(&ep->queue))
822         {
823                 DWC_WARN("%s() %s XFer In process\n", __func__, _ep->name);
824                 retval = -EAGAIN;
825         }
826         else if (_value == 0) 
827         {
828                 dwc_otg_ep_clear_stall( ep->pcd->otg_dev->core_if, 
829                                                                         &ep->dwc_ep );           
830         }
831         else if(_value == 1)
832         {
833                 if (ep->dwc_ep.num == 0) 
834                 {
835                         ep->pcd->ep0state = EP0_STALL;
836                 }
837                 
838                 ep->stopped = 1;
839                 dwc_otg_ep_set_stall( ep->pcd->otg_dev->core_if, 
840                                                                 &ep->dwc_ep );
841         }
842         else if (_value == 2) 
843         {
844                 ep->dwc_ep.stall_clear_flag = 0;
845         }
846         else if (_value == 3) 
847         {
848                 ep->dwc_ep.stall_clear_flag = 1;
849         }
850         
851         SPIN_UNLOCK_IRQRESTORE(&ep->pcd->lock, flags);
852         return retval;
853 }
854
855
856 static struct usb_ep_ops dwc_otg_pcd_ep_ops = 
857 {
858         .enable         = dwc_otg_pcd_ep_enable,
859         .disable        = dwc_otg_pcd_ep_disable,
860
861         .alloc_request  = dwc_otg_pcd_alloc_request,
862         .free_request   = dwc_otg_pcd_free_request,
863
864 //      .alloc_buffer   = dwc_otg_pcd_alloc_buffer,
865 //      .free_buffer    = dwc_otg_pcd_free_buffer,
866
867         .queue          = dwc_otg_pcd_ep_queue,
868         .dequeue        = dwc_otg_pcd_ep_dequeue,
869
870         .set_halt       = dwc_otg_pcd_ep_set_halt,
871         .fifo_status    = 0,
872         .fifo_flush = 0,
873 };
874
875 /*      Gadget Operations */
876 /**
877  * The following gadget operations will be implemented in the DWC_otg
878  * PCD. Functions in the API that are not described below are not
879  * implemented.
880  *
881  * The Gadget API provides wrapper functions for each of the function
882  * pointers defined in usb_gadget_ops. The Gadget Driver calls the
883  * wrapper function, which then calls the underlying PCD function. The
884  * following sections are named according to the wrapper functions
885  * (except for ioctl, which doesn't have a wrapper function). Within
886  * each section, the corresponding DWC_otg PCD function name is
887  * specified.
888  *
889  */
890
891 /**
892  *Gets the USB Frame number of the last SOF.
893  */
894 static int dwc_otg_pcd_get_frame(struct usb_gadget *_gadget)
895 {
896         dwc_otg_pcd_t *pcd;
897         
898         DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _gadget);
899                 
900         if (_gadget == 0)
901         {
902                 return -ENODEV;
903         } 
904         else 
905         {
906                 pcd = container_of(_gadget, dwc_otg_pcd_t, gadget);
907                 dwc_otg_get_frame_number( GET_CORE_IF(pcd) );
908         }
909                 
910         return 0;
911 }
912
913 void dwc_otg_pcd_initiate_srp(dwc_otg_pcd_t *_pcd)
914 {
915         uint32_t *addr = (uint32_t *)&(GET_CORE_IF(_pcd)->core_global_regs->gotgctl);
916         gotgctl_data_t mem;
917         gotgctl_data_t val;
918                 
919         val.d32 = dwc_read_reg32( addr );
920         if (val.b.sesreq) 
921         {
922                 DWC_ERROR("Session Request Already active!\n");
923                         return;
924         }
925
926         DWC_NOTICE("Session Request Initated\n");
927         mem.d32 = dwc_read_reg32(addr);
928         mem.b.sesreq = 1;
929         dwc_write_reg32(addr, mem.d32);
930
931         /* Start the SRP timer */
932         dwc_otg_pcd_start_srp_timer( _pcd );
933         return;
934 }
935
936 void dwc_otg_pcd_remote_wakeup(dwc_otg_pcd_t *_pcd, int set)
937 {
938         dctl_data_t dctl = {.d32=0};
939         volatile uint32_t *addr = 
940                                 &(GET_CORE_IF(_pcd)->dev_if->dev_global_regs->dctl);
941
942         if (dwc_otg_is_device_mode(GET_CORE_IF(_pcd))) 
943         {
944                 if (_pcd->remote_wakeup_enable) 
945                 {
946                         if (set) 
947                         {
948                                 dctl.b.rmtwkupsig = 1;
949                                 dwc_modify_reg32( addr, 0, dctl.d32 );
950                                 DWC_DEBUGPL(DBG_PCD, "Set Remote Wakeup\n");
951                                 mdelay(1);
952                                 dwc_modify_reg32( addr, dctl.d32, 0 );
953                                 DWC_DEBUGPL(DBG_PCD, "Clear Remote Wakeup\n");
954                         }
955                         else 
956                         {
957                         }
958                 }
959                 else 
960                 {
961                         DWC_DEBUGPL(DBG_PCD, "Remote Wakeup is disabled\n");
962                 }
963         }
964
965         return;
966 }
967
968 /**
969  * Initiates Session Request Protocol (SRP) to wakeup the host if no
970  * session is in progress. If a session is already in progress, but
971  * the device is suspended, remote wakeup signaling is started.
972  *
973  */
974 static int dwc_otg_pcd_wakeup(struct usb_gadget *_gadget)
975 {
976         unsigned long flags;
977         dwc_otg_pcd_t *pcd;
978         dsts_data_t             dsts;
979         gotgctl_data_t  gotgctl;
980                 
981         DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _gadget);
982                 
983         if (_gadget == 0)
984         {
985                 return -ENODEV;
986         } 
987         else 
988         {
989                 pcd = container_of(_gadget, dwc_otg_pcd_t, gadget);
990         }
991         SPIN_LOCK_IRQSAVE(&pcd->lock, flags);
992
993         /*
994          * This function starts the Protocol if no session is in progress. If
995          * a session is already in progress, but the device is suspended,
996          * remote wakeup signaling is started.
997          */
998
999         /* Check if valid session */
1000         gotgctl.d32 = dwc_read_reg32(&(GET_CORE_IF(pcd)->core_global_regs->gotgctl));
1001         if (gotgctl.b.bsesvld) 
1002         {
1003                 /* Check if suspend state */
1004                 dsts.d32 = dwc_read_reg32(&(GET_CORE_IF(pcd)->dev_if->dev_global_regs->dsts));
1005                 if (dsts.b.suspsts) 
1006                 {
1007                         dwc_otg_pcd_remote_wakeup(pcd, 1);
1008                 }
1009         }
1010         else 
1011         {
1012                 dwc_otg_pcd_initiate_srp(pcd);
1013         }
1014
1015         SPIN_UNLOCK_IRQRESTORE(&pcd->lock, flags);
1016         return 0;
1017 }
1018
1019 static int dwc_otg_pcd_pullup(struct usb_gadget *_gadget, int is_on)
1020 {
1021         //unsigned long flags;
1022         dwc_otg_pcd_t *pcd;
1023     dctl_data_t dctl = {.d32=0};
1024     dwc_otg_core_if_t *core_if;
1025         DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _gadget);
1026                 
1027         if (_gadget == 0)
1028         {
1029                 return -ENODEV;
1030         } 
1031         else 
1032         {
1033                 pcd = container_of(_gadget, dwc_otg_pcd_t, gadget);
1034         core_if = GET_CORE_IF(pcd); 
1035         }
1036         if(is_on)   //connect
1037         {
1038 #ifdef CONFIG_DWC_CONN_EN
1039         pcd->conn_en = 1;
1040 #else
1041         pcd->conn_en = 0;
1042 #endif
1043         pcd->conn_status = 0;
1044     }
1045     else        //disconnect
1046     {
1047         dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
1048         dctl.b.sftdiscon = 1;
1049         dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
1050         pcd->conn_status = 3;
1051     }
1052     return 0;
1053 }
1054
1055 static const struct usb_gadget_ops dwc_otg_pcd_ops = 
1056 {
1057         .get_frame       = dwc_otg_pcd_get_frame,
1058         .wakeup          = dwc_otg_pcd_wakeup,
1059         .pullup      = dwc_otg_pcd_pullup,
1060         // current versions must always be self-powered
1061 };
1062
1063 /**
1064  * This function updates the otg values in the gadget structure. 
1065  */
1066 void dwc_otg_pcd_update_otg( dwc_otg_pcd_t *_pcd, const unsigned _reset )
1067 {
1068                 
1069         if (!_pcd->gadget.is_otg)
1070                 return;
1071
1072         if (_reset) 
1073         {
1074                 _pcd->b_hnp_enable = 0;
1075                 _pcd->a_hnp_support = 0;
1076                 _pcd->a_alt_hnp_support = 0;
1077         }
1078
1079         _pcd->gadget.b_hnp_enable = _pcd->b_hnp_enable;
1080         _pcd->gadget.a_hnp_support =  _pcd->a_hnp_support;
1081         _pcd->gadget.a_alt_hnp_support = _pcd->a_alt_hnp_support;
1082 }
1083
1084 /** 
1085  * This function is the top level PCD interrupt handler.
1086  */
1087 static irqreturn_t 
1088 dwc_otg_pcd_irq(int _irq, void *_dev)
1089 {
1090         dwc_otg_pcd_t *pcd = _dev;
1091         int32_t retval = IRQ_NONE;
1092
1093         retval = dwc_otg_pcd_handle_intr( pcd );
1094         return IRQ_RETVAL(retval);
1095 }
1096
1097 /**
1098  * PCD Callback function for initializing the PCD when switching to
1099  * device mode.
1100  *
1101  * @param _p void pointer to the <code>dwc_otg_pcd_t</code>
1102  */
1103  
1104 static int32_t dwc_otg_pcd_start_cb( void *_p )
1105 {
1106         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)_p;
1107         
1108         /*
1109          * Initialized the Core for Device mode.
1110          */
1111         if (dwc_otg_is_device_mode( GET_CORE_IF(pcd) ))
1112         {
1113         pcd->phy_suspend = 1;
1114         pcd->vbus_status = 0;
1115         dwc_otg_pcd_start_vbus_timer(pcd);
1116         }
1117         
1118         return 1;
1119 }
1120
1121 /**
1122  * PCD Callback function for stopping the PCD when switching to Host
1123  * mode.
1124  *
1125  * @param _p void pointer to the <code>dwc_otg_pcd_t</code>
1126  */
1127 static int32_t dwc_otg_pcd_stop_cb( void *_p )
1128 {
1129         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)_p;
1130         extern void dwc_otg_pcd_stop(dwc_otg_pcd_t *_pcd);
1131         
1132         dwc_otg_pcd_stop( pcd );
1133         return 1;
1134 }
1135
1136
1137 /**
1138  * PCD Callback function for notifying the PCD when resuming from
1139  * suspend.
1140  *
1141  * @param _p void pointer to the <code>dwc_otg_pcd_t</code>
1142  */
1143 static int32_t dwc_otg_pcd_suspend_cb( void *_p ,int suspend)
1144 {
1145         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)_p;
1146 //#ifdef CONFIG_ANDROID_POWER
1147 #if 0
1148         /* yk@rk 20100520
1149          * PC disconnect the USB, unlock the msc_lock and
1150          * system can enter level 2 sleep mode.
1151          */
1152         struct usb_composite_dev        *cdev;
1153         if (pcd->driver && pcd->driver->resume) 
1154         {
1155                 cdev = get_gadget_data(&pcd->gadget);
1156                 if(cdev->config)
1157                         pcd->conn_status = 3;
1158         }
1159 #endif
1160 //#endif                
1161         if (pcd->driver && pcd->driver->resume) 
1162         {
1163                 pcd->driver->suspend(&pcd->gadget);
1164         }
1165         return 1;
1166 }
1167
1168
1169 /**
1170  * PCD Callback function for notifying the PCD when resuming from
1171  * suspend.
1172  *
1173  * @param _p void pointer to the <code>dwc_otg_pcd_t</code>
1174  */
1175 static int32_t dwc_otg_pcd_resume_cb( void *_p )
1176 {
1177         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)_p;
1178         
1179         if (pcd->driver && pcd->driver->resume) 
1180         {
1181                         pcd->driver->resume(&pcd->gadget);
1182         }
1183         
1184         /* Stop the SRP timeout timer. */
1185         if ((GET_CORE_IF(pcd)->core_params->phy_type != DWC_PHY_TYPE_PARAM_FS) ||
1186                 (!GET_CORE_IF(pcd)->core_params->i2c_enable))
1187         {
1188                 if (GET_CORE_IF(pcd)->srp_timer_started) 
1189                 {
1190                         GET_CORE_IF(pcd)->srp_timer_started = 0;
1191                         del_timer( &pcd->srp_timer );
1192                 }
1193         }
1194         return 1;
1195 }
1196
1197
1198 /**
1199  * PCD Callback structure for handling mode switching.
1200  */
1201 static dwc_otg_cil_callbacks_t pcd_callbacks = 
1202 {
1203         .start = dwc_otg_pcd_start_cb,
1204         .stop = dwc_otg_pcd_stop_cb,
1205         .suspend = dwc_otg_pcd_suspend_cb,
1206         .resume_wakeup = dwc_otg_pcd_resume_cb,
1207         .p = 0, /* Set at registration */
1208 };
1209
1210 /**
1211  * This function is called when the SRP timer expires.  The SRP should
1212  * complete within 6 seconds. 
1213  */
1214 static void srp_timeout( unsigned long _ptr )
1215 {
1216         gotgctl_data_t gotgctl;
1217         dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *)_ptr;
1218         volatile uint32_t *addr = &core_if->core_global_regs->gotgctl;
1219
1220         gotgctl.d32 = dwc_read_reg32(addr);
1221
1222         core_if->srp_timer_started = 0;
1223
1224         if ((core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) && 
1225                 (core_if->core_params->i2c_enable))
1226         {
1227                 DWC_PRINT( "SRP Timeout\n");
1228
1229                 if ((core_if->srp_success) && 
1230                         (gotgctl.b.bsesvld))
1231                 {
1232                         if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup ) 
1233                         {
1234                                 core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
1235                         }
1236                         
1237                         /* Clear Session Request */
1238                         gotgctl.d32 = 0;
1239                         gotgctl.b.sesreq = 1;
1240                         dwc_modify_reg32( &core_if->core_global_regs->gotgctl, 
1241                                           gotgctl.d32, 0);
1242         
1243                         core_if->srp_success = 0;
1244                 }
1245                 else 
1246                 {
1247                         DWC_ERROR( "Device not connected/responding\n");
1248                         gotgctl.b.sesreq = 0;
1249                         dwc_write_reg32(addr, gotgctl.d32);
1250                 }
1251         }
1252         else if (gotgctl.b.sesreq) 
1253         {
1254                 DWC_PRINT( "SRP Timeout\n");
1255
1256                 DWC_ERROR( "Device not connected/responding\n");
1257                 gotgctl.b.sesreq = 0;
1258                 dwc_write_reg32(addr, gotgctl.d32);
1259         } 
1260         else 
1261         {
1262                 DWC_PRINT( " SRP GOTGCTL=%0x\n", gotgctl.d32);
1263         } 
1264 }
1265
1266 /**
1267  * Start the SRP timer to detect when the SRP does not complete within 
1268  * 6 seconds.
1269  *
1270  * @param _pcd the pcd structure.
1271  */
1272 void dwc_otg_pcd_start_srp_timer(dwc_otg_pcd_t *_pcd )
1273 {
1274         struct timer_list *srp_timer = &_pcd->srp_timer;
1275         GET_CORE_IF(_pcd)->srp_timer_started = 1;
1276         init_timer( srp_timer );
1277         srp_timer->function = srp_timeout;
1278         srp_timer->data = (unsigned long)GET_CORE_IF(_pcd);
1279         srp_timer->expires = jiffies + (HZ*6);
1280         add_timer( srp_timer );
1281 }
1282
1283 /**
1284  * Tasklet
1285  *
1286  */
1287 extern void start_next_request( dwc_otg_pcd_ep_t *_ep );
1288
1289 static void start_xfer_tasklet_func (unsigned long data)
1290 {
1291         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t*)data;
1292         dwc_otg_core_if_t *core_if = pcd->otg_dev->core_if;
1293
1294         int i;
1295         depctl_data_t diepctl;
1296
1297         DWC_DEBUGPL(DBG_PCDV, "Start xfer tasklet\n");
1298
1299         diepctl.d32 = dwc_read_reg32( &core_if->dev_if->in_ep_regs[0]->diepctl);
1300
1301         if (pcd->ep0.queue_sof) 
1302         {
1303                 pcd->ep0.queue_sof = 0;
1304                 start_next_request (&pcd->ep0);
1305                 // break;
1306         }
1307
1308         for (i=0; i<core_if->dev_if->num_in_eps; i++) 
1309         {
1310                 depctl_data_t diepctl;
1311                 diepctl.d32 = dwc_read_reg32( &core_if->dev_if->in_ep_regs[i]->diepctl);
1312
1313                 if (pcd->in_ep[i].queue_sof) 
1314                 {
1315                         pcd->in_ep[i].queue_sof = 0;
1316                         start_next_request (&pcd->in_ep[i]);
1317                         // break;
1318                 }
1319         }
1320
1321         return;
1322 }
1323
1324
1325
1326
1327
1328
1329
1330 static struct tasklet_struct start_xfer_tasklet = {
1331         .next = NULL,
1332         .state = 0,
1333         .count = ATOMIC_INIT(0),
1334         .func = start_xfer_tasklet_func,
1335         .data = 0,//pcd
1336 };
1337 /**
1338  * This function initialized the pcd Dp structures to there default
1339  * state.
1340  *
1341  * @param _pcd the pcd structure.
1342  */
1343 void dwc_otg_pcd_reinit(dwc_otg_pcd_t *_pcd)
1344 {
1345         dwc_otg_core_if_t * core_if = GET_CORE_IF(_pcd);
1346         
1347         //dwc_otg_dump_dev_registers(core_if);
1348         static const char * names[] = 
1349                 {
1350                         
1351                         "ep0",
1352                         "ep1in",        
1353                         "ep2in",        
1354                         "ep3in",        
1355                         "ep4in",        
1356 #ifdef CONFIG_ARCH_RK29
1357                         "ep5in-int",    
1358 #else
1359                         "ep5in",        
1360 #endif
1361                         "ep6in",        
1362                         "ep7in",        
1363                         "ep8in",        
1364                         "ep9in",        
1365                         "ep10in",       
1366                         "ep11in",       
1367                         "ep12in",       
1368                         "ep13in",       
1369                         "ep14in",       
1370                         "ep15in",       
1371                         "ep1out",  
1372                         "ep2out",  
1373                         "ep3out",
1374                         "ep4out",
1375                         "ep5out",
1376                         "ep6out",
1377                         "ep7out",
1378                         "ep8out",
1379                         "ep9out",
1380                         "ep10out",
1381                         "ep11out",
1382                         "ep12out",
1383                         "ep13out",
1384                         "ep14out",
1385                         "ep15out"
1386                         
1387         };
1388                 
1389         int i;
1390         int in_ep_cntr, out_ep_cntr;
1391         uint32_t hwcfg1;
1392         uint32_t num_in_eps = core_if->dev_if->num_in_eps; /* = 3 */
1393         uint32_t num_out_eps = core_if->dev_if->num_out_eps; /* = 3 */
1394         dwc_otg_pcd_ep_t *ep;
1395         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _pcd);
1396         
1397         INIT_LIST_HEAD (&_pcd->gadget.ep_list);
1398         _pcd->gadget.ep0 = &_pcd->ep0.ep;
1399         _pcd->gadget.speed = USB_SPEED_UNKNOWN;
1400
1401         INIT_LIST_HEAD (&_pcd->gadget.ep0->ep_list);
1402
1403         /**
1404          * Initialize the EP0 structure.
1405          */
1406         ep = &_pcd->ep0;
1407
1408         /* Init EP structure */
1409         ep->desc = 0;
1410         ep->pcd = _pcd;
1411         ep->stopped = 1;
1412
1413         /* Init DWC ep structure */
1414         ep->dwc_ep.num = 0;
1415         ep->dwc_ep.active = 0;
1416         ep->dwc_ep.tx_fifo_num = 0;
1417         /* Control until ep is actvated */
1418         ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL; 
1419         ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
1420         ep->dwc_ep.dma_addr = 0;
1421         ep->dwc_ep.start_xfer_buff = 0;
1422         ep->dwc_ep.xfer_buff = 0;
1423         ep->dwc_ep.xfer_len = 0;
1424         ep->dwc_ep.xfer_count = 0;
1425         ep->dwc_ep.sent_zlp = 0;
1426         ep->dwc_ep.total_len = 0;
1427         ep->queue_sof = 0;
1428
1429         /* Init the usb_ep structure. */
1430         ep->ep.name = names[0];
1431         ep->ep.ops = &dwc_otg_pcd_ep_ops;
1432
1433         /**
1434          * @todo NGS: What should the max packet size be set to
1435          * here?  Before EP type is set?
1436          */
1437         ep->ep.maxpacket = MAX_PACKET_SIZE;
1438
1439         list_add_tail (&ep->ep.ep_list, &_pcd->gadget.ep_list);
1440                 
1441         INIT_LIST_HEAD (&ep->queue);
1442         /**
1443          * Initialize the EP structures.
1444          */
1445         in_ep_cntr = 0;
1446         hwcfg1 = core_if->hwcfg1.d32 >> 3;
1447          
1448         for (i = 1; in_ep_cntr < num_in_eps; i++) 
1449         {
1450                 if((hwcfg1 & 0x1) == 0)
1451                 {
1452                         dwc_otg_pcd_ep_t *ep = &_pcd->in_ep[in_ep_cntr];
1453                         in_ep_cntr ++;
1454                         
1455                         /* Init EP structure */
1456                         ep->desc = 0;
1457                         ep->pcd = _pcd;
1458                         ep->stopped = 1;
1459         
1460                         /* Init DWC ep structure */
1461                         ep->dwc_ep.is_in = 1;
1462                         ep->dwc_ep.num = i;
1463                         ep->dwc_ep.active = 0;
1464                         ep->dwc_ep.tx_fifo_num = 0;
1465                         
1466                         /* Control until ep is actvated */
1467                         ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL; 
1468                         ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
1469                         ep->dwc_ep.dma_addr = 0;
1470                         ep->dwc_ep.start_xfer_buff = 0;
1471                         ep->dwc_ep.xfer_buff = 0;
1472                         ep->dwc_ep.xfer_len = 0;
1473                         ep->dwc_ep.xfer_count = 0;
1474                         ep->dwc_ep.sent_zlp = 0;
1475                         ep->dwc_ep.total_len = 0;
1476                         ep->queue_sof = 0;
1477         
1478                         /* Init the usb_ep structure. */
1479                         /**
1480                          * @todo NGS: Add direction to EP, based on contents
1481                          * of HWCFG1.  Need a copy of HWCFG1 in pcd structure?
1482                          * sprintf( ";r
1483                          */
1484                         ep->ep.name = names[i];
1485                         ep->ep.ops = &dwc_otg_pcd_ep_ops;
1486                         
1487                         /**
1488                          * @todo NGS: What should the max packet size be set to
1489                          * here?  Before EP type is set?
1490                          */
1491                         ep->ep.maxpacket = MAX_PACKET_SIZE;
1492                         
1493                         INIT_LIST_HEAD (&ep->queue);
1494
1495                         /**
1496                          * @yk@rk 20120329
1497                          * EP8&EP9 of rk30 are IN&OUT ep, we use ep8 as OUT EP default
1498                          */
1499                 #ifdef CONFIG_ARCH_RK30
1500                 if(i == 8)
1501                     continue;
1502                 #endif
1503                 #ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30
1504                 if(i == 8)
1505                     continue;
1506                 #endif
1507                         list_add_tail (&ep->ep.ep_list, &_pcd->gadget.ep_list);
1508                                 
1509                 }
1510                 hwcfg1 >>= 2;
1511         }
1512         out_ep_cntr = 0;
1513         hwcfg1 = core_if->hwcfg1.d32 >> 2;
1514
1515         for (i = 1; out_ep_cntr < num_out_eps; i++) 
1516         {
1517                 if((hwcfg1 & 0x1) == 0)
1518                 {
1519                         dwc_otg_pcd_ep_t *ep = &_pcd->out_ep[out_ep_cntr];
1520                         out_ep_cntr++;
1521         
1522                         /* Init EP structure */
1523                         ep->desc = 0;
1524                         ep->pcd = _pcd;
1525                         ep->stopped = 1;
1526         
1527                         /* Init DWC ep structure */
1528                         ep->dwc_ep.is_in = 0;
1529                         ep->dwc_ep.num = i;
1530                         ep->dwc_ep.active = 0;
1531                         ep->dwc_ep.tx_fifo_num = 0;
1532                         /* Control until ep is actvated */
1533                         ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL; 
1534                         ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
1535                         ep->dwc_ep.dma_addr = 0;
1536                         ep->dwc_ep.start_xfer_buff = 0;
1537                         ep->dwc_ep.xfer_buff = 0;
1538                         ep->dwc_ep.xfer_len = 0;
1539                         ep->dwc_ep.xfer_count = 0;
1540                         ep->dwc_ep.sent_zlp = 0;
1541                         ep->dwc_ep.total_len = 0;
1542                         ep->queue_sof = 0;
1543         
1544                         /* Init the usb_ep structure. */
1545                         /**
1546                          * @todo NGS: Add direction to EP, based on contents
1547                          * of HWCFG1.  Need a copy of HWCFG1 in pcd structure?
1548                          * sprintf( ";r
1549                          */
1550                         ep->ep.name = names[15 + i];
1551                         ep->ep.ops = &dwc_otg_pcd_ep_ops;
1552                         /**
1553                          * @todo NGS: What should the max packet size be set to
1554                          * here?  Before EP type is set?
1555                          */
1556                         ep->ep.maxpacket = MAX_PACKET_SIZE;
1557         
1558                         INIT_LIST_HEAD (&ep->queue);
1559                         
1560                         /**
1561                          * @yk@rk 20120329
1562                          * EP8&EP9 of rk30 are IN&OUT ep, we use ep9 as IN EP default
1563                          */
1564                 #ifdef CONFIG_ARCH_RK30
1565                 if(i == 9)
1566                     continue;
1567                 #endif
1568                 #ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30
1569                 if(i == 9)
1570                     continue;
1571                 #endif
1572                         list_add_tail (&ep->ep.ep_list, &_pcd->gadget.ep_list);
1573                                 
1574                 }
1575                 hwcfg1 >>= 2;
1576         }
1577         
1578         /* remove ep0 from the list.  There is a ep0 pointer.*/
1579         list_del_init (&_pcd->ep0.ep.ep_list);
1580    
1581         _pcd->ep0state = EP0_DISCONNECT;
1582         _pcd->ep0.ep.maxpacket = MAX_EP0_SIZE;            
1583         _pcd->ep0.dwc_ep.maxpacket = MAX_EP0_SIZE;
1584         _pcd->ep0.dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
1585 }
1586
1587 /**
1588  * This function releases the Gadget device.
1589  * required by device_unregister().
1590  *
1591  * @todo Should this do something?      Should it free the PCD? 
1592  */
1593 static void dwc_otg_pcd_gadget_release(struct device *_dev)
1594 {
1595         DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _dev);
1596 }
1597
1598 int dwc_pcd_reset(dwc_otg_pcd_t *pcd)
1599 {
1600     dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1601     dwc_otg_disable_global_interrupts( core_if );
1602     //
1603 #ifdef CONFIG_ARCH_RK29
1604     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_AHB_BUS, true);
1605     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_PHY, true);
1606     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_CONTROLLER, true);
1607     udelay(1);
1608
1609     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_AHB_BUS, false);
1610     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_PHY, false);
1611     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_CONTROLLER, false);
1612     mdelay(1);
1613 #endif    
1614     //rockchip_scu_reset_unit(12);
1615     dwc_otg_pcd_reinit( pcd );
1616     dwc_otg_core_dev_init(core_if);
1617     //DWC_PRINT("%s\n" , __func__ );
1618     dwc_otg_enable_global_interrupts( core_if );
1619     return 0;
1620 }
1621
1622 /*
1623  * close usb phy , about 7ma--2.5v
1624  * 20090925,add vbus test code.500ms ¼ä¸ô.
1625  * 20100122,HSL@RK,hard reset usb controller and phy.
1626 */
1627 int dwc_otg20phy_suspend( int exitsuspend )
1628 {
1629         dwc_otg_pcd_t *pcd = s_pcd;
1630 #ifdef CONFIG_ARCH_RK29
1631     unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON);
1632     if(exitsuspend && (pcd->phy_suspend == 1)) {
1633         clk_enable(pcd->otg_dev->ahbclk);
1634         clk_enable(pcd->otg_dev->phyclk);
1635         pcd->phy_suspend = 0;
1636         *otg_phy_con1 |= (0x01<<2);
1637         *otg_phy_con1 |= (0x01<<3);    // exit suspend.
1638         *otg_phy_con1 &= ~(0x01<<2);
1639         
1640         /* 20091011,reenable usb phy ,will raise reset intr */
1641         //debug_print("enable usb phy\n");
1642         DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
1643     }
1644     if( !exitsuspend && (pcd->phy_suspend == 0)) {
1645         pcd->phy_suspend = 1;
1646         *otg_phy_con1 |= ((0x01<<2)|(0x05<<6));
1647         *otg_phy_con1 &= ~(0x01<<3);    // enter suspend.
1648         udelay(3);
1649         clk_disable(pcd->otg_dev->phyclk);
1650         clk_disable(pcd->otg_dev->ahbclk);
1651         //*otg_phy_con1 &= ~(0x01<<2);
1652         //debug_print("disable usb phy\n");
1653         DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
1654     }
1655 #endif
1656 #ifdef CONFIG_ARCH_RK30
1657     unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);
1658     if(exitsuspend && (pcd->phy_suspend == 1)) {
1659         clk_enable(pcd->otg_dev->ahbclk);
1660         clk_enable(pcd->otg_dev->phyclk);
1661         pcd->phy_suspend = 0;
1662         *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.
1663         DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
1664     }
1665     if( !exitsuspend && (pcd->phy_suspend == 0)) {
1666         pcd->phy_suspend = 1;
1667         *otg_phy_con1 = 0x554|(0xfff<<16);   // enter suspend.
1668         udelay(3);
1669         clk_disable(pcd->otg_dev->phyclk);
1670         clk_disable(pcd->otg_dev->ahbclk);
1671         DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
1672     }
1673 #endif
1674 #ifdef CONFIG_ARCH_RK2928                
1675     unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);
1676     if(exitsuspend && (pcd->phy_suspend == 1)) {
1677         clk_enable(pcd->otg_dev->ahbclk);
1678         clk_enable(pcd->otg_dev->phyclk);
1679         pcd->phy_suspend = 0;
1680         *otg_phy_con1 = (0x01<<16);    // exit suspend.
1681         DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
1682     }
1683     if( !exitsuspend && (pcd->phy_suspend == 0)) {
1684         pcd->phy_suspend = 1;
1685        *otg_phy_con1 = 0x55 |(0x7f<<16);   // enter suspend.
1686       //  *otg_phy_con1 = 0x1D5 |(0x1ff<<16);   // enter suspend.   enable dm,dp  debug_wlf @2012.8.10
1687         udelay(3);
1688         clk_disable(pcd->otg_dev->phyclk);
1689         clk_disable(pcd->otg_dev->ahbclk);
1690         DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
1691     }
1692 #endif
1693     return pcd->phy_suspend;
1694 }
1695
1696 int dwc_otg_reset( void ) 
1697 {
1698     dwc_otg_pcd_t * pcd = s_pcd;
1699     dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1700     dctl_data_t dctl = {.d32=0};
1701
1702     dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
1703     dctl.b.sftdiscon = 1;
1704     dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
1705     //DWC_PRINT("%s::otg reset connect!!!\n" , __func__ );
1706     return 0;
1707 }
1708 void dwc_otg_msc_lock(dwc_otg_pcd_t *pcd)
1709 {
1710         unsigned long           flags;
1711
1712         local_irq_save(flags);
1713     wake_lock(&pcd->wake_lock);
1714     local_irq_restore(flags);
1715
1716 }
1717
1718 void dwc_otg_msc_unlock(dwc_otg_pcd_t *pcd)
1719 {
1720         unsigned long           flags;
1721         local_irq_save(flags);
1722         wake_unlock(&pcd->wake_lock);
1723         local_irq_restore(flags);
1724 }
1725 static void dwc_phy_reconnect(struct work_struct *work)
1726 {
1727     dwc_otg_pcd_t *pcd;
1728     dwc_otg_core_if_t *core_if;
1729     gotgctl_data_t    gctrl;
1730     dctl_data_t dctl = {.d32=0};
1731
1732     pcd = container_of(work, dwc_otg_pcd_t, reconnect.work);
1733     core_if = GET_CORE_IF(pcd); 
1734     gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl );
1735     if( gctrl.b.bsesvld  ) {
1736         pcd->conn_status++;
1737             dwc_pcd_reset(pcd);
1738         /*
1739          * Enable the global interrupt after all the interrupt
1740          * handlers are installed.
1741          */
1742         dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
1743         dctl.b.sftdiscon = 0;
1744         dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );      
1745         DWC_PRINT("********soft connect!!!*****************************************\n");
1746     } 
1747 }
1748 #ifdef CONFIG_ARCH_RK29
1749 static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
1750 {
1751     dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata;
1752     dwc_otg_core_if_t *core_if = GET_CORE_IF(_pcd);
1753     gotgctl_data_t    gctrl;
1754     dctl_data_t dctl = {.d32=0};
1755     //dsts_data_t           gsts;
1756         unsigned long flags;
1757         local_irq_save(flags);
1758     gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl );
1759     //gsts.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dsts);
1760
1761     _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */
1762     if( gctrl.b.bsesvld ) {
1763         /* if usb not connect before ,then start connect */
1764          if( _pcd->vbus_status == 0 ) {
1765             dwc_otg_msc_lock(_pcd);
1766             DWC_PRINT("********vbus detect*********************************************\n");
1767             _pcd->vbus_status = 1;
1768             /* soft disconnect */
1769             dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
1770             dctl.b.sftdiscon = 1;
1771             dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
1772             /* Clear any pending interrupts */
1773             dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); 
1774             if(_pcd->conn_en)
1775             {
1776                     schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
1777                      _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
1778             }
1779
1780         } else if((_pcd->conn_status>0)&&(_pcd->conn_status <3)) {
1781             //dwc_otg_msc_unlock(_pcd);
1782             DWC_PRINT("********soft reconnect******************************************\n");
1783             //_pcd->vbus_status =0;
1784             
1785             /* soft disconnect */
1786                 dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
1787                 dctl.b.sftdiscon = 1;
1788                 dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
1789             /* Clear any pending interrupts */
1790             dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); 
1791             if(_pcd->conn_en)
1792             {
1793                     schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
1794                      _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
1795             }
1796         }
1797         else if((_pcd->conn_en)&&(_pcd->conn_status == 0))
1798         {
1799         
1800             schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
1801                      _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
1802         }
1803         else if(_pcd->conn_status ==3)
1804         {
1805                         //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*//
1806             dwc_otg_msc_unlock(_pcd);
1807             _pcd->conn_status++;
1808             if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
1809                 _pcd->vbus_status = 2;
1810         }
1811     } else {
1812         //DWC_PRINT("new vbus=%d,old vbus=%d\n" , gctrl.b.bsesvld , _pcd->vbus_status );
1813         _pcd->vbus_status = 0;
1814         if(_pcd->conn_status)
1815         {
1816              _pcd->conn_status = 0;
1817              dwc_otg_msc_unlock(_pcd);
1818         }
1819         /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */
1820         if( _pcd->phy_suspend == 0 ) {
1821                 /* no vbus detect here , close usb phy for 500ms */
1822              dwc_otg20phy_suspend( 0 );
1823               _pcd->check_vbus_timer.expires = jiffies + (HZ/2); /* 500 ms */
1824         } else if( _pcd->phy_suspend  == 1 ) { 
1825              dwc_otg20phy_suspend( 1 );
1826              /*20100325 yk@rk,delay 2-->8,for host connect id detect*/
1827              _pcd->check_vbus_timer.expires = jiffies + 8; /* 20091127,HSL@RK,1-->2  */
1828              
1829         }
1830     }
1831     //DWC_PRINT("%s:restart check vbus timer\n" , __func__ );
1832     add_timer(&_pcd->check_vbus_timer); 
1833         local_irq_restore(flags);
1834 }
1835 #endif
1836 #ifdef CONFIG_ARCH_RK30
1837 static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
1838 {
1839     dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata;
1840         unsigned long flags;
1841     unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);
1842
1843         local_irq_save(flags);
1844     _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */
1845     if((usbgrf_status &(1<<20)) == 0){  // id low
1846     
1847         if( _pcd->phy_suspend) 
1848              dwc_otg20phy_suspend( 1 );
1849     }
1850         else if(usbgrf_status &0x20000){  // bvalid
1851         /* if usb not connect before ,then start connect */
1852          if( _pcd->vbus_status == 0 ) {
1853             DWC_PRINT("********vbus detect*********************************************\n");
1854             _pcd->vbus_status = 1;
1855             if(_pcd->conn_en)
1856                 goto connect;
1857             else
1858                 // not connect, suspend phy
1859                 dwc_otg20phy_suspend(0);
1860         } 
1861         else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <3)){
1862             DWC_PRINT("********soft reconnect******************************************\n");
1863             goto connect;
1864         }
1865         else if(_pcd->conn_status ==3){
1866                         //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*//
1867             dwc_otg_msc_unlock(_pcd);
1868             _pcd->conn_status++;
1869             if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
1870                 _pcd->vbus_status = 2;
1871                 
1872             // not connect, suspend phy
1873             dwc_otg20phy_suspend(0);
1874         }
1875         }else {
1876         _pcd->vbus_status = 0;
1877         if(_pcd->conn_status){
1878              _pcd->conn_status = 0;
1879              dwc_otg_msc_unlock(_pcd);
1880         }
1881         /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */
1882         else if( _pcd->phy_suspend == 0 ) 
1883                 /* no vbus detect here , close usb phy  */
1884              dwc_otg20phy_suspend( 0 );
1885     }
1886     add_timer(&_pcd->check_vbus_timer); 
1887         local_irq_restore(flags);
1888     return;
1889
1890 connect:
1891     if(_pcd->conn_status==0)
1892         dwc_otg_msc_lock(_pcd);
1893     if( _pcd->phy_suspend  == 1 )
1894          dwc_otg20phy_suspend( 1 );
1895     schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
1896      _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
1897     add_timer(&_pcd->check_vbus_timer); 
1898         local_irq_restore(flags);
1899     return;
1900 }
1901
1902 #endif
1903 #ifdef CONFIG_ARCH_RK2928
1904 static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
1905 {
1906     dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata;
1907         unsigned long flags;
1908     unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);//@lyz USBGRF_SOC_STATUS0½á¹¹Óбä
1909
1910         local_irq_save(flags);
1911     _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */
1912     if((usbgrf_status &(1<<10)) == 0){  // id low  //@lyz SOC_STATUS0[10] represents id_dig
1913     
1914         if( _pcd->phy_suspend) 
1915              dwc_otg20phy_suspend( 1 );
1916     }
1917         else if(usbgrf_status & (1<<7)){  //@lyz SOC_STATUS0[7] represents bvalid
1918         /* if usb not connect before ,then start connect */
1919          if( _pcd->vbus_status == 0 ) {
1920             DWC_PRINT("********vbus detect*********************************************\n");
1921             dwc_otg_msc_lock(_pcd);
1922             _pcd->vbus_status = 1;
1923             if(_pcd->conn_en)
1924                 goto connect;
1925             else
1926                 dwc_otg20phy_suspend( 0 );
1927         } 
1928         else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <3)){
1929             DWC_PRINT("********soft reconnect******************************************\n");
1930             goto connect;
1931         }
1932         else if(_pcd->conn_status ==3){
1933                         //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*//
1934             dwc_otg_msc_unlock(_pcd);
1935             _pcd->conn_status++;
1936             if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
1937                 _pcd->vbus_status = 2;
1938         }
1939         }else {
1940         _pcd->vbus_status = 0;
1941         if(_pcd->conn_status)
1942         {
1943              _pcd->conn_status = 0;
1944              dwc_otg_msc_unlock(_pcd);
1945         }
1946         /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */
1947         if( _pcd->phy_suspend == 0 ) 
1948                 /* no vbus detect here , close usb phy  */
1949              dwc_otg20phy_suspend( 0 );
1950     }
1951     add_timer(&_pcd->check_vbus_timer); 
1952         local_irq_restore(flags);
1953     return;
1954
1955 connect:
1956     if( _pcd->phy_suspend  == 1 )
1957          dwc_otg20phy_suspend( 1 );
1958     schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
1959      _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
1960     add_timer(&_pcd->check_vbus_timer); 
1961         local_irq_restore(flags);
1962     return;
1963 }
1964
1965 #endif
1966 #ifdef CONFIG_ARCH_RK29
1967 /*
1968  * This function can be only called in charge mode.
1969  * return value:
1970  *  -1: ioremap fail;
1971  *  0: vbus not connected;
1972  *  1: vbus connected, dp,dm not in both high status;
1973  *  2: vbus connected and both dp,dm in high level.(standard USB charger)
1974  */
1975 int dwc_otg_check_dpdm(void)
1976 {
1977         static uint8_t * reg_base = 0;
1978     volatile unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON);
1979     volatile unsigned int * otg_clkgate = (unsigned int*)(USB_CLKGATE_CON);
1980     volatile unsigned int * otg_clkreset = (unsigned int*)(RK29_CRU_BASE+0x70);
1981     volatile unsigned int * otg_dctl;
1982     volatile unsigned int * otg_gotgctl;
1983     volatile unsigned int * otg_hprt0;
1984     int bus_status = 0;
1985     
1986     
1987     // softreset & clockgate 
1988     *otg_clkreset |= (7<<16);
1989     udelay(3);
1990     *otg_clkreset &= ~(7<<16);
1991     *otg_clkgate &= ~((1<<4)|(3<<25));
1992         
1993     // exit phy suspend 
1994     *otg_phy_con1 |= (0x01<<2);
1995     *otg_phy_con1 |= (0x01<<3);    // exit suspend.
1996     *otg_phy_con1 &= ~(0x01<<2);
1997     
1998     // soft connect
1999     if(reg_base == 0){
2000         reg_base = ioremap(RK29_USBOTG0_PHYS,USBOTG_SIZE);
2001         if(!reg_base){
2002             bus_status = -1;
2003             goto out;
2004         }
2005     }
2006     mdelay(105);
2007     printk("regbase %p 0x%x, otg_phy_con%p, 0x%x, otg_clkgate %p,0x%x\n",
2008         reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1, otg_clkgate, *otg_clkgate);
2009     otg_dctl = (unsigned int * )(reg_base+0x804);
2010     otg_gotgctl = (unsigned int * )(reg_base);
2011     otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
2012     if(*otg_gotgctl &(1<<19)){
2013         bus_status = 1;
2014         *otg_dctl &= ~2;
2015         mdelay(50);    // delay about 10ms
2016     // check dp,dm
2017         if((*otg_hprt0 & 0xc00)==0xc00)
2018             bus_status = 2;
2019     }
2020 out:
2021     return bus_status;
2022 }
2023 #endif
2024 #ifdef CONFIG_ARCH_RK30
2025 int dwc_otg_check_dpdm(void)
2026 {
2027         static uint8_t * reg_base = 0;
2028     volatile unsigned int * otg_dctl;
2029     volatile unsigned int * otg_gotgctl;
2030     volatile unsigned int * otg_hprt0;
2031     int bus_status = 0;
2032     unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);
2033     
2034     // softreset & clockgate 
2035     *(unsigned int*)(RK30_CRU_BASE+0x120) = ((7<<5)<<16)|(7<<5);    // otg0 phy clkgate
2036     udelay(3);
2037     *(unsigned int*)(RK30_CRU_BASE+0x120) = ((7<<5)<<16)|(0<<5);    // otg0 phy clkgate
2038     dsb();
2039     *(unsigned int*)(RK30_CRU_BASE+0xd4) = ((1<<5)<<16);    // otg0 phy clkgate
2040     *(unsigned int*)(RK30_CRU_BASE+0xe4) = ((1<<13)<<16);   // otg0 hclk clkgate
2041     *(unsigned int*)(RK30_CRU_BASE+0xe0) = ((3<<5)<<16);    // hclk usb clkgate
2042     
2043     // exit phy suspend 
2044         *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.
2045     
2046     // soft connect
2047     if(reg_base == 0){
2048         reg_base = ioremap(RK30_USBOTG20_PHYS,USBOTG_SIZE);
2049         if(!reg_base){
2050             bus_status = -1;
2051             goto out;
2052         }
2053     }
2054     mdelay(105);
2055     printk("regbase %p 0x%x, otg_phy_con%p, 0x%x\n",
2056         reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1);
2057     otg_dctl = (unsigned int * )(reg_base+0x804);
2058     otg_gotgctl = (unsigned int * )(reg_base);
2059     otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
2060     if(*otg_gotgctl &(1<<19)){
2061         bus_status = 1;
2062         *otg_dctl &= ~2;
2063         mdelay(50);    // delay about 10ms
2064     // check dp,dm
2065         if((*otg_hprt0 & 0xc00)==0xc00)
2066             bus_status = 2;
2067     }
2068 out:
2069     return bus_status;
2070 }
2071
2072 EXPORT_SYMBOL(dwc_otg_check_dpdm);
2073 #endif
2074 #ifdef CONFIG_ARCH_RK2928
2075 int dwc_otg_check_dpdm(void)
2076 {
2077         static uint8_t * reg_base = 0;
2078     volatile unsigned int * otg_dctl;
2079     volatile unsigned int * otg_gotgctl;
2080     volatile unsigned int * otg_hprt0;
2081     int bus_status = 0;
2082     unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);//@lyz modify UOC0_CON2 to CON5
2083     
2084     // softreset & clockgate //@lyz modify RK2928_CRU_BASE
2085     *(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(7<<5);    // otg0 phy clkgate
2086     udelay(3);
2087     *(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(0<<5);    // otg0 phy clkgate
2088     dsb();
2089     *(unsigned int*)(RK2928_CRU_BASE+0xd4) = ((1<<5)<<16);    // otg0 phy clkgate
2090     *(unsigned int*)(RK2928_CRU_BASE+0xe4) = ((1<<13)<<16);   // otg0 hclk clkgate
2091     *(unsigned int*)(RK2928_CRU_BASE+0xf4) = ((3<<10)<<16);    // hclk usb clkgate//@lyz to be check
2092     
2093     // exit phy suspend 
2094         *otg_phy_con1 = ((0x01<<0)<<16);    // exit suspend.@lyz
2095     
2096     // soft connect
2097     if(reg_base == 0){
2098         reg_base = ioremap(RK2928_USBOTG20_PHYS,USBOTG_SIZE);//@lyz
2099         if(!reg_base){
2100             bus_status = -1;
2101             goto out;
2102         }
2103     }
2104     mdelay(105);
2105     printk("regbase %p 0x%x, otg_phy_con%p, 0x%x\n",
2106         reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1);
2107     otg_dctl = (unsigned int * )(reg_base+0x804);
2108     otg_gotgctl = (unsigned int * )(reg_base);
2109     otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
2110     if(*otg_gotgctl &(1<<19)){
2111         bus_status = 1;
2112         *otg_dctl &= ~(0x01<<1);//@lyz exit soft-disconnect mode
2113         mdelay(50);    // delay about 10ms
2114     // check dp,dm
2115         if((*otg_hprt0 & 0xc00)==0xc00)//@lyz check hprt[11:10] 
2116             bus_status = 2;
2117     }
2118 out:
2119     return bus_status;
2120 }
2121
2122 EXPORT_SYMBOL(dwc_otg_check_dpdm);
2123 #endif
2124 void dwc_otg_pcd_start_vbus_timer( dwc_otg_pcd_t * _pcd )
2125 {
2126         struct timer_list *vbus_timer = &_pcd->check_vbus_timer;
2127
2128         /* 
2129          * when receive reset int,the vbus state may not be update,so 
2130          * always start timer here.
2131          */                
2132         mod_timer( vbus_timer , jiffies + (HZ));
2133 }
2134
2135 /*
2136 * 20091228,HSL@RK,to get the current vbus status.
2137 */
2138 int dwc_vbus_status( void )
2139 {
2140     dwc_otg_pcd_t *pcd = s_pcd;
2141     if(!pcd)
2142        return 0;
2143     else
2144         return pcd->vbus_status ;
2145 }
2146 EXPORT_SYMBOL(dwc_vbus_status);
2147
2148 int dwc_otg_set_phy_status(uint8_t status)
2149 {
2150     dwc_otg_pcd_t *pcd = s_pcd;
2151     pcd->phy_suspend = status;
2152     return pcd->phy_suspend;
2153 }
2154 /** 
2155  * This function initialized the PCD portion of the driver.
2156  *
2157  */
2158 int dwc_otg_pcd_init(struct device *dev)
2159 {
2160         static char pcd_name[] = "dwc_otg_pcd";
2161         dwc_otg_pcd_t *pcd;
2162         dwc_otg_device_t *otg_dev = dev->platform_data;
2163     dwc_otg_core_if_t *core_if = otg_dev->core_if;
2164         int retval = 0;
2165         int irq;
2166          /*
2167          * Allocate PCD structure
2168          */
2169         pcd = kmalloc( sizeof(dwc_otg_pcd_t), GFP_KERNEL);
2170         
2171         if (pcd == 0) 
2172         {
2173                         return -ENOMEM;
2174         }
2175         
2176         memset( pcd, 0, sizeof(dwc_otg_pcd_t));
2177         spin_lock_init( &pcd->lock );
2178         otg_dev->pcd = pcd;
2179         s_pcd = pcd;
2180         pcd->gadget.name = pcd_name;
2181         //strcpy(pcd->gadget.dev.bus_id, "gadget");
2182         
2183         pcd->otg_dev = otg_dev;
2184         
2185         pcd->gadget.dev.parent = dev;
2186         pcd->gadget.dev.release = dwc_otg_pcd_gadget_release;
2187         pcd->gadget.dev.init_name= "gadget";
2188         pcd->gadget.ops = &dwc_otg_pcd_ops;
2189         
2190         pcd->gadget.is_dualspeed = 0;
2191         pcd->gadget.is_otg = 0;
2192         pcd->driver = 0;
2193     pcd->conn_en = 0;
2194         /* Register the gadget device */
2195         retval = device_register( &pcd->gadget.dev );
2196         if(retval != 0)
2197         {
2198                 DWC_ERROR("device_register failed\n");
2199                 return -EBUSY;
2200         }
2201         
2202         /*
2203          * Register the PCD Callbacks. 
2204          */
2205         dwc_otg_cil_register_pcd_callbacks( otg_dev->core_if, &pcd_callbacks, 
2206                                                                                 pcd );
2207         /*
2208          * Setup interupt handler
2209          */
2210         irq = platform_get_irq(to_platform_device(dev),0);
2211         DWC_DEBUGPL( DBG_ANY, "registering handler for irq%d\n", irq);
2212         retval = request_irq(irq, dwc_otg_pcd_irq,
2213                                                  IRQF_SHARED, pcd->gadget.name, pcd);
2214         if (retval != 0) 
2215         {
2216                 DWC_ERROR("request of irq%d failed\n", irq);
2217                 kfree (pcd);
2218                 return -EBUSY;
2219         }
2220     
2221         wake_lock_init(&pcd->wake_lock, WAKE_LOCK_SUSPEND,
2222                            "usb_pcd");
2223
2224         /*
2225          * Initialize EP structures
2226          */
2227         dwc_otg_pcd_reinit( pcd );
2228         /* 
2229          * Initialize the DMA buffer for SETUP packets
2230          */
2231         if (GET_CORE_IF(pcd)->dma_enable) 
2232         {
2233                 pcd->setup_pkt = dma_alloc_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, &pcd->setup_pkt_dma_handle, 0);
2234                 pcd->status_buf = dma_alloc_coherent (NULL, sizeof (uint16_t), &pcd->status_buf_dma_handle, 0);
2235         }
2236         else 
2237         {
2238                 pcd->setup_pkt = kmalloc (sizeof (*pcd->setup_pkt) * 5, GFP_KERNEL);
2239                 pcd->status_buf = kmalloc (sizeof (uint16_t), GFP_KERNEL);
2240         }
2241         
2242         if (pcd->setup_pkt == 0) 
2243         {
2244                 DWC_PRINT("pcd->setup_pkt alloc fail,everest\n");
2245                 kfree (pcd);
2246                 return -ENOMEM;
2247         }
2248         /* Initialize tasklet */
2249         start_xfer_tasklet.data = (unsigned long)pcd;
2250         pcd->start_xfer_tasklet = &start_xfer_tasklet;
2251
2252
2253
2254     init_timer( &pcd->check_vbus_timer );
2255     pcd->check_vbus_timer.function = dwc_otg_pcd_check_vbus_timer;
2256     pcd->check_vbus_timer.data = (unsigned long)(pcd);
2257     
2258     INIT_DELAYED_WORK(&pcd->reconnect , dwc_phy_reconnect);
2259     pcd->vbus_status  = 0;
2260     pcd->phy_suspend  = 0;
2261     if(dwc_otg_is_device_mode(core_if))
2262         mod_timer(&pcd->check_vbus_timer, jiffies+(HZ<<4)); // delay 16 S
2263         return 0;
2264 }
2265 /**
2266  * Cleanup the PCD.
2267  */
2268 void dwc_otg_pcd_remove( struct device *dev )
2269 {
2270         dwc_otg_device_t *otg_dev = dev->platform_data;
2271         dwc_otg_pcd_t *pcd = otg_dev->pcd;
2272         
2273         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
2274
2275         wake_lock_destroy(&pcd->wake_lock);
2276
2277         /*
2278          * Free the IRQ 
2279          */
2280         free_irq( platform_get_irq(to_platform_device(dev),0), pcd );
2281         
2282          /* start with the driver above us */
2283         if (pcd->driver) 
2284         {
2285                 /* should have been done already by driver model core */
2286                 DWC_WARN("driver '%s' is still registered\n",
2287                                          pcd->driver->driver.name);
2288                 usb_gadget_unregister_driver( pcd->driver);
2289         }
2290         device_unregister(&pcd->gadget.dev);
2291                 
2292         if (GET_CORE_IF(pcd)->dma_enable) 
2293         {
2294                 dma_free_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, pcd->setup_pkt, pcd->setup_pkt_dma_handle);
2295                 dma_free_coherent (NULL, sizeof (uint16_t), pcd->status_buf, pcd->status_buf_dma_handle);
2296         }
2297         else 
2298         {
2299                 kfree (pcd->setup_pkt);
2300                 kfree (pcd->status_buf);
2301         }
2302         
2303         kfree( pcd );
2304         otg_dev->pcd = 0;
2305     s_pcd = 0; 
2306 }
2307
2308 /**
2309  * This function registers a gadget driver with the PCD.
2310  *
2311  * When a driver is successfully registered, it will receive control
2312  * requests including set_configuration(), which enables non-control
2313  * requests.  then usb traffic follows until a disconnect is reported.
2314  * then a host may connect again, or the driver might get unbound.
2315  *
2316  * @param _driver The driver being registered
2317  */
2318  
2319 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
2320 int usb_gadget_probe_driver(struct usb_gadget_driver *_driver,
2321                 int (*bind)(struct usb_gadget *))
2322 #else
2323 int usb_gadget_register_driver(struct usb_gadget_driver *_driver)
2324 #endif
2325 {
2326         int retval;
2327
2328         DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", _driver->driver.name);
2329                 
2330         if (!_driver || _driver->speed == USB_SPEED_UNKNOWN || 
2331 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
2332                 !bind ||
2333 #else
2334                 !_driver->bind || 
2335 #endif
2336                 !_driver->unbind || 
2337                 !_driver->disconnect || 
2338                 !_driver->setup) 
2339         {
2340                 DWC_ERROR("EINVAL\n");  
2341                 return -EINVAL;
2342         }
2343         if (s_pcd == 0) 
2344         {
2345                 DWC_ERROR("ENODEV\n");  
2346                 return -ENODEV;
2347         }
2348         if (s_pcd->driver != 0) 
2349         {
2350                 DWC_ERROR("EBUSY (%p)\n", s_pcd->driver);   
2351                 return -EBUSY;
2352         }
2353         
2354         /* hook up the driver */
2355         s_pcd->driver = _driver;
2356         s_pcd->gadget.dev.driver = &_driver->driver;
2357
2358         DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", _driver->driver.name);
2359 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
2360         retval = bind(&s_pcd->gadget);
2361 #else
2362         retval = _driver->bind(&s_pcd->gadget);
2363 #endif
2364         if (retval) 
2365         {
2366                 DWC_ERROR("bind to driver %s --> error %d\n",
2367                                         _driver->driver.name, retval);
2368                 s_pcd->driver = 0;
2369                 s_pcd->gadget.dev.driver = 0;
2370                 return retval;
2371         }
2372         DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n", 
2373                                         _driver->driver.name);
2374         return 0;
2375 }
2376 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
2377 EXPORT_SYMBOL(usb_gadget_probe_driver);
2378 #else
2379 EXPORT_SYMBOL(usb_gadget_register_driver);
2380 #endif
2381
2382 /**
2383  * This function unregisters a gadget driver
2384  *
2385  * @param _driver The driver being unregistered
2386  */
2387 int usb_gadget_unregister_driver(struct usb_gadget_driver *_driver)
2388 {
2389         DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver);
2390
2391         if (s_pcd == 0) 
2392         {
2393                 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__, 
2394                                         -ENODEV);
2395                 return -ENODEV;
2396         }
2397         if (_driver == 0 || _driver != s_pcd->driver) 
2398         {
2399                 DWC_DEBUGPL( DBG_ANY, "%s Return(%d): driver?\n", __func__, 
2400                                         -EINVAL);
2401                 return -EINVAL;
2402         }
2403
2404         _driver->unbind(&s_pcd->gadget);
2405         s_pcd->driver = 0;
2406
2407         DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n", 
2408                                         _driver->driver.name);
2409         return 0;
2410 }
2411 EXPORT_SYMBOL(usb_gadget_unregister_driver);
2412 #endif /* DWC_HOST_ONLY */