示例#1
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);
		}
	}
}
示例#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,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();
}