Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[pandora-kernel.git] / arch / arm / mach-omap1 / board-palmte.c
1 /*
2  * linux/arch/arm/mach-omap1/board-palmte.c
3  *
4  * Modified from board-generic.c
5  *
6  * Support for the Palm Tungsten E PDA.
7  *
8  * Original version : Laurent Gonzalez
9  *
10  * Maintainers : http://palmtelinux.sf.net
11  *                palmtelinux-developpers@lists.sf.net
12  *
13  * Copyright (c) 2006 Andrzej Zaborowski  <balrog@zabor.org>
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License version 2 as
17  * published by the Free Software Foundation.
18  */
19
20 #include <linux/kernel.h>
21 #include <linux/init.h>
22 #include <linux/input.h>
23 #include <linux/platform_device.h>
24 #include <linux/mtd/mtd.h>
25 #include <linux/mtd/partitions.h>
26 #include <linux/mtd/physmap.h>
27 #include <linux/spi/spi.h>
28 #include <linux/interrupt.h>
29 #include <linux/apm-emulation.h>
30
31 #include <mach/hardware.h>
32 #include <asm/mach-types.h>
33 #include <asm/mach/arch.h>
34 #include <asm/mach/map.h>
35
36 #include <mach/gpio.h>
37 #include <plat/flash.h>
38 #include <plat/mux.h>
39 #include <plat/usb.h>
40 #include <plat/tc.h>
41 #include <plat/dma.h>
42 #include <plat/board.h>
43 #include <plat/irda.h>
44 #include <plat/keypad.h>
45 #include <plat/common.h>
46
47 #define PALMTE_USBDETECT_GPIO   0
48 #define PALMTE_USB_OR_DC_GPIO   1
49 #define PALMTE_TSC_GPIO         4
50 #define PALMTE_PINTDAV_GPIO     6
51 #define PALMTE_MMC_WP_GPIO      8
52 #define PALMTE_MMC_POWER_GPIO   9
53 #define PALMTE_HDQ_GPIO         11
54 #define PALMTE_HEADPHONES_GPIO  14
55 #define PALMTE_SPEAKER_GPIO     15
56 #define PALMTE_DC_GPIO          OMAP_MPUIO(2)
57 #define PALMTE_MMC_SWITCH_GPIO  OMAP_MPUIO(4)
58 #define PALMTE_MMC1_GPIO        OMAP_MPUIO(6)
59 #define PALMTE_MMC2_GPIO        OMAP_MPUIO(7)
60 #define PALMTE_MMC3_GPIO        OMAP_MPUIO(11)
61
62 static void __init omap_palmte_init_irq(void)
63 {
64         omap1_init_common_hw();
65         omap_init_irq();
66         omap_gpio_init();
67 }
68
69 static const int palmte_keymap[] = {
70         KEY(0, 0, KEY_F1),              /* Calendar */
71         KEY(0, 1, KEY_F2),              /* Contacts */
72         KEY(0, 2, KEY_F3),              /* Tasks List */
73         KEY(0, 3, KEY_F4),              /* Note Pad */
74         KEY(0, 4, KEY_POWER),
75         KEY(1, 0, KEY_LEFT),
76         KEY(1, 1, KEY_DOWN),
77         KEY(1, 2, KEY_UP),
78         KEY(1, 3, KEY_RIGHT),
79         KEY(1, 4, KEY_ENTER),
80         0,
81 };
82
83 static struct omap_kp_platform_data palmte_kp_data = {
84         .rows   = 8,
85         .cols   = 8,
86         .keymap = (int *) palmte_keymap,
87         .rep    = 1,
88         .delay  = 12,
89 };
90
91 static struct resource palmte_kp_resources[] = {
92         [0]     = {
93                 .start  = INT_KEYBOARD,
94                 .end    = INT_KEYBOARD,
95                 .flags  = IORESOURCE_IRQ,
96         },
97 };
98
99 static struct platform_device palmte_kp_device = {
100         .name           = "omap-keypad",
101         .id             = -1,
102         .dev            = {
103                 .platform_data  = &palmte_kp_data,
104         },
105         .num_resources  = ARRAY_SIZE(palmte_kp_resources),
106         .resource       = palmte_kp_resources,
107 };
108
109 static struct mtd_partition palmte_rom_partitions[] = {
110         /* PalmOS "Small ROM", contains the bootloader and the debugger */
111         {
112                 .name           = "smallrom",
113                 .offset         = 0,
114                 .size           = 0xa000,
115                 .mask_flags     = MTD_WRITEABLE,
116         },
117         /* PalmOS "Big ROM", a filesystem with all the OS code and data */
118         {
119                 .name           = "bigrom",
120                 .offset         = SZ_128K,
121                 /*
122                  * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
123                  * 0x7b0000 bytes in the English-only ("enUS") version.
124                  */
125                 .size           = 0x7b0000,
126                 .mask_flags     = MTD_WRITEABLE,
127         },
128 };
129
130 static struct physmap_flash_data palmte_rom_data = {
131         .width          = 2,
132         .set_vpp        = omap1_set_vpp,
133         .parts          = palmte_rom_partitions,
134         .nr_parts       = ARRAY_SIZE(palmte_rom_partitions),
135 };
136
137 static struct resource palmte_rom_resource = {
138         .start          = OMAP_CS0_PHYS,
139         .end            = OMAP_CS0_PHYS + SZ_8M - 1,
140         .flags          = IORESOURCE_MEM,
141 };
142
143 static struct platform_device palmte_rom_device = {
144         .name           = "physmap-flash",
145         .id             = -1,
146         .dev            = {
147                 .platform_data  = &palmte_rom_data,
148         },
149         .num_resources  = 1,
150         .resource       = &palmte_rom_resource,
151 };
152
153 static struct platform_device palmte_lcd_device = {
154         .name           = "lcd_palmte",
155         .id             = -1,
156 };
157
158 static struct omap_backlight_config palmte_backlight_config = {
159         .default_intensity      = 0xa0,
160 };
161
162 static struct platform_device palmte_backlight_device = {
163         .name           = "omap-bl",
164         .id             = -1,
165         .dev            = {
166                 .platform_data  = &palmte_backlight_config,
167         },
168 };
169
170 static struct omap_irda_config palmte_irda_config = {
171         .transceiver_cap        = IR_SIRMODE,
172         .rx_channel             = OMAP_DMA_UART3_RX,
173         .tx_channel             = OMAP_DMA_UART3_TX,
174         .dest_start             = UART3_THR,
175         .src_start              = UART3_RHR,
176         .tx_trigger             = 0,
177         .rx_trigger             = 0,
178 };
179
180 static struct resource palmte_irda_resources[] = {
181         [0]     = {
182                 .start  = INT_UART3,
183                 .end    = INT_UART3,
184                 .flags  = IORESOURCE_IRQ,
185         },
186 };
187
188 static struct platform_device palmte_irda_device = {
189         .name           = "omapirda",
190         .id             = -1,
191         .dev            = {
192                 .platform_data  = &palmte_irda_config,
193         },
194         .num_resources  = ARRAY_SIZE(palmte_irda_resources),
195         .resource       = palmte_irda_resources,
196 };
197
198 static struct platform_device *palmte_devices[] __initdata = {
199         &palmte_rom_device,
200         &palmte_kp_device,
201         &palmte_lcd_device,
202         &palmte_backlight_device,
203         &palmte_irda_device,
204 };
205
206 static struct omap_usb_config palmte_usb_config __initdata = {
207         .register_dev   = 1,    /* Mini-B only receptacle */
208         .hmc_mode       = 0,
209         .pins[0]        = 2,
210 };
211
212 static struct omap_lcd_config palmte_lcd_config __initdata = {
213         .ctrl_name      = "internal",
214 };
215
216 #ifdef CONFIG_APM
217 /*
218  * Values measured in 10 minute intervals averaged over 10 samples.
219  * May differ slightly from device to device but should be accurate
220  * enough to give basic idea of battery life left and trigger
221  * potential alerts.
222  */
223 static const int palmte_battery_sample[] = {
224         2194, 2157, 2138, 2120,
225         2104, 2089, 2075, 2061,
226         2048, 2038, 2026, 2016,
227         2008, 1998, 1989, 1980,
228         1970, 1958, 1945, 1928,
229         1910, 1888, 1860, 1827,
230         1791, 1751, 1709, 1656,
231 };
232
233 #define INTERVAL                10
234 #define BATTERY_HIGH_TRESHOLD   66
235 #define BATTERY_LOW_TRESHOLD    33
236
237 static void palmte_get_power_status(struct apm_power_info *info, int *battery)
238 {
239         int charging, batt, hi, lo, mid;
240
241         charging = !gpio_get_value(PALMTE_DC_GPIO);
242         batt = battery[0];
243         if (charging)
244                 batt -= 60;
245
246         hi = ARRAY_SIZE(palmte_battery_sample);
247         lo = 0;
248
249         info->battery_flag = 0;
250         info->units = APM_UNITS_MINS;
251
252         if (batt > palmte_battery_sample[lo]) {
253                 info->battery_life = 100;
254                 info->time = INTERVAL * ARRAY_SIZE(palmte_battery_sample);
255         } else if (batt <= palmte_battery_sample[hi - 1]) {
256                 info->battery_life = 0;
257                 info->time = 0;
258         } else {
259                 while (hi > lo + 1) {
260                         mid = (hi + lo) >> 1;
261                         if (batt <= palmte_battery_sample[mid])
262                                 lo = mid;
263                         else
264                                 hi = mid;
265                 }
266
267                 mid = palmte_battery_sample[lo] - palmte_battery_sample[hi];
268                 hi = palmte_battery_sample[lo] - batt;
269                 info->battery_life = 100 - (100 * lo + 100 * hi / mid) /
270                         ARRAY_SIZE(palmte_battery_sample);
271                 info->time = INTERVAL * (ARRAY_SIZE(palmte_battery_sample) -
272                                 lo) - INTERVAL * hi / mid;
273         }
274
275         if (charging) {
276                 info->ac_line_status = APM_AC_ONLINE;
277                 info->battery_status = APM_BATTERY_STATUS_CHARGING;
278                 info->battery_flag |= APM_BATTERY_FLAG_CHARGING;
279         } else {
280                 info->ac_line_status = APM_AC_OFFLINE;
281                 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
282                         info->battery_status = APM_BATTERY_STATUS_HIGH;
283                 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
284                         info->battery_status = APM_BATTERY_STATUS_LOW;
285                 else
286                         info->battery_status = APM_BATTERY_STATUS_CRITICAL;
287         }
288
289         if (info->battery_life > BATTERY_HIGH_TRESHOLD)
290                 info->battery_flag |= APM_BATTERY_FLAG_HIGH;
291         else if (info->battery_life > BATTERY_LOW_TRESHOLD)
292                 info->battery_flag |= APM_BATTERY_FLAG_LOW;
293         else
294                 info->battery_flag |= APM_BATTERY_FLAG_CRITICAL;
295 }
296 #else
297 #define palmte_get_power_status NULL
298 #endif
299
300 static struct omap_board_config_kernel palmte_config[] __initdata = {
301         { OMAP_TAG_LCD,         &palmte_lcd_config },
302 };
303
304 static struct spi_board_info palmte_spi_info[] __initdata = {
305         {
306                 .modalias       = "tsc2102",
307                 .bus_num        = 2,    /* uWire (officially) */
308                 .chip_select    = 0,    /* As opposed to 3 */
309                 .irq            = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO),
310                 .max_speed_hz   = 8000000,
311         },
312 };
313
314 static void palmte_headphones_detect(void *data, int state)
315 {
316         if (state) {
317                 /* Headphones connected, disable speaker */
318                 gpio_set_value(PALMTE_SPEAKER_GPIO, 0);
319                 printk(KERN_INFO "PM: speaker off\n");
320         } else {
321                 /* Headphones unplugged, re-enable speaker */
322                 gpio_set_value(PALMTE_SPEAKER_GPIO, 1);
323                 printk(KERN_INFO "PM: speaker on\n");
324         }
325 }
326
327 static void __init palmte_misc_gpio_setup(void)
328 {
329         /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */
330         if (gpio_request(PALMTE_PINTDAV_GPIO, "TSC2102 PINTDAV") < 0) {
331                 printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n");
332                 return;
333         }
334         gpio_direction_input(PALMTE_PINTDAV_GPIO);
335
336         /* Set USB-or-DC-IN pin as input (unused) */
337         if (gpio_request(PALMTE_USB_OR_DC_GPIO, "USB/DC-IN") < 0) {
338                 printk(KERN_ERR "Could not reserve cable signal GPIO!\n");
339                 return;
340         }
341         gpio_direction_input(PALMTE_USB_OR_DC_GPIO);
342 }
343
344 static void __init omap_palmte_init(void)
345 {
346         /* mux pins for uarts */
347         omap_cfg_reg(UART1_TX);
348         omap_cfg_reg(UART1_RTS);
349         omap_cfg_reg(UART2_TX);
350         omap_cfg_reg(UART2_RTS);
351         omap_cfg_reg(UART3_TX);
352         omap_cfg_reg(UART3_RX);
353
354         omap_board_config = palmte_config;
355         omap_board_config_size = ARRAY_SIZE(palmte_config);
356
357         platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
358
359         spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
360         palmte_misc_gpio_setup();
361         omap_serial_init();
362         omap_usb_init(&palmte_usb_config);
363         omap_register_i2c_bus(1, 100, NULL, 0);
364 }
365
366 static void __init omap_palmte_map_io(void)
367 {
368         omap1_map_common_io();
369 }
370
371 MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
372         .phys_io        = 0xfff00000,
373         .io_pg_offst    = ((0xfef00000) >> 18) & 0xfffc,
374         .boot_params    = 0x10000100,
375         .map_io         = omap_palmte_map_io,
376         .init_irq       = omap_palmte_init_irq,
377         .init_machine   = omap_palmte_init,
378         .timer          = &omap_timer,
379 MACHINE_END