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