static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) { struct twl6030_usb *twl = _twl; enum musb_vbus_id_status status = MUSB_UNKNOWN; u8 hw_state; int ret; hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); if (hw_state & STS_USB_ID) { ret = regulator_enable(twl->usb3v3); if (ret) dev_err(twl->dev, "Failed to enable usb3v3\n"); twl->asleep = 1; twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); status = MUSB_ID_GROUND; twl->linkstat = status; musb_mailbox(status); } else { twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); } twl6030_writeb(twl, TWL_MODULE_USB, status, USB_ID_INT_LATCH_CLR); return IRQ_HANDLED; }
static irqreturn_t twl6030_usb_irq(int irq, void *_twl) { struct twl6030_usb *twl = _twl; enum musb_vbus_id_status status = MUSB_UNKNOWN; u8 vbus_state, hw_state; int ret; hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); vbus_state = twl6030_readb(twl, TWL_MODULE_MAIN_CHARGE, CONTROLLER_STAT1); if (!(hw_state & STS_USB_ID)) { if (vbus_state & VBUS_DET) { ret = regulator_enable(twl->usb3v3); if (ret) dev_err(twl->dev, "Failed to enable usb3v3\n"); twl->asleep = 1; status = MUSB_VBUS_VALID; twl->linkstat = status; ret = musb_mailbox(status); if (ret) twl->linkstat = MUSB_UNKNOWN; } else { if (twl->linkstat != MUSB_UNKNOWN) { status = MUSB_VBUS_OFF; twl->linkstat = status; ret = musb_mailbox(status); if (ret) twl->linkstat = MUSB_UNKNOWN; if (twl->asleep) { regulator_disable(twl->usb3v3); twl->asleep = 0; } } } } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); return IRQ_HANDLED; }
static irqreturn_t twl4030_usb_irq(int irq, void *_twl) { struct twl4030_usb *twl = _twl; enum musb_vbus_id_status status; bool status_changed = false; status = twl4030_usb_linkstat(twl); mutex_lock(&twl->lock); if (status >= 0 && status != twl->linkstat) { status_changed = cable_present(twl->linkstat) != cable_present(status); twl->linkstat = status; } mutex_unlock(&twl->lock); if (status_changed) { /* FIXME add a set_power() method so that B-devices can * configure the charger appropriately. It's not always * correct to consume VBUS power, and how much current to * consume is a function of the USB configuration chosen * by the host. * * REVISIT usb_gadget_vbus_connect(...) as needed, ditto * its disconnect() sibling, when changing to/from the * USB_LINK_VBUS state. musb_hdrc won't care until it * starts to handle softconnect right. */ if (cable_present(status)) { pm_runtime_get_sync(twl->dev); } else { pm_runtime_mark_last_busy(twl->dev); pm_runtime_put_autosuspend(twl->dev); } musb_mailbox(status); } /* don't schedule during sleep - irq works right then */ if (status == MUSB_ID_GROUND && pm_runtime_active(twl->dev)) { cancel_delayed_work(&twl->id_workaround_work); schedule_delayed_work(&twl->id_workaround_work, HZ); } if (irq) sysfs_notify(&twl->dev->kobj, NULL, "vbus"); return IRQ_HANDLED; }