Merge branch 'for-rmk' of git://linux-arm.org/linux-2.6 into devel
[sfrench/cifs-2.6.git] / arch / arm / mach-mx3 / armadillo5x0.c
1 /*
2  * armadillo5x0.c
3  *
4  * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
5  * updates in http://alberdroid.blogspot.com/
6  *
7  * Based on Atmark Techno, Inc. armadillo 500 BSP 2008
8  * Based on mx31ads.c and pcm037.c Great Work!
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23  * MA 02110-1301, USA.
24  */
25
26 #include <linux/types.h>
27 #include <linux/init.h>
28 #include <linux/clk.h>
29 #include <linux/platform_device.h>
30 #include <linux/gpio.h>
31 #include <linux/smsc911x.h>
32 #include <linux/interrupt.h>
33 #include <linux/irq.h>
34
35 #include <mach/hardware.h>
36 #include <asm/mach-types.h>
37 #include <asm/mach/arch.h>
38 #include <asm/mach/time.h>
39 #include <asm/memory.h>
40 #include <asm/mach/map.h>
41
42 #include <mach/common.h>
43 #include <mach/imx-uart.h>
44 #include <mach/iomux-mx3.h>
45 #include <mach/board-armadillo5x0.h>
46 #include <mach/mmc.h>
47 #include <mach/ipu.h>
48 #include <mach/mx3fb.h>
49
50 #include "devices.h"
51
52 static int armadillo5x0_pins[] = {
53         /* UART1 */
54         MX31_PIN_CTS1__CTS1,
55         MX31_PIN_RTS1__RTS1,
56         MX31_PIN_TXD1__TXD1,
57         MX31_PIN_RXD1__RXD1,
58         /* UART2 */
59         MX31_PIN_CTS2__CTS2,
60         MX31_PIN_RTS2__RTS2,
61         MX31_PIN_TXD2__TXD2,
62         MX31_PIN_RXD2__RXD2,
63         /* LAN9118_IRQ */
64         IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO),
65         /* SDHC1 */
66         MX31_PIN_SD1_DATA3__SD1_DATA3,
67         MX31_PIN_SD1_DATA2__SD1_DATA2,
68         MX31_PIN_SD1_DATA1__SD1_DATA1,
69         MX31_PIN_SD1_DATA0__SD1_DATA0,
70         MX31_PIN_SD1_CLK__SD1_CLK,
71         MX31_PIN_SD1_CMD__SD1_CMD,
72         /* Framebuffer */
73         MX31_PIN_LD0__LD0,
74         MX31_PIN_LD1__LD1,
75         MX31_PIN_LD2__LD2,
76         MX31_PIN_LD3__LD3,
77         MX31_PIN_LD4__LD4,
78         MX31_PIN_LD5__LD5,
79         MX31_PIN_LD6__LD6,
80         MX31_PIN_LD7__LD7,
81         MX31_PIN_LD8__LD8,
82         MX31_PIN_LD9__LD9,
83         MX31_PIN_LD10__LD10,
84         MX31_PIN_LD11__LD11,
85         MX31_PIN_LD12__LD12,
86         MX31_PIN_LD13__LD13,
87         MX31_PIN_LD14__LD14,
88         MX31_PIN_LD15__LD15,
89         MX31_PIN_LD16__LD16,
90         MX31_PIN_LD17__LD17,
91         MX31_PIN_VSYNC3__VSYNC3,
92         MX31_PIN_HSYNC__HSYNC,
93         MX31_PIN_FPSHIFT__FPSHIFT,
94         MX31_PIN_DRDY0__DRDY0,
95         IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/
96
97 };
98
99 /*
100  * FB support
101  */
102 static const struct fb_videomode fb_modedb[] = {
103         {       /* 640x480 @ 60 Hz */
104                 .name           = "CRT-VGA",
105                 .refresh        = 60,
106                 .xres           = 640,
107                 .yres           = 480,
108                 .pixclock       = 39721,
109                 .left_margin    = 35,
110                 .right_margin   = 115,
111                 .upper_margin   = 43,
112                 .lower_margin   = 1,
113                 .hsync_len      = 10,
114                 .vsync_len      = 1,
115                 .sync           = FB_SYNC_OE_ACT_HIGH,
116                 .vmode          = FB_VMODE_NONINTERLACED,
117                 .flag           = 0,
118         }, {/* 800x600 @ 56 Hz */
119                 .name           = "CRT-SVGA",
120                 .refresh        = 56,
121                 .xres           = 800,
122                 .yres           = 600,
123                 .pixclock       = 30000,
124                 .left_margin    = 30,
125                 .right_margin   = 108,
126                 .upper_margin   = 13,
127                 .lower_margin   = 10,
128                 .hsync_len      = 10,
129                 .vsync_len      = 1,
130                 .sync           = FB_SYNC_OE_ACT_HIGH | FB_SYNC_HOR_HIGH_ACT |
131                                   FB_SYNC_VERT_HIGH_ACT,
132                 .vmode          = FB_VMODE_NONINTERLACED,
133                 .flag           = 0,
134         },
135 };
136
137 static struct ipu_platform_data mx3_ipu_data = {
138         .irq_base = MXC_IPU_IRQ_START,
139 };
140
141 static struct mx3fb_platform_data mx3fb_pdata = {
142         .dma_dev        = &mx3_ipu.dev,
143         .name           = "CRT-VGA",
144         .mode           = fb_modedb,
145         .num_modes      = ARRAY_SIZE(fb_modedb),
146 };
147
148 /*
149  * SDHC 1
150  * MMC support
151  */
152 static int armadillo5x0_sdhc1_get_ro(struct device *dev)
153 {
154         return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
155 }
156
157 static int armadillo5x0_sdhc1_init(struct device *dev,
158                                    irq_handler_t detect_irq, void *data)
159 {
160         int ret;
161         int gpio_det, gpio_wp;
162
163         gpio_det = IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK);
164         gpio_wp = IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B);
165
166         ret = gpio_request(gpio_det, "sdhc-card-detect");
167         if (ret)
168                 return ret;
169
170         gpio_direction_input(gpio_det);
171
172         ret = gpio_request(gpio_wp, "sdhc-write-protect");
173         if (ret)
174                 goto err_gpio_free;
175
176         gpio_direction_input(gpio_wp);
177
178         /* When supported the trigger type have to be BOTH */
179         ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), detect_irq,
180                           IRQF_DISABLED | IRQF_TRIGGER_FALLING,
181                           "sdhc-detect", data);
182
183         if (ret)
184                 goto err_gpio_free_2;
185
186         return 0;
187
188 err_gpio_free_2:
189         gpio_free(gpio_wp);
190
191 err_gpio_free:
192         gpio_free(gpio_det);
193
194         return ret;
195
196 }
197
198 static void armadillo5x0_sdhc1_exit(struct device *dev, void *data)
199 {
200         free_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), data);
201         gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK));
202         gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
203 }
204
205 static struct imxmmc_platform_data sdhc_pdata = {
206         .get_ro = armadillo5x0_sdhc1_get_ro,
207         .init = armadillo5x0_sdhc1_init,
208         .exit = armadillo5x0_sdhc1_exit,
209 };
210
211 /*
212  * SMSC 9118
213  * Network support
214  */
215 static struct resource armadillo5x0_smc911x_resources[] = {
216         {
217                 .start  = CS3_BASE_ADDR,
218                 .end    = CS3_BASE_ADDR + SZ_32M - 1,
219                 .flags  = IORESOURCE_MEM,
220         }, {
221                 .start  = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
222                 .end    = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
223                 .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
224         },
225 };
226
227 static struct smsc911x_platform_config smsc911x_info = {
228         .flags          = SMSC911X_USE_32BIT,
229         .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
230         .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
231 };
232
233 static struct platform_device armadillo5x0_smc911x_device = {
234         .name           = "smsc911x",
235         .id             = -1,
236         .num_resources  = ARRAY_SIZE(armadillo5x0_smc911x_resources),
237         .resource       = armadillo5x0_smc911x_resources,
238         .dev            = {
239                 .platform_data = &smsc911x_info,
240         },
241 };
242
243 /* UART device data */
244 static struct imxuart_platform_data uart_pdata = {
245         .flags = IMXUART_HAVE_RTSCTS,
246 };
247
248 static struct platform_device *devices[] __initdata = {
249         &armadillo5x0_smc911x_device,
250 };
251
252 /*
253  * Perform board specific initializations
254  */
255 static void __init armadillo5x0_init(void)
256 {
257         mxc_iomux_setup_multiple_pins(armadillo5x0_pins,
258                         ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
259
260         platform_add_devices(devices, ARRAY_SIZE(devices));
261
262         /* Register UART */
263         mxc_register_device(&mxc_uart_device0, &uart_pdata);
264         mxc_register_device(&mxc_uart_device1, &uart_pdata);
265
266         /* SMSC9118 IRQ pin */
267         gpio_direction_input(MX31_PIN_GPIO1_0);
268
269         /* Register SDHC */
270         mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
271
272         /* Register FB */
273         mxc_register_device(&mx3_ipu, &mx3_ipu_data);
274         mxc_register_device(&mx3_fb, &mx3fb_pdata);
275 }
276
277 static void __init armadillo5x0_timer_init(void)
278 {
279         mx31_clocks_init(26000000);
280 }
281
282 static struct sys_timer armadillo5x0_timer = {
283         .init   = armadillo5x0_timer_init,
284 };
285
286 MACHINE_START(ARMADILLO5X0, "Armadillo-500")
287         /* Maintainer: Alberto Panizzo  */
288         .phys_io        = AIPS1_BASE_ADDR,
289         .io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
290         .boot_params    = PHYS_OFFSET + 0x00000100,
291         .map_io         = mx31_map_io,
292         .init_irq       = mxc_init_irq,
293         .timer          = &armadillo5x0_timer,
294         .init_machine   = armadillo5x0_init,
295 MACHINE_END