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

Commit 25f59744 authored by Ajay Agarwal's avatar Ajay Agarwal
Browse files

usb: phy: msm: Expose DP/DM operations as a regulator



Instead of having the controller driver call the PHY's DP/DM
properties on behalf of the charger driver to enable and disable
the regulator, allow the PHY to expose a regulator device.
The charger driver then obtains a handle to this regulator to
perform regulator enable and disable directly.

Change-Id: I24c9b5722d84ea90f5a339245eb85b6a0dcbccf0
Signed-off-by: default avatarAjay Agarwal <ajaya@codeaurora.org>
parent 389ef271
Loading
Loading
Loading
Loading
+83 −0
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@
#include <linux/usb/msm_hsusb_hw.h>
#include <linux/usb/msm_ext_chg.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/qpnp/qpnp-adc.h>

#include <linux/msm-bus.h>
@@ -3920,6 +3922,81 @@ static enum power_supply_property otg_pm_power_props_usb[] = {
	POWER_SUPPLY_PROP_USB_OTG,
};

static int msm_otg_dpdm_regulator_enable(struct regulator_dev *rdev)
{
	int ret = 0;
	struct msm_otg *motg = rdev_get_drvdata(rdev);

	if (!motg->rm_pulldown) {
		ret = msm_hsusb_ldo_enable(motg, USB_PHY_REG_3P3_ON);
		if (!ret) {
			motg->rm_pulldown = true;
			msm_otg_dbg_log_event(&motg->phy, "RM Pulldown",
					motg->rm_pulldown, 0);
		}
	}

	return ret;
}

static int msm_otg_dpdm_regulator_disable(struct regulator_dev *rdev)
{
	int ret = 0;
	struct msm_otg *motg = rdev_get_drvdata(rdev);

	if (motg->rm_pulldown) {
		ret = msm_hsusb_ldo_enable(motg, USB_PHY_REG_3P3_OFF);
		if (!ret) {
			motg->rm_pulldown = false;
			msm_otg_dbg_log_event(&motg->phy, "RM Pulldown",
					motg->rm_pulldown, 0);
		}
	}

	return ret;
}

static int msm_otg_dpdm_regulator_is_enabled(struct regulator_dev *rdev)
{
	struct msm_otg *motg = rdev_get_drvdata(rdev);

	return motg->rm_pulldown;
}

static struct regulator_ops msm_otg_dpdm_regulator_ops = {
	.enable		= msm_otg_dpdm_regulator_enable,
	.disable	= msm_otg_dpdm_regulator_disable,
	.is_enabled	= msm_otg_dpdm_regulator_is_enabled,
};

static int usb_phy_regulator_init(struct msm_otg *motg)
{
	struct device *dev = motg->phy.dev;
	struct regulator_config cfg = {};
	struct regulator_init_data *init_data;

	init_data = devm_kzalloc(dev, sizeof(*init_data), GFP_KERNEL);
	if (!init_data)
		return -ENOMEM;

	init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_STATUS;
	motg->dpdm_rdesc.owner = THIS_MODULE;
	motg->dpdm_rdesc.type = REGULATOR_VOLTAGE;
	motg->dpdm_rdesc.ops = &msm_otg_dpdm_regulator_ops;
	motg->dpdm_rdesc.name = kbasename(dev->of_node->full_name);

	cfg.dev = dev;
	cfg.init_data = init_data;
	cfg.driver_data = motg;
	cfg.of_node = dev->of_node;

	motg->dpdm_rdev = devm_regulator_register(dev, &motg->dpdm_rdesc, &cfg);
	if (IS_ERR(motg->dpdm_rdev))
		return PTR_ERR(motg->dpdm_rdev);

	return 0;
}

const struct file_operations msm_otg_bus_fops = {
	.open = msm_otg_bus_open,
	.read = seq_read,
@@ -5053,6 +5130,12 @@ static int msm_otg_probe(struct platform_device *pdev)
		goto free_async_irq;
	}

	ret = usb_phy_regulator_init(motg);
	if (ret) {
		dev_err(&pdev->dev, "usb_phy_regulator_init failed\n");
		goto remove_phy;
	}

	if (motg->pdata->mode == USB_OTG &&
		motg->pdata->otg_control == OTG_PMIC_CONTROL &&
		!motg->phy_irq) {
+5 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/power_supply.h>
#include <linux/cdev.h>
#include <linux/usb_bam.h>
#include <linux/regulator/driver.h>
/**
 * Requested USB votes for NOC frequency
 *
@@ -166,6 +167,8 @@ enum usb_id_state {
 * @phy_irq_pending: Gets set when PHY IRQ arrives in LPM.
 * @id_state: Indicates USBID line status.
 * @rm_pulldown: Indicates pulldown status on D+ and D- data lines.
 * @dpdm_desc: Regulator descriptor for D+ and D- voting.
 * @dpdm_rdev: Regulator class device for dpdm regulator.
 * @dbg_idx: Dynamic debug buffer Index.
 * @dbg_lock: Dynamic debug buffer Lock.
 * @buf: Dynamic Debug Buffer.
@@ -296,6 +299,8 @@ struct msm_otg {
	bool phy_irq_pending;
	enum usb_id_state id_state;
	bool rm_pulldown;
	struct regulator_desc	dpdm_rdesc;
	struct regulator_dev	*dpdm_rdev;
/* Maximum debug message length */
#define DEBUG_MSG_LEN   128UL
/* Maximum number of messages */