From fa606c4acbb2713135454b77f8cb36c38cb81d11 Mon Sep 17 00:00:00 2001
From: Guennadi Liakhovetski <lyakh@axis700.grange>
Date: Thu, 16 Apr 2009 14:28:05 +0200
Subject: [PATCH] ARM: add USB device support to pcm037

Add OTG device definition and resources to i.MX31 and a pure USB device mode
support to the pcm037 board.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 arch/arm/mach-mx3/devices.c                |   25 +++++++++++++
 arch/arm/mach-mx3/devices.h                |    1 +
 arch/arm/mach-mx3/pcm037.c                 |   51 ++++++++++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/iomux-mx3.h |   12 ++++++
 4 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index a3ac845..c4b0d51 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -353,6 +353,31 @@ struct platform_device mx3_camera = {
 	},
 };
 
+static struct resource otg_resources[] = {
+	{
+		.start = OTG_BASE_ADDR,
+		.end   = OTG_BASE_ADDR + 0x1ff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_USB3,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static u64 otg_dmamask = DMA_BIT_MASK(32);
+
+/* OTG gadget device */
+struct platform_device mxc_otg_udc_device = {
+	.name = "fsl-usb2-udc",
+	.id   = -1,
+	.dev  = {
+		.dma_mask          = &otg_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.resource = otg_resources,
+	.num_resources = ARRAY_SIZE(otg_resources),
+};
+
 #ifdef CONFIG_ARCH_MX35
 static struct resource mxc_fec_resources[] = {
 	{
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h
index 7045f8b..475410a 100644
--- a/arch/arm/mach-mx3/devices.h
+++ b/arch/arm/mach-mx3/devices.h
@@ -15,3 +15,4 @@ extern struct platform_device mx3_camera;
 extern struct platform_device mxc_fec_device;
 extern struct platform_device mxcsdhc_device0;
 extern struct platform_device mxcsdhc_device1;
+extern struct platform_device mxc_otg_udc_device;
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c
index 00ce1eb..8e2fee6 100644
--- a/arch/arm/mach-mx3/pcm037.c
+++ b/arch/arm/mach-mx3/pcm037.c
@@ -31,6 +31,7 @@
 #include <linux/delay.h>
 #include <linux/spi/spi.h>
 #include <linux/irq.h>
+#include <linux/fsl_devices.h>
 
 #include <media/soc_camera.h>
 
@@ -152,6 +153,54 @@ static struct resource pcm037_flash_resource = {
 	.flags	= IORESOURCE_MEM,
 };
 
+static int usbotg_pins[] = {
+	MX31_PIN_USBOTG_DATA0__DATA0,
+	MX31_PIN_USBOTG_DATA1__DATA1,
+	MX31_PIN_USBOTG_DATA2__DATA2,
+	MX31_PIN_USBOTG_DATA3__DATA3,
+	MX31_PIN_USBOTG_DATA4__DATA4,
+	MX31_PIN_USBOTG_DATA5__DATA5,
+	MX31_PIN_USBOTG_DATA6__DATA6,
+	MX31_PIN_USBOTG_DATA7__DATA7,
+	MX31_PIN_USBOTG_CLK__CLK,
+	MX31_PIN_USBOTG_DIR__DIR,
+	MX31_PIN_USBOTG_NXT__NXT,
+	MX31_PIN_USBOTG_STP__STP,
+};
+
+/* USB OTG HS port */
+static int __init gpio_usbotg_hs_activate(void)
+{
+	int ret = mxc_iomux_setup_multiple_pins(usbotg_pins,
+					ARRAY_SIZE(usbotg_pins), "usbotg");
+
+	if (ret < 0) {
+		printk(KERN_ERR "Cannot set up OTG pins\n");
+		return ret;
+	}
+
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK,   PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR,   PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT,   PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_STP,   PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST);
+
+	return 0;
+}
+
+/* OTG config */
+static struct fsl_usb2_platform_data usb_pdata = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_ULPI,
+};
+
 static struct platform_device pcm037_flash = {
 	.name	= "physmap-flash",
 	.id	= 0,
@@ -414,6 +463,8 @@ static void __init mxc_board_init(void)
 	mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
 	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
 	mxc_register_device(&mx3_fb, &mx3fb_pdata);
+	if (!gpio_usbotg_hs_activate())
+		mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
 
 	/* CSI */
 	/* Camera power: default - off */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
index 43d4199..c44d090 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -624,6 +624,18 @@ enum iomux_pins {
 #define MX31_PIN_GPIO3_0__GPIO3_0	IOMUX_MODE(MX31_PIN_GPIO3_0, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_GPIO3_1__GPIO3_1	IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_TXD2__GPIO1_28		IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_USBOTG_DATA0__DATA0	IOMUX_MODE(MX31_PIN_USBOTG_DATA0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA1__DATA1	IOMUX_MODE(MX31_PIN_USBOTG_DATA1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA2__DATA2	IOMUX_MODE(MX31_PIN_USBOTG_DATA2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA3__DATA3	IOMUX_MODE(MX31_PIN_USBOTG_DATA3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA4__DATA4	IOMUX_MODE(MX31_PIN_USBOTG_DATA4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA5__DATA5	IOMUX_MODE(MX31_PIN_USBOTG_DATA5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA6__DATA6	IOMUX_MODE(MX31_PIN_USBOTG_DATA6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA7__DATA7	IOMUX_MODE(MX31_PIN_USBOTG_DATA7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_CLK__CLK	IOMUX_MODE(MX31_PIN_USBOTG_CLK,   IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DIR__DIR	IOMUX_MODE(MX31_PIN_USBOTG_DIR,   IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_NXT__NXT	IOMUX_MODE(MX31_PIN_USBOTG_NXT,   IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_STP__STP	IOMUX_MODE(MX31_PIN_USBOTG_STP,   IOMUX_CONFIG_FUNC)
 
 /*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0
  * cspi1_ss1*/
-- 
1.5.4

