static void __exit twl4030_usb_exit(void) { struct twl4030_usb *twl = the_transceiver; int val; usb_irq_disable(); free_irq(twl->irq, twl); /* set transceiver mode to power on defaults */ twl4030_usb_set_mode(twl, -1); /* autogate 60MHz ULPI clock, * clear dpll clock request for i2c access, * disable 32KHz */ val = twl4030_usb_read(PHY_CLK_CTRL); if (val >= 0) { val |= PHY_CLK_CTRL_CLOCKGATING_EN; val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); twl4030_usb_write(PHY_CLK_CTRL, (u8)val); } /* disable complete OTG block */ twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); twl4030_phy_power(twl, 0); kfree(twl); }
static int twl4030_usb_remove(struct platform_device *pdev) { struct twl4030_usb *twl = platform_get_drvdata(pdev); int val; cancel_delayed_work(&twl->id_workaround_work); device_remove_file(twl->dev, &dev_attr_vbus); /* set transceiver mode to power on defaults */ twl4030_usb_set_mode(twl, -1); /* autogate 60MHz ULPI clock, * clear dpll clock request for i2c access, * disable 32KHz */ val = twl4030_usb_read(twl, PHY_CLK_CTRL); if (val >= 0) { val |= PHY_CLK_CTRL_CLOCKGATING_EN; val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val); } /* disable complete OTG block */ twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); if (!twl->asleep) twl4030_phy_power(twl, 0); return 0; }
static int __exit twl4030_usb_remove(struct platform_device *pdev) { struct twl4030_usb *twl = platform_get_drvdata(pdev); int val; free_irq(twl->irq, twl); device_remove_file(twl->dev, &dev_attr_vbus); twl4030_usb_set_mode(twl, -1); val = twl4030_usb_read(twl, PHY_CLK_CTRL); if (val >= 0) { val |= PHY_CLK_CTRL_CLOCKGATING_EN; val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val); } twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); if (!twl->asleep) twl4030_phy_power(twl, 0); regulator_put(twl->usb1v5); regulator_put(twl->usb1v8); regulator_put(twl->usb3v1); kfree(twl->phy.otg); kfree(twl); return 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; }
static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off) { if (twl->asleep) return; twl4030_phy_power(twl, 0); twl->asleep = 1; }
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_suspend(struct twl4030_usb *twl, int controller_off) { if (twl->asleep) return; twl4030_phy_power(twl, 0); twl->asleep = 1; dev_dbg(twl->dev, "%s\n", __func__); }
/* * Initiaze the ULPI interface * ULPI : Universal Transceiver Macrocell Low Pin Interface * An interface between the USB link controller like musb and the * the PHY or transceiver that drives the actual bus. */ int twl4030_usb_ulpi_init(void) { long timeout = 1000 * 1000; /* 1 sec */; u8 clk, sts, pwr; /* twl4030 ldo init */ twl4030_usb_ldo_init(); /* Enable the twl4030 phy */ twl4030_phy_power(); /* Enable DPLL to access PHY registers over I2C */ clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL); clk |= REQ_PHY_DPLL_CLK; twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk); /* Check if the PHY DPLL is locked */ sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS); while (!(sts & PHY_DPLL_CLK) && 0 < timeout) { udelay(10); sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS); timeout -= 10; } /* Final check */ sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS); if (!(sts & PHY_DPLL_CLK)) { printf("Error:TWL4030:USB Timeout setting PHY DPLL clock\n"); return -1; } /* * There are two circuit blocks attached to the PHY, * Carkit and USB OTG. Disable Carkit and enable USB OTG */ twl4030_usb_write(TWL4030_USB_IFC_CTRL_CLR, CARKITMODE); pwr = twl4030_usb_read(TWL4030_USB_POWER_CTRL); pwr |= OTG_ENAB; twl4030_usb_write(TWL4030_USB_POWER_CTRL_SET, pwr); /* Clear the opmode bits to ensure normal encode */ twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, OPMODE_MASK); /* Clear the xcvrselect bits to enable the high speed transeiver */ twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, XCVRSELECT_MASK); /* Let ULPI control the DPLL clock */ clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL); clk &= ~REQ_PHY_DPLL_CLK; twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk); return 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_off(struct phy *phy) { struct twl4030_usb *twl = phy_get_drvdata(phy); if (twl->asleep) return 0; twl4030_phy_power(twl, 0); twl->asleep = 1; dev_dbg(twl->dev, "%s\n", __func__); return 0; }
static int twl4030_usb_runtime_resume(struct device *dev) { struct twl4030_usb *twl = dev_get_drvdata(dev); dev_dbg(twl->dev, "%s\n", __func__); if (!twl->asleep) return 0; twl4030_phy_power(twl, 1); twl->asleep = 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_suspend(struct twl4030_usb *twl, int controller_off) { if (twl->asleep) return; twl4030_phy_power(twl, 0); twl->asleep = 1; #if defined(USB_LAT_CONST) && defined(CONFIG_OMAP3_PM) /* Release USB constraint on OFF/RET */ if (twl->usb_power_constraint) constraint_remove(twl->usb_power_constraint); #endif wake_unlock(&twl->wake_lock); return; }
static void twl4030_phy_suspend(int controller_off) { struct twl4030_usb *twl = the_transceiver; if (controller_off) usb_irq_disable(); if (twl->asleep) return; if (!controller_off) /* enable rising edge interrupt to detect cable attach */ usb_irq_enable(1, 0); twl4030_phy_power(twl, 0); twl->asleep = 1; return; }
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 __exit twl4030_usb_remove(struct platform_device *pdev) { struct twl4030_usb *twl = platform_get_drvdata(pdev); int val; free_irq(twl->irq, twl); device_remove_file(twl->dev, &dev_attr_vbus); /* set transceiver mode to power on defaults */ twl4030_usb_set_mode(twl, -1); /* autogate 60MHz ULPI clock, * clear dpll clock request for i2c access, * disable 32KHz */ val = twl4030_usb_read(twl, PHY_CLK_CTRL); if (val >= 0) { val |= PHY_CLK_CTRL_CLOCKGATING_EN; val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val); } /* disable complete OTG block */ twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); twl4030_phy_power(twl, 0); regulator_put(twl->usb1v5); regulator_put(twl->usb1v8); #if 0 /* LGE_CHANGE [HEAVEN: [email protected]] on 2009-10-14, for <25.12 USB interrupt fix> */ regulator_put(twl->usb3v1); #endif kfree(twl); #if 1 /* mbk_wake mbk_temp */ // LGE_CHANGE wake lock for usb connection wake_lock_destroy(&the_wlock.wake_lock); // LGE_CHANGE wake lock for usb connection #endif 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; }
static int __exit twl4030_usb_remove(struct platform_device *pdev) { struct twl4030_usb *twl = platform_get_drvdata(pdev); int val; free_irq(twl->irq, twl); device_remove_file(twl->dev, &dev_attr_vbus); /* set transceiver mode to power on defaults */ twl4030_usb_set_mode(twl, -1); /* autogate 60MHz ULPI clock, * clear dpll clock request for i2c access, * disable 32KHz */ val = twl4030_usb_read(twl, PHY_CLK_CTRL); if (val >= 0) { val |= PHY_CLK_CTRL_CLOCKGATING_EN; val &= ~(PHY_CLK_CTRL_CLK32K_EN | REQ_PHY_DPLL_CLK); twl4030_usb_write(twl, PHY_CLK_CTRL, (u8)val); } /* disable complete OTG block */ twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); twl4030_phy_power(twl, 0); regulator_put(twl->usb1v5); regulator_put(twl->usb1v8); regulator_put(twl->usb3v1); wake_lock_destroy(&usb_lock); kfree(twl); return 0; }