static void tegra_change_otg_state(struct tegra_otg_data *tegra,
				enum usb_otg_state to)
{
	struct otg_transceiver *otg = &tegra->otg;
	enum usb_otg_state from = otg->state;

	if(!tegra->interrupt_mode){
		DBG("OTG: Vbus detection is disabled");
		return;
	}

	DBG("%s(%d) requested otg state %s-->%s\n", __func__,
		__LINE__, tegra_state_name(from), tegra_state_name(to));

	if (to != OTG_STATE_UNDEFINED && from != to) {
		otg->state = to;
		dev_info(tegra->otg.dev, "%s --> %s\n", tegra_state_name(from),
					      tegra_state_name(to));

		if (from == OTG_STATE_A_SUSPEND) {
			if (to == OTG_STATE_B_PERIPHERAL && otg->gadget)
				usb_gadget_vbus_connect(otg->gadget);
			else if (to == OTG_STATE_A_HOST)
				tegra_start_host(tegra);
		} else if (from == OTG_STATE_A_HOST) {
			if (to == OTG_STATE_A_SUSPEND)
				tegra_stop_host(tegra);
		} else if (from == OTG_STATE_B_PERIPHERAL && otg->gadget) {
			if (to == OTG_STATE_A_SUSPEND)
				usb_gadget_vbus_disconnect(otg->gadget);
		}
	}
}
Example #2
0
static void irq_work(struct work_struct *work)
{
	struct tegra_otg_data *tegra =
		container_of(work, struct tegra_otg_data, work);
	struct otg_transceiver *otg = &tegra->otg;
	enum usb_otg_state from = otg->state;
	enum usb_otg_state to = OTG_STATE_UNDEFINED;
	unsigned long flags;
	unsigned long status;

	clk_enable(tegra->clk);

	spin_lock_irqsave(&tegra->lock, flags);

	status = tegra->int_status;

	if (tegra->int_status & USB_ID_INT_STATUS) {
		if (status & USB_ID_STATUS) {
			if ((status & USB_VBUS_STATUS) && (from != OTG_STATE_A_HOST))
				to = OTG_STATE_B_PERIPHERAL;
			else
				to = OTG_STATE_A_SUSPEND;
		}
		else
			to = OTG_STATE_A_HOST;
	}
	if (from != OTG_STATE_A_HOST) {
		if (tegra->int_status & USB_VBUS_INT_STATUS) {
			if (status & USB_VBUS_STATUS)
				to = OTG_STATE_B_PERIPHERAL;
			else
				to = OTG_STATE_A_SUSPEND;
		}
	}
	spin_unlock_irqrestore(&tegra->lock, flags);

	if (to != OTG_STATE_UNDEFINED) {
		otg->state = to;

		dev_info(tegra->otg.dev, "%s --> %s\n", tegra_state_name(from),
					      tegra_state_name(to));

		if (to == OTG_STATE_A_SUSPEND) {
			if (from == OTG_STATE_A_HOST)
				tegra_stop_host(tegra);
			else if (from == OTG_STATE_B_PERIPHERAL && otg->gadget)
				usb_gadget_vbus_disconnect(otg->gadget);
		} else if (to == OTG_STATE_B_PERIPHERAL && otg->gadget) {
			if (from == OTG_STATE_A_SUSPEND)
				usb_gadget_vbus_connect(otg->gadget);
		} else if (to == OTG_STATE_A_HOST) {
			if (from == OTG_STATE_A_SUSPEND)
			tegra_start_host(tegra);
		}
	}
	clk_disable(tegra->clk);

}
static void tegra_change_otg_state(struct tegra_otg_data *tegra,
				enum usb_otg_state to)
{
	struct otg_transceiver *otg = &tegra->otg;
	enum usb_otg_state from = otg->state;

	if(!tegra->interrupt_mode){
		DBG("OTG: Vbus detection is disabled");
		return;
	}

	//&*&*&*AL1_20121121 skip tegra_stop_host api to avoid device hang on suspend handle
	if (from == OTG_STATE_A_HOST && to == OTG_STATE_A_SUSPEND) {		
		if (tegra->pdev->dev.power.is_suspended) {
			DBG("OTG: host is suspended\n");
			//&*&*&*AL1_20121126
			tegra_otg_notify_event(otg, USB_EVENT_NONE);
			//&*&*&*AL2_20121126
			return;
		}	
	}
	//&*&*&*AL2_20121121 skip tegra_stop_host api to avoid device hang on suspend handle

	DBG("%s(%d) requested otg state %s-->%s\n", __func__,
		__LINE__, tegra_state_name(from), tegra_state_name(to));

	if (to != OTG_STATE_UNDEFINED && from != to) {
		otg->state = to;
		dev_info(tegra->otg.dev, "%s --> %s\n", tegra_state_name(from),
					      tegra_state_name(to));

		#if 1 //CL2N+
		if (tegra->charger_cb)
			tegra->charger_cb(to, from, tegra->charger_cb_data);
		#endif //CL2N-
		if (from == OTG_STATE_A_SUSPEND) {
			if (to == OTG_STATE_B_PERIPHERAL && otg->gadget) {
				usb_gadget_vbus_connect(otg->gadget);
				tegra_otg_notify_event(otg, USB_EVENT_VBUS);
			}
			else if (to == OTG_STATE_A_HOST) {
				tegra_start_host(tegra);
				tegra_otg_notify_event(otg, USB_EVENT_ID);
			}
		} else if (from == OTG_STATE_A_HOST) {
			if (to == OTG_STATE_A_SUSPEND) {
				tegra_stop_host(tegra);
				tegra_otg_notify_event(otg, USB_EVENT_NONE);
			}
		} else if (from == OTG_STATE_B_PERIPHERAL && otg->gadget) {
			if (to == OTG_STATE_A_SUSPEND) {
				usb_gadget_vbus_disconnect(otg->gadget);
				tegra_otg_notify_event(otg, USB_EVENT_NONE);
			}
		}
	}
}
Example #4
0
static void tegra_change_otg_state(struct tegra_otg_data *tegra,
				enum usb_otg_state to)
{
	struct otg_transceiver *otg = &tegra->otg;
	enum usb_otg_state from = otg->state;

	if(!tegra->interrupt_mode){
		DBG("OTG: Vbus detection is disabled");
		return;
	}

	DBG("%s(%d) requested otg state %s-->%s\n", __func__,
		__LINE__, tegra_state_name(from), tegra_state_name(to));

	if (to != OTG_STATE_UNDEFINED && from != to) {
		otg->state = to;
		/*dev_info(tegra->otg.dev, "%s --> %s\n", tegra_state_name(from),
					      tegra_state_name(to));*/
		USBH_INFO("%s --> %s\n", tegra_state_name(from), tegra_state_name(to));

		if (from == OTG_STATE_A_SUSPEND) {
			if (to == OTG_STATE_B_PERIPHERAL && otg->gadget) {
				usb_gadget_vbus_connect(otg->gadget);
#ifdef CONFIG_USB_ANDROID_PROJECTOR
				if (check_htc_mode_status() != NOT_ON_AUTOBOT) {
					htc_mode_enable(0);
					android_switch_default();
				}
#endif
			} else if (to == OTG_STATE_A_HOST) {
				tegra_start_host(tegra);
				dump_otg_state();
			}
		} else if (from == OTG_STATE_A_HOST) {
			if (to == OTG_STATE_A_SUSPEND)
				tegra_stop_host(tegra);
		} else if (from == OTG_STATE_B_PERIPHERAL && otg->gadget) {
			if (to == OTG_STATE_A_SUSPEND)
				usb_gadget_vbus_disconnect(otg->gadget);
		}
	} else if (to != OTG_STATE_UNDEFINED && from == to) {
		USBH_INFO("%s --> %s (%d)\n", tegra_state_name(from), tegra_state_name(to), USB_disabled);
		if (USB_disabled) {
			usb_gadget_disconnect(otg->gadget);
		} else if (to == OTG_STATE_B_PERIPHERAL) {
			usb_gadget_vbus_connect(otg->gadget);
			usb_gadget_connect(otg->gadget);
		} else {
			usb_gadget_connect(otg->gadget);
		}
	}
}
Example #5
0
static int tegra_otg_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct tegra_otg_data *tegra_otg = platform_get_drvdata(pdev);
	struct otg_transceiver *otg = &tegra_otg->otg;
	enum usb_otg_state from = otg->state;
	/* store the interupt enable for cable ID and VBUS */
	clk_enable(tegra_otg->clk);
	tegra_otg->intr_reg_data = readl(tegra_otg->regs + USB_PHY_WAKEUP);
	clk_disable(tegra_otg->clk);

	if (from == OTG_STATE_A_HOST)
		tegra_stop_host(tegra_otg);
	else if (from == OTG_STATE_B_PERIPHERAL && otg->gadget)
		usb_gadget_vbus_disconnect(otg->gadget);

	otg->state = OTG_STATE_A_SUSPEND;
	tegra_otg_disable_clk();
	return 0;
}
Example #6
0
static void tegra_change_otg_state(struct tegra_otg_data *tegra,
				enum usb_otg_state to)
{
	struct otg_transceiver *otg = &tegra->otg;
	enum usb_otg_state from = otg->state;

	if(!tegra->interrupt_mode){
		DBG("OTG: Vbus detection is disabled");
		return;
	}

	DBG("%s(%d) requested otg state %s-->%s\n", __func__,
		__LINE__, tegra_state_name(from), tegra_state_name(to));

	if (to != OTG_STATE_UNDEFINED && from != to) {
		otg->state = to;
		dev_info(tegra->otg.dev, "%s --> %s\n", tegra_state_name(from),
					      tegra_state_name(to));

		if (tegra->charger_cb)
			tegra->charger_cb(to, from, tegra->charger_cb_data);

		if (from == OTG_STATE_A_SUSPEND) {
			if (to == OTG_STATE_B_PERIPHERAL && otg->gadget)
				usb_gadget_vbus_connect(otg->gadget);
			else if (to == OTG_STATE_A_HOST)
				tegra_start_host(tegra);
		} else if (from == OTG_STATE_A_HOST) {
			if (to == OTG_STATE_A_SUSPEND)
			{
				tegra_stop_host(tegra);
			 #ifdef CONFIG_MHL_SII8334
			      if(zte_get_board_id() > 1)
				    CBUS_ID_Opened_AfterPlugedout();
			#endif	 
			}
		} else if (from == OTG_STATE_B_PERIPHERAL && otg->gadget) {
			if (to == OTG_STATE_A_SUSPEND)
				usb_gadget_vbus_disconnect(otg->gadget);
		}
	}
}
Example #7
0
static void tegra_otg_work(struct work_struct *work)
{
    struct tegra_otg_data *tegra = container_of(work, struct tegra_otg_data, work);
    struct otg_transceiver *otg = &tegra->otg;
    enum usb_otg_state from = otg->state;
    enum usb_otg_state to = OTG_STATE_UNDEFINED;
    unsigned long event = tegra->event;

    unsigned long val;
    unsigned long flags;

    if (event == USB_EVENT_VBUS)
        to = OTG_STATE_B_PERIPHERAL;
    else if (event == USB_EVENT_ID)
        to = OTG_STATE_A_HOST;
    else
        to = OTG_STATE_A_SUSPEND;

    if (from == to)
        return;

    otg->state = to;

    dev_info(tegra->otg.dev, "%s --> %s", tegra_state_name(from),
             tegra_state_name(to));
    dev_info(tegra->otg.dev, "host: %p, gadget: %p", otg->host, otg->gadget);

    clk_enable(tegra->clk);

    if ((to == OTG_STATE_A_HOST) && (from == OTG_STATE_B_PERIPHERAL)
            && otg->gadget) {

        usb_gadget_vbus_disconnect(otg->gadget);
        wake_unlock(&tegra->wake_lock);

        spin_lock_irqsave(&tegra->lock, flags);
        val = otg_readl(tegra, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        val &= ~TEGRA_INTS; /* Do NOT ack pending interrupts */

        val &= ~TEGRA_ID_SW_VALUE;			/* CableID is 0 */
        val &= ~TEGRA_VBUS_INT_EN;			/* We can't use VBUS ints in host mode */

        otg_writel(tegra, val, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        spin_unlock_irqrestore(&tegra->lock, flags);

        tegra_start_host(tegra);

    } else if ((to == OTG_STATE_A_HOST) && (from == OTG_STATE_A_SUSPEND)) {

        spin_lock_irqsave(&tegra->lock, flags);
        val = otg_readl(tegra, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        val &= ~TEGRA_INTS; /* Do NOT ack pending interrupts */

        val &= ~TEGRA_ID_SW_VALUE;			/* CableID is 0 */
        val &= ~TEGRA_VBUS_INT_EN;			/* We can't use VBUS ints in host mode */

        otg_writel(tegra, val, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        spin_unlock_irqrestore(&tegra->lock, flags);

        tegra_start_host(tegra);

    } else if ((to == OTG_STATE_A_SUSPEND) && (from == OTG_STATE_A_HOST)) {

        tegra_stop_host(tegra);

        spin_lock_irqsave(&tegra->lock, flags);
        val = otg_readl(tegra, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        val &= ~TEGRA_INTS; /* Do NOT ack pending interrupts */

        val |=  TEGRA_ID_SW_VALUE;			/* CableID is 1 */
        val |=  TEGRA_VBUS_INT_EN;			/* Use VBUS ints in suspend mode to wakeup */

        otg_writel(tegra, val, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        spin_unlock_irqrestore(&tegra->lock, flags);

    } else if ((to == OTG_STATE_B_PERIPHERAL) && (from == OTG_STATE_A_HOST)
               && otg->gadget) {

        tegra_stop_host(tegra);

        spin_lock_irqsave(&tegra->lock, flags);
        val = otg_readl(tegra, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        val &= ~TEGRA_INTS; /* Do NOT ack pending interrupts */

        val |=  TEGRA_ID_SW_VALUE;			/* CableID is 1 */
        val |=  TEGRA_VBUS_INT_EN;			/* Use VBUS ints in suspend mode to wakeup */

        otg_writel(tegra, val, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        spin_unlock_irqrestore(&tegra->lock, flags);

        wake_lock(&tegra->wake_lock);
        usb_gadget_vbus_connect(otg->gadget);

    } else if ((to == OTG_STATE_B_PERIPHERAL) && (from == OTG_STATE_A_SUSPEND)
               && otg->gadget) {

        spin_lock_irqsave(&tegra->lock, flags);
        val = otg_readl(tegra, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        val &= ~TEGRA_INTS; /* Do NOT ack pending interrupts */

        val |=  TEGRA_ID_SW_VALUE;			/* CableID is 1 */
        val |=  TEGRA_VBUS_INT_EN;			/* Use VBUS ints in suspend mode to wakeup */

        otg_writel(tegra, val, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        spin_unlock_irqrestore(&tegra->lock, flags);

        wake_lock(&tegra->wake_lock);
        usb_gadget_vbus_connect(otg->gadget);

    } else if ((to == OTG_STATE_A_SUSPEND) && (from == OTG_STATE_B_PERIPHERAL)
               && otg->gadget) {

        usb_gadget_vbus_disconnect(otg->gadget);
        wake_unlock(&tegra->wake_lock);

        spin_lock_irqsave(&tegra->lock, flags);
        val = otg_readl(tegra, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        val &= ~TEGRA_INTS; /* Do NOT ack pending interrupts */

        val |=  TEGRA_ID_SW_VALUE;			/* CableID is 1 */
        val |=  TEGRA_VBUS_INT_EN;			/* Use VBUS ints in suspend mode to wakeup */

        otg_writel(tegra, val, TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
        spin_unlock_irqrestore(&tegra->lock, flags);

    }

    /* Delay a bit toensure registers are updated */
    udelay(1);

    clk_disable(tegra->clk);
}
Example #8
0
static void irq_work(struct work_struct *work)
{
	struct tegra_otg_data *tegra =
		container_of(work, struct tegra_otg_data, work);
	struct otg_transceiver *otg = &tegra->otg;
	enum usb_otg_state from = otg->state;
	enum usb_otg_state to = OTG_STATE_UNDEFINED;
	unsigned long flags;
	unsigned long status,val;

	val = otg_readl(tegra, USB_PHY_WAKEUP);

	clk_enable(tegra->clk);

	spin_lock_irqsave(&tegra->lock, flags);

	status = tegra->int_status;

	if (tegra->rcv_host_en && board_mfg_mode() == 2 /* recovery mode */) {
		if (from != OTG_STATE_A_HOST) {
			if (tegra->int_status & USB_VBUS_INT_STATUS) {
				if (status & USB_VBUS_STATUS)
					to = OTG_STATE_A_HOST;
				else
					to = OTG_STATE_A_SUSPEND;
			}
		}
	}
	else {  /* NV Original */
#if defined(CONFIG_USB_HOST_MODE)
		if (tegra->int_status & USB_ID_INT_STATUS) {
			if (status & USB_ID_STATUS) {
				if ((status & USB_VBUS_STATUS) && (from != OTG_STATE_A_HOST))
					to = OTG_STATE_B_PERIPHERAL;
				else
					to = OTG_STATE_A_SUSPEND;
			}
			else
				to = OTG_STATE_A_HOST;
		}
#endif
		if (from != OTG_STATE_A_HOST) {
			if (tegra->int_status & USB_VBUS_INT_STATUS) {
				if (status & USB_VBUS_STATUS)
					to = OTG_STATE_B_PERIPHERAL;
				else
					to = OTG_STATE_A_SUSPEND;
			}
		}
	}
	spin_unlock_irqrestore(&tegra->lock, flags);

	if (to != OTG_STATE_UNDEFINED) {
		otg->state = to;

		pr_info("[USBOTG] %s --> %s\n", tegra_state_name(from),
					      tegra_state_name(to));

		if (to == OTG_STATE_A_SUSPEND) {
			if (from == OTG_STATE_A_HOST)
				tegra_stop_host(tegra);
			else if (from == OTG_STATE_B_PERIPHERAL && otg->gadget)
				usb_gadget_vbus_disconnect(otg->gadget);
			else if (from == OTG_STATE_UNDEFINED && otg->gadget) {
				USB_INFO("from == OTG_STATE_UNDEFINED \n");
				usb_gadget_vbus_disconnect(otg->gadget);
			}
		} else if (to == OTG_STATE_B_PERIPHERAL && otg->gadget) {
			if (from == OTG_STATE_A_SUSPEND) {
				usb_gadget_vbus_connect(otg->gadget);
#if CONFIG_USB_ANDROID_PROJECTOR
				if (check_htc_mode_status() != NOT_ON_AUTOBOT) {
					htc_mode_enable(0);
					android_switch_adb_ums();
				}
#endif
			}
		} else if (to == OTG_STATE_A_HOST) {
			if (from == OTG_STATE_A_SUSPEND)
				tegra_start_host(tegra);
		}
	}
	clk_disable(tegra->clk);
	tegra_otg_disable_clk();
}
Example #9
0
static void irq_work(struct work_struct *work)
{
	struct tegra_otg_data *tegra =
		container_of(work, struct tegra_otg_data, work);
	struct otg_transceiver *otg = &tegra->otg;
	enum usb_otg_state from = otg->state;
	enum usb_otg_state to = OTG_STATE_UNDEFINED;
	unsigned long flags;
	unsigned long status;

	if (tegra->detect_vbus) {
		tegra->detect_vbus = false;
		tegra_otg_enable_clk();
		return;
	}

	clk_enable(tegra->clk);

	spin_lock_irqsave(&tegra->lock, flags);

	status = tegra->int_status;

	/* Debug prints */
	DBG("%s(%d) status = 0x%x\n", __func__, __LINE__, status);
	if ((status & USB_ID_INT_STATUS) &&
			(status & USB_VBUS_INT_STATUS))
		DBG("%s(%d) got vbus & id interrupt\n", __func__, __LINE__);
	else {
		if (status & USB_ID_INT_STATUS)
			DBG("%s(%d) got id interrupt\n", __func__, __LINE__);
		if (status & USB_VBUS_INT_STATUS)
			DBG("%s(%d) got vbus interrupt\n", __func__, __LINE__);
	}

	if (tegra->int_status & USB_ID_INT_STATUS) {
		if (status & USB_ID_STATUS) {
			if ((status & USB_VBUS_STATUS) && (from != OTG_STATE_A_HOST))
				to = OTG_STATE_B_PERIPHERAL;
			else
				to = OTG_STATE_A_SUSPEND;
		}
		else
			to = OTG_STATE_A_HOST;
	}
	if (from != OTG_STATE_A_HOST) {
		if (tegra->int_status & USB_VBUS_INT_STATUS) {
			if (status & USB_VBUS_STATUS)
				to = OTG_STATE_B_PERIPHERAL;
			else
				to = OTG_STATE_A_SUSPEND;
		}
	}
	spin_unlock_irqrestore(&tegra->lock, flags);

	if (to != OTG_STATE_UNDEFINED) {
		otg->state = to;

		dev_info(tegra->otg.dev, "%s --> %s\n", tegra_state_name(from),
					      tegra_state_name(to));

		if (tegra->charger_cb)
			tegra->charger_cb(to, from, tegra->charger_cb_data);

		if (to == OTG_STATE_A_SUSPEND) {
#ifdef CONFIG_MACH_SAMSUNG_VARIATION_TEGRA
#ifdef CONFIG_USB_HOST_NOTIFY
			tegra->ndev.mode = NOTIFY_NONE_MODE;
#endif
#endif
			if (from == OTG_STATE_A_HOST) {
#ifdef CONFIG_MACH_SAMSUNG_VARIATION_TEGRA
#ifdef CONFIG_USB_HOST_NOTIFY
				host_state_notify(&tegra->ndev,
					 NOTIFY_HOST_REMOVE, false);
#endif
#endif
				tegra_stop_host(tegra);
			} else if (from == OTG_STATE_B_PERIPHERAL
					&& otg->gadget)
#ifdef _SEC_DM_
				if (!usb_access_lock)
#endif
					usb_gadget_vbus_disconnect(otg->gadget);
		} else if (to == OTG_STATE_B_PERIPHERAL && otg->gadget) {
			if (from != OTG_STATE_B_PERIPHERAL)
#ifdef _SEC_DM_
				if (!usb_access_lock)
#endif
					usb_gadget_vbus_connect(otg->gadget);
#ifdef CONFIG_MACH_SAMSUNG_VARIATION_TEGRA
#ifdef CONFIG_USB_HOST_NOTIFY
			tegra->ndev.mode = NOTIFY_PERIPHERAL_MODE;
#endif
#endif
		} else if (to == OTG_STATE_A_HOST) {
			if (from == OTG_STATE_A_SUSPEND)
				tegra_start_host(tegra);
#ifdef CONFIG_MACH_SAMSUNG_VARIATION_TEGRA
			else if (from == OTG_STATE_B_PERIPHERAL) {
#ifdef _SEC_DM_
				if (!usb_access_lock)
#endif
					usb_gadget_vbus_disconnect(otg->gadget);
				tegra_start_host(tegra);
			}
#ifdef CONFIG_USB_HOST_NOTIFY
			tegra->ndev.mode = NOTIFY_HOST_MODE;
			host_state_notify(&tegra->ndev, NOTIFY_HOST_ADD, false);
#endif
#endif
		}
	}
	clk_disable(tegra->clk);
	tegra_otg_disable_clk();
}