board-igep0030.c 10 KB

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