예제 #1
0
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);
	}
}
예제 #3
0
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");
}
예제 #5
0
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;
}
예제 #6
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;
}