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

Commit 1f14d5b7 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: pd: policy_engine: Add support to handle floating charger"

parents b52f6435 9ffb0179
Loading
Loading
Loading
Loading
+66 −10
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@
#include "debug.h"
#include "xhci.h"

#define SDP_CONNETION_CHECK_TIME 10000 /* in ms */

/* time out to wait for USB cable status notification (in ms)*/
#define SM_INIT_TIMEOUT 30000

@@ -227,6 +229,7 @@ struct dwc3_msm {
	int pm_qos_latency;
	struct pm_qos_request pm_qos_req_dma;
	struct delayed_work perf_vote_work;
	struct delayed_work sdp_check;
};

#define USB_HSPHY_3P3_VOL_MIN		3050000 /* uV */
@@ -2625,6 +2628,42 @@ done:
	return NOTIFY_DONE;
}


static void check_for_sdp_connection(struct work_struct *w)
{
	int ret;
	union power_supply_propval pval = {0};
	struct dwc3_msm *mdwc =
		container_of(w, struct dwc3_msm, sdp_check.work);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	if (!mdwc->vbus_active)
		return;

	/* floating D+/D- lines detected */
	if (dwc->gadget.state < USB_STATE_DEFAULT &&
		dwc3_gadget_get_link_state(dwc) != DWC3_LINK_STATE_CMPLY) {
		if (!mdwc->usb_psy) {
			mdwc->usb_psy = power_supply_get_by_name("usb");
			if (!mdwc->usb_psy) {
				dev_dbg(mdwc->dev,
					"Could not get usb power_supply\n");
				return;
			}
		}
		pval.intval = -ETIMEDOUT;
		ret = power_supply_set_property(mdwc->usb_psy,
					POWER_SUPPLY_PROP_CURRENT_MAX, &pval);
		if (ret)
			dev_dbg(mdwc->dev,
				"power supply error when setting property\n");

		mdwc->vbus_active = 0;
		dbg_event(0xFF, "Q RW SPD CHK", mdwc->vbus_active);
		queue_work(mdwc->dwc3_wq, &mdwc->resume_work);
	}
}

static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
	unsigned long event, void *ptr)
{
@@ -2833,6 +2872,7 @@ static int dwc3_msm_probe(struct platform_device *pdev)
	INIT_WORK(&mdwc->vbus_draw_work, dwc3_msm_vbus_draw_work);
	INIT_DELAYED_WORK(&mdwc->sm_work, dwc3_otg_sm_work);
	INIT_DELAYED_WORK(&mdwc->perf_vote_work, msm_dwc3_perf_vote_work);
	INIT_DELAYED_WORK(&mdwc->sdp_check, check_for_sdp_connection);

	mdwc->dwc3_wq = alloc_ordered_workqueue("dwc3_wq", 0);
	if (!mdwc->dwc3_wq) {
@@ -3586,28 +3626,38 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on)
	return 0;
}

static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned mA)
int get_psy_type(struct dwc3_msm *mdwc)
{
	union power_supply_propval pval = {0};
	int ret;

	if (mdwc->charging_disabled)
		return 0;

	if (mdwc->max_power == mA)
		return 0;
		return -EINVAL;

	if (!mdwc->usb_psy) {
		mdwc->usb_psy = power_supply_get_by_name("usb");
		if (!mdwc->usb_psy) {
			dev_warn(mdwc->dev, "Could not get usb power_supply\n");
			dev_err(mdwc->dev, "Could not get usb psy\n");
			return -ENODEV;
		}
	}

	power_supply_get_property(mdwc->usb_psy,
			POWER_SUPPLY_PROP_REAL_TYPE, &pval);
	if (pval.intval != POWER_SUPPLY_TYPE_USB)
	power_supply_get_property(mdwc->usb_psy, POWER_SUPPLY_PROP_REAL_TYPE,
			&pval);

	return pval.intval;
}

static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned mA)
{
	union power_supply_propval pval = {0};
	int ret, psy_type;

	if (mdwc->max_power == mA)
		return 0;

	psy_type = get_psy_type(mdwc);
	if (psy_type != POWER_SUPPLY_TYPE_USB &&
			psy_type != POWER_SUPPLY_TYPE_USB_FLOAT)
		return 0;

	dev_info(mdwc->dev, "Avail curr from USB = %u\n", mA);
@@ -3684,6 +3734,10 @@ static void dwc3_otg_sm_work(struct work_struct *w)
			work = 1;
		} else if (test_bit(B_SESS_VLD, &mdwc->inputs)) {
			dev_dbg(mdwc->dev, "b_sess_vld\n");
			if (get_psy_type(mdwc) == POWER_SUPPLY_TYPE_USB_FLOAT)
				queue_delayed_work(mdwc->dwc3_wq,
						&mdwc->sdp_check,
				msecs_to_jiffies(SDP_CONNETION_CHECK_TIME));
			/*
			 * Increment pm usage count upon cable connect. Count
			 * is decremented in OTG_STATE_B_PERIPHERAL state on
@@ -3707,6 +3761,7 @@ static void dwc3_otg_sm_work(struct work_struct *w)
				!test_bit(ID, &mdwc->inputs)) {
			dev_dbg(mdwc->dev, "!id || !bsv\n");
			mdwc->otg_state = OTG_STATE_B_IDLE;
			cancel_delayed_work_sync(&mdwc->sdp_check);
			dwc3_otg_start_peripheral(mdwc, 0);
			/*
			 * Decrement pm usage count upon cable disconnect
@@ -3739,6 +3794,7 @@ static void dwc3_otg_sm_work(struct work_struct *w)
		if (!test_bit(B_SESS_VLD, &mdwc->inputs)) {
			dev_dbg(mdwc->dev, "BSUSP: !bsv\n");
			mdwc->otg_state = OTG_STATE_B_IDLE;
			cancel_delayed_work_sync(&mdwc->sdp_check);
			dwc3_otg_start_peripheral(mdwc, 0);
		} else if (!test_bit(B_SUSPEND, &mdwc->inputs)) {
			dev_dbg(mdwc->dev, "BSUSP !susp\n");
+1 −0
Original line number Diff line number Diff line
@@ -920,6 +920,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)

			if (pd->psy_type == POWER_SUPPLY_TYPE_USB ||
				pd->psy_type == POWER_SUPPLY_TYPE_USB_CDP ||
				pd->psy_type == POWER_SUPPLY_TYPE_USB_FLOAT ||
				usb_compliance_mode)
				start_usb_peripheral(pd);
		}