示例#1
0
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;
	}
}
示例#2
0
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;
}
示例#4
0
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;
	}
}
示例#5
0
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;
	}
}
示例#6
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);
	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;
}
示例#7
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;
}
示例#8
0
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;
}
示例#9
0
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);
}
示例#10
0
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;
}
示例#11
0
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;
}
示例#12
0
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;
}
示例#13
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,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();
}