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