2 #include "dwc_otg_regs.h"
4 static struct dwc_otg_control_usb *control_usb;
6 static u32 uoc_read(u32 reg)
10 regmap_read(control_usb->grf, reg, &val);
14 static void uoc_write(u32 value, u32 reg)
16 regmap_write(control_usb->grf, reg, value);
19 #ifdef CONFIG_USB20_OTG
20 static void usb20otg_hw_init(void)
22 /* Turn off differential receiver in suspend mode */
23 uoc_write(UOC_HIWORD_UPDATE(0, 1, 2), 0x798);
25 /* other haredware init,include:
26 * DRV_VBUS GPIO init */
27 if (gpio_is_valid(control_usb->otg_gpios->gpio))
28 gpio_set_value(control_usb->otg_gpios->gpio, 0);
31 static void usb20otg_phy_suspend(void *pdata, int suspend)
33 struct dwc_otg_platform_data *usbpdata = pdata;
36 /* enable soft control */
37 uoc_write(UOC_HIWORD_UPDATE(0x55, 0x7f, 0), 0x700);
38 usbpdata->phy_status = 1;
41 uoc_write(UOC_HIWORD_UPDATE(0x0, 0x1, 0), 0x700);
42 usbpdata->phy_status = 0;
46 static void usb20otg_soft_reset(void *pdata, enum rkusb_rst_flag rst_type)
48 struct dwc_otg_platform_data *usbpdata = pdata;
49 struct reset_control *rst_otg_h, *rst_otg_p, *rst_otg_c;
51 rst_otg_h = devm_reset_control_get(usbpdata->dev, "otg_ahb");
52 rst_otg_p = devm_reset_control_get(usbpdata->dev, "otg_phy");
53 rst_otg_c = devm_reset_control_get(usbpdata->dev, "otg_controller");
54 if (IS_ERR(rst_otg_h) || IS_ERR(rst_otg_p) || IS_ERR(rst_otg_c)) {
55 dev_err(usbpdata->dev, "Fail to get reset control from dts\n");
62 uoc_write(UOC_HIWORD_UPDATE(0x1, 0x3, 0), 0x700);
63 reset_control_assert(rst_otg_p);
65 uoc_write(UOC_HIWORD_UPDATE(0x2, 0x3, 0), 0x700);
67 reset_control_deassert(rst_otg_p);
70 /* Controller reset */
71 reset_control_assert(rst_otg_c);
72 reset_control_assert(rst_otg_h);
76 reset_control_deassert(rst_otg_c);
77 reset_control_deassert(rst_otg_h);
85 static void usb20otg_clock_init(void *pdata)
87 struct dwc_otg_platform_data *usbpdata = pdata;
88 struct clk *ahbclk, *phyclk;
90 ahbclk = devm_clk_get(usbpdata->dev, "hclk_otg");
92 dev_err(usbpdata->dev, "Failed to get hclk_usb0\n");
96 phyclk = devm_clk_get(usbpdata->dev, "clk_usbphy0");
98 dev_err(usbpdata->dev, "Failed to get clk_usbphy0\n");
102 usbpdata->phyclk = phyclk;
103 usbpdata->ahbclk = ahbclk;
106 static void usb20otg_clock_enable(void *pdata, int enable)
108 struct dwc_otg_platform_data *usbpdata = pdata;
111 clk_prepare_enable(usbpdata->ahbclk);
112 clk_prepare_enable(usbpdata->phyclk);
114 clk_disable_unprepare(usbpdata->ahbclk);
115 clk_disable_unprepare(usbpdata->phyclk);
119 static int usb20otg_get_status(int id)
122 u32 soc_status15 = uoc_read(0x4bc);
125 case USB_STATUS_BVABLID:
127 ret = soc_status15 & (0x1 << 23);
129 case USB_STATUS_DPDM:
131 ret = soc_status15 & (0x3 << 24);
135 ret = soc_status15 & (0x1 << 26);
138 ret = control_usb->chip_id;
140 case USB_REMOTE_WAKEUP:
141 ret = control_usb->remote_wakeup;
144 ret = control_usb->usb_irq_wakeup;
152 #ifdef CONFIG_RK_USB_UART
154 * dwc_otg_uart_enabled - check if a usb-uart bypass func is enabled in DT
156 * Returns true if the status property of node "usb_uart" is set to "okay"
157 * or "ok", if this property is absent it will use the default status "ok"
160 static bool dwc_otg_uart_enabled(void)
165 static void dwc_otg_uart_mode(void *pdata, int enter_usb_uart_mode)
169 static void dwc_otg_uart_mode(void *pdata, int enter_usb_uart_mode)
174 static void usb20otg_power_enable(int enable)
177 /* disable otg_drv power */
178 if (gpio_is_valid(control_usb->otg_gpios->gpio))
179 gpio_set_value(control_usb->otg_gpios->gpio, 0);
180 } else if (1 == enable) {
181 /* enable otg_drv power */
182 if (gpio_is_valid(control_usb->otg_gpios->gpio))
183 gpio_set_value(control_usb->otg_gpios->gpio, 1);
187 struct dwc_otg_platform_data usb20otg_pdata_rk3368 = {
192 .hw_init = usb20otg_hw_init,
193 .phy_suspend = usb20otg_phy_suspend,
194 .soft_reset = usb20otg_soft_reset,
195 .clock_init = usb20otg_clock_init,
196 .clock_enable = usb20otg_clock_enable,
197 .get_status = usb20otg_get_status,
198 .power_enable = usb20otg_power_enable,
199 .dwc_otg_uart_mode = dwc_otg_uart_mode,
200 .bc_detect_cb = rk_battery_charger_detect_cb,
204 #ifdef CONFIG_USB_EHCI_RK
205 static void usb20ehci_hw_init(void)
207 /* Turn off differential receiver in suspend mode */
208 uoc_write(UOC_HIWORD_UPDATE(0, 1, 2), 0x7b8);
209 /* Set disconnect detection trigger point to 600mv */
210 uoc_write(UOC_HIWORD_UPDATE(1, 0xf, 11), 0x7bc);
212 /* other haredware init,include:
213 * DRV_VBUS GPIO init */
214 if (gpio_is_valid(control_usb->host_gpios->gpio)) {
215 if (!gpio_get_value(control_usb->host_gpios->gpio))
216 gpio_set_value(control_usb->host_gpios->gpio, 1);
220 static void usb20ehci_phy_suspend(void *pdata, int suspend)
222 struct rkehci_platform_data *usbpdata = pdata;
225 /* enable soft control */
226 uoc_write(UOC_HIWORD_UPDATE(0x1d5, 0x1ff, 0), 0x728);
227 usbpdata->phy_status = 1;
230 uoc_write(UOC_HIWORD_UPDATE(0x0, 0x1, 0), 0x728);
231 usbpdata->phy_status = 0;
235 static void usb20ehci_soft_reset(void *pdata, enum rkusb_rst_flag rst_type)
237 struct rkehci_platform_data *usbpdata = pdata;
238 struct reset_control *rst_host_h, *rst_host_p, *rst_host_c;
240 rst_host_h = devm_reset_control_get(usbpdata->dev, "host_ahb");
241 rst_host_p = devm_reset_control_get(usbpdata->dev, "host_phy");
242 rst_host_c = devm_reset_control_get(usbpdata->dev, "host_controller");
243 if (IS_ERR(rst_host_h) || IS_ERR(rst_host_p) || IS_ERR(rst_host_c)) {
244 dev_err(usbpdata->dev, "Fail to get reset control from dts\n");
251 uoc_write(UOC_HIWORD_UPDATE(0x1, 0x3, 0), 0x728);
252 reset_control_assert(rst_host_p);
254 uoc_write(UOC_HIWORD_UPDATE(0x2, 0x3, 0), 0x728);
257 reset_control_deassert(rst_host_p);
259 /* Controller reset */
260 reset_control_assert(rst_host_c);
261 reset_control_assert(rst_host_h);
265 reset_control_deassert(rst_host_c);
266 reset_control_deassert(rst_host_h);
274 static void usb20ehci_clock_init(void *pdata)
278 static void usb20ehci_clock_enable(void *pdata, int enable)
282 static int usb20ehci_get_status(int id)
284 /* For HOST port in rk336x can not get any info from GRF */
288 struct rkehci_platform_data usb20ehci_pdata_rk3368 = {
292 .hw_init = usb20ehci_hw_init,
293 .phy_suspend = usb20ehci_phy_suspend,
294 .soft_reset = usb20ehci_soft_reset,
295 .clock_init = usb20ehci_clock_init,
296 .clock_enable = usb20ehci_clock_enable,
297 .get_status = usb20ehci_get_status,
301 struct dwc_otg_platform_data usb20ohci_pdata_rk3368;
304 static const struct of_device_id rk_usb_control_id_table[] = {
306 .compatible = "rockchip,rk3368-usb-control",
311 /*********************************************************************
312 rk3126 usb detections
313 *********************************************************************/
315 #define WAKE_LOCK_TIMEOUT (HZ * 10)
316 static inline void do_wakeup(struct work_struct *work)
318 /* wake up the system */
319 rk_send_wakeup_key();
322 static void usb_battery_charger_detect_work(struct work_struct *work)
324 rk_battery_charger_detect_cb(usb_battery_charger_detect(1));
327 /********** handler for bvalid irq **********/
328 static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
331 uoc_write(UOC_HIWORD_UPDATE(0x1, 0x1, 3), 0x6a0);
332 #ifdef CONFIG_RK_USB_UART
333 /* usb otg dp/dm switch to usb phy */
334 dwc_otg_uart_mode(NULL, PHY_USB_MODE);
337 if (control_usb->usb_irq_wakeup) {
338 wake_lock_timeout(&control_usb->usb_wakelock,
340 schedule_delayed_work(&control_usb->usb_det_wakeup_work,
344 schedule_delayed_work(&control_usb->usb_charger_det_work, HZ / 10);
349 /************* register usb detection irqs **************/
350 static int otg_irq_detect_init(struct platform_device *pdev)
355 wake_lock_init(&control_usb->usb_wakelock, WAKE_LOCK_SUSPEND,
357 INIT_DELAYED_WORK(&control_usb->usb_det_wakeup_work, do_wakeup);
359 /*register otg_bvalid irq */
360 irq = platform_get_irq_byname(pdev, "otg_bvalid");
361 if ((irq > 0) && control_usb->usb_irq_wakeup) {
362 ret = request_irq(irq, bvalid_irq_handler,
363 0, "otg_bvalid", NULL);
365 dev_err(&pdev->dev, "request_irq %d failed!\n", irq);
367 /* enable bvalid irq */
368 uoc_write(UOC_HIWORD_UPDATE(0x1, 0x1, 3), 0x680);
375 /********** end of usb detections **********/
377 static const struct of_device_id dwc_otg_control_usb_id_table[] = {
379 .compatible = "rockchip,rk3368-dwc-control-usb",
384 static int dwc_otg_control_usb_probe(struct platform_device *pdev)
386 struct device *dev = &pdev->dev;
387 struct device_node *np = dev->of_node;
388 struct clk *hclk_usb_peri;
392 control_usb = devm_kzalloc(dev, sizeof(*control_usb), GFP_KERNEL);
394 dev_err(&pdev->dev, "Unable to alloc memory for control usb\n");
398 /* Init regmap GRF */
399 grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
401 dev_err(&pdev->dev, "Missing rockchip,grf property\n");
404 control_usb->grf = grf;
406 /* Init Vbus-drv GPIOs */
407 control_usb->host_gpios =
408 devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
409 if (!control_usb->host_gpios) {
410 dev_err(&pdev->dev, "Unable to alloc memory for host_gpios\n");
414 gpio = of_get_named_gpio(np, "host_drv_gpio", 0);
415 control_usb->host_gpios->gpio = gpio;
417 if (gpio_is_valid(gpio)) {
418 if (devm_gpio_request(&pdev->dev, gpio, "usb_host_drv")) {
420 "Failed to request GPIO%d for host_drv\n",
424 gpio_direction_output(control_usb->host_gpios->gpio, 1);
427 control_usb->otg_gpios =
428 devm_kzalloc(&pdev->dev, sizeof(struct gpio), GFP_KERNEL);
429 if (!control_usb->otg_gpios) {
430 dev_err(&pdev->dev, "Unable to alloc memory for otg_gpios\n");
434 gpio = of_get_named_gpio(np, "otg_drv_gpio", 0);
435 control_usb->otg_gpios->gpio = gpio;
437 if (gpio_is_valid(gpio)) {
438 if (devm_gpio_request(&pdev->dev, gpio, "usb_otg_drv")) {
440 "failed to request GPIO%d for otg_drv\n", gpio);
443 gpio_direction_output(control_usb->otg_gpios->gpio, 0);
447 control_usb->remote_wakeup = of_property_read_bool(np,
448 "rockchip,remote_wakeup");
449 control_usb->usb_irq_wakeup = of_property_read_bool(np,
450 "rockchip,usb_irq_wakeup");
452 /* Init hclk_usb_peri */
453 hclk_usb_peri = devm_clk_get(&pdev->dev, "hclk_usb_peri");
454 if (IS_ERR(hclk_usb_peri)) {
455 dev_err(&pdev->dev, "Failed to get hclk_usb_peri\n");
456 return PTR_ERR(hclk_usb_peri);
458 control_usb->hclk_usb_peri = hclk_usb_peri;
459 clk_prepare_enable(hclk_usb_peri);
461 #ifdef CONFIG_USB20_OTG
462 INIT_DELAYED_WORK(&control_usb->usb_charger_det_work,
463 usb_battery_charger_detect_work);
465 if (usb20otg_get_status(USB_STATUS_BVABLID))
466 schedule_delayed_work(&control_usb->usb_charger_det_work,
470 ret = otg_irq_detect_init(pdev);
477 clk_disable_unprepare(hclk_usb_peri);
481 static int dwc_otg_control_usb_remove(struct platform_device *pdev)
483 clk_disable_unprepare(control_usb->hclk_usb_peri);
487 static struct platform_driver dwc_otg_control_usb_driver = {
488 .probe = dwc_otg_control_usb_probe,
489 .remove = dwc_otg_control_usb_remove,
491 .name = "rk3368-dwc-control-usb",
492 .owner = THIS_MODULE,
493 .of_match_table = of_match_ptr(dwc_otg_control_usb_id_table),
497 static int __init dwc_otg_control_usb_init(void)
501 retval |= platform_driver_register(&dwc_otg_control_usb_driver);
505 subsys_initcall(dwc_otg_control_usb_init);
507 static void __exit dwc_otg_control_usb_exit(void)
509 platform_driver_unregister(&dwc_otg_control_usb_driver);
512 module_exit(dwc_otg_control_usb_exit);
513 MODULE_ALIAS("platform: dwc_control_usb");
514 MODULE_AUTHOR("RockChip Inc.");
515 MODULE_DESCRIPTION("RockChip Control Module USB Driver");
516 MODULE_LICENSE("GPL v2");