Commit | Line | Data |
---|---|---|
143a179d ACA |
1 | /* |
2 | * Copyright (C) 2000 Deep Blue Solutions Ltd | |
3 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | |
4 | * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. | |
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. | |
143a179d ACA |
15 | */ |
16 | ||
17 | #include <linux/platform_device.h> | |
18 | #include <linux/mtd/mtd.h> | |
19 | #include <linux/mtd/map.h> | |
20 | #include <linux/mtd/partitions.h> | |
21 | #include <linux/mtd/physmap.h> | |
22 | #include <linux/i2c.h> | |
23 | #include <linux/irq.h> | |
24 | #include <mach/common.h> | |
25 | #include <mach/hardware.h> | |
26 | #include <asm/mach-types.h> | |
27 | #include <asm/mach/arch.h> | |
28 | #include <asm/mach/time.h> | |
29 | #include <asm/mach/map.h> | |
30 | #include <linux/gpio.h> | |
31 | #include <mach/imx-uart.h> | |
e835d88e | 32 | #include <mach/iomux-mx27.h> |
143a179d ACA |
33 | #include <mach/mxc_nand.h> |
34 | #include <mach/i2c.h> | |
9e3e7afe | 35 | #include <linux/i2c/pca953x.h> |
143a179d ACA |
36 | #include <mach/imxfb.h> |
37 | #include <mach/mmc.h> | |
38 | ||
0e7a29a8 | 39 | #include "devices-imx27.h" |
143a179d ACA |
40 | #include "devices.h" |
41 | ||
42 | static unsigned int mxt_td60_pins[] __initdata = { | |
43 | /* UART0 */ | |
44 | PE12_PF_UART1_TXD, | |
45 | PE13_PF_UART1_RXD, | |
46 | PE14_PF_UART1_CTS, | |
47 | PE15_PF_UART1_RTS, | |
48 | /* UART1 */ | |
49 | PE3_PF_UART2_CTS, | |
50 | PE4_PF_UART2_RTS, | |
51 | PE6_PF_UART2_TXD, | |
52 | PE7_PF_UART2_RXD, | |
53 | /* UART2 */ | |
54 | PE8_PF_UART3_TXD, | |
55 | PE9_PF_UART3_RXD, | |
56 | PE10_PF_UART3_CTS, | |
57 | PE11_PF_UART3_RTS, | |
143a179d ACA |
58 | /* FEC */ |
59 | PD0_AIN_FEC_TXD0, | |
60 | PD1_AIN_FEC_TXD1, | |
61 | PD2_AIN_FEC_TXD2, | |
62 | PD3_AIN_FEC_TXD3, | |
63 | PD4_AOUT_FEC_RX_ER, | |
64 | PD5_AOUT_FEC_RXD1, | |
65 | PD6_AOUT_FEC_RXD2, | |
66 | PD7_AOUT_FEC_RXD3, | |
67 | PD8_AF_FEC_MDIO, | |
68 | PD9_AIN_FEC_MDC, | |
69 | PD10_AOUT_FEC_CRS, | |
70 | PD11_AOUT_FEC_TX_CLK, | |
71 | PD12_AOUT_FEC_RXD0, | |
72 | PD13_AOUT_FEC_RX_DV, | |
73 | PD14_AOUT_FEC_RX_CLK, | |
74 | PD15_AOUT_FEC_COL, | |
75 | PD16_AIN_FEC_TX_ER, | |
76 | PF23_AIN_FEC_TX_EN, | |
77 | /* I2C1 */ | |
78 | PD17_PF_I2C_DATA, | |
79 | PD18_PF_I2C_CLK, | |
80 | /* I2C2 */ | |
81 | PC5_PF_I2C2_SDA, | |
82 | PC6_PF_I2C2_SCL, | |
83 | /* FB */ | |
84 | PA5_PF_LSCLK, | |
85 | PA6_PF_LD0, | |
86 | PA7_PF_LD1, | |
87 | PA8_PF_LD2, | |
88 | PA9_PF_LD3, | |
89 | PA10_PF_LD4, | |
90 | PA11_PF_LD5, | |
91 | PA12_PF_LD6, | |
92 | PA13_PF_LD7, | |
93 | PA14_PF_LD8, | |
94 | PA15_PF_LD9, | |
95 | PA16_PF_LD10, | |
96 | PA17_PF_LD11, | |
97 | PA18_PF_LD12, | |
98 | PA19_PF_LD13, | |
99 | PA20_PF_LD14, | |
100 | PA21_PF_LD15, | |
101 | PA22_PF_LD16, | |
102 | PA23_PF_LD17, | |
103 | PA25_PF_CLS, | |
104 | PA27_PF_SPL_SPR, | |
105 | PA28_PF_HSYNC, | |
106 | PA29_PF_VSYNC, | |
107 | PA30_PF_CONTRAST, | |
108 | PA31_PF_OE_ACD, | |
109 | /* OWIRE */ | |
110 | PE16_AF_OWIRE, | |
111 | /* SDHC1*/ | |
112 | PE18_PF_SD1_D0, | |
113 | PE19_PF_SD1_D1, | |
114 | PE20_PF_SD1_D2, | |
115 | PE21_PF_SD1_D3, | |
116 | PE22_PF_SD1_CMD, | |
117 | PE23_PF_SD1_CLK, | |
9e3e7afe | 118 | PF8_AF_ATA_IORDY, |
143a179d ACA |
119 | /* SDHC2*/ |
120 | PB4_PF_SD2_D0, | |
121 | PB5_PF_SD2_D1, | |
122 | PB6_PF_SD2_D2, | |
123 | PB7_PF_SD2_D3, | |
124 | PB8_PF_SD2_CMD, | |
125 | PB9_PF_SD2_CLK, | |
126 | }; | |
127 | ||
0e7a29a8 UKK |
128 | static const struct mxc_nand_platform_data |
129 | mxt_td60_nand_board_info __initconst = { | |
143a179d ACA |
130 | .width = 1, |
131 | .hw_ecc = 1, | |
132 | }; | |
133 | ||
134 | static struct imxi2c_platform_data mxt_td60_i2c_data = { | |
135 | .bitrate = 100000, | |
136 | }; | |
137 | ||
9e3e7afe ACA |
138 | /* PCA9557 */ |
139 | static int mxt_td60_pca9557_setup(struct i2c_client *client, | |
140 | unsigned gpio_base, unsigned ngpio, | |
141 | void *context) | |
142 | { | |
143 | static int mxt_td60_gpio_value[] = { | |
144 | -1, -1, -1, -1, -1, -1, -1, 1 | |
145 | }; | |
146 | int n; | |
147 | ||
148 | for (n = 0; n < ARRAY_SIZE(mxt_td60_gpio_value); ++n) { | |
149 | gpio_request(gpio_base + n, "MXT_TD60 GPIO Exp"); | |
150 | if (mxt_td60_gpio_value[n] < 0) | |
151 | gpio_direction_input(gpio_base + n); | |
152 | else | |
153 | gpio_direction_output(gpio_base + n, | |
154 | mxt_td60_gpio_value[n]); | |
155 | gpio_export(gpio_base + n, 0); | |
156 | } | |
157 | ||
158 | return 0; | |
159 | } | |
160 | ||
161 | static struct pca953x_platform_data mxt_td60_pca9557_pdata = { | |
162 | .gpio_base = 240, /* place PCA9557 after all MX27 gpio pins */ | |
163 | .invert = 0, /* Do not invert */ | |
164 | .setup = mxt_td60_pca9557_setup, | |
165 | }; | |
166 | ||
143a179d | 167 | static struct i2c_board_info mxt_td60_i2c_devices[] = { |
9e3e7afe ACA |
168 | { |
169 | I2C_BOARD_INFO("pca9557", 0x18), | |
170 | .platform_data = &mxt_td60_pca9557_pdata, | |
171 | }, | |
143a179d ACA |
172 | }; |
173 | ||
174 | static struct imxi2c_platform_data mxt_td60_i2c2_data = { | |
175 | .bitrate = 100000, | |
176 | }; | |
177 | ||
178 | static struct i2c_board_info mxt_td60_i2c2_devices[] = { | |
179 | }; | |
180 | ||
181 | static struct imx_fb_videomode mxt_td60_modes[] = { | |
182 | { | |
183 | .mode = { | |
184 | .name = "Chimei LW700AT9003", | |
185 | .refresh = 60, | |
186 | .xres = 800, | |
187 | .yres = 480, | |
188 | .pixclock = 30303, | |
189 | .hsync_len = 64, | |
190 | .left_margin = 0x67, | |
191 | .right_margin = 0x68, | |
192 | .vsync_len = 16, | |
193 | .upper_margin = 0x0f, | |
194 | .lower_margin = 0x0f, | |
195 | }, | |
196 | .bpp = 16, | |
197 | .pcr = 0xFA208B83, | |
198 | }, | |
199 | }; | |
200 | ||
201 | static struct imx_fb_platform_data mxt_td60_fb_data = { | |
202 | .mode = mxt_td60_modes, | |
203 | .num_modes = ARRAY_SIZE(mxt_td60_modes), | |
204 | ||
205 | /* | |
206 | * - HSYNC active high | |
207 | * - VSYNC active high | |
208 | * - clk notenabled while idle | |
209 | * - clock inverted | |
210 | * - data not inverted | |
211 | * - data enable low active | |
212 | * - enable sharp mode | |
213 | */ | |
214 | .pwmr = 0x00A903FF, | |
215 | .lscr1 = 0x00120300, | |
216 | .dmacr = 0x00020010, | |
217 | }; | |
218 | ||
219 | static int mxt_td60_sdhc1_init(struct device *dev, irq_handler_t detect_irq, | |
220 | void *data) | |
221 | { | |
9e3e7afe | 222 | return request_irq(IRQ_GPIOF(8), detect_irq, IRQF_TRIGGER_FALLING, |
143a179d ACA |
223 | "sdhc1-card-detect", data); |
224 | } | |
225 | ||
226 | static void mxt_td60_sdhc1_exit(struct device *dev, void *data) | |
227 | { | |
9e3e7afe | 228 | free_irq(IRQ_GPIOF(8), data); |
143a179d ACA |
229 | } |
230 | ||
231 | static struct imxmmc_platform_data sdhc1_pdata = { | |
232 | .init = mxt_td60_sdhc1_init, | |
233 | .exit = mxt_td60_sdhc1_exit, | |
234 | }; | |
235 | ||
236 | static struct platform_device *platform_devices[] __initdata = { | |
237 | &mxc_fec_device, | |
238 | }; | |
239 | ||
240 | static struct imxuart_platform_data uart_pdata[] = { | |
241 | { | |
242 | .flags = IMXUART_HAVE_RTSCTS, | |
243 | }, { | |
244 | .flags = IMXUART_HAVE_RTSCTS, | |
245 | }, { | |
246 | .flags = IMXUART_HAVE_RTSCTS, | |
143a179d ACA |
247 | }, |
248 | }; | |
249 | ||
250 | static void __init mxt_td60_board_init(void) | |
251 | { | |
252 | mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins), | |
253 | "MXT_TD60"); | |
254 | ||
551823e7 UKK |
255 | mxc_register_device(&imx2x_uart_device0, &uart_pdata[0]); |
256 | mxc_register_device(&imx2x_uart_device1, &uart_pdata[1]); | |
257 | mxc_register_device(&imx2x_uart_device2, &uart_pdata[2]); | |
0e7a29a8 | 258 | imx27_add_mxc_nand(&mxt_td60_nand_board_info); |
143a179d ACA |
259 | |
260 | i2c_register_board_info(0, mxt_td60_i2c_devices, | |
261 | ARRAY_SIZE(mxt_td60_i2c_devices)); | |
262 | ||
263 | i2c_register_board_info(1, mxt_td60_i2c2_devices, | |
264 | ARRAY_SIZE(mxt_td60_i2c2_devices)); | |
265 | ||
266 | mxc_register_device(&mxc_i2c_device0, &mxt_td60_i2c_data); | |
267 | mxc_register_device(&mxc_i2c_device1, &mxt_td60_i2c2_data); | |
268 | mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data); | |
269 | mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata); | |
270 | ||
271 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | |
272 | } | |
273 | ||
274 | static void __init mxt_td60_timer_init(void) | |
275 | { | |
276 | mx27_clocks_init(26000000); | |
277 | } | |
278 | ||
279 | static struct sys_timer mxt_td60_timer = { | |
280 | .init = mxt_td60_timer_init, | |
281 | }; | |
282 | ||
283 | MACHINE_START(MXT_TD60, "Maxtrack i-MXT TD60") | |
284 | /* maintainer: Maxtrack Industrial */ | |
3f35d1f5 UKK |
285 | .phys_io = MX27_AIPI_BASE_ADDR, |
286 | .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, | |
34101237 | 287 | .boot_params = MX27_PHYS_OFFSET + 0x100, |
143a179d ACA |
288 | .map_io = mx27_map_io, |
289 | .init_irq = mx27_init_irq, | |
290 | .init_machine = mxt_td60_board_init, | |
291 | .timer = &mxt_td60_timer, | |
292 | MACHINE_END | |
293 |