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

Commit 23c38c95 authored by Jack Pham's avatar Jack Pham
Browse files

usb: pd: Set PROP_PR_SWAP before forcing role



On newer PMICs forcing the current role prior to a PR Swap
causes the Type-C state machine to re-run. During this time
debounce is happening and PD PHY messages will fail to be
transmitted. This is remedied by first sending the Accept
message before setting PROP_PR_SWAP which temporarily reduces
debounce delay, so that then forcing role can happen in a
short time and not interfere with PD PHY operation.

While at it consolidate the handling of all of the above in the
PE_SRC_SNK_TRANSITION_TO_OFF and PE_SNK_SRC_TRANSITION_TO_OFF
cases in usbpd_set_state() to remove redundant code.

Change-Id: Id4d196d121a285cabedfff74aaa9768bb73595e4
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent a6100e9d
Loading
Loading
Loading
Loading
+21 −24
Original line number Original line Diff line number Diff line
@@ -1251,6 +1251,18 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
		dual_role_instance_changed(pd->dual_role);
		dual_role_instance_changed(pd->dual_role);
		break;
		break;


	case PE_PRS_SRC_SNK_TRANSITION_TO_OFF:
		val.intval = pd->in_pr_swap = true;
		power_supply_set_property(pd->usb_psy,
				POWER_SUPPLY_PROP_PR_SWAP, &val);
		pd->in_explicit_contract = false;

		/* lock in current mode */
		set_power_role(pd, pd->current_pr);

		kick_sm(pd, SRC_TRANSITION_TIME);
		break;

	case PE_SRC_HARD_RESET:
	case PE_SRC_HARD_RESET:
	case PE_SNK_HARD_RESET:
	case PE_SNK_HARD_RESET:
		/* are we still connected? */
		/* are we still connected? */
@@ -1414,6 +1426,13 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
		break;
		break;


	case PE_PRS_SNK_SRC_TRANSITION_TO_OFF:
	case PE_PRS_SNK_SRC_TRANSITION_TO_OFF:
		val.intval = pd->in_pr_swap = true;
		power_supply_set_property(pd->usb_psy,
				POWER_SUPPLY_PROP_PR_SWAP, &val);

		/* lock in current mode */
		set_power_role(pd, pd->current_pr);

		val.intval = pd->requested_current = 0; /* suspend charging */
		val.intval = pd->requested_current = 0; /* suspend charging */
		power_supply_set_property(pd->usb_psy,
		power_supply_set_property(pd->usb_psy,
				POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
				POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
@@ -2187,9 +2206,6 @@ static void usbpd_sm(struct work_struct *w)


			dr_swap(pd);
			dr_swap(pd);
		} else if (IS_CTRL(rx_msg, MSG_PR_SWAP)) {
		} else if (IS_CTRL(rx_msg, MSG_PR_SWAP)) {
			/* lock in current mode */
			set_power_role(pd, pd->current_pr);

			/* we'll happily accept Src->Sink requests anytime */
			/* we'll happily accept Src->Sink requests anytime */
			ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
			ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
			if (ret) {
			if (ret) {
@@ -2198,8 +2214,7 @@ static void usbpd_sm(struct work_struct *w)
				break;
				break;
			}
			}


			pd->current_state = PE_PRS_SRC_SNK_TRANSITION_TO_OFF;
			usbpd_set_state(pd, PE_PRS_SRC_SNK_TRANSITION_TO_OFF);
			kick_sm(pd, SRC_TRANSITION_TIME);
			break;
			break;
		} else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP)) {
		} else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP)) {
			ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
			ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
@@ -2478,9 +2493,6 @@ static void usbpd_sm(struct work_struct *w)
			dr_swap(pd);
			dr_swap(pd);
		} else if (IS_CTRL(rx_msg, MSG_PR_SWAP) &&
		} else if (IS_CTRL(rx_msg, MSG_PR_SWAP) &&
				pd->spec_rev == USBPD_REV_20) {
				pd->spec_rev == USBPD_REV_20) {
			/* lock in current mode */
			set_power_role(pd, pd->current_pr);

			/* TODO: should we Reject in certain circumstances? */
			/* TODO: should we Reject in certain circumstances? */
			ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
			ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
			if (ret) {
			if (ret) {
@@ -2489,10 +2501,6 @@ static void usbpd_sm(struct work_struct *w)
				break;
				break;
			}
			}


			pd->in_pr_swap = true;
			val.intval = 1;
			power_supply_set_property(pd->usb_psy,
					POWER_SUPPLY_PROP_PR_SWAP, &val);
			usbpd_set_state(pd, PE_PRS_SNK_SRC_TRANSITION_TO_OFF);
			usbpd_set_state(pd, PE_PRS_SNK_SRC_TRANSITION_TO_OFF);
			break;
			break;
		} else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP) &&
		} else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP) &&
@@ -2745,17 +2753,10 @@ static void usbpd_sm(struct work_struct *w)
			break;
			break;
		}
		}


		pd->current_state = PE_PRS_SRC_SNK_TRANSITION_TO_OFF;
		usbpd_set_state(pd, PE_PRS_SRC_SNK_TRANSITION_TO_OFF);
		kick_sm(pd, SRC_TRANSITION_TIME);
		break;
		break;


	case PE_PRS_SRC_SNK_TRANSITION_TO_OFF:
	case PE_PRS_SRC_SNK_TRANSITION_TO_OFF:
		pd->in_pr_swap = true;
		val.intval = 1;
		power_supply_set_property(pd->usb_psy,
				POWER_SUPPLY_PROP_PR_SWAP, &val);
		pd->in_explicit_contract = false;

		if (pd->vbus_enabled) {
		if (pd->vbus_enabled) {
			regulator_disable(pd->vbus);
			regulator_disable(pd->vbus);
			pd->vbus_enabled = false;
			pd->vbus_enabled = false;
@@ -2793,10 +2794,6 @@ static void usbpd_sm(struct work_struct *w)
			break;
			break;
		}
		}


		pd->in_pr_swap = true;
		val.intval = 1;
		power_supply_set_property(pd->usb_psy,
				POWER_SUPPLY_PROP_PR_SWAP, &val);
		usbpd_set_state(pd, PE_PRS_SNK_SRC_TRANSITION_TO_OFF);
		usbpd_set_state(pd, PE_PRS_SNK_SRC_TRANSITION_TO_OFF);
		break;
		break;