static void twl4030_phy_power(struct twl4030_usb *twl, int on) { if (on) { regulator_enable(twl->usb3v1); regulator_enable(twl->usb1v8); /* * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP * in twl4030) resets the VUSB_DEDICATED2 register. This reset * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to * SLEEP. We work around this by clearing the bit after usv3v1 * is re-activated. This ensures that VUSB3V1 is really active. */ twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); regulator_enable(twl->usb1v5); __twl4030_phy_power(twl, 1); twl4030_usb_write(twl, PHY_CLK_CTRL, twl4030_usb_read(twl, PHY_CLK_CTRL) | (PHY_CLK_CTRL_CLOCKGATING_EN | PHY_CLK_CTRL_CLK32K_EN)); } else { __twl4030_phy_power(twl, 0); regulator_disable(twl->usb1v5); regulator_disable(twl->usb1v8); regulator_disable(twl->usb3v1); } }
static void twl4030_phy_power(struct twl4030_usb *twl, int on) { if (on) { regulator_enable(twl->usb3v1); regulator_enable(twl->usb1v8); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); regulator_enable(twl->usb1v5); __twl4030_phy_power(twl, 1); twl4030_usb_write(twl, PHY_CLK_CTRL, twl4030_usb_read(twl, PHY_CLK_CTRL) | (PHY_CLK_CTRL_CLOCKGATING_EN | PHY_CLK_CTRL_CLK32K_EN)); } else { __twl4030_phy_power(twl, 0); regulator_disable(twl->usb1v5); regulator_disable(twl->usb1v8); regulator_disable(twl->usb3v1); } }
static int twl4030_usb_runtime_suspend(struct device *dev) { struct twl4030_usb *twl = dev_get_drvdata(dev); dev_dbg(twl->dev, "%s\n", __func__); __twl4030_phy_power(twl, 0); regulator_disable(twl->usb1v5); regulator_disable(twl->usb1v8); regulator_disable(twl->usb3v1); 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 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; }
static int twl4030_usb_runtime_resume(struct device *dev) { struct twl4030_usb *twl = dev_get_drvdata(dev); int res; dev_dbg(twl->dev, "%s\n", __func__); res = regulator_enable(twl->usb3v1); if (res) dev_err(twl->dev, "Failed to enable usb3v1\n"); res = regulator_enable(twl->usb1v8); if (res) dev_err(twl->dev, "Failed to enable usb1v8\n"); /* * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP * in twl4030) resets the VUSB_DEDICATED2 register. This reset * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to * SLEEP. We work around this by clearing the bit after usv3v1 * is re-activated. This ensures that VUSB3V1 is really active. */ twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); res = regulator_enable(twl->usb1v5); if (res) dev_err(twl->dev, "Failed to enable usb1v5\n"); __twl4030_phy_power(twl, 1); twl4030_usb_write(twl, PHY_CLK_CTRL, twl4030_usb_read(twl, PHY_CLK_CTRL) | (PHY_CLK_CTRL_CLOCKGATING_EN | PHY_CLK_CTRL_CLK32K_EN)); return 0; }