Exemplo n.º 1
0
static int twl4030_set_host(struct otg_transceiver *x, struct usb_bus *host)
{
	struct twl4030_usb *twl;

	if (!x)
		return -ENODEV;

	twl = xceiv_to_twl(x);

	if (!host) {
		omap_writew(0, OTG_IRQ_EN);
		twl4030_phy_suspend(twl, 1);
		twl->otg.host = NULL;

		return -ENODEV;
	}

	twl->otg.host = host;
	twl4030_phy_resume(twl);

	twl4030_usb_set_bits(twl, TWL4030_OTG_CTRL,
			TWL4030_OTG_CTRL_DMPULLDOWN
				| TWL4030_OTG_CTRL_DPPULLDOWN);

	twl4030_usb_set_bits(twl, FUNC_CTRL, FUNC_CTRL_SUSPENDM);
	twl4030_usb_set_bits(twl, TWL4030_OTG_CTRL, TWL4030_OTG_CTRL_DRVVBUS);

	return 0;
}
Exemplo n.º 2
0
//&*&*&*Simon_20110615, Interrupt handling function for GPIO-41
static irqreturn_t twl4030_OTG_irq(int irq, void *_twl)
{
	struct twl4030_usb *twl = _twl;
	struct otg_transceiver x = twl->otg;
	
	int status=-1;
	int otg_value=-1;
	otg_value=gpio_get_value(41);
   status = twl4030_readb(twl, TWL4030_MODULE_PM_MASTER,	STS_HW_CONDITIONS);
   printk("[OTG] %s twl4030_OTG_irq =%d status=0x%02x\n",twl->otg.label,otg_value,status);
   
   if(otg_value==1)
   {   	
		twl4030_otg_enable(0); //Simon
		//msleep(500);		
		blocking_notifier_call_chain(&twl->otg.notifier, USB_EVENT_NONE,	twl->otg.gadget);
		
		msleep(200);
		twl4030_phy_suspend(twl, 0);
		sysfs_notify(&twl->dev->kobj, NULL, "vbus");
		if(wake_lock_active(&usb_lock))
		{
			wake_unlock(&usb_lock);
		}
   }
   return IRQ_HANDLED;
}
Exemplo n.º 3
0
static int twl4030_set_peripheral(struct otg_transceiver *x,
		struct usb_gadget *gadget)
{
	struct twl4030_usb *twl;
	u32 l;

	if (!x)
		return -ENODEV;

	twl = xceiv_to_twl(x);

	if (!gadget) {
		omap_writew(0, OTG_IRQ_EN);
		twl4030_phy_suspend(twl, 1);
		twl->otg.gadget = NULL;

		return -ENODEV;
	}

	twl->otg.gadget = gadget;
	twl4030_phy_resume(twl);

	l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK;
	l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS);
	l |= OTG_ID;
	omap_writel(l, OTG_CTRL);

	twl->otg.state = OTG_STATE_B_IDLE;

	return 0;
}
Exemplo n.º 4
0
static int twl4030_set_host(struct otg_transceiver *xceiv, struct usb_bus *host)
{
	struct twl4030_usb *twl = xceiv_to_twl(xceiv);

	if (!xceiv)
		return -ENODEV;

	if (!host) {
		OTG_IRQ_EN_REG = 0;
		twl4030_phy_suspend(1);
		twl->otg.host = NULL;

		return -ENODEV;
	}

	twl->otg.host = host;
	twl4030_phy_resume();

	twl4030_usb_set_bits(twl, OTG_CTRL,
			OTG_CTRL_DMPULLDOWN | OTG_CTRL_DPPULLDOWN);
	twl4030_usb_set_bits(twl, USB_INT_EN_RISE, USB_INT_IDGND);
	twl4030_usb_set_bits(twl, USB_INT_EN_FALL, USB_INT_IDGND);
	twl4030_usb_set_bits(twl, FUNC_CTRL, FUNC_CTRL_SUSPENDM);
	twl4030_usb_set_bits(twl, OTG_CTRL, OTG_CTRL_DRVVBUS);

	return 0;
}
Exemplo n.º 5
0
static int twl4030_set_peripheral(struct otg_transceiver *xceiv,
		struct usb_gadget *gadget)
{
	struct twl4030_usb *twl = xceiv_to_twl(xceiv);

	if (!xceiv)
		return -ENODEV;

	if (!gadget) {
		OTG_IRQ_EN_REG = 0;
		twl4030_phy_suspend(1);
		twl->otg.gadget = NULL;

		return -ENODEV;
	}

	twl->otg.gadget = gadget;
	twl4030_phy_resume();

	OTG_CTRL_REG = (OTG_CTRL_REG & OTG_CTRL_MASK
			& ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS))
			| OTG_ID;

	twl->otg.state = OTG_STATE_B_IDLE;

	twl4030_usb_set_bits(twl, USB_INT_EN_RISE,
			USB_INT_SESSVALID | USB_INT_VBUSVALID);
	twl4030_usb_set_bits(twl, USB_INT_EN_FALL,
			USB_INT_SESSVALID | USB_INT_VBUSVALID);

	return 0;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
static int twl4030_set_suspend(struct otg_transceiver *x, int suspend)
{
	if (suspend)
		twl4030_phy_suspend(1);
	else
		twl4030_phy_resume();

	return 0;
}
Exemplo n.º 9
0
static int twl4030_set_suspend(struct otg_transceiver *x, int suspend)
{
	struct twl4030_usb *twl = xceiv_to_twl(x);

	if (suspend)
		twl4030_phy_suspend(twl, 1);
	else
		twl4030_phy_resume(twl);

	return 0;
}
static int twl4030_set_suspend(struct usb_phy *x, int suspend)
{
	struct twl4030_usb *twl = phy_to_twl(x);

	if (suspend)
		twl4030_phy_suspend(twl, 1);
	else
		twl4030_phy_resume(twl);

	return 0;
}
Exemplo n.º 11
0
static int __init twl4030_usb_init(void)
{
	struct twl4030_usb	*twl;
	int status;

	if (the_transceiver)
		return 0;

	twl = kzalloc(sizeof *twl, GFP_KERNEL);
	if (!twl)
		return 0;

	the_transceiver = twl;

	twl->irq		= TWL4030_PWRIRQ_USB_PRES;
	twl->otg.set_host	= twl4030_set_host;
	twl->otg.set_peripheral	= twl4030_set_peripheral;
	twl->otg.set_suspend	= twl4030_set_suspend;

	usb_irq_disable();
	status = request_irq(twl->irq, twl4030_usb_irq, 0, "twl4030_usb", twl);
	if (status < 0) {
		printk(KERN_DEBUG "can't get IRQ %d, err %d\n",
			twl->irq, status);
		kfree(twl);
		return -ENODEV;
	}

#if defined(CONFIG_TWL4030_USB_HS_ULPI)
	hs_usb_init(twl);
#endif
	twl4030_usb_ldo_init(twl);
	twl4030_phy_power(twl, 1);
	twl4030_i2c_access(1);
	twl4030_usb_set_mode(twl, twl->usb_mode);
	if (twl->usb_mode == T2_USB_MODE_ULPI)
		twl4030_i2c_access(0);

	twl->asleep = 0;

	if (twl->usb_mode == T2_USB_MODE_ULPI)
		twl4030_phy_suspend(1);

	otg_set_transceiver(&twl->otg);

	printk(KERN_INFO "Initialized TWL4030 USB module\n");

	return 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) {
		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;
}
Exemplo n.º 13
0
static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
{
	int ret = IRQ_NONE;
	u8 val;

	/* action based on cable attach or detach */
	if (twl4030_i2c_read_u8(TWL4030_MODULE_INT, &val, REG_PWR_EDR1) < 0) {
		printk(KERN_ERR "twl4030_usb: i2c read failed,"
				" line %d\n", __LINE__);
		goto done;
	}

	if (val & USB_PRES_RISING)
		twl4030_phy_resume();
	else
		twl4030_phy_suspend(0);

	ret = IRQ_HANDLED;

done:
	return ret;
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
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");
}
Exemplo n.º 16
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;
}