2 * linux/arch/arm/mach-omap1/board-palmte.c
4 * Modified from board-generic.c
6 * Support for the Palm Tungsten E PDA.
8 * Original version : Laurent Gonzalez
10 * Maintainers : http://palmtelinux.sf.net
11 * palmtelinux-developpers@lists.sf.net
13 * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
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.
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>
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>
36 #include <mach/gpio.h>
41 #include <mach/board.h>
42 #include <mach/irda.h>
43 #include <mach/keypad.h>
44 #include <mach/common.h>
45 #include <mach/gpio-switch.h>
47 static void __init omap_palmte_init_irq(void)
49 omap1_init_common_hw();
54 static const int palmte_keymap[] = {
55 KEY(0, 0, KEY_F1), /* Calendar */
56 KEY(0, 1, KEY_F2), /* Contacts */
57 KEY(0, 2, KEY_F3), /* Tasks List */
58 KEY(0, 3, KEY_F4), /* Note Pad */
68 static struct omap_kp_platform_data palmte_kp_data = {
71 .keymap = (int *) palmte_keymap,
76 static struct resource palmte_kp_resources[] = {
78 .start = INT_KEYBOARD,
80 .flags = IORESOURCE_IRQ,
84 static struct platform_device palmte_kp_device = {
85 .name = "omap-keypad",
88 .platform_data = &palmte_kp_data,
90 .num_resources = ARRAY_SIZE(palmte_kp_resources),
91 .resource = palmte_kp_resources,
94 static struct mtd_partition palmte_rom_partitions[] = {
95 /* PalmOS "Small ROM", contains the bootloader and the debugger */
100 .mask_flags = MTD_WRITEABLE,
102 /* PalmOS "Big ROM", a filesystem with all the OS code and data */
107 * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
108 * 0x7b0000 bytes in the English-only ("enUS") version.
111 .mask_flags = MTD_WRITEABLE,
115 static struct flash_platform_data palmte_rom_data = {
116 .map_name = "map_rom",
118 .parts = palmte_rom_partitions,
119 .nr_parts = ARRAY_SIZE(palmte_rom_partitions),
122 static struct resource palmte_rom_resource = {
123 .start = OMAP_CS0_PHYS,
124 .end = OMAP_CS0_PHYS + SZ_8M - 1,
125 .flags = IORESOURCE_MEM,
128 static struct platform_device palmte_rom_device = {
132 .platform_data = &palmte_rom_data,
135 .resource = &palmte_rom_resource,
138 static struct platform_device palmte_lcd_device = {
139 .name = "lcd_palmte",
143 static struct omap_backlight_config palmte_backlight_config = {
144 .default_intensity = 0xa0,
147 static struct platform_device palmte_backlight_device = {
151 .platform_data = &palmte_backlight_config,
155 static struct omap_irda_config palmte_irda_config = {
156 .transceiver_cap = IR_SIRMODE,
157 .rx_channel = OMAP_DMA_UART3_RX,
158 .tx_channel = OMAP_DMA_UART3_TX,
159 .dest_start = UART3_THR,
160 .src_start = UART3_RHR,
165 static struct resource palmte_irda_resources[] = {
169 .flags = IORESOURCE_IRQ,
173 static struct platform_device palmte_irda_device = {
177 .platform_data = &palmte_irda_config,
179 .num_resources = ARRAY_SIZE(palmte_irda_resources),
180 .resource = palmte_irda_resources,
183 static struct platform_device *palmte_devices[] __initdata = {
187 &palmte_backlight_device,
191 static struct omap_usb_config palmte_usb_config __initdata = {
192 .register_dev = 1, /* Mini-B only receptacle */
197 static struct omap_lcd_config palmte_lcd_config __initdata = {
198 .ctrl_name = "internal",
201 static struct omap_uart_config palmte_uart_config __initdata = {
202 .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
207 * Values measured in 10 minute intervals averaged over 10 samples.
208 * May differ slightly from device to device but should be accurate
209 * enough to give basic idea of battery life left and trigger
212 static const int palmte_battery_sample[] = {
213 2194, 2157, 2138, 2120,
214 2104, 2089, 2075, 2061,
215 2048, 2038, 2026, 2016,
216 2008, 1998, 1989, 1980,
217 1970, 1958, 1945, 1928,
218 1910, 1888, 1860, 1827,
219 1791, 1751, 1709, 1656,
223 #define BATTERY_HIGH_TRESHOLD 66
224 #define BATTERY_LOW_TRESHOLD 33
226 static void palmte_get_power_status(struct apm_power_info *info, int *battery)
228 int charging, batt, hi, lo, mid;
230 charging = !gpio_get_value(PALMTE_DC_GPIO);
235 hi = ARRAY_SIZE(palmte_battery_sample);
238 info->battery_flag = 0;
239 info->units = APM_UNITS_MINS;
241 if (batt > palmte_battery_sample[lo]) {
242 info->battery_life = 100;
243 info->time = INTERVAL * ARRAY_SIZE(palmte_battery_sample);
244 } else if (batt <= palmte_battery_sample[hi - 1]) {
245 info->battery_life = 0;
248 while (hi > lo + 1) {
249 mid = (hi + lo) >> 1;
250 if (batt <= palmte_battery_sample[mid])
256 mid = palmte_battery_sample[lo] - palmte_battery_sample[hi];
257 hi = palmte_battery_sample[lo] - batt;
258 info->battery_life = 100 - (100 * lo + 100 * hi / mid) /
259 ARRAY_SIZE(palmte_battery_sample);
260 info->time = INTERVAL * (ARRAY_SIZE(palmte_battery_sample) -
261 lo) - INTERVAL * hi / mid;
265 info->ac_line_status = APM_AC_ONLINE;
266 info->battery_status = APM_BATTERY_STATUS_CHARGING;
267 info->battery_flag |= APM_BATTERY_FLAG_CHARGING;
269 info->ac_line_status = APM_AC_OFFLINE;
270 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
271 info->battery_status = APM_BATTERY_STATUS_HIGH;
272 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
273 info->battery_status = APM_BATTERY_STATUS_LOW;
275 info->battery_status = APM_BATTERY_STATUS_CRITICAL;
278 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
279 info->battery_flag |= APM_BATTERY_FLAG_HIGH;
280 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
281 info->battery_flag |= APM_BATTERY_FLAG_LOW;
283 info->battery_flag |= APM_BATTERY_FLAG_CRITICAL;
286 #define palmte_get_power_status NULL
289 static struct omap_board_config_kernel palmte_config[] __initdata = {
290 { OMAP_TAG_USB, &palmte_usb_config },
291 { OMAP_TAG_LCD, &palmte_lcd_config },
292 { OMAP_TAG_UART, &palmte_uart_config },
295 static struct spi_board_info palmte_spi_info[] __initdata = {
297 .modalias = "tsc2102",
298 .bus_num = 2, /* uWire (officially) */
299 .chip_select = 0, /* As opposed to 3 */
300 .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO),
301 .max_speed_hz = 8000000,
305 static void palmte_headphones_detect(void *data, int state)
308 /* Headphones connected, disable speaker */
309 gpio_set_value(PALMTE_SPEAKER_GPIO, 0);
310 printk(KERN_INFO "PM: speaker off\n");
312 /* Headphones unplugged, re-enable speaker */
313 gpio_set_value(PALMTE_SPEAKER_GPIO, 1);
314 printk(KERN_INFO "PM: speaker on\n");
318 static struct omap_gpio_switch palmte_switches[] __initdata = {
319 /* Speaker-enable pin is an output */
321 .name = "speaker-enable",
322 .gpio = PALMTE_SPEAKER_GPIO,
323 .type = OMAP_GPIO_SWITCH_TYPE_ACTIVITY,
324 .flags = OMAP_GPIO_SWITCH_FLAG_OUTPUT |
325 OMAP_GPIO_SWITCH_FLAG_INVERTED,
327 /* Indicates whether power is from DC-IN or battery */
330 .gpio = PALMTE_DC_GPIO,
331 .type = OMAP_GPIO_SWITCH_TYPE_CONNECTION,
332 .flags = OMAP_GPIO_SWITCH_FLAG_INVERTED,
334 /* Indicates whether a USB host is on the other end of the cable */
337 .gpio = PALMTE_USBDETECT_GPIO,
338 .type = OMAP_GPIO_SWITCH_TYPE_CONNECTION,
340 /* High when headphones jack is plugged in */
342 .name = "headphones",
343 .gpio = PALMTE_HEADPHONES_GPIO,
344 .type = OMAP_GPIO_SWITCH_TYPE_CONNECTION,
345 .notify = palmte_headphones_detect,
349 static void __init palmte_misc_gpio_setup(void)
351 /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */
352 if (gpio_request(PALMTE_PINTDAV_GPIO, "TSC2102 PINTDAV") < 0) {
353 printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n");
356 gpio_direction_input(PALMTE_PINTDAV_GPIO);
358 /* Set USB-or-DC-IN pin as input (unused) */
359 if (gpio_request(PALMTE_USB_OR_DC_GPIO, "USB/DC-IN") < 0) {
360 printk(KERN_ERR "Could not reserve cable signal GPIO!\n");
363 gpio_direction_input(PALMTE_USB_OR_DC_GPIO);
366 static void __init omap_palmte_init(void)
368 omap_board_config = palmte_config;
369 omap_board_config_size = ARRAY_SIZE(palmte_config);
371 platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
373 spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
375 omap_register_gpio_switches(palmte_switches,
376 ARRAY_SIZE(palmte_switches));
378 palmte_misc_gpio_setup();
380 omap_register_i2c_bus(1, 100, NULL, 0);
383 static void __init omap_palmte_map_io(void)
385 omap1_map_common_io();
388 MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
389 .phys_io = 0xfff00000,
390 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
391 .boot_params = 0x10000100,
392 .map_io = omap_palmte_map_io,
393 .init_irq = omap_palmte_init_irq,
394 .init_machine = omap_palmte_init,
395 .timer = &omap_timer,