Merge git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
[linux-2.6] / arch / arm / mach-pxa / zylonite.c
1 /*
2  * linux/arch/arm/mach-pxa/zylonite.c
3  *
4  * Support for the PXA3xx Development Platform (aka Zylonite)
5  *
6  * Copyright (C) 2006 Marvell International Ltd.
7  *
8  * 2007-09-04: eric miao <eric.miao@marvell.com>
9  *             rewrite to align with latest kernel
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  */
15
16 #include <linux/module.h>
17 #include <linux/kernel.h>
18 #include <linux/interrupt.h>
19 #include <linux/init.h>
20 #include <linux/platform_device.h>
21
22 #include <asm/mach-types.h>
23 #include <asm/mach/arch.h>
24 #include <asm/hardware.h>
25 #include <asm/arch/gpio.h>
26 #include <asm/arch/pxafb.h>
27 #include <asm/arch/zylonite.h>
28 #include <asm/arch/mmc.h>
29
30 #include "generic.h"
31
32 #define MAX_SLOTS       3
33 struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS];
34
35 int gpio_backlight;
36 int gpio_eth_irq;
37
38 int lcd_id;
39 int lcd_orientation;
40
41 static struct resource smc91x_resources[] = {
42         [0] = {
43                 .start  = ZYLONITE_ETH_PHYS + 0x300,
44                 .end    = ZYLONITE_ETH_PHYS + 0xfffff,
45                 .flags  = IORESOURCE_MEM,
46         },
47         [1] = {
48                 .start  = -1,   /* for run-time assignment */
49                 .end    = -1,
50                 .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
51         }
52 };
53
54 static struct platform_device smc91x_device = {
55         .name           = "smc91x",
56         .id             = 0,
57         .num_resources  = ARRAY_SIZE(smc91x_resources),
58         .resource       = smc91x_resources,
59 };
60
61 #if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES)
62 static void zylonite_backlight_power(int on)
63 {
64         gpio_set_value(gpio_backlight, on);
65 }
66
67 static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
68         .pixclock               = 110000,
69         .xres                   = 240,
70         .yres                   = 320,
71         .bpp                    = 16,
72         .hsync_len              = 4,
73         .left_margin            = 6,
74         .right_margin           = 4,
75         .vsync_len              = 2,
76         .upper_margin           = 2,
77         .lower_margin           = 3,
78         .sync                   = FB_SYNC_VERT_HIGH_ACT,
79 };
80
81 static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
82         .pixclock               = 50000,
83         .xres                   = 640,
84         .yres                   = 480,
85         .bpp                    = 16,
86         .hsync_len              = 1,
87         .left_margin            = 0x9f,
88         .right_margin           = 1,
89         .vsync_len              = 44,
90         .upper_margin           = 0,
91         .lower_margin           = 0,
92         .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
93 };
94
95 static struct pxafb_mach_info zylonite_toshiba_lcd_info = {
96         .num_modes              = 1,
97         .lccr0                  = LCCR0_Act,
98         .lccr3                  = LCCR3_PCP,
99         .pxafb_backlight_power  = zylonite_backlight_power,
100 };
101
102 static struct pxafb_mode_info sharp_ls037_modes[] = {
103         [0] = {
104                 .pixclock       = 158000,
105                 .xres           = 240,
106                 .yres           = 320,
107                 .bpp            = 16,
108                 .hsync_len      = 4,
109                 .left_margin    = 39,
110                 .right_margin   = 39,
111                 .vsync_len      = 1,
112                 .upper_margin   = 2,
113                 .lower_margin   = 3,
114                 .sync           = 0,
115         },
116         [1] = {
117                 .pixclock       = 39700,
118                 .xres           = 480,
119                 .yres           = 640,
120                 .bpp            = 16,
121                 .hsync_len      = 8,
122                 .left_margin    = 81,
123                 .right_margin   = 81,
124                 .vsync_len      = 1,
125                 .upper_margin   = 2,
126                 .lower_margin   = 7,
127                 .sync           = 0,
128         },
129 };
130
131 static struct pxafb_mach_info zylonite_sharp_lcd_info = {
132         .modes                  = sharp_ls037_modes,
133         .num_modes              = 2,
134         .lccr0                  = LCCR0_Act,
135         .lccr3                  = LCCR3_PCP | LCCR3_HSP | LCCR3_VSP,
136         .pxafb_backlight_power  = zylonite_backlight_power,
137 };
138
139 static void __init zylonite_init_lcd(void)
140 {
141         /* backlight GPIO: output, default on */
142         gpio_direction_output(gpio_backlight, 1);
143
144         if (lcd_id & 0x20) {
145                 set_pxa_fb_info(&zylonite_sharp_lcd_info);
146                 return;
147         }
148
149         /* legacy LCD panels, it would be handy here if LCD panel type can
150          * be decided at run-time
151          */
152         if (1)
153                 zylonite_toshiba_lcd_info.modes = &toshiba_ltm035a776c_mode;
154         else
155                 zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode;
156
157         set_pxa_fb_info(&zylonite_toshiba_lcd_info);
158 }
159 #else
160 static inline void zylonite_init_lcd(void) {}
161 #endif
162
163 #if defined(CONFIG_MMC)
164 static int zylonite_mci_ro(struct device *dev)
165 {
166         struct platform_device *pdev = to_platform_device(dev);
167
168         return gpio_get_value(zylonite_mmc_slot[pdev->id].gpio_wp);
169 }
170
171 static int zylonite_mci_init(struct device *dev,
172                              irq_handler_t zylonite_detect_int,
173                              void *data)
174 {
175         struct platform_device *pdev = to_platform_device(dev);
176         int err, cd_irq, gpio_cd, gpio_wp;
177
178         cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
179         gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
180         gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
181
182         /*
183          * setup GPIO for Zylonite MMC controller
184          */
185         err = gpio_request(gpio_cd, "mmc card detect");
186         if (err)
187                 goto err_request_cd;
188         gpio_direction_input(gpio_cd);
189
190         err = gpio_request(gpio_wp, "mmc write protect");
191         if (err)
192                 goto err_request_wp;
193         gpio_direction_input(gpio_wp);
194
195         err = request_irq(cd_irq, zylonite_detect_int,
196                           IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
197                           "MMC card detect", data);
198         if (err) {
199                 printk(KERN_ERR "%s: MMC/SD/SDIO: "
200                                 "can't request card detect IRQ\n", __func__);
201                 goto err_request_irq;
202         }
203
204         return 0;
205
206 err_request_irq:
207         gpio_free(gpio_wp);
208 err_request_wp:
209         gpio_free(gpio_cd);
210 err_request_cd:
211         return err;
212 }
213
214 static void zylonite_mci_exit(struct device *dev, void *data)
215 {
216         struct platform_device *pdev = to_platform_device(dev);
217         int cd_irq, gpio_cd, gpio_wp;
218
219         cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
220         gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
221         gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
222
223         free_irq(cd_irq, data);
224         gpio_free(gpio_cd);
225         gpio_free(gpio_wp);
226 }
227
228 static struct pxamci_platform_data zylonite_mci_platform_data = {
229         .detect_delay   = 20,
230         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
231         .init           = zylonite_mci_init,
232         .exit           = zylonite_mci_exit,
233         .get_ro         = zylonite_mci_ro,
234 };
235
236 static struct pxamci_platform_data zylonite_mci2_platform_data = {
237         .detect_delay   = 20,
238         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
239 };
240
241 static void __init zylonite_init_mmc(void)
242 {
243         pxa_set_mci_info(&zylonite_mci_platform_data);
244         pxa3xx_set_mci2_info(&zylonite_mci2_platform_data);
245         if (cpu_is_pxa310())
246                 pxa3xx_set_mci3_info(&zylonite_mci_platform_data);
247 }
248 #else
249 static inline void zylonite_init_mmc(void) {}
250 #endif
251
252 static void __init zylonite_init(void)
253 {
254         /* board-processor specific initialization */
255         zylonite_pxa300_init();
256         zylonite_pxa320_init();
257
258         /*
259          * Note: We depend that the bootloader set
260          * the correct value to MSC register for SMC91x.
261          */
262         smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq);
263         smc91x_resources[1].end   = gpio_to_irq(gpio_eth_irq);
264         platform_device_register(&smc91x_device);
265
266         zylonite_init_lcd();
267         zylonite_init_mmc();
268 }
269
270 MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
271         .phys_io        = 0x40000000,
272         .boot_params    = 0xa0000100,
273         .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
274         .map_io         = pxa_map_io,
275         .init_irq       = pxa3xx_init_irq,
276         .timer          = &pxa_timer,
277         .init_machine   = zylonite_init,
278 MACHINE_END