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); } } }
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); } } } }
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); } } }
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); } } }
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); }
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(); }
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(); }