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

Commit 42f765e7 authored by Jack Pham's avatar Jack Pham
Browse files

usb: pd: Handle APSD detection during initial connection



The charger driver recently updated to run APSD type detection
concurrently with initial PD communication. In the case of a
non-PD SDP source, the type detection will be completed as the
sink state machine is attempting to do a hard reset. Add a check
in SNK_STARTUP to determine if it is SDP/CDP and start the USB
peripheral stack then.

In the case a PD source is connected and the USB Communication
bit is set in the capabilities message, wait until after setting
PD_ACTIVE to the charger before starting the USB peripheral stack.
This ensures that the charger will be done using D+/D- for charger
detection and won't conflict with USB data signaling. In this
case the USB Communication capable bit supersedes the charger type
detection.

Change-Id: If068046e1ba959eb31ec2233159313e642442e00
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent 2c953bcd
Loading
Loading
Loading
Loading
+15 −5
Original line number Original line Diff line number Diff line
@@ -820,10 +820,6 @@ static int pd_eval_src_caps(struct usbpd *pd)
	power_supply_set_property(pd->usb_psy,
	power_supply_set_property(pd->usb_psy,
			POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED, &val);
			POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED, &val);


	/* First time connecting to a PD source and it supports USB data */
	if (pd->peer_usb_comm && pd->current_dr == DR_UFP && !pd->pd_connected)
		start_usb_peripheral(pd);

	/* Check for PPS APDOs */
	/* Check for PPS APDOs */
	if (pd->spec_rev == USBPD_REV_30) {
	if (pd->spec_rev == USBPD_REV_30) {
		for (i = 1; i < PD_MAX_DATA_OBJ; i++) {
		for (i = 1; i < PD_MAX_DATA_OBJ; i++) {
@@ -846,6 +842,10 @@ static int pd_eval_src_caps(struct usbpd *pd)
	power_supply_set_property(pd->usb_psy,
	power_supply_set_property(pd->usb_psy,
			POWER_SUPPLY_PROP_PD_ACTIVE, &val);
			POWER_SUPPLY_PROP_PD_ACTIVE, &val);


	/* First time connecting to a PD source and it supports USB data */
	if (pd->peer_usb_comm && pd->current_dr == DR_UFP && !pd->pd_connected)
		start_usb_peripheral(pd);

	/* Select the first PDO (vSafe5V) immediately. */
	/* Select the first PDO (vSafe5V) immediately. */
	pd_select_pdo(pd, 1, 0, 0);
	pd_select_pdo(pd, 1, 0, 0);


@@ -2209,9 +2209,19 @@ static void enter_state_snk_startup(struct usbpd *pd)
	};
	};
	union power_supply_propval val = {0};
	union power_supply_propval val = {0};


	if (pd->current_dr == DR_NONE || pd->current_dr == DR_UFP)
	if (pd->current_dr == DR_NONE || pd->current_dr == DR_UFP) {
		pd->current_dr = DR_UFP;
		pd->current_dr = DR_UFP;


		ret = power_supply_get_property(pd->usb_psy,
				POWER_SUPPLY_PROP_REAL_TYPE, &val);
		if (!ret) {
			usbpd_dbg(&pd->dev, "type:%d\n", val.intval);
			if (val.intval == POWER_SUPPLY_TYPE_USB ||
				val.intval == POWER_SUPPLY_TYPE_USB_CDP)
				start_usb_peripheral(pd);
		}
	}

	dual_role_instance_changed(pd->dual_role);
	dual_role_instance_changed(pd->dual_role);


	/*
	/*