diff options
| author | Hemant Kumar <hemantk@codeaurora.org> | 2017-05-30 15:54:55 -0700 |
|---|---|---|
| committer | Hemant Kumar <hemantk@codeaurora.org> | 2017-06-01 13:51:13 -0700 |
| commit | 6577867741e343ba3df76112245c28385685f8cf (patch) | |
| tree | a5d9461f155bdd692d8ae761aeb8597887d921b8 | |
| parent | 840d1a232cfd67867a61a31ccc5d81c5c2192474 (diff) | |
usb: pd: policy_engine: Handle spec revision properly
As per USB PD 3.0 specification the 2-bit Specification Revision field
of a GoodCRC Message does not carry any meaning and Shall be considered
as don't care by the recipient of the Message. Hence set spec revision
to USBPD_REV_20 for GoodCRC message. PD protocol message header defaults
to USBPD_REV_20 which gets updated USBPD_REV_30 if PD 3.0 source capabale
of programmable power supply.
Change-Id: I5209bb00c437f3c959d093a972f1ac75233cbcf9
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
| -rw-r--r-- | drivers/usb/pd/policy_engine.c | 34 | ||||
| -rw-r--r-- | drivers/usb/pd/qpnp-pdphy.c | 13 | ||||
| -rw-r--r-- | drivers/usb/pd/usbpd.h | 7 |
3 files changed, 16 insertions, 38 deletions
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index 7bfadccf0e47..d46e21bd2c68 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -187,6 +187,8 @@ static void *usbpd_ipc_log; #define PD_MAX_MSG_ID 7 +#define PD_MAX_DATA_OBJ 7 + #define PD_MSG_HDR(type, dr, pr, id, cnt, rev) \ (((type) & 0xF) | ((dr) << 5) | (rev << 6) | \ ((pr) << 8) | ((id) << 9) | ((cnt) << 12)) @@ -308,7 +310,7 @@ struct usbpd { struct list_head rx_q; spinlock_t rx_lock; - u32 received_pdos[7]; + u32 received_pdos[PD_MAX_DATA_OBJ]; u16 src_cap_id; u8 selected_pdo; u8 requested_pdo; @@ -547,6 +549,7 @@ static int pd_select_pdo(struct usbpd *pd, int pdo_pos, int uv, int ua) static int pd_eval_src_caps(struct usbpd *pd) { + int obj_cnt; union power_supply_propval val; u32 first_pdo = pd->received_pdos[0]; @@ -563,6 +566,13 @@ static int pd_eval_src_caps(struct usbpd *pd) power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED, &val); + for (obj_cnt = 1; obj_cnt < PD_MAX_DATA_OBJ; obj_cnt++) { + if ((PD_SRC_PDO_TYPE(pd->received_pdos[obj_cnt]) == + PD_SRC_PDO_TYPE_AUGMENTED) && + !PD_APDO_PPS(pd->received_pdos[obj_cnt])) + pd->spec_rev = USBPD_REV_30; + } + /* Select the first PDO (vSafe5V) immediately. */ pd_select_pdo(pd, 1, 0, 0); @@ -653,12 +663,6 @@ static void phy_msg_received(struct usbpd *pd, enum pd_msg_type type, return; } - /* if spec rev differs (i.e. is older), update PHY */ - if (PD_MSG_HDR_REV(header) < pd->spec_rev) { - pd->spec_rev = PD_MSG_HDR_REV(header); - pd_phy_update_spec_rev(pd->spec_rev); - } - rx_msg = kzalloc(sizeof(*rx_msg), GFP_KERNEL); if (!rx_msg) return; @@ -701,7 +705,6 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) .shutdown_cb = phy_shutdown, .frame_filter_val = FRAME_FILTER_EN_SOP | FRAME_FILTER_EN_HARD_RESET, - .spec_rev = USBPD_REV_20, }; union power_supply_propval val = {0}; unsigned long flags; @@ -748,8 +751,6 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &val); - /* support only PD 2.0 as a source */ - pd->spec_rev = USBPD_REV_20; pd_reset_protocol(pd); if (!pd->in_pr_swap) { @@ -760,7 +761,6 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) phy_params.data_role = pd->current_dr; phy_params.power_role = pd->current_pr; - phy_params.spec_rev = pd->spec_rev; ret = pd_phy_open(&phy_params); if (ret) { @@ -772,8 +772,6 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) } pd->pd_phy_opened = true; - } else { - pd_phy_update_spec_rev(pd->spec_rev); } pd->current_state = PE_SRC_SEND_CAPABILITIES; @@ -909,11 +907,6 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) if (!val.intval) break; - /* - * support up to PD 3.0 as a sink; if source is 2.0, - * phy_msg_received() will handle the downgrade. - */ - pd->spec_rev = USBPD_REV_30; pd_reset_protocol(pd); if (!pd->in_pr_swap) { @@ -924,7 +917,6 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) phy_params.data_role = pd->current_dr; phy_params.power_role = pd->current_pr; - phy_params.spec_rev = pd->spec_rev; ret = pd_phy_open(&phy_params); if (ret) { @@ -936,8 +928,6 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) } pd->pd_phy_opened = true; - } else { - pd_phy_update_spec_rev(pd->spec_rev); } pd->current_voltage = pd->requested_voltage = 5000000; @@ -3314,6 +3304,8 @@ struct usbpd *usbpd_create(struct device *parent) pd->dual_role->drv_data = pd; } + /* default support as PD 2.0 source or sink */ + pd->spec_rev = USBPD_REV_20; pd->current_pr = PR_NONE; pd->current_dr = DR_NONE; list_add_tail(&pd->instance, &_usbpd); diff --git a/drivers/usb/pd/qpnp-pdphy.c b/drivers/usb/pd/qpnp-pdphy.c index 588af94db6cd..fa3b71d6ce08 100644 --- a/drivers/usb/pd/qpnp-pdphy.c +++ b/drivers/usb/pd/qpnp-pdphy.c @@ -334,15 +334,6 @@ int pd_phy_update_roles(enum data_role dr, enum power_role pr) } EXPORT_SYMBOL(pd_phy_update_roles); -int pd_phy_update_spec_rev(enum pd_spec_rev rev) -{ - struct usb_pdphy *pdphy = __pdphy; - - return pdphy_masked_write(pdphy, USB_PDPHY_MSG_CONFIG, - MSG_CONFIG_SPEC_REV_MASK, rev); -} -EXPORT_SYMBOL(pd_phy_update_spec_rev); - int pd_phy_open(struct pd_phy_params *params) { int ret; @@ -377,7 +368,9 @@ int pd_phy_open(struct pd_phy_params *params) if (ret) return ret; - ret = pd_phy_update_spec_rev(params->spec_rev); + /* PD 2.0 phy */ + ret = pdphy_masked_write(pdphy, USB_PDPHY_MSG_CONFIG, + MSG_CONFIG_SPEC_REV_MASK, USBPD_REV_20); if (ret) return ret; diff --git a/drivers/usb/pd/usbpd.h b/drivers/usb/pd/usbpd.h index b2663add7f3c..108701739f89 100644 --- a/drivers/usb/pd/usbpd.h +++ b/drivers/usb/pd/usbpd.h @@ -68,7 +68,6 @@ struct pd_phy_params { enum data_role data_role; enum power_role power_role; u8 frame_filter_val; - u8 spec_rev; }; #if IS_ENABLED(CONFIG_QPNP_USB_PDPHY) @@ -77,7 +76,6 @@ int pd_phy_signal(enum pd_sig_type type, unsigned int timeout_ms); int pd_phy_write(u16 hdr, const u8 *data, size_t data_len, enum pd_msg_type type, unsigned int timeout_ms); int pd_phy_update_roles(enum data_role dr, enum power_role pr); -int pd_phy_update_spec_rev(enum pd_spec_rev rev); void pd_phy_close(void); #else static inline int pd_phy_open(struct pd_phy_params *params) @@ -101,11 +99,6 @@ static inline int pd_phy_update_roles(enum data_role dr, enum power_role pr) return -ENODEV; } -static inline int pd_phy_update_spec_rev(enum pd_spec_rev rev) -{ - return -ENODEV; -} - static inline void pd_phy_close(void) { } |
