Example #1
0
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);
	}
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #6
0
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;
}
Example #10
0
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;
}
Example #11
0
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;
}
Example #12
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;

}
Example #13
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");
}
Example #14
0
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;
}