MLK-16776 staging: typec: tcpci: use vbus from partner for EXTCON_USB
authorLi Jun <jun.li@nxp.com>
Tue, 7 Nov 2017 13:32:51 +0000 (21:32 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:39:12 +0000 (15:39 -0500)
Change to use the vbus from partner to notify EXTCON_USB.
This is to work around the case of source only typec port
connecting to Host PC via a Rp fixed cable.

Acked-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Li Jun <jun.li@nxp.com>
drivers/staging/typec/tcpci.c

index be0fa9c..6cca961 100644 (file)
@@ -40,7 +40,7 @@ struct tcpci {
        struct regmap *regmap;
 
        bool controls_vbus;
-       bool attached;
+       bool drive_vbus;
        struct gpio_desc *ss_sel_gpio;
 
        struct tcpc_dev tcpc;
@@ -251,11 +251,6 @@ static int tcpci_get_cc(struct tcpc_dev *tcpc,
                                 TCPC_CC_STATUS_CC2_MASK,
                                 reg & TCPC_CC_STATUS_TERM);
 
-       if ((*cc1 == TYPEC_CC_OPEN) && (*cc2 == TYPEC_CC_OPEN))
-               tcpci->attached = false;
-       else
-               tcpci->attached = true;
-
        return 0;
 }
 
@@ -317,19 +312,10 @@ static int tcpci_set_roles(struct tcpc_dev *tcpc, bool attached,
        if (ret < 0)
                return ret;
 
-       if (data == TYPEC_HOST) {
-               extcon_set_state_sync(tcpci->edev, EXTCON_USB, false);
+       if (data == TYPEC_HOST)
                extcon_set_state_sync(tcpci->edev, EXTCON_USB_HOST, true);
-       } else {
+       else
                extcon_set_state_sync(tcpci->edev, EXTCON_USB_HOST, false);
-               /*
-                * Instead of use 'attached' input, we need
-                * the real HW connection status to notify
-                * USB device controller driver the attach
-                * and dettach event to host.
-                */
-               extcon_set_state_sync(tcpci->edev, EXTCON_USB, tcpci->attached);
-       }
 
        return 0;
 }
@@ -359,7 +345,19 @@ static int tcpci_get_vbus(struct tcpc_dev *tcpc)
        if (ret < 0)
                return ret;
 
-       return !!(reg & TCPC_POWER_STATUS_VBUS_PRES);
+       ret = !!(reg & TCPC_POWER_STATUS_VBUS_PRES);
+
+       /*
+        * If the vbus is not from itself for source, we
+        * assume the vbus is from the port partner, this
+        * is to work around the case of connect to legacy
+        * Host like PC via a fixed Rp pull up cable, so
+        * we notify the possible EXTCON_USB connection.
+        */
+       if (!tcpci->drive_vbus)
+               extcon_set_state_sync(tcpci->edev, EXTCON_USB, ret);
+
+       return ret;
 }
 
 static unsigned int tcpci_get_vbus_vol(struct tcpc_dev *tcpc)
@@ -390,6 +388,7 @@ static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink)
                if (ret < 0)
                        return ret;
 
+               tcpci->drive_vbus = false;
                /* Enable force discharge */
                tcpci_vbus_force_discharge(tcpc, true);
        }
@@ -406,6 +405,7 @@ static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink)
                                   TCPC_CMD_SRC_VBUS_DEFAULT);
                if (ret < 0)
                        return ret;
+               tcpci->drive_vbus = true;
        }
 
        if (sink) {