Merge branch 'for-rmk' of git://gitorious.org/linux-gemini/mainline into devel
[linux-2.6] / arch / arm / mach-pxa / palmt5.c
1 /*
2  * Hardware definitions for Palm Tungsten|T5
3  *
4  * Author:      Marek Vasut <marek.vasut@gmail.com>
5  *
6  * Based on work of:
7  *              Ales Snuparek <snuparek@atlas.cz>
8  *              Justin Kendrick <twilightsentry@gmail.com>
9  *              RichardT5 <richard_t5@users.sourceforge.net>
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  * (find more info at www.hackndev.com)
16  *
17  */
18
19 #include <linux/platform_device.h>
20 #include <linux/delay.h>
21 #include <linux/irq.h>
22 #include <linux/gpio_keys.h>
23 #include <linux/input.h>
24 #include <linux/pda_power.h>
25 #include <linux/pwm_backlight.h>
26 #include <linux/gpio.h>
27 #include <linux/wm97xx_batt.h>
28 #include <linux/power_supply.h>
29
30 #include <asm/mach-types.h>
31 #include <asm/mach/arch.h>
32 #include <asm/mach/map.h>
33
34 #include <mach/pxa27x.h>
35 #include <mach/audio.h>
36 #include <mach/palmt5.h>
37 #include <mach/mmc.h>
38 #include <mach/pxafb.h>
39 #include <mach/irda.h>
40 #include <mach/pxa27x_keypad.h>
41 #include <mach/udc.h>
42 #include <mach/palmasoc.h>
43
44 #include "generic.h"
45 #include "devices.h"
46
47 /******************************************************************************
48  * Pin configuration
49  ******************************************************************************/
50 static unsigned long palmt5_pin_config[] __initdata = {
51         /* MMC */
52         GPIO32_MMC_CLK,
53         GPIO92_MMC_DAT_0,
54         GPIO109_MMC_DAT_1,
55         GPIO110_MMC_DAT_2,
56         GPIO111_MMC_DAT_3,
57         GPIO112_MMC_CMD,
58         GPIO14_GPIO,    /* SD detect */
59         GPIO114_GPIO,   /* SD power */
60         GPIO115_GPIO,   /* SD r/o switch */
61
62         /* AC97 */
63         GPIO28_AC97_BITCLK,
64         GPIO29_AC97_SDATA_IN_0,
65         GPIO30_AC97_SDATA_OUT,
66         GPIO31_AC97_SYNC,
67
68         /* IrDA */
69         GPIO40_GPIO,    /* ir disable */
70         GPIO46_FICP_RXD,
71         GPIO47_FICP_TXD,
72
73         /* USB */
74         GPIO15_GPIO,    /* usb detect */
75         GPIO95_GPIO,    /* usb power */
76
77         /* MATRIX KEYPAD */
78         GPIO100_KP_MKIN_0,
79         GPIO101_KP_MKIN_1,
80         GPIO102_KP_MKIN_2,
81         GPIO97_KP_MKIN_3,
82         GPIO103_KP_MKOUT_0,
83         GPIO104_KP_MKOUT_1,
84         GPIO105_KP_MKOUT_2,
85
86         /* LCD */
87         GPIO58_LCD_LDD_0,
88         GPIO59_LCD_LDD_1,
89         GPIO60_LCD_LDD_2,
90         GPIO61_LCD_LDD_3,
91         GPIO62_LCD_LDD_4,
92         GPIO63_LCD_LDD_5,
93         GPIO64_LCD_LDD_6,
94         GPIO65_LCD_LDD_7,
95         GPIO66_LCD_LDD_8,
96         GPIO67_LCD_LDD_9,
97         GPIO68_LCD_LDD_10,
98         GPIO69_LCD_LDD_11,
99         GPIO70_LCD_LDD_12,
100         GPIO71_LCD_LDD_13,
101         GPIO72_LCD_LDD_14,
102         GPIO73_LCD_LDD_15,
103         GPIO74_LCD_FCLK,
104         GPIO75_LCD_LCLK,
105         GPIO76_LCD_PCLK,
106         GPIO77_LCD_BIAS,
107
108         /* PWM */
109         GPIO16_PWM0_OUT,
110
111         /* MISC */
112         GPIO10_GPIO,    /* hotsync button */
113         GPIO90_GPIO,    /* power detect */
114         GPIO107_GPIO,   /* earphone detect */
115 };
116
117 /******************************************************************************
118  * SD/MMC card controller
119  ******************************************************************************/
120 static int palmt5_mci_init(struct device *dev, irq_handler_t palmt5_detect_int,
121                                 void *data)
122 {
123         int err = 0;
124
125         /* Setup an interrupt for detecting card insert/remove events */
126         err = gpio_request(GPIO_NR_PALMT5_SD_DETECT_N, "SD IRQ");
127         if (err)
128                 goto err;
129         err = gpio_direction_input(GPIO_NR_PALMT5_SD_DETECT_N);
130         if (err)
131                 goto err2;
132         err = request_irq(gpio_to_irq(GPIO_NR_PALMT5_SD_DETECT_N),
133                         palmt5_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
134                         IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
135                         "SD/MMC card detect", data);
136         if (err) {
137                 printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
138                                 __func__);
139                 goto err2;
140         }
141
142         err = gpio_request(GPIO_NR_PALMT5_SD_POWER, "SD_POWER");
143         if (err)
144                 goto err3;
145         err = gpio_direction_output(GPIO_NR_PALMT5_SD_POWER, 0);
146         if (err)
147                 goto err4;
148
149         err = gpio_request(GPIO_NR_PALMT5_SD_READONLY, "SD_READONLY");
150         if (err)
151                 goto err4;
152         err = gpio_direction_input(GPIO_NR_PALMT5_SD_READONLY);
153         if (err)
154                 goto err5;
155
156         printk(KERN_DEBUG "%s: irq registered\n", __func__);
157
158         return 0;
159
160 err5:
161         gpio_free(GPIO_NR_PALMT5_SD_READONLY);
162 err4:
163         gpio_free(GPIO_NR_PALMT5_SD_POWER);
164 err3:
165         free_irq(gpio_to_irq(GPIO_NR_PALMT5_SD_DETECT_N), data);
166 err2:
167         gpio_free(GPIO_NR_PALMT5_SD_DETECT_N);
168 err:
169         return err;
170 }
171
172 static void palmt5_mci_exit(struct device *dev, void *data)
173 {
174         gpio_free(GPIO_NR_PALMT5_SD_READONLY);
175         gpio_free(GPIO_NR_PALMT5_SD_POWER);
176         free_irq(IRQ_GPIO_PALMT5_SD_DETECT_N, data);
177         gpio_free(GPIO_NR_PALMT5_SD_DETECT_N);
178 }
179
180 static void palmt5_mci_power(struct device *dev, unsigned int vdd)
181 {
182         struct pxamci_platform_data *p_d = dev->platform_data;
183         gpio_set_value(GPIO_NR_PALMT5_SD_POWER, p_d->ocr_mask & (1 << vdd));
184 }
185
186 static int palmt5_mci_get_ro(struct device *dev)
187 {
188         return gpio_get_value(GPIO_NR_PALMT5_SD_READONLY);
189 }
190
191 static struct pxamci_platform_data palmt5_mci_platform_data = {
192         .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34,
193         .setpower       = palmt5_mci_power,
194         .get_ro         = palmt5_mci_get_ro,
195         .init           = palmt5_mci_init,
196         .exit           = palmt5_mci_exit,
197 };
198
199 /******************************************************************************
200  * GPIO keyboard
201  ******************************************************************************/
202 static unsigned int palmt5_matrix_keys[] = {
203         KEY(0, 0, KEY_POWER),
204         KEY(0, 1, KEY_F1),
205         KEY(0, 2, KEY_ENTER),
206
207         KEY(1, 0, KEY_F2),
208         KEY(1, 1, KEY_F3),
209         KEY(1, 2, KEY_F4),
210
211         KEY(2, 0, KEY_UP),
212         KEY(2, 2, KEY_DOWN),
213
214         KEY(3, 0, KEY_RIGHT),
215         KEY(3, 2, KEY_LEFT),
216 };
217
218 static struct pxa27x_keypad_platform_data palmt5_keypad_platform_data = {
219         .matrix_key_rows        = 4,
220         .matrix_key_cols        = 3,
221         .matrix_key_map         = palmt5_matrix_keys,
222         .matrix_key_map_size    = ARRAY_SIZE(palmt5_matrix_keys),
223
224         .debounce_interval      = 30,
225 };
226
227 /******************************************************************************
228  * GPIO keys
229  ******************************************************************************/
230 static struct gpio_keys_button palmt5_pxa_buttons[] = {
231         {KEY_F8, GPIO_NR_PALMT5_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
232 };
233
234 static struct gpio_keys_platform_data palmt5_pxa_keys_data = {
235         .buttons        = palmt5_pxa_buttons,
236         .nbuttons       = ARRAY_SIZE(palmt5_pxa_buttons),
237 };
238
239 static struct platform_device palmt5_pxa_keys = {
240         .name   = "gpio-keys",
241         .id     = -1,
242         .dev    = {
243                 .platform_data = &palmt5_pxa_keys_data,
244         },
245 };
246
247 /******************************************************************************
248  * Backlight
249  ******************************************************************************/
250 static int palmt5_backlight_init(struct device *dev)
251 {
252         int ret;
253
254         ret = gpio_request(GPIO_NR_PALMT5_BL_POWER, "BL POWER");
255         if (ret)
256                 goto err;
257         ret = gpio_direction_output(GPIO_NR_PALMT5_BL_POWER, 0);
258         if (ret)
259                 goto err2;
260         ret = gpio_request(GPIO_NR_PALMT5_LCD_POWER, "LCD POWER");
261         if (ret)
262                 goto err2;
263         ret = gpio_direction_output(GPIO_NR_PALMT5_LCD_POWER, 0);
264         if (ret)
265                 goto err3;
266
267         return 0;
268 err3:
269         gpio_free(GPIO_NR_PALMT5_LCD_POWER);
270 err2:
271         gpio_free(GPIO_NR_PALMT5_BL_POWER);
272 err:
273         return ret;
274 }
275
276 static int palmt5_backlight_notify(int brightness)
277 {
278         gpio_set_value(GPIO_NR_PALMT5_BL_POWER, brightness);
279         gpio_set_value(GPIO_NR_PALMT5_LCD_POWER, brightness);
280         return brightness;
281 }
282
283 static void palmt5_backlight_exit(struct device *dev)
284 {
285         gpio_free(GPIO_NR_PALMT5_BL_POWER);
286         gpio_free(GPIO_NR_PALMT5_LCD_POWER);
287 }
288
289 static struct platform_pwm_backlight_data palmt5_backlight_data = {
290         .pwm_id         = 0,
291         .max_brightness = PALMT5_MAX_INTENSITY,
292         .dft_brightness = PALMT5_MAX_INTENSITY,
293         .pwm_period_ns  = PALMT5_PERIOD_NS,
294         .init           = palmt5_backlight_init,
295         .notify         = palmt5_backlight_notify,
296         .exit           = palmt5_backlight_exit,
297 };
298
299 static struct platform_device palmt5_backlight = {
300         .name   = "pwm-backlight",
301         .dev    = {
302                 .parent         = &pxa27x_device_pwm0.dev,
303                 .platform_data  = &palmt5_backlight_data,
304         },
305 };
306
307 /******************************************************************************
308  * IrDA
309  ******************************************************************************/
310 static int palmt5_irda_startup(struct device *dev)
311 {
312         int err;
313         err = gpio_request(GPIO_NR_PALMT5_IR_DISABLE, "IR DISABLE");
314         if (err)
315                 goto err;
316         err = gpio_direction_output(GPIO_NR_PALMT5_IR_DISABLE, 1);
317         if (err)
318                 gpio_free(GPIO_NR_PALMT5_IR_DISABLE);
319 err:
320         return err;
321 }
322
323 static void palmt5_irda_shutdown(struct device *dev)
324 {
325         gpio_free(GPIO_NR_PALMT5_IR_DISABLE);
326 }
327
328 static void palmt5_irda_transceiver_mode(struct device *dev, int mode)
329 {
330         gpio_set_value(GPIO_NR_PALMT5_IR_DISABLE, mode & IR_OFF);
331         pxa2xx_transceiver_mode(dev, mode);
332 }
333
334 static struct pxaficp_platform_data palmt5_ficp_platform_data = {
335         .startup                = palmt5_irda_startup,
336         .shutdown               = palmt5_irda_shutdown,
337         .transceiver_cap        = IR_SIRMODE | IR_FIRMODE | IR_OFF,
338         .transceiver_mode       = palmt5_irda_transceiver_mode,
339 };
340
341 /******************************************************************************
342  * UDC
343  ******************************************************************************/
344 static struct pxa2xx_udc_mach_info palmt5_udc_info __initdata = {
345         .gpio_vbus              = GPIO_NR_PALMT5_USB_DETECT_N,
346         .gpio_vbus_inverted     = 1,
347         .gpio_pullup            = GPIO_NR_PALMT5_USB_POWER,
348         .gpio_pullup_inverted   = 0,
349 };
350
351 /******************************************************************************
352  * Power supply
353  ******************************************************************************/
354 static int power_supply_init(struct device *dev)
355 {
356         int ret;
357
358         ret = gpio_request(GPIO_NR_PALMT5_POWER_DETECT, "CABLE_STATE_AC");
359         if (ret)
360                 goto err1;
361         ret = gpio_direction_input(GPIO_NR_PALMT5_POWER_DETECT);
362         if (ret)
363                 goto err2;
364
365         return 0;
366 err2:
367         gpio_free(GPIO_NR_PALMT5_POWER_DETECT);
368 err1:
369         return ret;
370 }
371
372 static int palmt5_is_ac_online(void)
373 {
374         return gpio_get_value(GPIO_NR_PALMT5_POWER_DETECT);
375 }
376
377 static void power_supply_exit(struct device *dev)
378 {
379         gpio_free(GPIO_NR_PALMT5_POWER_DETECT);
380 }
381
382 static char *palmt5_supplicants[] = {
383         "main-battery",
384 };
385
386 static struct pda_power_pdata power_supply_info = {
387         .init            = power_supply_init,
388         .is_ac_online    = palmt5_is_ac_online,
389         .exit            = power_supply_exit,
390         .supplied_to     = palmt5_supplicants,
391         .num_supplicants = ARRAY_SIZE(palmt5_supplicants),
392 };
393
394 static struct platform_device power_supply = {
395         .name = "pda-power",
396         .id   = -1,
397         .dev  = {
398                 .platform_data = &power_supply_info,
399         },
400 };
401
402 /******************************************************************************
403  * WM97xx battery
404  ******************************************************************************/
405 static struct wm97xx_batt_info wm97xx_batt_pdata = {
406         .batt_aux       = WM97XX_AUX_ID3,
407         .temp_aux       = WM97XX_AUX_ID2,
408         .charge_gpio    = -1,
409         .max_voltage    = PALMT5_BAT_MAX_VOLTAGE,
410         .min_voltage    = PALMT5_BAT_MIN_VOLTAGE,
411         .batt_mult      = 1000,
412         .batt_div       = 414,
413         .temp_mult      = 1,
414         .temp_div       = 1,
415         .batt_tech      = POWER_SUPPLY_TECHNOLOGY_LIPO,
416         .batt_name      = "main-batt",
417 };
418
419 /******************************************************************************
420  * aSoC audio
421  ******************************************************************************/
422 static struct palm27x_asoc_info palm27x_asoc_pdata = {
423         .jack_gpio      = GPIO_NR_PALMT5_EARPHONE_DETECT,
424 };
425
426 /******************************************************************************
427  * Framebuffer
428  ******************************************************************************/
429 static struct pxafb_mode_info palmt5_lcd_modes[] = {
430 {
431         .pixclock       = 57692,
432         .xres           = 320,
433         .yres           = 480,
434         .bpp            = 16,
435
436         .left_margin    = 32,
437         .right_margin   = 1,
438         .upper_margin   = 7,
439         .lower_margin   = 1,
440
441         .hsync_len      = 4,
442         .vsync_len      = 1,
443 },
444 };
445
446 static struct pxafb_mach_info palmt5_lcd_screen = {
447         .modes          = palmt5_lcd_modes,
448         .num_modes      = ARRAY_SIZE(palmt5_lcd_modes),
449         .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
450 };
451
452 /******************************************************************************
453  * Machine init
454  ******************************************************************************/
455 static struct platform_device *devices[] __initdata = {
456 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
457         &palmt5_pxa_keys,
458 #endif
459         &palmt5_backlight,
460         &power_supply,
461 };
462
463 /* setup udc GPIOs initial state */
464 static void __init palmt5_udc_init(void)
465 {
466         if (!gpio_request(GPIO_NR_PALMT5_USB_POWER, "UDC Vbus")) {
467                 gpio_direction_output(GPIO_NR_PALMT5_USB_POWER, 1);
468                 gpio_free(GPIO_NR_PALMT5_USB_POWER);
469         }
470 }
471
472 static void __init palmt5_init(void)
473 {
474         pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
475
476         set_pxa_fb_info(&palmt5_lcd_screen);
477         pxa_set_mci_info(&palmt5_mci_platform_data);
478         palmt5_udc_init();
479         pxa_set_udc_info(&palmt5_udc_info);
480         pxa_set_ac97_info(NULL);
481         pxa_set_ficp_info(&palmt5_ficp_platform_data);
482         pxa_set_keypad_info(&palmt5_keypad_platform_data);
483         wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
484         palm27x_asoc_set_pdata(&palm27x_asoc_pdata);
485         platform_add_devices(devices, ARRAY_SIZE(devices));
486 }
487
488 MACHINE_START(PALMT5, "Palm Tungsten|T5")
489         .phys_io        = PALMT5_PHYS_IO_START,
490         .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
491         .boot_params    = 0xa0000100,
492         .map_io         = pxa_map_io,
493         .init_irq       = pxa27x_init_irq,
494         .timer          = &pxa_timer,
495         .init_machine   = palmt5_init
496 MACHINE_END