diff options
Diffstat (limited to 'arch/arm/mach-omap2/board-omap3pandora.c')
-rw-r--r-- | arch/arm/mach-omap2/board-omap3pandora.c | 157 |
1 files changed, 131 insertions, 26 deletions
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index db06dc910ba7..55836fa35060 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c | |||
@@ -25,6 +25,9 @@ | |||
25 | #include <linux/spi/ads7846.h> | 25 | #include <linux/spi/ads7846.h> |
26 | #include <linux/regulator/machine.h> | 26 | #include <linux/regulator/machine.h> |
27 | #include <linux/i2c/twl.h> | 27 | #include <linux/i2c/twl.h> |
28 | #include <linux/spi/wl12xx.h> | ||
29 | #include <linux/mtd/partitions.h> | ||
30 | #include <linux/mtd/nand.h> | ||
28 | #include <linux/leds.h> | 31 | #include <linux/leds.h> |
29 | #include <linux/input.h> | 32 | #include <linux/input.h> |
30 | #include <linux/input/matrix_keypad.h> | 33 | #include <linux/input/matrix_keypad.h> |
@@ -41,15 +44,49 @@ | |||
41 | #include <plat/mcspi.h> | 44 | #include <plat/mcspi.h> |
42 | #include <plat/usb.h> | 45 | #include <plat/usb.h> |
43 | #include <plat/display.h> | 46 | #include <plat/display.h> |
47 | #include <plat/nand.h> | ||
44 | 48 | ||
45 | #include "mux.h" | 49 | #include "mux.h" |
46 | #include "sdram-micron-mt46h32m32lf-6.h" | 50 | #include "sdram-micron-mt46h32m32lf-6.h" |
47 | #include "hsmmc.h" | 51 | #include "hsmmc.h" |
48 | 52 | ||
53 | #define PANDORA_WIFI_IRQ_GPIO 21 | ||
54 | #define PANDORA_WIFI_NRESET_GPIO 23 | ||
49 | #define OMAP3_PANDORA_TS_GPIO 94 | 55 | #define OMAP3_PANDORA_TS_GPIO 94 |
50 | 56 | ||
51 | /* hardware debounce: (value + 1) * 31us */ | 57 | #define NAND_BLOCK_SIZE SZ_128K |
52 | #define GPIO_DEBOUNCE_TIME 127 | 58 | |
59 | static struct mtd_partition omap3pandora_nand_partitions[] = { | ||
60 | { | ||
61 | .name = "xloader", | ||
62 | .offset = 0, | ||
63 | .size = 4 * NAND_BLOCK_SIZE, | ||
64 | .mask_flags = MTD_WRITEABLE | ||
65 | }, { | ||
66 | .name = "uboot", | ||
67 | .offset = MTDPART_OFS_APPEND, | ||
68 | .size = 15 * NAND_BLOCK_SIZE, | ||
69 | }, { | ||
70 | .name = "uboot-env", | ||
71 | .offset = MTDPART_OFS_APPEND, | ||
72 | .size = 1 * NAND_BLOCK_SIZE, | ||
73 | }, { | ||
74 | .name = "boot", | ||
75 | .offset = MTDPART_OFS_APPEND, | ||
76 | .size = 80 * NAND_BLOCK_SIZE, | ||
77 | }, { | ||
78 | .name = "rootfs", | ||
79 | .offset = MTDPART_OFS_APPEND, | ||
80 | .size = MTDPART_SIZ_FULL, | ||
81 | }, | ||
82 | }; | ||
83 | |||
84 | static struct omap_nand_platform_data pandora_nand_data = { | ||
85 | .cs = 0, | ||
86 | .devsize = 1, /* '0' for 8-bit, '1' for 16-bit device */ | ||
87 | .parts = omap3pandora_nand_partitions, | ||
88 | .nr_parts = ARRAY_SIZE(omap3pandora_nand_partitions), | ||
89 | }; | ||
53 | 90 | ||
54 | static struct gpio_led pandora_gpio_leds[] = { | 91 | static struct gpio_led pandora_gpio_leds[] = { |
55 | { | 92 | { |
@@ -88,6 +125,7 @@ static struct platform_device pandora_leds_gpio = { | |||
88 | .type = ev_type, \ | 125 | .type = ev_type, \ |
89 | .code = ev_code, \ | 126 | .code = ev_code, \ |
90 | .active_low = act_low, \ | 127 | .active_low = act_low, \ |
128 | .debounce_interval = 4, \ | ||
91 | .desc = "btn " descr, \ | 129 | .desc = "btn " descr, \ |
92 | } | 130 | } |
93 | 131 | ||
@@ -99,14 +137,14 @@ static struct gpio_keys_button pandora_gpio_keys[] = { | |||
99 | GPIO_BUTTON_LOW(103, KEY_DOWN, "down"), | 137 | GPIO_BUTTON_LOW(103, KEY_DOWN, "down"), |
100 | GPIO_BUTTON_LOW(96, KEY_LEFT, "left"), | 138 | GPIO_BUTTON_LOW(96, KEY_LEFT, "left"), |
101 | GPIO_BUTTON_LOW(98, KEY_RIGHT, "right"), | 139 | GPIO_BUTTON_LOW(98, KEY_RIGHT, "right"), |
102 | GPIO_BUTTON_LOW(109, KEY_KP1, "game 1"), | 140 | GPIO_BUTTON_LOW(109, KEY_PAGEUP, "game 1"), |
103 | GPIO_BUTTON_LOW(111, KEY_KP2, "game 2"), | 141 | GPIO_BUTTON_LOW(111, KEY_END, "game 2"), |
104 | GPIO_BUTTON_LOW(106, KEY_KP3, "game 3"), | 142 | GPIO_BUTTON_LOW(106, KEY_PAGEDOWN, "game 3"), |
105 | GPIO_BUTTON_LOW(101, KEY_KP4, "game 4"), | 143 | GPIO_BUTTON_LOW(101, KEY_HOME, "game 4"), |
106 | GPIO_BUTTON_LOW(102, BTN_TL, "l"), | 144 | GPIO_BUTTON_LOW(102, KEY_RIGHTSHIFT, "l"), |
107 | GPIO_BUTTON_LOW(97, BTN_TL2, "l2"), | 145 | GPIO_BUTTON_LOW(97, KEY_KPPLUS, "l2"), |
108 | GPIO_BUTTON_LOW(105, BTN_TR, "r"), | 146 | GPIO_BUTTON_LOW(105, KEY_RIGHTCTRL, "r"), |
109 | GPIO_BUTTON_LOW(107, BTN_TR2, "r2"), | 147 | GPIO_BUTTON_LOW(107, KEY_KPMINUS, "r2"), |
110 | GPIO_BUTTON_LOW(104, KEY_LEFTCTRL, "ctrl"), | 148 | GPIO_BUTTON_LOW(104, KEY_LEFTCTRL, "ctrl"), |
111 | GPIO_BUTTON_LOW(99, KEY_MENU, "menu"), | 149 | GPIO_BUTTON_LOW(99, KEY_MENU, "menu"), |
112 | GPIO_BUTTON_LOW(176, KEY_COFFEE, "hold"), | 150 | GPIO_BUTTON_LOW(176, KEY_COFFEE, "hold"), |
@@ -127,14 +165,7 @@ static struct platform_device pandora_keys_gpio = { | |||
127 | }, | 165 | }, |
128 | }; | 166 | }; |
129 | 167 | ||
130 | static void __init pandora_keys_gpio_init(void) | 168 | static const uint32_t board_keymap[] = { |
131 | { | ||
132 | /* set debounce time for GPIO banks 4 and 6 */ | ||
133 | gpio_set_debounce(32 * 3, GPIO_DEBOUNCE_TIME); | ||
134 | gpio_set_debounce(32 * 5, GPIO_DEBOUNCE_TIME); | ||
135 | } | ||
136 | |||
137 | static int board_keymap[] = { | ||
138 | /* row, col, code */ | 169 | /* row, col, code */ |
139 | KEY(0, 0, KEY_9), | 170 | KEY(0, 0, KEY_9), |
140 | KEY(0, 1, KEY_8), | 171 | KEY(0, 1, KEY_8), |
@@ -255,12 +286,33 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = { | |||
255 | static int omap3pandora_twl_gpio_setup(struct device *dev, | 286 | static int omap3pandora_twl_gpio_setup(struct device *dev, |
256 | unsigned gpio, unsigned ngpio) | 287 | unsigned gpio, unsigned ngpio) |
257 | { | 288 | { |
289 | int ret, gpio_32khz; | ||
290 | |||
258 | /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */ | 291 | /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */ |
259 | omap3pandora_mmc[0].gpio_cd = gpio + 0; | 292 | omap3pandora_mmc[0].gpio_cd = gpio + 0; |
260 | omap3pandora_mmc[1].gpio_cd = gpio + 1; | 293 | omap3pandora_mmc[1].gpio_cd = gpio + 1; |
261 | omap2_hsmmc_init(omap3pandora_mmc); | 294 | omap2_hsmmc_init(omap3pandora_mmc); |
262 | 295 | ||
296 | /* gpio + 13 drives 32kHz buffer for wifi module */ | ||
297 | gpio_32khz = gpio + 13; | ||
298 | ret = gpio_request(gpio_32khz, "wifi 32kHz"); | ||
299 | if (ret < 0) { | ||
300 | pr_err("Cannot get GPIO line %d, ret=%d\n", gpio_32khz, ret); | ||
301 | goto fail; | ||
302 | } | ||
303 | |||
304 | ret = gpio_direction_output(gpio_32khz, 1); | ||
305 | if (ret < 0) { | ||
306 | pr_err("Cannot set GPIO line %d, ret=%d\n", gpio_32khz, ret); | ||
307 | goto fail_direction; | ||
308 | } | ||
309 | |||
263 | return 0; | 310 | return 0; |
311 | |||
312 | fail_direction: | ||
313 | gpio_free(gpio_32khz); | ||
314 | fail: | ||
315 | return -ENODEV; | ||
264 | } | 316 | } |
265 | 317 | ||
266 | static struct twl4030_gpio_platform_data omap3pandora_gpio_data = { | 318 | static struct twl4030_gpio_platform_data omap3pandora_gpio_data = { |
@@ -539,10 +591,67 @@ static void __init omap3pandora_init_irq(void) | |||
539 | omap_gpio_init(); | 591 | omap_gpio_init(); |
540 | } | 592 | } |
541 | 593 | ||
594 | static void pandora_wl1251_set_power(bool enable) | ||
595 | { | ||
596 | /* | ||
597 | * Keep power always on until wl1251_sdio driver learns to re-init | ||
598 | * the chip after powering it down and back up. | ||
599 | */ | ||
600 | } | ||
601 | |||
602 | static struct wl12xx_platform_data pandora_wl1251_pdata = { | ||
603 | .set_power = pandora_wl1251_set_power, | ||
604 | .use_eeprom = true, | ||
605 | }; | ||
606 | |||
607 | static struct platform_device pandora_wl1251_data = { | ||
608 | .name = "wl1251_data", | ||
609 | .id = -1, | ||
610 | .dev = { | ||
611 | .platform_data = &pandora_wl1251_pdata, | ||
612 | }, | ||
613 | }; | ||
614 | |||
615 | static void pandora_wl1251_init(void) | ||
616 | { | ||
617 | int ret; | ||
618 | |||
619 | ret = gpio_request(PANDORA_WIFI_IRQ_GPIO, "wl1251 irq"); | ||
620 | if (ret < 0) | ||
621 | goto fail; | ||
622 | |||
623 | ret = gpio_direction_input(PANDORA_WIFI_IRQ_GPIO); | ||
624 | if (ret < 0) | ||
625 | goto fail_irq; | ||
626 | |||
627 | pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO); | ||
628 | if (pandora_wl1251_pdata.irq < 0) | ||
629 | goto fail_irq; | ||
630 | |||
631 | ret = gpio_request(PANDORA_WIFI_NRESET_GPIO, "wl1251 nreset"); | ||
632 | if (ret < 0) | ||
633 | goto fail_irq; | ||
634 | |||
635 | /* start powered so that it probes with MMC subsystem */ | ||
636 | ret = gpio_direction_output(PANDORA_WIFI_NRESET_GPIO, 1); | ||
637 | if (ret < 0) | ||
638 | goto fail_nreset; | ||
639 | |||
640 | return; | ||
641 | |||
642 | fail_nreset: | ||
643 | gpio_free(PANDORA_WIFI_NRESET_GPIO); | ||
644 | fail_irq: | ||
645 | gpio_free(PANDORA_WIFI_IRQ_GPIO); | ||
646 | fail: | ||
647 | printk(KERN_ERR "wl1251 board initialisation failed\n"); | ||
648 | } | ||
649 | |||
542 | static struct platform_device *omap3pandora_devices[] __initdata = { | 650 | static struct platform_device *omap3pandora_devices[] __initdata = { |
543 | &pandora_leds_gpio, | 651 | &pandora_leds_gpio, |
544 | &pandora_keys_gpio, | 652 | &pandora_keys_gpio, |
545 | &pandora_dss_device, | 653 | &pandora_dss_device, |
654 | &pandora_wl1251_data, | ||
546 | }; | 655 | }; |
547 | 656 | ||
548 | static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { | 657 | static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { |
@@ -575,6 +684,7 @@ static void __init omap3pandora_init(void) | |||
575 | { | 684 | { |
576 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); | 685 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); |
577 | omap3pandora_i2c_init(); | 686 | omap3pandora_i2c_init(); |
687 | pandora_wl1251_init(); | ||
578 | platform_add_devices(omap3pandora_devices, | 688 | platform_add_devices(omap3pandora_devices, |
579 | ARRAY_SIZE(omap3pandora_devices)); | 689 | ARRAY_SIZE(omap3pandora_devices)); |
580 | omap_serial_init(); | 690 | omap_serial_init(); |
@@ -582,25 +692,20 @@ static void __init omap3pandora_init(void) | |||
582 | ARRAY_SIZE(omap3pandora_spi_board_info)); | 692 | ARRAY_SIZE(omap3pandora_spi_board_info)); |
583 | omap3pandora_ads7846_init(); | 693 | omap3pandora_ads7846_init(); |
584 | usb_ehci_init(&ehci_pdata); | 694 | usb_ehci_init(&ehci_pdata); |
585 | pandora_keys_gpio_init(); | ||
586 | usb_musb_init(&musb_board_data); | 695 | usb_musb_init(&musb_board_data); |
696 | gpmc_nand_init(&pandora_nand_data); | ||
587 | 697 | ||
588 | /* Ensure SDRC pins are mux'd for self-refresh */ | 698 | /* Ensure SDRC pins are mux'd for self-refresh */ |
589 | omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); | 699 | omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); |
590 | omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); | 700 | omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); |
591 | } | 701 | } |
592 | 702 | ||
593 | static void __init omap3pandora_map_io(void) | ||
594 | { | ||
595 | omap2_set_globals_343x(); | ||
596 | omap34xx_map_common_io(); | ||
597 | } | ||
598 | |||
599 | MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console") | 703 | MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console") |
600 | .phys_io = 0x48000000, | 704 | .phys_io = 0x48000000, |
601 | .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc, | 705 | .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc, |
602 | .boot_params = 0x80000100, | 706 | .boot_params = 0x80000100, |
603 | .map_io = omap3pandora_map_io, | 707 | .map_io = omap3_map_io, |
708 | .reserve = omap_reserve, | ||
604 | .init_irq = omap3pandora_init_irq, | 709 | .init_irq = omap3pandora_init_irq, |
605 | .init_machine = omap3pandora_init, | 710 | .init_machine = omap3pandora_init, |
606 | .timer = &omap_timer, | 711 | .timer = &omap_timer, |