UPSTREAM: arm64: dts: rockchip: add powerdomain for typec on rk3399
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / fusb302.c
index ca0eb20c0014f466e170f48e5b9f9ed48ff2ca46..effa6968d1a1f06beb8dd68ea29ea48dad164160 100644 (file)
@@ -103,6 +103,7 @@ static void dump_notify_info(struct fusb30x_chip *chip)
 static const unsigned int fusb302_cable[] = {
        EXTCON_USB,
        EXTCON_USB_HOST,
+       EXTCON_USB_VBUS_EN,
        EXTCON_CHG_USB_SDP,
        EXTCON_CHG_USB_CDP,
        EXTCON_CHG_USB_DCP,
@@ -139,7 +140,7 @@ void fusb_irq_enable(struct fusb30x_chip *chip)
 
 static void platform_fusb_notify(struct fusb30x_chip *chip)
 {
-       bool plugged = 0, flip = 0, dfp = 0, ufp = 0, dp = 0;
+       bool plugged = 0, flip = 0, dfp = 0, ufp = 0, dp = 0, usb_ss = 0;
        union extcon_property_value property;
 
        if (chip->notify.is_cc_connected)
@@ -159,13 +160,17 @@ static void platform_fusb_notify(struct fusb30x_chip *chip)
                       (chip->notify.orientation - 1) : 0;
                dp = chip->notify.is_enter_mode;
 
-               if (dp)
-                       dfp = (chip->notify.pin_assignment_def &
+               if (dp) {
+                       dfp = 1;
+                       usb_ss = (chip->notify.pin_assignment_def &
                                (PIN_MAP_B | PIN_MAP_D | PIN_MAP_F)) ? 1 : 0;
-               else if (chip->notify.data_role)
+               } else if (chip->notify.data_role) {
                        dfp = 1;
-               else if (plugged)
+                       usb_ss = 1;
+               } else if (plugged) {
                        ufp = 1;
+                       usb_ss = 1;
+               }
 
                property.intval = flip;
                extcon_set_property(chip->extcon, EXTCON_USB,
@@ -174,6 +179,14 @@ static void platform_fusb_notify(struct fusb30x_chip *chip)
                                    EXTCON_PROP_USB_TYPEC_POLARITY, property);
                extcon_set_property(chip->extcon, EXTCON_DISP_DP,
                                    EXTCON_PROP_USB_TYPEC_POLARITY, property);
+
+               property.intval = usb_ss;
+               extcon_set_property(chip->extcon, EXTCON_USB,
+                                   EXTCON_PROP_USB_SS, property);
+               extcon_set_property(chip->extcon, EXTCON_USB_HOST,
+                                   EXTCON_PROP_USB_SS, property);
+               extcon_set_property(chip->extcon, EXTCON_DISP_DP,
+                                   EXTCON_PROP_USB_SS, property);
                extcon_set_state(chip->extcon, EXTCON_USB, ufp);
                extcon_set_state(chip->extcon, EXTCON_USB_HOST, dfp);
                extcon_set_state(chip->extcon, EXTCON_DISP_DP, dp);
@@ -199,8 +212,15 @@ static void fusb_timer_start(struct hrtimer *timer, int ms)
 static void platform_set_vbus_lvl_enable(struct fusb30x_chip *chip, int vbus_5v,
                                         int vbus_other)
 {
-       if (chip->gpio_vbus_5v)
+       if (chip->gpio_vbus_5v) {
                gpiod_set_raw_value(chip->gpio_vbus_5v, vbus_5v);
+               /* Only set state here, don't sync notifier to PMIC */
+               extcon_set_state(chip->extcon, EXTCON_USB_VBUS_EN, vbus_5v);
+       } else {
+               extcon_set_state(chip->extcon, EXTCON_USB_VBUS_EN, vbus_5v);
+               extcon_sync(chip->extcon, EXTCON_USB_VBUS_EN);
+               dev_info(chip->dev, "fusb302 send extcon to enable vbus 5v\n");
+       }
 
        if (chip->gpio_vbus_other)
                gpiod_set_raw_value(chip->gpio_vbus_5v, vbus_other);
@@ -1305,7 +1325,6 @@ static void fusb_state_attach_wait_source(struct fusb30x_chip *chip, int evt)
 static void fusb_state_attached_source(struct fusb30x_chip *chip, int evt)
 {
        tcpm_set_polarity(chip, !(chip->cc_state & 0x01));
-       extcon_set_state(chip->extcon, EXTCON_USB_HOST, 1);
        platform_set_vbus_lvl_enable(chip, 1, 0);
        tcpm_set_vconn(chip, 1);
 
@@ -2273,6 +2292,33 @@ static int fusb30x_probe(struct i2c_client *client,
                return ret;
        }
 
+       ret = extcon_set_property_capability(chip->extcon, EXTCON_USB,
+                                            EXTCON_PROP_USB_SS);
+       if (ret) {
+               dev_err(&client->dev,
+                       "failed to set USB USB_SS property capability: %d\n",
+                       ret);
+               return ret;
+       }
+
+       ret = extcon_set_property_capability(chip->extcon, EXTCON_USB_HOST,
+                                            EXTCON_PROP_USB_SS);
+       if (ret) {
+               dev_err(&client->dev,
+                       "failed to set USB_HOST USB_SS property capability: %d\n",
+                       ret);
+               return ret;
+       }
+
+       ret = extcon_set_property_capability(chip->extcon, EXTCON_DISP_DP,
+                                            EXTCON_PROP_USB_SS);
+       if (ret) {
+               dev_err(&client->dev,
+                       "failed to set DISP_DP USB_SS property capability: %d\n",
+                       ret);
+               return ret;
+       }
+
        i2c_set_clientdata(client, chip);
 
        spin_lock_init(&chip->irq_lock);