RK2928 usb pcd modified
[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     }
1051     return 0;
1052 }
1053
1054 static const struct usb_gadget_ops dwc_otg_pcd_ops = 
1055 {
1056         .get_frame       = dwc_otg_pcd_get_frame,
1057         .wakeup          = dwc_otg_pcd_wakeup,
1058         .pullup      = dwc_otg_pcd_pullup,
1059         // current versions must always be self-powered
1060 };
1061
1062 /**
1063  * This function updates the otg values in the gadget structure. 
1064  */
1065 void dwc_otg_pcd_update_otg( dwc_otg_pcd_t *_pcd, const unsigned _reset )
1066 {
1067                 
1068         if (!_pcd->gadget.is_otg)
1069                 return;
1070
1071         if (_reset) 
1072         {
1073                 _pcd->b_hnp_enable = 0;
1074                 _pcd->a_hnp_support = 0;
1075                 _pcd->a_alt_hnp_support = 0;
1076         }
1077
1078         _pcd->gadget.b_hnp_enable = _pcd->b_hnp_enable;
1079         _pcd->gadget.a_hnp_support =  _pcd->a_hnp_support;
1080         _pcd->gadget.a_alt_hnp_support = _pcd->a_alt_hnp_support;
1081 }
1082
1083 /** 
1084  * This function is the top level PCD interrupt handler.
1085  */
1086 static irqreturn_t 
1087 dwc_otg_pcd_irq(int _irq, void *_dev)
1088 {
1089         dwc_otg_pcd_t *pcd = _dev;
1090         int32_t retval = IRQ_NONE;
1091
1092         retval = dwc_otg_pcd_handle_intr( pcd );
1093         return IRQ_RETVAL(retval);
1094 }
1095
1096 /**
1097  * PCD Callback function for initializing the PCD when switching to
1098  * device mode.
1099  *
1100  * @param _p void pointer to the <code>dwc_otg_pcd_t</code>
1101  */
1102  
1103 static int32_t dwc_otg_pcd_start_cb( void *_p )
1104 {
1105         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)_p;
1106         
1107         /*
1108          * Initialized the Core for Device mode.
1109          */
1110         if (dwc_otg_is_device_mode( GET_CORE_IF(pcd) ))
1111         {
1112         pcd->phy_suspend = 1;
1113         pcd->vbus_status = 0;
1114         dwc_otg_pcd_start_vbus_timer(pcd);
1115         }
1116         
1117         return 1;
1118 }
1119
1120 /**
1121  * PCD Callback function for stopping the PCD when switching to Host
1122  * mode.
1123  *
1124  * @param _p void pointer to the <code>dwc_otg_pcd_t</code>
1125  */
1126 static int32_t dwc_otg_pcd_stop_cb( void *_p )
1127 {
1128         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)_p;
1129         extern void dwc_otg_pcd_stop(dwc_otg_pcd_t *_pcd);
1130         
1131         dwc_otg_pcd_stop( pcd );
1132         return 1;
1133 }
1134
1135
1136 /**
1137  * PCD Callback function for notifying the PCD when resuming from
1138  * suspend.
1139  *
1140  * @param _p void pointer to the <code>dwc_otg_pcd_t</code>
1141  */
1142 static int32_t dwc_otg_pcd_suspend_cb( void *_p ,int suspend)
1143 {
1144         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)_p;
1145 //#ifdef CONFIG_ANDROID_POWER
1146 #if 0
1147         /* yk@rk 20100520
1148          * PC disconnect the USB, unlock the msc_lock and
1149          * system can enter level 2 sleep mode.
1150          */
1151         struct usb_composite_dev        *cdev;
1152         if (pcd->driver && pcd->driver->resume) 
1153         {
1154                 cdev = get_gadget_data(&pcd->gadget);
1155                 if(cdev->config)
1156                         pcd->conn_status = 3;
1157         }
1158 #endif
1159 //#endif                
1160         if (pcd->driver && pcd->driver->resume) 
1161         {
1162                 pcd->driver->suspend(&pcd->gadget);
1163         }
1164         return 1;
1165 }
1166
1167
1168 /**
1169  * PCD Callback function for notifying the PCD when resuming from
1170  * suspend.
1171  *
1172  * @param _p void pointer to the <code>dwc_otg_pcd_t</code>
1173  */
1174 static int32_t dwc_otg_pcd_resume_cb( void *_p )
1175 {
1176         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t *)_p;
1177         
1178         if (pcd->driver && pcd->driver->resume) 
1179         {
1180                         pcd->driver->resume(&pcd->gadget);
1181         }
1182         
1183         /* Stop the SRP timeout timer. */
1184         if ((GET_CORE_IF(pcd)->core_params->phy_type != DWC_PHY_TYPE_PARAM_FS) ||
1185                 (!GET_CORE_IF(pcd)->core_params->i2c_enable))
1186         {
1187                 if (GET_CORE_IF(pcd)->srp_timer_started) 
1188                 {
1189                         GET_CORE_IF(pcd)->srp_timer_started = 0;
1190                         del_timer( &pcd->srp_timer );
1191                 }
1192         }
1193         return 1;
1194 }
1195
1196
1197 /**
1198  * PCD Callback structure for handling mode switching.
1199  */
1200 static dwc_otg_cil_callbacks_t pcd_callbacks = 
1201 {
1202         .start = dwc_otg_pcd_start_cb,
1203         .stop = dwc_otg_pcd_stop_cb,
1204         .suspend = dwc_otg_pcd_suspend_cb,
1205         .resume_wakeup = dwc_otg_pcd_resume_cb,
1206         .p = 0, /* Set at registration */
1207 };
1208
1209 /**
1210  * This function is called when the SRP timer expires.  The SRP should
1211  * complete within 6 seconds. 
1212  */
1213 static void srp_timeout( unsigned long _ptr )
1214 {
1215         gotgctl_data_t gotgctl;
1216         dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *)_ptr;
1217         volatile uint32_t *addr = &core_if->core_global_regs->gotgctl;
1218
1219         gotgctl.d32 = dwc_read_reg32(addr);
1220
1221         core_if->srp_timer_started = 0;
1222
1223         if ((core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS) && 
1224                 (core_if->core_params->i2c_enable))
1225         {
1226                 DWC_PRINT( "SRP Timeout\n");
1227
1228                 if ((core_if->srp_success) && 
1229                         (gotgctl.b.bsesvld))
1230                 {
1231                         if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup ) 
1232                         {
1233                                 core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
1234                         }
1235                         
1236                         /* Clear Session Request */
1237                         gotgctl.d32 = 0;
1238                         gotgctl.b.sesreq = 1;
1239                         dwc_modify_reg32( &core_if->core_global_regs->gotgctl, 
1240                                           gotgctl.d32, 0);
1241         
1242                         core_if->srp_success = 0;
1243                 }
1244                 else 
1245                 {
1246                         DWC_ERROR( "Device not connected/responding\n");
1247                         gotgctl.b.sesreq = 0;
1248                         dwc_write_reg32(addr, gotgctl.d32);
1249                 }
1250         }
1251         else if (gotgctl.b.sesreq) 
1252         {
1253                 DWC_PRINT( "SRP Timeout\n");
1254
1255                 DWC_ERROR( "Device not connected/responding\n");
1256                 gotgctl.b.sesreq = 0;
1257                 dwc_write_reg32(addr, gotgctl.d32);
1258         } 
1259         else 
1260         {
1261                 DWC_PRINT( " SRP GOTGCTL=%0x\n", gotgctl.d32);
1262         } 
1263 }
1264
1265 /**
1266  * Start the SRP timer to detect when the SRP does not complete within 
1267  * 6 seconds.
1268  *
1269  * @param _pcd the pcd structure.
1270  */
1271 void dwc_otg_pcd_start_srp_timer(dwc_otg_pcd_t *_pcd )
1272 {
1273         struct timer_list *srp_timer = &_pcd->srp_timer;
1274         GET_CORE_IF(_pcd)->srp_timer_started = 1;
1275         init_timer( srp_timer );
1276         srp_timer->function = srp_timeout;
1277         srp_timer->data = (unsigned long)GET_CORE_IF(_pcd);
1278         srp_timer->expires = jiffies + (HZ*6);
1279         add_timer( srp_timer );
1280 }
1281
1282 /**
1283  * Tasklet
1284  *
1285  */
1286 extern void start_next_request( dwc_otg_pcd_ep_t *_ep );
1287
1288 static void start_xfer_tasklet_func (unsigned long data)
1289 {
1290         dwc_otg_pcd_t *pcd = (dwc_otg_pcd_t*)data;
1291         dwc_otg_core_if_t *core_if = pcd->otg_dev->core_if;
1292
1293         int i;
1294         depctl_data_t diepctl;
1295
1296         DWC_DEBUGPL(DBG_PCDV, "Start xfer tasklet\n");
1297
1298         diepctl.d32 = dwc_read_reg32( &core_if->dev_if->in_ep_regs[0]->diepctl);
1299
1300         if (pcd->ep0.queue_sof) 
1301         {
1302                 pcd->ep0.queue_sof = 0;
1303                 start_next_request (&pcd->ep0);
1304                 // break;
1305         }
1306
1307         for (i=0; i<core_if->dev_if->num_in_eps; i++) 
1308         {
1309                 depctl_data_t diepctl;
1310                 diepctl.d32 = dwc_read_reg32( &core_if->dev_if->in_ep_regs[i]->diepctl);
1311
1312                 if (pcd->in_ep[i].queue_sof) 
1313                 {
1314                         pcd->in_ep[i].queue_sof = 0;
1315                         start_next_request (&pcd->in_ep[i]);
1316                         // break;
1317                 }
1318         }
1319
1320         return;
1321 }
1322
1323
1324
1325
1326
1327
1328
1329 static struct tasklet_struct start_xfer_tasklet = {
1330         .next = NULL,
1331         .state = 0,
1332         .count = ATOMIC_INIT(0),
1333         .func = start_xfer_tasklet_func,
1334         .data = 0,//pcd
1335 };
1336 /**
1337  * This function initialized the pcd Dp structures to there default
1338  * state.
1339  *
1340  * @param _pcd the pcd structure.
1341  */
1342 void dwc_otg_pcd_reinit(dwc_otg_pcd_t *_pcd)
1343 {
1344         dwc_otg_core_if_t * core_if = GET_CORE_IF(_pcd);
1345         
1346         //dwc_otg_dump_dev_registers(core_if);
1347         static const char * names[] = 
1348                 {
1349                         
1350                         "ep0",
1351                         "ep1in",        
1352                         "ep2in",        
1353                         "ep3in",        
1354                         "ep4in",        
1355                         "ep5in",        
1356                         "ep6in",        
1357                         "ep7in",        
1358                         "ep8in",        
1359                         "ep9in",        
1360                         "ep10in",       
1361                         "ep11in",       
1362                         "ep12in",       
1363                         "ep13in",       
1364                         "ep14in",       
1365                         "ep15in",       
1366                         "ep1out",  
1367                         "ep2out",  
1368                         "ep3out",
1369                         "ep4out",
1370                         "ep5out",
1371                         "ep6out",
1372                         "ep7out",
1373                         "ep8out",
1374                         "ep9out",
1375                         "ep10out",
1376                         "ep11out",
1377                         "ep12out",
1378                         "ep13out",
1379                         "ep14out",
1380                         "ep15out"
1381                         
1382         };
1383                 
1384         int i;
1385         int in_ep_cntr, out_ep_cntr;
1386         uint32_t hwcfg1;
1387         uint32_t num_in_eps = core_if->dev_if->num_in_eps; /* = 3 */
1388         uint32_t num_out_eps = core_if->dev_if->num_out_eps; /* = 3 */
1389         dwc_otg_pcd_ep_t *ep;
1390         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, _pcd);
1391         
1392         INIT_LIST_HEAD (&_pcd->gadget.ep_list);
1393         _pcd->gadget.ep0 = &_pcd->ep0.ep;
1394         _pcd->gadget.speed = USB_SPEED_UNKNOWN;
1395
1396         INIT_LIST_HEAD (&_pcd->gadget.ep0->ep_list);
1397
1398         /**
1399          * Initialize the EP0 structure.
1400          */
1401         ep = &_pcd->ep0;
1402
1403         /* Init EP structure */
1404         ep->desc = 0;
1405         ep->pcd = _pcd;
1406         ep->stopped = 1;
1407
1408         /* Init DWC ep structure */
1409         ep->dwc_ep.num = 0;
1410         ep->dwc_ep.active = 0;
1411         ep->dwc_ep.tx_fifo_num = 0;
1412         /* Control until ep is actvated */
1413         ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL; 
1414         ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
1415         ep->dwc_ep.dma_addr = 0;
1416         ep->dwc_ep.start_xfer_buff = 0;
1417         ep->dwc_ep.xfer_buff = 0;
1418         ep->dwc_ep.xfer_len = 0;
1419         ep->dwc_ep.xfer_count = 0;
1420         ep->dwc_ep.sent_zlp = 0;
1421         ep->dwc_ep.total_len = 0;
1422         ep->queue_sof = 0;
1423
1424         /* Init the usb_ep structure. */
1425         ep->ep.name = names[0];
1426         ep->ep.ops = &dwc_otg_pcd_ep_ops;
1427
1428         /**
1429          * @todo NGS: What should the max packet size be set to
1430          * here?  Before EP type is set?
1431          */
1432         ep->ep.maxpacket = MAX_PACKET_SIZE;
1433
1434         list_add_tail (&ep->ep.ep_list, &_pcd->gadget.ep_list);
1435                 
1436         INIT_LIST_HEAD (&ep->queue);
1437         /**
1438          * Initialize the EP structures.
1439          */
1440         in_ep_cntr = 0;
1441         hwcfg1 = core_if->hwcfg1.d32 >> 3;
1442          
1443         for (i = 1; in_ep_cntr < num_in_eps; i++) 
1444         {
1445                 if((hwcfg1 & 0x1) == 0)
1446                 {
1447                         dwc_otg_pcd_ep_t *ep = &_pcd->in_ep[in_ep_cntr];
1448                         in_ep_cntr ++;
1449                         
1450                         /* Init EP structure */
1451                         ep->desc = 0;
1452                         ep->pcd = _pcd;
1453                         ep->stopped = 1;
1454         
1455                         /* Init DWC ep structure */
1456                         ep->dwc_ep.is_in = 1;
1457                         ep->dwc_ep.num = i;
1458                         ep->dwc_ep.active = 0;
1459                         ep->dwc_ep.tx_fifo_num = 0;
1460                         
1461                         /* Control until ep is actvated */
1462                         ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL; 
1463                         ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
1464                         ep->dwc_ep.dma_addr = 0;
1465                         ep->dwc_ep.start_xfer_buff = 0;
1466                         ep->dwc_ep.xfer_buff = 0;
1467                         ep->dwc_ep.xfer_len = 0;
1468                         ep->dwc_ep.xfer_count = 0;
1469                         ep->dwc_ep.sent_zlp = 0;
1470                         ep->dwc_ep.total_len = 0;
1471                         ep->queue_sof = 0;
1472         
1473                         /* Init the usb_ep structure. */
1474                         /**
1475                          * @todo NGS: Add direction to EP, based on contents
1476                          * of HWCFG1.  Need a copy of HWCFG1 in pcd structure?
1477                          * sprintf( ";r
1478                          */
1479                         ep->ep.name = names[i];
1480                         ep->ep.ops = &dwc_otg_pcd_ep_ops;
1481                         
1482                         /**
1483                          * @todo NGS: What should the max packet size be set to
1484                          * here?  Before EP type is set?
1485                          */
1486                         ep->ep.maxpacket = MAX_PACKET_SIZE;
1487                         
1488                         INIT_LIST_HEAD (&ep->queue);
1489
1490                         /**
1491                          * @yk@rk 20120329
1492                          * EP8&EP9 of rk30 are IN&OUT ep, we use ep8 as OUT EP default
1493                          */
1494                 #ifdef CONFIG_ARCH_RK30
1495                 if(i == 8)
1496                     continue;
1497                 #endif
1498                 #ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30
1499                 if(i == 8)
1500                     continue;
1501                 #endif
1502                         list_add_tail (&ep->ep.ep_list, &_pcd->gadget.ep_list);
1503                                 
1504                 }
1505                 hwcfg1 >>= 2;
1506         }
1507         out_ep_cntr = 0;
1508         hwcfg1 = core_if->hwcfg1.d32 >> 2;
1509
1510         for (i = 1; out_ep_cntr < num_out_eps; i++) 
1511         {
1512                 if((hwcfg1 & 0x1) == 0)
1513                 {
1514                         dwc_otg_pcd_ep_t *ep = &_pcd->out_ep[out_ep_cntr];
1515                         out_ep_cntr++;
1516         
1517                         /* Init EP structure */
1518                         ep->desc = 0;
1519                         ep->pcd = _pcd;
1520                         ep->stopped = 1;
1521         
1522                         /* Init DWC ep structure */
1523                         ep->dwc_ep.is_in = 0;
1524                         ep->dwc_ep.num = i;
1525                         ep->dwc_ep.active = 0;
1526                         ep->dwc_ep.tx_fifo_num = 0;
1527                         /* Control until ep is actvated */
1528                         ep->dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL; 
1529                         ep->dwc_ep.maxpacket = MAX_PACKET_SIZE;
1530                         ep->dwc_ep.dma_addr = 0;
1531                         ep->dwc_ep.start_xfer_buff = 0;
1532                         ep->dwc_ep.xfer_buff = 0;
1533                         ep->dwc_ep.xfer_len = 0;
1534                         ep->dwc_ep.xfer_count = 0;
1535                         ep->dwc_ep.sent_zlp = 0;
1536                         ep->dwc_ep.total_len = 0;
1537                         ep->queue_sof = 0;
1538         
1539                         /* Init the usb_ep structure. */
1540                         /**
1541                          * @todo NGS: Add direction to EP, based on contents
1542                          * of HWCFG1.  Need a copy of HWCFG1 in pcd structure?
1543                          * sprintf( ";r
1544                          */
1545                         ep->ep.name = names[15 + i];
1546                         ep->ep.ops = &dwc_otg_pcd_ep_ops;
1547                         /**
1548                          * @todo NGS: What should the max packet size be set to
1549                          * here?  Before EP type is set?
1550                          */
1551                         ep->ep.maxpacket = MAX_PACKET_SIZE;
1552         
1553                         INIT_LIST_HEAD (&ep->queue);
1554                         
1555                         /**
1556                          * @yk@rk 20120329
1557                          * EP8&EP9 of rk30 are IN&OUT ep, we use ep9 as IN EP default
1558                          */
1559                 #ifdef CONFIG_ARCH_RK30
1560                 if(i == 9)
1561                     continue;
1562                 #endif
1563                 #ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30
1564                 if(i == 9)
1565                     continue;
1566                 #endif
1567                         list_add_tail (&ep->ep.ep_list, &_pcd->gadget.ep_list);
1568                                 
1569                 }
1570                 hwcfg1 >>= 2;
1571         }
1572         
1573         /* remove ep0 from the list.  There is a ep0 pointer.*/
1574         list_del_init (&_pcd->ep0.ep.ep_list);
1575    
1576         _pcd->ep0state = EP0_DISCONNECT;
1577         _pcd->ep0.ep.maxpacket = MAX_EP0_SIZE;            
1578         _pcd->ep0.dwc_ep.maxpacket = MAX_EP0_SIZE;
1579         _pcd->ep0.dwc_ep.type = DWC_OTG_EP_TYPE_CONTROL;
1580 }
1581
1582 /**
1583  * This function releases the Gadget device.
1584  * required by device_unregister().
1585  *
1586  * @todo Should this do something?      Should it free the PCD? 
1587  */
1588 static void dwc_otg_pcd_gadget_release(struct device *_dev)
1589 {
1590         DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _dev);
1591 }
1592
1593 int dwc_pcd_reset(dwc_otg_pcd_t *pcd)
1594 {
1595     dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1596     dwc_otg_disable_global_interrupts( core_if );
1597     //
1598 #ifdef CONFIG_ARCH_RK29
1599     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_AHB_BUS, true);
1600     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_PHY, true);
1601     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_CONTROLLER, true);
1602     udelay(1);
1603
1604     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_AHB_BUS, false);
1605     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_PHY, false);
1606     cru_set_soft_reset(SOFT_RST_USB_OTG_2_0_CONTROLLER, false);
1607 #endif    
1608     //rockchip_scu_reset_unit(12);
1609     dwc_otg_pcd_reinit( pcd );
1610     dwc_otg_core_dev_init(core_if);
1611     //DWC_PRINT("%s\n" , __func__ );
1612     dwc_otg_enable_global_interrupts( core_if );
1613     return 0;
1614 }
1615
1616 /*
1617  * close usb phy , about 7ma--2.5v
1618  * 20090925,add vbus test code.500ms ¼ä¸ô.
1619  * 20100122,HSL@RK,hard reset usb controller and phy.
1620 */
1621 int dwc_otg20phy_suspend( int exitsuspend )
1622 {
1623         dwc_otg_pcd_t *pcd = s_pcd;
1624 #ifdef CONFIG_ARCH_RK29
1625     unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON);
1626     if(exitsuspend && (pcd->phy_suspend == 1)) {
1627         clk_enable(pcd->otg_dev->ahbclk);
1628         clk_enable(pcd->otg_dev->phyclk);
1629         pcd->phy_suspend = 0;
1630         *otg_phy_con1 |= (0x01<<2);
1631         *otg_phy_con1 |= (0x01<<3);    // exit suspend.
1632         *otg_phy_con1 &= ~(0x01<<2);
1633         
1634         /* 20091011,reenable usb phy ,will raise reset intr */
1635         //debug_print("enable usb phy\n");
1636         DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
1637     }
1638     if( !exitsuspend && (pcd->phy_suspend == 0)) {
1639         pcd->phy_suspend = 1;
1640         *otg_phy_con1 |= ((0x01<<2)|(0x05<<6));
1641         *otg_phy_con1 &= ~(0x01<<3);    // enter suspend.
1642         udelay(3);
1643         clk_disable(pcd->otg_dev->phyclk);
1644         clk_disable(pcd->otg_dev->ahbclk);
1645         //*otg_phy_con1 &= ~(0x01<<2);
1646         //debug_print("disable usb phy\n");
1647         DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
1648     }
1649 #endif
1650 #ifdef CONFIG_ARCH_RK30
1651     unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);
1652     if(exitsuspend && (pcd->phy_suspend == 1)) {
1653         clk_enable(pcd->otg_dev->ahbclk);
1654         clk_enable(pcd->otg_dev->phyclk);
1655         pcd->phy_suspend = 0;
1656         *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.
1657         DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
1658     }
1659     if( !exitsuspend && (pcd->phy_suspend == 0)) {
1660         pcd->phy_suspend = 1;
1661         *otg_phy_con1 = 0x554|(0xfff<<16);   // enter suspend.
1662         udelay(3);
1663         clk_disable(pcd->otg_dev->phyclk);
1664         clk_disable(pcd->otg_dev->ahbclk);
1665         DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
1666     }
1667 #endif
1668 #ifdef CONFIG_ARCH_RK2928                
1669     unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);
1670     if(exitsuspend && (pcd->phy_suspend == 1)) {
1671         clk_enable(pcd->otg_dev->ahbclk);
1672         clk_enable(pcd->otg_dev->phyclk);
1673         pcd->phy_suspend = 0;
1674         *otg_phy_con1 = (0x01<<16);    // exit suspend.
1675         DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
1676     }
1677     if( !exitsuspend && (pcd->phy_suspend == 0)) {
1678         pcd->phy_suspend = 1;
1679         *otg_phy_con1 = 0x55 |(0x7f<<16);   // enter suspend.
1680         udelay(3);
1681         clk_disable(pcd->otg_dev->phyclk);
1682         clk_disable(pcd->otg_dev->ahbclk);
1683         DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
1684     }
1685 #endif
1686     return pcd->phy_suspend;
1687 }
1688
1689 int dwc_otg_reset( void ) 
1690 {
1691     dwc_otg_pcd_t * pcd = s_pcd;
1692     dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
1693     dctl_data_t dctl = {.d32=0};
1694
1695     dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
1696     dctl.b.sftdiscon = 1;
1697     dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
1698     //DWC_PRINT("%s::otg reset connect!!!\n" , __func__ );
1699     return 0;
1700 }
1701 void dwc_otg_msc_lock(dwc_otg_pcd_t *pcd)
1702 {
1703         unsigned long           flags;
1704
1705         local_irq_save(flags);
1706     wake_lock(&pcd->wake_lock);
1707     local_irq_restore(flags);
1708
1709 }
1710
1711 void dwc_otg_msc_unlock(dwc_otg_pcd_t *pcd)
1712 {
1713         unsigned long           flags;
1714         local_irq_save(flags);
1715         wake_unlock(&pcd->wake_lock);
1716         local_irq_restore(flags);
1717 }
1718 static void dwc_phy_reconnect(struct work_struct *work)
1719 {
1720     dwc_otg_pcd_t *pcd;
1721     dwc_otg_core_if_t *core_if;
1722     gotgctl_data_t    gctrl;
1723     dctl_data_t dctl = {.d32=0};
1724
1725     pcd = container_of(work, dwc_otg_pcd_t, reconnect.work);
1726     core_if = GET_CORE_IF(pcd); 
1727     gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl );
1728     if( gctrl.b.bsesvld  ) {
1729         pcd->conn_status++;
1730             dwc_pcd_reset(pcd);
1731         /*
1732          * Enable the global interrupt after all the interrupt
1733          * handlers are installed.
1734          */
1735         dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
1736         dctl.b.sftdiscon = 0;
1737         dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );      
1738         DWC_PRINT("********soft connect!!!*****************************************\n");
1739     } 
1740 }
1741 #ifdef CONFIG_ARCH_RK29
1742 static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
1743 {
1744     dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata;
1745     dwc_otg_core_if_t *core_if = GET_CORE_IF(_pcd);
1746     gotgctl_data_t    gctrl;
1747     dctl_data_t dctl = {.d32=0};
1748     //dsts_data_t           gsts;
1749         unsigned long flags;
1750         local_irq_save(flags);
1751     gctrl.d32 = dwc_read_reg32( &core_if->core_global_regs->gotgctl );
1752     //gsts.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dsts);
1753
1754     _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */
1755     if( gctrl.b.bsesvld ) {
1756         /* if usb not connect before ,then start connect */
1757          if( _pcd->vbus_status == 0 ) {
1758             dwc_otg_msc_lock(_pcd);
1759             DWC_PRINT("********vbus detect*********************************************\n");
1760             _pcd->vbus_status = 1;
1761             /* soft disconnect */
1762             dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
1763             dctl.b.sftdiscon = 1;
1764             dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
1765             /* Clear any pending interrupts */
1766             dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); 
1767             if(_pcd->conn_en)
1768             {
1769                     schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
1770                      _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
1771             }
1772
1773         } else if((_pcd->conn_status>0)&&(_pcd->conn_status <3)) {
1774             //dwc_otg_msc_unlock(_pcd);
1775             DWC_PRINT("********soft reconnect******************************************\n");
1776             //_pcd->vbus_status =0;
1777             
1778             /* soft disconnect */
1779                 dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
1780                 dctl.b.sftdiscon = 1;
1781                 dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
1782             /* Clear any pending interrupts */
1783             dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF); 
1784             if(_pcd->conn_en)
1785             {
1786                     schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
1787                      _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
1788             }
1789         }
1790         else if((_pcd->conn_en)&&(_pcd->conn_status == 0))
1791         {
1792         
1793             schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
1794                      _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
1795         }
1796         else if(_pcd->conn_status ==3)
1797         {
1798                         //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*//
1799             dwc_otg_msc_unlock(_pcd);
1800             _pcd->conn_status++;
1801             if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
1802                 _pcd->vbus_status = 2;
1803         }
1804     } else {
1805         //DWC_PRINT("new vbus=%d,old vbus=%d\n" , gctrl.b.bsesvld , _pcd->vbus_status );
1806         _pcd->vbus_status = 0;
1807         if(_pcd->conn_status)
1808         {
1809              _pcd->conn_status = 0;
1810              dwc_otg_msc_unlock(_pcd);
1811         }
1812         /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */
1813         if( _pcd->phy_suspend == 0 ) {
1814                 /* no vbus detect here , close usb phy for 500ms */
1815              dwc_otg20phy_suspend( 0 );
1816               _pcd->check_vbus_timer.expires = jiffies + (HZ/2); /* 500 ms */
1817         } else if( _pcd->phy_suspend  == 1 ) { 
1818              dwc_otg20phy_suspend( 1 );
1819              /*20100325 yk@rk,delay 2-->8,for host connect id detect*/
1820              _pcd->check_vbus_timer.expires = jiffies + 8; /* 20091127,HSL@RK,1-->2  */
1821              
1822         }
1823     }
1824     //DWC_PRINT("%s:restart check vbus timer\n" , __func__ );
1825     add_timer(&_pcd->check_vbus_timer); 
1826         local_irq_restore(flags);
1827 }
1828 #endif
1829 #ifdef CONFIG_ARCH_RK30
1830 static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
1831 {
1832     dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata;
1833         unsigned long flags;
1834     unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);
1835
1836         local_irq_save(flags);
1837     _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */
1838     if((usbgrf_status &(1<<20)) == 0){  // id low
1839     
1840         if( _pcd->phy_suspend) 
1841              dwc_otg20phy_suspend( 1 );
1842     }
1843         else if(usbgrf_status &0x20000){  // bvalid
1844         /* if usb not connect before ,then start connect */
1845          if( _pcd->vbus_status == 0 ) {
1846             DWC_PRINT("********vbus detect*********************************************\n");
1847             dwc_otg_msc_lock(_pcd);
1848             _pcd->vbus_status = 1;
1849             if(_pcd->conn_en)
1850                 goto connect;
1851             else
1852                 dwc_otg20phy_suspend( 0 );
1853         } 
1854         else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <3)){
1855             DWC_PRINT("********soft reconnect******************************************\n");
1856             goto connect;
1857         }
1858         else if(_pcd->conn_status ==3){
1859                         //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*//
1860             dwc_otg_msc_unlock(_pcd);
1861             _pcd->conn_status++;
1862             if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
1863                 _pcd->vbus_status = 2;
1864         }
1865         }else {
1866         _pcd->vbus_status = 0;
1867         if(_pcd->conn_status)
1868         {
1869              _pcd->conn_status = 0;
1870              dwc_otg_msc_unlock(_pcd);
1871         }
1872         /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */
1873         if( _pcd->phy_suspend == 0 ) 
1874                 /* no vbus detect here , close usb phy  */
1875              dwc_otg20phy_suspend( 0 );
1876     }
1877     add_timer(&_pcd->check_vbus_timer); 
1878         local_irq_restore(flags);
1879     return;
1880
1881 connect:
1882     if( _pcd->phy_suspend  == 1 )
1883          dwc_otg20phy_suspend( 1 );
1884     schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
1885      _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
1886     add_timer(&_pcd->check_vbus_timer); 
1887         local_irq_restore(flags);
1888     return;
1889 }
1890
1891 #endif
1892 #ifdef CONFIG_ARCH_RK2928
1893 static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
1894 {
1895     dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata;
1896         unsigned long flags;
1897     unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);//@lyz USBGRF_SOC_STATUS0½á¹¹Óбä
1898
1899         local_irq_save(flags);
1900     _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */
1901     if((usbgrf_status &(1<<10)) == 0){  // id low  //@lyz SOC_STATUS0[10] represents id_dig
1902     
1903         if( _pcd->phy_suspend) 
1904              dwc_otg20phy_suspend( 1 );
1905     }
1906         else if(usbgrf_status & (1<<7)){  //@lyz SOC_STATUS0[7] represents bvalid
1907         /* if usb not connect before ,then start connect */
1908          if( _pcd->vbus_status == 0 ) {
1909             DWC_PRINT("********vbus detect*********************************************\n");
1910             dwc_otg_msc_lock(_pcd);
1911             _pcd->vbus_status = 1;
1912             if(_pcd->conn_en)
1913                 goto connect;
1914             else
1915                 dwc_otg20phy_suspend( 0 );
1916         } 
1917         else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <3)){
1918             DWC_PRINT("********soft reconnect******************************************\n");
1919             goto connect;
1920         }
1921         else if(_pcd->conn_status ==3){
1922                         //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*//
1923             dwc_otg_msc_unlock(_pcd);
1924             _pcd->conn_status++;
1925             if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
1926                 _pcd->vbus_status = 2;
1927         }
1928         }else {
1929         _pcd->vbus_status = 0;
1930         if(_pcd->conn_status)
1931         {
1932              _pcd->conn_status = 0;
1933              dwc_otg_msc_unlock(_pcd);
1934         }
1935         /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */
1936         if( _pcd->phy_suspend == 0 ) 
1937                 /* no vbus detect here , close usb phy  */
1938              dwc_otg20phy_suspend( 0 );
1939     }
1940     add_timer(&_pcd->check_vbus_timer); 
1941         local_irq_restore(flags);
1942     return;
1943
1944 connect:
1945     if( _pcd->phy_suspend  == 1 )
1946          dwc_otg20phy_suspend( 1 );
1947     schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
1948      _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
1949     add_timer(&_pcd->check_vbus_timer); 
1950         local_irq_restore(flags);
1951     return;
1952 }
1953
1954 #endif
1955 #ifdef CONFIG_ARCH_RK29
1956 /*
1957  * This function can be only called in charge mode.
1958  * return value:
1959  *  -1: ioremap fail;
1960  *  0: vbus not connected;
1961  *  1: vbus connected, dp,dm not in both high status;
1962  *  2: vbus connected and both dp,dm in high level.(standard USB charger)
1963  */
1964 int dwc_otg_check_dpdm(void)
1965 {
1966         static uint8_t * reg_base = 0;
1967     volatile unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON);
1968     volatile unsigned int * otg_clkgate = (unsigned int*)(USB_CLKGATE_CON);
1969     volatile unsigned int * otg_clkreset = (unsigned int*)(RK29_CRU_BASE+0x70);
1970     volatile unsigned int * otg_dctl;
1971     volatile unsigned int * otg_gotgctl;
1972     volatile unsigned int * otg_hprt0;
1973     int bus_status = 0;
1974     
1975     
1976     // softreset & clockgate 
1977     *otg_clkreset |= (7<<16);
1978     udelay(3);
1979     *otg_clkreset &= ~(7<<16);
1980     *otg_clkgate &= ~((1<<4)|(3<<25));
1981         
1982     // exit phy suspend 
1983     *otg_phy_con1 |= (0x01<<2);
1984     *otg_phy_con1 |= (0x01<<3);    // exit suspend.
1985     *otg_phy_con1 &= ~(0x01<<2);
1986     
1987     // soft connect
1988     if(reg_base == 0){
1989         reg_base = ioremap(RK29_USBOTG0_PHYS,USBOTG_SIZE);
1990         if(!reg_base){
1991             bus_status = -1;
1992             goto out;
1993         }
1994     }
1995     mdelay(105);
1996     printk("regbase %p 0x%x, otg_phy_con%p, 0x%x, otg_clkgate %p,0x%x\n",
1997         reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1, otg_clkgate, *otg_clkgate);
1998     otg_dctl = (unsigned int * )(reg_base+0x804);
1999     otg_gotgctl = (unsigned int * )(reg_base);
2000     otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
2001     if(*otg_gotgctl &(1<<19)){
2002         bus_status = 1;
2003         *otg_dctl &= ~2;
2004         mdelay(50);    // delay about 10ms
2005     // check dp,dm
2006         if((*otg_hprt0 & 0xc00)==0xc00)
2007             bus_status = 2;
2008     }
2009 out:
2010     return bus_status;
2011 }
2012 #endif
2013 #ifdef CONFIG_ARCH_RK30
2014 int dwc_otg_check_dpdm(void)
2015 {
2016         static uint8_t * reg_base = 0;
2017     volatile unsigned int * otg_dctl;
2018     volatile unsigned int * otg_gotgctl;
2019     volatile unsigned int * otg_hprt0;
2020     int bus_status = 0;
2021     unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);
2022     
2023     // softreset & clockgate 
2024     *(unsigned int*)(RK30_CRU_BASE+0x120) = ((7<<5)<<16)|(7<<5);    // otg0 phy clkgate
2025     udelay(3);
2026     *(unsigned int*)(RK30_CRU_BASE+0x120) = ((7<<5)<<16)|(0<<5);    // otg0 phy clkgate
2027     dsb();
2028     *(unsigned int*)(RK30_CRU_BASE+0xd4) = ((1<<5)<<16);    // otg0 phy clkgate
2029     *(unsigned int*)(RK30_CRU_BASE+0xe4) = ((1<<13)<<16);   // otg0 hclk clkgate
2030     *(unsigned int*)(RK30_CRU_BASE+0xe0) = ((3<<5)<<16);    // hclk usb clkgate
2031     
2032     // exit phy suspend 
2033         *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.
2034     
2035     // soft connect
2036     if(reg_base == 0){
2037         reg_base = ioremap(RK30_USBOTG20_PHYS,USBOTG_SIZE);
2038         if(!reg_base){
2039             bus_status = -1;
2040             goto out;
2041         }
2042     }
2043     mdelay(105);
2044     printk("regbase %p 0x%x, otg_phy_con%p, 0x%x\n",
2045         reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1);
2046     otg_dctl = (unsigned int * )(reg_base+0x804);
2047     otg_gotgctl = (unsigned int * )(reg_base);
2048     otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
2049     if(*otg_gotgctl &(1<<19)){
2050         bus_status = 1;
2051         *otg_dctl &= ~2;
2052         mdelay(50);    // delay about 10ms
2053     // check dp,dm
2054         if((*otg_hprt0 & 0xc00)==0xc00)
2055             bus_status = 2;
2056     }
2057 out:
2058     return bus_status;
2059 }
2060
2061 EXPORT_SYMBOL(dwc_otg_check_dpdm);
2062 #endif
2063 #ifdef CONFIG_ARCH_RK2928
2064 int dwc_otg_check_dpdm(void)
2065 {
2066         static uint8_t * reg_base = 0;
2067     volatile unsigned int * otg_dctl;
2068     volatile unsigned int * otg_gotgctl;
2069     volatile unsigned int * otg_hprt0;
2070     int bus_status = 0;
2071     unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);//@lyz modify UOC0_CON2 to CON5
2072     
2073     // softreset & clockgate //@lyz modify RK2928_CRU_BASE
2074     *(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(7<<5);    // otg0 phy clkgate
2075     udelay(3);
2076     *(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(0<<5);    // otg0 phy clkgate
2077     dsb();
2078     *(unsigned int*)(RK2928_CRU_BASE+0xd4) = ((1<<5)<<16);    // otg0 phy clkgate
2079     *(unsigned int*)(RK2928_CRU_BASE+0xe4) = ((1<<13)<<16);   // otg0 hclk clkgate
2080     *(unsigned int*)(RK2928_CRU_BASE+0xf4) = ((3<<10)<<16);    // hclk usb clkgate//@lyz to be check
2081     
2082     // exit phy suspend 
2083         *otg_phy_con1 = ((0x01<<0)<<16);    // exit suspend.@lyz
2084     
2085     // soft connect
2086     if(reg_base == 0){
2087         reg_base = ioremap(RK2928_USBOTG20_PHYS,USBOTG_SIZE);//@lyz
2088         if(!reg_base){
2089             bus_status = -1;
2090             goto out;
2091         }
2092     }
2093     mdelay(105);
2094     printk("regbase %p 0x%x, otg_phy_con%p, 0x%x\n",
2095         reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1);
2096     otg_dctl = (unsigned int * )(reg_base+0x804);
2097     otg_gotgctl = (unsigned int * )(reg_base);
2098     otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
2099     if(*otg_gotgctl &(1<<19)){
2100         bus_status = 1;
2101         *otg_dctl &= ~(0x01<<1);//@lyz exit soft-disconnect mode
2102         mdelay(50);    // delay about 10ms
2103     // check dp,dm
2104         if((*otg_hprt0 & 0xc00)==0xc00)//@lyz check hprt[11:10] 
2105             bus_status = 2;
2106     }
2107 out:
2108     return bus_status;
2109 }
2110
2111 EXPORT_SYMBOL(dwc_otg_check_dpdm);
2112 #endif
2113 void dwc_otg_pcd_start_vbus_timer( dwc_otg_pcd_t * _pcd )
2114 {
2115         struct timer_list *vbus_timer = &_pcd->check_vbus_timer;
2116
2117         /* 
2118          * when receive reset int,the vbus state may not be update,so 
2119          * always start timer here.
2120          */                
2121         mod_timer( vbus_timer , jiffies + (HZ));
2122 }
2123
2124 /*
2125 * 20091228,HSL@RK,to get the current vbus status.
2126 */
2127 int dwc_vbus_status( void )
2128 {
2129     dwc_otg_pcd_t *pcd = s_pcd;
2130     if(!pcd)
2131        return 0;
2132     else
2133         return pcd->vbus_status ;
2134 }
2135 EXPORT_SYMBOL(dwc_vbus_status);
2136
2137 int dwc_otg_set_phy_status(uint8_t status)
2138 {
2139     dwc_otg_pcd_t *pcd = s_pcd;
2140     pcd->phy_suspend = status;
2141     return pcd->phy_suspend;
2142 }
2143 /** 
2144  * This function initialized the PCD portion of the driver.
2145  *
2146  */
2147 int dwc_otg_pcd_init(struct device *dev)
2148 {
2149         static char pcd_name[] = "dwc_otg_pcd";
2150         dwc_otg_pcd_t *pcd;
2151         dwc_otg_device_t *otg_dev = dev->platform_data;
2152     dwc_otg_core_if_t *core_if = otg_dev->core_if;
2153         int retval = 0;
2154         int irq;
2155          /*
2156          * Allocate PCD structure
2157          */
2158         pcd = kmalloc( sizeof(dwc_otg_pcd_t), GFP_KERNEL);
2159         
2160         if (pcd == 0) 
2161         {
2162                         return -ENOMEM;
2163         }
2164         
2165         memset( pcd, 0, sizeof(dwc_otg_pcd_t));
2166         spin_lock_init( &pcd->lock );
2167         otg_dev->pcd = pcd;
2168         s_pcd = pcd;
2169         pcd->gadget.name = pcd_name;
2170         //strcpy(pcd->gadget.dev.bus_id, "gadget");
2171         
2172         pcd->otg_dev = otg_dev;
2173         
2174         pcd->gadget.dev.parent = dev;
2175         pcd->gadget.dev.release = dwc_otg_pcd_gadget_release;
2176         pcd->gadget.dev.init_name= "gadget";
2177         pcd->gadget.ops = &dwc_otg_pcd_ops;
2178         
2179         pcd->gadget.is_dualspeed = 0;
2180         pcd->gadget.is_otg = 0;
2181         pcd->driver = 0;
2182     pcd->conn_en = 0;
2183         /* Register the gadget device */
2184         retval = device_register( &pcd->gadget.dev );
2185         if(retval != 0)
2186         {
2187                 DWC_ERROR("device_register failed\n");
2188                 return -EBUSY;
2189         }
2190         
2191         /*
2192          * Register the PCD Callbacks. 
2193          */
2194         dwc_otg_cil_register_pcd_callbacks( otg_dev->core_if, &pcd_callbacks, 
2195                                                                                 pcd );
2196         /*
2197          * Setup interupt handler
2198          */
2199         irq = platform_get_irq(to_platform_device(dev),0);
2200         DWC_DEBUGPL( DBG_ANY, "registering handler for irq%d\n", irq);
2201         retval = request_irq(irq, dwc_otg_pcd_irq,
2202                                                  IRQF_SHARED, pcd->gadget.name, pcd);
2203         if (retval != 0) 
2204         {
2205                 DWC_ERROR("request of irq%d failed\n", irq);
2206                 kfree (pcd);
2207                 return -EBUSY;
2208         }
2209     
2210         wake_lock_init(&pcd->wake_lock, WAKE_LOCK_SUSPEND,
2211                            "usb_pcd");
2212
2213         /*
2214          * Initialize EP structures
2215          */
2216         dwc_otg_pcd_reinit( pcd );
2217         /* 
2218          * Initialize the DMA buffer for SETUP packets
2219          */
2220         if (GET_CORE_IF(pcd)->dma_enable) 
2221         {
2222                 pcd->setup_pkt = dma_alloc_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, &pcd->setup_pkt_dma_handle, 0);
2223                 pcd->status_buf = dma_alloc_coherent (NULL, sizeof (uint16_t), &pcd->status_buf_dma_handle, 0);
2224         }
2225         else 
2226         {
2227                 pcd->setup_pkt = kmalloc (sizeof (*pcd->setup_pkt) * 5, GFP_KERNEL);
2228                 pcd->status_buf = kmalloc (sizeof (uint16_t), GFP_KERNEL);
2229         }
2230         
2231         if (pcd->setup_pkt == 0) 
2232         {
2233                 DWC_PRINT("pcd->setup_pkt alloc fail,everest\n");
2234                 kfree (pcd);
2235                 return -ENOMEM;
2236         }
2237         /* Initialize tasklet */
2238         start_xfer_tasklet.data = (unsigned long)pcd;
2239         pcd->start_xfer_tasklet = &start_xfer_tasklet;
2240
2241
2242
2243     init_timer( &pcd->check_vbus_timer );
2244     pcd->check_vbus_timer.function = dwc_otg_pcd_check_vbus_timer;
2245     pcd->check_vbus_timer.data = (unsigned long)(pcd);
2246     
2247     INIT_DELAYED_WORK(&pcd->reconnect , dwc_phy_reconnect);
2248     pcd->vbus_status  = 0;
2249     pcd->phy_suspend  = 0;
2250     if(dwc_otg_is_device_mode(core_if))
2251         mod_timer(&pcd->check_vbus_timer, jiffies+(HZ<<4)); // delay 16 S
2252         return 0;
2253 }
2254 /**
2255  * Cleanup the PCD.
2256  */
2257 void dwc_otg_pcd_remove( struct device *dev )
2258 {
2259         dwc_otg_device_t *otg_dev = dev->platform_data;
2260         dwc_otg_pcd_t *pcd = otg_dev->pcd;
2261         
2262         DWC_DEBUGPL(DBG_PCDV, "%s(%p)\n", __func__, dev);
2263
2264         wake_lock_destroy(&pcd->wake_lock);
2265
2266         /*
2267          * Free the IRQ 
2268          */
2269         free_irq( platform_get_irq(to_platform_device(dev),0), pcd );
2270         
2271          /* start with the driver above us */
2272         if (pcd->driver) 
2273         {
2274                 /* should have been done already by driver model core */
2275                 DWC_WARN("driver '%s' is still registered\n",
2276                                          pcd->driver->driver.name);
2277                 usb_gadget_unregister_driver( pcd->driver);
2278         }
2279         device_unregister(&pcd->gadget.dev);
2280                 
2281         if (GET_CORE_IF(pcd)->dma_enable) 
2282         {
2283                 dma_free_coherent (NULL, sizeof (*pcd->setup_pkt) * 5, pcd->setup_pkt, pcd->setup_pkt_dma_handle);
2284                 dma_free_coherent (NULL, sizeof (uint16_t), pcd->status_buf, pcd->status_buf_dma_handle);
2285         }
2286         else 
2287         {
2288                 kfree (pcd->setup_pkt);
2289                 kfree (pcd->status_buf);
2290         }
2291         
2292         kfree( pcd );
2293         otg_dev->pcd = 0;
2294     s_pcd = 0; 
2295 }
2296
2297 /**
2298  * This function registers a gadget driver with the PCD.
2299  *
2300  * When a driver is successfully registered, it will receive control
2301  * requests including set_configuration(), which enables non-control
2302  * requests.  then usb traffic follows until a disconnect is reported.
2303  * then a host may connect again, or the driver might get unbound.
2304  *
2305  * @param _driver The driver being registered
2306  */
2307  
2308 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
2309 int usb_gadget_probe_driver(struct usb_gadget_driver *_driver,
2310                 int (*bind)(struct usb_gadget *))
2311 #else
2312 int usb_gadget_register_driver(struct usb_gadget_driver *_driver)
2313 #endif
2314 {
2315         int retval;
2316
2317         DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n", _driver->driver.name);
2318                 
2319         if (!_driver || _driver->speed == USB_SPEED_UNKNOWN || 
2320 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
2321                 !bind ||
2322 #else
2323                 !_driver->bind || 
2324 #endif
2325                 !_driver->unbind || 
2326                 !_driver->disconnect || 
2327                 !_driver->setup) 
2328         {
2329                 DWC_ERROR("EINVAL\n");  
2330                 return -EINVAL;
2331         }
2332         if (s_pcd == 0) 
2333         {
2334                 DWC_ERROR("ENODEV\n");  
2335                 return -ENODEV;
2336         }
2337         if (s_pcd->driver != 0) 
2338         {
2339                 DWC_ERROR("EBUSY (%p)\n", s_pcd->driver);   
2340                 return -EBUSY;
2341         }
2342         
2343         /* hook up the driver */
2344         s_pcd->driver = _driver;
2345         s_pcd->gadget.dev.driver = &_driver->driver;
2346
2347         DWC_DEBUGPL(DBG_PCD, "bind to driver %s\n", _driver->driver.name);
2348 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
2349         retval = bind(&s_pcd->gadget);
2350 #else
2351         retval = _driver->bind(&s_pcd->gadget);
2352 #endif
2353         if (retval) 
2354         {
2355                 DWC_ERROR("bind to driver %s --> error %d\n",
2356                                         _driver->driver.name, retval);
2357                 s_pcd->driver = 0;
2358                 s_pcd->gadget.dev.driver = 0;
2359                 return retval;
2360         }
2361         DWC_DEBUGPL(DBG_ANY, "registered gadget driver '%s'\n", 
2362                                         _driver->driver.name);
2363         return 0;
2364 }
2365 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
2366 EXPORT_SYMBOL(usb_gadget_probe_driver);
2367 #else
2368 EXPORT_SYMBOL(usb_gadget_register_driver);
2369 #endif
2370
2371 /**
2372  * This function unregisters a gadget driver
2373  *
2374  * @param _driver The driver being unregistered
2375  */
2376 int usb_gadget_unregister_driver(struct usb_gadget_driver *_driver)
2377 {
2378         DWC_DEBUGPL(DBG_PCDV,"%s(%p)\n", __func__, _driver);
2379
2380         if (s_pcd == 0) 
2381         {
2382                 DWC_DEBUGPL(DBG_ANY, "%s Return(%d): s_pcd==0\n", __func__, 
2383                                         -ENODEV);
2384                 return -ENODEV;
2385         }
2386         if (_driver == 0 || _driver != s_pcd->driver) 
2387         {
2388                 DWC_DEBUGPL( DBG_ANY, "%s Return(%d): driver?\n", __func__, 
2389                                         -EINVAL);
2390                 return -EINVAL;
2391         }
2392
2393         _driver->unbind(&s_pcd->gadget);
2394         s_pcd->driver = 0;
2395
2396         DWC_DEBUGPL(DBG_ANY, "unregistered driver '%s'\n", 
2397                                         _driver->driver.name);
2398         return 0;
2399 }
2400 EXPORT_SYMBOL(usb_gadget_unregister_driver);
2401 #endif /* DWC_HOST_ONLY */