Пример #1
0
static void twl4030_phy_power(void)
{
    u8 pwr, clk;

    /* Power the PHY */
    pwr = twl4030_usb_read(TWL4030_USB_PHY_PWR_CTRL);
    pwr &= ~PHYPWD;
    twl4030_usb_write(TWL4030_USB_PHY_PWR_CTRL, pwr);
    /* Enable clocks */
    clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
    clk |= CLOCKGATING_EN | CLK32K_EN;
    twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
}
Пример #2
0
static void twl4030_phy_power(struct twl4030_usb *twl, int on)
{
	u8 pwr;

	pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
	if (on) {
		regulator_enable(twl->usb3v1);
		regulator_enable(twl->usb1v8);
		
		twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0,
							VUSB_DEDICATED2);
		regulator_enable(twl->usb1v5);
		pwr &= ~PHY_PWR_PHYPWD;
		WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
		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  {
		pwr |= PHY_PWR_PHYPWD;
		WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
		regulator_disable(twl->usb1v5);
		regulator_disable(twl->usb1v8);
		regulator_disable(twl->usb3v1);
	}
}
Пример #3
0
static void twl4030_phy_power(struct twl4030_usb *twl, int on)
{
	u8 pwr;

	pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
	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);
		pwr &= ~PHY_PWR_PHYPWD;
		WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
		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  {
		pwr |= PHY_PWR_PHYPWD;
		WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
		regulator_disable(twl->usb1v5);
		regulator_disable(twl->usb1v8);
		regulator_disable(twl->usb3v1);
	}
}
Пример #4
0
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);
}
Пример #5
0
static void twl4030_phy_power(struct twl4030_usb *twl, int on)
{
	u8 pwr;

	pwr = twl4030_usb_read(PHY_PWR_CTRL);
	if (on) {
		pwr &= ~PHY_PWR_PHYPWD;
		if (twl4030_usb_write_verify(PHY_PWR_CTRL, pwr) < 0) {
			printk(KERN_ERR "twl4030_usb: i2c write failed,"
					" line %d\n", __LINE__);
			return;
		}
		twl4030_usb_write(PHY_CLK_CTRL,
				  twl4030_usb_read(PHY_CLK_CTRL) |
					(PHY_CLK_CTRL_CLOCKGATING_EN |
						PHY_CLK_CTRL_CLK32K_EN));
	} else  {
		pwr |= PHY_PWR_PHYPWD;
		if (twl4030_usb_write_verify(PHY_PWR_CTRL, pwr) < 0) {
			printk(KERN_ERR "twl4030_usb: i2c write failed,"
					" line %d\n", __LINE__);
		}
	}
	return;
}
Пример #6
0
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;
}
Пример #8
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);
#ifndef CONFIG_TWL4030_MADC
		regulator_disable(twl->usb3v1);
#endif
	}
}
Пример #9
0
static void twl4030_phy_power(struct twl4030_usb *twl, int on)
{
	u8 pwr;

	pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
	printk(KERN_ERR "twl4030_phy_power + : PHY_PWR_CTRL=%x ====^^==== (twl4030-usb.c)\n", pwr);
	pwr = twl4030_usb_read(twl, PHY_CLK_CTRL);
	printk(KERN_ERR "twl4030_phy_power + : PHY_CLK_CTRL=%x ====^^==== (twl4030-usb.c)\n", pwr);
	pwr = twl4030_usb_read(twl, PHY_CLK_CTRL_STS);
	printk(KERN_ERR "twl4030_phy_power + : PHY_CLK_CTRL_STS=%x ====^^==== (twl4030-usb.c)\n", pwr);
	if (on) {
#if 0	/* LGE_CHANGE [HEAVEN: [email protected]] on 2009-10-14, for <25.12 USB interrupt fix> */
		regulator_enable(twl->usb3v1);
		regulator_enable(twl->usb1v8);
#endif
		/*
		 * 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);
#if 1	/* LGE_CHANGE [HEAVEN: [email protected]] on 2009-10-14, for <25.12 USB interrupt fix> */
		regulator_enable(twl->usb1v8);
#endif
		regulator_enable(twl->usb1v5);
		pwr &= ~PHY_PWR_PHYPWD;
		WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
		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  {
		msleep(250); // LGE_CHANGE [HUB] jjun.lee for USB unplug detect (TI Girish)
		pwr |= PHY_PWR_PHYPWD;
		WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
		regulator_disable(twl->usb1v5);
		regulator_disable(twl->usb1v8);
#if 1	/* LGE_CHANGE [HEAVEN: [email protected]] on 2009-10-14, for <25.12 USB interrupt fix> */
		/* Put VUSB3V1 regulator in sleep mode */
		twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x08,
				                        VUSB_DEDICATED2);
#else
			regulator_disable(twl->usb3v1);
#endif
	}
	pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
	printk(KERN_ERR "twl4030_phy_power - : PHY_PWR_CTRL=%x ====^^==== (twl4030-usb.c)\n", pwr);
	pwr = twl4030_usb_read(twl, PHY_CLK_CTRL);
	printk(KERN_ERR "twl4030_phy_power - : PHY_CLK_CTRL=%x ====^^==== (twl4030-usb.c)\n", pwr);
	pwr = twl4030_usb_read(twl, PHY_CLK_CTRL_STS);
	printk(KERN_ERR "twl4030_phy_power - : PHY_CLK_CTRL_STS=%x ====^^==== (twl4030-usb.c)\n", pwr);
}
Пример #10
0
static void twl4030_i2c_access(bool on)
{
	int val;

	if ((val = twl4030_usb_read(PHY_CLK_CTRL)) >= 0) {
		if (on) {
			/* enable DPLL to access PHY registers over I2C */
			val |= REQ_PHY_DPLL_CLK;
			twl4030_usb_write(PHY_CLK_CTRL, (uint8_t)val);

			while (!(twl4030_usb_read(PHY_CLK_CTRL_STS) & PHY_DPLL_CLK)) {
				spin(10);
			}
			if (!(twl4030_usb_read(PHY_CLK_CTRL_STS) & PHY_DPLL_CLK))
				printf("Timeout setting T2 HSUSB " "PHY DPLL clock\n");
		} else {
			/* let ULPI control the DPLL clock */
			val &= ~REQ_PHY_DPLL_CLK;
			twl4030_usb_write(PHY_CLK_CTRL, (uint8_t)val);
		}
	}
	return;
}
Пример #11
0
static void twl4030_phy_power(struct twl4030_usb *twl, int on)
{
	u8 pwr;

	pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
	if (on) {
		pwr &= ~PHY_PWR_PHYPWD;
		WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
		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  {
		pwr |= PHY_PWR_PHYPWD;
		WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
	}
}
Пример #12
0
/*
 * 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;
}
Пример #13
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);
#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_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);
	}
}
Пример #15
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;
}
Пример #16
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;
}
Пример #17
0
static int twl4030_usb_remove(struct platform_device *pdev)
{
	struct twl4030_usb *twl = platform_get_drvdata(pdev);
	int val;

	usb_remove_phy(&twl->phy);
	pm_runtime_get_sync(twl->dev);
	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);

	/* idle ulpi before powering off */
	if (cable_present(twl->linkstat))
		pm_runtime_put_noidle(twl->dev);
	pm_runtime_mark_last_busy(twl->dev);
	pm_runtime_put_sync_suspend(twl->dev);
	pm_runtime_disable(twl->dev);

	/* 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);

	return 0;
}
Пример #18
0
static int twl4030_usb_clear_bits(uint8_t reg, uint8_t bits)
{
	return twl4030_usb_write(reg + 2, bits);
}
Пример #19
0
static inline int
twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits)
{
	return twl4030_usb_write(twl, reg + 2, bits);
}
Пример #20
0
static inline int
twl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits)
{
	return twl4030_usb_write(reg + 1, bits);
}
Пример #21
0
static inline int
twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits)
{
	return twl4030_usb_write(twl, ULPI_CLR(reg), bits);
}
Пример #22
0
static inline int
twl4030_usb_set_bits(struct twl4030_usb *twl, u8 reg, u8 bits)
{
	return twl4030_usb_write(twl, ULPI_SET(reg), bits);
}
Пример #23
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;
}
Пример #24
0
static int twl4030_usb_set_bits(uint8_t reg, uint8_t bits)
{
	return twl4030_usb_write(reg + 1, bits);
}