mach-mx27_3ds.c 8.0 KB

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