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