Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[deliverable/linux.git] / 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) || defined(CONFIG_FB_PXA_MODULE)
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
This page took 0.063612 seconds and 6 git commands to generate.