[ARM] pxa/palm: add NAND Flash support for PalmTX
[safe/jmp/linux-2.6] / arch / arm / mach-pxa / palmtx.c
1 /*
2  * Hardware definitions for PalmTX
3  *
4  * Author:     Marek Vasut <marek.vasut@gmail.com>
5  *
6  * Based on work of:
7  *              Alex Osborne <ato@meshy.org>
8  *              Cristiano P. <cristianop@users.sourceforge.net>
9  *              Jan Herman <2hp@seznam.cz>
10  *              Michal Hrusecky
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  *
16  * (find more info at www.hackndev.com)
17  *
18  */
19
20 #include <linux/platform_device.h>
21 #include <linux/delay.h>
22 #include <linux/irq.h>
23 #include <linux/gpio_keys.h>
24 #include <linux/input.h>
25 #include <linux/pda_power.h>
26 #include <linux/pwm_backlight.h>
27 #include <linux/gpio.h>
28 #include <linux/wm97xx_batt.h>
29 #include <linux/power_supply.h>
30 #include <linux/usb/gpio_vbus.h>
31 #include <linux/mtd/nand.h>
32 #include <linux/mtd/partitions.h>
33
34 #include <asm/mach-types.h>
35 #include <asm/mach/arch.h>
36 #include <asm/mach/map.h>
37
38 #include <mach/pxa27x.h>
39 #include <mach/audio.h>
40 #include <mach/palmtx.h>
41 #include <mach/mmc.h>
42 #include <mach/pxafb.h>
43 #include <mach/irda.h>
44 #include <mach/pxa27x_keypad.h>
45 #include <mach/udc.h>
46 #include <mach/palmasoc.h>
47
48 #include "generic.h"
49 #include "devices.h"
50
51 /******************************************************************************
52  * Pin configuration
53  ******************************************************************************/
54 static unsigned long palmtx_pin_config[] __initdata = {
55         /* MMC */
56         GPIO32_MMC_CLK,
57         GPIO92_MMC_DAT_0,
58         GPIO109_MMC_DAT_1,
59         GPIO110_MMC_DAT_2,
60         GPIO111_MMC_DAT_3,
61         GPIO112_MMC_CMD,
62         GPIO14_GPIO,    /* SD detect */
63         GPIO114_GPIO,   /* SD power */
64         GPIO115_GPIO,   /* SD r/o switch */
65
66         /* AC97 */
67         GPIO28_AC97_BITCLK,
68         GPIO29_AC97_SDATA_IN_0,
69         GPIO30_AC97_SDATA_OUT,
70         GPIO31_AC97_SYNC,
71         GPIO89_AC97_SYSCLK,
72         GPIO95_AC97_nRESET,
73
74         /* IrDA */
75         GPIO40_GPIO,    /* ir disable */
76         GPIO46_FICP_RXD,
77         GPIO47_FICP_TXD,
78
79         /* PWM */
80         GPIO16_PWM0_OUT,
81
82         /* USB */
83         GPIO13_GPIO,    /* usb detect */
84         GPIO93_GPIO,    /* usb power */
85
86         /* PCMCIA */
87         GPIO48_nPOE,
88         GPIO49_nPWE,
89         GPIO50_nPIOR,
90         GPIO51_nPIOW,
91         GPIO85_nPCE_1,
92         GPIO54_nPCE_2,
93         GPIO79_PSKTSEL,
94         GPIO55_nPREG,
95         GPIO56_nPWAIT,
96         GPIO57_nIOIS16,
97         GPIO94_GPIO,    /* wifi power 1 */
98         GPIO108_GPIO,   /* wifi power 2 */
99         GPIO116_GPIO,   /* wifi ready */
100
101         /* MATRIX KEYPAD */
102         GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
103         GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
104         GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
105         GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
106         GPIO103_KP_MKOUT_0,
107         GPIO104_KP_MKOUT_1,
108         GPIO105_KP_MKOUT_2,
109
110         /* LCD */
111         GPIO58_LCD_LDD_0,
112         GPIO59_LCD_LDD_1,
113         GPIO60_LCD_LDD_2,
114         GPIO61_LCD_LDD_3,
115         GPIO62_LCD_LDD_4,
116         GPIO63_LCD_LDD_5,
117         GPIO64_LCD_LDD_6,
118         GPIO65_LCD_LDD_7,
119         GPIO66_LCD_LDD_8,
120         GPIO67_LCD_LDD_9,
121         GPIO68_LCD_LDD_10,
122         GPIO69_LCD_LDD_11,
123         GPIO70_LCD_LDD_12,
124         GPIO71_LCD_LDD_13,
125         GPIO72_LCD_LDD_14,
126         GPIO73_LCD_LDD_15,
127         GPIO74_LCD_FCLK,
128         GPIO75_LCD_LCLK,
129         GPIO76_LCD_PCLK,
130         GPIO77_LCD_BIAS,
131
132         /* FFUART */
133         GPIO34_FFUART_RXD,
134         GPIO39_FFUART_TXD,
135
136         /* NAND */
137         GPIO15_nCS_1,
138         GPIO18_RDY,
139
140         /* MISC. */
141         GPIO10_GPIO,    /* hotsync button */
142         GPIO12_GPIO,    /* power detect */
143         GPIO107_GPIO,   /* earphone detect */
144 };
145
146 /******************************************************************************
147  * SD/MMC card controller
148  ******************************************************************************/
149 static struct pxamci_platform_data palmtx_mci_platform_data = {
150         .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
151         .gpio_card_detect       = GPIO_NR_PALMTX_SD_DETECT_N,
152         .gpio_card_ro           = GPIO_NR_PALMTX_SD_READONLY,
153         .gpio_power             = GPIO_NR_PALMTX_SD_POWER,
154         .detect_delay           = 20,
155 };
156
157 /******************************************************************************
158  * GPIO keyboard
159  ******************************************************************************/
160 static unsigned int palmtx_matrix_keys[] = {
161         KEY(0, 0, KEY_POWER),
162         KEY(0, 1, KEY_F1),
163         KEY(0, 2, KEY_ENTER),
164
165         KEY(1, 0, KEY_F2),
166         KEY(1, 1, KEY_F3),
167         KEY(1, 2, KEY_F4),
168
169         KEY(2, 0, KEY_UP),
170         KEY(2, 2, KEY_DOWN),
171
172         KEY(3, 0, KEY_RIGHT),
173         KEY(3, 2, KEY_LEFT),
174 };
175
176 static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = {
177         .matrix_key_rows        = 4,
178         .matrix_key_cols        = 3,
179         .matrix_key_map         = palmtx_matrix_keys,
180         .matrix_key_map_size    = ARRAY_SIZE(palmtx_matrix_keys),
181
182         .debounce_interval      = 30,
183 };
184
185 /******************************************************************************
186  * GPIO keys
187  ******************************************************************************/
188 static struct gpio_keys_button palmtx_pxa_buttons[] = {
189         {KEY_F8, GPIO_NR_PALMTX_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
190 };
191
192 static struct gpio_keys_platform_data palmtx_pxa_keys_data = {
193         .buttons        = palmtx_pxa_buttons,
194         .nbuttons       = ARRAY_SIZE(palmtx_pxa_buttons),
195 };
196
197 static struct platform_device palmtx_pxa_keys = {
198         .name   = "gpio-keys",
199         .id     = -1,
200         .dev    = {
201                 .platform_data = &palmtx_pxa_keys_data,
202         },
203 };
204
205 /******************************************************************************
206  * Backlight
207  ******************************************************************************/
208 static int palmtx_backlight_init(struct device *dev)
209 {
210         int ret;
211
212         ret = gpio_request(GPIO_NR_PALMTX_BL_POWER, "BL POWER");
213         if (ret)
214                 goto err;
215         ret = gpio_direction_output(GPIO_NR_PALMTX_BL_POWER, 0);
216         if (ret)
217                 goto err2;
218         ret = gpio_request(GPIO_NR_PALMTX_LCD_POWER, "LCD POWER");
219         if (ret)
220                 goto err2;
221         ret = gpio_direction_output(GPIO_NR_PALMTX_LCD_POWER, 0);
222         if (ret)
223                 goto err3;
224
225         return 0;
226 err3:
227         gpio_free(GPIO_NR_PALMTX_LCD_POWER);
228 err2:
229         gpio_free(GPIO_NR_PALMTX_BL_POWER);
230 err:
231         return ret;
232 }
233
234 static int palmtx_backlight_notify(int brightness)
235 {
236         gpio_set_value(GPIO_NR_PALMTX_BL_POWER, brightness);
237         gpio_set_value(GPIO_NR_PALMTX_LCD_POWER, brightness);
238         return brightness;
239 }
240
241 static void palmtx_backlight_exit(struct device *dev)
242 {
243         gpio_free(GPIO_NR_PALMTX_BL_POWER);
244         gpio_free(GPIO_NR_PALMTX_LCD_POWER);
245 }
246
247 static struct platform_pwm_backlight_data palmtx_backlight_data = {
248         .pwm_id         = 0,
249         .max_brightness = PALMTX_MAX_INTENSITY,
250         .dft_brightness = PALMTX_MAX_INTENSITY,
251         .pwm_period_ns  = PALMTX_PERIOD_NS,
252         .init           = palmtx_backlight_init,
253         .notify         = palmtx_backlight_notify,
254         .exit           = palmtx_backlight_exit,
255 };
256
257 static struct platform_device palmtx_backlight = {
258         .name   = "pwm-backlight",
259         .dev    = {
260                 .parent         = &pxa27x_device_pwm0.dev,
261                 .platform_data  = &palmtx_backlight_data,
262         },
263 };
264
265 /******************************************************************************
266  * IrDA
267  ******************************************************************************/
268 static int palmtx_irda_startup(struct device *dev)
269 {
270         int err;
271         err = gpio_request(GPIO_NR_PALMTX_IR_DISABLE, "IR DISABLE");
272         if (err)
273                 goto err;
274         err = gpio_direction_output(GPIO_NR_PALMTX_IR_DISABLE, 1);
275         if (err)
276                 gpio_free(GPIO_NR_PALMTX_IR_DISABLE);
277 err:
278         return err;
279 }
280
281 static void palmtx_irda_shutdown(struct device *dev)
282 {
283         gpio_free(GPIO_NR_PALMTX_IR_DISABLE);
284 }
285
286 static void palmtx_irda_transceiver_mode(struct device *dev, int mode)
287 {
288         gpio_set_value(GPIO_NR_PALMTX_IR_DISABLE, mode & IR_OFF);
289         pxa2xx_transceiver_mode(dev, mode);
290 }
291
292 static struct pxaficp_platform_data palmtx_ficp_platform_data = {
293         .startup                = palmtx_irda_startup,
294         .shutdown               = palmtx_irda_shutdown,
295         .transceiver_cap        = IR_SIRMODE | IR_FIRMODE | IR_OFF,
296         .transceiver_mode       = palmtx_irda_transceiver_mode,
297 };
298
299 /******************************************************************************
300  * UDC
301  ******************************************************************************/
302 static struct gpio_vbus_mach_info palmtx_udc_info = {
303         .gpio_vbus              = GPIO_NR_PALMTX_USB_DETECT_N,
304         .gpio_vbus_inverted     = 1,
305         .gpio_pullup            = GPIO_NR_PALMTX_USB_PULLUP,
306 };
307
308 static struct platform_device palmtx_gpio_vbus = {
309         .name   = "gpio-vbus",
310         .id     = -1,
311         .dev    = {
312                 .platform_data  = &palmtx_udc_info,
313         },
314 };
315
316 /******************************************************************************
317  * Power supply
318  ******************************************************************************/
319 static int power_supply_init(struct device *dev)
320 {
321         int ret;
322
323         ret = gpio_request(GPIO_NR_PALMTX_POWER_DETECT, "CABLE_STATE_AC");
324         if (ret)
325                 goto err1;
326         ret = gpio_direction_input(GPIO_NR_PALMTX_POWER_DETECT);
327         if (ret)
328                 goto err2;
329
330         return 0;
331
332 err2:
333         gpio_free(GPIO_NR_PALMTX_POWER_DETECT);
334 err1:
335         return ret;
336 }
337
338 static int palmtx_is_ac_online(void)
339 {
340         return gpio_get_value(GPIO_NR_PALMTX_POWER_DETECT);
341 }
342
343 static void power_supply_exit(struct device *dev)
344 {
345         gpio_free(GPIO_NR_PALMTX_POWER_DETECT);
346 }
347
348 static char *palmtx_supplicants[] = {
349         "main-battery",
350 };
351
352 static struct pda_power_pdata power_supply_info = {
353         .init            = power_supply_init,
354         .is_ac_online    = palmtx_is_ac_online,
355         .exit            = power_supply_exit,
356         .supplied_to     = palmtx_supplicants,
357         .num_supplicants = ARRAY_SIZE(palmtx_supplicants),
358 };
359
360 static struct platform_device power_supply = {
361         .name = "pda-power",
362         .id   = -1,
363         .dev  = {
364                 .platform_data = &power_supply_info,
365         },
366 };
367
368 /******************************************************************************
369  * WM97xx battery
370  ******************************************************************************/
371 static struct wm97xx_batt_info wm97xx_batt_pdata = {
372         .batt_aux       = WM97XX_AUX_ID3,
373         .temp_aux       = WM97XX_AUX_ID2,
374         .charge_gpio    = -1,
375         .max_voltage    = PALMTX_BAT_MAX_VOLTAGE,
376         .min_voltage    = PALMTX_BAT_MIN_VOLTAGE,
377         .batt_mult      = 1000,
378         .batt_div       = 414,
379         .temp_mult      = 1,
380         .temp_div       = 1,
381         .batt_tech      = POWER_SUPPLY_TECHNOLOGY_LIPO,
382         .batt_name      = "main-batt",
383 };
384
385 /******************************************************************************
386  * aSoC audio
387  ******************************************************************************/
388 static struct palm27x_asoc_info palmtx_asoc_pdata = {
389         .jack_gpio      = GPIO_NR_PALMTX_EARPHONE_DETECT,
390 };
391
392 static pxa2xx_audio_ops_t palmtx_ac97_pdata = {
393         .reset_gpio     = 95,
394 };
395
396 static struct platform_device palmtx_asoc = {
397         .name = "palm27x-asoc",
398         .id   = -1,
399         .dev  = {
400                 .platform_data = &palmtx_asoc_pdata,
401         },
402 };
403
404 /******************************************************************************
405  * Framebuffer
406  ******************************************************************************/
407 static struct pxafb_mode_info palmtx_lcd_modes[] = {
408 {
409         .pixclock       = 57692,
410         .xres           = 320,
411         .yres           = 480,
412         .bpp            = 16,
413
414         .left_margin    = 32,
415         .right_margin   = 1,
416         .upper_margin   = 7,
417         .lower_margin   = 1,
418
419         .hsync_len      = 4,
420         .vsync_len      = 1,
421 },
422 };
423
424 static struct pxafb_mach_info palmtx_lcd_screen = {
425         .modes          = palmtx_lcd_modes,
426         .num_modes      = ARRAY_SIZE(palmtx_lcd_modes),
427         .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
428 };
429
430 /******************************************************************************
431  * NAND Flash
432  ******************************************************************************/
433 static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
434                                  unsigned int ctrl)
435 {
436         struct nand_chip *this = mtd->priv;
437         unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
438
439         if (cmd == NAND_CMD_NONE)
440                 return;
441
442         if (ctrl & NAND_CLE)
443                 writeb(cmd, PALMTX_NAND_CLE_VIRT);
444         else if (ctrl & NAND_ALE)
445                 writeb(cmd, PALMTX_NAND_ALE_VIRT);
446         else
447                 writeb(cmd, nandaddr);
448 }
449
450 static struct mtd_partition palmtx_partition_info[] = {
451         [0] = {
452                 .name   = "palmtx-0",
453                 .offset = 0,
454                 .size   = MTDPART_SIZ_FULL
455         },
456 };
457
458 static const char *palmtx_part_probes[] = { "cmdlinepart", NULL };
459
460 struct platform_nand_data palmtx_nand_platdata = {
461         .chip   = {
462                 .nr_chips               = 1,
463                 .chip_offset            = 0,
464                 .nr_partitions          = ARRAY_SIZE(palmtx_partition_info),
465                 .partitions             = palmtx_partition_info,
466                 .chip_delay             = 20,
467                 .part_probe_types       = palmtx_part_probes,
468         },
469         .ctrl   = {
470                 .cmd_ctrl       = palmtx_nand_cmd_ctl,
471         },
472 };
473
474 static struct resource palmtx_nand_resource[] = {
475         [0]     = {
476                 .start  = PXA_CS1_PHYS,
477                 .end    = PXA_CS1_PHYS + SZ_1M - 1,
478                 .flags  = IORESOURCE_MEM,
479         },
480 };
481
482 static struct platform_device palmtx_nand = {
483         .name           = "gen_nand",
484         .num_resources  = ARRAY_SIZE(palmtx_nand_resource),
485         .resource       = palmtx_nand_resource,
486         .id             = -1,
487         .dev            = {
488                 .platform_data  = &palmtx_nand_platdata,
489         }
490 };
491
492 /******************************************************************************
493  * Power management - standby
494  ******************************************************************************/
495 static void __init palmtx_pm_init(void)
496 {
497         static u32 resume[] = {
498                 0xe3a00101,     /* mov  r0,     #0x40000000 */
499                 0xe380060f,     /* orr  r0, r0, #0x00f00000 */
500                 0xe590f008,     /* ldr  pc, [r0, #0x08] */
501         };
502
503         /* copy the bootloader */
504         memcpy(phys_to_virt(PALMTX_STR_BASE), resume, sizeof(resume));
505 }
506
507 /******************************************************************************
508  * Machine init
509  ******************************************************************************/
510 static struct platform_device *devices[] __initdata = {
511 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
512         &palmtx_pxa_keys,
513 #endif
514         &palmtx_backlight,
515         &power_supply,
516         &palmtx_asoc,
517         &palmtx_gpio_vbus,
518         &palmtx_nand,
519 };
520
521 static struct map_desc palmtx_io_desc[] __initdata = {
522 {
523         .virtual        = PALMTX_PCMCIA_VIRT,
524         .pfn            = __phys_to_pfn(PALMTX_PCMCIA_PHYS),
525         .length         = PALMTX_PCMCIA_SIZE,
526         .type           = MT_DEVICE,
527 }, {
528         .virtual        = PALMTX_NAND_ALE_VIRT,
529         .pfn            = __phys_to_pfn(PALMTX_NAND_ALE_PHYS),
530         .length         = SZ_1M,
531         .type           = MT_DEVICE,
532 }, {
533         .virtual        = PALMTX_NAND_CLE_VIRT,
534         .pfn            = __phys_to_pfn(PALMTX_NAND_CLE_PHYS),
535         .length         = SZ_1M,
536         .type           = MT_DEVICE,
537 }
538 };
539
540 static void __init palmtx_map_io(void)
541 {
542         pxa_map_io();
543         iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc));
544 }
545
546 /* setup udc GPIOs initial state */
547 static void __init palmtx_udc_init(void)
548 {
549         if (!gpio_request(GPIO_NR_PALMTX_USB_PULLUP, "UDC Vbus")) {
550                 gpio_direction_output(GPIO_NR_PALMTX_USB_PULLUP, 1);
551                 gpio_free(GPIO_NR_PALMTX_USB_PULLUP);
552         }
553 }
554
555
556 static void __init palmtx_init(void)
557 {
558         pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config));
559
560         palmtx_pm_init();
561         set_pxa_fb_info(&palmtx_lcd_screen);
562         pxa_set_mci_info(&palmtx_mci_platform_data);
563         palmtx_udc_init();
564         pxa_set_ac97_info(&palmtx_ac97_pdata);
565         pxa_set_ficp_info(&palmtx_ficp_platform_data);
566         pxa_set_keypad_info(&palmtx_keypad_platform_data);
567         wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
568
569         platform_add_devices(devices, ARRAY_SIZE(devices));
570 }
571
572 MACHINE_START(PALMTX, "Palm T|X")
573         .phys_io        = PALMTX_PHYS_IO_START,
574         .io_pg_offst    = io_p2v(0x40000000),
575         .boot_params    = 0xa0000100,
576         .map_io         = palmtx_map_io,
577         .init_irq       = pxa27x_init_irq,
578         .timer          = &pxa_timer,
579         .init_machine   = palmtx_init
580 MACHINE_END