[ARM] 5238/2: Very basic Palm Zire 72 support
[linux-2.6.git] / arch / arm / mach-pxa / palmz72.c
1 /*
2  * Hardware definitions for Palm Zire72
3  *
4  * Authors:
5  *      Vladimir "Farcaller" Pouzanov <farcaller@gmail.com>
6  *      Sergey Lapin <slapin@ossfans.org>
7  *      Alex Osborne <bobofdoom@gmail.com>
8  *      Jan Herman <2hp@seznam.cz>
9  *
10  * Rewrite for mainline:
11  *      Marek Vasut <marek.vasut@gmail.com>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License version 2 as
15  * published by the Free Software Foundation.
16  *
17  * (find more info at www.hackndev.com)
18  *
19  */
20
21 #include <linux/platform_device.h>
22 #include <linux/sysdev.h>
23 #include <linux/delay.h>
24 #include <linux/irq.h>
25 #include <linux/gpio_keys.h>
26 #include <linux/input.h>
27 #include <linux/pda_power.h>
28 #include <linux/pwm_backlight.h>
29 #include <linux/gpio.h>
30 #include <linux/power_supply.h>
31
32 #include <asm/mach-types.h>
33 #include <asm/mach/arch.h>
34 #include <asm/mach/map.h>
35
36 #include <mach/audio.h>
37 #include <mach/palmz72.h>
38 #include <mach/mmc.h>
39 #include <mach/pxafb.h>
40 #include <mach/pxa-regs.h>
41 #include <mach/pxa2xx-regs.h>
42 #include <mach/mfp-pxa27x.h>
43 #include <mach/irda.h>
44 #include <mach/pxa27x_keypad.h>
45 #include <mach/udc.h>
46 #include <mach/pm.h>
47
48 #include "generic.h"
49 #include "devices.h"
50
51 /******************************************************************************
52  * Pin configuration
53  ******************************************************************************/
54 static unsigned long palmz72_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         GPIO115_GPIO,   /* SD RO */
64         GPIO98_GPIO,    /* SD power */
65
66         /* AC97 */
67         GPIO28_AC97_BITCLK,
68         GPIO29_AC97_SDATA_IN_0,
69         GPIO30_AC97_SDATA_OUT,
70         GPIO31_AC97_SYNC,
71
72         /* IrDA */
73         GPIO49_GPIO,    /* ir disable */
74         GPIO46_FICP_RXD,
75         GPIO47_FICP_TXD,
76
77         /* PWM */
78         GPIO16_PWM0_OUT,
79
80         /* USB */
81         GPIO15_GPIO,    /* usb detect */
82         GPIO12_GPIO,    /* usb pullup */
83         GPIO95_GPIO,    /* usb power */
84
85         /* Matrix keypad */
86         GPIO100_KP_MKIN_0       | WAKEUP_ON_LEVEL_HIGH,
87         GPIO101_KP_MKIN_1       | WAKEUP_ON_LEVEL_HIGH,
88         GPIO102_KP_MKIN_2       | WAKEUP_ON_LEVEL_HIGH,
89         GPIO97_KP_MKIN_3        | WAKEUP_ON_LEVEL_HIGH,
90         GPIO103_KP_MKOUT_0,
91         GPIO104_KP_MKOUT_1,
92         GPIO105_KP_MKOUT_2,
93
94         /* LCD */
95         GPIO58_LCD_LDD_0,
96         GPIO59_LCD_LDD_1,
97         GPIO60_LCD_LDD_2,
98         GPIO61_LCD_LDD_3,
99         GPIO62_LCD_LDD_4,
100         GPIO63_LCD_LDD_5,
101         GPIO64_LCD_LDD_6,
102         GPIO65_LCD_LDD_7,
103         GPIO66_LCD_LDD_8,
104         GPIO67_LCD_LDD_9,
105         GPIO68_LCD_LDD_10,
106         GPIO69_LCD_LDD_11,
107         GPIO70_LCD_LDD_12,
108         GPIO71_LCD_LDD_13,
109         GPIO72_LCD_LDD_14,
110         GPIO73_LCD_LDD_15,
111         GPIO74_LCD_FCLK,
112         GPIO75_LCD_LCLK,
113         GPIO76_LCD_PCLK,
114         GPIO77_LCD_BIAS,
115         GPIO20_GPIO,    /* bl power */
116         GPIO21_GPIO,    /* LCD border switch */
117         GPIO22_GPIO,    /* LCD border color */
118         GPIO96_GPIO,    /* lcd power */
119
120         /* Misc. */
121         GPIO0_GPIO      | WAKEUP_ON_LEVEL_HIGH, /* power detect */
122         GPIO88_GPIO,                            /* green led */
123         GPIO27_GPIO,                            /* WM9712 IRQ */
124 };
125
126 /******************************************************************************
127  * SD/MMC card controller
128  ******************************************************************************/
129 static int palmz72_mci_init(struct device *dev,
130                                 irq_handler_t palmz72_detect_int, void *data)
131 {
132         int err = 0;
133
134         /* Setup an interrupt for detecting card insert/remove events */
135         err = gpio_request(GPIO_NR_PALMZ72_SD_DETECT_N, "SD IRQ");
136         if (err)
137                 goto err;
138         err = gpio_direction_input(GPIO_NR_PALMZ72_SD_DETECT_N);
139         if (err)
140                 goto err2;
141         err = request_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N),
142                         palmz72_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
143                         IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
144                         "SD/MMC card detect", data);
145         if (err) {
146                 printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
147                                 __func__);
148                 goto err2;
149         }
150
151         /* SD_POWER is not actually power, but it is more like chip
152          * select, i.e. it is inverted */
153
154         err = gpio_request(GPIO_NR_PALMZ72_SD_POWER_N, "SD_POWER");
155         if (err)
156                 goto err3;
157         err = gpio_direction_output(GPIO_NR_PALMZ72_SD_POWER_N, 0);
158         if (err)
159                 goto err4;
160         err = gpio_request(GPIO_NR_PALMZ72_SD_RO, "SD_RO");
161         if (err)
162                 goto err4;
163         err = gpio_direction_input(GPIO_NR_PALMZ72_SD_RO);
164         if (err)
165                 goto err5;
166
167         printk(KERN_DEBUG "%s: irq registered\n", __func__);
168
169         return 0;
170
171 err5:
172         gpio_free(GPIO_NR_PALMZ72_SD_RO);
173 err4:
174         gpio_free(GPIO_NR_PALMZ72_SD_POWER_N);
175 err3:
176         free_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N), data);
177 err2:
178         gpio_free(GPIO_NR_PALMZ72_SD_DETECT_N);
179 err:
180         return err;
181 }
182
183 static void palmz72_mci_exit(struct device *dev, void *data)
184 {
185         gpio_free(GPIO_NR_PALMZ72_SD_POWER_N);
186         free_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N), data);
187         gpio_free(GPIO_NR_PALMZ72_SD_DETECT_N);
188         gpio_free(GPIO_NR_PALMZ72_SD_RO);
189 }
190
191 static void palmz72_mci_power(struct device *dev, unsigned int vdd)
192 {
193         struct pxamci_platform_data *p_d = dev->platform_data;
194         if (p_d->ocr_mask & (1 << vdd))
195                 gpio_set_value(GPIO_NR_PALMZ72_SD_POWER_N, 0);
196         else
197                 gpio_set_value(GPIO_NR_PALMZ72_SD_POWER_N, 1);
198 }
199
200 static int palmz72_mci_ro(struct device *dev)
201 {
202         return gpio_get_value(GPIO_NR_PALMZ72_SD_RO);
203 }
204
205 static struct pxamci_platform_data palmz72_mci_platform_data = {
206         .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34,
207         .setpower       = palmz72_mci_power,
208         .get_ro         = palmz72_mci_ro,
209         .init           = palmz72_mci_init,
210         .exit           = palmz72_mci_exit,
211 };
212
213 /******************************************************************************
214  * GPIO keyboard
215  ******************************************************************************/
216 static unsigned int palmz72_matrix_keys[] = {
217         KEY(0, 0, KEY_POWER),
218         KEY(0, 1, KEY_F1),
219         KEY(0, 2, KEY_ENTER),
220
221         KEY(1, 0, KEY_F2),
222         KEY(1, 1, KEY_F3),
223         KEY(1, 2, KEY_F4),
224
225         KEY(2, 0, KEY_UP),
226         KEY(2, 2, KEY_DOWN),
227
228         KEY(3, 0, KEY_RIGHT),
229         KEY(3, 2, KEY_LEFT),
230 };
231
232 static struct pxa27x_keypad_platform_data palmz72_keypad_platform_data = {
233         .matrix_key_rows        = 4,
234         .matrix_key_cols        = 3,
235         .matrix_key_map         = palmz72_matrix_keys,
236         .matrix_key_map_size    = ARRAY_SIZE(palmz72_matrix_keys),
237
238         .debounce_interval      = 30,
239 };
240
241 /******************************************************************************
242  * Backlight
243  ******************************************************************************/
244 static int palmz72_backlight_init(struct device *dev)
245 {
246         int ret;
247
248         ret = gpio_request(GPIO_NR_PALMZ72_BL_POWER, "BL POWER");
249         if (ret)
250                 goto err;
251         ret = gpio_direction_output(GPIO_NR_PALMZ72_BL_POWER, 0);
252         if (ret)
253                 goto err2;
254         ret = gpio_request(GPIO_NR_PALMZ72_LCD_POWER, "LCD POWER");
255         if (ret)
256                 goto err2;
257         ret = gpio_direction_output(GPIO_NR_PALMZ72_LCD_POWER, 0);
258         if (ret)
259                 goto err3;
260
261         return 0;
262 err3:
263         gpio_free(GPIO_NR_PALMZ72_LCD_POWER);
264 err2:
265         gpio_free(GPIO_NR_PALMZ72_BL_POWER);
266 err:
267         return ret;
268 }
269
270 static int palmz72_backlight_notify(int brightness)
271 {
272         gpio_set_value(GPIO_NR_PALMZ72_BL_POWER, brightness);
273         gpio_set_value(GPIO_NR_PALMZ72_LCD_POWER, brightness);
274         return brightness;
275 }
276
277 static void palmz72_backlight_exit(struct device *dev)
278 {
279         gpio_free(GPIO_NR_PALMZ72_BL_POWER);
280         gpio_free(GPIO_NR_PALMZ72_LCD_POWER);
281 }
282
283 static struct platform_pwm_backlight_data palmz72_backlight_data = {
284         .pwm_id         = 0,
285         .max_brightness = PALMZ72_MAX_INTENSITY,
286         .dft_brightness = PALMZ72_MAX_INTENSITY,
287         .pwm_period_ns  = PALMZ72_PERIOD_NS,
288         .init           = palmz72_backlight_init,
289         .notify         = palmz72_backlight_notify,
290         .exit           = palmz72_backlight_exit,
291 };
292
293 static struct platform_device palmz72_backlight = {
294         .name   = "pwm-backlight",
295         .dev    = {
296                 .parent         = &pxa27x_device_pwm0.dev,
297                 .platform_data  = &palmz72_backlight_data,
298         },
299 };
300
301 /******************************************************************************
302  * IrDA
303  ******************************************************************************/
304 static int palmz72_irda_startup(struct device *dev)
305 {
306         int err;
307         err = gpio_request(GPIO_NR_PALMZ72_IR_DISABLE, "IR DISABLE");
308         if (err)
309                 goto err;
310         err = gpio_direction_output(GPIO_NR_PALMZ72_IR_DISABLE, 1);
311         if (err)
312                 gpio_free(GPIO_NR_PALMZ72_IR_DISABLE);
313 err:
314         return err;
315 }
316
317 static void palmz72_irda_shutdown(struct device *dev)
318 {
319         gpio_free(GPIO_NR_PALMZ72_IR_DISABLE);
320 }
321
322 static void palmz72_irda_transceiver_mode(struct device *dev, int mode)
323 {
324         gpio_set_value(GPIO_NR_PALMZ72_IR_DISABLE, mode & IR_OFF);
325         pxa2xx_transceiver_mode(dev, mode);
326 }
327
328 static struct pxaficp_platform_data palmz72_ficp_platform_data = {
329         .startup                = palmz72_irda_startup,
330         .shutdown               = palmz72_irda_shutdown,
331         .transceiver_cap        = IR_SIRMODE | IR_OFF,
332         .transceiver_mode       = palmz72_irda_transceiver_mode,
333 };
334
335 /******************************************************************************
336  * LEDs
337  ******************************************************************************/
338 static struct gpio_led gpio_leds[] = {
339         {
340                 .name                   = "palmz72:green:led",
341                 .default_trigger        = "none",
342                 .gpio                   = GPIO_NR_PALMZ72_LED_GREEN,
343         },
344 };
345
346 static struct gpio_led_platform_data gpio_led_info = {
347         .leds           = gpio_leds,
348         .num_leds       = ARRAY_SIZE(gpio_leds),
349 };
350
351 static struct platform_device palmz72_leds = {
352         .name   = "leds-gpio",
353         .id     = -1,
354         .dev    = {
355                 .platform_data  = &gpio_led_info,
356         }
357 };
358
359 /******************************************************************************
360  * Power supply
361  ******************************************************************************/
362 static int power_supply_init(struct device *dev)
363 {
364         int ret;
365
366         ret = gpio_request(GPIO_NR_PALMZ72_POWER_DETECT, "CABLE_STATE_AC");
367         if (ret)
368                 goto err1;
369         ret = gpio_direction_input(GPIO_NR_PALMZ72_POWER_DETECT);
370         if (ret)
371                 goto err2;
372
373         ret = gpio_request(GPIO_NR_PALMZ72_USB_DETECT_N, "CABLE_STATE_USB");
374         if (ret)
375                 goto err2;
376         ret = gpio_direction_input(GPIO_NR_PALMZ72_USB_DETECT_N);
377         if (ret)
378                 goto err3;
379
380         return 0;
381 err3:
382         gpio_free(GPIO_NR_PALMZ72_USB_DETECT_N);
383 err2:
384         gpio_free(GPIO_NR_PALMZ72_POWER_DETECT);
385 err1:
386         return ret;
387 }
388
389 static int palmz72_is_ac_online(void)
390 {
391         return gpio_get_value(GPIO_NR_PALMZ72_POWER_DETECT);
392 }
393
394 static int palmz72_is_usb_online(void)
395 {
396         return !gpio_get_value(GPIO_NR_PALMZ72_USB_DETECT_N);
397 }
398
399 static void power_supply_exit(struct device *dev)
400 {
401         gpio_free(GPIO_NR_PALMZ72_USB_DETECT_N);
402         gpio_free(GPIO_NR_PALMZ72_POWER_DETECT);
403 }
404
405 static char *palmz72_supplicants[] = {
406         "main-battery",
407 };
408
409 static struct pda_power_pdata power_supply_info = {
410         .init            = power_supply_init,
411         .is_ac_online    = palmz72_is_ac_online,
412         .is_usb_online   = palmz72_is_usb_online,
413         .exit            = power_supply_exit,
414         .supplied_to     = palmz72_supplicants,
415         .num_supplicants = ARRAY_SIZE(palmz72_supplicants),
416 };
417
418 static struct platform_device power_supply = {
419         .name = "pda-power",
420         .id   = -1,
421         .dev  = {
422                 .platform_data = &power_supply_info,
423         },
424 };
425
426 /******************************************************************************
427  * Framebuffer
428  ******************************************************************************/
429 static struct pxafb_mode_info palmz72_lcd_modes[] = {
430 {
431         .pixclock       = 115384,
432         .xres           = 320,
433         .yres           = 320,
434         .bpp            = 16,
435
436         .left_margin    = 27,
437         .right_margin   = 7,
438         .upper_margin   = 7,
439         .lower_margin   = 8,
440
441         .hsync_len      = 6,
442         .vsync_len      = 1,
443 },
444 };
445
446 static struct pxafb_mach_info palmz72_lcd_screen = {
447         .modes          = palmz72_lcd_modes,
448         .num_modes      = ARRAY_SIZE(palmz72_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         &palmz72_backlight,
457         &palmz72_leds,
458         &power_supply,
459 };
460
461 static void __init palmz72_init(void)
462 {
463         pxa2xx_mfp_config(ARRAY_AND_SIZE(palmz72_pin_config));
464         set_pxa_fb_info(&palmz72_lcd_screen);
465         pxa_set_mci_info(&palmz72_mci_platform_data);
466         pxa_set_ac97_info(NULL);
467         pxa_set_ficp_info(&palmz72_ficp_platform_data);
468         pxa_set_keypad_info(&palmz72_keypad_platform_data);
469         platform_add_devices(devices, ARRAY_SIZE(devices));
470 }
471
472 MACHINE_START(PALMZ72, "Palm Zire72")
473         .phys_io        = 0x40000000,
474         .io_pg_offst    = io_p2v(0x40000000),
475         .boot_params    = 0xa0000100,
476         .map_io         = pxa_map_io,
477         .init_irq       = pxa27x_init_irq,
478         .timer          = &pxa_timer,
479         .init_machine   = palmz72_init
480 MACHINE_END