diff options
Diffstat (limited to 'arch/arm/mach-omap2/board-igep0030.c')
-rw-r--r-- | arch/arm/mach-omap2/board-igep0030.c | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/board-igep0030.c b/arch/arm/mach-omap2/board-igep0030.c new file mode 100644 index 000000000000..22b0b253e16b --- /dev/null +++ b/arch/arm/mach-omap2/board-igep0030.c | |||
@@ -0,0 +1,400 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 - ISEE 2007 SL | ||
3 | * | ||
4 | * Modified from mach-omap2/board-generic.c | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/clk.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | |||
21 | #include <linux/regulator/machine.h> | ||
22 | #include <linux/i2c/twl.h> | ||
23 | #include <linux/mmc/host.h> | ||
24 | |||
25 | #include <asm/mach-types.h> | ||
26 | #include <asm/mach/arch.h> | ||
27 | |||
28 | #include <plat/board.h> | ||
29 | #include <plat/common.h> | ||
30 | #include <plat/gpmc.h> | ||
31 | #include <plat/usb.h> | ||
32 | #include <plat/onenand.h> | ||
33 | |||
34 | #include "mux.h" | ||
35 | #include "hsmmc.h" | ||
36 | #include "sdram-numonyx-m65kxxxxam.h" | ||
37 | |||
38 | #define IGEP3_GPIO_LED0_GREEN 54 | ||
39 | #define IGEP3_GPIO_LED0_RED 53 | ||
40 | #define IGEP3_GPIO_LED1_RED 16 | ||
41 | |||
42 | #define IGEP3_GPIO_WIFI_NPD 138 | ||
43 | #define IGEP3_GPIO_WIFI_NRESET 139 | ||
44 | #define IGEP3_GPIO_BT_NRESET 137 | ||
45 | |||
46 | #define IGEP3_GPIO_USBH_NRESET 115 | ||
47 | |||
48 | |||
49 | #if defined(CONFIG_MTD_ONENAND_OMAP2) || \ | ||
50 | defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) | ||
51 | |||
52 | #define ONENAND_MAP 0x20000000 | ||
53 | |||
54 | /* | ||
55 | * x2 Flash built-in COMBO POP MEMORY | ||
56 | * Since the device is equipped with two DataRAMs, and two-plane NAND | ||
57 | * Flash memory array, these two component enables simultaneous program | ||
58 | * of 4KiB. Plane1 has only even blocks such as block0, block2, block4 | ||
59 | * while Plane2 has only odd blocks such as block1, block3, block5. | ||
60 | * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048) | ||
61 | */ | ||
62 | |||
63 | static struct mtd_partition igep3_onenand_partitions[] = { | ||
64 | { | ||
65 | .name = "X-Loader", | ||
66 | .offset = 0, | ||
67 | .size = 2 * (64*(2*2048)) | ||
68 | }, | ||
69 | { | ||
70 | .name = "U-Boot", | ||
71 | .offset = MTDPART_OFS_APPEND, | ||
72 | .size = 6 * (64*(2*2048)), | ||
73 | }, | ||
74 | { | ||
75 | .name = "Environment", | ||
76 | .offset = MTDPART_OFS_APPEND, | ||
77 | .size = 2 * (64*(2*2048)), | ||
78 | }, | ||
79 | { | ||
80 | .name = "Kernel", | ||
81 | .offset = MTDPART_OFS_APPEND, | ||
82 | .size = 12 * (64*(2*2048)), | ||
83 | }, | ||
84 | { | ||
85 | .name = "File System", | ||
86 | .offset = MTDPART_OFS_APPEND, | ||
87 | .size = MTDPART_SIZ_FULL, | ||
88 | }, | ||
89 | }; | ||
90 | |||
91 | static struct omap_onenand_platform_data igep3_onenand_pdata = { | ||
92 | .parts = igep3_onenand_partitions, | ||
93 | .nr_parts = ARRAY_SIZE(igep3_onenand_partitions), | ||
94 | .onenand_setup = NULL, | ||
95 | .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */ | ||
96 | }; | ||
97 | |||
98 | static struct platform_device igep3_onenand_device = { | ||
99 | .name = "omap2-onenand", | ||
100 | .id = -1, | ||
101 | .dev = { | ||
102 | .platform_data = &igep3_onenand_pdata, | ||
103 | }, | ||
104 | }; | ||
105 | |||
106 | void __init igep3_flash_init(void) | ||
107 | { | ||
108 | u8 cs = 0; | ||
109 | u8 onenandcs = GPMC_CS_NUM + 1; | ||
110 | |||
111 | for (cs = 0; cs < GPMC_CS_NUM; cs++) { | ||
112 | u32 ret; | ||
113 | ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); | ||
114 | |||
115 | /* Check if NAND/oneNAND is configured */ | ||
116 | if ((ret & 0xC00) == 0x800) | ||
117 | /* NAND found */ | ||
118 | pr_err("IGEP3: Unsupported NAND found\n"); | ||
119 | else { | ||
120 | ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); | ||
121 | |||
122 | if ((ret & 0x3F) == (ONENAND_MAP >> 24)) | ||
123 | /* OneNAND found */ | ||
124 | onenandcs = cs; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | if (onenandcs > GPMC_CS_NUM) { | ||
129 | pr_err("IGEP3: Unable to find configuration in GPMC\n"); | ||
130 | return; | ||
131 | } | ||
132 | |||
133 | igep3_onenand_pdata.cs = onenandcs; | ||
134 | |||
135 | if (platform_device_register(&igep3_onenand_device) < 0) | ||
136 | pr_err("IGEP3: Unable to register OneNAND device\n"); | ||
137 | } | ||
138 | |||
139 | #else | ||
140 | void __init igep3_flash_init(void) {} | ||
141 | #endif | ||
142 | |||
143 | static struct regulator_consumer_supply igep3_vmmc1_supply = { | ||
144 | .supply = "vmmc", | ||
145 | }; | ||
146 | |||
147 | /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ | ||
148 | static struct regulator_init_data igep3_vmmc1 = { | ||
149 | .constraints = { | ||
150 | .min_uV = 1850000, | ||
151 | .max_uV = 3150000, | ||
152 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
153 | | REGULATOR_MODE_STANDBY, | ||
154 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
155 | | REGULATOR_CHANGE_MODE | ||
156 | | REGULATOR_CHANGE_STATUS, | ||
157 | }, | ||
158 | .num_consumer_supplies = 1, | ||
159 | .consumer_supplies = &igep3_vmmc1_supply, | ||
160 | }; | ||
161 | |||
162 | static struct omap2_hsmmc_info mmc[] = { | ||
163 | [0] = { | ||
164 | .mmc = 1, | ||
165 | .caps = MMC_CAP_4_BIT_DATA, | ||
166 | .gpio_cd = -EINVAL, | ||
167 | .gpio_wp = -EINVAL, | ||
168 | }, | ||
169 | #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE) | ||
170 | [1] = { | ||
171 | .mmc = 2, | ||
172 | .caps = MMC_CAP_4_BIT_DATA, | ||
173 | .gpio_cd = -EINVAL, | ||
174 | .gpio_wp = -EINVAL, | ||
175 | }, | ||
176 | #endif | ||
177 | {} /* Terminator */ | ||
178 | }; | ||
179 | |||
180 | #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) | ||
181 | #include <linux/leds.h> | ||
182 | |||
183 | static struct gpio_led igep3_gpio_leds[] = { | ||
184 | [0] = { | ||
185 | .name = "gpio-led:red:d0", | ||
186 | .gpio = IGEP3_GPIO_LED0_RED, | ||
187 | .default_trigger = "default-off" | ||
188 | }, | ||
189 | [1] = { | ||
190 | .name = "gpio-led:green:d0", | ||
191 | .gpio = IGEP3_GPIO_LED0_GREEN, | ||
192 | .default_trigger = "default-off", | ||
193 | }, | ||
194 | [2] = { | ||
195 | .name = "gpio-led:red:d1", | ||
196 | .gpio = IGEP3_GPIO_LED1_RED, | ||
197 | .default_trigger = "default-off", | ||
198 | }, | ||
199 | [3] = { | ||
200 | .name = "gpio-led:green:d1", | ||
201 | .default_trigger = "heartbeat", | ||
202 | .gpio = -EINVAL, /* gets replaced */ | ||
203 | }, | ||
204 | }; | ||
205 | |||
206 | static struct gpio_led_platform_data igep3_led_pdata = { | ||
207 | .leds = igep3_gpio_leds, | ||
208 | .num_leds = ARRAY_SIZE(igep3_gpio_leds), | ||
209 | }; | ||
210 | |||
211 | static struct platform_device igep3_led_device = { | ||
212 | .name = "leds-gpio", | ||
213 | .id = -1, | ||
214 | .dev = { | ||
215 | .platform_data = &igep3_led_pdata, | ||
216 | }, | ||
217 | }; | ||
218 | |||
219 | static void __init igep3_leds_init(void) | ||
220 | { | ||
221 | platform_device_register(&igep3_led_device); | ||
222 | } | ||
223 | |||
224 | #else | ||
225 | static inline void igep3_leds_init(void) | ||
226 | { | ||
227 | if ((gpio_request(IGEP3_GPIO_LED0_RED, "gpio-led:red:d0") == 0) && | ||
228 | (gpio_direction_output(IGEP3_GPIO_LED0_RED, 1) == 0)) { | ||
229 | gpio_export(IGEP3_GPIO_LED0_RED, 0); | ||
230 | gpio_set_value(IGEP3_GPIO_LED0_RED, 1); | ||
231 | } else | ||
232 | pr_warning("IGEP3: Could not obtain gpio GPIO_LED0_RED\n"); | ||
233 | |||
234 | if ((gpio_request(IGEP3_GPIO_LED0_GREEN, "gpio-led:green:d0") == 0) && | ||
235 | (gpio_direction_output(IGEP3_GPIO_LED0_GREEN, 1) == 0)) { | ||
236 | gpio_export(IGEP3_GPIO_LED0_GREEN, 0); | ||
237 | gpio_set_value(IGEP3_GPIO_LED0_GREEN, 1); | ||
238 | } else | ||
239 | pr_warning("IGEP3: Could not obtain gpio GPIO_LED0_GREEN\n"); | ||
240 | |||
241 | if ((gpio_request(IGEP3_GPIO_LED1_RED, "gpio-led:red:d1") == 0) && | ||
242 | (gpio_direction_output(IGEP3_GPIO_LED1_RED, 1) == 0)) { | ||
243 | gpio_export(IGEP3_GPIO_LED1_RED, 0); | ||
244 | gpio_set_value(IGEP3_GPIO_LED1_RED, 1); | ||
245 | } else | ||
246 | pr_warning("IGEP3: Could not obtain gpio GPIO_LED1_RED\n"); | ||
247 | } | ||
248 | #endif | ||
249 | |||
250 | static int igep3_twl4030_gpio_setup(struct device *dev, | ||
251 | unsigned gpio, unsigned ngpio) | ||
252 | { | ||
253 | /* gpio + 0 is "mmc0_cd" (input/IRQ) */ | ||
254 | mmc[0].gpio_cd = gpio + 0; | ||
255 | omap2_hsmmc_init(mmc); | ||
256 | |||
257 | /* | ||
258 | * link regulators to MMC adapters ... we "know" the | ||
259 | * regulators will be set up only *after* we return. | ||
260 | */ | ||
261 | igep3_vmmc1_supply.dev = mmc[0].dev; | ||
262 | |||
263 | /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ | ||
264 | #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE) | ||
265 | if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0) | ||
266 | && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0)) { | ||
267 | gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0); | ||
268 | gpio_set_value(gpio + TWL4030_GPIO_MAX + 1, 0); | ||
269 | } else | ||
270 | pr_warning("IGEP3: Could not obtain gpio GPIO_LED1_GREEN\n"); | ||
271 | #else | ||
272 | igep3_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1; | ||
273 | #endif | ||
274 | |||
275 | return 0; | ||
276 | }; | ||
277 | |||
278 | static struct twl4030_gpio_platform_data igep3_twl4030_gpio_pdata = { | ||
279 | .gpio_base = OMAP_MAX_GPIO_LINES, | ||
280 | .irq_base = TWL4030_GPIO_IRQ_BASE, | ||
281 | .irq_end = TWL4030_GPIO_IRQ_END, | ||
282 | .use_leds = true, | ||
283 | .setup = igep3_twl4030_gpio_setup, | ||
284 | }; | ||
285 | |||
286 | static struct twl4030_usb_data igep3_twl4030_usb_data = { | ||
287 | .usb_mode = T2_USB_MODE_ULPI, | ||
288 | }; | ||
289 | |||
290 | static void __init igep3_init_irq(void) | ||
291 | { | ||
292 | omap2_init_common_hw(m65kxxxxam_sdrc_params, m65kxxxxam_sdrc_params); | ||
293 | omap_init_irq(); | ||
294 | omap_gpio_init(); | ||
295 | } | ||
296 | |||
297 | static struct twl4030_platform_data igep3_twl4030_pdata = { | ||
298 | .irq_base = TWL4030_IRQ_BASE, | ||
299 | .irq_end = TWL4030_IRQ_END, | ||
300 | |||
301 | /* platform_data for children goes here */ | ||
302 | .usb = &igep3_twl4030_usb_data, | ||
303 | .gpio = &igep3_twl4030_gpio_pdata, | ||
304 | .vmmc1 = &igep3_vmmc1, | ||
305 | }; | ||
306 | |||
307 | static struct i2c_board_info __initdata igep3_i2c_boardinfo[] = { | ||
308 | { | ||
309 | I2C_BOARD_INFO("twl4030", 0x48), | ||
310 | .flags = I2C_CLIENT_WAKE, | ||
311 | .irq = INT_34XX_SYS_NIRQ, | ||
312 | .platform_data = &igep3_twl4030_pdata, | ||
313 | }, | ||
314 | }; | ||
315 | |||
316 | static int __init igep3_i2c_init(void) | ||
317 | { | ||
318 | omap_register_i2c_bus(1, 2600, igep3_i2c_boardinfo, | ||
319 | ARRAY_SIZE(igep3_i2c_boardinfo)); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static struct omap_musb_board_data musb_board_data = { | ||
325 | .interface_type = MUSB_INTERFACE_ULPI, | ||
326 | .mode = MUSB_OTG, | ||
327 | .power = 100, | ||
328 | }; | ||
329 | |||
330 | #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE) | ||
331 | |||
332 | static void __init igep3_wifi_bt_init(void) | ||
333 | { | ||
334 | /* Configure MUX values for W-LAN + Bluetooth GPIO's */ | ||
335 | omap_mux_init_gpio(IGEP3_GPIO_WIFI_NPD, OMAP_PIN_OUTPUT); | ||
336 | omap_mux_init_gpio(IGEP3_GPIO_WIFI_NRESET, OMAP_PIN_OUTPUT); | ||
337 | omap_mux_init_gpio(IGEP3_GPIO_BT_NRESET, OMAP_PIN_OUTPUT); | ||
338 | |||
339 | /* Set GPIO's for W-LAN + Bluetooth combo module */ | ||
340 | if ((gpio_request(IGEP3_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) && | ||
341 | (gpio_direction_output(IGEP3_GPIO_WIFI_NPD, 1) == 0)) { | ||
342 | gpio_export(IGEP3_GPIO_WIFI_NPD, 0); | ||
343 | } else | ||
344 | pr_warning("IGEP3: Could not obtain gpio GPIO_WIFI_NPD\n"); | ||
345 | |||
346 | if ((gpio_request(IGEP3_GPIO_WIFI_NRESET, "GPIO_WIFI_NRESET") == 0) && | ||
347 | (gpio_direction_output(IGEP3_GPIO_WIFI_NRESET, 1) == 0)) { | ||
348 | gpio_export(IGEP3_GPIO_WIFI_NRESET, 0); | ||
349 | gpio_set_value(IGEP3_GPIO_WIFI_NRESET, 0); | ||
350 | udelay(10); | ||
351 | gpio_set_value(IGEP3_GPIO_WIFI_NRESET, 1); | ||
352 | } else | ||
353 | pr_warning("IGEP3: Could not obtain gpio GPIO_WIFI_NRESET\n"); | ||
354 | |||
355 | if ((gpio_request(IGEP3_GPIO_BT_NRESET, "GPIO_BT_NRESET") == 0) && | ||
356 | (gpio_direction_output(IGEP3_GPIO_BT_NRESET, 1) == 0)) { | ||
357 | gpio_export(IGEP3_GPIO_BT_NRESET, 0); | ||
358 | } else | ||
359 | pr_warning("IGEP3: Could not obtain gpio GPIO_BT_NRESET\n"); | ||
360 | } | ||
361 | #else | ||
362 | void __init igep3_wifi_bt_init(void) {} | ||
363 | #endif | ||
364 | |||
365 | #ifdef CONFIG_OMAP_MUX | ||
366 | static struct omap_board_mux board_mux[] __initdata = { | ||
367 | { .reg_offset = OMAP_MUX_TERMINATOR }, | ||
368 | }; | ||
369 | #else | ||
370 | #define board_mux NULL | ||
371 | #endif | ||
372 | |||
373 | static void __init igep3_init(void) | ||
374 | { | ||
375 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); | ||
376 | |||
377 | /* Register I2C busses and drivers */ | ||
378 | igep3_i2c_init(); | ||
379 | |||
380 | omap_serial_init(); | ||
381 | usb_musb_init(&musb_board_data); | ||
382 | |||
383 | igep3_flash_init(); | ||
384 | igep3_leds_init(); | ||
385 | |||
386 | /* | ||
387 | * WLAN-BT combo module from MuRata wich has a Marvell WLAN | ||
388 | * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface. | ||
389 | */ | ||
390 | igep3_wifi_bt_init(); | ||
391 | |||
392 | } | ||
393 | |||
394 | MACHINE_START(IGEP0030, "IGEP OMAP3 module") | ||
395 | .boot_params = 0x80000100, | ||
396 | .map_io = omap3_map_io, | ||
397 | .init_irq = igep3_init_irq, | ||
398 | .init_machine = igep3_init, | ||
399 | .timer = &omap_timer, | ||
400 | MACHINE_END | ||