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

Commit f98fb1fc authored by Rohith Kollalsi's avatar Rohith Kollalsi
Browse files

usb: dwc3: Set current accordingly based on type of charger detection



For ADSP based charger detection set the current for all
charger types as it will again be handled on ADSP side.
Other wise set current only for SDP charger which is usb
based charger. For NON ADSP based charger detection if
'iio-channel-names' is passed in the device tree, charger
detection is done through iio channel or else it is
done by power_supply_get_property.

Change-Id: I17e65448459318ad26b7a2c36742296afa5f0adf
Signed-off-by: default avatarRohith Kollalsi <rkollals@codeaurora.org>
parent b22b60a0
Loading
Loading
Loading
Loading
+63 −15
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
 */

#include <linux/module.h>
@@ -184,6 +184,12 @@ enum dbm_reg {
	DBM_DATA_FIFO_SIZE_EN,
};

enum charger_detection_type {
	REMOTE_PROC,
	IIO,
	PSY,
};

struct dbm_reg_data {
	u32 offset;
	unsigned int ep_mult;
@@ -478,6 +484,7 @@ struct dwc3_msm {
	struct mutex suspend_resume_mutex;

	enum usb_device_speed override_usb_speed;
	enum charger_detection_type apsd_source;
	u32			*gsi_reg;
	int			gsi_reg_offset_cnt;

@@ -4496,6 +4503,14 @@ static int dwc3_msm_probe(struct platform_device *pdev)
		}
	}

	/* Check charger detection type to obtain charger type */
	if (of_get_property(mdwc->dev->of_node, "io-channel-names", NULL))
		mdwc->apsd_source = IIO;
	else if (of_get_property(mdwc->dev->of_node, "usb-role-switch", NULL))
		mdwc->apsd_source = REMOTE_PROC;
	else
		mdwc->apsd_source = PSY;

	if (of_property_read_bool(node, "extcon")) {
		ret = dwc3_msm_extcon_register(mdwc);
		if (ret)
@@ -5010,12 +5025,17 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on)

static int get_chg_type(struct dwc3_msm *mdwc)
{
	int ret, value;
	int ret, value = 0;
	union power_supply_propval pval = {0};

	switch (mdwc->apsd_source) {
	case IIO:
		if (!mdwc->chg_type) {
		mdwc->chg_type = devm_iio_channel_get(mdwc->dev, "chg_type");
			mdwc->chg_type = devm_iio_channel_get(mdwc->dev,
						"chg_type");
			if (IS_ERR_OR_NULL(mdwc->chg_type)) {
			dev_dbg(mdwc->dev, "unable to get iio channel\n");
				dev_dbg(mdwc->dev,
					"unable to get iio channel\n");
				mdwc->chg_type = NULL;
				return -ENODEV;
			}
@@ -5026,6 +5046,23 @@ static int get_chg_type(struct dwc3_msm *mdwc)
			dev_err(mdwc->dev, "failed to get charger type\n");
			return ret;
		}
		break;
	case PSY:
		if (!mdwc->usb_psy) {
			mdwc->usb_psy = power_supply_get_by_name("usb");
			if (!mdwc->usb_psy) {
				dev_err(mdwc->dev, "Could not get usb psy\n");
				return -ENODEV;
			}
		}

		power_supply_get_property(mdwc->usb_psy,
				POWER_SUPPLY_PROP_USB_TYPE, &pval);
		value = pval.intval;
		break;
	default:
		return -EINVAL;
	}

	return value;
}
@@ -5064,12 +5101,23 @@ static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned int mA)
		goto set_prop;
	}

	/* Do not set current multiple times */
	if (mdwc->max_power == mA)
		return 0;

	/*
	 * Set the valid current only when the device
	 * is connected to a Standard Downstream Port.
	 * For ADSP based charger detection set current
	 * for all charger types. For psy based charger
	 * detection power_supply_usb_type enum is
	 * returned from pmic while for iio based charger
	 * detection power_supply_type enum is returned.
	 */
	if (mdwc->max_power == mA || (chg_type != -ENODEV
				&& chg_type != POWER_SUPPLY_TYPE_USB))
	if (mdwc->apsd_source == PSY && chg_type != POWER_SUPPLY_USB_TYPE_SDP)
		return 0;

	if (mdwc->apsd_source == IIO && chg_type != POWER_SUPPLY_TYPE_USB)
		return 0;

	/* Set max current limit in uA */