static void ci13xxx_msm_notify_event(struct ci13xxx *udc, unsigned event) { switch (event) { case CI13XXX_CONTROLLER_RESET_EVENT: USB_INFO("CI13XXX_CONTROLLER_RESET_EVENT received\n"); writel(0, USB_AHBBURST); writel_relaxed(0x08, USB_AHBMODE); break; case CI13XXX_CONTROLLER_DISCONNECT_EVENT: USB_INFO("CI13XXX_CONTROLLER_DISCONNECT_EVENT received\n"); ci13xxx_msm_resume(); break; case CI13XXX_CONTROLLER_SUSPEND_EVENT: USB_INFO("CI13XXX_CONTROLLER_SUSPEND_EVENT received\n"); ci13xxx_msm_suspend(); break; case CI13XXX_CONTROLLER_RESUME_EVENT: USB_INFO( "CI13XXX_CONTROLLER_RESUME_EVENT received\n"); ci13xxx_msm_resume(); break; default: USB_INFO("unknown ci13xxx_udc event\n"); break; } }
static irqreturn_t tegra_otg_irq(int irq, void *data) { struct tegra_otg_data *tegra = data; unsigned long flags; unsigned long val; if (irq_otg_debug==1) { USB_INFO("otg_irq"); irq_otg_debug = 0; } spin_lock_irqsave(&tegra->lock, flags); val = otg_readl(tegra, USB_PHY_WAKEUP); if (val & (USB_VBUS_INT_EN | USB_ID_INT_EN)) { otg_writel(tegra, val, USB_PHY_WAKEUP); if ((val & USB_ID_INT_STATUS) || (val & USB_VBUS_INT_STATUS)) { tegra->int_status = val; schedule_work(&tegra->work); } } spin_unlock_irqrestore(&tegra->lock, flags); return IRQ_HANDLED; }
bool USBHostKeyboard::connect() { if (dev_connected) { return true; } for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { if ((dev = host->getDevice(i)) != NULL) { if (host->enumerate(dev, this)) break; if (keyboard_device_found) { int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN); if (!int_in) break; USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf); dev->setName("Keyboard", keyboard_intf); host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init); int_in->attach(this, &USBHostKeyboard::rxHandler); host->interruptRead(dev, int_in, report, int_in->getSize(), false); dev_connected = true; return true; } } } init(); return false; }
static void ci13xxx_msm_resume(void) { USB_INFO("ci13xxx_msm_resume\n"); if (_udc_ctxt.wake_irq && _udc_ctxt.wake_irq_state) { disable_irq_wake(_udc_ctxt.wake_irq); disable_irq_nosync(_udc_ctxt.wake_irq); _udc_ctxt.wake_irq_state = false; } }
static void ci13xxx_msm_suspend(void) { USB_INFO("ci13xxx_msm_suspend\n"); if (_udc_ctxt.wake_irq && !_udc_ctxt.wake_irq_state) { enable_irq_wake(_udc_ctxt.wake_irq); enable_irq(_udc_ctxt.wake_irq); _udc_ctxt.wake_irq_state = true; } }
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 void tegra_otg_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct tegra_otg_data *tegra_otg = platform_get_drvdata(pdev); int val; unsigned long flags; USB_INFO("%s\n",__func__); tegra_otg_enable_clk(); /* Following delay is intentional. * It is placed here after observing system hang. * Root cause is not confirmed. */ msleep(1); /* restore the interupt enable for cable ID and VBUS */ clk_enable(tegra_otg->clk); val = readl(tegra_otg->regs + USB_PHY_WAKEUP); writel(val, (tegra_otg->regs + USB_PHY_WAKEUP)); val = otg_readl(tegra_otg, USB_PHY_WAKEUP); val |= (USB_VBUS_INT_EN | USB_VBUS_WAKEUP_EN); val |= (USB_ID_INT_EN | USB_ID_PIN_WAKEUP_EN); otg_writel(tegra_otg, val, USB_PHY_WAKEUP); val = readl(tegra_otg->regs + USB_PHY_WAKEUP); clk_disable(tegra_otg->clk); spin_lock_irqsave(&tegra_otg->lock, flags); if (tps80031_vbus_on) val |= USB_VBUS_STATUS; else val &= ~USB_VBUS_STATUS; tegra_otg->int_status = (val | USB_VBUS_INT_STATUS ); spin_unlock_irqrestore(&tegra_otg->lock, flags); schedule_work(&tegra_otg->work); #if 0 /* A device might be connected while CPU is in sleep mode. In this case no interrupt * will be triggered * force irq_work to recheck connected devices */ if (!(val & USB_ID_STATUS)) { spin_lock_irqsave(&tegra_otg->lock, flags); tegra_otg->int_status = (val | USB_ID_INT_STATUS ); spin_unlock_irqrestore(&tegra_otg->lock, flags); schedule_work(&tegra_otg->work); } #endif return; }
bool USBHostHub::connect(USBDeviceConnected * dev) { if (dev_connected) { return true; } if(host->enumerate(dev, this)) { init(); return false; } if (hub_device_found) { this->dev = dev; int_in = dev->getEndpoint(hub_intf, INTERRUPT_ENDPOINT, IN); if (!int_in) { init(); return false; } USB_INFO("New HUB: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, hub_intf); dev->setName("Hub", hub_intf); host->registerDriver(dev, hub_intf, this, &USBHostHub::disconnect); int_in->attach(this, &USBHostHub::rxHandler); // get HUB descriptor host->controlRead( dev, USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS, GET_DESCRIPTOR, 0x29 << 8, 0, buf, sizeof(HubDescriptor)); nb_port = buf[2]; hub_characteristics = buf[3]; USB_DBG("Hub has %d port", nb_port); for (uint8_t j = 1; j <= nb_port; j++) { setPortFeature(PORT_POWER_FEATURE, j); } wait_ms(buf[5]*2); host->interruptRead(dev, int_in, buf, 1, false); dev_connected = true; return true; } return false; }
void USBHostSerialPort::connect(USBHost* _host, USBDeviceConnected * _dev, uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out) { host = _host; dev = _dev; serial_intf = _serial_intf; bulk_in = _bulk_in; bulk_out = _bulk_out; USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf); dev->setName("Serial", serial_intf); host->registerDriver(dev, serial_intf, this, &USBHostSerialPort::init); //baud(9600); size_bulk_in = bulk_in->getSize(); size_bulk_out = bulk_out->getSize(); bulk_in->attach(this, &USBHostSerialPort::rxHandler); bulk_out->attach(this, &USBHostSerialPort::txHandler); host->bulkRead(dev, bulk_in, buf, size_bulk_in, false); }
bool USBHostSerial::connect() { if (dev_connected) { return true; } for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { if ((dev = host->getDevice(i)) != NULL) { USB_DBG("Trying to connect serial device\r\n"); if(host->enumerate(dev, this)) break; if (serial_device_found) { bulk_in = dev->getEndpoint(serial_intf, BULK_ENDPOINT, IN); bulk_out = dev->getEndpoint(serial_intf, BULK_ENDPOINT, OUT); if (!bulk_in || !bulk_out) break; USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf); dev->setName("Serial", serial_intf); host->registerDriver(dev, serial_intf, this, &USBHostSerial::init); baud(9600); size_bulk_in = bulk_in->getSize(); size_bulk_out = bulk_out->getSize(); bulk_in->attach(this, &USBHostSerial::rxHandler); bulk_out->attach(this, &USBHostSerial::txHandler); host->bulkRead(dev, bulk_in, buf, size_bulk_in, false); dev_connected = true; return true; } } } init(); return false; }
bool USBHostMouse::connect() { int len_listen; if (dev_connected) { return true; } for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { if ((dev = host->getDevice(i)) != NULL) { if(host->enumerate(dev, this)) break; if (mouse_device_found) { int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN); if (!int_in) break; USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf); dev->setName("Mouse", mouse_intf); host->registerDriver(dev, mouse_intf, this, &USBHostMouse::init); int_in->attach(this, &USBHostMouse::rxHandler); len_listen = int_in->getSize(); if (len_listen > sizeof(report)) { len_listen = sizeof(report); } host->interruptRead(dev, int_in, report, len_listen, false); dev_connected = true; return true; } } } init(); return false; }
static int tegra_otg_probe(struct platform_device *pdev) { struct tegra_otg_data *tegra; struct tegra_otg_platform_data *otg_pdata; struct tegra_ehci_platform_data *ehci_pdata; struct resource *res; struct tegra_otg_platform_data *pdata; int err; tegra = kzalloc(sizeof(struct tegra_otg_data), GFP_KERNEL); if (!tegra) return -ENOMEM; pdata = pdev->dev.platform_data; tegra->otg.dev = &pdev->dev; otg_pdata = tegra->otg.dev->platform_data; ehci_pdata = otg_pdata->ehci_pdata; tegra->otg.label = "tegra-otg"; tegra->otg.state = OTG_STATE_UNDEFINED; tegra->otg.set_host = tegra_otg_set_host; tegra->otg.set_peripheral = tegra_otg_set_peripheral; tegra->otg.set_suspend = tegra_otg_set_suspend; tegra->otg.set_power = tegra_otg_set_power; spin_lock_init(&tegra->lock); platform_set_drvdata(pdev, tegra); tegra_clone = tegra; tegra->clk_enabled = false; tegra->rcv_host_en = pdata->rcv_host_en; tegra->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(tegra->clk)) { dev_err(&pdev->dev, "Can't get otg clock\n"); err = PTR_ERR(tegra->clk); goto err_clk; } err = clk_enable(tegra->clk); if (err) goto err_clken; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Failed to get I/O memory\n"); err = -ENXIO; goto err_io; } tegra->regs = ioremap(res->start, resource_size(res)); if (!tegra->regs) { err = -ENOMEM; goto err_io; } tegra->otg.state = OTG_STATE_A_SUSPEND; err = otg_set_transceiver(&tegra->otg); if (err) { dev_err(&pdev->dev, "can't register transceiver (%d)\n", err); goto err_otg; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(&pdev->dev, "Failed to get IRQ\n"); err = -ENXIO; goto err_irq; } tegra->irq = res->start; //enable_irq_wake(tegra->irq); err = request_threaded_irq(tegra->irq, tegra_otg_irq, NULL, IRQF_SHARED, "tegra-otg", tegra); if (err) { dev_err(&pdev->dev, "Failed to register IRQ\n"); goto err_irq; } INIT_WORK (&tegra->work, irq_work); if (!ehci_pdata->default_enable) clk_disable(tegra->clk); dev_info(&pdev->dev, "otg transceiver registered\n"); USB_INFO("%s done!\n", __func__); return 0; err_irq: otg_set_transceiver(NULL); err_otg: iounmap(tegra->regs); err_io: clk_disable(tegra->clk); err_clken: clk_put(tegra->clk); err_clk: platform_set_drvdata(pdev, NULL); kfree(tegra); return err; }
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(); }