usb: otg: notify to pmu the otg vbus change
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / usbdev_rk3368.c
1 #ifdef CONFIG_ARM64
2 #include "usbdev_rk.h"
3 #include "dwc_otg_regs.h"
4
5 static struct dwc_otg_control_usb *control_usb;
6
7 static u32 uoc_read(u32 reg)
8 {
9         unsigned int val;
10
11         regmap_read(control_usb->grf, reg, &val);
12         return val;
13 }
14
15 static void uoc_write(u32 value, u32 reg)
16 {
17         regmap_write(control_usb->grf, reg, value);
18 }
19
20 #ifdef CONFIG_USB20_OTG
21 static void usb20otg_hw_init(void)
22 {
23         /* Turn off differential receiver in suspend mode */
24         uoc_write(UOC_HIWORD_UPDATE(0, 1, 2), 0x798);
25
26         /* Set disconnect detection trigger point to 600mv */
27         uoc_write(UOC_HIWORD_UPDATE(0, 0xf, 11), 0x79c);
28
29         /* other haredware init,include:
30          * DRV_VBUS GPIO init */
31         if (gpio_is_valid(control_usb->otg_gpios->gpio))
32                 gpio_set_value(control_usb->otg_gpios->gpio, 0);
33 }
34
35 static void usb20otg_phy_suspend(void *pdata, int suspend)
36 {
37         struct dwc_otg_platform_data *usbpdata = pdata;
38         if (suspend) {
39                 /* enable soft control */
40                 uoc_write(UOC_HIWORD_UPDATE(0x1d5, 0x1ff, 0), 0x700);
41                 usbpdata->phy_status = 1;
42         } else {
43                 /* exit suspend */
44                 uoc_write(UOC_HIWORD_UPDATE(0x0, 0x1, 0), 0x700);
45                 usbpdata->phy_status = 0;
46         }
47 }
48
49 static void usb20otg_soft_reset(void *pdata, enum rkusb_rst_flag rst_type)
50 {
51         struct dwc_otg_platform_data *usbpdata = pdata;
52         struct reset_control *rst_otg_h, *rst_otg_p, *rst_otg_c;
53
54         rst_otg_h = devm_reset_control_get(usbpdata->dev, "otg_ahb");
55         rst_otg_p = devm_reset_control_get(usbpdata->dev, "otg_phy");
56         rst_otg_c = devm_reset_control_get(usbpdata->dev, "otg_controller");
57         if (IS_ERR(rst_otg_h) || IS_ERR(rst_otg_p) || IS_ERR(rst_otg_c)) {
58                 dev_err(usbpdata->dev, "Fail to get reset control from dts\n");
59                 return;
60         }
61
62         switch (rst_type) {
63         case RST_POR:
64                 /* PHY reset */
65                 uoc_write(UOC_HIWORD_UPDATE(0x1, 0x3, 0), 0x700);
66                 reset_control_assert(rst_otg_p);
67                 udelay(15);
68                 uoc_write(UOC_HIWORD_UPDATE(0x2, 0x3, 0), 0x700);
69                 udelay(1500);
70                 reset_control_deassert(rst_otg_p);
71                 udelay(2);
72
73                 /* Controller reset */
74                 reset_control_assert(rst_otg_c);
75                 reset_control_assert(rst_otg_h);
76
77                 udelay(2);
78
79                 reset_control_deassert(rst_otg_c);
80                 reset_control_deassert(rst_otg_h);
81                 break;
82
83         default:
84                 break;
85         }
86 }
87
88 static void usb20otg_clock_init(void *pdata)
89 {
90         struct dwc_otg_platform_data *usbpdata = pdata;
91         struct clk *ahbclk, *phyclk;
92
93         ahbclk = devm_clk_get(usbpdata->dev, "hclk_otg");
94         if (IS_ERR(ahbclk)) {
95                 dev_err(usbpdata->dev, "Failed to get hclk_usb0\n");
96                 return;
97         }
98
99         phyclk = devm_clk_get(usbpdata->dev, "clk_usbphy0");
100         if (IS_ERR(phyclk)) {
101                 dev_err(usbpdata->dev, "Failed to get clk_usbphy0\n");
102                 return;
103         }
104
105         usbpdata->phyclk = phyclk;
106         usbpdata->ahbclk = ahbclk;
107 }
108
109 static void usb20otg_clock_enable(void *pdata, int enable)
110 {
111         struct dwc_otg_platform_data *usbpdata = pdata;
112
113         if (enable) {
114                 clk_prepare_enable(usbpdata->ahbclk);
115                 clk_prepare_enable(usbpdata->phyclk);
116         } else {
117                 clk_disable_unprepare(usbpdata->ahbclk);
118                 clk_disable_unprepare(usbpdata->phyclk);
119         }
120 }
121
122 static int usb20otg_get_status(int id)
123 {
124         int ret = -1;
125         u32 soc_status15 = uoc_read(0x4bc);
126
127         switch (id) {
128         case USB_STATUS_BVABLID:
129                 /* bvalid in grf */
130                 ret = soc_status15 & (0x1 << 23);
131                 break;
132         case USB_STATUS_DPDM:
133                 /* dpdm in grf */
134                 ret = soc_status15 & (0x3 << 24);
135                 break;
136         case USB_STATUS_ID:
137                 /* id in grf */
138                 ret = soc_status15 & (0x1 << 26);
139                 break;
140         case USB_CHIP_ID:
141                 ret = control_usb->chip_id;
142                 break;
143         case USB_REMOTE_WAKEUP:
144                 ret = control_usb->remote_wakeup;
145                 break;
146         case USB_IRQ_WAKEUP:
147                 ret = control_usb->usb_irq_wakeup;
148                 break;
149         default:
150                 break;
151         }
152         return ret;
153 }
154
155 #ifdef CONFIG_RK_USB_UART
156 /**
157  *  dwc_otg_uart_enabled - check if a usb-uart bypass func is enabled in DT
158  *
159  *  Returns true if the status property of node "usb_uart" is set to "okay"
160  *  or "ok", if this property is absent it will use the default status "ok"
161  *  0 otherwise
162  */
163 static bool dwc_otg_uart_enabled(void)
164 {
165         return false;
166 }
167
168 static void dwc_otg_uart_mode(void *pdata, int enter_usb_uart_mode)
169 {
170 }
171 #else
172 static void dwc_otg_uart_mode(void *pdata, int enter_usb_uart_mode)
173 {
174 }
175 #endif
176
177 static void usb20otg_power_enable(int enable)
178 {
179         if (0 == enable) {
180                 rk_battery_charger_detect_cb(USB_OTG_POWER_OFF);
181                 /* disable otg_drv power */
182                 if (gpio_is_valid(control_usb->otg_gpios->gpio))
183                         gpio_set_value(control_usb->otg_gpios->gpio, 0);
184         } else if (1 == enable) {
185                 rk_battery_charger_detect_cb(USB_OTG_POWER_ON);
186                 /* enable otg_drv power */
187                 if (gpio_is_valid(control_usb->otg_gpios->gpio))
188                         gpio_set_value(control_usb->otg_gpios->gpio, 1);
189         }
190 }
191
192 struct dwc_otg_platform_data usb20otg_pdata_rk3368 = {
193         .phyclk = NULL,
194         .ahbclk = NULL,
195         .busclk = NULL,
196         .phy_status = 0,
197         .hw_init = usb20otg_hw_init,
198         .phy_suspend = usb20otg_phy_suspend,
199         .soft_reset = usb20otg_soft_reset,
200         .clock_init = usb20otg_clock_init,
201         .clock_enable = usb20otg_clock_enable,
202         .get_status = usb20otg_get_status,
203         .power_enable = usb20otg_power_enable,
204         .dwc_otg_uart_mode = dwc_otg_uart_mode,
205         .bc_detect_cb = rk_battery_charger_detect_cb,
206 };
207 #endif
208
209 #ifdef CONFIG_USB_EHCI_RK
210 static void usb20ehci_hw_init(void)
211 {
212         /* Turn off differential receiver in suspend mode */
213         uoc_write(UOC_HIWORD_UPDATE(0, 1, 2), 0x7b8);
214         /* Set disconnect detection trigger point to 600mv */
215         uoc_write(UOC_HIWORD_UPDATE(1, 0xf, 11), 0x7bc);
216
217         /* other haredware init,include:
218          * DRV_VBUS GPIO init */
219         if (gpio_is_valid(control_usb->host_gpios->gpio)) {
220                 if (!gpio_get_value(control_usb->host_gpios->gpio))
221                         gpio_set_value(control_usb->host_gpios->gpio, 1);
222         }
223 }
224
225 static void usb20ehci_phy_suspend(void *pdata, int suspend)
226 {
227         struct rkehci_platform_data *usbpdata = pdata;
228
229         if (suspend) {
230                 /* enable soft control */
231                 uoc_write(UOC_HIWORD_UPDATE(0x1d5, 0x1ff, 0), 0x728);
232                 usbpdata->phy_status = 1;
233         } else {
234                 /* exit suspend */
235                 uoc_write(UOC_HIWORD_UPDATE(0x0, 0x1, 0), 0x728);
236                 usbpdata->phy_status = 0;
237         }
238 }
239
240 static void usb20ehci_soft_reset(void *pdata, enum rkusb_rst_flag rst_type)
241 {
242         struct rkehci_platform_data *usbpdata = pdata;
243         struct reset_control *rst_host_h, *rst_host_p, *rst_host_c;
244
245         rst_host_h = devm_reset_control_get(usbpdata->dev, "host_ahb");
246         rst_host_p = devm_reset_control_get(usbpdata->dev, "host_phy");
247         rst_host_c = devm_reset_control_get(usbpdata->dev, "host_controller");
248         if (IS_ERR(rst_host_h) || IS_ERR(rst_host_p) || IS_ERR(rst_host_c)) {
249                 dev_err(usbpdata->dev, "Fail to get reset control from dts\n");
250                 return;
251         }
252
253         switch (rst_type) {
254         case RST_POR:
255                 /* PHY reset */
256                 uoc_write(UOC_HIWORD_UPDATE(0x1, 0x3, 0), 0x728);
257                 reset_control_assert(rst_host_p);
258                 udelay(15);
259                 uoc_write(UOC_HIWORD_UPDATE(0x2, 0x3, 0), 0x728);
260
261                 udelay(1500);
262                 reset_control_deassert(rst_host_p);
263
264                 /* Controller reset */
265                 reset_control_assert(rst_host_c);
266                 reset_control_assert(rst_host_h);
267
268                 udelay(5);
269
270                 reset_control_deassert(rst_host_c);
271                 reset_control_deassert(rst_host_h);
272                 break;
273
274         default:
275                 break;
276         }
277 }
278
279 static void usb20ehci_clock_init(void *pdata)
280 {
281 }
282
283 static void usb20ehci_clock_enable(void *pdata, int enable)
284 {
285 }
286
287 static int usb20ehci_get_status(int id)
288 {
289         /* For HOST port in rk336x can not get any info from GRF */
290         return -ENOENT;
291 }
292
293 struct rkehci_platform_data usb20ehci_pdata_rk3368 = {
294         .phyclk = NULL,
295         .ahbclk = NULL,
296         .phy_status = 0,
297         .hw_init = usb20ehci_hw_init,
298         .phy_suspend = usb20ehci_phy_suspend,
299         .soft_reset = usb20ehci_soft_reset,
300         .clock_init = usb20ehci_clock_init,
301         .clock_enable = usb20ehci_clock_enable,
302         .get_status = usb20ehci_get_status,
303 };
304 #endif
305
306 struct dwc_otg_platform_data usb20ohci_pdata_rk3368;
307
308 #ifdef CONFIG_OF
309 static const struct of_device_id rk_usb_control_id_table[] = {
310         {
311          .compatible = "rockchip,rk3368-usb-control",
312          },
313         {},
314 };
315 #endif
316 /*********************************************************************
317                         rk3126 usb detections
318 *********************************************************************/
319
320 #define WAKE_LOCK_TIMEOUT (HZ * 10)
321 static inline void do_wakeup(struct work_struct *work)
322 {
323         /* wake up the system */
324         rk_send_wakeup_key();
325 }
326
327 static void usb_battery_charger_detect_work(struct work_struct *work)
328 {
329         rk_battery_charger_detect_cb(usb_battery_charger_detect(1));
330 }
331
332 /********** handler for bvalid irq **********/
333 static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
334 {
335         /* clear irq */
336         uoc_write(UOC_HIWORD_UPDATE(0x1, 0x1, 3), 0x6a0);
337 #ifdef CONFIG_RK_USB_UART
338         /* usb otg dp/dm switch to usb phy */
339         dwc_otg_uart_mode(NULL, PHY_USB_MODE);
340 #endif
341
342         if (control_usb->usb_irq_wakeup) {
343                 wake_lock_timeout(&control_usb->usb_wakelock,
344                                   WAKE_LOCK_TIMEOUT);
345                 schedule_delayed_work(&control_usb->usb_det_wakeup_work,
346                                       HZ / 10);
347         }
348
349         schedule_delayed_work(&control_usb->usb_charger_det_work, HZ / 10);
350
351         return IRQ_HANDLED;
352 }
353
354 /************* register usb detection irqs **************/
355 static int otg_irq_detect_init(struct platform_device *pdev)
356 {
357         int ret = 0;
358         int irq = 0;
359
360         wake_lock_init(&control_usb->usb_wakelock, WAKE_LOCK_SUSPEND,
361                        "usb_detect");
362         INIT_DELAYED_WORK(&control_usb->usb_det_wakeup_work, do_wakeup);
363
364         /*register otg_bvalid irq */
365         irq = platform_get_irq_byname(pdev, "otg_bvalid");
366         if ((irq > 0) && control_usb->usb_irq_wakeup) {
367                 ret = request_irq(irq, bvalid_irq_handler,
368                                   0, "otg_bvalid", NULL);
369                 if (ret < 0) {
370                         dev_err(&pdev->dev, "request_irq %d failed!\n", irq);
371                 } else {
372                         /* enable bvalid irq  */
373                         uoc_write(UOC_HIWORD_UPDATE(0x1, 0x1, 3), 0x680);
374                 }
375         }
376
377         return 0;
378 }
379
380 /********** end of usb detections **********/
381 #ifdef CONFIG_OF
382 static const struct of_device_id dwc_otg_control_usb_id_table[] = {
383         {
384          .compatible = "rockchip,rk3368-dwc-control-usb",
385          },
386         {},
387 };
388 #endif
389 static int dwc_otg_control_usb_probe(struct platform_device *pdev)
390 {
391         struct device *dev = &pdev->dev;
392         struct device_node *np = dev->of_node;
393         struct clk *hclk_usb_peri;
394         struct regmap *grf;
395         int gpio, ret = 0;
396
397         control_usb = devm_kzalloc(dev, sizeof(*control_usb), GFP_KERNEL);
398         if (!control_usb) {
399                 dev_err(&pdev->dev, "Unable to alloc memory for control usb\n");
400                 return -ENOMEM;
401         }
402
403         /* Init regmap GRF */
404         grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
405         if (IS_ERR(grf)) {
406                 dev_err(&pdev->dev, "Missing rockchip,grf property\n");
407                 return PTR_ERR(grf);
408         }
409         control_usb->grf = grf;
410
411         /* Init Vbus-drv GPIOs */
412         control_usb->host_gpios =
413             devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
414         if (!control_usb->host_gpios) {
415                 dev_err(&pdev->dev, "Unable to alloc memory for host_gpios\n");
416                 return -ENOMEM;
417         }
418
419         gpio = of_get_named_gpio(np, "host_drv_gpio", 0);
420         control_usb->host_gpios->gpio = gpio;
421
422         if (gpio_is_valid(gpio)) {
423                 if (devm_gpio_request(&pdev->dev, gpio, "usb_host_drv")) {
424                         dev_err(&pdev->dev,
425                                 "Failed to request GPIO%d for host_drv\n",
426                                 gpio);
427                         return -EINVAL;
428                 }
429                 gpio_direction_output(control_usb->host_gpios->gpio, 1);
430         }
431
432         control_usb->otg_gpios =
433             devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
434         if (!control_usb->otg_gpios) {
435                 dev_err(&pdev->dev, "Unable to alloc memory for otg_gpios\n");
436                 return -ENOMEM;
437         }
438
439         gpio = of_get_named_gpio(np, "otg_drv_gpio", 0);
440         control_usb->otg_gpios->gpio = gpio;
441
442         if (gpio_is_valid(gpio)) {
443                 if (devm_gpio_request(&pdev->dev, gpio, "usb_otg_drv")) {
444                         dev_err(&pdev->dev,
445                                 "failed to request GPIO%d for otg_drv\n", gpio);
446                         return -EINVAL;
447                 }
448                 gpio_direction_output(control_usb->otg_gpios->gpio, 0);
449         }
450
451
452         control_usb->remote_wakeup = of_property_read_bool(np,
453                                                            "rockchip,remote_wakeup");
454         control_usb->usb_irq_wakeup = of_property_read_bool(np,
455                                                             "rockchip,usb_irq_wakeup");
456
457         /* Init hclk_usb_peri */
458         hclk_usb_peri = devm_clk_get(&pdev->dev, "hclk_usb_peri");
459         if (IS_ERR(hclk_usb_peri)) {
460                 dev_err(&pdev->dev, "Failed to get hclk_usb_peri\n");
461                 return PTR_ERR(hclk_usb_peri);
462         }
463         control_usb->hclk_usb_peri = hclk_usb_peri;
464         clk_prepare_enable(hclk_usb_peri);
465
466 #ifdef CONFIG_USB20_OTG
467         INIT_DELAYED_WORK(&control_usb->usb_charger_det_work,
468                           usb_battery_charger_detect_work);
469
470         if (usb20otg_get_status(USB_STATUS_BVABLID))
471                 schedule_delayed_work(&control_usb->usb_charger_det_work,
472                                       HZ / 10);
473 #endif
474
475         ret = otg_irq_detect_init(pdev);
476         if (ret < 0)
477                 goto err;
478
479         return 0;
480
481 err:
482         clk_disable_unprepare(hclk_usb_peri);
483         return ret;
484 }
485
486 static int dwc_otg_control_usb_remove(struct platform_device *pdev)
487 {
488         clk_disable_unprepare(control_usb->hclk_usb_peri);
489         return 0;
490 }
491
492 static struct platform_driver dwc_otg_control_usb_driver = {
493         .probe = dwc_otg_control_usb_probe,
494         .remove = dwc_otg_control_usb_remove,
495         .driver = {
496                    .name = "rk3368-dwc-control-usb",
497                    .owner = THIS_MODULE,
498                    .of_match_table = of_match_ptr(dwc_otg_control_usb_id_table),
499                    },
500 };
501
502 static int __init dwc_otg_control_usb_init(void)
503 {
504         int retval = 0;
505
506         retval |= platform_driver_register(&dwc_otg_control_usb_driver);
507         return retval;
508 }
509
510 subsys_initcall(dwc_otg_control_usb_init);
511
512 static void __exit dwc_otg_control_usb_exit(void)
513 {
514         platform_driver_unregister(&dwc_otg_control_usb_driver);
515 }
516
517 module_exit(dwc_otg_control_usb_exit);
518 MODULE_ALIAS("platform: dwc_control_usb");
519 MODULE_AUTHOR("RockChip Inc.");
520 MODULE_DESCRIPTION("RockChip Control Module USB Driver");
521 MODULE_LICENSE("GPL v2");
522 #endif