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 }
/* add or disable the host device+driver */ static int isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) { struct isp1301 *isp = container_of(otg, struct isp1301, otg); if (!otg || isp != the_transceiver) return -ENODEV; if (!host) { omap_writew(0, OTG_IRQ_EN); power_down(isp); isp->otg.host = NULL; return 0; } #ifdef CONFIG_USB_OTG isp->otg.host = host; dev_dbg(&isp->client->dev, "registered host\n"); host_suspend(isp); if (isp->otg.gadget) return isp1301_otg_enable(isp); return 0; #elif !defined(CONFIG_USB_GADGET_OMAP) // FIXME update its refcount isp->otg.host = host; power_up(isp); if (machine_is_omap_h2()) isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); dev_info(&isp->client->dev, "A-Host sessions ok\n"); isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING, INTR_ID_GND); isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, INTR_ID_GND); /* If this has a Mini-AB connector, this mode is highly * nonstandard ... but can be handy for testing, especially with * the Mini-A end of an OTG cable. (Or something nonstandard * like MiniB-to-StandardB, maybe built with a gender mender.) */ isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV); dump_regs(isp, __func__); return 0; #else dev_dbg(&isp->client->dev, "host sessions not allowed\n"); return -EINVAL; #endif }