blob: 66b446ca273dbbd06032207117153401ab046193 [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>
eric miao5cca9142008-04-13 21:46:34 +010021#include <linux/pwm_backlight.h>
eric miao2c8086a2007-09-11 19:13:17 -070022
23#include <asm/mach-types.h>
24#include <asm/mach/arch.h>
25#include <asm/hardware.h>
Mark Browncabb3522008-06-10 10:48:25 +010026#include <asm/arch/audio.h>
eric miao2c8086a2007-09-11 19:13:17 -070027#include <asm/arch/gpio.h>
28#include <asm/arch/pxafb.h>
29#include <asm/arch/zylonite.h>
Bridge Wufafc9d32007-12-21 19:00:13 +080030#include <asm/arch/mmc.h>
eric miao468e0862008-01-23 14:25:50 +080031#include <asm/arch/pxa27x_keypad.h>
eric miao2c8086a2007-09-11 19:13:17 -070032
eric miao5cca9142008-04-13 21:46:34 +010033#include "devices.h"
eric miao2c8086a2007-09-11 19:13:17 -070034#include "generic.h"
35
Bridge Wu5a1f21b2007-12-21 19:27:08 +080036#define MAX_SLOTS 3
Bridge Wufafc9d32007-12-21 19:00:13 +080037struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS];
38
eric miao2c8086a2007-09-11 19:13:17 -070039int gpio_eth_irq;
40
Mark Brown768dec42008-04-15 15:50:49 +010041int wm9713_irq;
42
eric miao2c8086a2007-09-11 19:13:17 -070043int lcd_id;
44int lcd_orientation;
45
46static struct resource smc91x_resources[] = {
47 [0] = {
48 .start = ZYLONITE_ETH_PHYS + 0x300,
49 .end = ZYLONITE_ETH_PHYS + 0xfffff,
50 .flags = IORESOURCE_MEM,
51 },
52 [1] = {
53 .start = -1, /* for run-time assignment */
54 .end = -1,
Russell Kinge7b3dc72008-01-14 22:30:10 +000055 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
eric miao2c8086a2007-09-11 19:13:17 -070056 }
57};
58
59static struct platform_device smc91x_device = {
60 .name = "smc91x",
61 .id = 0,
62 .num_resources = ARRAY_SIZE(smc91x_resources),
63 .resource = smc91x_resources,
64};
65
eric miao7a987e82008-02-27 02:00:26 +010066#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
eric miao5cca9142008-04-13 21:46:34 +010067static struct platform_pwm_backlight_data zylonite_backlight_data = {
68 .pwm_id = 3,
69 .max_brightness = 100,
70 .dft_brightness = 100,
71 .pwm_period_ns = 10000,
72};
73
74static struct platform_device zylonite_backlight_device = {
75 .name = "pwm-backlight",
76 .dev = {
77 .parent = &pxa27x_device_pwm1.dev,
78 .platform_data = &zylonite_backlight_data,
79 },
80};
eric miao2c8086a2007-09-11 19:13:17 -070081
82static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
83 .pixclock = 110000,
84 .xres = 240,
85 .yres = 320,
86 .bpp = 16,
87 .hsync_len = 4,
88 .left_margin = 6,
89 .right_margin = 4,
90 .vsync_len = 2,
91 .upper_margin = 2,
92 .lower_margin = 3,
93 .sync = FB_SYNC_VERT_HIGH_ACT,
94};
95
96static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
97 .pixclock = 50000,
98 .xres = 640,
99 .yres = 480,
100 .bpp = 16,
101 .hsync_len = 1,
102 .left_margin = 0x9f,
103 .right_margin = 1,
104 .vsync_len = 44,
105 .upper_margin = 0,
106 .lower_margin = 0,
107 .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
108};
109
110static struct pxafb_mach_info zylonite_toshiba_lcd_info = {
111 .num_modes = 1,
eric miao0454bd02008-04-30 00:52:23 -0700112 .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
eric miao2c8086a2007-09-11 19:13:17 -0700113};
114
115static struct pxafb_mode_info sharp_ls037_modes[] = {
116 [0] = {
117 .pixclock = 158000,
118 .xres = 240,
119 .yres = 320,
120 .bpp = 16,
121 .hsync_len = 4,
122 .left_margin = 39,
123 .right_margin = 39,
124 .vsync_len = 1,
125 .upper_margin = 2,
126 .lower_margin = 3,
127 .sync = 0,
128 },
129 [1] = {
130 .pixclock = 39700,
131 .xres = 480,
132 .yres = 640,
133 .bpp = 16,
134 .hsync_len = 8,
135 .left_margin = 81,
136 .right_margin = 81,
137 .vsync_len = 1,
138 .upper_margin = 2,
139 .lower_margin = 7,
140 .sync = 0,
141 },
142};
143
144static struct pxafb_mach_info zylonite_sharp_lcd_info = {
145 .modes = sharp_ls037_modes,
146 .num_modes = 2,
eric miao0454bd02008-04-30 00:52:23 -0700147 .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
eric miao2c8086a2007-09-11 19:13:17 -0700148};
149
150static void __init zylonite_init_lcd(void)
151{
eric miao5cca9142008-04-13 21:46:34 +0100152 platform_device_register(&zylonite_backlight_device);
eric miao2c8086a2007-09-11 19:13:17 -0700153
154 if (lcd_id & 0x20) {
155 set_pxa_fb_info(&zylonite_sharp_lcd_info);
156 return;
157 }
158
159 /* legacy LCD panels, it would be handy here if LCD panel type can
160 * be decided at run-time
161 */
162 if (1)
163 zylonite_toshiba_lcd_info.modes = &toshiba_ltm035a776c_mode;
164 else
165 zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode;
166
167 set_pxa_fb_info(&zylonite_toshiba_lcd_info);
168}
169#else
170static inline void zylonite_init_lcd(void) {}
171#endif
172
Bridge Wufafc9d32007-12-21 19:00:13 +0800173#if defined(CONFIG_MMC)
174static int zylonite_mci_ro(struct device *dev)
175{
176 struct platform_device *pdev = to_platform_device(dev);
177
178 return gpio_get_value(zylonite_mmc_slot[pdev->id].gpio_wp);
179}
180
181static int zylonite_mci_init(struct device *dev,
182 irq_handler_t zylonite_detect_int,
183 void *data)
184{
185 struct platform_device *pdev = to_platform_device(dev);
186 int err, cd_irq, gpio_cd, gpio_wp;
187
188 cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
189 gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
190 gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
191
192 /*
193 * setup GPIO for Zylonite MMC controller
194 */
195 err = gpio_request(gpio_cd, "mmc card detect");
196 if (err)
197 goto err_request_cd;
198 gpio_direction_input(gpio_cd);
199
200 err = gpio_request(gpio_wp, "mmc write protect");
201 if (err)
202 goto err_request_wp;
203 gpio_direction_input(gpio_wp);
204
205 err = request_irq(cd_irq, zylonite_detect_int,
206 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
207 "MMC card detect", data);
208 if (err) {
209 printk(KERN_ERR "%s: MMC/SD/SDIO: "
210 "can't request card detect IRQ\n", __func__);
211 goto err_request_irq;
212 }
213
214 return 0;
215
216err_request_irq:
217 gpio_free(gpio_wp);
218err_request_wp:
219 gpio_free(gpio_cd);
220err_request_cd:
221 return err;
222}
223
224static void zylonite_mci_exit(struct device *dev, void *data)
225{
226 struct platform_device *pdev = to_platform_device(dev);
227 int cd_irq, gpio_cd, gpio_wp;
228
229 cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
230 gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
231 gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
232
233 free_irq(cd_irq, data);
234 gpio_free(gpio_cd);
235 gpio_free(gpio_wp);
236}
237
238static struct pxamci_platform_data zylonite_mci_platform_data = {
239 .detect_delay = 20,
240 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
241 .init = zylonite_mci_init,
242 .exit = zylonite_mci_exit,
243 .get_ro = zylonite_mci_ro,
244};
245
Bridge Wu8d33b052007-12-21 19:15:36 +0800246static struct pxamci_platform_data zylonite_mci2_platform_data = {
247 .detect_delay = 20,
248 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
249};
250
Bridge Wufafc9d32007-12-21 19:00:13 +0800251static void __init zylonite_init_mmc(void)
252{
253 pxa_set_mci_info(&zylonite_mci_platform_data);
Bridge Wu8d33b052007-12-21 19:15:36 +0800254 pxa3xx_set_mci2_info(&zylonite_mci2_platform_data);
Bridge Wu5a1f21b2007-12-21 19:27:08 +0800255 if (cpu_is_pxa310())
256 pxa3xx_set_mci3_info(&zylonite_mci_platform_data);
Bridge Wufafc9d32007-12-21 19:00:13 +0800257}
258#else
259static inline void zylonite_init_mmc(void) {}
260#endif
261
eric miao468e0862008-01-23 14:25:50 +0800262#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULES)
263static unsigned int zylonite_matrix_key_map[] = {
264 /* KEY(row, col, key_code) */
265 KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_C), KEY(0, 5, KEY_D),
266 KEY(1, 0, KEY_E), KEY(1, 1, KEY_F), KEY(1, 2, KEY_G), KEY(1, 5, KEY_H),
267 KEY(2, 0, KEY_I), KEY(2, 1, KEY_J), KEY(2, 2, KEY_K), KEY(2, 5, KEY_L),
268 KEY(3, 0, KEY_M), KEY(3, 1, KEY_N), KEY(3, 2, KEY_O), KEY(3, 5, KEY_P),
269 KEY(5, 0, KEY_Q), KEY(5, 1, KEY_R), KEY(5, 2, KEY_S), KEY(5, 5, KEY_T),
270 KEY(6, 0, KEY_U), KEY(6, 1, KEY_V), KEY(6, 2, KEY_W), KEY(6, 5, KEY_X),
271 KEY(7, 1, KEY_Y), KEY(7, 2, KEY_Z),
272
273 KEY(4, 4, KEY_0), KEY(1, 3, KEY_1), KEY(4, 1, KEY_2), KEY(1, 4, KEY_3),
274 KEY(2, 3, KEY_4), KEY(4, 2, KEY_5), KEY(2, 4, KEY_6), KEY(3, 3, KEY_7),
275 KEY(4, 3, KEY_8), KEY(3, 4, KEY_9),
276
277 KEY(4, 5, KEY_SPACE),
278 KEY(5, 3, KEY_KPASTERISK), /* * */
279 KEY(5, 4, KEY_KPDOT), /* #" */
280
281 KEY(0, 7, KEY_UP),
282 KEY(1, 7, KEY_DOWN),
283 KEY(2, 7, KEY_LEFT),
284 KEY(3, 7, KEY_RIGHT),
285 KEY(2, 6, KEY_HOME),
286 KEY(3, 6, KEY_END),
287 KEY(6, 4, KEY_DELETE),
288 KEY(6, 6, KEY_BACK),
289 KEY(6, 3, KEY_CAPSLOCK), /* KEY_LEFTSHIFT), */
290
291 KEY(4, 6, KEY_ENTER), /* scroll push */
292 KEY(5, 7, KEY_ENTER), /* keypad action */
293
294 KEY(0, 4, KEY_EMAIL),
295 KEY(5, 6, KEY_SEND),
296 KEY(4, 0, KEY_CALENDAR),
297 KEY(7, 6, KEY_RECORD),
298 KEY(6, 7, KEY_VOLUMEUP),
299 KEY(7, 7, KEY_VOLUMEDOWN),
300
301 KEY(0, 6, KEY_F22), /* soft1 */
302 KEY(1, 6, KEY_F23), /* soft2 */
303 KEY(0, 3, KEY_AUX), /* contact */
304};
305
306static struct pxa27x_keypad_platform_data zylonite_keypad_info = {
307 .matrix_key_rows = 8,
308 .matrix_key_cols = 8,
309 .matrix_key_map = zylonite_matrix_key_map,
310 .matrix_key_map_size = ARRAY_SIZE(zylonite_matrix_key_map),
311
312 .enable_rotary0 = 1,
313 .rotary0_up_key = KEY_UP,
314 .rotary0_down_key = KEY_DOWN,
315
316 .debounce_interval = 30,
317};
318
319static void __init zylonite_init_keypad(void)
320{
321 pxa_set_keypad_info(&zylonite_keypad_info);
322}
323#else
324static inline void zylonite_init_keypad(void) {}
325#endif
326
eric miao2c8086a2007-09-11 19:13:17 -0700327static void __init zylonite_init(void)
328{
329 /* board-processor specific initialization */
330 zylonite_pxa300_init();
331 zylonite_pxa320_init();
332
333 /*
334 * Note: We depend that the bootloader set
335 * the correct value to MSC register for SMC91x.
336 */
337 smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq);
338 smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq);
339 platform_device_register(&smc91x_device);
340
Mark Browncabb3522008-06-10 10:48:25 +0100341 pxa_set_ac97_info(NULL);
eric miao2c8086a2007-09-11 19:13:17 -0700342 zylonite_init_lcd();
Bridge Wufafc9d32007-12-21 19:00:13 +0800343 zylonite_init_mmc();
eric miao468e0862008-01-23 14:25:50 +0800344 zylonite_init_keypad();
eric miao2c8086a2007-09-11 19:13:17 -0700345}
346
347MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
348 .phys_io = 0x40000000,
349 .boot_params = 0xa0000100,
350 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
351 .map_io = pxa_map_io,
352 .init_irq = pxa3xx_init_irq,
353 .timer = &pxa_timer,
354 .init_machine = zylonite_init,
355MACHINE_END