USB: support DWC_OTG Driver Version3.10 and used by default
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / usbdev_rk3190.c
1 #include <linux/kernel.h>
2 #include <linux/platform_device.h>
3 #include <linux/delay.h>
4 #include <linux/dma-mapping.h>
5 #include <linux/clk.h>
6 #include <linux/io.h>
7 #include <linux/wakelock.h>
8 #include <linux/workqueue.h>
9 #include <linux/interrupt.h>
10 #include <linux/irq.h>
11
12 #include <mach/irqs.h>
13 #include <mach/gpio.h>
14 #include <mach/iomux.h>
15 #include <mach/cru.h>
16 #include <mach/board.h>
17
18 #include "usbdev_rk.h"
19 #include "dwc_otg_regs.h"
20
21 #ifdef CONFIG_ARCH_RK319X
22 #include "usbdev_rk3190_grf_regs.h"
23
24 pGRF_UOC0_REG USBGRF_UOC0 = (pGRF_UOC0_REG)(GRF_UOC0_BASE);
25 pGRF_UOC1_REG USBGRF_UOC1 = (pGRF_UOC1_REG)(GRF_UOC1_BASE);
26 pGRF_HSIC_REG USBGRF_HSIC = (pGRF_HSIC_REG)(GRF_UOC2_BASE);
27 pGRF_USBPHY_REG GRF_USBPHY1 = (pGRF_USBPHY_REG)(GRF_USBPHY1_CON_BASE);
28 pGRF_SOC_STATUS USBGRF_STATUS = (pGRF_SOC_STATUS)(USBGRF_SOC_STATUS0);
29
30 int dwc_otg_check_dpdm(void)
31 {
32 /*
33         static uint8_t * reg_base = 0;
34     volatile unsigned int * otg_dctl;
35     volatile unsigned int * otg_gotgctl;
36     volatile unsigned int * otg_hprt0;
37     int bus_status = 0;
38     unsigned int * otg_phy_con0 = (unsigned int*)(USBGRF_UOC0_CON0) ;
39     
40     *(unsigned int*)(RK319X_CRU_BASE+0x120) = ((7<<5)<<16)|(7<<5);    // otg0 phy clkgate
41     udelay(3);
42     *(unsigned int*)(RK319X_CRU_BASE+0x120) = ((7<<5)<<16)|(0<<5);    // otg0 phy clkgate
43     dsb();
44     *(unsigned int*)(RK319X_CRU_BASE+0xd4) = ((1<<5)<<16);    // otg0 phy clkgate
45     *(unsigned int*)(RK319X_CRU_BASE+0xe4) = ((1<<13)<<16);   // otg0 hclk clkgate
46     *(unsigned int*)(RK319X_CRU_BASE+0xf4) = ((3<<10)<<16);    // hclk usb clkgat
47    
48     // exit phy suspend 
49         *otg_phy_con0 = ((0x01<<0)<<16);  
50     
51     // soft connect
52     if(reg_base == 0){
53         reg_base = ioremap(RK319X_USBOTG20_PHYS, RK319X_USBOTG20_SIZE);
54         if(!reg_base){
55             bus_status = -1;
56             goto out;
57         }
58     }
59     mdelay(10);
60     //printk("regbase %p 0x%x, otg_phy_con%p, 0x%x\n",
61     //    reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1);
62     otg_dctl = (unsigned int * )(reg_base+0x804);
63     otg_gotgctl = (unsigned int * )(reg_base);
64     otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
65     if(*otg_gotgctl &(1<<19)){
66         bus_status = 1;
67         *otg_dctl &= ~(0x01<<1);//exit soft-disconnect mode
68         mdelay(1);    // delay about 1ms
69     // check dp,dm
70         if((*otg_hprt0 & 0xc00)==0xc00)//check hprt[11:10] 
71             bus_status = 2;
72         //*(unsigned int*)(GRF_REG_BASE + GRF_UOC0_CON0) = 0x10001000;
73     }
74 out:
75     return bus_status;
76     */
77     return 0;
78 }
79
80 EXPORT_SYMBOL(dwc_otg_check_dpdm);
81
82 /***********************************
83 USB Port Type
84 0 : Disconnect
85 1 : SDP - pc
86 2 : DCP - charger
87 3 : CDP - pc with big currect charge
88 ***********************************/
89 /* When do BC detect PCD pull-up register should be disabled  */
90
91 #define T_DCD_TIMEOUT    (200)
92 #define T_BC_WAIT_CHGDET (40)
93 #define T_BC_SRC_OFF     (10)
94
95 int usb_battery_charger_detect(void)
96 {
97         int port_type = 0;
98         int timeout;
99     
100         //VBUS Valid detect
101         if(USBGRF_STATUS->otg_vbusvalid){
102             //todo : add DCD !
103                 mdelay(T_DCD_TIMEOUT);//no DCD just wait for timeout
104                 /* Turn on VDPSRC */
105         //Primary Detection
106                 USBGRF_UOC0->CON2 = 0x00e000e0;
107                 timeout = T_BC_WAIT_CHGDET;
108                 while(timeout--){
109                         if((USBGRF_STATUS->snps_chgdet))
110                                 break;
111                         mdelay(1);
112                 }
113
114                 /* SDP and CDP/DCP distinguish */
115         if(!(USBGRF_STATUS->snps_chgdet))
116                 {
117                     port_type = 1;
118                     /* Turn off VDPSRC */
119                     USBGRF_UOC0->CON2 = 0x00e00000;
120                     goto out;
121                 }
122
123                 /* Turn on VDMSRC */
124                 //Secondary Detection
125         USBGRF_UOC0->CON2 = 0x00e000c0;
126         timeout = T_BC_SRC_OFF;
127                 while(timeout--){
128                         if((USBGRF_UOC0->CON2 & 0x00e0) == 0x00c0)
129                                 break;
130                         mdelay(1);
131                 }
132
133         timeout = T_BC_WAIT_CHGDET;
134                 while(timeout--){
135                         if((USBGRF_STATUS->snps_chgdet))
136                                 break;
137                         mdelay(1);
138                 }
139                 
140                 if((USBGRF_STATUS->snps_chgdet))
141                         port_type = 2;
142                 else
143                         port_type = 3;
144
145         USBGRF_UOC0->CON2 = 0x00e00000;
146         timeout = T_BC_SRC_OFF;
147                 while(timeout--){
148                         if((USBGRF_UOC0->CON2 & 0x00e0) == 0x00c0)
149                                 break;
150                         mdelay(1);
151                 }
152         }
153 out:
154         printk("%s , battery_charger_detect %d\n", __func__, port_type);
155         return port_type;
156 }
157 EXPORT_SYMBOL(usb_battery_charger_detect);
158
159
160 #ifdef CONFIG_USB20_OTG
161 /*DWC_OTG*/
162 static struct resource usb20_otg_resource[] = {
163         {
164                 .start = IRQ_USB_OTG,
165                 .end   = IRQ_USB_OTG,
166                 .flags = IORESOURCE_IRQ,
167         },
168         {
169                 .start = RK319X_USBOTG20_PHYS,
170                 .end   = RK319X_USBOTG20_PHYS + RK319X_USBOTG20_SIZE - 1,
171                 .flags = IORESOURCE_MEM,
172         },
173
174 };
175
176 void usb20otg_hw_init(void)
177 {
178 #ifndef CONFIG_USB20_HOST
179     // close USB 2.0 HOST phy and clock
180     USBGRF_UOC1->CON1 = 0x007f0055;
181 #endif
182
183     // usb phy config init
184
185     // other hardware init
186     iomux_set(OTG_DRV_VBUS);
187 }
188 void usb20otg_phy_suspend(void* pdata, int suspend)
189 {
190     struct dwc_otg_platform_data *usbpdata=pdata;
191     if(suspend){
192         USBGRF_UOC0->CON3 = 0x003f002a;
193         USBGRF_UOC0->CON2 = 0x00040004;
194         
195         usbpdata->phy_status = 1;
196     }
197     else{
198         USBGRF_UOC0->CON2 = 0x00040000;
199         usbpdata->phy_status = 0;
200     }
201 }
202
203 void usb20otg_soft_reset(void)
204 {
205     cru_set_soft_reset(SOFT_RST_USBOTG0, true);
206     cru_set_soft_reset(SOFT_RST_USBPHY0, true);
207     cru_set_soft_reset(SOFT_RST_OTGC0, true);
208     udelay(5);
209
210     cru_set_soft_reset(SOFT_RST_USBOTG0, false);
211     cru_set_soft_reset(SOFT_RST_USBPHY0, false);
212     cru_set_soft_reset(SOFT_RST_OTGC0, false);
213     mdelay(2);
214 }
215
216 void usb20otg_clock_init(void* pdata)
217 {
218     struct dwc_otg_platform_data *usbpdata=pdata;
219     struct clk* ahbclk,*phyclk;
220     ahbclk = clk_get(NULL, "hclk_otg0");
221     phyclk = clk_get(NULL, "otgphy0_480m_vir");
222         usbpdata->phyclk = phyclk;
223         usbpdata->ahbclk = ahbclk;
224 }
225 void usb20otg_clock_enable(void* pdata, int enable)
226 {
227     struct dwc_otg_platform_data *usbpdata=pdata;
228     if(enable){
229         clk_enable(usbpdata->ahbclk);
230         clk_enable(usbpdata->phyclk);
231     }
232     else{
233         clk_disable(usbpdata->phyclk);   
234         clk_disable(usbpdata->ahbclk);
235     }
236 }
237 int usb20otg_get_status(int id)
238 {
239     int ret = -1;
240     switch(id)
241     {
242         case USB_STATUS_BVABLID:
243             // bvalid in grf
244             ret = USBGRF_STATUS->otg_bvalid;
245             break;
246         case USB_STATUS_DPDM:
247             // dpdm in grf
248             ret = USBGRF_STATUS->otg_linestate;
249             break;
250         case USB_STATUS_ID:
251             // id in grf
252             ret = USBGRF_STATUS->otg_iddig;
253             break;
254
255         default:
256             break;
257     }
258     return ret;
259 }
260 void dwc_otg_uart_mode(void* pdata, int enter_usb_uart_mode)
261 {
262 #ifdef CONFIG_RK_USB_UART
263     //struct dwc_otg_platform_data *usbpdata=pdata;//1:uart 0:usb
264     if(1 == enter_usb_uart_mode)   //uart mode
265     {
266         USBGRF_UOC0->CON0 = 0x03000300;
267         printk("otg-phy enter uart mode USBGRF_UOC1_CON0 = 0x%08x\n",USBGRF_UOC0->CON0);
268         
269     }
270     if(0 == enter_usb_uart_mode)   //usb mode
271     {   
272         USBGRF_UOC0->CON0 = 0x03000000;
273         printk("otg-phy enter usb mode USBGRF_UOC1_CON0 = 0x%08x\n",USBGRF_UOC0->CON0);
274     }
275 #endif
276 }
277
278 void usb20otg_power_enable(int enable)
279 {
280
281 }
282 struct dwc_otg_platform_data usb20otg_pdata = {
283     .phyclk = NULL,
284     .ahbclk = NULL,
285     .busclk = NULL,
286     .phy_status = 0,
287     .hw_init=usb20otg_hw_init,
288     .phy_suspend=usb20otg_phy_suspend,
289     .soft_reset=usb20otg_soft_reset,
290     .clock_init=usb20otg_clock_init,
291     .clock_enable=usb20otg_clock_enable,
292     .get_status=usb20otg_get_status,
293     .dwc_otg_uart_mode=dwc_otg_uart_mode,
294 };
295
296 struct platform_device device_usb20_otg = {
297         .name             = "usb20_otg",
298         .id               = -1,
299         .num_resources    = ARRAY_SIZE(usb20_otg_resource),
300         .resource         = usb20_otg_resource,
301         .dev            = {
302                 .platform_data  = &usb20otg_pdata,
303         },
304 };
305 #endif
306 #ifdef CONFIG_USB20_HOST
307 static struct resource usb20_host_resource[] = {
308     {
309         .start = IRQ_USB_HOST,
310         .end   = IRQ_USB_HOST,
311         .flags = IORESOURCE_IRQ,
312     },
313     {
314         .start = RK319X_USBHOST20_PHYS,
315         .end   = RK319X_USBHOST20_PHYS + RK319X_USBHOST20_SIZE - 1,
316         .flags = IORESOURCE_MEM,
317     },
318
319 };
320
321 void usb20host_hw_init(void)
322 {
323     // usb phy config init
324
325     //GRF_USBPHY1->CON7 = 0x78000000;//host_discon_con 575mv
326     GRF_USBPHY1->CON0 = 0xffff8518;
327     GRF_USBPHY1->CON1 = 0xffffe007;
328     GRF_USBPHY1->CON2 = 0xffff82c9;
329     GRF_USBPHY1->CON3 = 0xffff0202;
330     GRF_USBPHY1->CON4 = 0xffff5556;
331     GRF_USBPHY1->CON5 = 0xffff5555;
332     GRF_USBPHY1->CON6 = 0xffff0005;
333     GRF_USBPHY1->CON7 = 0xffff68d0;
334     GRF_USBPHY1->CON8 = 0xffff0001;
335
336     // other haredware init
337     iomux_set(HOST_DRV_VBUS);
338 }
339 void usb20host_phy_suspend(void* pdata, int suspend)
340 {
341     struct dwc_otg_platform_data *usbpdata=pdata;
342
343     if(suspend){
344         USBGRF_UOC1->CON1 = 0x007f0051;
345         usbpdata->phy_status = 1;
346     }
347     else{
348         USBGRF_UOC1->CON1 = 0x00010000;
349         usbpdata->phy_status = 0;
350     }
351 }
352 void usb20host_soft_reset(void)
353 {
354     //phy reset
355     USBGRF_UOC1->CON1 = 0x00030001;
356
357     cru_set_soft_reset(SOFT_RST_USBPHY1_UTMI, true);
358
359     udelay(15);
360
361     USBGRF_UOC1->CON1 = 0x00030002;
362
363     udelay(1500);
364     cru_set_soft_reset(SOFT_RST_USBPHY1_UTMI, false);
365
366     cru_set_soft_reset(SOFT_RST_USBOTG1, true);
367     cru_set_soft_reset(SOFT_RST_USBPHY1, true);
368     cru_set_soft_reset(SOFT_RST_OTGC1, true);
369     udelay(5);
370
371     cru_set_soft_reset(SOFT_RST_USBOTG1, false);
372     cru_set_soft_reset(SOFT_RST_USBPHY1, false);
373     cru_set_soft_reset(SOFT_RST_OTGC1, false);
374     mdelay(2);
375
376 }
377
378 void usb20host_clock_init(void* pdata)
379 {
380     struct dwc_otg_platform_data *usbpdata=pdata;
381     struct clk* ahbclk,*phyclk;
382     ahbclk = clk_get(NULL, "hclk_otg1");
383     phyclk = clk_get(NULL, "otgphy1_480m_vir");
384         usbpdata->phyclk = phyclk;
385         usbpdata->ahbclk = ahbclk;
386 }
387
388 void usb20host_clock_enable(void* pdata, int enable)
389 {
390     struct dwc_otg_platform_data *usbpdata=pdata;
391
392     if(enable){
393         clk_enable(usbpdata->ahbclk);
394         clk_enable(usbpdata->phyclk);
395     }
396     else{
397         clk_disable(usbpdata->ahbclk);
398         //clk_disable(usbpdata->phyclk);
399     }
400 }
401 int usb20host_get_status(int id)
402 {
403     int ret = -1;
404     pGRF_SOC_STATUS USBGRF_STATUS = (pGRF_SOC_STATUS)(USBGRF_SOC_STATUS0);
405     switch(id)
406     {
407         case USB_STATUS_BVABLID:
408             // bvalid in grf
409             ret = USBGRF_STATUS->uhost_bvalid;
410             break;
411         case USB_STATUS_DPDM:
412             // dpdm in grf
413             ret = USBGRF_STATUS->uhost_linestate;
414             break;
415         case USB_STATUS_ID:
416             // id in grf
417             ret = 0;
418             break;
419         default:
420             break;
421     }
422     return ret;
423 }
424 void usb20host_power_enable(int enable)
425 {
426     ;
427 }
428 struct dwc_otg_platform_data usb20host_pdata = {
429     .phyclk = NULL,
430     .ahbclk = NULL,
431     .busclk = NULL,
432     .phy_status = 0,
433     .hw_init=usb20host_hw_init,
434     .phy_suspend=usb20host_phy_suspend,
435     .soft_reset=usb20host_soft_reset,
436     .clock_init=usb20host_clock_init,
437     .clock_enable=usb20host_clock_enable,
438     .get_status=usb20host_get_status,
439 };
440
441 struct platform_device device_usb20_host = {
442     .name             = "usb20_host",
443     .id               = -1,
444     .num_resources    = ARRAY_SIZE(usb20_host_resource),
445     .resource         = usb20_host_resource,
446     .dev                = {
447                 .platform_data  = &usb20host_pdata,
448         },
449 };
450 #endif
451 #ifdef CONFIG_USB_EHCI_RK
452 void rkehci_hw_init(void)
453 {
454         // usb phy config init
455         // hsic phy config init, set hsicphy_txsrtune
456         USBGRF_HSIC->PHY_CON0 = 0x03c003c0;
457
458         // other haredware init
459         // set common_on, in suspend mode, otg/host PLL blocks remain powered
460         USBGRF_UOC1->CON0 = 0x00400000;
461
462         /* change INCR to INCR16 or INCR8(beats less than 16)
463          * or INCR4(beats less than 8) or SINGLE(beats less than 4)
464          */
465         USBGRF_HSIC->CTRLER_CON0 = 0x00ff00bc;
466 }
467
468 void rkehci_clock_init(void* pdata)
469 {
470         struct rkehci_platform_data *usbpdata=pdata;
471
472         struct clk *clk_otg, *clk_hs;
473
474         /* By default, hsicphy_480m's parent is otg phy 480MHz clk
475          * rk3188 must use host phy 480MHz clk
476          */
477         clk_hs = clk_get(NULL, "hsicphy_480m");
478         clk_otg = clk_get(NULL, "otgphy1_480m");
479         clk_set_parent(clk_hs, clk_otg);
480
481         usbpdata->hclk_hsic = clk_get(NULL, "hclk_hsic");
482         usbpdata->hsic_phy_480m = clk_get(NULL, "hsicphy_480m");
483         usbpdata->hsic_phy_12m = clk_get(NULL, "hsicphy_12m");
484 }
485
486 void rkehci_clock_enable(void* pdata, int enable)
487 {
488         struct rkehci_platform_data *usbpdata=pdata;
489
490         if(enable == usbpdata->clk_status)
491                 return;
492
493         if(enable){
494                 clk_enable(usbpdata->hclk_hsic);
495                 clk_enable(usbpdata->hsic_phy_480m);
496                 clk_enable(usbpdata->hsic_phy_12m);
497                 usbpdata->clk_status = 1;
498         }else{
499                 clk_disable(usbpdata->hsic_phy_12m);
500                 clk_disable(usbpdata->hsic_phy_480m);
501                 clk_disable(usbpdata->hclk_hsic);
502                 usbpdata->clk_status = 0;
503         }
504 }
505
506 void rkehci_soft_reset(void)
507 {
508     pGRF_HSIC_REG USBGRF_HSIC = (pGRF_HSIC_REG)(GRF_UOC2_BASE);
509
510         cru_set_soft_reset(SOFT_RST_HSICPHY, true);
511         udelay(12);
512         cru_set_soft_reset(SOFT_RST_HSICPHY, false);
513         mdelay(2);
514
515     USBGRF_HSIC->PHY_CON0 = 0x04000400;
516         udelay(2);
517     USBGRF_HSIC->PHY_CON0 = 0x04000000;
518         udelay(2);
519
520         cru_set_soft_reset(SOFT_RST_HSIC_AHB, true);
521         udelay(2);
522         cru_set_soft_reset(SOFT_RST_HSIC_AHB, false);
523         udelay(2);
524 }
525
526 struct rkehci_platform_data rkehci_pdata = {
527         .hclk_hsic = NULL,
528         .hsic_phy_12m = NULL,
529         .hsic_phy_480m = NULL,
530         .clk_status = -1,
531         .hw_init = rkehci_hw_init,
532         .clock_init = rkehci_clock_init,
533         .clock_enable = rkehci_clock_enable,
534         .soft_reset = rkehci_soft_reset,
535 };
536
537 static struct resource resources_hsusb_host[] = {
538     {
539         .start = IRQ_HSIC,
540         .end   = IRQ_HSIC,
541         .flags = IORESOURCE_IRQ,
542     },
543     {
544         .start = RK30_HSIC_PHYS,
545         .end   = RK30_HSIC_PHYS + RK30_HSIC_SIZE - 1,
546         .flags = IORESOURCE_MEM,
547     },
548 };
549
550 struct platform_device device_hsusb_host = {
551     .name           = "rk_hsusb_host",
552     .id             = -1,
553     .num_resources  = ARRAY_SIZE(resources_hsusb_host),
554     .resource       = resources_hsusb_host,
555     .dev            = {
556         .coherent_dma_mask      = 0xffffffff,
557         .platform_data  = &rkehci_pdata,
558     },
559 };
560 #endif
561 static int __init usbdev_init_devices(void)
562 {
563     int ret = 0;
564 #ifdef CONFIG_USB20_OTG
565         ret |= platform_device_register(&device_usb20_otg);
566 #endif
567 #ifdef CONFIG_USB20_HOST
568         ret |= platform_device_register(&device_usb20_host);
569 #endif
570 #ifdef CONFIG_USB_EHCI_RK
571     ret |= platform_device_register(&device_hsusb_host);
572 #endif
573     if(ret < 0){
574         printk("%s: platform_device_register(usb20_otg) failed\n", __func__);
575     }
576     return ret;
577 }
578 arch_initcall(usbdev_init_devices);
579
580 /*********************************************************************
581                         rk3190 usb detect 
582 *********************************************************************/
583
584 #define WAKE_LOCK_TIMEOUT (HZ * 10)
585
586 static struct wake_lock usb_wakelock;
587 static struct delayed_work usb_det_wakeup_work;
588
589 inline void do_wakeup(void)
590 {
591     wake_lock_timeout(&usb_wakelock, WAKE_LOCK_TIMEOUT);
592         rk28_send_wakeup_key();
593 }
594
595
596 /*********** handler for bvalid irq ***********/
597
598 static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
599 {
600     
601 #ifdef CONFIG_RK_USB_UART
602     /* usb otg dp/dm switch to usb phy */
603     dwc_otg_uart_mode(NULL, PHY_USB_MODE);
604 #endif
605     
606     schedule_delayed_work(&usb_det_wakeup_work, 0);
607
608     /* clear irq pending */
609     writel_relaxed(0x02000200, &USBGRF_UOC0->CON3);
610
611     return IRQ_HANDLED;
612 }
613
614 /***** handler for otg id rise and fall edge *****/
615
616 static irqreturn_t id_irq_handler(int irq, void *dev_id)
617 {
618     unsigned int uoc_con;
619     
620     /* clear irq */  
621     uoc_con = USBGRF_UOC0->CON3;
622     
623     if(uoc_con & (1<<11))//id rise 
624     {
625         writel_relaxed(0x08000800, &USBGRF_UOC0->CON3);//clear id rise irq pandding
626     }
627     if(uoc_con & (1<<13))//id fall
628     {
629     
630 #ifdef CONFIG_RK_USB_UART
631         /* usb otg dp/dm switch to usb phy */
632         dwc_otg_uart_mode(NULL, PHY_USB_MODE);
633 #endif
634
635         writel_relaxed(0x20002000, &USBGRF_UOC0->CON3);//clear id fall irq pandding
636     }
637     schedule_delayed_work(&usb_det_wakeup_work, 0);
638
639     return IRQ_HANDLED;
640 }
641
642 /***** handler for otg line status change *****/
643
644 static int __init otg_irq_detect_init(void)
645 {
646     int ret;
647     int irq = IRQ_OTG_BVALID;
648
649     wake_lock_init(&usb_wakelock, WAKE_LOCK_SUSPEND, "usb_detect");
650     INIT_DELAYED_WORK(&usb_det_wakeup_work, do_wakeup);
651
652     ret = request_irq(irq, bvalid_irq_handler, 0, "bvalid", NULL);
653     if (ret < 0) {
654         pr_err("%s: request_irq(%d) failed\n", __func__, irq);
655         return ret;
656     }
657     
658     /* clear & enable bvalid irq */
659     writel_relaxed((3 << 8) | (3 << 24), &USBGRF_UOC0->CON3);
660
661     irq = IRQ_OTG0_ID;
662
663     ret = request_irq(irq, id_irq_handler, 0, "otg-id", NULL);
664     if (ret < 0) {
665         pr_err("%s: request_irq(%d) failed\n", __func__, irq);
666         return ret;
667     }
668
669     /* clear & enable otg change irq */
670     /* for rk3026 enable and clear id_fall_irq & id_rise_irq*/
671     writel_relaxed((0xf << 26) | (0xf << 10), &USBGRF_UOC0->CON3);
672     
673     return 0;
674 }
675 late_initcall(otg_irq_detect_init);
676 #endif
677