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