int musb_platform_set_mode(struct musb *musb, u8 musb_mode) { u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); devctl |= MUSB_DEVCTL_SESSION; musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); switch (musb_mode) { #ifdef CONFIG_USB_MUSB_HDRC_HCD case MUSB_HOST: otg_set_host(&musb->xceiv, musb->xceiv.host); break; #endif #ifdef CONFIG_USB_GADGET_MUSB_HDRC case MUSB_PERIPHERAL: otg_set_peripheral(&musb->xceiv, musb->xceiv.gadget); break; #endif #ifdef CONFIG_USB_MUSB_OTG case MUSB_OTG: break; #endif default: return -EINVAL; } return 0; }
/* * * linux usb function * */ static int usbhsg_gadget_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct device *dev = usbhs_priv_to_dev(priv); int ret; if (!driver || !driver->setup || driver->max_speed < USB_SPEED_FULL) return -EINVAL; /* connect to bus through transceiver */ if (!IS_ERR_OR_NULL(gpriv->transceiver)) { ret = otg_set_peripheral(gpriv->transceiver->otg, &gpriv->gadget); if (ret) { dev_err(dev, "%s: can't bind to transceiver\n", gpriv->gadget.name); return ret; } /* get vbus using phy versions */ usbhs_mod_phy_mode(priv); } /* first hook up the driver ... */ gpriv->driver = driver; return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); }
static int usbhsg_gadget_stop(struct usb_gadget *gadget) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); if (!IS_ERR_OR_NULL(gpriv->transceiver)) otg_set_peripheral(gpriv->transceiver->otg, NULL); gpriv->driver = NULL; return 0; }
/** * musb_platform_set_mode() - Set the mode for the USB driver. * @musb: struct musb pointer. * @musb_mode: usb mode. * * This function set the mode for the USB. */ int musb_platform_set_mode(struct musb *musb, u8 musb_mode) { u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); devctl |= MUSB_DEVCTL_SESSION; musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); switch (musb_mode) { case MUSB_HOST: otg_set_host(musb->xceiv, musb->xceiv->host); break; case MUSB_PERIPHERAL: otg_set_peripheral(musb->xceiv, musb->xceiv->gadget); break; case MUSB_OTG: break; default: return -EINVAL; } return 0; }
static int msm72k_probe(struct platform_device *pdev) { struct usb_info *ui; struct msm_hsusb_gadget_platform_data *pdata; struct msm_otg *otg; int retval; INFO("msm72k_probe\n"); ui = kzalloc(sizeof(struct usb_info), GFP_KERNEL); if (!ui) return -ENOMEM; ui->pdev = pdev; if (pdev->dev.platform_data) { pdata = pdev->dev.platform_data; ui->phy_reset = pdata->phy_reset; ui->phy_init_seq = pdata->phy_init_seq; ui->chg_init = pdata->chg_init; ui->chg_connected = pdata->chg_connected; ui->chg_vbus_draw = pdata->chg_vbus_draw; ui->usb_connected = pdata->usb_connected; } if (ui->chg_init) ui->chg_init(1); ui->buf = dma_alloc_coherent(&pdev->dev, 4096, &ui->dma, GFP_KERNEL); if (!ui->buf) return usb_free(ui, -ENOMEM); ui->pool = dma_pool_create("msm72k_udc", NULL, 32, 32, 0); if (!ui->pool) return usb_free(ui, -ENOMEM); /* FIXME: dmb cannot be called from interrupt context * for the first time; Need to verify on how it needs * to be fixed */ dmb(); ui->xceiv = otg_get_transceiver(); if (!ui->xceiv) return usb_free(ui, -ENODEV); otg = to_msm_otg(ui->xceiv); ui->addr = otg->regs; ui->gadget.ops = &msm72k_ops; ui->gadget.is_dualspeed = 1; device_initialize(&ui->gadget.dev); strcpy(ui->gadget.dev.bus_id, "gadget"); ui->gadget.dev.parent = &pdev->dev; ui->gadget.dev.dma_mask = pdev->dev.dma_mask; the_usb_info = ui; pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, DRIVER_NAME, PM_QOS_DEFAULT_VALUE); pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ, DRIVER_NAME, PM_QOS_DEFAULT_VALUE); usb_debugfs_init(ui); usb_prepare(ui); retval = otg_set_peripheral(ui->xceiv, &ui->gadget); if (retval) { pr_err("%s: Cannot bind the transceiver, retval:(%d)\n", __func__, retval); return usb_free(ui, retval); } return 0; }