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; }
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; }
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; }
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 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 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; }
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; }
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; }