Merge remote-tracking branch 'origin/develop-3.10' into develop-3.10-next
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / usbdev_rk3036.c
1 #include "usbdev_rk.h"
2 #include "usbdev_grf_regs.h"
3 #include "dwc_otg_regs.h"
4 static struct dwc_otg_control_usb *control_usb;
5
6 #ifdef CONFIG_USB20_OTG
7 static void usb20otg_hw_init(void)
8 {
9         /* other haredware init,include:
10          * DRV_VBUS GPIO init */
11         if (gpio_is_valid(control_usb->otg_gpios->gpio)) {
12                 if (gpio_get_value(control_usb->otg_gpios->gpio))
13                         gpio_set_value(control_usb->otg_gpios->gpio, 0);
14         }
15 }
16
17 static void usb20otg_phy_suspend(void *pdata, int suspend)
18 {
19         struct dwc_otg_platform_data *usbpdata = pdata;
20
21         if (suspend) {
22                 /* enable soft control */
23                 writel(UOC_HIWORD_UPDATE(0x55, 0x7f, 0),
24                        RK_GRF_VIRT + RK3036_GRF_UOC0_CON5);
25                 usbpdata->phy_status = 1;
26         } else {
27                 /* exit suspend */
28                 writel(UOC_HIWORD_UPDATE(0x0, 0x1, 0),
29                        RK_GRF_VIRT + RK3036_GRF_UOC0_CON5);
30                 usbpdata->phy_status = 0;
31         }
32 }
33
34 static void usb20otg_soft_reset(void)
35 {
36         writel(UOC_HIWORD_UPDATE(0x1, 0x3, 0),
37                RK_GRF_VIRT + RK3036_GRF_UOC0_CON5);
38         writel(UOC_HIWORD_UPDATE(0x1, 0x3, 0),
39                RK_GRF_VIRT + RK3036_GRF_UOC1_CON5);
40         /* cru_set_soft_reset(SOFT_RST_USBPOR, true); */
41         writel(UOC_HIWORD_UPDATE(0x1, 0x1, 9),
42                RK_CRU_VIRT + RK3036_CRU_SOFTRST6_CON);
43         /* cru_set_soft_reset(SOFT_RST_UTMI0, true); */
44         writel(UOC_HIWORD_UPDATE(0x1, 0x1, 7),
45                RK_CRU_VIRT + RK3036_CRU_SOFTRST6_CON);
46         /* cru_set_soft_reset(SOFT_RST_UTMI1, true); */
47         writel(UOC_HIWORD_UPDATE(0x1, 0x1, 8),
48                RK_CRU_VIRT + RK3036_CRU_SOFTRST6_CON);
49
50         udelay(15);
51
52         writel(UOC_HIWORD_UPDATE(0x2, 0x3, 0),
53                RK_GRF_VIRT + RK3036_GRF_UOC0_CON5);
54         writel(UOC_HIWORD_UPDATE(0x2, 0x3, 0),
55                RK_GRF_VIRT + RK3036_GRF_UOC1_CON5);
56
57         udelay(1500);
58         /* cru_set_soft_reset(SOFT_RST_USBPOR, false); */
59         writel(UOC_HIWORD_UPDATE(0x0, 0x1, 9),
60                RK_CRU_VIRT + RK3036_CRU_SOFTRST6_CON);
61         udelay(2);
62         /* cru_set_soft_reset(SOFT_RST_UTMI0, false); */
63         writel(UOC_HIWORD_UPDATE(0x0, 0x1, 7),
64                RK_CRU_VIRT + RK3036_CRU_SOFTRST6_CON);
65         /* cru_set_soft_reset(SOFT_RST_UTMI1, false); */
66         writel(UOC_HIWORD_UPDATE(0x0, 0x1, 8),
67                RK_CRU_VIRT + RK3036_CRU_SOFTRST6_CON);
68
69         /* ctrler reset */
70         /* cru_set_soft_reset(SOFT_RST_OTGC0, true); */
71         writel(UOC_HIWORD_UPDATE(0x1, 0x1, 7),
72                RK_CRU_VIRT + RK3036_CRU_SOFTRST4_CON);
73         /* cru_set_soft_reset(SOFT_RST_OTGC1, true); */
74         writel(UOC_HIWORD_UPDATE(0x1, 0x1, 10),
75                RK_CRU_VIRT + RK3036_CRU_SOFTRST4_CON);
76         udelay(2);
77
78         /* cru_set_soft_reset(SOFT_RST_USBOTG0, true); */
79         writel(UOC_HIWORD_UPDATE(0x1, 0x1, 5),
80                RK_CRU_VIRT + RK3036_CRU_SOFTRST4_CON);
81         /* cru_set_soft_reset(SOFT_RST_USBOTG1, true); */
82         writel(UOC_HIWORD_UPDATE(0x1, 0x1, 8),
83                RK_CRU_VIRT + RK3036_CRU_SOFTRST4_CON);
84         udelay(2);
85         /*
86            cru_set_soft_reset(SOFT_RST_OTGC0,false);
87            cru_set_soft_reset(SOFT_RST_OTGC1,false);
88            ru_set_soft_reset(SOFT_RST_USBOTG0,false);
89            cru_set_soft_reset(SOFT_RST_USBOTG1,false);
90          */
91         writel(UOC_HIWORD_UPDATE(0x0, 0x1, 7),
92                RK_CRU_VIRT + RK3036_CRU_SOFTRST4_CON);
93         writel(UOC_HIWORD_UPDATE(0x0, 0x1, 10),
94                RK_CRU_VIRT + RK3036_CRU_SOFTRST4_CON);
95         writel(UOC_HIWORD_UPDATE(0x0, 0x1, 5),
96                RK_CRU_VIRT + RK3036_CRU_SOFTRST4_CON);
97         writel(UOC_HIWORD_UPDATE(0x0, 0x1, 8),
98                RK_CRU_VIRT + RK3036_CRU_SOFTRST4_CON);
99 }
100
101 static void usb20otg_clock_init(void *pdata)
102 {
103         struct dwc_otg_platform_data *usbpdata = pdata;
104         struct clk *ahbclk, *phyclk;
105
106         ahbclk = devm_clk_get(usbpdata->dev, "hclk_usb0");
107         if (IS_ERR(ahbclk)) {
108                 dev_err(usbpdata->dev, "Failed to get hclk_usb0\n");
109                 return;
110         }
111
112         phyclk = devm_clk_get(usbpdata->dev, "clk_usbphy0");
113         if (IS_ERR(phyclk)) {
114                 dev_err(usbpdata->dev, "Failed to get clk_usbphy0\n");
115                 return;
116         }
117
118         usbpdata->phyclk = phyclk;
119         usbpdata->ahbclk = ahbclk;
120 }
121
122 static void usb20otg_clock_enable(void *pdata, int enable)
123 {
124         struct dwc_otg_platform_data *usbpdata = pdata;
125
126         if (enable) {
127                 clk_prepare_enable(usbpdata->ahbclk);
128                 clk_prepare_enable(usbpdata->phyclk);
129         } else {
130                 clk_disable_unprepare(usbpdata->ahbclk);
131                 /*
132                    clk_disable_unprepare(usbpdata->phyclk);
133                  */
134         }
135 }
136
137 static int usb20otg_get_status(int id)
138 {
139         int ret = -1;
140         u32 soc_status0 = readl(RK_GRF_VIRT + RK3036_GRF_CPU_STATUS0);
141
142         switch (id) {
143         case USB_STATUS_BVABLID:
144                 /* bvalid in grf */
145                 ret = soc_status0 & (0x1 << 8);
146                 break;
147         case USB_STATUS_DPDM:
148                 /* dpdm in grf */
149                 ret = soc_status0 & (0x3 << 9);
150                 break;
151         case USB_STATUS_ID:
152                 /* id in grf */
153                 ret = soc_status0 & (0x1 << 11);
154                 break;
155         case USB_CHIP_ID:
156                 ret = control_usb->chip_id;
157                 break;
158         case USB_REMOTE_WAKEUP:
159                 ret = control_usb->remote_wakeup;
160                 break;
161         case USB_IRQ_WAKEUP:
162                 ret = control_usb->usb_irq_wakeup;
163                 break;
164         default:
165                 break;
166         }
167         return ret;
168 }
169
170 static void dwc_otg_uart_mode(void *pdata, int enter_usb_uart_mode)
171 {
172 #ifdef CONFIG_RK_USB_UART
173         if (1 == enter_usb_uart_mode) {
174                 /* bypass dm, enter uart mode */
175                 writel(UOC_HIWORD_UPDATE(0x3, 0x3, 12),
176                        RK_GRF_VIRT + RK3036_GRF_UOC1_CON4);
177         } else if (0 == enter_usb_uart_mode) {
178                 /* enter usb mode */
179                 writel(UOC_HIWORD_UPDATE(0x0, 0x3, 12),
180                        RK_GRF_VIRT + RK3036_GRF_UOC1_CON4);
181         }
182 #endif
183 }
184
185 static void usb20otg_power_enable(int enable)
186 {
187         if (0 == enable) {
188                 /* disable otg_drv power */
189                 if (gpio_is_valid(control_usb->otg_gpios->gpio))
190                         gpio_set_value(control_usb->otg_gpios->gpio, 0);
191         } else if (1 == enable) {
192                 /* enable otg_drv power */
193                 if (gpio_is_valid(control_usb->otg_gpios->gpio))
194                         gpio_set_value(control_usb->otg_gpios->gpio, 1);
195         }
196 }
197
198 struct dwc_otg_platform_data usb20otg_pdata_rk3036 = {
199         .phyclk = NULL,
200         .ahbclk = NULL,
201         .busclk = NULL,
202         .phy_status = 0,
203         .hw_init = usb20otg_hw_init,
204         .phy_suspend = usb20otg_phy_suspend,
205         .soft_reset = usb20otg_soft_reset,
206         .clock_init = usb20otg_clock_init,
207         .clock_enable = usb20otg_clock_enable,
208         .get_status = usb20otg_get_status,
209         .power_enable = usb20otg_power_enable,
210         .dwc_otg_uart_mode = dwc_otg_uart_mode,
211         .bc_detect_cb = usb20otg_battery_charger_detect_cb,
212 };
213 #endif
214
215 #ifdef CONFIG_USB20_HOST
216 static void usb20host_hw_init(void)
217 {
218         /* other haredware init,include:
219          * DRV_VBUS GPIO init */
220         if (gpio_is_valid(control_usb->host_gpios->gpio)) {
221                 if (!gpio_get_value(control_usb->host_gpios->gpio))
222                         gpio_set_value(control_usb->host_gpios->gpio, 1);
223         }
224 }
225
226 static void usb20host_phy_suspend(void *pdata, int suspend)
227 {
228         struct dwc_otg_platform_data *usbpdata = pdata;
229
230         if (suspend) {
231                 /* enable soft control */
232                 writel(UOC_HIWORD_UPDATE(0x1d5, 0x1ff, 0),
233                        RK_GRF_VIRT + RK3036_GRF_UOC1_CON5);
234                 usbpdata->phy_status = 1;
235         } else {
236                 /* exit suspend */
237                 writel(UOC_HIWORD_UPDATE(0x0, 0x1, 0),
238                        RK_GRF_VIRT + RK3036_GRF_UOC1_CON5);
239                 usbpdata->phy_status = 0;
240         }
241 }
242
243 static void usb20host_soft_reset(void)
244 {
245         ;
246 }
247
248 static void usb20host_clock_init(void *pdata)
249 {
250         struct dwc_otg_platform_data *usbpdata = pdata;
251         struct clk *ahbclk, *phyclk;
252
253         ahbclk = devm_clk_get(usbpdata->dev, "hclk_usb1");
254         if (IS_ERR(ahbclk)) {
255                 dev_err(usbpdata->dev, "Failed to get hclk_usb1\n");
256                 return;
257         }
258
259         phyclk = devm_clk_get(usbpdata->dev, "clk_usbphy1");
260         if (IS_ERR(phyclk)) {
261                 dev_err(usbpdata->dev, "Failed to get clk_usbphy1\n");
262                 return;
263         }
264
265         usbpdata->phyclk = phyclk;
266         usbpdata->ahbclk = ahbclk;
267 }
268
269 static void usb20host_clock_enable(void *pdata, int enable)
270 {
271         struct dwc_otg_platform_data *usbpdata = pdata;
272
273         if (enable) {
274                 clk_prepare_enable(usbpdata->ahbclk);
275                 clk_prepare_enable(usbpdata->phyclk);
276         } else {
277                 clk_disable_unprepare(usbpdata->ahbclk);
278                 clk_disable_unprepare(usbpdata->phyclk);
279         }
280 }
281
282 static int usb20host_get_status(int id)
283 {
284         int ret = -1;
285         u32 soc_status0 = readl(RK_GRF_VIRT + RK3036_GRF_CPU_STATUS0);
286
287         switch (id) {
288         case USB_STATUS_BVABLID:
289                 /* bvalid in grf */
290                 ret = soc_status0 & (0x1 << 13);
291                 break;
292         case USB_STATUS_DPDM:
293                 /* dpdm in grf */
294                 ret = soc_status0 & (0x3 << 14);
295                 break;
296         case USB_STATUS_ID:
297                 /* id in grf */
298                 ret = 0;
299                 break;
300         case USB_CHIP_ID:
301                 ret = control_usb->chip_id;
302                 break;
303         case USB_REMOTE_WAKEUP:
304                 ret = control_usb->remote_wakeup;
305                 break;
306         case USB_IRQ_WAKEUP:
307                 ret = control_usb->usb_irq_wakeup;
308                 break;
309         default:
310                 break;
311         }
312         return ret;
313 }
314
315 static void usb20host_power_enable(int enable)
316 {
317         if (0 == enable) {
318                 /* disable host_drv power */
319                 /* do not disable power in default */
320         } else if (1 == enable) {
321                 /* enable host_drv power */
322                 if (gpio_is_valid(control_usb->host_gpios->gpio))
323                         gpio_set_value(control_usb->host_gpios->gpio, 1);
324         }
325 }
326
327 struct dwc_otg_platform_data usb20host_pdata_rk3036 = {
328         .phyclk = NULL,
329         .ahbclk = NULL,
330         .busclk = NULL,
331         .phy_status = 0,
332         .hw_init = usb20host_hw_init,
333         .phy_suspend = usb20host_phy_suspend,
334         .soft_reset = usb20host_soft_reset,
335         .clock_init = usb20host_clock_init,
336         .clock_enable = usb20host_clock_enable,
337         .get_status = usb20host_get_status,
338         .power_enable = usb20host_power_enable,
339 };
340 #endif
341
342 #ifdef CONFIG_OF
343 static const struct of_device_id rk_usb_control_id_table[] = {
344         {
345          .compatible = "rockchip,rk3036-usb-control",
346          },
347         {},
348 };
349 #endif
350 /*********************************************************************
351                         rk3036 usb detections
352 *********************************************************************/
353
354 #define WAKE_LOCK_TIMEOUT (HZ * 10)
355 static inline void do_wakeup(struct work_struct *work)
356 {
357         /* wake up the system */
358         rk_send_wakeup_key();
359 }
360
361 static void usb_battery_charger_detect_work(struct work_struct *work)
362 {
363         rk_usb_charger_status = usb_battery_charger_detect(0);
364 }
365
366 /********** handler for bvalid irq **********/
367 static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
368 {
369         /* clear irq */
370         writel(UOC_HIWORD_UPDATE(0x1, 0x1, 15),
371                RK_GRF_VIRT + RK3036_GRF_UOC0_CON5);
372 #ifdef CONFIG_RK_USB_UART
373         /* usb otg dp/dm switch to usb phy */
374         dwc_otg_uart_mode(NULL, PHY_USB_MODE);
375 #endif
376
377         if (control_usb->usb_irq_wakeup) {
378                 wake_lock_timeout(&control_usb->usb_wakelock,
379                                   WAKE_LOCK_TIMEOUT);
380                 schedule_delayed_work(&control_usb->usb_det_wakeup_work,
381                                       HZ / 10);
382         }
383
384         rk_usb_charger_status = USB_BC_TYPE_SDP;
385         schedule_delayed_work(&control_usb->usb_charger_det_work, HZ / 10);
386
387         return IRQ_HANDLED;
388 }
389
390 /************* register usb detection irqs **************/
391 static int otg_irq_detect_init(struct platform_device *pdev)
392 {
393         int ret = 0;
394         int irq = 0;
395
396         if (control_usb->usb_irq_wakeup) {
397                 wake_lock_init(&control_usb->usb_wakelock, WAKE_LOCK_SUSPEND,
398                                "usb_detect");
399                 INIT_DELAYED_WORK(&control_usb->usb_det_wakeup_work, do_wakeup);
400         }
401
402         /*register otg_bvalid irq */
403         irq = platform_get_irq_byname(pdev, "otg_bvalid");
404         if ((irq > 0) && control_usb->usb_irq_wakeup) {
405                 ret = request_irq(irq, bvalid_irq_handler,
406                                   0, "otg_bvalid", NULL);
407                 if (ret < 0) {
408                         dev_err(&pdev->dev, "request_irq %d failed!\n", irq);
409                 } else {
410                         /* enable bvalid irq  */
411                         writel(UOC_HIWORD_UPDATE(0x1, 0x1, 14),
412                                RK_GRF_VIRT + RK3036_GRF_UOC0_CON5);
413                 }
414         }
415         return ret;
416 }
417
418 /********** end of rk3036 usb detections **********/
419 static int rk_usb_control_probe(struct platform_device *pdev)
420 {
421         int gpio, err;
422         struct device_node *np = pdev->dev.of_node;
423         int ret = 0;
424
425         control_usb =
426             devm_kzalloc(&pdev->dev, sizeof(*control_usb), GFP_KERNEL);
427         if (!control_usb) {
428                 dev_err(&pdev->dev, "unable to alloc memory for control usb\n");
429                 ret = -ENOMEM;
430                 goto out;
431         }
432
433         control_usb->chip_id = RK3036_USB_CTLR;
434         control_usb->remote_wakeup = of_property_read_bool(np,
435                                                            "rockchip,remote_wakeup");
436         control_usb->usb_irq_wakeup = of_property_read_bool(np,
437                                                             "rockchip,usb_irq_wakeup");
438
439         INIT_DELAYED_WORK(&control_usb->usb_charger_det_work,
440                           usb_battery_charger_detect_work);
441
442         control_usb->host_gpios =
443             devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
444         if (!control_usb->host_gpios) {
445                 dev_err(&pdev->dev, "unable to alloc memory for host_gpios\n");
446                 ret = -ENOMEM;
447                 goto out;
448         }
449
450         gpio = of_get_named_gpio(np, "host_drv_gpio", 0);
451         control_usb->host_gpios->gpio = gpio;
452
453         if (!gpio_is_valid(gpio)) {
454                 dev_err(&pdev->dev, "invalid host gpio%d\n", gpio);
455         } else {
456                 err = devm_gpio_request(&pdev->dev, gpio, "host_drv_gpio");
457                 if (err) {
458                         dev_err(&pdev->dev,
459                                 "failed to request GPIO%d for host_drv\n",
460                                 gpio);
461                         ret = err;
462                         goto out;
463                 }
464                 gpio_direction_output(control_usb->host_gpios->gpio, 1);
465         }
466
467         control_usb->otg_gpios =
468             devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
469         if (!control_usb->otg_gpios) {
470                 dev_err(&pdev->dev, "unable to alloc memory for otg_gpios\n");
471                 ret = -ENOMEM;
472                 goto out;
473         }
474
475         gpio = of_get_named_gpio(np, "otg_drv_gpio", 0);
476         control_usb->otg_gpios->gpio = gpio;
477
478         if (!gpio_is_valid(gpio)) {
479                 dev_err(&pdev->dev, "invalid otg gpio%d\n", gpio);
480         } else {
481                 err = devm_gpio_request(&pdev->dev, gpio, "otg_drv_gpio");
482                 if (err) {
483                         dev_err(&pdev->dev,
484                                 "failed to request GPIO%d for otg_drv\n", gpio);
485                         ret = err;
486                         goto out;
487                 }
488                 gpio_direction_output(control_usb->otg_gpios->gpio, 0);
489         }
490
491 out:
492         return ret;
493 }
494
495 static int rk_usb_control_remove(struct platform_device *pdev)
496 {
497         return 0;
498 }
499
500 static struct platform_driver rk_usb_control_driver = {
501         .probe = rk_usb_control_probe,
502         .remove = rk_usb_control_remove,
503         .driver = {
504                    .name = "rk3036-usb-control",
505                    .owner = THIS_MODULE,
506                    .of_match_table = of_match_ptr(rk_usb_control_id_table),
507                    },
508 };
509
510 #ifdef CONFIG_OF
511
512 static const struct of_device_id dwc_otg_control_usb_id_table[] = {
513         {
514          .compatible = "rockchip,rk3036-dwc-control-usb",
515          },
516         {},
517 };
518
519 #endif
520 static int dwc_otg_control_usb_probe(struct platform_device *pdev)
521 {
522         struct clk *hclk_usb_peri;
523         int ret = 0;
524
525         if (!control_usb) {
526                 dev_err(&pdev->dev, "unable to alloc memory for control usb\n");
527                 ret = -ENOMEM;
528                 goto err1;
529         }
530
531         hclk_usb_peri = devm_clk_get(&pdev->dev, "hclk_usb_peri");
532         if (IS_ERR(hclk_usb_peri)) {
533                 dev_err(&pdev->dev, "Failed to get hclk_usb_peri\n");
534                 ret = -EINVAL;
535                 goto err1;
536         }
537
538         control_usb->hclk_usb_peri = hclk_usb_peri;
539         clk_prepare_enable(hclk_usb_peri);
540
541 #ifdef CONFIG_USB20_OTG
542         if (usb20otg_get_status(USB_STATUS_BVABLID)) {
543                 rk_usb_charger_status = USB_BC_TYPE_SDP;
544                 schedule_delayed_work(&control_usb->usb_charger_det_work,
545                                       HZ / 10);
546         }
547 #endif
548
549         ret = otg_irq_detect_init(pdev);
550         if (ret < 0)
551                 goto err2;
552
553         return 0;
554
555 err2:
556         clk_disable_unprepare(hclk_usb_peri);
557 err1:
558         return ret;
559 }
560
561 static int dwc_otg_control_usb_remove(struct platform_device *pdev)
562 {
563         clk_disable_unprepare(control_usb->hclk_usb_peri);
564         return 0;
565 }
566
567 static struct platform_driver dwc_otg_control_usb_driver = {
568         .probe = dwc_otg_control_usb_probe,
569         .remove = dwc_otg_control_usb_remove,
570         .driver = {
571                    .name = "rk3036-dwc-control-usb",
572                    .owner = THIS_MODULE,
573                    .of_match_table = of_match_ptr(dwc_otg_control_usb_id_table),
574                    },
575 };
576
577 static int __init dwc_otg_control_usb_init(void)
578 {
579         int retval = 0;
580
581         retval |= platform_driver_register(&rk_usb_control_driver);
582         retval |= platform_driver_register(&dwc_otg_control_usb_driver);
583         return retval;
584 }
585
586 subsys_initcall(dwc_otg_control_usb_init);
587
588 static void __exit dwc_otg_control_usb_exit(void)
589 {
590         platform_driver_unregister(&rk_usb_control_driver);
591         platform_driver_unregister(&dwc_otg_control_usb_driver);
592 }
593
594 module_exit(dwc_otg_control_usb_exit);
595 MODULE_ALIAS("platform: dwc_control_usb");
596 MODULE_AUTHOR("RockChip Inc.");
597 MODULE_DESCRIPTION("RockChip Control Module USB Driver");
598 MODULE_LICENSE("GPL v2");