Merge branch 'linus' into core/rcu
[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
29 #include <asm/mach-types.h>
30 #include <asm/mach/arch.h>
31 #include <asm/mach/map.h>
32
33 #include <mach/audio.h>
34 #include <mach/palmtx.h>
35 #include <mach/mmc.h>
36 #include <mach/pxafb.h>
37 #include <mach/pxa-regs.h>
38 #include <mach/mfp-pxa27x.h>
39 #include <mach/irda.h>
40 #include <mach/pxa27x_keypad.h>
41 #include <mach/udc.h>
42
43 #include "generic.h"
44 #include "devices.h"
45
46 /******************************************************************************
47  * Pin configuration
48  ******************************************************************************/
49 static unsigned long palmtx_pin_config[] __initdata = {
50         /* MMC */
51         GPIO32_MMC_CLK,
52         GPIO92_MMC_DAT_0,
53         GPIO109_MMC_DAT_1,
54         GPIO110_MMC_DAT_2,
55         GPIO111_MMC_DAT_3,
56         GPIO112_MMC_CMD,
57
58         /* AC97 */
59         GPIO28_AC97_BITCLK,
60         GPIO29_AC97_SDATA_IN_0,
61         GPIO30_AC97_SDATA_OUT,
62         GPIO31_AC97_SYNC,
63
64         /* IrDA */
65         GPIO46_FICP_RXD,
66         GPIO47_FICP_TXD,
67
68         /* PWM */
69         GPIO16_PWM0_OUT,
70
71         /* USB */
72         GPIO13_GPIO,
73
74         /* PCMCIA */
75         GPIO48_nPOE,
76         GPIO49_nPWE,
77         GPIO50_nPIOR,
78         GPIO51_nPIOW,
79         GPIO85_nPCE_1,
80         GPIO54_nPCE_2,
81         GPIO79_PSKTSEL,
82         GPIO55_nPREG,
83         GPIO56_nPWAIT,
84         GPIO57_nIOIS16,
85 };
86
87 /******************************************************************************
88  * SD/MMC card controller
89  ******************************************************************************/
90 static int palmtx_mci_init(struct device *dev, irq_handler_t palmtx_detect_int,
91                                 void *data)
92 {
93         int err = 0;
94
95         /* Setup an interrupt for detecting card insert/remove events */
96         err = request_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, palmtx_detect_int,
97                         IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
98                         IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
99                         "SD/MMC card detect", data);
100         if (err) {
101                 printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
102                                 __func__);
103                 return err;
104         }
105
106         err = gpio_request(GPIO_NR_PALMTX_SD_POWER, "SD_POWER");
107         if (err)
108                 goto pwr_err;
109
110         err = gpio_request(GPIO_NR_PALMTX_SD_READONLY, "SD_READONLY");
111         if (err)
112                 goto ro_err;
113
114         printk(KERN_DEBUG "%s: irq registered\n", __func__);
115
116         return 0;
117
118 ro_err:
119         gpio_free(GPIO_NR_PALMTX_SD_POWER);
120 pwr_err:
121         free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data);
122         return err;
123 }
124
125 static void palmtx_mci_exit(struct device *dev, void *data)
126 {
127         gpio_free(GPIO_NR_PALMTX_SD_READONLY);
128         gpio_free(GPIO_NR_PALMTX_SD_POWER);
129         free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data);
130 }
131
132 static void palmtx_mci_power(struct device *dev, unsigned int vdd)
133 {
134         struct pxamci_platform_data *p_d = dev->platform_data;
135         gpio_set_value(GPIO_NR_PALMTX_SD_POWER, p_d->ocr_mask & (1 << vdd));
136 }
137
138 static int palmtx_mci_get_ro(struct device *dev)
139 {
140         return gpio_get_value(GPIO_NR_PALMTX_SD_READONLY);
141 }
142
143 static struct pxamci_platform_data palmtx_mci_platform_data = {
144         .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34,
145         .setpower       = palmtx_mci_power,
146         .get_ro         = palmtx_mci_get_ro,
147         .init           = palmtx_mci_init,
148         .exit           = palmtx_mci_exit,
149 };
150
151 /******************************************************************************
152  * GPIO keyboard
153  ******************************************************************************/
154 static unsigned int palmtx_matrix_keys[] = {
155         KEY(0, 0, KEY_POWER),
156         KEY(0, 1, KEY_F1),
157         KEY(0, 2, KEY_ENTER),
158
159         KEY(1, 0, KEY_F2),
160         KEY(1, 1, KEY_F3),
161         KEY(1, 2, KEY_F4),
162
163         KEY(2, 0, KEY_UP),
164         KEY(2, 2, KEY_DOWN),
165
166         KEY(3, 0, KEY_RIGHT),
167         KEY(3, 2, KEY_LEFT),
168
169 };
170
171 static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = {
172         .matrix_key_rows        = 4,
173         .matrix_key_cols        = 3,
174         .matrix_key_map         = palmtx_matrix_keys,
175         .matrix_key_map_size    = ARRAY_SIZE(palmtx_matrix_keys),
176
177         .debounce_interval      = 30,
178 };
179
180 /******************************************************************************
181  * GPIO keys
182  ******************************************************************************/
183 static struct gpio_keys_button palmtx_pxa_buttons[] = {
184         {KEY_F8, GPIO_NR_PALMTX_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
185 };
186
187 static struct gpio_keys_platform_data palmtx_pxa_keys_data = {
188         .buttons        = palmtx_pxa_buttons,
189         .nbuttons       = ARRAY_SIZE(palmtx_pxa_buttons),
190 };
191
192 static struct platform_device palmtx_pxa_keys = {
193         .name   = "gpio-keys",
194         .id     = -1,
195         .dev    = {
196                 .platform_data = &palmtx_pxa_keys_data,
197         },
198 };
199
200 /******************************************************************************
201  * Backlight
202  ******************************************************************************/
203 static int palmtx_backlight_init(struct device *dev)
204 {
205         int ret;
206
207         ret = gpio_request(GPIO_NR_PALMTX_BL_POWER, "BL POWER");
208         if (ret)
209                 goto err;
210         ret = gpio_request(GPIO_NR_PALMTX_LCD_POWER, "LCD POWER");
211         if (ret)
212                 goto err2;
213
214         return 0;
215 err2:
216         gpio_free(GPIO_NR_PALMTX_BL_POWER);
217 err:
218         return ret;
219 }
220
221 static int palmtx_backlight_notify(int brightness)
222 {
223         gpio_set_value(GPIO_NR_PALMTX_BL_POWER, brightness);
224         gpio_set_value(GPIO_NR_PALMTX_LCD_POWER, brightness);
225         return brightness;
226 }
227
228 static void palmtx_backlight_exit(struct device *dev)
229 {
230         gpio_free(GPIO_NR_PALMTX_BL_POWER);
231         gpio_free(GPIO_NR_PALMTX_LCD_POWER);
232 }
233
234 static struct platform_pwm_backlight_data palmtx_backlight_data = {
235         .pwm_id         = 0,
236         .max_brightness = PALMTX_MAX_INTENSITY,
237         .dft_brightness = PALMTX_MAX_INTENSITY,
238         .pwm_period_ns  = PALMTX_PERIOD_NS,
239         .init           = palmtx_backlight_init,
240         .notify         = palmtx_backlight_notify,
241         .exit           = palmtx_backlight_exit,
242 };
243
244 static struct platform_device palmtx_backlight = {
245         .name   = "pwm-backlight",
246         .dev    = {
247                 .parent         = &pxa27x_device_pwm0.dev,
248                 .platform_data  = &palmtx_backlight_data,
249         },
250 };
251
252 /******************************************************************************
253  * IrDA
254  ******************************************************************************/
255 static void palmtx_irda_transceiver_mode(struct device *dev, int mode)
256 {
257         gpio_set_value(GPIO_NR_PALMTX_IR_DISABLE, mode & IR_OFF);
258         pxa2xx_transceiver_mode(dev, mode);
259 }
260
261 static struct pxaficp_platform_data palmtx_ficp_platform_data = {
262         .transceiver_cap        = IR_SIRMODE | IR_FIRMODE | IR_OFF,
263         .transceiver_mode       = palmtx_irda_transceiver_mode,
264 };
265
266 /******************************************************************************
267  * UDC
268  ******************************************************************************/
269 static void palmtx_udc_command(int cmd)
270 {
271         gpio_set_value(GPIO_NR_PALMTX_USB_POWER, !cmd);
272         udelay(50);
273         gpio_set_value(GPIO_NR_PALMTX_USB_PULLUP, !cmd);
274 }
275
276 static struct pxa2xx_udc_mach_info palmtx_udc_info __initdata = {
277         .gpio_vbus              = GPIO_NR_PALMTX_USB_DETECT_N,
278         .gpio_vbus_inverted     = 1,
279         .udc_command            = palmtx_udc_command,
280 };
281
282 /******************************************************************************
283  * Power supply
284  ******************************************************************************/
285 static int power_supply_init(struct device *dev)
286 {
287         int ret;
288
289         ret = gpio_request(GPIO_NR_PALMTX_POWER_DETECT, "CABLE_STATE_AC");
290         if (ret)
291                 goto err_cs_ac;
292
293         ret = gpio_request(GPIO_NR_PALMTX_USB_DETECT_N, "CABLE_STATE_USB");
294         if (ret)
295                 goto err_cs_usb;
296
297         return 0;
298
299 err_cs_usb:
300         gpio_free(GPIO_NR_PALMTX_POWER_DETECT);
301 err_cs_ac:
302         return ret;
303 }
304
305 static int palmtx_is_ac_online(void)
306 {
307         return gpio_get_value(GPIO_NR_PALMTX_POWER_DETECT);
308 }
309
310 static int palmtx_is_usb_online(void)
311 {
312         return !gpio_get_value(GPIO_NR_PALMTX_USB_DETECT_N);
313 }
314
315 static void power_supply_exit(struct device *dev)
316 {
317         gpio_free(GPIO_NR_PALMTX_USB_DETECT_N);
318         gpio_free(GPIO_NR_PALMTX_POWER_DETECT);
319 }
320
321 static char *palmtx_supplicants[] = {
322         "main-battery",
323 };
324
325 static struct pda_power_pdata power_supply_info = {
326         .init            = power_supply_init,
327         .is_ac_online    = palmtx_is_ac_online,
328         .is_usb_online   = palmtx_is_usb_online,
329         .exit            = power_supply_exit,
330         .supplied_to     = palmtx_supplicants,
331         .num_supplicants = ARRAY_SIZE(palmtx_supplicants),
332 };
333
334 static struct platform_device power_supply = {
335         .name = "pda-power",
336         .id   = -1,
337         .dev  = {
338                 .platform_data = &power_supply_info,
339         },
340 };
341
342 /******************************************************************************
343  * Framebuffer
344  ******************************************************************************/
345 static struct pxafb_mode_info palmtx_lcd_modes[] = {
346 {
347         .pixclock       = 57692,
348         .xres           = 320,
349         .yres           = 480,
350         .bpp            = 16,
351
352         .left_margin    = 32,
353         .right_margin   = 1,
354         .upper_margin   = 7,
355         .lower_margin   = 1,
356
357         .hsync_len      = 4,
358         .vsync_len      = 1,
359 },
360 };
361
362 static struct pxafb_mach_info palmtx_lcd_screen = {
363         .modes          = palmtx_lcd_modes,
364         .num_modes      = ARRAY_SIZE(palmtx_lcd_modes),
365         .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
366 };
367
368 /******************************************************************************
369  * Machine init
370  ******************************************************************************/
371 static struct platform_device *devices[] __initdata = {
372 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
373         &palmtx_pxa_keys,
374 #endif
375         &palmtx_backlight,
376         &power_supply,
377 };
378
379 static struct map_desc palmtx_io_desc[] __initdata = {
380 {
381         .virtual        = PALMTX_PCMCIA_VIRT,
382         .pfn            = __phys_to_pfn(PALMTX_PCMCIA_PHYS),
383         .length         = PALMTX_PCMCIA_SIZE,
384         .type           = MT_DEVICE
385 },
386 };
387
388 static void __init palmtx_map_io(void)
389 {
390         pxa_map_io();
391         iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc));
392 }
393
394 static void __init palmtx_init(void)
395 {
396         pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config));
397
398         set_pxa_fb_info(&palmtx_lcd_screen);
399         pxa_set_mci_info(&palmtx_mci_platform_data);
400         pxa_set_udc_info(&palmtx_udc_info);
401         pxa_set_ac97_info(NULL);
402         pxa_set_ficp_info(&palmtx_ficp_platform_data);
403         pxa_set_keypad_info(&palmtx_keypad_platform_data);
404
405         platform_add_devices(devices, ARRAY_SIZE(devices));
406 }
407
408 MACHINE_START(PALMTX, "Palm T|X")
409         .phys_io        = PALMTX_PHYS_IO_START,
410         .io_pg_offst    = io_p2v(0x40000000),
411         .boot_params    = 0xa0000100,
412         .map_io         = palmtx_map_io,
413         .init_irq       = pxa27x_init_irq,
414         .timer          = &pxa_timer,
415         .init_machine   = palmtx_init
416 MACHINE_END