static void twl4030_id_workaround_work(struct work_struct *work) { struct twl4030_usb *twl = container_of(work, struct twl4030_usb, id_workaround_work.work); enum omap_musb_vbus_id_status status; bool status_changed = false; status = twl4030_usb_linkstat(twl); spin_lock_irq(&twl->lock); if (status >= 0 && status != twl->linkstat) { twl->linkstat = status; status_changed = true; } spin_unlock_irq(&twl->lock); if (status_changed) { dev_dbg(twl->dev, "handle missing status change to %d\n", status); omap_musb_mailbox(status); } /* don't schedule during sleep - irq works right then */ if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) { cancel_delayed_work(&twl->id_workaround_work); schedule_delayed_work(&twl->id_workaround_work, HZ); } }
static irqreturn_t twl4030_usb_irq(int irq, void *_twl) { struct twl4030_usb *twl = _twl; int status; #ifdef CONFIG_LOCKDEP local_irq_enable(); #endif status = twl4030_usb_linkstat(twl); if (status != USB_LINK_UNKNOWN) { twl4030charger_usb_en(status == USB_LINK_VBUS); if (status == USB_LINK_NONE) twl4030_phy_suspend(twl, 0); else twl4030_phy_resume(twl); } 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 omap_musb_vbus_id_status status; bool status_changed = false; status = twl4030_usb_linkstat(twl); spin_lock_irq(&twl->lock); if (status >= 0 && status != twl->linkstat) { twl->linkstat = status; status_changed = true; } spin_unlock_irq(&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. */ omap_musb_mailbox(status); } 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; int status; status = twl4030_usb_linkstat(twl); if (status >= 0) { /* 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 (status == USB_EVENT_NONE) twl4030_phy_suspend(twl, 0); else twl4030_phy_resume(twl); blocking_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } 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 omap_musb_vbus_id_status status; bool status_changed = false; status = twl4030_usb_linkstat(twl); spin_lock_irq(&twl->lock); if (status >= 0 && status != twl->linkstat) { twl->linkstat = status; status_changed = true; } spin_unlock_irq(&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 ((status == OMAP_MUSB_VBUS_VALID) || (status == OMAP_MUSB_ID_GROUND)) { if (twl->asleep) pm_runtime_get_sync(twl->dev); } else { if (!twl->asleep) { pm_runtime_mark_last_busy(twl->dev); pm_runtime_put_autosuspend(twl->dev); } } omap_musb_mailbox(status); } /* don't schedule during sleep - irq works right then */ if (status == OMAP_MUSB_ID_GROUND && !twl->asleep) { 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; }
static void twl4030_phy_resume(struct twl4030_usb *twl) { if (!twl->asleep) return; /* Check the link status before enabling */ if (twl4030_usb_linkstat(twl) == USB_EVENT_NONE) return; twl4030_phy_power(twl, 1); twl4030_i2c_access(twl, 1); twl4030_usb_set_mode(twl, twl->usb_mode); if (twl->usb_mode == T2_USB_MODE_ULPI) twl4030_i2c_access(twl, 0); twl->asleep = 0; }
static int twl4030_phy_init(struct phy *phy) { struct twl4030_usb *twl = phy_get_drvdata(phy); enum omap_musb_vbus_id_status status; pm_runtime_get_sync(twl->dev); status = twl4030_usb_linkstat(twl); twl->linkstat = status; if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) omap_musb_mailbox(twl->linkstat); sysfs_notify(&twl->dev->kobj, NULL, "vbus"); pm_runtime_mark_last_busy(twl->dev); pm_runtime_put_autosuspend(twl->dev); return 0; }
static void twl4030_usb_phy_init(struct twl4030_usb *twl) { int status; status = twl4030_usb_linkstat(twl); if (status >= 0) { if (status == USB_EVENT_NONE) { __twl4030_phy_power(twl, 0); twl->asleep = 1; } else { __twl4030_phy_resume(twl); twl->asleep = 0; } atomic_notifier_call_chain(&twl->phy.notifier, status, twl->phy.otg->gadget); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); }
static irqreturn_t twl4030_usb_irq(int irq, void *_twl) { struct twl4030_usb *twl = _twl; int status; status = twl4030_usb_linkstat(twl); if (status >= 0) { if (status == USB_EVENT_NONE) twl4030_phy_suspend(twl, 0); else twl4030_phy_resume(twl); atomic_notifier_call_chain(&twl->phy.notifier, status, twl->phy.otg->gadget); } 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; int status; #ifdef CONFIG_LOCKDEP /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which * we don't want and can't tolerate. Although it might be * friendlier not to borrow this thread context... */ local_irq_enable(); #endif status = twl4030_usb_linkstat(twl); if (status != USB_LINK_UNKNOWN) { /* 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. */ twl4030charger_usb_en(status == USB_LINK_VBUS); if (status == USB_LINK_NONE) twl4030_phy_suspend(twl, 0); else twl4030_phy_resume(twl); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); return IRQ_HANDLED; }
static int twl4030_phy_init(struct phy *phy) { struct twl4030_usb *twl = phy_get_drvdata(phy); enum omap_musb_vbus_id_status status; /* * Start in sleep state, we'll get called through set_suspend() * callback when musb is runtime resumed and it's time to start. */ __twl4030_phy_power(twl, 0); twl->asleep = 1; status = twl4030_usb_linkstat(twl); twl->linkstat = status; if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) { omap_musb_mailbox(twl->linkstat); twl4030_phy_power_on(phy); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); return 0; }
static void twl4030_phy_resume(struct twl4030_usb *twl) { int status; // LGE CHANGE jjun.lee, Current Optimization by Prakash TI if (!twl->asleep) { return; } // LGE CHANGE jjun.lee, Current Optimization by Prakash TI /* To check the LINK status before resume.. * check to avoid enabling a LDO's * */ status = twl4030_usb_linkstat(twl); if (status == USB_EVENT_NONE) return; // LGE CHANGE jjun.lee, Current Optimization by Prakash TI twl4030_phy_power(twl, 1); twl4030_i2c_access(twl, 1); twl4030_usb_set_mode(twl, twl->usb_mode); if (twl->usb_mode == T2_USB_MODE_ULPI) twl4030_i2c_access(twl, 0); twl->asleep = 0; }
//&*&*&*SJ1_20110701, fix adb connect issue. static void do_softint_usb_irq(struct work_struct *work) { struct twl4030_usb *twl = container_of(work, struct twl4030_usb, usb_irq_delay_work.work); static int last_state=USB_EVENT_NONE; int status; static int run_flag=0; mdelay(200); last_state = twl->linkstat; status = twl4030_usb_linkstat(twl); if (status >= 0) { /* 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 (status == USB_EVENT_NONE) { //&*&*&*QY_20110706, don't send USB_EVENT_NONE again if(last_state==USB_EVENT_NONE) { return ; } //&*&*&*QY_20110706 twl4030_phy_suspend(twl, 0); if(twl->enter_early_suspend == 1) { SendPowerbuttonEvent(); printk("[twl4030-usb]Enter %s, send power suspend event.\n", __FUNCTION__); } if(wake_lock_active(&usb_lock)) wake_unlock(&usb_lock); } else { if(!wake_lock_active(&usb_lock)) wake_lock(&usb_lock); twl4030_phy_resume(twl); } //&*&*&*QY_20110706, don't send USB_EVENT_NONE if last status is USB_EVENT_ID if(status != USB_EVENT_ID) { twl4030_otg_enable(0); //Simon if( (status==USB_EVENT_VBUS) || (status==USB_EVENT_NONE && last_state!=USB_EVENT_ID)) { blocking_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } } //&*&*&*QY_20110706 //&*&*&*QY_20110706, enable 5V when OTG-cable plug-in else //(status == USB_EVENT_ID) { gpio_direction_output(OTG_EN_1V8, 0); gpio_direction_output(CHG_OFFMODE, 1); if(!run_flag) { //msleep(500); mdelay(3000); } blocking_notifier_call_chain(&twl->otg.notifier, USB_EVENT_ID, twl->otg.gadget); if(run_flag) { //msleep(500); mdelay(1000); } else { msleep(1000); } twl4030_otg_enable(1); //Simon } //&*&*&*QY_20110706 } run_flag=1; sysfs_notify(&twl->dev->kobj, NULL, "vbus"); }
static irqreturn_t twl4030_usb_irq(int irq, void *_twl) { struct twl4030_usb *twl = _twl; int status; #ifdef CONFIG_LGE_OMAP3_EXT_PWR twl4030_usb_irq_occured = 1; #endif status = twl4030_usb_linkstat(twl); if (status >= 0) { /* 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 (status == USB_EVENT_NONE) { twl_detect_usb_irq = 0; #if defined(CONFIG_MACH_LGE_OMAP3) musb_link_force_active(0); #endif // defined(CONFIG_MACH_LGE_OMAP3) twl4030_phy_suspend(twl, 0); } else // usb connnect { twl_detect_usb_irq = 1; #if defined(CONFIG_MACH_LGE_OMAP3) musb_link_force_active(1); #endif // defined(CONFIG_MACH_LGE_OMAP3) twl4030_phy_resume(twl); } blocking_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); #if 1 /* mbk_temp */ // LGE_CHANGE work queue & wake lock for usb connection printk(KERN_INFO "[charging_msg] %s: status %x\n", __FUNCTION__, status); //lge_twl4030charger_presence_evt(1); if( status == USB_EVENT_NONE) { if(1==the_wlock.wake_lock_on){ schedule_delayed_work(&twl4030_usb_wq, msecs_to_jiffies(500)); /* 500 msec */ // to delay unlock wake_lock } } else if( status == USB_EVENT_VBUS) { if(0==the_wlock.wake_lock_on){ wake_lock(&the_wlock.wake_lock); the_wlock.wake_lock_on=1; printk(KERN_WARNING "[twl4030-usb] wake_lock_on=1 (locked)\n"); } } // LGE_CHANGE work queue & wake lock for usb connection #endif return IRQ_HANDLED; }