Пример #1
0
static void twl4030_phy_resume(struct twl4030_usb *twl)
{
	if (!twl->asleep)
		return;

	wake_lock(&twl->wake_lock);

#if defined(USB_LAT_CONST) && defined(CONFIG_OMAP3_PM)
	/* Acquire USB constraint on OFF/RET */
	if (twl->usb_power_constraint)
		constraint_set(twl->usb_power_constraint,
					CO_LATENCY_MPUOFF_COREON);
#endif

	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;

#ifdef CONFIG_OMAP34XX_OFFMODE
	/* Restore context of MUSB from OFF mode */
	if (t2_transceiver->link_context_restore_and_wakeup)
		t2_transceiver->link_context_restore_and_wakeup();
#endif

	return;
}
Пример #2
0
static void __twl4030_phy_power_on(struct twl4030_usb *twl)
{
	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);
}
static void twl4030_phy_resume(struct twl4030_usb *twl)
{
	if (!twl->asleep)
		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;
}
Пример #4
0
static int twl4030_phy_power_on(struct phy *phy)
{
	struct twl4030_usb *twl = phy_get_drvdata(phy);

	dev_dbg(twl->dev, "%s\n", __func__);
	pm_runtime_get_sync(twl->dev);
	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);
	schedule_delayed_work(&twl->id_workaround_work, 0);

	return 0;
}
Пример #5
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;
}
Пример #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;
}
Пример #7
0
static void twl4030_phy_resume(void)
{
	struct twl4030_usb *twl = the_transceiver;

	if (!twl->asleep)
		return;

	/* enable falling edge interrupt to detect cable detach */
	usb_irq_enable(0, 1);

	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;
	return;
}
static int twl4030_phy_power_on(struct phy *phy)
{
	struct twl4030_usb *twl = phy_get_drvdata(phy);

	dev_dbg(twl->dev, "%s\n", __func__);
	pm_runtime_get_sync(twl->dev);
	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);

	/*
	 * XXX When VBUS gets driven after musb goes to A mode,
	 * ID_PRES related interrupts no longer arrive, why?
	 * Register itself is updated fine though, so we must poll.
	 */
	if (twl->linkstat == OMAP_MUSB_ID_GROUND) {
		cancel_delayed_work(&twl->id_workaround_work);
		schedule_delayed_work(&twl->id_workaround_work, HZ);
	}
	return 0;
}
Пример #9
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;

}
Пример #10
0
int twl4030_usb_reset(void)
{
	TRACE_ENTRY;
#if 0
	twl4030_usb_clear_bits(OTG_CTRL, DMPULLDOWN | DPPULLDOWN);
	twl4030_usb_clear_bits(USB_INT_EN_RISE, ~0);
	twl4030_usb_clear_bits(USB_INT_EN_FALL, ~0);
	twl4030_usb_clear_bits(MCPC_IO_CTRL, ~TXDTYP);
	twl4030_usb_set_bits(MCPC_IO_CTRL, TXDTYP);
	twl4030_usb_clear_bits(OTHER_FUNC_CTRL, (BDIS_ACON_EN | FIVEWIRE_MODE));
	twl4030_usb_clear_bits(OTHER_IFC_CTRL, ~0);
	twl4030_usb_clear_bits(OTHER_INT_EN_RISE, ~0);
	twl4030_usb_clear_bits(OTHER_INT_EN_FALL, ~0);
	twl4030_usb_clear_bits(OTHER_IFC_CTRL2, ~0);
	twl4030_usb_clear_bits(REG_CTRL_EN, ULPI_I2C_CONFLICT_INTEN);
	twl4030_usb_clear_bits(OTHER_FUNC_CTRL2, VBAT_TIMER_EN);
#endif

	/* Enable writing to power configuration registers */
	i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, PROTECT_KEY, 0xC0);
	i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, PROTECT_KEY, 0x0C);

	/* put VUSB3V1 LDO in active state */
	i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB_DEDICATED2, 0);

	/* input to VUSB3V1 LDO is from VBAT, not VBUS */
	i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB_DEDICATED1, 0x14);

	/* turn on 3.1V regulator */
	i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB3V1_DEV_GRP, 0x20);
	i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB3V1_TYPE, 0);

	/* turn on 1.5V regulator */
	i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB1V5_DEV_GRP, 0x20);
	i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB1V5_TYPE, 0);

	/* turn on 1.8V regulator */
	i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB1V8_DEV_GRP, 0x20);
	i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, VUSB1V8_TYPE, 0);

	/* disable access to power configuration registers */
	i2c_write_reg(TWL_I2C_BUS, TWL_PM_RECEIVER_ADDR, PROTECT_KEY, 0);

	/* turn on the phy */
	uint8_t pwr = twl4030_usb_read(PHY_PWR_CTRL);
	pwr &= ~PHYPWD;
	twl4030_usb_write(PHY_PWR_CTRL, pwr);
	twl4030_usb_write(PHY_CLK_CTRL,
	                  twl4030_usb_read(PHY_CLK_CTRL) |
	                  (CLOCKGATING_EN | CLK32K_EN));

	/* set DPLL i2c access mode */
	twl4030_i2c_access(true);
	/* set ulpi mode */
	twl4030_usb_clear_bits(IFC_CTRL, CARKITMODE);
	twl4030_usb_set_bits(POWER_CTRL, OTG_ENAB);
	twl4030_usb_write(FUNC_CTRL, XCVRSELECT_HS); // set high speed mode
//	twl4030_usb_write(FUNC_CTRL, XCVRSELECT_FS); // set full speed mode
	twl4030_i2c_access(false);

	return 0;
}