usb-uart: add support 3188&3288 kernel-3.10
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / usbdev_rk30.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/module.h>
7 #include <linux/slab.h>
8 #include <linux/of.h>
9 #include <linux/err.h>
10 #include <linux/io.h>
11 #include <linux/of_gpio.h>
12 #include <linux/of_device.h>
13 #include <linux/gpio.h>
14 #include <linux/wakelock.h>
15 #include <linux/workqueue.h>
16 #include <linux/interrupt.h>
17 #include <linux/irq.h>
18 #include "usbdev_grf_regs.h"
19 #include "usbdev_rk.h"
20 #include "dwc_otg_regs.h"
21
22 static struct dwc_otg_control_usb *control_usb;
23
24 static int usb_get_chip_id(void)
25 {
26         return control_usb->chip_id;
27 }
28
29 #ifdef CONFIG_USB20_OTG
30
31 static void usb20otg_hw_init(void)
32 {
33 #ifndef CONFIG_USB20_HOST
34         //enable soft control
35         control_usb->grf_uoc1_base->CON2 = (0x01<<2)|((0x01<<2)<<16);
36         // enter suspend
37         control_usb->grf_uoc1_base->CON3 = 0x2A|(0x3F<<16);
38 #endif
39         /* usb phy config init
40          * usb phy enter usb mode */
41         control_usb->grf_uoc0_base->CON0 = (0x0300 << 16);
42
43         /* other haredware init,include:
44          * DRV_VBUS GPIO init */
45         gpio_direction_output(control_usb->otg_gpios->gpio, 0);
46 }
47
48 static void usb20otg_phy_suspend(void* pdata, int suspend)
49 {
50         struct dwc_otg_platform_data *usbpdata=pdata;
51
52         if(suspend){
53                 //enable soft control
54                 control_usb->grf_uoc0_base->CON2 = (0x01<<2)|((0x01<<2)<<16);
55                 // enter suspend
56                 control_usb->grf_uoc0_base->CON3 = 0x2A|(0x3F<<16);
57                 usbpdata->phy_status = 1;
58         }else{
59                 // exit suspend.
60                 control_usb->grf_uoc0_base->CON2 = ((0x01<<2)<<16);
61                 usbpdata->phy_status = 0;
62         }
63 }
64
65 static void usb20otg_soft_reset(void)
66 {
67 }
68
69 static void usb20otg_clock_init(void* pdata)
70 {
71         struct dwc_otg_platform_data *usbpdata=pdata;
72         struct clk* ahbclk,*phyclk;
73
74         ahbclk = devm_clk_get(usbpdata->dev, "hclk_otg0");
75         if (IS_ERR(ahbclk)) {
76                 dev_err(usbpdata->dev, "Failed to get hclk_otg0\n");
77                 return;
78         }
79
80         phyclk = devm_clk_get(usbpdata->dev, "otgphy0");
81         if (IS_ERR(phyclk)) {
82                 dev_err(usbpdata->dev, "Failed to get otgphy0\n");
83                 return;
84         }
85
86         usbpdata->phyclk = phyclk;
87         usbpdata->ahbclk = ahbclk;
88 }
89
90 static void usb20otg_clock_enable(void* pdata, int enable)
91 {
92         struct dwc_otg_platform_data *usbpdata=pdata;
93
94         if(enable){
95                 clk_prepare_enable(usbpdata->ahbclk);
96                 clk_prepare_enable(usbpdata->phyclk);
97         }else{
98                 clk_disable_unprepare(usbpdata->ahbclk);
99                 clk_disable_unprepare(usbpdata->phyclk);
100         }
101 }
102
103 static int usb20otg_get_status(int id)
104 {
105         int ret = -1;
106
107         switch(id){
108                 case USB_STATUS_BVABLID:
109                         // bvalid in grf
110                         ret = control_usb->grf_soc_status0_rk3188->otg_bvalid;
111                         break;
112                 case USB_STATUS_DPDM:
113                         // dpdm in grf
114                         ret = control_usb->grf_soc_status0_rk3188->otg_linestate;
115                         break;
116                 case USB_STATUS_ID:
117                         // id in grf
118                         ret = control_usb->grf_soc_status0_rk3188->otg_iddig;
119                         break;
120                 default:
121                         break;
122         }
123
124         return ret;
125 }
126
127 #ifdef CONFIG_RK_USB_UART
128 static void dwc_otg_uart_mode(void* pdata, int enter_usb_uart_mode)
129 {
130         if(1 == enter_usb_uart_mode){
131                 /* enter uart mode
132                  * note: can't disable otg here! If otg disable, the ID change
133                  * interrupt can't be triggered when otg cable connect without
134                  * device.At the same time, uart can't be used normally
135                  */
136                 /* bypass dm, enter uart mode */
137                 control_usb->grf_uoc0_base->CON0 = (0x0300 | (0x0300 << 16));
138         }else if(0 == enter_usb_uart_mode){
139                 /* enter usb mode */
140                 control_usb->grf_uoc0_base->CON0 = (0x0300 << 16);
141         }
142 }
143 #endif
144
145 static void usb20otg_power_enable(int enable)
146 {
147         if(0 == enable){//disable otg_drv power
148                 gpio_set_value(control_usb->otg_gpios->gpio, 0);
149         }else if(1 == enable){//enable otg_drv power
150                 gpio_set_value(control_usb->otg_gpios->gpio, 1);
151         }
152 }
153
154 struct dwc_otg_platform_data usb20otg_pdata_rk3188 = {
155         .phyclk = NULL,
156         .ahbclk = NULL,
157         .busclk = NULL,
158         .phy_status = 0,
159         .hw_init = usb20otg_hw_init,
160         .phy_suspend = usb20otg_phy_suspend,
161         .soft_reset = usb20otg_soft_reset,
162         .clock_init = usb20otg_clock_init,
163         .clock_enable = usb20otg_clock_enable,
164         .get_status = usb20otg_get_status,
165         .get_chip_id = usb_get_chip_id,
166         .power_enable = usb20otg_power_enable,
167 #ifdef CONFIG_RK_USB_UART
168         .dwc_otg_uart_mode = dwc_otg_uart_mode,
169 #endif
170 };
171
172 #endif
173
174 #ifdef CONFIG_USB20_HOST
175 static void usb20host_hw_init(void)
176 {
177         /* usb phy config init */
178
179         /* other haredware init,include:
180          * DRV_VBUS GPIO init */
181         gpio_direction_output(control_usb->host_gpios->gpio, 1);
182
183 }
184
185 static void usb20host_phy_suspend(void* pdata, int suspend)
186 {
187         struct dwc_otg_platform_data *usbpdata=pdata;
188
189         if(suspend){
190                 // enable soft control
191                 control_usb->grf_uoc1_base->CON2 = (0x01<<2)|((0x01<<2)<<16);
192                 // enter suspend
193                 control_usb->grf_uoc1_base->CON3 = 0x2A|(0x3F<<16); 
194                 usbpdata->phy_status = 1;
195         }else{
196                 //exit suspend.
197                 control_usb->grf_uoc1_base->CON2 = ((0x01<<2)<<16);
198                 usbpdata->phy_status = 0;
199         }
200 }
201
202 static void usb20host_soft_reset(void)
203 {
204 }
205
206 static void usb20host_clock_init(void* pdata)
207 {
208         struct dwc_otg_platform_data *usbpdata=pdata;
209         struct clk* ahbclk,*phyclk;
210
211         ahbclk = devm_clk_get(usbpdata->dev, "hclk_otg1");
212         if (IS_ERR(ahbclk)) {
213                 dev_err(usbpdata->dev, "Failed to get hclk_otg1\n");
214                 return;
215         }
216
217         phyclk = devm_clk_get(usbpdata->dev, "otgphy1");
218         if (IS_ERR(phyclk)) {
219                 dev_err(usbpdata->dev, "Failed to get otgphy1\n");
220                 return;
221         }
222
223         usbpdata->phyclk = phyclk;
224         usbpdata->ahbclk = ahbclk;
225 }
226
227 static void usb20host_clock_enable(void* pdata, int enable)
228 {
229         struct dwc_otg_platform_data *usbpdata=pdata;
230
231         if(enable){
232                 clk_prepare_enable(usbpdata->ahbclk);
233                 clk_prepare_enable(usbpdata->phyclk);
234         }else{
235                 clk_disable_unprepare(usbpdata->ahbclk);
236                 clk_disable_unprepare(usbpdata->phyclk);
237         }
238 }
239
240 static int usb20host_get_status(int id)
241 {
242         int ret = -1;
243
244         switch(id){
245                 case USB_STATUS_BVABLID:
246                         // bvalid in grf
247                         ret = control_usb->grf_soc_status0_rk3188->uhost_bvalid;
248                         break;
249                 case USB_STATUS_DPDM:
250                         // dpdm in grf
251                         ret = control_usb->grf_soc_status0_rk3188->uhost_linestate;
252                         break;
253                 case USB_STATUS_ID:
254                         // id in grf
255                         ret = control_usb->grf_soc_status0_rk3188->uhost_iddig;
256                         break;
257                 default:
258                         break;
259         }
260
261         return ret;
262 }
263
264 static void usb20host_power_enable(int enable)
265 {
266         if(0 == enable){//disable host_drv power
267                 //do not disable power in default
268         }else if(1 == enable){//enable host_drv power
269                 gpio_set_value(control_usb->host_gpios->gpio, 1);
270         }
271 }
272
273 struct dwc_otg_platform_data usb20host_pdata_rk3188 = {
274         .phyclk = NULL,
275         .ahbclk = NULL,
276         .busclk = NULL,
277         .phy_status = 0,
278         .hw_init = usb20host_hw_init,
279         .phy_suspend = usb20host_phy_suspend,
280         .soft_reset = usb20host_soft_reset,
281         .clock_init = usb20host_clock_init,
282         .clock_enable = usb20host_clock_enable,
283         .get_status = usb20host_get_status,
284         .get_chip_id = usb_get_chip_id,
285         .power_enable = usb20host_power_enable,
286 };
287 #endif
288
289 #ifdef CONFIG_USB_EHCI_RKHSIC
290 static void rk_hsic_hw_init(void)
291 {
292         // usb phy config init
293         // hsic phy config init, set hsicphy_txsrtune
294         control_usb->grf_uoc2_base->CON0 = ((0xf<<6)<<16)|(0xf<<6);
295
296         /* other haredware init
297          * set common_on, in suspend mode, otg/host PLL blocks remain powered
298          * for RK3168 set control_usb->grf_uoc0_base->CON0 = (1<<16)|0;
299          * for Rk3188 set control_usb->grf_uoc1_base->CON0 = (1<<16)|0;
300          */
301         control_usb->grf_uoc1_base->CON0 = (1<<16)|0;
302
303         /* change INCR to INCR16 or INCR8(beats less than 16)
304          * or INCR4(beats less than 8) or SINGLE(beats less than 4)
305          */
306         control_usb->grf_uoc3_base->CON0 = 0x00ff00bc;
307 }
308
309 static void rk_hsic_clock_init(void* pdata)
310 {
311         /* By default, hsicphy_480m's parent is otg phy 480MHz clk
312          * rk3188 must use host phy 480MHz clk, because if otg bypass
313          * to uart mode, otg phy 480MHz clk will be closed automatically
314          */
315         struct rkehci_platform_data *usbpdata=pdata;
316         struct clk *ahbclk, *phyclk480m_hsic, *phyclk12m_hsic, *phyclk_otgphy1;
317
318         phyclk480m_hsic = devm_clk_get(usbpdata->dev, "hsicphy480m");
319         if (IS_ERR(phyclk480m_hsic)) {
320                 dev_err(usbpdata->dev, "Failed to get hsicphy480m\n");
321                 return;
322         }
323
324         phyclk12m_hsic = devm_clk_get(usbpdata->dev, "hsicphy12m");
325         if (IS_ERR(phyclk12m_hsic)) {
326                 dev_err(usbpdata->dev, "Failed to get hsicphy12m\n");
327                 return;
328         }
329
330         phyclk_otgphy1 = devm_clk_get(usbpdata->dev, "hsic_otgphy1");
331         if (IS_ERR(phyclk_otgphy1)) {
332                 dev_err(usbpdata->dev, "Failed to get hsic_otgphy1\n");
333                 return;
334         }
335
336         ahbclk = devm_clk_get(usbpdata->dev, "hclk_hsic");
337         if (IS_ERR(ahbclk)) {
338                 dev_err(usbpdata->dev, "Failed to get hclk_hsic\n");
339                 return;
340         }
341
342         clk_set_parent(phyclk480m_hsic, phyclk_otgphy1);
343         
344         usbpdata->hclk_hsic = ahbclk;
345         usbpdata->hsic_phy_480m = phyclk480m_hsic;
346         usbpdata->hsic_phy_12m = phyclk12m_hsic;
347 }
348
349 static void rk_hsic_clock_enable(void* pdata, int enable)
350 {
351         struct rkehci_platform_data *usbpdata=pdata;
352
353         if(enable == usbpdata->clk_status)
354                 return;
355         if(enable){
356                 clk_prepare_enable(usbpdata->hclk_hsic);
357                 clk_prepare_enable(usbpdata->hsic_phy_480m);
358                 clk_prepare_enable(usbpdata->hsic_phy_12m);
359                 usbpdata->clk_status = 1;
360         }else{
361                 clk_disable_unprepare(usbpdata->hclk_hsic);
362                 clk_disable_unprepare(usbpdata->hsic_phy_480m);
363                 clk_disable_unprepare(usbpdata->hsic_phy_12m);
364                 usbpdata->clk_status = 0;
365         }
366 }
367
368 static void rk_hsic_soft_reset(void)
369 {
370
371 }
372
373 struct rkehci_platform_data rkhsic_pdata_rk3188 = {
374         .hclk_hsic = NULL,
375         .hsic_phy_12m = NULL,
376         .hsic_phy_480m = NULL,
377         .clk_status = -1,
378         .hw_init = rk_hsic_hw_init,
379         .clock_init = rk_hsic_clock_init,
380         .clock_enable = rk_hsic_clock_enable,
381         .soft_reset = rk_hsic_soft_reset,
382         .get_chip_id = usb_get_chip_id,
383 };
384 #endif
385
386 #ifdef CONFIG_RK_USB_DETECT_BY_OTG_BVALID
387 #define WAKE_LOCK_TIMEOUT (HZ * 10)
388
389 inline static void do_wakeup(struct work_struct *work)
390 {
391 //      rk28_send_wakeup_key();
392 }
393 #endif
394
395 /********** handler for bvalid irq **********/
396 static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
397 {
398         /* clear irq */
399         control_usb->grf_uoc0_base->CON3 = (1 << 31) | (1 << 15);
400
401 #ifdef CONFIG_RK_USB_UART
402         /* usb otg dp/dm switch to usb phy */
403         dwc_otg_uart_mode(NULL, PHY_USB_MODE);
404 #endif
405
406 #ifdef CONFIG_RK_USB_DETECT_BY_OTG_BVALID
407         wake_lock_timeout(&control_usb->usb_wakelock, WAKE_LOCK_TIMEOUT);
408         schedule_delayed_work(&control_usb->usb_det_wakeup_work, HZ/10);
409 #endif
410
411         return IRQ_HANDLED;
412 }
413
414 /************* register bvalid irq **************/
415 static int otg_irq_detect_init(struct platform_device *pdev)
416 {
417         int ret = 0;
418         int irq = 0;
419
420 #ifdef CONFIG_RK_USB_DETECT_BY_OTG_BVALID
421         wake_lock_init(&control_usb->usb_wakelock, WAKE_LOCK_SUSPEND, "usb_detect");
422         INIT_DELAYED_WORK(&control_usb->usb_det_wakeup_work, do_wakeup);
423 #endif
424
425         irq = platform_get_irq_byname(pdev, "bvalid");
426         if (irq > 0) {
427                 ret = request_irq(irq, bvalid_irq_handler, 0, "bvalid", NULL);
428                 if(ret < 0){
429                         dev_err(&pdev->dev, "request_irq %d failed!\n", irq);
430                         return ret;
431                 }
432
433                 /* clear & enable bvalid irq */
434                 control_usb->grf_uoc0_base->CON3 = (3 << 30) | (3 << 14);
435
436 #ifdef CONFIG_RK_USB_DETECT_BY_OTG_BVALID
437                 enable_irq_wake(irq);
438 #endif
439         }
440
441         return ret;
442 }
443
444 static int usb_grf_ioremap(struct platform_device *pdev)
445 {
446         int ret = 0;
447         struct resource *res;
448         void *grf_soc_status0;
449         void *grf_uoc0_base;
450         void *grf_uoc1_base;
451         void *grf_uoc2_base;
452         void *grf_uoc3_base;
453
454         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
455                                                 "GRF_SOC_STATUS0");
456         grf_soc_status0 = devm_ioremap_resource(&pdev->dev, res);
457         if (IS_ERR(grf_soc_status0)){
458                 ret = PTR_ERR(grf_soc_status0);
459                 return ret;
460         }
461         control_usb->grf_soc_status0_rk3188 = (pGRF_SOC_STATUS_RK3188)grf_soc_status0;
462
463         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
464                                                 "GRF_UOC0_BASE");
465         grf_uoc0_base = devm_ioremap_resource(&pdev->dev, res);
466         if (IS_ERR(grf_uoc0_base)){
467                 ret = PTR_ERR(grf_uoc0_base);
468                 return ret;
469         }
470         control_usb->grf_uoc0_base = (pGRF_UOC0_REG)grf_uoc0_base;
471
472         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
473                                                 "GRF_UOC1_BASE");
474         grf_uoc1_base = devm_ioremap_resource(&pdev->dev, res);
475         if (IS_ERR(grf_uoc1_base)){
476                 ret = PTR_ERR(grf_uoc1_base);
477                 return ret;
478         }
479         control_usb->grf_uoc1_base = (pGRF_UOC1_REG)grf_uoc1_base;
480
481         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
482                                                 "GRF_UOC2_BASE");
483         grf_uoc2_base = devm_ioremap_resource(&pdev->dev, res);
484         if (IS_ERR(grf_uoc2_base)){
485                 ret = PTR_ERR(grf_uoc2_base);
486                 return ret;
487         }
488         control_usb->grf_uoc2_base = (pGRF_UOC2_REG)grf_uoc2_base;
489
490         res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
491                                                 "GRF_UOC3_BASE");
492         grf_uoc3_base = devm_ioremap_resource(&pdev->dev, res);
493         if (IS_ERR(grf_uoc3_base)){
494                 ret = PTR_ERR(grf_uoc3_base);
495                 return ret;
496         }
497         control_usb->grf_uoc3_base = (pGRF_UOC3_REG)grf_uoc3_base;
498
499         return ret;
500 }
501
502 #ifdef CONFIG_OF
503
504 static const struct of_device_id dwc_otg_control_usb_id_table[] = {
505         {
506                 .compatible = "rockchip,rk3188-dwc-control-usb",
507         },
508         { },
509 };
510 MODULE_DEVICE_TABLE(of, dwc_otg_control_usb_id_table);
511 #endif
512
513 static int dwc_otg_control_usb_probe(struct platform_device *pdev)
514 {
515         int gpio, err;
516         struct device_node *np = pdev->dev.of_node;
517         struct clk* hclk_usb_peri;
518         int ret = 0;
519
520         control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb),GFP_KERNEL);
521         if (!control_usb) {
522                 dev_err(&pdev->dev, "unable to alloc memory for control usb\n");
523                 ret =  -ENOMEM;
524                 goto err1;
525         }
526
527         control_usb->chip_id = RK3188_USB_CTLR;
528
529         hclk_usb_peri = devm_clk_get(&pdev->dev, "hclk_usb_peri");
530         if (IS_ERR(hclk_usb_peri)) {
531                 dev_err(&pdev->dev, "Failed to get hclk_usb_peri\n");
532                 ret = -EINVAL;
533                 goto err1;
534         }
535
536         control_usb->hclk_usb_peri = hclk_usb_peri;
537         clk_prepare_enable(hclk_usb_peri);
538
539         ret = usb_grf_ioremap(pdev);
540         if(ret){
541                 dev_err(&pdev->dev, "Failed to ioremap usb grf\n");
542                 goto err2;
543         }
544
545         control_usb->host_gpios = devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
546
547         gpio =  of_get_named_gpio(np, "gpios", 0);
548         if(!gpio_is_valid(gpio)){
549                 dev_err(&pdev->dev, "invalid host gpio%d\n", gpio);
550                 ret = -EINVAL;
551                 goto err2;
552         }
553         control_usb->host_gpios->gpio = gpio;
554         err = devm_gpio_request(&pdev->dev, gpio, "host_drv_gpio");
555         if (err) {
556                 dev_err(&pdev->dev,
557                         "failed to request GPIO%d for host_drv\n",
558                         gpio);
559                 ret = err;
560                 goto err2;
561         }
562
563         control_usb->otg_gpios = devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
564
565         gpio =  of_get_named_gpio(np, "gpios", 1);
566         if(!gpio_is_valid(gpio)){
567                 dev_err(&pdev->dev, "invalid otg gpio%d\n", gpio);
568                 ret = -EINVAL;
569                 goto err2;
570         }
571         control_usb->otg_gpios->gpio = gpio;
572         err = devm_gpio_request(&pdev->dev, gpio, "otg_drv_gpio");
573         if (err) {
574                 dev_err(&pdev->dev,
575                         "failed to request GPIO%d for otg_drv\n",
576                         gpio);
577                 ret = err;
578                 goto err2;
579         }
580
581         ret = otg_irq_detect_init(pdev);
582         if (ret < 0)
583                 goto err2;
584
585         return 0;
586
587 err2:
588         clk_disable_unprepare(hclk_usb_peri);
589 err1:
590         return ret;
591 }
592
593 static int dwc_otg_control_usb_remove(struct platform_device *pdev)
594 {
595         clk_disable_unprepare(control_usb->hclk_usb_peri);
596         return 0;
597 }
598
599 static struct platform_driver dwc_otg_control_usb_driver = {
600         .probe          = dwc_otg_control_usb_probe,
601         .remove         = dwc_otg_control_usb_remove,
602         .driver         = {
603                 .name   = "rk3188-dwc-control-usb",
604                 .owner  = THIS_MODULE,
605                 .of_match_table = of_match_ptr(dwc_otg_control_usb_id_table),
606         },
607 };
608
609 static int __init dwc_otg_control_usb_init(void)
610 {
611         return platform_driver_register(&dwc_otg_control_usb_driver);
612 }
613 subsys_initcall(dwc_otg_control_usb_init);
614
615 static void __exit dwc_otg_control_usb_exit(void)
616 {
617         platform_driver_unregister(&dwc_otg_control_usb_driver);
618 }
619
620 module_exit(dwc_otg_control_usb_exit);
621 MODULE_ALIAS("platform: dwc_control_usb");
622 MODULE_AUTHOR("RockChip Inc.");
623 MODULE_DESCRIPTION("RockChip Control Module USB Driver");
624 MODULE_LICENSE("GPL v2");