[RFC][PATCH 3/3] usb: phy: msm: use extcon to notify charger

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Phy already keeps track of the USB charger mode it is in, that
information could be useful to a power supply to let it know how much
current it can draw. So in this case when DCP or CDP is set maximum
current available is 1500mA, and 100mA when SDP is set.

This is a bit peculiar in that this driver only handle EXTCON_CHG_*
states, EXTCON_USB_* events come from another driver.

Signed-off-by: Damien Riegel <damien.riegel@xxxxxxxxxxxxxxxxxxxx>
---
 drivers/usb/phy/phy-msm-usb.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index f89a2a540f71..f264d5a5ad76 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -217,6 +217,7 @@ struct msm_otg {
 
 	struct msm_usb_cable vbus;
 	struct msm_usb_cable id;
+	struct extcon_dev *edev;
 
 	struct gpio_desc *switch_gpio;
 	struct notifier_block reboot;
@@ -248,6 +249,13 @@ enum vdd_levels {
 	VDD_LEVEL_MAX,
 };
 
+static const unsigned int msm_extcon_cables[] = {
+	EXTCON_CHG_USB_SDP,
+	EXTCON_CHG_USB_DCP,
+	EXTCON_CHG_USB_CDP,
+	EXTCON_NONE,
+};
+
 static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init)
 {
 	int ret = 0;
@@ -834,6 +842,21 @@ static int msm_otg_resume(struct msm_otg *motg)
 
 static void msm_otg_notify_charger(struct msm_otg *motg, unsigned mA)
 {
+	const unsigned int extcon_cables[][2] = {
+		{ EXTCON_CHG_USB_SDP, USB_SDP_CHARGER },
+		{ EXTCON_CHG_USB_DCP, USB_DCP_CHARGER },
+		{ EXTCON_CHG_USB_CDP, USB_CDP_CHARGER },
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(extcon_cables); i++) {
+		unsigned int cable = extcon_cables[i][0];
+		unsigned int chg_type = extcon_cables[i][1];
+
+		extcon_set_cable_state_(motg->edev, cable,
+				motg->chg_type == chg_type);
+	}
+
 	if (motg->cur_power == mA)
 		return;
 
@@ -1861,6 +1884,21 @@ static int msm_otg_probe(struct platform_device *pdev)
 	}
 
 	/*
+	 * Documentation in extcon.h states that EXTCONG_CHG_USB_SDP should
+	 * always appear together with EXTCON_USB, so register extcon cables
+	 * only if we successfully got the vbus extcon.
+	 */
+	if (!IS_ERR(motg->vbus.extcon)) {
+		motg->edev = devm_extcon_dev_allocate(&pdev->dev, msm_extcon_cables);
+		if (IS_ERR(motg->edev))
+			return PTR_ERR(motg->edev);
+
+		ret = devm_extcon_dev_register(&pdev->dev, motg->edev);
+		if (ret)
+			return ret;
+	}
+
+	/*
 	 * NOTE: The PHYs can be multiplexed between the chipidea controller
 	 * and the dwc3 controller, using a single bit. It is important that
 	 * the dwc3 driver does not set this bit in an incompatible way.
-- 
2.12.2

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux