Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb30afd5 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: pd: qpnp-pdphy: Fix reception of Get_Battery_Cap"

parents 0dafc364 7a838dde
Loading
Loading
Loading
Loading
+109 −51
Original line number Diff line number Diff line
@@ -233,6 +233,7 @@ static void *usbpd_ipc_log;
#define FIRST_SOURCE_CAP_TIME	100
#define VDM_BUSY_TIME		50
#define VCONN_ON_TIME		100
#define SINK_TX_TIME		16

/* tPSHardReset + tSafe0V */
#define SNK_HARD_RESET_VBUS_OFF_TIME	(35 + 650)
@@ -843,10 +844,6 @@ static int pd_eval_src_caps(struct usbpd *pd)
				break;
			}
		}

		/* downgrade to 2.0 if no PPS */
		if (!pps_found)
			pd->spec_rev = USBPD_REV_20;
	}

	val.intval = pps_found ?
@@ -1199,6 +1196,39 @@ static void log_decoded_request(struct usbpd *pd, u32 rdo)
	}
}

static bool in_src_ams(struct usbpd *pd)
{
	union power_supply_propval val = {0};

	if (pd->current_pr != PR_SRC)
		return false;

	if (pd->spec_rev != USBPD_REV_30)
		return true;

	power_supply_get_property(pd->usb_psy, POWER_SUPPLY_PROP_TYPEC_SRC_RP,
			&val);

	return val.intval == 1;
}

static void start_src_ams(struct usbpd *pd, bool ams)
{
	union power_supply_propval val = {0};

	if (pd->current_pr != PR_SRC || pd->spec_rev < USBPD_REV_30)
		return;

	usbpd_dbg(&pd->dev, "Set Rp to %s\n", ams ? "1.5A" : "3A");

	val.intval = ams ? 1 : 2; /* SinkTxNG / SinkTxOK */
	power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_TYPEC_SRC_RP,
			&val);

	if (ams)
		kick_sm(pd, SINK_TX_TIME);
}

int usbpd_register_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr)
{
	if (find_svid_handler(pd, hdlr->svid)) {
@@ -1510,11 +1540,26 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)

static void handle_vdm_tx(struct usbpd *pd, enum pd_sop_type sop_type)
{
	u32 vdm_hdr;
	int ret;

	if (!pd->vdm_tx)
		return;

	/* only send one VDM at a time */
	if (pd->vdm_tx) {
		u32 vdm_hdr = pd->vdm_tx->data[0];
	vdm_hdr = pd->vdm_tx->data[0];

	/*
	 * PD 3.0: For initiated SVDMs, source must first ensure Rp is set
	 * to SinkTxNG to indicate the start of an AMS
	 */
	if (VDM_IS_SVDM(vdm_hdr) &&
		SVDM_HDR_CMD_TYPE(vdm_hdr) == SVDM_CMD_TYPE_INITIATOR &&
		pd->current_pr == PR_SRC && !in_src_ams(pd)) {
		/* Set SinkTxNG and reschedule sm_work to send again */
		start_src_ams(pd, true);
		return;
	}

	ret = pd_send_msg(pd, MSG_VDM, pd->vdm_tx->data,
			pd->vdm_tx->size, sop_type);
@@ -1549,7 +1594,6 @@ static void handle_vdm_tx(struct usbpd *pd, enum pd_sop_type sop_type)

	pd->vdm_tx = NULL;
}
}

static void reset_vdm_state(struct usbpd *pd)
{
@@ -1785,6 +1829,12 @@ static int usbpd_startup_common(struct usbpd *pd,
	pd_reset_protocol(pd);

	if (!pd->in_pr_swap) {
		/*
		 * support up to PD 3.0; if peer is 2.0
		 * phy_msg_received() will handle the downgrade.
		 */
		pd->spec_rev = USBPD_REV_30;

		if (pd->pd_phy_opened) {
			pd_phy_close();
			pd->pd_phy_opened = false;
@@ -1830,14 +1880,15 @@ static void enter_state_src_startup(struct usbpd *pd)

	dual_role_instance_changed(pd->dual_role);

	val.intval = 1; /* Rp-1.5A; SinkTxNG for PD 3.0 */
	power_supply_set_property(pd->usb_psy,
			POWER_SUPPLY_PROP_TYPEC_SRC_RP, &val);

	/* Set CC back to DRP toggle for the next disconnect */
	val.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
	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;

	if (usbpd_startup_common(pd, &phy_params))
		return;

@@ -1897,6 +1948,12 @@ static void handle_state_src_startup_wait_for_vdm_resp(struct usbpd *pd,
	if (!rx_msg)
		ms -= SENDER_RESPONSE_TIME;

	/*
	 * Emarker may have negotiated down to rev 2.0.
	 * Reset to 3.0 to begin SOP communication with sink
	 */
	pd->spec_rev = USBPD_REV_30;

	pd->current_state = PE_SRC_SEND_CAPABILITIES;
	kick_sm(pd, ms);
}
@@ -2043,6 +2100,8 @@ static void enter_state_src_ready(struct usbpd *pd)
		usbpd_send_svdm(pd, USBPD_SID,
				USBPD_SVDM_DISCOVER_IDENTITY,
				SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
	else
		start_src_ams(pd, false);

	kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
	complete(&pd->is_ready);
@@ -2096,6 +2155,8 @@ static void handle_state_src_ready(struct usbpd *pd, struct rx_msg *rx_msg)
		}

		vconn_swap(pd);
		if (!pd->vdm_tx)
			start_src_ams(pd, false);
	} else if (IS_DATA(rx_msg, MSG_VDM)) {
		handle_vdm_rx(pd, rx_msg);
	} else if (rx_msg && pd->spec_rev == USBPD_REV_30) {
@@ -2125,8 +2186,10 @@ static void handle_state_src_ready(struct usbpd *pd, struct rx_msg *rx_msg)

		pd->current_state = PE_DRS_SEND_DR_SWAP;
		kick_sm(pd, SENDER_RESPONSE_TIME);
	} else {
	} else if (pd->vdm_tx) {
		handle_vdm_tx(pd, SOP_MSG);
	} else {
		start_src_ams(pd, false);
	}
}

@@ -2227,12 +2290,6 @@ static void enter_state_snk_startup(struct usbpd *pd)

	dual_role_instance_changed(pd->dual_role);

	/*
	 * 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;

	if (usbpd_startup_common(pd, &phy_params))
		return;

@@ -2488,8 +2545,7 @@ static void handle_ctrl_snk_ready(struct usbpd *pd, struct rx_msg *rx_msg)
				SOP_MSG);
		if (ret)
			usbpd_set_state(pd, PE_SEND_SOFT_RESET);
	} else if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP) &&
			pd->spec_rev == USBPD_REV_20) {
	} else if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP)) {
		ret = pd_send_msg(pd, MSG_SOURCE_CAPABILITIES,
				default_src_caps,
				ARRAY_SIZE(default_src_caps), SOP_MSG);
@@ -2510,8 +2566,7 @@ static void handle_ctrl_snk_ready(struct usbpd *pd, struct rx_msg *rx_msg)
		}

		dr_swap(pd);
	} else if (IS_CTRL(rx_msg, MSG_PR_SWAP) &&
			pd->spec_rev == USBPD_REV_20) {
	} else if (IS_CTRL(rx_msg, MSG_PR_SWAP)) {
		/* TODO: should we Reject in certain circumstances? */
		ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
		if (ret) {
@@ -2521,8 +2576,7 @@ static void handle_ctrl_snk_ready(struct usbpd *pd, struct rx_msg *rx_msg)

		usbpd_set_state(pd, PE_PRS_SNK_SRC_TRANSITION_TO_OFF);
		return;
	} else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP) &&
			pd->spec_rev == USBPD_REV_20) {
	} else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP)) {
		/*
		 * if VCONN is connected to VBUS, make sure we are
		 * not in high voltage contract, otherwise reject.
@@ -3494,6 +3548,10 @@ static int usbpd_do_swap(struct usbpd *pd, bool dr_swap,
		pd->send_dr_swap = true;
	else
		pd->send_pr_swap = true;

	if (pd->current_state == PE_SRC_READY && !in_src_ams(pd))
		start_src_ams(pd, true);
	else
		kick_sm(pd, 0);

	/* wait for operation to complete */
+1 −1
Original line number Diff line number Diff line
@@ -734,7 +734,7 @@ static irqreturn_t pdphy_msg_rx_irq(int irq, void *data)
	/* ack to change ownership of rx buffer back to PDPHY RX HW */
	pdphy_reg_write(pdphy, USB_PDPHY_RX_ACKNOWLEDGE, 0);

	if (((buf[0] & 0xf) == PD_MSG_BIST) && size >= 5) { /* BIST */
	if (((buf[0] & 0xf) == PD_MSG_BIST) && !(buf[1] & 0x80) && size >= 5) {
		u8 mode = buf[5] >> 4; /* [31:28] of 1st data object */

		pd_phy_bist_mode(mode);