Provide Host PC (after configured), Wall charger notifications. Typically Battery/Charger driver is subscribed to these notifications and responsible for notifying user space and drawing the current. This patch was originally developed by Google and is available at http://android.git.kernel.org/?p=kernel/experimental.git. Signed-off-by: Pavankumar Kondeti <pkondeti@xxxxxxxxxxxxxx> --- drivers/usb/gadget/msm72k_udc.c | 17 +++++++++++++++++ include/linux/usb/msm_hsusb.h | 16 ++++++++++++++++ 2 files changed, 33 insertions(+), 0 deletions(-) diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c index 2b476a6..80f6003 100644 --- a/drivers/usb/gadget/msm72k_udc.c +++ b/drivers/usb/gadget/msm72k_udc.c @@ -173,6 +173,8 @@ static void usb_do_work(struct work_struct *w); * comes from platform data. * @hw_reset: function pointer to assert/de-assert of link. * comes from platform data. + * @usb_connected: callback function registered to receive charger type + * notifications. comes from platform data. * @work: work_struct for state transitions. * @gadget: gadget struct of this driver. * @driver: gadget driver bound to this driver. @@ -211,6 +213,8 @@ struct usb_info { void (*phy_reset)(void); void (*hw_reset)(bool en); + void (*usb_connected)(int); + struct work_struct work; struct usb_gadget gadget; @@ -733,6 +737,8 @@ static void handle_setup(struct usb_info *ui) if (ctl.bRequestType == (USB_DIR_OUT | USB_TYPE_STANDARD)) { if (ctl.bRequest == USB_REQ_SET_CONFIGURATION) { ui->online = !!ctl.wValue; + if (ui->online && ui->usb_connected) + ui->usb_connected(USB_CHG_HOST); } else if (ctl.bRequest == USB_REQ_SET_ADDRESS) { /* write address delayed (will take effect ** after the next IN txn) @@ -1263,6 +1269,9 @@ static void usb_do_work(struct work_struct *w) msm72k_pullup(&ui->gadget, 0); spin_unlock_irqrestore(&ui->lock, iflags); + if (ui->usb_connected) + ui->usb_connected(USB_CHG_NONE); + /* terminate any transactions, etc */ flush_all_endpoints(ui); @@ -1302,6 +1311,13 @@ static void usb_do_work(struct work_struct *w) clk_enable(ui->pclk); usb_reset(ui); + /* detect shorted D+/D-, indicating AC power */ + usleep_range(10000, 12000); + if ((readl(USB_PORTSC) & PORTSC_LS) == + PORTSC_LS) + if (ui->usb_connected) + ui->usb_connected(USB_CHG_WALL); + ui->state = USB_STATE_ONLINE; usb_do_work_check_vbus(ui); } @@ -1790,6 +1806,7 @@ static int msm72k_probe(struct platform_device *pdev) struct msm_hsusb_platform_data *pdata = pdev->dev.platform_data; ui->phy_reset = pdata->phy_reset; ui->phy_init_seq = pdata->phy_init_seq; + ui->usb_connected = pdata->usb_connected; } irq = platform_get_irq(pdev, 0); diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h index 758d140..f95b62c 100644 --- a/include/linux/usb/msm_hsusb.h +++ b/include/linux/usb/msm_hsusb.h @@ -20,11 +20,26 @@ #include <linux/types.h> /** + * USB charger types. + * + * USB_CHG_NONE Charger is not connected. + * USB_CHG_HOST Connected to Host PC. + * USB_CHG_WALL Connected to Wall charger. + * + */ +enum usb_chg_type { + USB_CHG_NONE = 0, + USB_CHG_HOST, + USB_CHG_WALL, +}; + +/** * struct msm_hsusb_platform_data - platform device data * for msm72k_udc driver. * @phy_reset: assert followed by de-assert of PHY. * @hw_reset: if enable is true, assert link otherwise * de-assert link. + * @usb_connected: callback function to receive usb charger type notifications. * @phy_init_seq: PHY configuration sequence. val, reg pairs * terminated by -1. * @@ -32,6 +47,7 @@ struct msm_hsusb_platform_data { void (*phy_reset)(void); void (*hw_reset)(bool enable); + void (*usb_connected)(int); int *phy_init_seq; }; -- 1.7.1 -- 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