diff options
| author | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-02-13 15:17:59 +0000 | 
|---|---|---|
| committer | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-02-13 15:17:59 +0000 | 
| commit | 07c8d27309c0b6a734a012f7b6913a8e815f49eb (patch) | |
| tree | 8b0dcffac18eab34d3c77f4f4f388faf65fdb093 /target/linux/ramips/files/drivers/usb | |
| parent | 9aa91c2c63264cab39919b63efbd5072bbbb9a45 (diff) | |
ramips: add preliminary support for the RT3662/RT3883 SoCs
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@30495 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/ramips/files/drivers/usb')
| -rw-r--r-- | target/linux/ramips/files/drivers/usb/host/ehci-rt3883.c | 162 | ||||
| -rw-r--r-- | target/linux/ramips/files/drivers/usb/host/ohci-rt3883.c | 161 | 
2 files changed, 323 insertions, 0 deletions
diff --git a/target/linux/ramips/files/drivers/usb/host/ehci-rt3883.c b/target/linux/ramips/files/drivers/usb/host/ehci-rt3883.c new file mode 100644 index 000000000..d22bd73b9 --- /dev/null +++ b/target/linux/ramips/files/drivers/usb/host/ehci-rt3883.c @@ -0,0 +1,162 @@ +/* + *  Bus Glue for the built-in EHCI controller of the Ralink RT3662/RT3883 SoCs + * + *  Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org> + * + *  Parts of this file are based on Ralink's 2.6.21 BSP + * + *  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> +#include <asm/mach-ralink/rt3883.h> +#include <asm/mach-ralink/rt3883_ehci_platform.h> + +static int ehci_rt3883_init(struct usb_hcd *hcd) +{ +	struct ehci_hcd *ehci = hcd_to_ehci(hcd); +	int ret; + +	ehci->caps = hcd->regs; +	ehci->regs = hcd->regs + +		     HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); +	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_rt3883_hc_driver = { +	.description		= hcd_name, +	.product_desc		= "Ralink RT3883 built-in EHCI controller", +	.hcd_priv_size		= sizeof(struct ehci_hcd), +	.irq			= ehci_irq, +	.flags			= HCD_MEMORY | HCD_USB2, + +	.reset			= ehci_rt3883_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_rt3883_probe(struct platform_device *pdev) +{ +	struct rt3883_ehci_platform_data *pdata; +	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 for %s\n", +			dev_name(&pdev->dev)); +		return -ENODEV; +	} +	irq = res->start; + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (!res) { +		dev_dbg(&pdev->dev, "no base address specified for %s\n", +			dev_name(&pdev->dev)); +		return -ENODEV; +	} + +	hcd = usb_create_hcd(&ehci_rt3883_hc_driver, &pdev->dev, +			     dev_name(&pdev->dev)); +	if (!hcd) +		return -ENOMEM; + +	hcd->rsrc_start	= res->start; +	hcd->rsrc_len	= res->end - res->start + 1; + +	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; +	} + +	pdata = pdev->dev.platform_data; +	if (pdata && pdata->start_hw) +		pdata->start_hw(); + +	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_rt3883_remove(struct platform_device *pdev) +{ +	struct usb_hcd *hcd = platform_get_drvdata(pdev); +	struct rt3883_ehci_platform_data *pdata; + +	usb_remove_hcd(hcd); +	iounmap(hcd->regs); +	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +	usb_put_hcd(hcd); + +	pdata = pdev->dev.platform_data; +	if (pdata && pdata->stop_hw) +		pdata->stop_hw(); + +	return 0; +} + +static struct platform_driver ehci_rt3883_driver = { +	.probe		= ehci_rt3883_probe, +	.remove		= ehci_rt3883_remove, +	.driver = { +		.owner	= THIS_MODULE, +		.name	= "rt3883-ehci", +	} +}; + +MODULE_ALIAS("platform:rt3883-ehci"); diff --git a/target/linux/ramips/files/drivers/usb/host/ohci-rt3883.c b/target/linux/ramips/files/drivers/usb/host/ohci-rt3883.c new file mode 100644 index 000000000..ea13aebe5 --- /dev/null +++ b/target/linux/ramips/files/drivers/usb/host/ohci-rt3883.c @@ -0,0 +1,161 @@ +/* + *  Bus Glue for the built-in OHCI controller of the Ralink RT3662/RT3883 SoCs + * + *  Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org> + * + *  Parts of this file are based on Ralink's 2.6.21 BSP + * + *  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> +#include <asm/mach-ralink/rt3883.h> +#include <asm/mach-ralink/rt3883_ohci_platform.h> + +static int __devinit ohci_rt3883_start(struct usb_hcd *hcd) +{ +	struct ohci_hcd	*ohci = hcd_to_ohci(hcd); +	int ret; + +	ret = ohci_init(ohci); +	if (ret < 0) +		return ret; + +	ret = ohci_run(ohci); +	if (ret < 0) +		goto err; + +	return 0; + +err: +	ohci_stop(hcd); +	return ret; +} + +static const struct hc_driver ohci_rt3883_hc_driver = { +	.description		= hcd_name, +	.product_desc		= "Ralink RT3883 built-in OHCI controller", +	.hcd_priv_size		= sizeof(struct ohci_hcd), + +	.irq			= ohci_irq, +	.flags			= HCD_USB11 | HCD_MEMORY, + +	.start			= ohci_rt3883_start, +	.stop			= ohci_stop, +	.shutdown		= ohci_shutdown, + +	.urb_enqueue		= ohci_urb_enqueue, +	.urb_dequeue		= ohci_urb_dequeue, +	.endpoint_disable	= ohci_endpoint_disable, + +	/* +	 * scheduling support +	 */ +	.get_frame_number	= ohci_get_frame, + +	/* +	 * root hub support +	 */ +	.hub_status_data	= ohci_hub_status_data, +	.hub_control		= ohci_hub_control, +	.start_port_reset	= ohci_start_port_reset, +}; + +static int ohci_rt3883_probe(struct platform_device *pdev) +{ +	struct rt3883_ohci_platform_data *pdata; +	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 for %s\n", +			dev_name(&pdev->dev)); +		return -ENODEV; +	} +	irq = res->start; + +	hcd = usb_create_hcd(&ohci_rt3883_hc_driver, +			     &pdev->dev, dev_name(&pdev->dev)); +	if (!hcd) +		return -ENOMEM; + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (!res) { +		dev_dbg(&pdev->dev, "no base address specified for %s\n", +			dev_name(&pdev->dev)); +		ret = -ENODEV; +		goto err_put_hcd; +	} +	hcd->rsrc_start	= res->start; +	hcd->rsrc_len	= res->end - res->start + 1; + +	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; +	} + +	pdata = pdev->dev.platform_data; +	if (pdata && pdata->start_hw) +		pdata->start_hw(); + +	ohci_hcd_init(hcd_to_ohci(hcd)); + +	ret = usb_add_hcd(hcd, irq, IRQF_SHARED); +	if (ret) +		goto err_stop_hcd; + +	return 0; + +err_stop_hcd: +	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 ohci_rt3883_remove(struct platform_device *pdev) +{ +	struct usb_hcd *hcd = platform_get_drvdata(pdev); +	struct rt3883_ohci_platform_data *pdata; + +	usb_remove_hcd(hcd); +	iounmap(hcd->regs); +	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +	usb_put_hcd(hcd); + +	pdata = pdev->dev.platform_data; +	if (pdata && pdata->stop_hw) +		pdata->stop_hw(); + +	return 0; +} + +static struct platform_driver ohci_rt3883_driver = { +	.probe		= ohci_rt3883_probe, +	.remove		= ohci_rt3883_remove, +	.shutdown	= usb_hcd_platform_shutdown, +	.driver		= { +		.name	= "rt3883-ohci", +		.owner	= THIS_MODULE, +	}, +}; + +MODULE_ALIAS("platform:rt3883-ohci");  | 
