Example #1
0
/**
 * funct_host_notify_timer() - Initialize the timer for USB host driver.
 * @data: usb host data.
 *
 * This function runs the timer for the USB host mode.
 */
static void funct_host_notify_timer(unsigned long data)
{
	if (!cpu_is_u5500()) {
		struct musb	*musb = (struct musb *)data;
		unsigned long	flags;
		u8	devctl;
		spin_lock_irqsave(&musb->lock, flags);

		stm_set_peripheral_clock(PERI5_CLK_ENABLE);

		devctl = musb_readb(musb->mregs, MUSB_DEVCTL);

		switch (musb->xceiv->state) {
		case OTG_STATE_A_WAIT_BCON:
			if (devctl & MUSB_DEVCTL_BDEVICE) {
				musb->xceiv->state = OTG_STATE_B_IDLE;
				MUSB_DEV_MODE(musb);
			} else {
				musb->xceiv->state = OTG_STATE_A_IDLE;
				MUSB_HST_MODE(musb);
			}

#ifdef CONFIG_PM
		if (!(devctl & MUSB_DEVCTL_SESSION))
			stm_musb_context(USB_DISABLE);
#endif


		break;
		case OTG_STATE_A_SUSPEND:
		default:
		break;
		}

		stm_set_peripheral_clock(PERI5_CLK_DISABLE);

		spin_unlock_irqrestore(&musb->lock, flags);
		DBG(1, "otg_state %s devctl %d\n", otg_state_string(musb),
			devctl);
	}
}
/**
 * usb_device_phy_en() - for enabling the 5V to usb gadget
 * @enable: to enabling the Phy for device.
 *
 * This function used to set the voltage for USB gadget mode.
 */
static void usb_device_phy_en(int enable)
{
	int volt = 0;
	int ret = -1;

	if (phy_enable_stat == enable)
		return;

	if (enable == USB_ENABLE) {
		wake_lock(&ab8500_musb_wakelock);
		ux500_pins_enable(usb_gpio_pins);
		clk_enable(sysclock);
		phy_enable_stat = USB_ENABLE;
		regulator_enable(musb_vape_supply);
		regulator_enable(musb_smps2_supply);

		/* Set Vintcore12 LDO to 1.3V */
		ret = regulator_set_voltage(musb_vintcore_supply,
						1300000, 1350000);
		if (ret < 0)
			printk(KERN_ERR "Failed to set the Vintcore"
					" to 1.3V, ret=%d\n", ret);
		ret = regulator_set_optimum_mode(musb_vintcore_supply,
						 28000);
		if (ret < 0)
			printk(KERN_ERR "Failed to set optimum mode"
					" (ret=%d)\n", ret);
		regulator_enable(musb_vintcore_supply);
		volt = regulator_get_voltage(musb_vintcore_supply);
		if ((volt != 1300000) && (volt != 1350000))
			printk(KERN_ERR "Vintcore is not"
					" set to 1.3V"
					" volt=%d\n", volt);
#ifdef	CONFIG_PM
		stm_musb_context(USB_ENABLE);
#endif

		/* Workaround for USB performance issue. */
		schedule_delayed_work_on(0,
				 &work_usb_workaround,
				 msecs_to_jiffies(USB_PROBE_DELAY));

		prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
				DEVICE_NAME, 100);

		abx500_set_register_interruptible(device,
				AB8500_USB,
				AB8500_USB_PHY_CTRL_REG,
				AB8500_USB_DEVICE_ENABLE);
	} else { /* enable == USB_DISABLE */
		/*
		 * Workaround: Sometimes the DISCONNECT interrupt is
		 * not generated in musb_core. Force a disconnect if
		 * necessary before we power down the PHY.
		 */
		stm_musb_force_disconnect();

		if (boot_time_flag)
			boot_time_flag = USB_DISABLE;

		/*
		 * Workaround for bug31952 in ABB cut2.0. Write 0x1
		 * before disabling the PHY.
		 */
		abx500_set_register_interruptible(device, AB8500_USB,
			     AB8500_USB_PHY_CTRL_REG,
			     AB8500_USB_DEVICE_ENABLE);

		udelay(200);

		abx500_set_register_interruptible(device,
			AB8500_USB,
			AB8500_USB_PHY_CTRL_REG,
			AB8500_USB_DEVICE_DISABLE);
		prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
				DEVICE_NAME, 50);

		/* Workaround for USB performance issue. */
		cancel_delayed_work_sync(&work_usb_workaround);
		prcmu_qos_update_requirement(PRCMU_QOS_ARM_OPP,
					     "usb", 25);

		prcmu_release_usb_wakeup_state();
		phy_enable_stat = USB_DISABLE;
		regulator_disable(musb_vape_supply);
		regulator_disable(musb_smps2_supply);
		regulator_disable(musb_vintcore_supply);
		regulator_set_optimum_mode(musb_vintcore_supply, 0);
		/* Set Vintcore12 LDO to 0V to 1.35V */
		ret = regulator_set_voltage(musb_vintcore_supply,
						0000000, 1350000);
		if (ret < 0)
			printk(KERN_ERR "Failed to set the Vintcore"
					" to 0V to 1.35V,"
					" ret=%d\n", ret);
		clk_disable(sysclock);
#ifdef CONFIG_PM
		stm_musb_context(USB_DISABLE);
#endif
		ux500_pins_disable(usb_gpio_pins);
		wake_unlock(&ab8500_musb_wakelock);
	}
}
/**
 * usb_device_phy_en() - for enabling the 5V to usb gadget
 * @enable: to enabling the Phy for device.
 *
 * This function used to set the voltage for USB gadget mode.
 */
static void usb_device_phy_en(int enable)
{
	int volt = 0;
	int ret = -1;

	if (phy_enable_stat == enable)
		return;

	if (enable == USB_ENABLE) {
		wake_lock(&ab8500_musb_wakelock);
		clk_enable(sysclock);
		phy_enable_stat = USB_ENABLE;
		regulator_enable(musb_vape_supply);
		regulator_enable(musb_smps2_supply);

		/* Set Vintcore12 LDO to 1.3V */
		ret = regulator_set_voltage(musb_vintcore_supply,
						1300000, 1350000);
		if (ret < 0)
			printk(KERN_ERR "Failed to set the Vintcore"
					" to 1.3V, ret=%d\n", ret);
		ret = regulator_set_optimum_mode(musb_vintcore_supply,
						 28000);
		if (ret < 0)
			printk(KERN_ERR "Failed to set optimum mode"
					" (ret=%d)\n", ret);
		regulator_enable(musb_vintcore_supply);
		volt = regulator_get_voltage(musb_vintcore_supply);
		if ((volt != 1300000) && (volt != 1350000))
			printk(KERN_ERR "Vintcore is not"
					" set to 1.3V"
					" volt=%d\n", volt);
#ifdef	CONFIG_PM
		stm_musb_context(USB_ENABLE);
#endif
		usb_kick_watchdog();

		/* Workaround for USB performance issue. */
		cpufreq_usb_connect_notify(true);

		prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
				DEVICE_NAME, 100);

		abx500_set_register_interruptible(device,
				AB8500_USB,
				AB8500_USB_PHY_CTRL_REG,
				AB8500_USB_DEVICE_ENABLE);
	} else { /* enable == USB_DISABLE */
		if (boot_time_flag)
			boot_time_flag = USB_DISABLE;

		/*
		 * Workaround for bug31952 in ABB cut2.0. Write 0x1
		 * before disabling the PHY.
		 */
		abx500_set_register_interruptible(device, AB8500_USB,
			     AB8500_USB_PHY_CTRL_REG,
			     AB8500_USB_DEVICE_ENABLE);

		udelay(100);

		abx500_set_register_interruptible(device,
			AB8500_USB,
			AB8500_USB_PHY_CTRL_REG,
			AB8500_USB_DEVICE_DISABLE);
		prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
				DEVICE_NAME, 50);

		/* Workaround for USB performance issue. */
		cpufreq_usb_connect_notify(false);

		prcmu_release_usb_wakeup_state();
		phy_enable_stat = USB_DISABLE;
		regulator_disable(musb_vape_supply);
		regulator_disable(musb_smps2_supply);
		regulator_disable(musb_vintcore_supply);
		regulator_set_optimum_mode(musb_vintcore_supply, 0);
		/* Set Vintcore12 LDO to 0V to 1.35V */
		ret = regulator_set_voltage(musb_vintcore_supply,
						0000000, 1350000);
		if (ret < 0)
			printk(KERN_ERR "Failed to set the Vintcore"
					" to 0V to 1.35V,"
					" ret=%d\n", ret);
		clk_disable(sysclock);
#ifdef CONFIG_PM
		stm_musb_context(USB_DISABLE);
#endif
		wake_unlock(&ab8500_musb_wakelock);
	}
}