mach-mx27_3ds.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
  3. *
  4. * Author: Fabio Estevam <fabio.estevam@freescale.com>
  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 as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. /*
  17. * This machine is known as:
  18. * - i.MX27 3-Stack Development System
  19. * - i.MX27 Platform Development Kit (i.MX27 PDK)
  20. */
  21. #include <linux/platform_device.h>
  22. #include <linux/gpio.h>
  23. #include <linux/irq.h>
  24. #include <linux/usb/otg.h>
  25. #include <linux/usb/ulpi.h>
  26. #include <linux/delay.h>
  27. #include <linux/mfd/mc13783.h>
  28. #include <linux/spi/spi.h>
  29. #include <linux/regulator/machine.h>
  30. #include <asm/mach-types.h>
  31. #include <asm/mach/arch.h>
  32. #include <asm/mach/time.h>
  33. #include <mach/hardware.h>
  34. #include <mach/common.h>
  35. #include <mach/iomux-mx27.h>
  36. #include <mach/ulpi.h>
  37. #include <mach/irqs.h>
  38. #include <mach/3ds_debugboard.h>
  39. #include "devices-imx27.h"
  40. #define SD1_EN_GPIO IMX_GPIO_NR(2, 25)
  41. #define OTG_PHY_RESET_GPIO IMX_GPIO_NR(2, 23)
  42. #define SPI2_SS0 IMX_GPIO_NR(4, 21)
  43. #define EXPIO_PARENT_INT gpio_to_irq(IMX_GPIO_NR(3, 28))
  44. #define PMIC_INT IMX_GPIO_NR(3, 14)
  45. static const int mx27pdk_pins[] __initconst = {
  46. /* UART1 */
  47. PE12_PF_UART1_TXD,
  48. PE13_PF_UART1_RXD,
  49. PE14_PF_UART1_CTS,
  50. PE15_PF_UART1_RTS,
  51. /* FEC */
  52. PD0_AIN_FEC_TXD0,
  53. PD1_AIN_FEC_TXD1,
  54. PD2_AIN_FEC_TXD2,
  55. PD3_AIN_FEC_TXD3,
  56. PD4_AOUT_FEC_RX_ER,
  57. PD5_AOUT_FEC_RXD1,
  58. PD6_AOUT_FEC_RXD2,
  59. PD7_AOUT_FEC_RXD3,
  60. PD8_AF_FEC_MDIO,
  61. PD9_AIN_FEC_MDC,
  62. PD10_AOUT_FEC_CRS,
  63. PD11_AOUT_FEC_TX_CLK,
  64. PD12_AOUT_FEC_RXD0,
  65. PD13_AOUT_FEC_RX_DV,
  66. PD14_AOUT_FEC_RX_CLK,
  67. PD15_AOUT_FEC_COL,
  68. PD16_AIN_FEC_TX_ER,
  69. PF23_AIN_FEC_TX_EN,
  70. /* SDHC1 */
  71. PE18_PF_SD1_D0,
  72. PE19_PF_SD1_D1,
  73. PE20_PF_SD1_D2,
  74. PE21_PF_SD1_D3,
  75. PE22_PF_SD1_CMD,
  76. PE23_PF_SD1_CLK,
  77. SD1_EN_GPIO | GPIO_GPIO | GPIO_OUT,
  78. /* OTG */
  79. OTG_PHY_RESET_GPIO | GPIO_GPIO | GPIO_OUT,
  80. PC7_PF_USBOTG_DATA5,
  81. PC8_PF_USBOTG_DATA6,
  82. PC9_PF_USBOTG_DATA0,
  83. PC10_PF_USBOTG_DATA2,
  84. PC11_PF_USBOTG_DATA1,
  85. PC12_PF_USBOTG_DATA4,
  86. PC13_PF_USBOTG_DATA3,
  87. PE0_PF_USBOTG_NXT,
  88. PE1_PF_USBOTG_STP,
  89. PE2_PF_USBOTG_DIR,
  90. PE24_PF_USBOTG_CLK,
  91. PE25_PF_USBOTG_DATA7,
  92. /* CSPI2 */
  93. PD22_PF_CSPI2_SCLK,
  94. PD23_PF_CSPI2_MISO,
  95. PD24_PF_CSPI2_MOSI,
  96. SPI2_SS0 | GPIO_GPIO | GPIO_OUT,
  97. /* I2C1 */
  98. PD17_PF_I2C_DATA,
  99. PD18_PF_I2C_CLK,
  100. /* PMIC INT */
  101. PMIC_INT | GPIO_GPIO | GPIO_IN,
  102. };
  103. static const struct imxuart_platform_data uart_pdata __initconst = {
  104. .flags = IMXUART_HAVE_RTSCTS,
  105. };
  106. /*
  107. * Matrix keyboard
  108. */
  109. static const uint32_t mx27_3ds_keymap[] = {
  110. KEY(0, 0, KEY_UP),
  111. KEY(0, 1, KEY_DOWN),
  112. KEY(1, 0, KEY_RIGHT),
  113. KEY(1, 1, KEY_LEFT),
  114. KEY(1, 2, KEY_ENTER),
  115. KEY(2, 0, KEY_F6),
  116. KEY(2, 1, KEY_F8),
  117. KEY(2, 2, KEY_F9),
  118. KEY(2, 3, KEY_F10),
  119. };
  120. static const struct matrix_keymap_data mx27_3ds_keymap_data __initconst = {
  121. .keymap = mx27_3ds_keymap,
  122. .keymap_size = ARRAY_SIZE(mx27_3ds_keymap),
  123. };
  124. static int mx27_3ds_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
  125. void *data)
  126. {
  127. return request_irq(IRQ_GPIOB(26), detect_irq, IRQF_TRIGGER_FALLING |
  128. IRQF_TRIGGER_RISING, "sdhc1-card-detect", data);
  129. }
  130. static void mx27_3ds_sdhc1_exit(struct device *dev, void *data)
  131. {
  132. free_irq(IRQ_GPIOB(26), data);
  133. }
  134. static const struct imxmmc_platform_data sdhc1_pdata __initconst = {
  135. .init = mx27_3ds_sdhc1_init,
  136. .exit = mx27_3ds_sdhc1_exit,
  137. };
  138. static void mx27_3ds_sdhc1_enable_level_translator(void)
  139. {
  140. /* Turn on TXB0108 OE pin */
  141. gpio_request(SD1_EN_GPIO, "sd1_enable");
  142. gpio_direction_output(SD1_EN_GPIO, 1);
  143. }
  144. static int otg_phy_init(void)
  145. {
  146. gpio_request(OTG_PHY_RESET_GPIO, "usb-otg-reset");
  147. gpio_direction_output(OTG_PHY_RESET_GPIO, 0);
  148. mdelay(1);
  149. gpio_set_value(OTG_PHY_RESET_GPIO, 1);
  150. return 0;
  151. }
  152. static int mx27_3ds_otg_init(struct platform_device *pdev)
  153. {
  154. return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
  155. }
  156. static struct mxc_usbh_platform_data otg_pdata __initdata = {
  157. .init = mx27_3ds_otg_init,
  158. .portsc = MXC_EHCI_MODE_ULPI,
  159. };
  160. static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
  161. .operating_mode = FSL_USB2_DR_DEVICE,
  162. .phy_mode = FSL_USB2_PHY_ULPI,
  163. };
  164. static int otg_mode_host;
  165. static int __init mx27_3ds_otg_mode(char *options)
  166. {
  167. if (!strcmp(options, "host"))
  168. otg_mode_host = 1;
  169. else if (!strcmp(options, "device"))
  170. otg_mode_host = 0;
  171. else
  172. pr_info("otg_mode neither \"host\" nor \"device\". "
  173. "Defaulting to device\n");
  174. return 0;
  175. }
  176. __setup("otg_mode=", mx27_3ds_otg_mode);
  177. /* Regulators */
  178. static struct regulator_init_data gpo_init = {
  179. .constraints = {
  180. .boot_on = 1,
  181. .always_on = 1,
  182. }
  183. };
  184. static struct regulator_consumer_supply vmmc1_consumers[] = {
  185. REGULATOR_SUPPLY("lcd_2v8", NULL),
  186. };
  187. static struct regulator_init_data vmmc1_init = {
  188. .constraints = {
  189. .min_uV = 2800000,
  190. .max_uV = 2800000,
  191. .apply_uV = 1,
  192. .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
  193. REGULATOR_CHANGE_STATUS,
  194. },
  195. .num_consumer_supplies = ARRAY_SIZE(vmmc1_consumers),
  196. .consumer_supplies = vmmc1_consumers,
  197. };
  198. static struct regulator_consumer_supply vgen_consumers[] = {
  199. REGULATOR_SUPPLY("vdd_lcdio", NULL),
  200. };
  201. static struct regulator_init_data vgen_init = {
  202. .constraints = {
  203. .min_uV = 1800000,
  204. .max_uV = 1800000,
  205. .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
  206. },
  207. .num_consumer_supplies = ARRAY_SIZE(vgen_consumers),
  208. .consumer_supplies = vgen_consumers,
  209. };
  210. static struct mc13xxx_regulator_init_data mx27_3ds_regulators[] = {
  211. {
  212. .id = MC13783_REG_VMMC1,
  213. .init_data = &vmmc1_init,
  214. }, {
  215. .id = MC13783_REG_VGEN,
  216. .init_data = &vgen_init,
  217. }, {
  218. .id = MC13783_REG_GPO1, /* Turn on 1.8V */
  219. .init_data = &gpo_init,
  220. }, {
  221. .id = MC13783_REG_GPO3, /* Turn on 3.3V */
  222. .init_data = &gpo_init,
  223. },
  224. };
  225. /* MC13783 */
  226. static struct mc13xxx_platform_data mc13783_pdata = {
  227. .regulators = {
  228. .regulators = mx27_3ds_regulators,
  229. .num_regulators = ARRAY_SIZE(mx27_3ds_regulators),
  230. },
  231. .flags = MC13783_USE_REGULATOR,
  232. };
  233. /* SPI */
  234. static int spi2_internal_chipselect[] = {SPI2_SS0};
  235. static const struct spi_imx_master spi2_pdata __initconst = {
  236. .chipselect = spi2_internal_chipselect,
  237. .num_chipselect = ARRAY_SIZE(spi2_internal_chipselect),
  238. };
  239. static struct spi_board_info mx27_3ds_spi_devs[] __initdata = {
  240. {
  241. .modalias = "mc13783",
  242. .max_speed_hz = 1000000,
  243. .bus_num = 1,
  244. .chip_select = 0, /* SS0 */
  245. .platform_data = &mc13783_pdata,
  246. .irq = IRQ_GPIOC(14),
  247. .mode = SPI_CS_HIGH,
  248. },
  249. };
  250. static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = {
  251. .bitrate = 100000,
  252. };
  253. static void __init mx27pdk_init(void)
  254. {
  255. mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
  256. "mx27pdk");
  257. mx27_3ds_sdhc1_enable_level_translator();
  258. imx27_add_imx_uart0(&uart_pdata);
  259. imx27_add_fec(NULL);
  260. imx27_add_imx_keypad(&mx27_3ds_keymap_data);
  261. imx27_add_mxc_mmc(0, &sdhc1_pdata);
  262. imx27_add_imx2_wdt(NULL);
  263. otg_phy_init();
  264. if (otg_mode_host) {
  265. otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
  266. ULPI_OTG_DRVVBUS_EXT);
  267. if (otg_pdata.otg)
  268. imx27_add_mxc_ehci_otg(&otg_pdata);
  269. }
  270. if (!otg_mode_host)
  271. imx27_add_fsl_usb2_udc(&otg_device_pdata);
  272. imx27_add_spi_imx1(&spi2_pdata);
  273. spi_register_board_info(mx27_3ds_spi_devs,
  274. ARRAY_SIZE(mx27_3ds_spi_devs));
  275. if (mxc_expio_init(MX27_CS5_BASE_ADDR, EXPIO_PARENT_INT))
  276. pr_warn("Init of the debugboard failed, all devices on the debugboard are unusable.\n");
  277. imx27_add_imx_i2c(0, &mx27_3ds_i2c0_data);
  278. }
  279. static void __init mx27pdk_timer_init(void)
  280. {
  281. mx27_clocks_init(26000000);
  282. }
  283. static struct sys_timer mx27pdk_timer = {
  284. .init = mx27pdk_timer_init,
  285. };
  286. MACHINE_START(MX27_3DS, "Freescale MX27PDK")
  287. /* maintainer: Freescale Semiconductor, Inc. */
  288. .boot_params = MX27_PHYS_OFFSET + 0x100,
  289. .map_io = mx27_map_io,
  290. .init_early = imx27_init_early,
  291. .init_irq = mx27_init_irq,
  292. .timer = &mx27pdk_timer,
  293. .init_machine = mx27pdk_init,
  294. MACHINE_END