Merge branch 'topic/nomm' into for-linus
[pandora-kernel.git] / arch / arm / mach-pxa / palmld.c
1 /*
2  * Hardware definitions for Palm LifeDrive
3  *
4  * Author:     Marek Vasut <marek.vasut@gmail.com>
5  *
6  * Based on work of:
7  *              Alex Osborne <ato@meshy.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  *
13  * (find more info at www.hackndev.com)
14  *
15  */
16
17 #include <linux/platform_device.h>
18 #include <linux/delay.h>
19 #include <linux/irq.h>
20 #include <linux/gpio_keys.h>
21 #include <linux/input.h>
22 #include <linux/pda_power.h>
23 #include <linux/pwm_backlight.h>
24 #include <linux/gpio.h>
25 #include <linux/wm97xx_batt.h>
26 #include <linux/power_supply.h>
27 #include <linux/sysdev.h>
28 #include <linux/mtd/mtd.h>
29 #include <linux/mtd/partitions.h>
30 #include <linux/mtd/physmap.h>
31
32 #include <asm/mach-types.h>
33 #include <asm/mach/arch.h>
34 #include <asm/mach/map.h>
35
36 #include <mach/pxa27x.h>
37 #include <mach/audio.h>
38 #include <mach/palmld.h>
39 #include <mach/mmc.h>
40 #include <mach/pxafb.h>
41 #include <mach/irda.h>
42 #include <mach/pxa27x_keypad.h>
43 #include <mach/palmasoc.h>
44
45 #include "generic.h"
46 #include "devices.h"
47
48 /******************************************************************************
49  * Pin configuration
50  ******************************************************************************/
51 static unsigned long palmld_pin_config[] __initdata = {
52         /* MMC */
53         GPIO32_MMC_CLK,
54         GPIO92_MMC_DAT_0,
55         GPIO109_MMC_DAT_1,
56         GPIO110_MMC_DAT_2,
57         GPIO111_MMC_DAT_3,
58         GPIO112_MMC_CMD,
59         GPIO14_GPIO,    /* SD detect */
60         GPIO114_GPIO,   /* SD power */
61         GPIO116_GPIO,   /* SD r/o switch */
62
63         /* AC97 */
64         GPIO28_AC97_BITCLK,
65         GPIO29_AC97_SDATA_IN_0,
66         GPIO30_AC97_SDATA_OUT,
67         GPIO31_AC97_SYNC,
68         GPIO89_AC97_SYSCLK,
69         GPIO95_AC97_nRESET,
70
71         /* IrDA */
72         GPIO108_GPIO,   /* ir disable */
73         GPIO46_FICP_RXD,
74         GPIO47_FICP_TXD,
75
76         /* MATRIX KEYPAD */
77         GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
78         GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
79         GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
80         GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
81         GPIO103_KP_MKOUT_0,
82         GPIO104_KP_MKOUT_1,
83         GPIO105_KP_MKOUT_2,
84
85         /* LCD */
86         GPIOxx_LCD_TFT_16BPP,
87
88         /* PWM */
89         GPIO16_PWM0_OUT,
90
91         /* GPIO KEYS */
92         GPIO10_GPIO,    /* hotsync button */
93         GPIO12_GPIO,    /* power switch */
94         GPIO15_GPIO,    /* lock switch */
95
96         /* LEDs */
97         GPIO52_GPIO,    /* green led */
98         GPIO94_GPIO,    /* orange led */
99
100         /* PCMCIA */
101         GPIO48_nPOE,
102         GPIO49_nPWE,
103         GPIO50_nPIOR,
104         GPIO51_nPIOW,
105         GPIO85_nPCE_1,
106         GPIO54_nPCE_2,
107         GPIO79_PSKTSEL,
108         GPIO55_nPREG,
109         GPIO56_nPWAIT,
110         GPIO57_nIOIS16,
111         GPIO36_GPIO,    /* wifi power */
112         GPIO38_GPIO,    /* wifi ready */
113         GPIO81_GPIO,    /* wifi reset */
114
115         /* FFUART */
116         GPIO34_FFUART_RXD,
117         GPIO39_FFUART_TXD,
118
119         /* HDD */
120         GPIO98_GPIO,    /* HDD reset */
121         GPIO115_GPIO,   /* HDD power */
122
123         /* MISC */
124         GPIO13_GPIO,    /* earphone detect */
125 };
126
127 /******************************************************************************
128  * NOR Flash
129  ******************************************************************************/
130 static struct mtd_partition palmld_partitions[] = {
131         {
132                 .name           = "Flash",
133                 .offset         = 0x00000000,
134                 .size           = MTDPART_SIZ_FULL,
135                 .mask_flags     = 0
136         }
137 };
138
139 static struct physmap_flash_data palmld_flash_data[] = {
140         {
141                 .width          = 2,                    /* bankwidth in bytes */
142                 .parts          = palmld_partitions,
143                 .nr_parts       = ARRAY_SIZE(palmld_partitions)
144         }
145 };
146
147 static struct resource palmld_flash_resource = {
148         .start  = PXA_CS0_PHYS,
149         .end    = PXA_CS0_PHYS + SZ_4M - 1,
150         .flags  = IORESOURCE_MEM,
151 };
152
153 static struct platform_device palmld_flash = {
154         .name           = "physmap-flash",
155         .id             = 0,
156         .resource       = &palmld_flash_resource,
157         .num_resources  = 1,
158         .dev            = {
159                 .platform_data = palmld_flash_data,
160         },
161 };
162
163 /******************************************************************************
164  * SD/MMC card controller
165  ******************************************************************************/
166 static struct pxamci_platform_data palmld_mci_platform_data = {
167         .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
168         .gpio_card_detect       = GPIO_NR_PALMLD_SD_DETECT_N,
169         .gpio_card_ro           = GPIO_NR_PALMLD_SD_READONLY,
170         .gpio_power             = GPIO_NR_PALMLD_SD_POWER,
171         .detect_delay           = 20,
172 };
173
174 /******************************************************************************
175  * GPIO keyboard
176  ******************************************************************************/
177 static unsigned int palmld_matrix_keys[] = {
178         KEY(0, 1, KEY_F2),
179         KEY(0, 2, KEY_UP),
180
181         KEY(1, 0, KEY_F3),
182         KEY(1, 1, KEY_F4),
183         KEY(1, 2, KEY_RIGHT),
184
185         KEY(2, 0, KEY_F1),
186         KEY(2, 1, KEY_F5),
187         KEY(2, 2, KEY_DOWN),
188
189         KEY(3, 0, KEY_F6),
190         KEY(3, 1, KEY_ENTER),
191         KEY(3, 2, KEY_LEFT),
192 };
193
194 static struct pxa27x_keypad_platform_data palmld_keypad_platform_data = {
195         .matrix_key_rows        = 4,
196         .matrix_key_cols        = 3,
197         .matrix_key_map         = palmld_matrix_keys,
198         .matrix_key_map_size    = ARRAY_SIZE(palmld_matrix_keys),
199
200         .debounce_interval      = 30,
201 };
202
203 /******************************************************************************
204  * GPIO keys
205  ******************************************************************************/
206 static struct gpio_keys_button palmld_pxa_buttons[] = {
207         {KEY_F8, GPIO_NR_PALMLD_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
208         {KEY_F9, GPIO_NR_PALMLD_LOCK_SWITCH, 0, "Lock Switch" },
209         {KEY_POWER, GPIO_NR_PALMLD_POWER_SWITCH, 0, "Power Switch" },
210 };
211
212 static struct gpio_keys_platform_data palmld_pxa_keys_data = {
213         .buttons        = palmld_pxa_buttons,
214         .nbuttons       = ARRAY_SIZE(palmld_pxa_buttons),
215 };
216
217 static struct platform_device palmld_pxa_keys = {
218         .name   = "gpio-keys",
219         .id     = -1,
220         .dev    = {
221                 .platform_data = &palmld_pxa_keys_data,
222         },
223 };
224
225 /******************************************************************************
226  * Backlight
227  ******************************************************************************/
228 static int palmld_backlight_init(struct device *dev)
229 {
230         int ret;
231
232         ret = gpio_request(GPIO_NR_PALMLD_BL_POWER, "BL POWER");
233         if (ret)
234                 goto err;
235         ret = gpio_direction_output(GPIO_NR_PALMLD_BL_POWER, 0);
236         if (ret)
237                 goto err2;
238         ret = gpio_request(GPIO_NR_PALMLD_LCD_POWER, "LCD POWER");
239         if (ret)
240                 goto err2;
241         ret = gpio_direction_output(GPIO_NR_PALMLD_LCD_POWER, 0);
242         if (ret)
243                 goto err3;
244
245         return 0;
246 err3:
247         gpio_free(GPIO_NR_PALMLD_LCD_POWER);
248 err2:
249         gpio_free(GPIO_NR_PALMLD_BL_POWER);
250 err:
251         return ret;
252 }
253
254 static int palmld_backlight_notify(struct device *dev, int brightness)
255 {
256         gpio_set_value(GPIO_NR_PALMLD_BL_POWER, brightness);
257         gpio_set_value(GPIO_NR_PALMLD_LCD_POWER, brightness);
258         return brightness;
259 }
260
261 static void palmld_backlight_exit(struct device *dev)
262 {
263         gpio_free(GPIO_NR_PALMLD_BL_POWER);
264         gpio_free(GPIO_NR_PALMLD_LCD_POWER);
265 }
266
267 static struct platform_pwm_backlight_data palmld_backlight_data = {
268         .pwm_id         = 0,
269         .max_brightness = PALMLD_MAX_INTENSITY,
270         .dft_brightness = PALMLD_MAX_INTENSITY,
271         .pwm_period_ns  = PALMLD_PERIOD_NS,
272         .init           = palmld_backlight_init,
273         .notify         = palmld_backlight_notify,
274         .exit           = palmld_backlight_exit,
275 };
276
277 static struct platform_device palmld_backlight = {
278         .name   = "pwm-backlight",
279         .dev    = {
280                 .parent         = &pxa27x_device_pwm0.dev,
281                 .platform_data  = &palmld_backlight_data,
282         },
283 };
284
285 /******************************************************************************
286  * IrDA
287  ******************************************************************************/
288 static struct pxaficp_platform_data palmld_ficp_platform_data = {
289         .gpio_pwdown            = GPIO_NR_PALMLD_IR_DISABLE,
290         .transceiver_cap        = IR_SIRMODE | IR_OFF,
291 };
292
293 /******************************************************************************
294  * LEDs
295  ******************************************************************************/
296 struct gpio_led gpio_leds[] = {
297 {
298         .name                   = "palmld:green:led",
299         .default_trigger        = "none",
300         .gpio                   = GPIO_NR_PALMLD_LED_GREEN,
301 }, {
302         .name                   = "palmld:amber:led",
303         .default_trigger        = "none",
304         .gpio                   = GPIO_NR_PALMLD_LED_AMBER,
305 },
306 };
307
308 static struct gpio_led_platform_data gpio_led_info = {
309         .leds           = gpio_leds,
310         .num_leds       = ARRAY_SIZE(gpio_leds),
311 };
312
313 static struct platform_device palmld_leds = {
314         .name   = "leds-gpio",
315         .id     = -1,
316         .dev    = {
317                 .platform_data  = &gpio_led_info,
318         }
319 };
320
321 /******************************************************************************
322  * Power supply
323  ******************************************************************************/
324 static int power_supply_init(struct device *dev)
325 {
326         int ret;
327
328         ret = gpio_request(GPIO_NR_PALMLD_POWER_DETECT, "CABLE_STATE_AC");
329         if (ret)
330                 goto err1;
331         ret = gpio_direction_input(GPIO_NR_PALMLD_POWER_DETECT);
332         if (ret)
333                 goto err2;
334
335         ret = gpio_request(GPIO_NR_PALMLD_USB_DETECT_N, "CABLE_STATE_USB");
336         if (ret)
337                 goto err2;
338         ret = gpio_direction_input(GPIO_NR_PALMLD_USB_DETECT_N);
339         if (ret)
340                 goto err3;
341
342         return 0;
343
344 err3:
345         gpio_free(GPIO_NR_PALMLD_USB_DETECT_N);
346 err2:
347         gpio_free(GPIO_NR_PALMLD_POWER_DETECT);
348 err1:
349         return ret;
350 }
351
352 static int palmld_is_ac_online(void)
353 {
354         return gpio_get_value(GPIO_NR_PALMLD_POWER_DETECT);
355 }
356
357 static int palmld_is_usb_online(void)
358 {
359         return !gpio_get_value(GPIO_NR_PALMLD_USB_DETECT_N);
360 }
361
362 static void power_supply_exit(struct device *dev)
363 {
364         gpio_free(GPIO_NR_PALMLD_USB_DETECT_N);
365         gpio_free(GPIO_NR_PALMLD_POWER_DETECT);
366 }
367
368 static char *palmld_supplicants[] = {
369         "main-battery",
370 };
371
372 static struct pda_power_pdata power_supply_info = {
373         .init            = power_supply_init,
374         .is_ac_online    = palmld_is_ac_online,
375         .is_usb_online   = palmld_is_usb_online,
376         .exit            = power_supply_exit,
377         .supplied_to     = palmld_supplicants,
378         .num_supplicants = ARRAY_SIZE(palmld_supplicants),
379 };
380
381 static struct platform_device power_supply = {
382         .name = "pda-power",
383         .id   = -1,
384         .dev  = {
385                 .platform_data = &power_supply_info,
386         },
387 };
388
389 /******************************************************************************
390  * WM97xx battery
391  ******************************************************************************/
392 static struct wm97xx_batt_info wm97xx_batt_pdata = {
393         .batt_aux       = WM97XX_AUX_ID3,
394         .temp_aux       = WM97XX_AUX_ID2,
395         .charge_gpio    = -1,
396         .max_voltage    = PALMLD_BAT_MAX_VOLTAGE,
397         .min_voltage    = PALMLD_BAT_MIN_VOLTAGE,
398         .batt_mult      = 1000,
399         .batt_div       = 414,
400         .temp_mult      = 1,
401         .temp_div       = 1,
402         .batt_tech      = POWER_SUPPLY_TECHNOLOGY_LIPO,
403         .batt_name      = "main-batt",
404 };
405
406 /******************************************************************************
407  * aSoC audio
408  ******************************************************************************/
409 static struct palm27x_asoc_info palmld_asoc_pdata = {
410         .jack_gpio      = GPIO_NR_PALMLD_EARPHONE_DETECT,
411 };
412
413 static pxa2xx_audio_ops_t palmld_ac97_pdata = {
414         .reset_gpio     = 95,
415 };
416
417 static struct platform_device palmld_asoc = {
418         .name = "palm27x-asoc",
419         .id   = -1,
420         .dev  = {
421                 .platform_data = &palmld_asoc_pdata,
422         },
423 };
424
425 /******************************************************************************
426  * HDD
427  ******************************************************************************/
428 static struct platform_device palmld_hdd = {
429         .name   = "pata_palmld",
430         .id     = -1,
431 };
432
433 /******************************************************************************
434  * Framebuffer
435  ******************************************************************************/
436 static struct pxafb_mode_info palmld_lcd_modes[] = {
437 {
438         .pixclock       = 57692,
439         .xres           = 320,
440         .yres           = 480,
441         .bpp            = 16,
442
443         .left_margin    = 32,
444         .right_margin   = 1,
445         .upper_margin   = 7,
446         .lower_margin   = 1,
447
448         .hsync_len      = 4,
449         .vsync_len      = 1,
450 },
451 };
452
453 static struct pxafb_mach_info palmld_lcd_screen = {
454         .modes          = palmld_lcd_modes,
455         .num_modes      = ARRAY_SIZE(palmld_lcd_modes),
456         .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
457 };
458
459 /******************************************************************************
460  * Power management - standby
461  ******************************************************************************/
462 static void __init palmld_pm_init(void)
463 {
464         static u32 resume[] = {
465                 0xe3a00101,     /* mov  r0,     #0x40000000 */
466                 0xe380060f,     /* orr  r0, r0, #0x00f00000 */
467                 0xe590f008,     /* ldr  pc, [r0, #0x08] */
468         };
469
470         /* copy the bootloader */
471         memcpy(phys_to_virt(PALMLD_STR_BASE), resume, sizeof(resume));
472 }
473
474 /******************************************************************************
475  * Machine init
476  ******************************************************************************/
477 static struct platform_device *devices[] __initdata = {
478 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
479         &palmld_pxa_keys,
480 #endif
481         &palmld_backlight,
482         &palmld_leds,
483         &power_supply,
484         &palmld_asoc,
485         &palmld_hdd,
486         &palmld_flash,
487 };
488
489 static struct map_desc palmld_io_desc[] __initdata = {
490 {
491         .virtual        = PALMLD_IDE_VIRT,
492         .pfn            = __phys_to_pfn(PALMLD_IDE_PHYS),
493         .length         = PALMLD_IDE_SIZE,
494         .type           = MT_DEVICE
495 },
496 {
497         .virtual        = PALMLD_USB_VIRT,
498         .pfn            = __phys_to_pfn(PALMLD_USB_PHYS),
499         .length         = PALMLD_USB_SIZE,
500         .type           = MT_DEVICE
501 },
502 };
503
504 static void __init palmld_map_io(void)
505 {
506         pxa_map_io();
507         iotable_init(palmld_io_desc, ARRAY_SIZE(palmld_io_desc));
508 }
509
510 static void __init palmld_init(void)
511 {
512         pxa2xx_mfp_config(ARRAY_AND_SIZE(palmld_pin_config));
513
514         pxa_set_ffuart_info(NULL);
515         pxa_set_btuart_info(NULL);
516         pxa_set_stuart_info(NULL);
517
518         palmld_pm_init();
519         set_pxa_fb_info(&palmld_lcd_screen);
520         pxa_set_mci_info(&palmld_mci_platform_data);
521         pxa_set_ac97_info(&palmld_ac97_pdata);
522         pxa_set_ficp_info(&palmld_ficp_platform_data);
523         pxa_set_keypad_info(&palmld_keypad_platform_data);
524         wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
525
526         platform_add_devices(devices, ARRAY_SIZE(devices));
527 }
528
529 MACHINE_START(PALMLD, "Palm LifeDrive")
530         .phys_io        = PALMLD_PHYS_IO_START,
531         .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
532         .boot_params    = 0xa0000100,
533         .map_io         = palmld_map_io,
534         .init_irq       = pxa27x_init_irq,
535         .timer          = &pxa_timer,
536         .init_machine   = palmld_init
537 MACHINE_END