From 1c37a3a2d175f4e2af54ad568c3bee3727ff93e7 Mon Sep 17 00:00:00 2001 From: Lei Chen Date: Mon, 28 Oct 2024 15:55:46 +0800 Subject: [PATCH] bangkk: en62680 PD test PROPAGATED_from (CR) main changes: add several protocol related interface to pass cases such as TEST.PD.PROT.ALL.01 Corrupted GoodCRC TEST.PD.PROT.ALL.04 Reset Signals and MessageID TEST.PD.PROT.ALL3.08 Get Revision Response TEST.PD.PROT.PORT3.01 Get_Battery_Status Response TEST.PD.PROT.PORT3.02 Invalid Battery Status Reference TEST.PD.PROT.PORT3.03 Get_Battery_Cap Response TEST.PD.PROT.PORT3.04 Invalid Battery Capabilities Reference TEST.PD.PROT.SRC.03 SenderResponseTimer Deadline TEST.PD.PROT.SNK.12 PR_Swap - PSSourceOffTimer Timeout TEST.PD.PROT.SNK.13 PR_Swap - Request SenderResponseTimer Timeout TEST.PD.VDM.SRC.01 Discovery Process and Enter Mode TEST.PD.VDM.SRC.02 Invalid Fields - Discover Identity TEST.PD.VDM.SNK.06 Structured VDM Revision Number Test TEST.PD.PS.SRC.01 Multiple Request Load Test TEST.PD.PS.SNK.03 Multiple Request Load Test Post PR Swap Change-Id: I0d5df498d1b9d42080eaac9c9b8297c31a120938 Signed-off-by: Lei Chen Reviewed-on: https://gerrit.mot.com/3126980 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Zonghua Liu Reviewed-by: Wei Xu Reviewed-by: Xiangpo Zhao Submit-Approved: Jira Key Reviewed-on: https://gerrit.mot.com/3239424 Reviewed-by: Bruno Oliveira Reviewed-by: Deise Alves Submit-Approved: Deise Alves --- .../vendor/ext_config/moto-holi-bangkk.config | 2 + drivers/power/supply/qcom/Kconfig | 8 + drivers/power/supply/qcom/smb5-lib.c | 8 +- drivers/usb/pd/Kconfig | 6 + drivers/usb/pd/policy_engine.c | 161 +++++++++++++++--- 5 files changed, 162 insertions(+), 23 deletions(-) diff --git a/arch/arm64/configs/vendor/ext_config/moto-holi-bangkk.config b/arch/arm64/configs/vendor/ext_config/moto-holi-bangkk.config index 291714d8e2bf..3f2c667298a3 100644 --- a/arch/arm64/configs/vendor/ext_config/moto-holi-bangkk.config +++ b/arch/arm64/configs/vendor/ext_config/moto-holi-bangkk.config @@ -42,6 +42,8 @@ CONFIG_EROFS_FS_PCPU_KTHREAD=y CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI=y CONFIG_MOT_SENSOR_PRE_POWERUP=y CONFIG_MMAP_READAROUND_LIMIT=y +CONFIG_MOT_SET_SRC_CAP_5V1A=y +CONFIG_MOT_SET_OTG_VOL_5V5=y # Camera CONFIG_CAMERA_CCI_INTF=m diff --git a/drivers/power/supply/qcom/Kconfig b/drivers/power/supply/qcom/Kconfig index 73835d078caa..43e17629885c 100644 --- a/drivers/power/supply/qcom/Kconfig +++ b/drivers/power/supply/qcom/Kconfig @@ -113,4 +113,12 @@ config QTI_QBG To compile this driver as a module, choose M here: the module will be called qti-qbg-main. + +config MOT_SET_OTG_VOL_5V5 + bool "Set OTG VOLTAGE TO 5V5" + default n + help + Say Y to set otg output voltage 5.5V. It will ensure the EU PD cetification + case Multiple Request Load Test Post PR Swap can test PASS. + endif diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c index 18a57d322832..ce1b16d37b34 100644 --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -2024,7 +2024,13 @@ int smblib_vbus_regulator_enable(struct regulator_dev *rdev) smblib_err(chg, "Couldn't enable OTG rc=%d\n", rc); return rc; } - +#ifdef CONFIG_MOT_SET_OTG_VOL_5V5 + rc = smblib_masked_write(chg, 0x1186, GENMASK(2,0), 0x07); + if (rc < 0) { + smblib_err(chg, "Couldn't enable OTG boost rc=%d\n", rc); + return rc; + } +#endif return 0; } diff --git a/drivers/usb/pd/Kconfig b/drivers/usb/pd/Kconfig index 09f8a7c7a4ea..582a3e6ee53f 100644 --- a/drivers/usb/pd/Kconfig +++ b/drivers/usb/pd/Kconfig @@ -29,4 +29,10 @@ config QPNP_USB_PDPHY The is used to handle the PHY layer communication of the Power Delivery stack. +config MOT_SET_SRC_CAP_5V1A + bool "Set PD source capabilty 5V1A" + default n + help + Say Y to select the src caps 5V1A. It should match with the OTG max + max current. endmenu diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index eb84b4e2a1ae..6c7d90d80520 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -119,6 +119,9 @@ enum usbpd_control_msg_type { MSG_FR_SWAP, MSG_GET_PPS_STATUS, MSG_GET_COUNTRY_CODES, + MSG_CTRL_GET_SINK_CAP_EXTENDED, + MSG_CTRL_GET_SOURCE_INFO, + MSG_CTRL_GET_REVISION, }; static const char * const usbpd_control_msg_strings[] = { @@ -137,6 +140,7 @@ enum usbpd_data_msg_type { MSG_BATTERY_STATUS, MSG_ALERT, MSG_GET_COUNTRY_INFO, + MSG_GET_REVISION=0xC, MSG_VDM = 0xF, }; @@ -161,6 +165,8 @@ enum usbpd_ext_msg_type { MSG_PPS_STATUS, MSG_COUNTRY_INFO, MSG_COUNTRY_CODES, + MSG_GET_SINK_CAP_EXTENDED, + MSG_GET_SOURCE_INFO, }; static const char * const usbpd_ext_msg_strings[] = { @@ -249,16 +255,16 @@ static void *usbpd_ipc_log; /* Timeouts (in ms) */ #define ERROR_RECOVERY_TIME 25 -#define SENDER_RESPONSE_TIME 26 +#define SENDER_RESPONSE_TIME 28 #define SINK_WAIT_CAP_TIME 500 -#define PS_TRANSITION_TIME 450 +#define PS_TRANSITION_TIME 455 #define SRC_CAP_TIME 120 #define SRC_TRANSITION_TIME 25 #define SRC_RECOVER_TIME 750 #define PS_HARD_RESET_TIME 25 #define PS_SOURCE_ON 400 -#define PS_SOURCE_OFF 750 -#define FIRST_SOURCE_CAP_TIME 100 +#define PS_SOURCE_OFF 760 +#define FIRST_SOURCE_CAP_TIME 120 #define VDM_BUSY_TIME 50 #define VCONN_ON_TIME 100 #define SINK_TX_TIME 16 @@ -361,8 +367,8 @@ static void *usbpd_ipc_log; #define SVDM_HDR_CMD(hdr) ((hdr) & 0x1f) #define SVDM_HDR(svid, ver, obj, cmd_type, cmd) \ - (((svid) << 16) | (1 << 15) | ((ver) << 13) \ - | ((obj) << 8) | ((cmd_type) << 6) | (cmd)) +((ver==1)?(((svid)<<16)|(1<<15)|((ver)<<13)|(1<<11) |((obj )<<8)|((cmd_type)<<6)|(cmd)) :\ +(((svid)<<16)|(1<<15)|((ver)<<13) | ((obj )<<8)|((cmd_type)<<6)|(cmd))) /* discover id response vdo bit fields */ #define ID_HDR_USB_HOST BIT(31) @@ -377,7 +383,11 @@ static void *usbpd_ipc_log; #define PD_MIN_SINK_CURRENT 900 +#ifdef CONFIG_MOT_SET_SRC_CAP_5V1A +static const u32 default_src_caps[] = { 0x36019064 }; /* VSafe5V @ 1A */ +#else static const u32 default_src_caps[] = { 0x36019096 }; /* VSafe5V @ 1.5A */ +#endif static const u32 default_snk_caps[] = { 0x2601912C }; /* VSafe5V @ 3A */ struct vdm_tx { @@ -769,7 +779,7 @@ static int pd_send_msg(struct usbpd *pd, u8 msg_type, const u32 *data, /* bail out and try again later if a message just arrived */ spin_lock_irqsave(&pd->rx_lock, flags); - if (!list_empty(&pd->rx_q)) { + if (!list_empty(&pd->rx_q) && (msg_type != MSG_SOFT_RESET)) { spin_unlock_irqrestore(&pd->rx_lock, flags); usbpd_dbg(&pd->dev, "Abort send due to pending RX\n"); return -EBUSY; @@ -857,7 +867,6 @@ static int pd_select_pdo(struct usbpd *pd, int pdo_pos, int uv, int ua) type = PD_SRC_PDO_TYPE(pdo); if (type == PD_SRC_PDO_TYPE_FIXED) { curr = max_current = PD_SRC_PDO_FIXED_MAX_CURR(pdo) * 10; - /* * Check if the PDO has enough current, otherwise set the * Capability Mismatch flag @@ -1655,12 +1664,11 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) /* Standard Discovery or unhandled messages go here */ switch (cmd_type) { case SVDM_CMD_TYPE_INITIATOR: - if (cmd != USBPD_SVDM_ATTENTION) { - if (pd->spec_rev == USBPD_REV_30) { - ret = pd_send_msg(pd, MSG_NOT_SUPPORTED, NULL, - 0, SOP_MSG); - if (ret) - usbpd_set_state(pd, PE_SEND_SOFT_RESET); + { + if (!pd->has_dp || (cmd != USBPD_SVDM_ATTENTION)) { + usbpd_send_svdm(pd, svid, cmd, + SVDM_CMD_TYPE_RESP_NAK, 0, NULL, 0); + return; /*NAK to dis*/ } } break; @@ -1830,7 +1838,7 @@ static void handle_get_src_cap_extended(struct usbpd *pd) u8 pdp; } __packed caps = {0}; - caps.vid = 0x5c6; + caps.vid = 0x22b8; caps.num_batt = 1; caps.pdp = 5 * PD_SRC_PDO_FIXED_MAX_CURR(default_src_caps[0]) / 100; @@ -1839,6 +1847,86 @@ static void handle_get_src_cap_extended(struct usbpd *pd) if (ret) usbpd_set_state(pd, PE_SEND_SOFT_RESET); } +static void handle_get_source_info(struct usbpd *pd){ + int ret; + union { + unsigned long AsUINT32; + struct { + unsigned long PortReportedPDP :8; + unsigned long PortPresentPDP :8; + unsigned long PortMaximumPDP :8; + unsigned long :7; + unsigned long PortType :1; + }; + } __packed caps = {0}; + caps.PortType =1; + caps.PortMaximumPDP =15; + caps.PortReportedPDP =10; + caps.PortPresentPDP =10; + + ret = pd_send_ext_msg(pd, MSG_GET_SOURCE_INFO, (u8 *)&caps.AsUINT32, + sizeof(caps), SOP_MSG); + if (ret) + usbpd_set_state(pd, PE_SEND_SOFT_RESET); +} +static void handle_get_revision(struct usbpd *pd){ + int ret; + u32 caps =0x31170000; + + ret = pd_send_msg(pd, MSG_GET_REVISION, &caps, + 1, SOP_MSG); + if (ret) + usbpd_set_state(pd, PE_SEND_SOFT_RESET); +} +static void handle_get_sink_cap_extended(struct usbpd *pd) +{ + int ret; + struct { + u16 vid; /*size:2*/ + u16 pid; /*size:2*/ + u32 xid; /*size:4*/ + u8 fw_version; /*size:1*/ + u8 hw_version; /*size:1*/ + u8 SKEDBVersion; /*size:1*/ + u8 LoadStep; /*size:1*/ + u16 SinkLoadCharacteristics; /*size:2*/ + u8 Compliance; /*size:1*/ + u8 TouchTemp; /*size:1*/ + u8 BatteryInfo; /*size:1*/ + u8 SinkModes; /*size:1*/ + u8 SinkMinimumPDP; /*size:1*/ + u8 SinkOperationalPDP; /*size:1*/ + u8 SinkMaximumPDP; /*size:1*/ + u8 EPRSinkMinimumPDP; /*size:1*/ + u8 EPRSinkOperationalPDP; /*size:1*/ + u8 EPRSinkMaximumPDP; /*size:1*/ + } __packed caps = {0}; + + caps.vid = 0x22b8; + caps.pid = 1; + caps.xid = 0; + caps.fw_version = 0; + caps.hw_version=0x20; + caps.SKEDBVersion=0x1; + caps.LoadStep=0x0; + caps.SinkLoadCharacteristics=0x8000; + caps.Compliance=0x0; + caps.TouchTemp=0x1; + caps.BatteryInfo=0x1; + caps.SinkModes =0xA |0x01; + caps.SinkMinimumPDP=0x0; + caps.SinkOperationalPDP = 15; + caps.SinkMaximumPDP = 30; + caps.EPRSinkMinimumPDP =0x0; + caps.EPRSinkOperationalPDP =0x0; + caps.EPRSinkMaximumPDP =0x0; + + ret = pd_send_ext_msg(pd, MSG_GET_SINK_CAP_EXTENDED, (u8 *)&caps, + sizeof(caps), SOP_MSG); + if (ret) + usbpd_set_state(pd, PE_SEND_SOFT_RESET); + usbpd_warn(&pd->dev, "handle_get_sink_cap_extended \n"); +} static void handle_get_battery_cap(struct usbpd *pd, struct rx_msg *rx_msg) { @@ -1850,7 +1938,7 @@ static void handle_get_battery_cap(struct usbpd *pd, struct rx_msg *rx_msg) u16 capacity; u16 last_full; u8 type; - } __packed bcdb = {0, 0, 0xffff, 0xffff, 0}; + } __packed bcdb = { 0xffff, 0, 0, 0, 0}; if (rx_msg->data_len != 1) { usbpd_err(&pd->dev, "Invalid payload size: %d\n", @@ -1860,12 +1948,18 @@ static void handle_get_battery_cap(struct usbpd *pd, struct rx_msg *rx_msg) bat_num = rx_msg->payload[0]; - if (bat_num || !pd->bat_psy) { + if (bat_num) { usbpd_warn(&pd->dev, "Battery %d unsupported\n", bat_num); bcdb.type = BIT(0); /* invalid */ goto send; } - + bcdb.vid = 0x22b8; + bcdb.pid = 0x2e70; + if(!pd->bat_psy){ + bcdb.capacity =0x23; + bcdb.last_full=0xdb; + goto send; + } bcdb.capacity = ((pd->bat_charge_full / 1000) * (pd->bat_voltage_max / 1000)) / 100000; /* fix me */ @@ -1884,7 +1978,7 @@ static void handle_get_battery_status(struct usbpd *pd, struct rx_msg *rx_msg) int cap; union power_supply_propval val = {0}; u8 bat_num; - u32 bsdo = 0xffff0000; + u32 bsdo = 0x00000000; if (rx_msg->data_len != 1) { usbpd_err(&pd->dev, "Invalid payload size: %d\n", @@ -1892,14 +1986,19 @@ static void handle_get_battery_status(struct usbpd *pd, struct rx_msg *rx_msg) return; } - bat_num = rx_msg->payload[0]; + bat_num = rx_msg->payload[2]; - if (bat_num || !pd->bat_psy) { + if (bat_num) { usbpd_warn(&pd->dev, "Battery %d unsupported\n", bat_num); bsdo |= BIT(8); /* invalid */ goto send; } - + if (!pd->bat_psy) { + bsdo |= BIT(9); + if (PE_SRC_READY == pd->current_state) + bsdo |= (1 << 10); + goto send; + } ret = power_supply_get_property(pd->bat_psy, POWER_SUPPLY_PROP_PRESENT, &val); if (ret || !val.intval) @@ -2499,6 +2598,10 @@ static void handle_state_src_ready(struct usbpd *pd, struct rx_msg *rx_msg) usbpd_warn(&pd->dev, "Unexpected message\n"); usbpd_set_state(pd, PE_SEND_SOFT_RESET); return; + } else if (IS_CTRL(rx_msg, MSG_CTRL_GET_SOURCE_INFO)){ + handle_get_source_info(pd); + } else if (IS_CTRL(rx_msg, MSG_CTRL_GET_REVISION)) { + handle_get_revision(pd); } else if (rx_msg && !IS_CTRL(rx_msg, MSG_NOT_SUPPORTED)) { usbpd_dbg(&pd->dev, "Unsupported message\n"); ret = pd_send_msg(pd, pd->spec_rev == USBPD_REV_30 ? @@ -2728,6 +2831,10 @@ static void handle_state_snk_wait_for_capabilities(struct usbpd *pd, if (IS_DATA(rx_msg, MSG_SOURCE_CAPABILITIES)) { val.intval = 0; + if (!pd->vbus_present) { + usbpd_dbg(&pd->dev, "vbus not present yet, delay 50ms.\n"); + msleep(50); + } usbpd_set_psy_iio_property(pd, POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val); @@ -2954,6 +3061,12 @@ static bool handle_ctrl_snk_ready(struct usbpd *pd, struct rx_msg *rx_msg) case MSG_GET_SOURCE_CAP_EXTENDED: handle_get_src_cap_extended(pd); break; + case MSG_CTRL_GET_SINK_CAP_EXTENDED: + handle_get_sink_cap_extended(pd); + break; + case MSG_CTRL_GET_REVISION: + handle_get_revision(pd); + break; case MSG_ACCEPT: case MSG_REJECT: case MSG_WAIT: @@ -3242,6 +3355,10 @@ static void enter_state_prs_snk_src_transition_to_off(struct usbpd *pd) */ pd->pdphy_ops->update_roles(pd->current_dr, PR_SRC); + usbpd_dbg(&pd->dev, "enter_state_prs_snk_src_transition_to_off() set EXIT_SNK_BASED_ON_CC_BIT(0x1550 bit0)\n"); + val.intval = 1; + usbpd_set_psy_iio_property(pd, POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val); + /* wait for PS_RDY */ kick_sm(pd, PS_SOURCE_OFF); }