[ARM] pxa: Palm Tungsten E2 basic support
[linux-2.6-block.git] / arch / arm / mach-pxa / palmte2.c
1 /*
2  * Hardware definitions for Palm Tungsten|E2
3  *
4  * Author:
5  *      Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.com>
6  *
7  * Rewrite for mainline:
8  *      Marek Vasut <marek.vasut@gmail.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * (find more info at www.hackndev.com)
15  *
16  */
17
18 #include <linux/platform_device.h>
19 #include <linux/delay.h>
20 #include <linux/irq.h>
21 #include <linux/gpio_keys.h>
22 #include <linux/input.h>
23 #include <linux/pwm_backlight.h>
24 #include <linux/gpio.h>
25
26 #include <asm/mach-types.h>
27 #include <asm/mach/arch.h>
28 #include <asm/mach/map.h>
29
30 #include <mach/audio.h>
31 #include <mach/palmte2.h>
32 #include <mach/mmc.h>
33 #include <mach/pxafb.h>
34 #include <mach/mfp-pxa25x.h>
35
36 #include "generic.h"
37 #include "devices.h"
38
39 /******************************************************************************
40  * Pin configuration
41  ******************************************************************************/
42 static unsigned long palmte2_pin_config[] __initdata = {
43         /* MMC */
44         GPIO6_MMC_CLK,
45         GPIO8_MMC_CS0,
46         GPIO10_GPIO,    /* SD detect */
47         GPIO55_GPIO,    /* SD power */
48         GPIO51_GPIO,    /* SD r/o switch */
49
50         /* AC97 */
51         GPIO28_AC97_BITCLK,
52         GPIO29_AC97_SDATA_IN_0,
53         GPIO30_AC97_SDATA_OUT,
54         GPIO31_AC97_SYNC,
55
56         /* PWM */
57         GPIO16_PWM0_OUT,
58
59         /* LCD */
60         GPIO58_LCD_LDD_0,
61         GPIO59_LCD_LDD_1,
62         GPIO60_LCD_LDD_2,
63         GPIO61_LCD_LDD_3,
64         GPIO62_LCD_LDD_4,
65         GPIO63_LCD_LDD_5,
66         GPIO64_LCD_LDD_6,
67         GPIO65_LCD_LDD_7,
68         GPIO66_LCD_LDD_8,
69         GPIO67_LCD_LDD_9,
70         GPIO68_LCD_LDD_10,
71         GPIO69_LCD_LDD_11,
72         GPIO70_LCD_LDD_12,
73         GPIO71_LCD_LDD_13,
74         GPIO72_LCD_LDD_14,
75         GPIO73_LCD_LDD_15,
76         GPIO74_LCD_FCLK,
77         GPIO75_LCD_LCLK,
78         GPIO76_LCD_PCLK,
79
80         /* GPIO KEYS */
81         GPIO5_GPIO,     /* notes */
82         GPIO7_GPIO,     /* tasks */
83         GPIO11_GPIO,    /* calendar */
84         GPIO13_GPIO,    /* contacts */
85         GPIO14_GPIO,    /* center */
86         GPIO19_GPIO,    /* left */
87         GPIO20_GPIO,    /* right */
88         GPIO21_GPIO,    /* down */
89         GPIO22_GPIO,    /* up */
90
91         /* MISC */
92         GPIO1_RST,      /* reset */
93 };
94
95 /******************************************************************************
96  * SD/MMC card controller
97  ******************************************************************************/
98 static int palmte2_mci_init(struct device *dev,
99                                 irq_handler_t palmte2_detect_int, void *data)
100 {
101         int err = 0;
102
103         /* Setup an interrupt for detecting card insert/remove events */
104         err = gpio_request(GPIO_NR_PALMTE2_SD_DETECT_N, "SD IRQ");
105         if (err)
106                 goto err;
107         err = gpio_direction_input(GPIO_NR_PALMTE2_SD_DETECT_N);
108         if (err)
109                 goto err2;
110         err = request_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N),
111                         palmte2_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
112                         IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
113                         "SD/MMC card detect", data);
114         if (err) {
115                 printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
116                                 __func__);
117                 goto err2;
118         }
119
120         err = gpio_request(GPIO_NR_PALMTE2_SD_POWER, "SD_POWER");
121         if (err)
122                 goto err3;
123         err = gpio_direction_output(GPIO_NR_PALMTE2_SD_POWER, 0);
124         if (err)
125                 goto err4;
126
127         err = gpio_request(GPIO_NR_PALMTE2_SD_READONLY, "SD_READONLY");
128         if (err)
129                 goto err4;
130         err = gpio_direction_input(GPIO_NR_PALMTE2_SD_READONLY);
131         if (err)
132                 goto err5;
133
134         printk(KERN_DEBUG "%s: irq registered\n", __func__);
135
136         return 0;
137
138 err5:
139         gpio_free(GPIO_NR_PALMTE2_SD_READONLY);
140 err4:
141         gpio_free(GPIO_NR_PALMTE2_SD_POWER);
142 err3:
143         free_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N), data);
144 err2:
145         gpio_free(GPIO_NR_PALMTE2_SD_DETECT_N);
146 err:
147         return err;
148 }
149
150 static void palmte2_mci_exit(struct device *dev, void *data)
151 {
152         gpio_free(GPIO_NR_PALMTE2_SD_READONLY);
153         gpio_free(GPIO_NR_PALMTE2_SD_POWER);
154         free_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N), data);
155         gpio_free(GPIO_NR_PALMTE2_SD_DETECT_N);
156 }
157
158 static void palmte2_mci_power(struct device *dev, unsigned int vdd)
159 {
160         struct pxamci_platform_data *p_d = dev->platform_data;
161         gpio_set_value(GPIO_NR_PALMTE2_SD_POWER, p_d->ocr_mask & (1 << vdd));
162 }
163
164 static int palmte2_mci_get_ro(struct device *dev)
165 {
166         return gpio_get_value(GPIO_NR_PALMTE2_SD_READONLY);
167 }
168
169 static struct pxamci_platform_data palmte2_mci_platform_data = {
170         .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34,
171         .setpower       = palmte2_mci_power,
172         .get_ro         = palmte2_mci_get_ro,
173         .init           = palmte2_mci_init,
174         .exit           = palmte2_mci_exit,
175 };
176
177 /******************************************************************************
178  * GPIO keys
179  ******************************************************************************/
180 static struct gpio_keys_button palmte2_pxa_buttons[] = {
181         {KEY_F1,        GPIO_NR_PALMTE2_KEY_CONTACTS,   1, "Contacts" },
182         {KEY_F2,        GPIO_NR_PALMTE2_KEY_CALENDAR,   1, "Calendar" },
183         {KEY_F3,        GPIO_NR_PALMTE2_KEY_TASKS,      1, "Tasks" },
184         {KEY_F4,        GPIO_NR_PALMTE2_KEY_NOTES,      1, "Notes" },
185         {KEY_ENTER,     GPIO_NR_PALMTE2_KEY_CENTER,     1, "Center" },
186         {KEY_LEFT,      GPIO_NR_PALMTE2_KEY_LEFT,       1, "Left" },
187         {KEY_RIGHT,     GPIO_NR_PALMTE2_KEY_RIGHT,      1, "Right" },
188         {KEY_DOWN,      GPIO_NR_PALMTE2_KEY_DOWN,       1, "Down" },
189         {KEY_UP,        GPIO_NR_PALMTE2_KEY_UP,         1, "Up" },
190 };
191
192 static struct gpio_keys_platform_data palmte2_pxa_keys_data = {
193         .buttons        = palmte2_pxa_buttons,
194         .nbuttons       = ARRAY_SIZE(palmte2_pxa_buttons),
195 };
196
197 static struct platform_device palmte2_pxa_keys = {
198         .name   = "gpio-keys",
199         .id     = -1,
200         .dev    = {
201                 .platform_data = &palmte2_pxa_keys_data,
202         },
203 };
204
205 /******************************************************************************
206  * Backlight
207  ******************************************************************************/
208 static struct platform_pwm_backlight_data palmte2_backlight_data = {
209         .pwm_id         = 0,
210         .max_brightness = PALMTE2_MAX_INTENSITY,
211         .dft_brightness = PALMTE2_MAX_INTENSITY,
212         .pwm_period_ns  = PALMTE2_PERIOD_NS,
213 };
214
215 static struct platform_device palmte2_backlight = {
216         .name   = "pwm-backlight",
217         .dev    = {
218                 .parent         = &pxa25x_device_pwm0.dev,
219                 .platform_data  = &palmte2_backlight_data,
220         },
221 };
222
223 /******************************************************************************
224  * Framebuffer
225  ******************************************************************************/
226 static struct pxafb_mode_info palmte2_lcd_modes[] = {
227 {
228         .pixclock       = 77757,
229         .xres           = 320,
230         .yres           = 320,
231         .bpp            = 16,
232
233         .left_margin    = 28,
234         .right_margin   = 7,
235         .upper_margin   = 7,
236         .lower_margin   = 5,
237
238         .hsync_len      = 4,
239         .vsync_len      = 1,
240 },
241 };
242
243 static struct pxafb_mach_info palmte2_lcd_screen = {
244         .modes          = palmte2_lcd_modes,
245         .num_modes      = ARRAY_SIZE(palmte2_lcd_modes),
246         .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
247 };
248
249 /******************************************************************************
250  * Machine init
251  ******************************************************************************/
252 static struct platform_device *devices[] __initdata = {
253 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
254         &palmte2_pxa_keys,
255 #endif
256         &palmte2_backlight,
257 };
258
259 static void __init palmte2_init(void)
260 {
261         pxa2xx_mfp_config(ARRAY_AND_SIZE(palmte2_pin_config));
262
263         set_pxa_fb_info(&palmte2_lcd_screen);
264         pxa_set_mci_info(&palmte2_mci_platform_data);
265         pxa_set_ac97_info(NULL);
266
267         platform_add_devices(devices, ARRAY_SIZE(devices));
268 }
269
270 MACHINE_START(PALMTE2, "Palm Tungsten|E2")
271         .phys_io        = 0x40000000,
272         .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
273         .boot_params    = 0xa0000100,
274         .map_io         = pxa_map_io,
275         .init_irq       = pxa25x_init_irq,
276         .timer          = &pxa_timer,
277         .init_machine   = palmte2_init
278 MACHINE_END