blob: cff920696e7962d9d10a8c094172b2f9f92be634 [file] [log] [blame]
Fabio Estevam1553a1e2008-11-12 15:38:39 +01001/*
2 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
Fabio Estevam1553a1e2008-11-12 15:38:39 +010013 */
14
Magnus Liljaa2ef4562010-05-14 17:08:29 +020015#include <linux/delay.h>
Fabio Estevam1553a1e2008-11-12 15:38:39 +010016#include <linux/types.h>
17#include <linux/init.h>
18#include <linux/clk.h>
19#include <linux/irq.h>
Magnus Lilja135cad32009-05-17 20:18:08 +020020#include <linux/gpio.h>
Magnus Lilja2b0c3672009-05-18 18:46:33 +020021#include <linux/platform_device.h>
Alberto Panizzoae7a3f12010-03-23 19:51:45 +010022#include <linux/mfd/mc13783.h>
23#include <linux/spi/spi.h>
24#include <linux/regulator/machine.h>
Fabio Estevam1c50e672010-12-21 16:38:21 -020025#include <linux/usb/otg.h>
26#include <linux/usb/ulpi.h>
Fabio Estevam1553a1e2008-11-12 15:38:39 +010027
28#include <mach/hardware.h>
29#include <asm/mach-types.h>
30#include <asm/mach/arch.h>
31#include <asm/mach/time.h>
32#include <asm/memory.h>
33#include <asm/mach/map.h>
34#include <mach/common.h>
Fabio Estevam1553a1e2008-11-12 15:38:39 +010035#include <mach/iomux-mx3.h>
Jason Wangc5d38f02010-06-24 21:11:29 +080036#include <mach/3ds_debugboard.h>
Fabio Estevam1c50e672010-12-21 16:38:21 -020037#include <mach/ulpi.h>
Alberto Panizzo0ce88b32011-03-07 11:45:07 +010038#include <mach/mmc.h>
Uwe Kleine-Königa2ceeef2010-06-16 12:23:11 +020039
40#include "devices-imx31.h"
Fabio Estevam1553a1e2008-11-12 15:38:39 +010041#include "devices.h"
42
Uwe Kleine-Königb396dc42010-03-08 16:57:19 +010043/* CPLD IRQ line for external uart, external ethernet etc */
44#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
45
Alberto Panizzo11a332adf2010-03-23 19:46:57 +010046static int mx31_3ds_pins[] = {
Magnus Lilja153fa1d2009-05-16 12:43:10 +020047 /* UART1 */
Valentin Longchamp63d976672009-01-28 15:13:53 +010048 MX31_PIN_CTS1__CTS1,
49 MX31_PIN_RTS1__RTS1,
50 MX31_PIN_TXD1__TXD1,
Magnus Lilja135cad32009-05-17 20:18:08 +020051 MX31_PIN_RXD1__RXD1,
52 IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
Alberto Panizzoa1ac4422010-03-23 19:50:28 +010053 /* SPI 1 */
54 MX31_PIN_CSPI2_SCLK__SCLK,
55 MX31_PIN_CSPI2_MOSI__MOSI,
56 MX31_PIN_CSPI2_MISO__MISO,
57 MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
58 MX31_PIN_CSPI2_SS0__SS0,
59 MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */
Alberto Panizzoae7a3f12010-03-23 19:51:45 +010060 /* MC13783 IRQ */
61 IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO),
Magnus Liljaa2ef4562010-05-14 17:08:29 +020062 /* USB OTG reset */
63 IOMUX_MODE(MX31_PIN_USB_PWR, IOMUX_CONFIG_GPIO),
64 /* USB OTG */
65 MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
66 MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
67 MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
68 MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
69 MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
70 MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
71 MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
72 MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
73 MX31_PIN_USBOTG_CLK__USBOTG_CLK,
74 MX31_PIN_USBOTG_DIR__USBOTG_DIR,
75 MX31_PIN_USBOTG_NXT__USBOTG_NXT,
76 MX31_PIN_USBOTG_STP__USBOTG_STP,
Alberto Panizzo54c1f632010-05-19 11:34:43 +020077 /*Keyboard*/
78 MX31_PIN_KEY_ROW0_KEY_ROW0,
79 MX31_PIN_KEY_ROW1_KEY_ROW1,
80 MX31_PIN_KEY_ROW2_KEY_ROW2,
81 MX31_PIN_KEY_COL0_KEY_COL0,
82 MX31_PIN_KEY_COL1_KEY_COL1,
83 MX31_PIN_KEY_COL2_KEY_COL2,
84 MX31_PIN_KEY_COL3_KEY_COL3,
Fabio Estevam0d95b752010-12-21 16:38:22 -020085 /* USB Host 2 */
86 IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
87 IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
88 IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
89 IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
90 IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
91 IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
92 IOMUX_MODE(MX31_PIN_PC_VS2, IOMUX_CONFIG_ALT1),
93 IOMUX_MODE(MX31_PIN_PC_BVD1, IOMUX_CONFIG_ALT1),
94 IOMUX_MODE(MX31_PIN_PC_BVD2, IOMUX_CONFIG_ALT1),
95 IOMUX_MODE(MX31_PIN_PC_RST, IOMUX_CONFIG_ALT1),
96 IOMUX_MODE(MX31_PIN_IOIS16, IOMUX_CONFIG_ALT1),
97 IOMUX_MODE(MX31_PIN_PC_RW_B, IOMUX_CONFIG_ALT1),
98 /* USB Host2 reset */
99 IOMUX_MODE(MX31_PIN_USB_BYP, IOMUX_CONFIG_GPIO),
Fabio Estevam3d943022011-03-01 16:59:45 -0300100 /* I2C1 */
101 MX31_PIN_I2C_CLK__I2C1_SCL,
102 MX31_PIN_I2C_DAT__I2C1_SDA,
Alberto Panizzo0ce88b32011-03-07 11:45:07 +0100103 /* SDHC1 */
104 MX31_PIN_SD1_DATA3__SD1_DATA3,
105 MX31_PIN_SD1_DATA2__SD1_DATA2,
106 MX31_PIN_SD1_DATA1__SD1_DATA1,
107 MX31_PIN_SD1_DATA0__SD1_DATA0,
108 MX31_PIN_SD1_CLK__SD1_CLK,
109 MX31_PIN_SD1_CMD__SD1_CMD,
110 MX31_PIN_GPIO3_1__GPIO3_1, /* Card detect */
111 MX31_PIN_GPIO3_0__GPIO3_0, /* OE */
112};
113
114/*
115 * Support for SD card slot in personality board
116 */
117#define MX31_3DS_GPIO_SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)
118#define MX31_3DS_GPIO_SDHC1_BE IOMUX_TO_GPIO(MX31_PIN_GPIO3_0)
119
120static struct gpio mx31_3ds_sdhc1_gpios[] = {
121 { MX31_3DS_GPIO_SDHC1_CD, GPIOF_IN, "sdhc1-card-detect" },
122 { MX31_3DS_GPIO_SDHC1_BE, GPIOF_OUT_INIT_LOW, "sdhc1-bus-en" },
123};
124
125static int mx31_3ds_sdhc1_init(struct device *dev,
126 irq_handler_t detect_irq,
127 void *data)
128{
129 int ret;
130
131 ret = gpio_request_array(mx31_3ds_sdhc1_gpios,
132 ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
133 if (ret) {
134 pr_warning("Unable to request the SD/MMC GPIOs.\n");
135 return ret;
136 }
137
138 ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
139 detect_irq, IRQF_DISABLED |
140 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
141 "sdhc1-detect", data);
142 if (ret) {
143 pr_warning("Unable to request the SD/MMC card-detect IRQ.\n");
144 goto gpio_free;
145 }
146
147 return 0;
148
149gpio_free:
150 gpio_free_array(mx31_3ds_sdhc1_gpios,
151 ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
152 return ret;
153}
154
155static void mx31_3ds_sdhc1_exit(struct device *dev, void *data)
156{
157 free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), data);
158 gpio_free_array(mx31_3ds_sdhc1_gpios,
159 ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
160}
161
162static void mx31_3ds_sdhc1_setpower(struct device *dev, unsigned int vdd)
163{
164 /*
165 * While the voltage stuff is done by the driver, activate the
166 * Buffer Enable Pin only if there is a card in slot to fix the card
167 * voltage issue caused by bi-directional chip TXB0108 on 3Stack.
168 * Done here because at this stage we have for sure a debounced value
169 * of the presence of the card, showed by the value of vdd.
170 * 7 == ilog2(MMC_VDD_165_195)
171 */
172 if (vdd > 7)
173 gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 1);
174 else
175 gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 0);
176}
177
178static struct imxmmc_platform_data sdhc1_pdata = {
179 .init = mx31_3ds_sdhc1_init,
180 .exit = mx31_3ds_sdhc1_exit,
181 .setpower = mx31_3ds_sdhc1_setpower,
Alberto Panizzo54c1f632010-05-19 11:34:43 +0200182};
183
184/*
185 * Matrix keyboard
186 */
187
188static const uint32_t mx31_3ds_keymap[] = {
189 KEY(0, 0, KEY_UP),
190 KEY(0, 1, KEY_DOWN),
191 KEY(1, 0, KEY_RIGHT),
192 KEY(1, 1, KEY_LEFT),
193 KEY(1, 2, KEY_ENTER),
194 KEY(2, 0, KEY_F6),
195 KEY(2, 1, KEY_F8),
196 KEY(2, 2, KEY_F9),
197 KEY(2, 3, KEY_F10),
198};
199
Uwe Kleine-Königd690b4c2010-11-16 21:27:33 +0100200static const struct matrix_keymap_data mx31_3ds_keymap_data __initconst = {
Alberto Panizzo54c1f632010-05-19 11:34:43 +0200201 .keymap = mx31_3ds_keymap,
202 .keymap_size = ARRAY_SIZE(mx31_3ds_keymap),
Alberto Panizzoae7a3f12010-03-23 19:51:45 +0100203};
204
205/* Regulators */
206static struct regulator_init_data pwgtx_init = {
207 .constraints = {
208 .boot_on = 1,
209 .always_on = 1,
210 },
211};
212
Fabio Estevam0d95b752010-12-21 16:38:22 -0200213static struct regulator_init_data gpo_init = {
214 .constraints = {
215 .boot_on = 1,
216 .always_on = 1,
217 }
218};
219
Alberto Panizzo0ce88b32011-03-07 11:45:07 +0100220static struct regulator_consumer_supply vmmc2_consumers[] = {
221 REGULATOR_SUPPLY("vmmc", "mxc-mmc.0"),
222};
223
224static struct regulator_init_data vmmc2_init = {
225 .constraints = {
226 .min_uV = 3000000,
227 .max_uV = 3000000,
228 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
229 REGULATOR_CHANGE_STATUS,
230 },
231 .num_consumer_supplies = ARRAY_SIZE(vmmc2_consumers),
232 .consumer_supplies = vmmc2_consumers,
233};
234
David Jander58363722011-02-10 10:59:44 +0100235static struct mc13xxx_regulator_init_data mx31_3ds_regulators[] = {
Alberto Panizzoae7a3f12010-03-23 19:51:45 +0100236 {
Yong Shen57c78e32010-12-14 14:00:53 +0800237 .id = MC13783_REG_PWGT1SPI, /* Power Gate for ARM core. */
Alberto Panizzoae7a3f12010-03-23 19:51:45 +0100238 .init_data = &pwgtx_init,
239 }, {
Yong Shen57c78e32010-12-14 14:00:53 +0800240 .id = MC13783_REG_PWGT2SPI, /* Power Gate for L2 Cache. */
Alberto Panizzoae7a3f12010-03-23 19:51:45 +0100241 .init_data = &pwgtx_init,
Fabio Estevam0d95b752010-12-21 16:38:22 -0200242 }, {
243
Sascha Hauerc97b7392011-01-14 09:44:02 +0100244 .id = MC13783_REG_GPO1, /* Turn on 1.8V */
Fabio Estevam0d95b752010-12-21 16:38:22 -0200245 .init_data = &gpo_init,
246 }, {
Sascha Hauerc97b7392011-01-14 09:44:02 +0100247 .id = MC13783_REG_GPO3, /* Turn on 3.3V */
Fabio Estevam0d95b752010-12-21 16:38:22 -0200248 .init_data = &gpo_init,
Alberto Panizzo0ce88b32011-03-07 11:45:07 +0100249 }, {
250 .id = MC13783_REG_VMMC2, /* Power MMC/SD, WiFi/Bluetooth. */
251 .init_data = &vmmc2_init,
Alberto Panizzoae7a3f12010-03-23 19:51:45 +0100252 },
253};
254
255/* MC13783 */
David Jander58363722011-02-10 10:59:44 +0100256static struct mc13xxx_platform_data mc13783_pdata __initdata = {
Alberto Panizzoae7a3f12010-03-23 19:51:45 +0100257 .regulators = mx31_3ds_regulators,
258 .num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
David Jander58363722011-02-10 10:59:44 +0100259 .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_TOUCHSCREEN
Alberto Panizzoa1ac4422010-03-23 19:50:28 +0100260};
261
262/* SPI */
263static int spi1_internal_chipselect[] = {
264 MXC_SPI_CS(0),
265 MXC_SPI_CS(2),
266};
267
Uwe Kleine-König06606ff2010-06-22 10:09:14 +0200268static const struct spi_imx_master spi1_pdata __initconst = {
Alberto Panizzoa1ac4422010-03-23 19:50:28 +0100269 .chipselect = spi1_internal_chipselect,
270 .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
Valentin Longchamp63d976672009-01-28 15:13:53 +0100271};
272
Alberto Panizzoae7a3f12010-03-23 19:51:45 +0100273static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
274 {
275 .modalias = "mc13783",
276 .max_speed_hz = 1000000,
277 .bus_num = 1,
278 .chip_select = 1, /* SS2 */
279 .platform_data = &mc13783_pdata,
280 .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
281 .mode = SPI_CS_HIGH,
282 },
283};
284
Alberto Panizzoa1b67b92010-03-23 19:49:35 +0100285/*
286 * NAND Flash
287 */
Uwe Kleine-Königa2ceeef2010-06-16 12:23:11 +0200288static const struct mxc_nand_platform_data
289mx31_3ds_nand_board_info __initconst = {
Alberto Panizzoa1b67b92010-03-23 19:49:35 +0100290 .width = 1,
291 .hw_ecc = 1,
292#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
293 .flash_bbt = 1,
294#endif
295};
296
Magnus Liljaa2ef4562010-05-14 17:08:29 +0200297/*
298 * USB OTG
299 */
300
301#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
302 PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
303
304#define USBOTG_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_PWR)
Fabio Estevam0d95b752010-12-21 16:38:22 -0200305#define USBH2_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_BYP)
Magnus Liljaa2ef4562010-05-14 17:08:29 +0200306
Fabio Estevam41f63472010-06-21 13:33:05 -0700307static int mx31_3ds_usbotg_init(void)
Magnus Liljaa2ef4562010-05-14 17:08:29 +0200308{
Fabio Estevam41f63472010-06-21 13:33:05 -0700309 int err;
310
Magnus Liljaa2ef4562010-05-14 17:08:29 +0200311 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
312 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
313 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
314 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
315 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
316 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
317 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
318 mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
319 mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
320 mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
321 mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
322 mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
323
Fabio Estevam41f63472010-06-21 13:33:05 -0700324 err = gpio_request(USBOTG_RST_B, "otgusb-reset");
325 if (err) {
326 pr_err("Failed to request the USB OTG reset gpio\n");
327 return err;
328 }
329
330 err = gpio_direction_output(USBOTG_RST_B, 0);
331 if (err) {
332 pr_err("Failed to drive the USB OTG reset gpio\n");
333 goto usbotg_free_reset;
334 }
335
Magnus Liljaa2ef4562010-05-14 17:08:29 +0200336 mdelay(1);
337 gpio_set_value(USBOTG_RST_B, 1);
Fabio Estevam41f63472010-06-21 13:33:05 -0700338 return 0;
339
340usbotg_free_reset:
341 gpio_free(USBOTG_RST_B);
342 return err;
Magnus Liljaa2ef4562010-05-14 17:08:29 +0200343}
344
Sascha Hauer4bd597b2011-01-03 11:30:28 +0100345static int mx31_3ds_otg_init(struct platform_device *pdev)
346{
347 return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
348}
349
350static int mx31_3ds_host2_init(struct platform_device *pdev)
Fabio Estevam0d95b752010-12-21 16:38:22 -0200351{
352 int err;
353
354 mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
355 mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
356 mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
357 mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
358 mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
359 mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
360 mxc_iomux_set_pad(MX31_PIN_PC_VS2, USB_PAD_CFG);
361 mxc_iomux_set_pad(MX31_PIN_PC_BVD1, USB_PAD_CFG);
362 mxc_iomux_set_pad(MX31_PIN_PC_BVD2, USB_PAD_CFG);
363 mxc_iomux_set_pad(MX31_PIN_PC_RST, USB_PAD_CFG);
364 mxc_iomux_set_pad(MX31_PIN_IOIS16, USB_PAD_CFG);
365 mxc_iomux_set_pad(MX31_PIN_PC_RW_B, USB_PAD_CFG);
366
367 err = gpio_request(USBH2_RST_B, "usbh2-reset");
368 if (err) {
369 pr_err("Failed to request the USB Host 2 reset gpio\n");
370 return err;
371 }
372
373 err = gpio_direction_output(USBH2_RST_B, 0);
374 if (err) {
375 pr_err("Failed to drive the USB Host 2 reset gpio\n");
376 goto usbotg_free_reset;
377 }
378
379 mdelay(1);
380 gpio_set_value(USBH2_RST_B, 1);
Sascha Hauer4bd597b2011-01-03 11:30:28 +0100381
382 mdelay(10);
383
384 return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
Fabio Estevam0d95b752010-12-21 16:38:22 -0200385
386usbotg_free_reset:
387 gpio_free(USBH2_RST_B);
388 return err;
389}
390
Fabio Estevam1c50e672010-12-21 16:38:21 -0200391static struct mxc_usbh_platform_data otg_pdata __initdata = {
Sascha Hauer4bd597b2011-01-03 11:30:28 +0100392 .init = mx31_3ds_otg_init,
Fabio Estevam1c50e672010-12-21 16:38:21 -0200393 .portsc = MXC_EHCI_MODE_ULPI,
Fabio Estevam1c50e672010-12-21 16:38:21 -0200394};
Fabio Estevam0d95b752010-12-21 16:38:22 -0200395
396static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
397 .init = mx31_3ds_host2_init,
398 .portsc = MXC_EHCI_MODE_ULPI,
Fabio Estevam0d95b752010-12-21 16:38:22 -0200399};
Fabio Estevam1c50e672010-12-21 16:38:21 -0200400
Uwe Kleine-König9e1dde32010-11-12 16:40:06 +0100401static const struct fsl_usb2_platform_data usbotg_pdata __initconst = {
Magnus Liljaa2ef4562010-05-14 17:08:29 +0200402 .operating_mode = FSL_USB2_DR_DEVICE,
403 .phy_mode = FSL_USB2_PHY_ULPI,
404};
405
Fabio Estevam1c50e672010-12-21 16:38:21 -0200406static int otg_mode_host;
407
408static int __init mx31_3ds_otg_mode(char *options)
409{
410 if (!strcmp(options, "host"))
411 otg_mode_host = 1;
412 else if (!strcmp(options, "device"))
413 otg_mode_host = 0;
414 else
415 pr_info("otg_mode neither \"host\" nor \"device\". "
416 "Defaulting to device\n");
417 return 0;
418}
419__setup("otg_mode=", mx31_3ds_otg_mode);
420
Uwe Kleine-König16cf5c42010-06-23 11:46:16 +0200421static const struct imxuart_platform_data uart_pdata __initconst = {
Magnus Lilja153fa1d2009-05-16 12:43:10 +0200422 .flags = IMXUART_HAVE_RTSCTS,
423};
Fabio Estevam1553a1e2008-11-12 15:38:39 +0100424
Fabio Estevam3d943022011-03-01 16:59:45 -0300425static const struct imxi2c_platform_data mx31_3ds_i2c0_data __initconst = {
426 .bitrate = 100000,
427};
428
Uwe Kleine-Könige134fb22011-02-11 10:23:19 +0100429static void __init mx31_3ds_init(void)
Fabio Estevam1553a1e2008-11-12 15:38:39 +0100430{
Alberto Panizzo11a332adf2010-03-23 19:46:57 +0100431 mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
432 "mx31_3ds");
Magnus Lilja153fa1d2009-05-16 12:43:10 +0200433
Uwe Kleine-König16cf5c42010-06-23 11:46:16 +0200434 imx31_add_imx_uart0(&uart_pdata);
Uwe Kleine-Königa2ceeef2010-06-16 12:23:11 +0200435 imx31_add_mxc_nand(&mx31_3ds_nand_board_info);
Alberto Panizzoae7a3f12010-03-23 19:51:45 +0100436
Rogerio Pimentel4a74bdd2010-10-25 12:55:14 -0200437 imx31_add_spi_imx1(&spi1_pdata);
Alberto Panizzoae7a3f12010-03-23 19:51:45 +0100438 spi_register_board_info(mx31_3ds_spi_devs,
439 ARRAY_SIZE(mx31_3ds_spi_devs));
Magnus Lilja135cad32009-05-17 20:18:08 +0200440
Uwe Kleine-Königd690b4c2010-11-16 21:27:33 +0100441 imx31_add_imx_keypad(&mx31_3ds_keymap_data);
Alberto Panizzo54c1f632010-05-19 11:34:43 +0200442
Magnus Liljaa2ef4562010-05-14 17:08:29 +0200443 mx31_3ds_usbotg_init();
Fabio Estevam1c50e672010-12-21 16:38:21 -0200444 if (otg_mode_host) {
Sascha Hauer48f6b092011-03-02 09:27:42 +0100445 otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
446 ULPI_OTG_DRVVBUS_EXT);
447 if (otg_pdata.otg)
448 imx31_add_mxc_ehci_otg(&otg_pdata);
Fabio Estevam1c50e672010-12-21 16:38:21 -0200449 }
Sascha Hauer48f6b092011-03-02 09:27:42 +0100450 usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
451 ULPI_OTG_DRVVBUS_EXT);
452 if (usbh2_pdata.otg)
453 imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
454
Fabio Estevam1c50e672010-12-21 16:38:21 -0200455 if (!otg_mode_host)
456 imx31_add_fsl_usb2_udc(&usbotg_pdata);
Magnus Liljaa2ef4562010-05-14 17:08:29 +0200457
Rogerio Pimentelb8be7b92010-10-25 12:54:24 -0200458 if (mxc_expio_init(MX31_CS5_BASE_ADDR, EXPIO_PARENT_INT))
459 printk(KERN_WARNING "Init of the debug board failed, all "
460 "devices on the debug board are unusable.\n");
Fabio Estevambfdde3a2010-12-07 17:14:44 -0200461 imx31_add_imx2_wdt(NULL);
Fabio Estevam3d943022011-03-01 16:59:45 -0300462 imx31_add_imx_i2c0(&mx31_3ds_i2c0_data);
Alberto Panizzo0ce88b32011-03-07 11:45:07 +0100463 imx31_add_mxc_mmc(0, &sdhc1_pdata);
Fabio Estevam1553a1e2008-11-12 15:38:39 +0100464}
465
Alberto Panizzo11a332adf2010-03-23 19:46:57 +0100466static void __init mx31_3ds_timer_init(void)
Fabio Estevam1553a1e2008-11-12 15:38:39 +0100467{
Sascha Hauer30c730f2009-02-16 14:36:49 +0100468 mx31_clocks_init(26000000);
Fabio Estevam1553a1e2008-11-12 15:38:39 +0100469}
470
Alberto Panizzo11a332adf2010-03-23 19:46:57 +0100471static struct sys_timer mx31_3ds_timer = {
472 .init = mx31_3ds_timer_init,
Fabio Estevam1553a1e2008-11-12 15:38:39 +0100473};
474
Fabio Estevam1553a1e2008-11-12 15:38:39 +0100475MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
476 /* Maintainer: Freescale Semiconductor, Inc. */
Uwe Kleine-König97976e22011-02-07 16:35:20 +0100477 .boot_params = MX3x_PHYS_OFFSET + 0x100,
478 .map_io = mx31_map_io,
479 .init_early = imx31_init_early,
480 .init_irq = mx31_init_irq,
481 .timer = &mx31_3ds_timer,
Uwe Kleine-Könige134fb22011-02-11 10:23:19 +0100482 .init_machine = mx31_3ds_init,
Fabio Estevam1553a1e2008-11-12 15:38:39 +0100483MACHINE_END