blob: b49c69d024c70c717167fdf74db7431821ba48ef [file] [log] [blame]
eric miao2c8086a2007-09-11 19:13:17 -07001/*
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 *
eric miaoe9bba8e2007-10-30 08:01:38 +01008 * 2007-09-04: eric miao <eric.miao@marvell.com>
eric miao2c8086a2007-09-11 19:13:17 -07009 * 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>
Bridge Wufafc9d32007-12-21 19:00:13 +080028#include <asm/arch/mmc.h>
eric miao2c8086a2007-09-11 19:13:17 -070029
30#include "generic.h"
31
Bridge Wu5a1f21b2007-12-21 19:27:08 +080032#define MAX_SLOTS 3
Bridge Wufafc9d32007-12-21 19:00:13 +080033struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS];
34
eric miao2c8086a2007-09-11 19:13:17 -070035int gpio_backlight;
36int gpio_eth_irq;
37
38int lcd_id;
39int lcd_orientation;
40
41static 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,
51 }
52};
53
54static 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)
62static void zylonite_backlight_power(int on)
63{
64 gpio_set_value(gpio_backlight, on);
65}
66
67static 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
81static 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
95static 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
102static 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
131static 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
139static 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
160static inline void zylonite_init_lcd(void) {}
161#endif
162
Bridge Wufafc9d32007-12-21 19:00:13 +0800163#if defined(CONFIG_MMC)
164static 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
171static 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
206err_request_irq:
207 gpio_free(gpio_wp);
208err_request_wp:
209 gpio_free(gpio_cd);
210err_request_cd:
211 return err;
212}
213
214static 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
228static 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
Bridge Wu8d33b052007-12-21 19:15:36 +0800236static 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
Bridge Wufafc9d32007-12-21 19:00:13 +0800241static void __init zylonite_init_mmc(void)
242{
243 pxa_set_mci_info(&zylonite_mci_platform_data);
Bridge Wu8d33b052007-12-21 19:15:36 +0800244 pxa3xx_set_mci2_info(&zylonite_mci2_platform_data);
Bridge Wu5a1f21b2007-12-21 19:27:08 +0800245 if (cpu_is_pxa310())
246 pxa3xx_set_mci3_info(&zylonite_mci_platform_data);
Bridge Wufafc9d32007-12-21 19:00:13 +0800247}
248#else
249static inline void zylonite_init_mmc(void) {}
250#endif
251
eric miao2c8086a2007-09-11 19:13:17 -0700252static 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();
Bridge Wufafc9d32007-12-21 19:00:13 +0800267 zylonite_init_mmc();
eric miao2c8086a2007-09-11 19:13:17 -0700268}
269
270MACHINE_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,
278MACHINE_END