From: Florian Fainelli <florian@openwrt.org>
Date: Thu, 6 Dec 2012 22:40:49 +0000 (+0000)
Subject: add support for on-board EHCI controller
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=a5aed4ec3acbb935aa406c339cd8b48e2e9ce870;p=openwrt%2Fstaging%2Fwigyori.git

add support for on-board EHCI controller

Signed-off-by: Florian Fainelli <florian@openwrt.org>

SVN-Revision: 34561
---

diff --git a/target/linux/adm8668/files/arch/mips/adm8668/platform.c b/target/linux/adm8668/files/arch/mips/adm8668/platform.c
index dc0fd91a33..71f3eca142 100644
--- a/target/linux/adm8668/files/arch/mips/adm8668/platform.c
+++ b/target/linux/adm8668/files/arch/mips/adm8668/platform.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/tulip.h>
+#include <linux/usb/ehci_pdriver.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/partitions.h>
 #include <linux/pci.h>
@@ -130,10 +131,38 @@ static struct platform_device adm8668_nor_device = {
 	.dev.platform_data = &nor_flash_data,
 };
 
+static struct resource usb_resources[] = {
+	{
+		.start	= ADM8668_USB_BASE,
+		.end	= ADM8668_USB_BASE + 0x1FFFFF,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_LVL_USB,
+		.end	= INT_LVL_USB,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct usb_ehci_pdata usb_pdata = {
+	.caps_offset	= 0x100,
+	.has_tt		= 1,
+	.port_power_off	= 1,
+};
+
+static struct platform_device adm8668_usb_device = {
+	.name		= "ehci-platform",
+	.id		= -1,
+	.resource	= usb_resources,
+	.num_resources	= ARRAY_SIZE(usb_resources),
+	.dev.platform_data = &usb_pdata,
+};
+
 static struct platform_device *adm8668_devs[] = {
 	&adm8668_eth0_device,
 	&adm8668_eth1_device,
 	&adm8668_nor_device,
+	&adm8668_usb_device,
 };
 
 static void adm8668_fetch_mac(int unit)
@@ -162,6 +191,21 @@ static void adm8668_fetch_mac(int unit)
 	memcpy(pdata->mac, mac, sizeof(pdata->mac));
 }
 
+static void adm8668_ehci_workaround(void)
+{
+	u32 chipid;
+
+	chipid = ADM8668_CONFIG_REG(ADM8668_CR0);
+	ADM8668_CONFIG_REG(ADM8668_CR66) = 0x0C1600D9;
+
+	if (chipid == 0x86880001)
+		return;
+
+	ADM8668_CONFIG_REG(ADM8668_CR66) &= ~(3 << 20);
+	ADM8668_CONFIG_REG(ADM8668_CR66) |= (1 << 20);
+	pr_info("ADM8668: applied USB workaround\n");
+}
+
 
 int __devinit adm8668_devs_register(void)
 {
@@ -173,6 +217,7 @@ int __devinit adm8668_devs_register(void)
 
 	adm8668_fetch_mac(0);
 	adm8668_fetch_mac(1);
+	adm8668_ehci_workaround();
 
 	return platform_add_devices(adm8668_devs, ARRAY_SIZE(adm8668_devs));
 }
diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h
index f7b2c5e632..65ed0b5d3e 100644
--- a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h
+++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h
@@ -64,6 +64,7 @@
 #define ADM8668_CR0		0x00
 #define ADM8668_CR1		0x04
 #define ADM8668_CR3		0x0C
+#define ADM8668_CR66		0x108
 
 /** For GPIO control **/
 #define	GPIO_REG		0x5C	/* on WLAN */