static int tegra_otg_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct tegra_otg_data *tegra_otg = platform_get_drvdata(pdev); USB_INFO("%s",__func__); /* 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); tegra_otg_disable_clk(); return 0; }
static int tegra_otg_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); 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_B_PERIPHERAL && otg->gadget) usb_gadget_vbus_disconnect(otg->gadget); tegra_otg_disable_clk(); return 0; }
static int tegra_otg_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); 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); // writel(0, (tegra_otg->regs + USB_PHY_WAKEUP)); clk_disable(tegra_otg->clk); printk(KERN_INFO "%s tegra_otg->intr_reg_data=%#X\n", __func__, tegra_otg->intr_reg_data); 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; }
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; 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); if(from != OTG_STATE_A_HOST){ wake_lock_timeout(&usb_wake_lock, HZ); printk(KERN_INFO "vbus disconnected, unlock wakelock\n"); } } } else if (to == OTG_STATE_B_PERIPHERAL && otg->gadget) { if (from == OTG_STATE_A_SUSPEND) { usb_gadget_vbus_connect(otg->gadget); wake_lock(&usb_wake_lock); printk(KERN_INFO "vbus connected, lock wakelock\n"); } } 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,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(); }