[PATCH 5/5] [ARM] pxa/cm-x300: enable USB host port 2 on CM-X300 with PXA310 cpu.
Igor Grinberg
grinberg at compulab.co.il
Wed Jun 2 03:40:50 EDT 2010
Signed-off-by: Igor Grinberg <grinberg at compulab.co.il>
Signed-off-by: Mike Rapoport <mike at compulab.co.il>
---
arch/arm/mach-pxa/cm-x300.c | 102 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 102 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index d37cfa1..87ffb38 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/dm9000.h>
@@ -35,6 +36,9 @@
#include <linux/spi/spi_gpio.h>
#include <linux/spi/tdo24m.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/setup.h>
@@ -47,6 +51,7 @@
#include <plat/i2c.h>
#include <plat/pxa3xx_nand.h>
#include <mach/audio.h>
+#include <mach/pxa310-ulpi.h>
#include <asm/mach/map.h>
@@ -65,6 +70,8 @@
#define GPIO97_RTC_RD (97)
#define GPIO98_RTC_IO (98)
+#define GPIO127_ULPI_PHY_RST (127)
+
static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = {
/* LCD */
GPIO54_LCD_LDD_0,
@@ -470,23 +477,118 @@ static inline void cm_x300_init_mmc(void) {}
#endif
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+#if defined(CONFIG_PXA310_ULPI)
+static struct clk *pout_clk;
+
+static int cm_x300_ulpi_clk_enable(void)
+{
+ int err;
+
+ /* CLK_POUT is connected to the ULPI PHY */
+ pout_clk = clk_get(NULL, "CLK_POUT");
+ if (IS_ERR(pout_clk)) {
+ err = PTR_ERR(pout_clk);
+ pr_err("%s: failed to get CLK_POUT: %d\n", __func__, err);
+ return err;
+ }
+ clk_enable(pout_clk);
+
+ return 0;
+}
+
+static inline void cm_x300_ulpi_clk_disable(void)
+{
+ if (!IS_ERR(pout_clk)) {
+ clk_disable(pout_clk);
+ clk_put(pout_clk);
+ }
+}
+
+static int cm_x300_ulpi_phy_reset(void)
+{
+ int err;
+
+ /* reset the PHY */
+ err = gpio_request(GPIO127_ULPI_PHY_RST, "ulpi reset");
+ if (err) {
+ pr_err("%s: failed to request ULPI reset GPIO: %d\n",
+ __func__, err);
+ return err;
+ }
+
+ gpio_direction_output(GPIO127_ULPI_PHY_RST, 0);
+ msleep(10);
+ gpio_set_value(GPIO127_ULPI_PHY_RST, 1);
+ msleep(10);
+
+ gpio_free(GPIO127_ULPI_PHY_RST);
+
+ return 0;
+}
+
+static inline int cm_x300_ulpi_init(void)
+{
+ int err;
+
+ err = cm_x300_ulpi_clk_enable();
+ if (err)
+ return err;
+
+ err = cm_x300_ulpi_phy_reset();
+ if (err)
+ pr_err("%s: ULPI PHY init failed!\n", __func__);
+
+ return err;
+}
+#else
+static inline int cm_x300_ulpi_init(void) { return 0; }
+static inline void cm_x300_ulpi_clk_disable(void) {}
+#endif /* CONFIG_PXA310_ULPI */
+
static int cm_x300_ohci_init(struct device *dev)
{
if (cpu_is_pxa300())
UP2OCR = UP2OCR_HXS
| UP2OCR_HXOE | UP2OCR_DMPDE | UP2OCR_DPPDE;
+ if (cpu_is_pxa310())
+ cm_x300_ulpi_init();
+
return 0;
}
+static void cm_x300_ohci_exit(struct device *dev)
+{
+ if (cpu_is_pxa310())
+ cm_x300_ulpi_clk_disable();
+}
+
static struct pxaohci_platform_data cm_x300_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW,
.init = cm_x300_ohci_init,
+ .exit = cm_x300_ohci_exit,
+
+#if defined(CONFIG_PXA310_ULPI)
+ .ulpi_mode = ULPI_IC_6PIN,
+#endif
};
static void __init cm_x300_init_ohci(void)
{
+ if (cpu_is_pxa310()) {
+#if defined(CONFIG_PXA310_ULPI)
+ cm_x300_ohci_platform_data.otg =
+ otg_ulpi_create(&pxa310_ulpi_access_ops,
+ USB_OTG_PULLDOWN_DM |
+ USB_OTG_PULLDOWN_DP |
+ USB_OTG_DRV_VBUS,
+ ULPI_IC_6PIN,
+ ULPI_FC_DEFAULT |
+ ULPI_FC_TRM_SEL);
+#endif
+ }
+
pxa_set_ohci_info(&cm_x300_ohci_platform_data);
}
#else
--
1.6.4.4
More information about the linux-arm-kernel
mailing list