[ARM] Acer n30: LED support.
[pandora-kernel.git] / arch / arm / mach-s3c2410 / mach-n30.c
1 /* Machine specific code for the Acer n30 PDA.
2  *
3  * Copyright (c) 2003-2005 Simtec Electronics
4  *      Ben Dooks <ben@simtec.co.uk>
5  *
6  * Copyright (c) 2005-2008 Christer Weinigel <christer@weinigel.se>
7  *
8  * There is a wiki with more information about the n30 port at
9  * http://handhelds.org/moin/moin.cgi/AcerN30Documentation .
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
16 #include <linux/kernel.h>
17 #include <linux/types.h>
18
19 #include <linux/delay.h>
20 #include <linux/gpio_keys.h>
21 #include <linux/init.h>
22 #include <linux/input.h>
23 #include <linux/interrupt.h>
24 #include <linux/platform_device.h>
25 #include <linux/serial_core.h>
26 #include <linux/timer.h>
27
28 #include <asm/hardware.h>
29 #include <asm/io.h>
30 #include <asm/irq.h>
31 #include <asm/mach-types.h>
32
33 #include <asm/arch/leds-gpio.h>
34 #include <asm/arch/regs-gpio.h>
35
36 #include <asm/mach/arch.h>
37 #include <asm/mach/irq.h>
38 #include <asm/mach/map.h>
39
40 #include <asm/plat-s3c/iic.h>
41 #include <asm/plat-s3c/regs-serial.h>
42
43 #include <asm/plat-s3c24xx/clock.h>
44 #include <asm/plat-s3c24xx/cpu.h>
45 #include <asm/plat-s3c24xx/devs.h>
46 #include <asm/plat-s3c24xx/s3c2410.h>
47 #include <asm/plat-s3c24xx/udc.h>
48
49 static struct map_desc n30_iodesc[] __initdata = {
50         /* nothing here yet */
51 };
52
53 static struct s3c2410_uartcfg n30_uartcfgs[] = {
54         /* Normal serial port */
55         [0] = {
56                 .hwport      = 0,
57                 .flags       = 0,
58                 .ucon        = 0x2c5,
59                 .ulcon       = 0x03,
60                 .ufcon       = 0x51,
61         },
62         /* IR port */
63         [1] = {
64                 .hwport      = 1,
65                 .flags       = 0,
66                 .uart_flags  = UPF_CONS_FLOW,
67                 .ucon        = 0x2c5,
68                 .ulcon       = 0x43,
69                 .ufcon       = 0x51,
70         },
71         /* The BlueTooth controller is connected to port 2 */
72         [2] = {
73                 .hwport      = 2,
74                 .flags       = 0,
75                 .ucon        = 0x2c5,
76                 .ulcon       = 0x03,
77                 .ufcon       = 0x51,
78         },
79 };
80
81 static void n30_udc_pullup(enum s3c2410_udc_cmd_e cmd)
82 {
83         switch (cmd)
84         {
85                 case S3C2410_UDC_P_ENABLE :
86                         s3c2410_gpio_setpin(S3C2410_GPB3, 1);
87                         break;
88                 case S3C2410_UDC_P_DISABLE :
89                         s3c2410_gpio_setpin(S3C2410_GPB3, 0);
90                         break;
91                 case S3C2410_UDC_P_RESET :
92                         break;
93                 default:
94                         break;
95         }
96 }
97
98 static struct s3c2410_udc_mach_info n30_udc_cfg __initdata = {
99         .udc_command            = n30_udc_pullup,
100         .vbus_pin               = S3C2410_GPG1,
101         .vbus_pin_inverted      = 0,
102 };
103
104 static struct gpio_keys_button n30_buttons[] = {
105         {
106                 .gpio           = S3C2410_GPF0,
107                 .code           = KEY_POWER,
108                 .desc           = "Power",
109                 .active_low     = 0,
110         },
111         {
112                 .gpio           = S3C2410_GPG9,
113                 .code           = KEY_UP,
114                 .desc           = "Thumbwheel Up",
115                 .active_low     = 0,
116         },
117         {
118                 .gpio           = S3C2410_GPG8,
119                 .code           = KEY_DOWN,
120                 .desc           = "Thumbwheel Down",
121                 .active_low     = 0,
122         },
123         {
124                 .gpio           = S3C2410_GPG7,
125                 .code           = KEY_ENTER,
126                 .desc           = "Thumbwheel Press",
127                 .active_low     = 0,
128         },
129         {
130                 .gpio           = S3C2410_GPF7,
131                 .code           = KEY_HOMEPAGE,
132                 .desc           = "Home",
133                 .active_low     = 0,
134         },
135         {
136                 .gpio           = S3C2410_GPF6,
137                 .code           = KEY_CALENDAR,
138                 .desc           = "Calendar",
139                 .active_low     = 0,
140         },
141         {
142                 .gpio           = S3C2410_GPF5,
143                 .code           = KEY_ADDRESSBOOK,
144                 .desc           = "Contacts",
145                 .active_low     = 0,
146         },
147         {
148                 .gpio           = S3C2410_GPF4,
149                 .code           = KEY_MAIL,
150                 .desc           = "Mail",
151                 .active_low     = 0,
152         },
153 };
154
155 static struct gpio_keys_platform_data n30_button_data = {
156         .buttons        = n30_buttons,
157         .nbuttons       = ARRAY_SIZE(n30_buttons),
158 };
159
160 static struct platform_device n30_button_device = {
161         .name           = "gpio-keys",
162         .id             = -1,
163         .dev            = {
164                 .platform_data  = &n30_button_data,
165         }
166 };
167
168 /* This is the bluetooth LED on the device. */
169 static struct s3c24xx_led_platdata n30_blue_led_pdata = {
170         .name           = "blue_led",
171         .gpio           = S3C2410_GPG6,
172         .def_trigger    = "",
173 };
174
175 /* This LED is driven by the battery microcontroller, and is blinking
176  * red, blinking green or solid green when the battery is low,
177  * charging or full respectively.  By driving GPD9 low, it's possible
178  * to force the LED to blink red, so call that warning LED.  */
179 static struct s3c24xx_led_platdata n30_warning_led_pdata = {
180         .name           = "warning_led",
181         .flags          = S3C24XX_LEDF_ACTLOW,
182         .gpio           = S3C2410_GPD9,
183         .def_trigger    = "",
184 };
185
186 static struct platform_device n30_blue_led = {
187         .name           = "s3c24xx_led",
188         .id             = 1,
189         .dev            = {
190                 .platform_data  = &n30_blue_led_pdata,
191         },
192 };
193
194 static struct platform_device n30_warning_led = {
195         .name           = "s3c24xx_led",
196         .id             = 2,
197         .dev            = {
198                 .platform_data  = &n30_warning_led_pdata,
199         },
200 };
201
202 static struct platform_device *n30_devices[] __initdata = {
203         &s3c_device_lcd,
204         &s3c_device_wdt,
205         &s3c_device_i2c,
206         &s3c_device_iis,
207         &s3c_device_usb,
208         &s3c_device_usbgadget,
209         &n30_button_device,
210         &n30_blue_led,
211         &n30_warning_led,
212 };
213
214 static struct s3c2410_platform_i2c n30_i2ccfg = {
215         .flags          = 0,
216         .slave_addr     = 0x10,
217         .bus_freq       = 10*1000,
218         .max_freq       = 10*1000,
219 };
220
221 static void __init n30_map_io(void)
222 {
223         s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
224         s3c24xx_init_clocks(0);
225         s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
226 }
227
228 static void __init n30_init_irq(void)
229 {
230         s3c24xx_init_irq();
231 }
232
233 /* GPB3 is the line that controls the pull-up for the USB D+ line */
234
235 static void __init n30_init(void)
236 {
237         s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
238         s3c24xx_udc_set_platdata(&n30_udc_cfg);
239
240         /* Turn off suspend on both USB ports, and switch the
241          * selectable USB port to USB device mode. */
242
243         s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
244                               S3C2410_MISCCR_USBSUSPND0 |
245                               S3C2410_MISCCR_USBSUSPND1, 0x0);
246
247         platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices));
248 }
249
250 MACHINE_START(N30, "Acer-N30")
251         /* Maintainer: Christer Weinigel <christer@weinigel.se>,
252                                 Ben Dooks <ben-linux@fluff.org>
253         */
254         .phys_io        = S3C2410_PA_UART,
255         .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
256         .boot_params    = S3C2410_SDRAM_PA + 0x100,
257         .timer          = &s3c24xx_timer,
258         .init_machine   = n30_init,
259         .init_irq       = n30_init_irq,
260         .map_io         = n30_map_io,
261 MACHINE_END