From cdb6ff52ea2b518216d8d4f185d9d8e95b77c09f Mon Sep 17 00:00:00 2001 From: mahj8 Date: Thu, 1 Oct 2020 16:38:26 +0800 Subject: [PATCH] pd-policy: Only select FIXED pdo in usbpd_select_pdo_match Current Moto PD controlling policy only applies to FIXED pdo but not programmable pdo(PPS), which requires periodic PD output power acknowledgement(at least 10s interval). So it has to redesign current Moto PD controlling policy to support PPS pdo selection. In order to avoid any PD controlling policy conflict with third party disable the PD controlling policy modification interfaces for user space (may be used by hvdcp_opti daemon in Qcom platform). pdo selection is only available in sink power role, so just return unsupported to tell the caller not try any more. refer to https://gerrit.mot.com/1461360 Change-Id: I675a1f21e6547b1e4e8af01c5f4ebe4a89972c41 Signed-off-by: mahj8 Reviewed-on: https://gerrit.mot.com/1770250 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Huosheng Liao Submit-Approved: Jira Key --- drivers/usb/pd/policy_engine.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index 53577aa7dd74..ae59318d30e0 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -4259,6 +4259,8 @@ int usbpd_select_pdo_match(struct usbpd *pd) int uv_diff = 0, max_uv_diff = 0, pdo = 0; int pdo_max_uv = 0, pdo_min_uv = 0, pdo_ua = 0; int uv_in, i; + int pdo_pos; + u8 type = -1; int ret; union power_supply_propval val; @@ -4267,6 +4269,12 @@ int usbpd_select_pdo_match(struct usbpd *pd) mutex_lock(&pd->swap_lock); + if (pd->current_pr == PR_SRC) { + usbpd_err(&pd->dev, "select_pdo: not support in source mode\n"); + ret = -ENOTSUPP; + goto out; + } + /* Only allowed if we are already in explicit sink contract */ if (pd->current_state != PE_SNK_READY || !is_sink_tx_ok(pd)) { usbpd_err(&pd->dev, "select_pdo: Cannot select new PDO yet\n"); @@ -4281,7 +4289,11 @@ int usbpd_select_pdo_match(struct usbpd *pd) /* start with 5 V */ max_uv_diff = 5000000; for (i = 1; i < 8; i++) { - if (!pd_get_pdo(pd, i, &pdo_max_uv, &pdo_min_uv, &pdo_ua)) { + pdo_pos = pd->received_pdos[i - 1]; + if (pdo_pos != 0) + type = PD_SRC_PDO_TYPE(pdo_pos); + if (type == PD_SRC_PDO_TYPE_FIXED && + pd_get_pdo(pd, i, &pdo_max_uv, &pdo_min_uv, &pdo_ua)) { if (pdo_max_uv <= uv_in) { uv_diff = uv_in - pdo_max_uv; if (uv_diff < max_uv_diff) { @@ -4294,7 +4306,7 @@ int usbpd_select_pdo_match(struct usbpd *pd) if (pdo < 1 || pdo > 7) { usbpd_err(&pd->dev, "select_pdo: invalid PDO:%d\n", pdo); - ret = -EINVAL; + ret = pd->current_voltage; goto out; } @@ -4334,6 +4346,7 @@ EXPORT_SYMBOL(usbpd_select_pdo_match); static ssize_t select_pdo_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { +#ifdef QCOM_BASE struct usbpd *pd = dev_get_drvdata(dev); int src_cap_id; int pdo, uv = 0, ua = 0; @@ -4395,6 +4408,9 @@ out: pd->send_request = false; mutex_unlock(&pd->swap_lock); return ret ? ret : size; +#else + return size; +#endif } static ssize_t select_pdo_show(struct device *dev,