コード例 #1
0
int tegra_udc_clk_init(struct platform_device *pdev)
{
	NvError nverr;

	nverr = NvDdkUsbPhyOpen(s_hRmGlobal, pdev->id, &s_hUsbPhy);
	if (nverr != NvSuccess)
		return -ENODEV;

	/* Power up the USB phy */
	NV_ASSERT_SUCCESS(NvDdkUsbPhyPowerUp(s_hUsbPhy, NV_FALSE, 0));
	wake_lock_init(&s_wake_lock, WAKE_LOCK_SUSPEND, "tegra-udc");
	return 0;
}
コード例 #2
0
static int tegra_ehci_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct tegra_hcd_platform_data *pdata = pdev->dev.platform_data;
	struct usb_hcd *hcd;
	int e = 0;
	int irq;
	unsigned int temp;
	struct ehci_hcd *ehci;

	if (!pdata) {
		dev_err(&pdev->dev, "platform data must be specified\n");
		return -EINVAL;
	}

	WARN_ON(!pdev->dev.coherent_dma_mask || !pdev->dev.dma_mask);

	hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev,
					dev_name(&pdev->dev));
	if (IS_ERR_OR_NULL(hcd)) {
		dev_err(&pdev->dev, "Unable to create HCD\n");
		return -ENOMEM;
	}

	if (pdata->id_detect == ID_PIN_GPIO) {
		e = gpio_request(pdata->gpio_nr, dev_name(&pdev->dev));
		if (e < 0) {
			dev_err(&pdev->dev, "request ID pin GPIO failed\n");
			goto fail_hcd;
		}

		e = gpio_direction_input(pdata->gpio_nr);
		if (e < 0) {
			dev_err(&pdev->dev, "failed to set ID pin as input\n");
			goto fail_gpio;
		}
	}

	INIT_WORK(&pdata->work, tegra_ehci_busy_hint_work);

	/* Init the tegra USB phy */
	if (NvDdkUsbPhyOpen(s_hRmGlobal, pdata->instance,
			    &pdata->hUsbPhy) != NvSuccess) {
		dev_err(&pdev->dev, "failed to open USB phy DDK\n");
		e = -ENODEV;
		goto fail_gpio;
	}
	tegra_ehci_power_up(hcd);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "failed to get I/O memory\n");
		e = -ENXIO;
		goto fail_phy;
	}
	if (!pdata->otg_mode) {
		res = request_mem_region(res->start, resource_size(res),
					 dev_name(&pdev->dev));
		if (!res) {
			dev_err(&pdev->dev, "resource in use\n");
			e = -EBUSY;
			goto fail_phy;
		}
	}
	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);
	hcd->regs = ioremap(res->start, resource_size(res));
	if (!hcd->regs) {
		e = -ENOMEM;
		goto fail_mem;
	}

	/* Set to Host mode by setting bit 0-1 of USB device mode register */
	temp = readl(hcd->regs + TEGRA_USB_USBMODE_REG_OFFSET);
	writel((temp | TEGRA_USB_USBMODE_HOST),
			(hcd->regs + TEGRA_USB_USBMODE_REG_OFFSET));
	irq = platform_get_irq(pdev, 0);
	if (!irq) {
		e = -ENODEV;
		goto fail_iomap;
	}

	set_irq_flags(irq, IRQF_VALID);

	ehci = hcd_to_ehci(hcd);
	INIT_WORK(&ehci->irq_work, tegra_ehci_irq_work);

	e = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
	if (e != 0) {
		dev_err(&pdev->dev, "failed to add HCD\n");
		goto fail_iomap;
	}
	platform_set_drvdata(pdev, hcd);

#ifdef CONFIG_DMABOUNCE
	e = dmabounce_register_dev(&pdev->dev, 1024, 32768);
	if (e != 0) {
		dev_err(&pdev->dev, "failed to register DMA bounce\n");
		goto fail_add;
	}
#endif

#ifdef CONFIG_USB_OTG_UTILS
	if (pdata->otg_mode) {
		ehci->transceiver = otg_get_transceiver();
		if (!ehci->transceiver) {
			dev_err(&pdev->dev, "Failed to get OTG transceiver\n");
			e = -ENODEV;
			goto fail_dmabounce;
		}

		otg_set_host(ehci->transceiver, (struct usb_bus *)hcd);
		/* Stop the controller and power down the phy, OTG will
		 * start the host driver based on the ID pin
		 * detection */
		ehci_halt(ehci);
		/* reset the host and put the controller in idle mode */
		temp = ehci_readl(ehci, &ehci->regs->command);
		temp |= CMD_RESET;
		ehci_writel(ehci, temp, &ehci->regs->command);
		temp = readl(hcd->regs + TEGRA_USB_USBMODE_REG_OFFSET);
		writel((temp & ~TEGRA_USB_USBMODE_HOST),
			(hcd->regs + TEGRA_USB_USBMODE_REG_OFFSET));
		/* indicate hcd flags, that hardware is not accessable now
		 * in host mode*/
		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
		tegra_ehci_power_down(hcd);
		ehci->host_reinited = 0;
	} else
#endif
	{
		if (pdata->id_detect == ID_PIN_CABLE_ID) {
			/* enable the cable ID interrupt */
			temp = readl(hcd->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET);
			temp |= TEGRA_USB_ID_INT_ENABLE;
			temp |= TEGRA_USB_ID_PIN_WAKEUP_ENABLE;
			writel(temp, (hcd->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET));

			/* Check if we detect any device connected */
			if (temp & TEGRA_USB_ID_PIN_STATUS) {
				tegra_ehci_power_down(hcd);
			} else {
				tegra_ehci_power_up(hcd);
			}
		}
	}

	return 0;

fail_dmabounce:
#ifdef CONFIG_DMABOUNCE
	dmabounce_unregister_dev(&pdev->dev);
#endif
fail_add:
	usb_remove_hcd(hcd);
fail_iomap:
	iounmap(hcd->regs);
fail_mem:
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	release_mem_region(res->start, resource_size(res));
fail_phy:
	NvDdkUsbPhyClose(pdata->hUsbPhy);
fail_gpio:
	if (pdata->gpio_nr)
		gpio_free(pdata->gpio_nr);
fail_hcd:
	usb_put_hcd(hcd);
	return e;
}
コード例 #3
0
/* platform driver interface */
static int __devinit tegra_otg_probe(struct platform_device *pdev)
{
	int err = 0;
	struct resource *res;
	int instance = pdev->id;
	NvError e;
	struct tegra_otg_platform_data *pdata;

	sg_tegra_otg = kzalloc(sizeof(struct tegra_otg_data), GFP_KERNEL);
	if (!sg_tegra_otg)
		return -ENOMEM;

	spin_lock_init(&sg_tegra_otg->lock);
	platform_set_drvdata(pdev, sg_tegra_otg);

	NV_CHECK_ERROR_CLEANUP(
		NvDdkUsbPhyOpen(s_hRmGlobal, instance, &sg_tegra_otg->usb_phy)
	);
	NV_CHECK_ERROR_CLEANUP(
		NvDdkUsbPhyPowerUp(sg_tegra_otg->usb_phy, NV_FALSE, 0)
	);
	sg_tegra_otg->instance = pdev->id;
	sg_tegra_otg->dev = &pdev->dev;
	sg_tegra_otg->otg.label = driver_name;
	sg_tegra_otg->otg.state = OTG_STATE_UNDEFINED;
	sg_tegra_otg->otg.set_peripheral = tegra_otg_set_peripheral;
	sg_tegra_otg->otg.set_host = tegra_otg_set_host;
	sg_tegra_otg->otg.set_power = tegra_otg_set_power;
	sg_tegra_otg->otg.set_suspend = tegra_otg_set_suspend;
	pdata = sg_tegra_otg->dev->platform_data;
	if(pdata->usb_property->IdPinDetectionType == NvOdmUsbIdPinType_CableId)
		sg_tegra_otg->id_connected = 1;
	if(pdata->usb_property->UseInternalPhyWakeup)
		sg_tegra_otg->vbus_connected = 1;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		err = -ENXIO;
		goto err_irq;
	}

	sg_tegra_otg->regs = ioremap(res->start, resource_size(res));
	if (!sg_tegra_otg->regs) {
		err = -ENOMEM;
		goto err_irq;
	}

	sg_tegra_otg->irq = platform_get_irq(pdev, 0);
	if (!sg_tegra_otg->irq) {
		err = -ENODEV;
		goto err_irq;
	}

	err = request_irq(sg_tegra_otg->irq, tegra_otg_irq, IRQF_SHARED,
			driver_name, pdev);
	if (err) {
		printk("cannot request irq %d err %d\n",
				sg_tegra_otg->irq, err);
		goto err_mem_map;
	}

	/* only active when a gadget is registered */
	err = otg_set_transceiver(&sg_tegra_otg->otg);
	if (err) {
		dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
			err);
		goto err_otg;
	}

	NvDdkUsbPhyPowerDown(sg_tegra_otg->usb_phy, NV_FALSE, 0);

	return 0;

err_otg:
	free_irq(sg_tegra_otg->irq, &pdev->dev);
err_mem_map:
	iounmap(sg_tegra_otg->regs);
err_irq:
	NvDdkUsbPhyClose(sg_tegra_otg->usb_phy);
fail:
	platform_set_drvdata(pdev, NULL);
	kfree(sg_tegra_otg);
	return err;
}