Merge branch develop-3.10 into develop-3.10-next
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / usbdev_rk3126.c
index 5c6debc79e158b4aca37b3626dfafddf3b3ec4d7..a6f174cc322dbe44ac16c4c65945a120a38f4e16 100755 (executable)
@@ -6,6 +6,9 @@ static struct dwc_otg_control_usb *control_usb;
 #ifdef CONFIG_USB20_OTG
 static void usb20otg_hw_init(void)
 {
+       /* Turn off differential receiver in suspend mode */
+       writel(UOC_HIWORD_UPDATE(0, 1, 2),
+                  RK_GRF_VIRT + RK312X_GRF_USBPHY1_CON6);
        /* other haredware init,include:
         * DRV_VBUS GPIO init */
        if (gpio_is_valid(control_usb->otg_gpios->gpio)) {
@@ -124,6 +127,9 @@ static int usb20otg_get_status(int id)
                /* id in grf */
                ret = soc_status0 & (0x1 << 8);
                break;
+       case USB_STATUS_UARTMODE:
+               ret = readl(RK_GRF_VIRT + RK312X_GRF_UOC1_CON4) & (1 << 12);
+               break;
        case USB_CHIP_ID:
                ret = control_usb->chip_id;
                break;
@@ -139,20 +145,43 @@ static int usb20otg_get_status(int id)
        return ret;
 }
 
+#ifdef CONFIG_RK_USB_UART
+/**
+ *  dwc_otg_uart_enabled - check if a usb-uart bypass func is enabled in DT
+ *
+ *  Returns true if the status property of node "usb_uart" is set to "okay"
+ *  or "ok", if this property is absent it will use the default status "ok"
+ *  0 otherwise
+ */
+static bool dwc_otg_uart_enabled(void)
+{
+       struct device_node *np;
+
+       np = of_find_node_by_name(NULL, "usb_uart");
+       if (np && of_device_is_available(np))
+               return true;
+
+       return false;
+}
+
 static void dwc_otg_uart_mode(void *pdata, int enter_usb_uart_mode)
 {
-#ifdef CONFIG_RK_USB_UART
-       if (1 == enter_usb_uart_mode) {
+       if ((1 == enter_usb_uart_mode) && dwc_otg_uart_enabled()) {
                /* bypass dm, enter uart mode */
-               writel(UOC_HIWORD_UPDATE(0x3, 0x3, 12),
-                      RK_GRF_VIRT + RK312X_GRF_UOC1_CON4);
+               writel(UOC_HIWORD_UPDATE(0x3, 0x3, 12), RK_GRF_VIRT +
+                          RK312X_GRF_UOC1_CON4);
+
        } else if (0 == enter_usb_uart_mode) {
                /* enter usb mode */
-               writel(UOC_HIWORD_UPDATE(0x0, 0x3, 12),
-                      RK_GRF_VIRT + RK312X_GRF_UOC1_CON4);
+               writel(UOC_HIWORD_UPDATE(0x0, 0x3, 12), RK_GRF_VIRT + 
+                          RK312X_GRF_UOC1_CON4);
        }
-#endif
 }
+#else
+static void dwc_otg_uart_mode(void *pdata, int enter_usb_uart_mode)
+{
+}
+#endif
 
 static void usb20otg_power_enable(int enable)
 {
@@ -180,15 +209,19 @@ struct dwc_otg_platform_data usb20otg_pdata_rk3126 = {
        .get_status = usb20otg_get_status,
        .power_enable = usb20otg_power_enable,
        .dwc_otg_uart_mode = dwc_otg_uart_mode,
-       .bc_detect_cb = usb20otg_battery_charger_detect_cb,
+       .bc_detect_cb = rk_battery_charger_detect_cb,
 };
 #endif
 
 #ifdef CONFIG_USB20_HOST
 static void usb20host_hw_init(void)
 {
+       /* Switch to DWC HOST */
        writel(UOC_HIWORD_UPDATE(1, 1, 3),
                   RK_GRF_VIRT + RK312X_GRF_SOC_CON2);
+       /* Turn off differential receiver in suspend mode */
+       writel(UOC_HIWORD_UPDATE(0, 1, 2),
+                  RK_GRF_VIRT + RK312X_GRF_USBPHY0_CON6);
        /* other haredware init,include:
         * DRV_VBUS GPIO init */
        if (gpio_is_valid(control_usb->host_gpios->gpio)) {
@@ -370,7 +403,7 @@ static inline void do_wakeup(struct work_struct *work)
 
 static void usb_battery_charger_detect_work(struct work_struct *work)
 {
-       rk_usb_charger_status = usb_battery_charger_detect(0);
+       rk_battery_charger_detect_cb(usb_battery_charger_detect(1));
 }
 
 /********** handler for bvalid irq **********/
@@ -391,7 +424,6 @@ static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
                                      HZ / 10);
        }
 
-       rk_usb_charger_status = USB_BC_TYPE_SDP;
        schedule_delayed_work(&control_usb->usb_charger_det_work, HZ / 10);
 
        return IRQ_HANDLED;
@@ -549,11 +581,9 @@ static int dwc_otg_control_usb_probe(struct platform_device *pdev)
        clk_prepare_enable(hclk_usb_peri);
 
 #ifdef CONFIG_USB20_OTG
-       if (usb20otg_get_status(USB_STATUS_BVABLID)) {
-               rk_usb_charger_status = USB_BC_TYPE_SDP;
+       if (usb20otg_get_status(USB_STATUS_BVABLID))
                schedule_delayed_work(&control_usb->usb_charger_det_work,
                                      HZ / 10);
-       }
 #endif
 
        ret = otg_irq_detect_init(pdev);