summaryrefslogtreecommitdiff
path: root/drivers/usb/pd
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-01-18 23:48:47 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-01-18 23:48:46 -0800
commitdd7b46d3f41f9331f073b4890ac69fbd51b2aef0 (patch)
tree64bfe6406619696c487a2d3f0f8efba8dd3a681c /drivers/usb/pd
parente12c25b9a5e4e09a731eeb9018eb6c0bb0b5b7b3 (diff)
parentd1a0cb9fa585fb4f4a6b49615f9239a570538243 (diff)
Merge "usb: pd: Re-enable SuperSpeed host by default"
Diffstat (limited to 'drivers/usb/pd')
-rw-r--r--drivers/usb/pd/policy_engine.c124
1 files changed, 62 insertions, 62 deletions
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index dfc63b47ae81..f8f79fcd4732 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -256,12 +256,6 @@ static void *usbpd_ipc_log;
static int min_sink_current = 900;
module_param(min_sink_current, int, S_IRUSR | S_IWUSR);
-static bool ss_host;
-module_param(ss_host, bool, S_IRUSR | S_IWUSR);
-
-static bool ss_dev = true;
-module_param(ss_dev, bool, S_IRUSR | S_IWUSR);
-
static const u32 default_src_caps[] = { 0x36019096 }; /* VSafe5V @ 1.5A */
static const u32 default_snk_caps[] = { 0x2601905A }; /* 5V @ 900mA */
@@ -375,20 +369,34 @@ enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd)
}
EXPORT_SYMBOL(usbpd_get_plug_orientation);
-static bool is_cable_flipped(struct usbpd *pd)
+static inline void stop_usb_host(struct usbpd *pd)
+{
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0);
+}
+
+static inline void start_usb_host(struct usbpd *pd, bool ss)
{
- enum plug_orientation cc;
+ enum plug_orientation cc = usbpd_get_plug_orientation(pd);
- cc = usbpd_get_plug_orientation(pd);
- if (cc == ORIENTATION_CC2)
- return true;
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
+ cc == ORIENTATION_CC2);
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, ss);
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 1);
+}
- /*
- * ORIENTATION_CC1 or ORIENTATION_NONE.
- * Return value for ORIENTATION_NONE is
- * "dont care" as disconnect handles it.
- */
- return false;
+static inline void stop_usb_peripheral(struct usbpd *pd)
+{
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB, 0);
+}
+
+static inline void start_usb_peripheral(struct usbpd *pd)
+{
+ enum plug_orientation cc = usbpd_get_plug_orientation(pd);
+
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
+ cc == ORIENTATION_CC2);
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, 1);
+ extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1);
}
static int set_power_role(struct usbpd *pd, enum power_role pr)
@@ -774,17 +782,12 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
case PE_SRC_READY:
pd->in_explicit_contract = true;
if (pd->current_dr == DR_DFP) {
+ /* don't start USB host until after SVDM discovery */
if (pd->vdm_state == VDM_NONE)
usbpd_send_svdm(pd, USBPD_SID,
USBPD_SVDM_DISCOVER_IDENTITY,
SVDM_CMD_TYPE_INITIATOR, 0,
NULL, 0);
-
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
- is_cable_flipped(pd));
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED,
- ss_host);
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 1);
}
kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
@@ -820,15 +823,8 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
pd->current_dr = DR_UFP;
if (pd->psy_type == POWER_SUPPLY_TYPE_USB ||
- pd->psy_type == POWER_SUPPLY_TYPE_USB_CDP) {
- extcon_set_cable_state_(pd->extcon,
- EXTCON_USB_CC,
- is_cable_flipped(pd));
- extcon_set_cable_state_(pd->extcon,
- EXTCON_USB_SPEED, ss_dev);
- extcon_set_cable_state_(pd->extcon,
- EXTCON_USB, 1);
- }
+ pd->psy_type == POWER_SUPPLY_TYPE_USB_CDP)
+ start_usb_peripheral(pd);
}
dual_role_instance_changed(pd->dual_role);
@@ -928,14 +924,9 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
case PE_SNK_TRANSITION_TO_DEFAULT:
if (pd->current_dr != DR_UFP) {
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0);
-
+ stop_usb_host(pd);
+ start_usb_peripheral(pd);
pd->current_dr = DR_UFP;
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
- is_cable_flipped(pd));
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED,
- ss_dev);
- extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1);
pd_phy_update_roles(pd->current_dr, pd->current_pr);
}
if (pd->vconn_enabled) {
@@ -1061,6 +1052,7 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)
u8 i, num_vdos = rx_msg->len - 1; /* num objects minus header */
u8 cmd = SVDM_HDR_CMD(vdm_hdr);
u8 cmd_type = SVDM_HDR_CMD_TYPE(vdm_hdr);
+ bool has_dp = false;
struct usbpd_svid_handler *handler;
usbpd_dbg(&pd->dev, "VDM rx: svid:%x cmd:%x cmd_type:%x vdm_hdr:%x\n",
@@ -1210,8 +1202,18 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)
handler->discovered = true;
}
}
+
+ if (svid == 0xFF01)
+ has_dp = true;
}
+ /*
+ * Finally start USB host now that we have determined
+ * if DisplayPort mode is present or not and limit USB
+ * to HS-only mode if so.
+ */
+ start_usb_host(pd, !has_dp);
+
break;
default:
@@ -1224,6 +1226,16 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)
case SVDM_CMD_TYPE_RESP_NAK:
usbpd_info(&pd->dev, "VDM NAK received for SVID:0x%04x command:0x%x\n",
svid, cmd);
+
+ switch (cmd) {
+ case USBPD_SVDM_DISCOVER_IDENTITY:
+ case USBPD_SVDM_DISCOVER_SVIDS:
+ start_usb_host(pd, true);
+ break;
+ default:
+ break;
+ }
+
break;
case SVDM_CMD_TYPE_RESP_BUSY:
@@ -1325,26 +1337,19 @@ static void reset_vdm_state(struct usbpd *pd)
static void dr_swap(struct usbpd *pd)
{
+ reset_vdm_state(pd);
+
if (pd->current_dr == DR_DFP) {
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0);
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
- is_cable_flipped(pd));
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, ss_dev);
- extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1);
+ stop_usb_host(pd);
+ start_usb_peripheral(pd);
pd->current_dr = DR_UFP;
} else if (pd->current_dr == DR_UFP) {
- extcon_set_cable_state_(pd->extcon, EXTCON_USB, 0);
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
- is_cable_flipped(pd));
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, ss_host);
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 1);
+ stop_usb_peripheral(pd);
pd->current_dr = DR_DFP;
- if (pd->vdm_state == VDM_NONE)
- usbpd_send_svdm(pd, USBPD_SID,
- USBPD_SVDM_DISCOVER_IDENTITY,
- SVDM_CMD_TYPE_INITIATOR, 0,
- NULL, 0);
+ /* don't start USB host until after SVDM discovery */
+ usbpd_send_svdm(pd, USBPD_SID, USBPD_SVDM_DISCOVER_IDENTITY,
+ SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
}
pd_phy_update_roles(pd->current_dr, pd->current_pr);
@@ -1466,9 +1471,9 @@ static void usbpd_sm(struct work_struct *w)
}
if (pd->current_dr == DR_UFP)
- extcon_set_cable_state_(pd->extcon, EXTCON_USB, 0);
+ stop_usb_peripheral(pd);
else if (pd->current_dr == DR_DFP)
- extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0);
+ stop_usb_host(pd);
pd->current_pr = PR_NONE;
pd->current_dr = DR_NONE;
@@ -1568,12 +1573,7 @@ static void usbpd_sm(struct work_struct *w)
if (pd->caps_count == 5 && pd->current_dr == DR_DFP) {
/* Likely not PD-capable, start host now */
- extcon_set_cable_state_(pd->extcon,
- EXTCON_USB_CC, is_cable_flipped(pd));
- extcon_set_cable_state_(pd->extcon,
- EXTCON_USB_SPEED, ss_host);
- extcon_set_cable_state_(pd->extcon,
- EXTCON_USB_HOST, 1);
+ start_usb_host(pd, true);
} else if (pd->caps_count >= PD_CAPS_COUNT) {
usbpd_dbg(&pd->dev, "Src CapsCounter exceeded, disabling PD\n");
usbpd_set_state(pd, PE_SRC_DISABLED);