static irqreturn_t nop_gpio_vbus_thread(int irq, void *data) { struct usb_phy_generic *nop = data; struct usb_otg *otg = nop->phy.otg; int vbus, status; vbus = gpiod_get_value(nop->gpiod_vbus); if ((vbus ^ nop->vbus) == 0) return IRQ_HANDLED; nop->vbus = vbus; if (vbus) { status = USB_EVENT_VBUS; otg->state = OTG_STATE_B_PERIPHERAL; nop->phy.last_event = status; usb_gadget_vbus_connect(otg->gadget); /* drawing a "unit load" is *always* OK, except for OTG */ nop_set_vbus_draw(nop, 100); atomic_notifier_call_chain(&nop->phy.notifier, status, otg->gadget); } else { nop_set_vbus_draw(nop, 0); usb_gadget_vbus_disconnect(otg->gadget); status = USB_EVENT_NONE; otg->state = OTG_STATE_B_IDLE; nop->phy.last_event = status; atomic_notifier_call_chain(&nop->phy.notifier, status, otg->gadget); } return IRQ_HANDLED; }
static int isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) { struct isp1301 *isp = container_of(otg, struct isp1301, otg); if (!otg || isp != the_transceiver) return -ENODEV; if (!gadget) { OTG_IRQ_EN_REG = 0; if (!isp->otg.default_a) enable_vbus_draw(isp, 0); usb_gadget_vbus_disconnect(isp->otg.gadget); isp->otg.gadget = 0; power_down(isp); return 0; } #ifdef CONFIG_USB_OTG isp->otg.gadget = gadget; dev_dbg(&isp->client.dev, "registered gadget\n"); /* gadget driver may be suspended until vbus_connect () */ if (isp->otg.host) return isp1301_otg_enable(isp); return 0; #elif !defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OHCI_HCD_MODULE) isp->otg.gadget = gadget; // FIXME update its refcount OTG_CTRL_REG = (OTG_CTRL_REG & OTG_CTRL_MASK & ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS)) | OTG_ID; power_up(isp); isp->otg.state = OTG_STATE_B_IDLE; if (machine_is_omap_h2()) isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, INTR_SESS_VLD); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, INTR_VBUS_VLD); dev_info(&isp->client.dev, "B-Peripheral sessions ok\n"); dump_regs(isp, __func__); /* If this has a Mini-AB connector, this mode is highly * nonstandard ... but can be handy for testing, so long * as you don't plug a Mini-A cable into the jack. */ if (isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE) & INTR_VBUS_VLD) b_peripheral(isp); return 0; #else dev_dbg(&isp->client.dev, "peripheral sessions not allowed\n"); return -EINVAL; #endif }
static void msm_otg_start_peripheral(struct usb_phy *phy, int on) { struct msm_otg *motg = container_of(phy, struct msm_otg, phy); struct msm_otg_platform_data *pdata = motg->pdata; if (!phy->otg->gadget) return; if (on) { dev_dbg(phy->dev, "gadget on\n"); /* * Some boards have a switch cotrolled by gpio * to enable/disable internal HUB. Disable internal * HUB before kicking the gadget. */ if (pdata->setup_gpio) pdata->setup_gpio(OTG_STATE_B_PERIPHERAL); usb_gadget_vbus_connect(phy->otg->gadget); } else { dev_dbg(phy->dev, "gadget off\n"); usb_gadget_vbus_disconnect(phy->otg->gadget); if (pdata->setup_gpio) pdata->setup_gpio(OTG_STATE_UNDEFINED); } }
static int dwc3_otg_start_gadget(struct otg_fsm *fsm, int on) { struct usb_otg *otg = fsm->otg; struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg); struct device *dev = dotg->dwc->dev; int ret; if (!otg->gadget) return -EINVAL; dev_err(dev, "Turn %s gadget %s\n", on ? "on" : "off", otg->gadget->name); if (on) { wake_lock(&dotg->wakelock); pm_runtime_get_sync(dev); dwc3_otg_set_peripheral_mode(dotg); ret = usb_gadget_vbus_connect(otg->gadget); } else { /* * Delay VBus OFF signal delivery to not miss Disconnect * interrupt (80ms is minimum; ascertained by experiment) */ msleep(200); ret = usb_gadget_vbus_disconnect(otg->gadget); pm_runtime_put_sync(dev); wake_unlock(&dotg->wakelock); } return ret; }
static void tahvo_usb_power_off(struct tahvo_usb *tu) { u32 l; int id; /* Disable gadget controller if any */ if (tu->otg.gadget) usb_gadget_vbus_disconnect(tu->otg.gadget); /* Disable OTG and interrupts */ if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL) id = OTG_ID; else id = 0; l = omap_readl(OTG_CTRL); l &= ~(OTG_CTRL_XCVR_MASK | OTG_CTRL_SYS_MASK | OTG_BSESSVLD); l |= id | OTG_BSESSEND; omap_writel(l, OTG_CTRL); omap_writew(0, OTG_IRQ_EN); l = omap_readl(OTG_SYSCON_2); l &= ~OTG_EN; omap_writel(l, OTG_SYSCON_2); l = omap_readl(OTG_SYSCON_1); l |= OTG_IDLE_EN; omap_writel(l, OTG_SYSCON_1); /* Power off transceiver */ tahvo_write_reg(tu->dev, TAHVO_REG_USBR, 0); tu->otg.state = OTG_STATE_UNDEFINED; }
/* usb cable call back function */ static void muic_usb_cb(u8 usb_mode) { struct usb_gadget *gadget = platform_get_drvdata(&s3c_device_usbgadget); pr_info("%s:%s MUIC usb_cb:%d\n", MUIC_DEV_NAME, __func__, usb_mode); if (gadget) { switch (usb_mode) { case USB_CABLE_DETACHED: pr_info("usb: muic: USB_CABLE_DETACHED(%d)\n", usb_mode); usb_gadget_vbus_disconnect(gadget); break; case USB_CABLE_ATTACHED: pr_info("usb: muic: USB_CABLE_ATTACHED(%d)\n", usb_mode); usb_gadget_vbus_connect(gadget); break; default: pr_info("usb: muic: invalid mode%d\n", usb_mode); } } }
/** * dwc3_otg_start_peripheral - bind/unbind the peripheral controller. * * @otg: Pointer to the otg_transceiver structure. * @gadget: pointer to the usb_gadget structure. * * Returns 0 on success otherwise negative errno. */ static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on) { struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg); struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv; if (!otg->gadget) return -EINVAL; if (on) { dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n", __func__, otg->gadget->name); /* Core reset is not required during start peripheral. Only * DBM reset is required, hence perform only DBM reset here */ if (ext_xceiv && ext_xceiv->otg_capability && ext_xceiv->ext_block_reset) ext_xceiv->ext_block_reset(ext_xceiv, false); dwc3_otg_set_hsphy_auto_suspend(dotg, true); dwc3_otg_set_peripheral_regs(dotg); usb_gadget_vbus_connect(otg->gadget); } else { dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n", __func__, otg->gadget->name); usb_gadget_vbus_disconnect(otg->gadget); dwc3_otg_set_hsphy_auto_suspend(dotg, false); } return 0; }
/** * dwc3_otg_start_peripheral - bind/unbind the peripheral controller. * * @otg: Pointer to the otg_transceiver structure. * @gadget: pointer to the usb_gadget structure. * * Returns 0 on success otherwise negative errno. */ static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on) { struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg); struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv; if (!otg->gadget) return -EINVAL; if (on) { dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n", __func__, otg->gadget->name); usb_phy_notify_connect(dotg->dwc->usb2_phy, USB_SPEED_HIGH); usb_phy_notify_connect(dotg->dwc->usb3_phy, USB_SPEED_SUPER); /* Core reset is not required during start peripheral. Only * DBM reset is required, hence perform only DBM reset here */ if (ext_xceiv && ext_xceiv->ext_block_reset) ext_xceiv->ext_block_reset(ext_xceiv, false); dwc3_set_mode(dotg->dwc, DWC3_GCTL_PRTCAP_DEVICE); usb_gadget_vbus_connect(otg->gadget); } else { dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n", __func__, otg->gadget->name); usb_gadget_vbus_disconnect(otg->gadget); usb_phy_notify_disconnect(dotg->dwc->usb2_phy, USB_SPEED_HIGH); usb_phy_notify_disconnect(dotg->dwc->usb3_phy, USB_SPEED_SUPER); dwc3_gadget_usb3_phy_suspend(dotg->dwc, false); } return 0; }
/** * exynos_drd_switch_start_peripheral - bind/unbind the peripheral controller. * * @otg: Pointer to the usb_otg structure. * @on: start / stop the gadget controller driver. * * Returns 0 on success otherwise negative errno. */ static int exynos_drd_switch_start_peripheral(struct usb_otg *otg, int on) { int ret; if (!otg->gadget) return -EINVAL; dev_dbg(otg->phy->dev, "Turn %s gadget %s\n", on ? "on" : "off", otg->gadget->name); if (on) { /* Start device only if host is off */ if (!exynos_drd_switch_is_host_off(otg)) { /* * REVISIT: if host is not suspended shall we check * runtime_error flag and clear it, if it is set? * It will give an additional chance to the host * to be suspended if runtime error happened. */ dev_vdbg(otg->phy->dev, "%s: host is still active\n", __func__); return -EAGAIN; } ret = usb_gadget_vbus_connect(otg->gadget); } else { ret = usb_gadget_vbus_disconnect(otg->gadget); /* Currently always return 0 */ } return ret; }
static void tahvo_usb_power_off(struct tahvo_usb *tu) { u32 l; int id; /* Disable gadget controller if any */ if (tu->otg.gadget) usb_gadget_vbus_disconnect(tu->otg.gadget); host_suspend(tu); /* Disable OTG and interrupts */ if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL) id = OTG_ID; else id = 0; l = OTG_CTRL_REG; l &= ~(OTG_CTRL_XCVR_MASK | OTG_CTRL_SYS_MASK | OTG_BSESSVLD); l |= id | OTG_BSESSEND; OTG_CTRL_REG = l; OTG_IRQ_EN_REG = 0; OTG_SYSCON_2_REG &= ~OTG_EN; OTG_SYSCON_1_REG |= OTG_IDLE_EN; /* Power off transceiver */ tahvo_write_reg(TAHVO_REG_USBR, 0); tu->otg.state = OTG_STATE_UNDEFINED; }
static int gadget_suspend(struct isp1301 *isp) { isp->otg.gadget->b_hnp_enable = 0; isp->otg.gadget->a_hnp_support = 0; isp->otg.gadget->a_alt_hnp_support = 0; return usb_gadget_vbus_disconnect(isp->otg.gadget); }
static ssize_t u1_switch_store_usb_lock(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int lock; struct s3c_udc *udc = platform_get_drvdata(&s3c_device_usbgadget); if (!strncmp(buf, "0", 1)) lock = 0; else if (!strncmp(buf, "1", 1)) lock = 1; else { pr_warn("%s: Wrong command\n", __func__); return count; } if (IS_ERR_OR_NULL(udc)) return count; pr_info("%s: lock=%d\n", __func__, lock); if (lock != is_usb_locked) { is_usb_locked = lock; if (lock) { if (udc->udc_enabled) usb_gadget_vbus_disconnect(&udc->gadget); } } return count; }
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 int sec_bat_check_cable_callback(void) { struct usb_gadget *gadget = platform_get_drvdata(&s3c_device_usbgadget); bool attach = true; int adc_1, adc_2, avg_adc; if (!charger_supply) { charger_supply = power_supply_get_by_name("sec-charger"); if (!charger_supply) pr_err("%s: failed to get power supplies\n", __func__); } /* ADC check margin (300~500ms) */ msleep(150); usb_switch_lock(); usb_switch_set_path(USB_PATH_ADCCHECK); adc_1 = stmpe811_get_adc_data(6); adc_2 = stmpe811_get_adc_data(6); avg_adc = (adc_1 + adc_2)/2; usb_switch_clr_path(USB_PATH_ADCCHECK); usb_switch_unlock(); pr_info("[BAT] %s: Adc value (%d)\n", __func__, avg_adc); attach = !gpio_get_value(GPIO_TA_nCONNECTED) ? true : false; if(attach) { if(avg_adc > TA_ADC_LOW) current_cable_type = POWER_SUPPLY_TYPE_MAINS; else current_cable_type = POWER_SUPPLY_TYPE_USB; } else current_cable_type = POWER_SUPPLY_TYPE_BATTERY; /* temp code : only set vbus enable when usb attaced */ if (gadget) { if (attach) usb_gadget_vbus_connect(gadget); else usb_gadget_vbus_disconnect(gadget); } #if 0 pr_info("%s: Cable type(%s), Attach(%d), Adc(%d)\n", __func__, current_cable_type == POWER_SUPPLY_TYPE_BATTERY ? "Battery" : current_cable_type == POWER_SUPPLY_TYPE_USB ? "USB" : "TA", attach, adc); #endif return current_cable_type; }
static void tahvo_usb_stop_peripheral(struct tahvo_usb *tu) { OTG_CTRL_REG = (OTG_CTRL_REG & ~OTG_BSESSVLD) | OTG_BSESSEND; if (tu->otg.gadget) usb_gadget_vbus_disconnect(tu->otg.gadget); tu->otg.state = OTG_STATE_B_IDLE; }
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 msm_otg_start_peripheral(struct otg_transceiver *xceiv, int on) { if (!xceiv->gadget) return; if (on) usb_gadget_vbus_connect(xceiv->gadget); else usb_gadget_vbus_disconnect(xceiv->gadget); }
void ci_handle_vbus_change(struct ci_hdrc *ci) { if (!ci->is_otg) return; if (hw_read_otgsc(ci, OTGSC_BSV)) usb_gadget_vbus_connect(&ci->gadget); else usb_gadget_vbus_disconnect(&ci->gadget); }
static void check_vbus_state(struct tahvo_usb *tu) { int reg, prev_state; reg = tahvo_read_reg(TAHVO_REG_IDSR); if (reg & 0x01) { u32 l; vbus_active = 1; switch (tu->otg.state) { case OTG_STATE_B_IDLE: /* Enable the gadget driver */ if (tu->otg.gadget) usb_gadget_vbus_connect(tu->otg.gadget); /* Set B-session valid and not B-sessio ended to indicate * Vbus to be ok. */ l = omap_readl(OTG_CTRL); l &= ~OTG_BSESSEND; l |= OTG_BSESSVLD; omap_writel(l, OTG_CTRL); tu->otg.state = OTG_STATE_B_PERIPHERAL; break; case OTG_STATE_A_IDLE: /* Session is now valid assuming the USB hub is driving Vbus */ tu->otg.state = OTG_STATE_A_HOST; host_resume(tu); break; default: break; } printk("USB cable connected\n"); } else { switch (tu->otg.state) { case OTG_STATE_B_PERIPHERAL: if (tu->otg.gadget) usb_gadget_vbus_disconnect(tu->otg.gadget); tu->otg.state = OTG_STATE_B_IDLE; break; case OTG_STATE_A_HOST: tu->otg.state = OTG_STATE_A_IDLE; break; default: break; } printk("USB cable disconnected\n"); vbus_active = 0; } prev_state = tu->vbus_state; tu->vbus_state = reg & 0x01; if (prev_state != tu->vbus_state) sysfs_notify(&tu->pt_dev->dev.kobj, NULL, "vbus_state"); }
static void gpio_vbus_work(struct work_struct *work) { struct gpio_vbus_data *gpio_vbus = container_of(work, struct gpio_vbus_data, work.work); struct gpio_vbus_mach_info *pdata = dev_get_platdata(gpio_vbus->dev); int gpio, status, vbus; if (!gpio_vbus->phy.otg->gadget) return; vbus = is_vbus_powered(pdata); if ((vbus ^ gpio_vbus->vbus) == 0) return; gpio_vbus->vbus = vbus; /* Peripheral controllers which manage the pullup themselves won't have * gpio_pullup configured here. If it's configured here, we'll do what * isp1301_omap::b_peripheral() does and enable the pullup here... although * that may complicate usb_gadget_{,dis}connect() support. */ gpio = pdata->gpio_pullup; if (vbus) { status = USB_EVENT_VBUS; gpio_vbus->phy.otg->state = OTG_STATE_B_PERIPHERAL; gpio_vbus->phy.last_event = status; usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget); /* drawing a "unit load" is *always* OK, except for OTG */ set_vbus_draw(gpio_vbus, 100); /* optionally enable D+ pullup */ if (gpio_is_valid(gpio)) gpio_set_value(gpio, !pdata->gpio_pullup_inverted); atomic_notifier_call_chain(&gpio_vbus->phy.notifier, status, gpio_vbus->phy.otg->gadget); } else { /* optionally disable D+ pullup */ if (gpio_is_valid(gpio)) gpio_set_value(gpio, pdata->gpio_pullup_inverted); set_vbus_draw(gpio_vbus, 0); usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); status = USB_EVENT_NONE; gpio_vbus->phy.otg->state = OTG_STATE_B_IDLE; gpio_vbus->phy.last_event = status; atomic_notifier_call_chain(&gpio_vbus->phy.notifier, status, gpio_vbus->phy.otg->gadget); } }
static void tahvo_usb_power_off(struct tahvo_usb *tu) { struct retu_dev *rdev = dev_get_drvdata(tu->pt_dev->dev.parent); /* Disable gadget controller if any */ if (tu->phy.otg->gadget) usb_gadget_vbus_disconnect(tu->phy.otg->gadget); /* Power off transceiver */ retu_write(rdev, TAHVO_REG_USBR, 0); tu->phy.state = OTG_STATE_UNDEFINED; }
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 tahvo_usb_stop_peripheral(struct tahvo_usb *tu) { u32 l; l = omap_readl(OTG_CTRL); l &= ~OTG_BSESSVLD; l |= OTG_BSESSEND; omap_writel(l, OTG_CTRL); if (tu->otg.gadget) usb_gadget_vbus_disconnect(tu->otg.gadget); tu->otg.state = OTG_STATE_B_IDLE; }
static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on) { struct otg_transceiver *otg = &mvotg->otg; if (!otg->gadget) return; dev_info(otg->dev, "gadget %s\n", on ? "on" : "off"); if (on) usb_gadget_vbus_connect(otg->gadget); else usb_gadget_vbus_disconnect(otg->gadget); }
static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on) { struct usb_otg *otg = mvotg->phy.otg; if (!otg->gadget) return; dev_info(mvotg->phy.dev, "gadget %s\n", on ? "on" : "off"); if (on) usb_gadget_vbus_connect(otg->gadget); else usb_gadget_vbus_disconnect(otg->gadget); }
static void check_vbus_state(struct tahvo_usb *tu) { struct retu_dev *rdev = dev_get_drvdata(tu->pt_dev->dev.parent); int reg, prev_state; reg = retu_read(rdev, TAHVO_REG_IDSR); if (reg & TAHVO_STAT_VBUS) { switch (tu->phy.state) { case OTG_STATE_B_IDLE: /* Enable the gadget driver */ if (tu->phy.otg->gadget) usb_gadget_vbus_connect(tu->phy.otg->gadget); tu->phy.state = OTG_STATE_B_PERIPHERAL; break; case OTG_STATE_A_IDLE: /* * Session is now valid assuming the USB hub is driving * Vbus. */ tu->phy.state = OTG_STATE_A_HOST; break; default: break; } dev_info(&tu->pt_dev->dev, "USB cable connected\n"); } else { switch (tu->phy.state) { case OTG_STATE_B_PERIPHERAL: if (tu->phy.otg->gadget) usb_gadget_vbus_disconnect(tu->phy.otg->gadget); tu->phy.state = OTG_STATE_B_IDLE; break; case OTG_STATE_A_HOST: tu->phy.state = OTG_STATE_A_IDLE; break; default: break; } dev_info(&tu->pt_dev->dev, "USB cable disconnected\n"); } prev_state = tu->vbus_state; tu->vbus_state = reg & TAHVO_STAT_VBUS; if (prev_state != tu->vbus_state) { extcon_set_cable_state(&tu->extcon, "USB", tu->vbus_state); sysfs_notify(&tu->pt_dev->dev.kobj, NULL, "vbus_state"); } }
/* VBUS change IRQ handler */ static irqreturn_t gpio_vbus_irq(int irq, void *data) { struct platform_device *pdev = data; struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); int gpio, vbus; vbus = gpio_get_value(pdata->gpio_vbus); if (pdata->gpio_vbus_inverted) vbus = !vbus; dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", vbus ? "supplied" : "inactive", gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none"); if (!gpio_vbus->otg.gadget) return IRQ_HANDLED; /* Peripheral controllers which manage the pullup themselves won't have * gpio_pullup configured here. If it's configured here, we'll do what * isp1301_omap::b_peripheral() does and enable the pullup here... although * that may complicate usb_gadget_{,dis}connect() support. */ gpio = pdata->gpio_pullup; if (vbus) { gpio_vbus->otg.state = OTG_STATE_B_PERIPHERAL; usb_gadget_vbus_connect(gpio_vbus->otg.gadget); /* drawing a "unit load" is *always* OK, except for OTG */ set_vbus_draw(gpio_vbus, 100); /* optionally enable D+ pullup */ if (gpio_is_valid(gpio)) gpio_set_value(gpio, !pdata->gpio_pullup_inverted); } else { /* optionally disable D+ pullup */ if (gpio_is_valid(gpio)) gpio_set_value(gpio, pdata->gpio_pullup_inverted); set_vbus_draw(gpio_vbus, 0); usb_gadget_vbus_disconnect(gpio_vbus->otg.gadget); gpio_vbus->otg.state = OTG_STATE_B_IDLE; } return IRQ_HANDLED; }
static int dwc3_otg_start_gadget(struct otg_fsm *fsm, int on) { struct usb_otg *otg = fsm->otg; struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg); struct dwc3 *dwc = dotg->dwc; struct device *dev = dotg->dwc->dev; int ret = 0; if (!otg->gadget) return -EINVAL; dev_err(dev, "Turn %s gadget %s\n", on ? "on" : "off", otg->gadget->name); /* sync usb3 phy state with usb2 phy */ dwc->usb3_phy->state = dwc->usb2_phy->state; if (on) { pm_runtime_get_sync(dev); ret = dwc3_core_init(dwc); if (ret) { dev_err(dwc->dev, "%s: failed to reinitialize core\n", __func__); goto err1; } dwc3_otg_set_peripheral_mode(dotg); ret = usb_gadget_vbus_connect(otg->gadget); if (ret) { dev_err(dwc->dev, "%s: vbus connect failed\n", __func__); goto err2; } } else { /* avoid missing disconnect interrupt */ wait_for_completion_timeout(&dwc->disconnect, msecs_to_jiffies(200)); ret = usb_gadget_vbus_disconnect(otg->gadget); if (ret) dev_err(dwc->dev, "%s: vbus disconnect failed\n", __func__); err2: dwc3_core_exit(dwc); err1: pm_runtime_put_sync(dev); } return ret; }
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; }