/*
 *  Bus Glue for Atheros AR7XXX/AR9XXX built-in EHCI controller.
 *
 *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
 *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
 *
 *  Parts of this file are based on Atheros' 2.6.15 BSP
 *	Copyright (C) 2007 Atheros Communications, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License version 2 as published
 *  by the Free Software Foundation.
 */

#include <linux/platform_device.h>

enum {
	EHCI_ATH79_IP_V1 = 0,
	EHCI_ATH79_IP_V2,
};

static const struct platform_device_id ehci_ath79_id_table[] = {
	{
		.name		= "ar71xx-ehci",
		.driver_data	= EHCI_ATH79_IP_V1,
	},
	{
		.name		= "ar724x-ehci",
		.driver_data	= EHCI_ATH79_IP_V2,
	},
	{
		.name		= "ar913x-ehci",
		.driver_data	= EHCI_ATH79_IP_V2,
	},
	{
		.name		= "ar933x-ehci",
		.driver_data	= EHCI_ATH79_IP_V2,
	},
	{
		/* terminating entry */
	},
};

MODULE_DEVICE_TABLE(platform, ehci_ath79_id_table);

static int ehci_ath79_init(struct usb_hcd *hcd)
{
	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
	struct platform_device *pdev = to_platform_device(hcd->self.controller);
	const struct platform_device_id *id;
	int ret;

	id = platform_get_device_id(pdev);
	if (!id) {
		dev_err(hcd->self.controller, "missing device id\n");
		return -EINVAL;
	}

	switch (id->driver_data) {
	case EHCI_ATH79_IP_V1:
		ehci->has_synopsys_hc_bug = 1;

		ehci->caps = hcd->regs;
		ehci->regs = hcd->regs +
			HC_LENGTH(ehci,
				  ehci_readl(ehci, &ehci->caps->hc_capbase));
		break;

	case EHCI_ATH79_IP_V2:
		hcd->has_tt = 1;

		ehci->caps = hcd->regs + 0x100;
		ehci->regs = hcd->regs + 0x100 +
			HC_LENGTH(ehci,
				  ehci_readl(ehci, &ehci->caps->hc_capbase));
		break;

	default:
		BUG();
	}

	dbg_hcs_params(ehci, "reset");
	dbg_hcc_params(ehci, "reset");
	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
	ehci->sbrn = 0x20;

	ehci_reset(ehci);

	ret = ehci_init(hcd);
	if (ret)
		return ret;

	ehci_port_power(ehci, 0);

	return 0;
}

static const struct hc_driver ehci_ath79_hc_driver = {
	.description		= hcd_name,
	.product_desc		= "Atheros built-in EHCI controller",
	.hcd_priv_size		= sizeof(struct ehci_hcd),
	.irq			= ehci_irq,
	.flags			= HCD_MEMORY | HCD_USB2,

	.reset			= ehci_ath79_init,
	.start			= ehci_run,
	.stop			= ehci_stop,
	.shutdown		= ehci_shutdown,

	.urb_enqueue		= ehci_urb_enqueue,
	.urb_dequeue		= ehci_urb_dequeue,
	.endpoint_disable	= ehci_endpoint_disable,
	.endpoint_reset		= ehci_endpoint_reset,

	.get_frame_number	= ehci_get_frame,

	.hub_status_data	= ehci_hub_status_data,
	.hub_control		= ehci_hub_control,

	.relinquish_port	= ehci_relinquish_port,
	.port_handed_over	= ehci_port_handed_over,

	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};

static int ehci_ath79_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct resource *res;
	int irq;
	int ret;

	if (usb_disabled())
		return -ENODEV;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_dbg(&pdev->dev, "no IRQ specified\n");
		return -ENODEV;
	}
	irq = res->start;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_dbg(&pdev->dev, "no base address specified\n");
		return -ENODEV;
	}

	hcd = usb_create_hcd(&ehci_ath79_hc_driver, &pdev->dev,
			     dev_name(&pdev->dev));
	if (!hcd)
		return -ENOMEM;

	hcd->rsrc_start	= res->start;
	hcd->rsrc_len	= resource_size(res);

	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		dev_dbg(&pdev->dev, "controller already in use\n");
		ret = -EBUSY;
		goto err_put_hcd;
	}

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_dbg(&pdev->dev, "error mapping memory\n");
		ret = -EFAULT;
		goto err_release_region;
	}

	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (ret)
		goto err_iounmap;

	return 0;

err_iounmap:
	iounmap(hcd->regs);

err_release_region:
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err_put_hcd:
	usb_put_hcd(hcd);
	return ret;
}

static int ehci_ath79_remove(struct platform_device *pdev)
{
	struct usb_hcd *hcd = platform_get_drvdata(pdev);

	usb_remove_hcd(hcd);
	iounmap(hcd->regs);
	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	usb_put_hcd(hcd);

	return 0;
}

static struct platform_driver ehci_ath79_driver = {
	.probe		= ehci_ath79_probe,
	.remove		= ehci_ath79_remove,
	.id_table	= ehci_ath79_id_table,
	.driver = {
		.owner	= THIS_MODULE,
		.name	= "ath79-ehci",
	}
};

MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ath79-ehci");
