rk: restore file mode
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / dwc_otg_pcd_linux.c
index 5d99badf5d5d7c6557f0beb9677d81db4f006018..e67384d733051ceb56d956311e2974bedfae87c7 100755 (executable)
@@ -746,7 +746,7 @@ static int dwc_otg_pcd_pullup(struct usb_gadget *_gadget, int is_on)
                pcd->conn_status = 0;
        } else {
                dwc_otg_pcd_pullup_disable(pcd);
-               pcd->conn_status = 2;
+               pcd->conn_en = 0;
        }
 
        return 0;
@@ -1502,7 +1502,7 @@ static void dwc_phy_reconnect(struct work_struct *work)
        }
 }
 
-void id_status_change(dwc_otg_core_if_t *p, bool current_id)
+static void id_status_change(dwc_otg_core_if_t *p, bool current_id)
 {
        dwc_otg_core_if_t *core_if = p;
        uint32_t count = 0;
@@ -1513,7 +1513,7 @@ void id_status_change(dwc_otg_core_if_t *p, bool current_id)
        DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32);
        DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts);
 
-       if( core_if->usb_mode != USB_MODE_NORMAL )
+       if (core_if->usb_mode != USB_MODE_NORMAL)
                return;
 
        /* B-Device connector (Device Mode) */
@@ -1535,6 +1535,7 @@ void id_status_change(dwc_otg_core_if_t *p, bool current_id)
                        DWC_PRINTF("Connection id status change timed out");
                        return;
                }
+               dwc_otg_set_force_mode(core_if, USB_MODE_FORCE_DEVICE);
                core_if->op_state = B_PERIPHERAL;
                cil_hcd_stop(core_if);
                /* pcd->phy_suspend = 1; */
@@ -1558,8 +1559,9 @@ void id_status_change(dwc_otg_core_if_t *p, bool current_id)
                }
 
                core_if->op_state = A_HOST;
+               dwc_otg_set_force_mode(core_if, USB_MODE_FORCE_HOST);
 
-               cancel_delayed_work(&pcd->check_vbus_work);
+               cancel_delayed_work_sync(&pcd->check_vbus_work);
 
                /*
                 * Initialize the Core for Host mode.
@@ -1580,21 +1582,19 @@ static void check_id(struct work_struct *work)
        static int last_id = -1;
        int id = pldata->get_status(USB_STATUS_ID);
 
-       if((last_id != id)) {
-               printk("[otg id chg] last id %d current id %d \n", last_id, id);
-               if (!id) { /* Force Host */
-                       if (pldata->phy_status == USB_PHY_SUSPEND) {
-                               pldata->clock_enable(pldata, 1);
-                               pldata->phy_suspend(pldata, USB_PHY_ENABLED);
-       }
-                       id_status_change(otg_dev->core_if, id);
-               } else { /* Force Device */
-                       id_status_change(otg_dev->core_if, id);
+       if (last_id != id) {
+               pr_info("[otg id chg] last id %d current id %d\n", last_id, id);
+
+               if (pldata->phy_status == USB_PHY_SUSPEND) {
+                       pldata->clock_enable(pldata, 1);
+                       pldata->phy_suspend(pldata, USB_PHY_ENABLED);
                }
+
+               /* Force Device or Host by id */
+               id_status_change(otg_dev->core_if, id);
        }
        last_id = id;
        schedule_delayed_work(&_pcd->check_id_work, (HZ));
-       return;
 }
 
 static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
@@ -1604,7 +1604,8 @@ static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
        struct dwc_otg_device *otg_dev = _pcd->otg_dev;
        struct dwc_otg_platform_data *pldata = otg_dev->pldata;
 
-       if (pldata->get_status(USB_STATUS_BVABLID)) {
+       if (pldata->get_status(USB_STATUS_BVABLID) &&
+           pldata->get_status(USB_STATUS_ID)) {
                /* if usb not connect before ,then start connect */
                if (_pcd->vbus_status == USB_BC_TYPE_DISCNT) {
                        printk("***************vbus detect*****************\n");
@@ -1633,7 +1634,7 @@ static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
                        _pcd->conn_status++;
                        if (pldata->bc_detect_cb != NULL) {
                                pldata->bc_detect_cb(_pcd->vbus_status =
-                                                    USB_BC_TYPE_DCP);
+                                                    usb_battery_charger_detect(1));
                        } else {
                                _pcd->vbus_status = USB_BC_TYPE_DCP;
                        }
@@ -1658,10 +1659,12 @@ static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
                if (pldata->phy_status == USB_PHY_ENABLED) {
                        /* release wake lock */
                        dwc_otg_msc_unlock(_pcd);
-                       /* no vbus detect here , close usb phy  */
-                       pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
-                       udelay(3);
-                       pldata->clock_enable(pldata, 0);
+                       if (pldata->get_status(USB_STATUS_ID)) {
+                               /* no vbus detect here , close usb phy  */
+                               pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
+                               udelay(3);
+                               pldata->clock_enable(pldata, 0);
+                       }
                }
 
                /* usb phy bypass to uart mode  */
@@ -1669,7 +1672,8 @@ static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
                        pldata->dwc_otg_uart_mode(pldata, PHY_UART_MODE);
        }
 
-       schedule_delayed_work(&_pcd->check_vbus_work, HZ);
+       if (pldata->get_status(USB_STATUS_ID))
+               schedule_delayed_work(&_pcd->check_vbus_work, HZ);
        return;
 
 connect:
@@ -1743,12 +1747,17 @@ static void dwc_otg_pcd_work_init(dwc_otg_pcd_t *pcd,
                        /* usb phy bypass to uart mode */
                        pldata->dwc_otg_uart_mode(pldata, PHY_UART_MODE);
                }
-       }
-       else if (pldata->dwc_otg_uart_mode != NULL) {
+       } else if (pldata->dwc_otg_uart_mode != NULL) {
                /* host mode,enter usb phy mode */
                pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
        }
-       schedule_delayed_work(&pcd->check_id_work, msecs_to_jiffies(HZ));
+       schedule_delayed_work(&pcd->check_id_work, 8 * HZ);
+       if (otg_dev->core_if->usb_mode == USB_MODE_FORCE_DEVICE) {
+               pcd->vbus_status = 0;
+               dwc_otg_core_init(otg_dev->core_if);
+               cil_pcd_start(otg_dev->core_if);
+               dwc_otg_pcd_start_check_vbus_work(pcd);
+       }
 }
 
 #endif /* DWC_HOST_ONLY */