diff options
| author | Alberto Panizzo <maramaopercheseimorto@gmail.com> | 2010-02-26 12:36:32 -0500 |
|---|---|---|
| committer | Sascha Hauer <s.hauer@pengutronix.de> | 2010-03-30 08:25:03 -0400 |
| commit | b3aa111f7ac1ad07009081a824b5ce7a71462c4c (patch) | |
| tree | ee0880936be81e1bcab9f788b59035a00e96a37c | |
| parent | 17669fd60e6b245945cdd4bbe87d1186a07a03b6 (diff) | |
MXC: mach_armadillo5x0: Add USB Host support.
This add USB Host capability. The Armadillo 500 board is supplied
with two USB Host connectors driven by the USB OTG and USB Host 2
ports, through two NXP isp 1504 transceivers.
Signed-off-by: Alberto Panizzo <maramaopercheseimorto@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
| -rw-r--r-- | arch/arm/mach-mx3/Kconfig | 1 | ||||
| -rw-r--r-- | arch/arm/mach-mx3/mach-armadillo5x0.c | 166 |
2 files changed, 167 insertions, 0 deletions
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 9a2911e004a3..170f68e46dd5 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig | |||
| @@ -104,6 +104,7 @@ config MACH_PCM043 | |||
| 104 | config MACH_ARMADILLO5X0 | 104 | config MACH_ARMADILLO5X0 |
| 105 | bool "Support Atmark Armadillo-500 Development Base Board" | 105 | bool "Support Atmark Armadillo-500 Development Base Board" |
| 106 | select ARCH_MX31 | 106 | select ARCH_MX31 |
| 107 | select MXC_ULPI if USB_ULPI | ||
| 107 | help | 108 | help |
| 108 | Include support for Atmark Armadillo-500 platform. This includes | 109 | Include support for Atmark Armadillo-500 platform. This includes |
| 109 | specific configurations for the board and its peripherals. | 110 | specific configurations for the board and its peripherals. |
diff --git a/arch/arm/mach-mx3/mach-armadillo5x0.c b/arch/arm/mach-mx3/mach-armadillo5x0.c index 3d72b0b89705..5f72ec91af2d 100644 --- a/arch/arm/mach-mx3/mach-armadillo5x0.c +++ b/arch/arm/mach-mx3/mach-armadillo5x0.c | |||
| @@ -36,6 +36,9 @@ | |||
| 36 | #include <linux/input.h> | 36 | #include <linux/input.h> |
| 37 | #include <linux/gpio_keys.h> | 37 | #include <linux/gpio_keys.h> |
| 38 | #include <linux/i2c.h> | 38 | #include <linux/i2c.h> |
| 39 | #include <linux/usb/otg.h> | ||
| 40 | #include <linux/usb/ulpi.h> | ||
| 41 | #include <linux/delay.h> | ||
| 39 | 42 | ||
| 40 | #include <mach/hardware.h> | 43 | #include <mach/hardware.h> |
| 41 | #include <asm/mach-types.h> | 44 | #include <asm/mach-types.h> |
| @@ -52,6 +55,8 @@ | |||
| 52 | #include <mach/ipu.h> | 55 | #include <mach/ipu.h> |
| 53 | #include <mach/mx3fb.h> | 56 | #include <mach/mx3fb.h> |
| 54 | #include <mach/mxc_nand.h> | 57 | #include <mach/mxc_nand.h> |
| 58 | #include <mach/mxc_ehci.h> | ||
| 59 | #include <mach/ulpi.h> | ||
| 55 | 60 | ||
| 56 | #include "devices.h" | 61 | #include "devices.h" |
| 57 | #include "crm_regs.h" | 62 | #include "crm_regs.h" |
| @@ -103,8 +108,158 @@ static int armadillo5x0_pins[] = { | |||
| 103 | /* I2C2 */ | 108 | /* I2C2 */ |
| 104 | MX31_PIN_CSPI2_MOSI__SCL, | 109 | MX31_PIN_CSPI2_MOSI__SCL, |
| 105 | MX31_PIN_CSPI2_MISO__SDA, | 110 | MX31_PIN_CSPI2_MISO__SDA, |
| 111 | /* OTG */ | ||
| 112 | MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, | ||
| 113 | MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, | ||
| 114 | MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, | ||
| 115 | MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, | ||
| 116 | MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, | ||
| 117 | MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, | ||
| 118 | MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, | ||
| 119 | MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, | ||
| 120 | MX31_PIN_USBOTG_CLK__USBOTG_CLK, | ||
| 121 | MX31_PIN_USBOTG_DIR__USBOTG_DIR, | ||
| 122 | MX31_PIN_USBOTG_NXT__USBOTG_NXT, | ||
| 123 | MX31_PIN_USBOTG_STP__USBOTG_STP, | ||
| 124 | /* USB host 2 */ | ||
| 125 | IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC), | ||
| 126 | IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC), | ||
| 127 | IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC), | ||
| 128 | IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC), | ||
| 129 | IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC), | ||
| 130 | IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC), | ||
| 131 | IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC), | ||
| 132 | IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC), | ||
| 133 | IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC), | ||
| 134 | IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC), | ||
| 135 | IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC), | ||
| 136 | IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC), | ||
| 106 | }; | 137 | }; |
| 107 | 138 | ||
| 139 | /* USB */ | ||
| 140 | #if defined(CONFIG_USB_ULPI) | ||
| 141 | |||
| 142 | #define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4) | ||
| 143 | #define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6) | ||
| 144 | #define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3) | ||
| 145 | |||
| 146 | #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
| 147 | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | ||
| 148 | |||
| 149 | static int usbotg_init(struct platform_device *pdev) | ||
| 150 | { | ||
| 151 | int err; | ||
| 152 | |||
| 153 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG); | ||
| 154 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG); | ||
| 155 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG); | ||
| 156 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG); | ||
| 157 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG); | ||
| 158 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG); | ||
| 159 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG); | ||
| 160 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG); | ||
| 161 | mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG); | ||
| 162 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG); | ||
| 163 | mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG); | ||
| 164 | mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG); | ||
| 165 | |||
| 166 | /* Chip already enabled by hardware */ | ||
| 167 | /* OTG phy reset*/ | ||
| 168 | err = gpio_request(OTG_RESET, "USB-OTG-RESET"); | ||
| 169 | if (err) { | ||
| 170 | pr_err("Failed to request the usb otg reset gpio\n"); | ||
| 171 | return err; | ||
| 172 | } | ||
| 173 | |||
| 174 | err = gpio_direction_output(OTG_RESET, 1/*HIGH*/); | ||
| 175 | if (err) { | ||
| 176 | pr_err("Failed to reset the usb otg phy\n"); | ||
| 177 | goto otg_free_reset; | ||
| 178 | } | ||
| 179 | |||
| 180 | gpio_set_value(OTG_RESET, 0/*LOW*/); | ||
| 181 | mdelay(5); | ||
| 182 | gpio_set_value(OTG_RESET, 1/*HIGH*/); | ||
| 183 | |||
| 184 | return 0; | ||
| 185 | |||
| 186 | otg_free_reset: | ||
| 187 | gpio_free(OTG_RESET); | ||
| 188 | return err; | ||
| 189 | } | ||
| 190 | |||
| 191 | static int usbh2_init(struct platform_device *pdev) | ||
| 192 | { | ||
| 193 | int err; | ||
| 194 | |||
| 195 | mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); | ||
| 196 | mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); | ||
| 197 | mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); | ||
| 198 | mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); | ||
| 199 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); | ||
| 200 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); | ||
| 201 | mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); | ||
| 202 | mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); | ||
| 203 | mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); | ||
| 204 | mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); | ||
| 205 | mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); | ||
| 206 | mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); | ||
| 207 | |||
| 208 | mxc_iomux_set_gpr(MUX_PGP_UH2, true); | ||
| 209 | |||
| 210 | |||
| 211 | /* Enable the chip */ | ||
| 212 | err = gpio_request(USBH2_CS, "USB-H2-CS"); | ||
| 213 | if (err) { | ||
| 214 | pr_err("Failed to request the usb host 2 CS gpio\n"); | ||
| 215 | return err; | ||
| 216 | } | ||
| 217 | |||
| 218 | err = gpio_direction_output(USBH2_CS, 0/*Enabled*/); | ||
| 219 | if (err) { | ||
| 220 | pr_err("Failed to drive the usb host 2 CS gpio\n"); | ||
| 221 | goto h2_free_cs; | ||
| 222 | } | ||
| 223 | |||
| 224 | /* H2 phy reset*/ | ||
| 225 | err = gpio_request(USBH2_RESET, "USB-H2-RESET"); | ||
| 226 | if (err) { | ||
| 227 | pr_err("Failed to request the usb host 2 reset gpio\n"); | ||
| 228 | goto h2_free_cs; | ||
| 229 | } | ||
| 230 | |||
| 231 | err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/); | ||
| 232 | if (err) { | ||
| 233 | pr_err("Failed to reset the usb host 2 phy\n"); | ||
| 234 | goto h2_free_reset; | ||
| 235 | } | ||
| 236 | |||
| 237 | gpio_set_value(USBH2_RESET, 0/*LOW*/); | ||
| 238 | mdelay(5); | ||
| 239 | gpio_set_value(USBH2_RESET, 1/*HIGH*/); | ||
| 240 | |||
| 241 | return 0; | ||
| 242 | |||
| 243 | h2_free_reset: | ||
| 244 | gpio_free(USBH2_RESET); | ||
| 245 | h2_free_cs: | ||
| 246 | gpio_free(USBH2_CS); | ||
| 247 | return err; | ||
| 248 | } | ||
| 249 | |||
| 250 | static struct mxc_usbh_platform_data usbotg_pdata = { | ||
| 251 | .init = usbotg_init, | ||
| 252 | .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, | ||
| 253 | .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI, | ||
| 254 | }; | ||
| 255 | |||
| 256 | static struct mxc_usbh_platform_data usbh2_pdata = { | ||
| 257 | .init = usbh2_init, | ||
| 258 | .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, | ||
| 259 | .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI, | ||
| 260 | }; | ||
| 261 | #endif /* CONFIG_USB_ULPI */ | ||
| 262 | |||
| 108 | /* RTC over I2C*/ | 263 | /* RTC over I2C*/ |
| 109 | #define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4) | 264 | #define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4) |
| 110 | 265 | ||
| @@ -393,6 +548,17 @@ static void __init armadillo5x0_init(void) | |||
| 393 | if (armadillo5x0_i2c_rtc.irq == 0) | 548 | if (armadillo5x0_i2c_rtc.irq == 0) |
| 394 | pr_warning("armadillo5x0_init: failed to get RTC IRQ\n"); | 549 | pr_warning("armadillo5x0_init: failed to get RTC IRQ\n"); |
| 395 | i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1); | 550 | i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1); |
| 551 | |||
| 552 | /* USB */ | ||
| 553 | #if defined(CONFIG_USB_ULPI) | ||
| 554 | usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | ||
| 555 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | ||
| 556 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | ||
| 557 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | ||
| 558 | |||
| 559 | mxc_register_device(&mxc_otg_host, &usbotg_pdata); | ||
| 560 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); | ||
| 561 | #endif | ||
| 396 | } | 562 | } |
| 397 | 563 | ||
| 398 | static void __init armadillo5x0_timer_init(void) | 564 | static void __init armadillo5x0_timer_init(void) |
