diff options
author | Mike Rapoport <mike@compulab.co.il> | 2009-05-12 09:31:16 -0400 |
---|---|---|
committer | Eric Miao <eric.y.miao@gmail.com> | 2009-06-04 22:50:25 -0400 |
commit | 128d88b82e47d070170c256b2b19f57c352af310 (patch) | |
tree | 6a135607b91b4804691583f9f505db080d5091d8 /arch/arm | |
parent | 3690a0f4266127557524501c680760b1e6cb55d0 (diff) |
[ARM] pxa/em-x270: add support for on-board USB Hub
Signed-off-by: Mike Rapoport <mike@compulab.co.il>
Signed-off-by: Eric Miao <eric.miao@marvell.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-pxa/em-x270.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 35a12038dc0b..3ff1fec017fd 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #define GPIO95_MMC_WP (95) | 55 | #define GPIO95_MMC_WP (95) |
56 | #define GPIO56_NAND_RB (56) | 56 | #define GPIO56_NAND_RB (56) |
57 | #define GPIO93_CAM_RESET (93) | 57 | #define GPIO93_CAM_RESET (93) |
58 | #define GPIO16_USB_HUB_RESET (16) | ||
58 | 59 | ||
59 | /* eXeda specific GPIOs */ | 60 | /* eXeda specific GPIOs */ |
60 | #define GPIO114_MMC_CD (114) | 61 | #define GPIO114_MMC_CD (114) |
@@ -63,6 +64,7 @@ | |||
63 | #define GPIO37_WLAN_RST (37) | 64 | #define GPIO37_WLAN_RST (37) |
64 | #define GPIO95_TOUCHPAD_INT (95) | 65 | #define GPIO95_TOUCHPAD_INT (95) |
65 | #define GPIO130_CAM_RESET (130) | 66 | #define GPIO130_CAM_RESET (130) |
67 | #define GPIO10_USB_HUB_RESET (10) | ||
66 | 68 | ||
67 | /* common GPIOs */ | 69 | /* common GPIOs */ |
68 | #define GPIO11_NAND_CS (11) | 70 | #define GPIO11_NAND_CS (11) |
@@ -70,11 +72,13 @@ | |||
70 | #define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ) | 72 | #define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ) |
71 | #define GPIO115_WLAN_PWEN (115) | 73 | #define GPIO115_WLAN_PWEN (115) |
72 | #define GPIO19_WLAN_STRAP (19) | 74 | #define GPIO19_WLAN_STRAP (19) |
75 | #define GPIO9_USB_VBUS_EN (9) | ||
73 | 76 | ||
74 | static int mmc_cd; | 77 | static int mmc_cd; |
75 | static int nand_rb; | 78 | static int nand_rb; |
76 | static int dm9000_flags; | 79 | static int dm9000_flags; |
77 | static int cam_reset; | 80 | static int cam_reset; |
81 | static int usb_hub_reset; | ||
78 | 82 | ||
79 | static unsigned long common_pin_config[] = { | 83 | static unsigned long common_pin_config[] = { |
80 | /* AC'97 */ | 84 | /* AC'97 */ |
@@ -197,12 +201,14 @@ static unsigned long common_pin_config[] = { | |||
197 | 201 | ||
198 | static unsigned long em_x270_pin_config[] = { | 202 | static unsigned long em_x270_pin_config[] = { |
199 | GPIO13_GPIO, /* MMC card detect */ | 203 | GPIO13_GPIO, /* MMC card detect */ |
204 | GPIO16_GPIO, /* USB hub reset */ | ||
200 | GPIO56_GPIO, /* NAND Ready/Busy */ | 205 | GPIO56_GPIO, /* NAND Ready/Busy */ |
201 | GPIO93_GPIO | MFP_LPM_DRIVE_LOW, /* Camera reset */ | 206 | GPIO93_GPIO | MFP_LPM_DRIVE_LOW, /* Camera reset */ |
202 | GPIO95_GPIO, /* MMC Write protect */ | 207 | GPIO95_GPIO, /* MMC Write protect */ |
203 | }; | 208 | }; |
204 | 209 | ||
205 | static unsigned long exeda_pin_config[] = { | 210 | static unsigned long exeda_pin_config[] = { |
211 | GPIO10_GPIO, /* USB hub reset */ | ||
206 | GPIO20_GPIO, /* NAND Ready/Busy */ | 212 | GPIO20_GPIO, /* NAND Ready/Busy */ |
207 | GPIO38_GPIO | MFP_LPM_DRIVE_LOW, /* SD slot power */ | 213 | GPIO38_GPIO | MFP_LPM_DRIVE_LOW, /* SD slot power */ |
208 | GPIO95_GPIO, /* touchpad IRQ */ | 214 | GPIO95_GPIO, /* touchpad IRQ */ |
@@ -471,18 +477,79 @@ static inline void em_x270_init_nor(void) {} | |||
471 | 477 | ||
472 | /* PXA27x OHCI controller setup */ | 478 | /* PXA27x OHCI controller setup */ |
473 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 479 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
480 | static struct regulator *em_x270_usb_ldo; | ||
481 | |||
482 | static int em_x270_usb_hub_init(void) | ||
483 | { | ||
484 | int err; | ||
485 | |||
486 | em_x270_usb_ldo = regulator_get(NULL, "vcc usb"); | ||
487 | if (IS_ERR(em_x270_usb_ldo)) | ||
488 | return PTR_ERR(em_x270_usb_ldo); | ||
489 | |||
490 | err = gpio_request(GPIO9_USB_VBUS_EN, "vbus en"); | ||
491 | if (err) | ||
492 | goto err_free_usb_ldo; | ||
493 | |||
494 | err = gpio_request(usb_hub_reset, "hub rst"); | ||
495 | if (err) | ||
496 | goto err_free_vbus_gpio; | ||
497 | |||
498 | /* USB Hub power-on and reset */ | ||
499 | gpio_direction_output(usb_hub_reset, 0); | ||
500 | regulator_enable(em_x270_usb_ldo); | ||
501 | gpio_set_value(usb_hub_reset, 1); | ||
502 | gpio_set_value(usb_hub_reset, 0); | ||
503 | regulator_disable(em_x270_usb_ldo); | ||
504 | regulator_enable(em_x270_usb_ldo); | ||
505 | gpio_set_value(usb_hub_reset, 1); | ||
506 | |||
507 | /* enable VBUS */ | ||
508 | gpio_direction_output(GPIO9_USB_VBUS_EN, 1); | ||
509 | |||
510 | return 0; | ||
511 | |||
512 | err_free_vbus_gpio: | ||
513 | gpio_free(GPIO9_USB_VBUS_EN); | ||
514 | err_free_usb_ldo: | ||
515 | regulator_put(em_x270_usb_ldo); | ||
516 | |||
517 | return err; | ||
518 | } | ||
519 | |||
474 | static int em_x270_ohci_init(struct device *dev) | 520 | static int em_x270_ohci_init(struct device *dev) |
475 | { | 521 | { |
522 | int err; | ||
523 | |||
524 | /* we don't want to entirely disable USB if the HUB init failed */ | ||
525 | err = em_x270_usb_hub_init(); | ||
526 | if (err) | ||
527 | pr_err("USB Hub initialization failed: %d\n", err); | ||
528 | |||
476 | /* enable port 2 transiever */ | 529 | /* enable port 2 transiever */ |
477 | UP2OCR = UP2OCR_HXS | UP2OCR_HXOE; | 530 | UP2OCR = UP2OCR_HXS | UP2OCR_HXOE; |
478 | 531 | ||
479 | return 0; | 532 | return 0; |
480 | } | 533 | } |
481 | 534 | ||
535 | static void em_x270_ohci_exit(struct device *dev) | ||
536 | { | ||
537 | gpio_free(usb_hub_reset); | ||
538 | gpio_free(GPIO9_USB_VBUS_EN); | ||
539 | |||
540 | if (!IS_ERR(em_x270_usb_ldo)) { | ||
541 | if (regulator_is_enabled(em_x270_usb_ldo)) | ||
542 | regulator_disable(em_x270_usb_ldo); | ||
543 | |||
544 | regulator_put(em_x270_usb_ldo); | ||
545 | } | ||
546 | } | ||
547 | |||
482 | static struct pxaohci_platform_data em_x270_ohci_platform_data = { | 548 | static struct pxaohci_platform_data em_x270_ohci_platform_data = { |
483 | .port_mode = PMM_PERPORT_MODE, | 549 | .port_mode = PMM_PERPORT_MODE, |
484 | .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW, | 550 | .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW, |
485 | .init = em_x270_ohci_init, | 551 | .init = em_x270_ohci_init, |
552 | .exit = em_x270_ohci_exit, | ||
486 | }; | 553 | }; |
487 | 554 | ||
488 | static void __init em_x270_init_ohci(void) | 555 | static void __init em_x270_init_ohci(void) |
@@ -1129,6 +1196,7 @@ static void __init em_x270_module_init(void) | |||
1129 | nand_rb = GPIO56_NAND_RB; | 1196 | nand_rb = GPIO56_NAND_RB; |
1130 | dm9000_flags = DM9000_PLATF_32BITONLY; | 1197 | dm9000_flags = DM9000_PLATF_32BITONLY; |
1131 | cam_reset = GPIO93_CAM_RESET; | 1198 | cam_reset = GPIO93_CAM_RESET; |
1199 | usb_hub_reset = GPIO16_USB_HUB_RESET; | ||
1132 | } | 1200 | } |
1133 | 1201 | ||
1134 | static void __init em_x270_exeda_init(void) | 1202 | static void __init em_x270_exeda_init(void) |
@@ -1140,6 +1208,7 @@ static void __init em_x270_exeda_init(void) | |||
1140 | nand_rb = GPIO20_NAND_RB; | 1208 | nand_rb = GPIO20_NAND_RB; |
1141 | dm9000_flags = DM9000_PLATF_16BITONLY; | 1209 | dm9000_flags = DM9000_PLATF_16BITONLY; |
1142 | cam_reset = GPIO130_CAM_RESET; | 1210 | cam_reset = GPIO130_CAM_RESET; |
1211 | usb_hub_reset = GPIO10_USB_HUB_RESET; | ||
1143 | } | 1212 | } |
1144 | 1213 | ||
1145 | static void __init em_x270_init(void) | 1214 | static void __init em_x270_init(void) |