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>
46 static void __init omap_palmte_init_irq(void)
48 omap1_init_common_hw();
53 static const int palmte_keymap[] = {
54 KEY(0, 0, KEY_F1), /* Calendar */
55 KEY(0, 1, KEY_F2), /* Contacts */
56 KEY(0, 2, KEY_F3), /* Tasks List */
57 KEY(0, 3, KEY_F4), /* Note Pad */
67 static struct omap_kp_platform_data palmte_kp_data = {
70 .keymap = (int *) palmte_keymap,
75 static struct resource palmte_kp_resources[] = {
77 .start = INT_KEYBOARD,
79 .flags = IORESOURCE_IRQ,
83 static struct platform_device palmte_kp_device = {
84 .name = "omap-keypad",
87 .platform_data = &palmte_kp_data,
89 .num_resources = ARRAY_SIZE(palmte_kp_resources),
90 .resource = palmte_kp_resources,
93 static struct mtd_partition palmte_rom_partitions[] = {
94 /* PalmOS "Small ROM", contains the bootloader and the debugger */
99 .mask_flags = MTD_WRITEABLE,
101 /* PalmOS "Big ROM", a filesystem with all the OS code and data */
106 * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
107 * 0x7b0000 bytes in the English-only ("enUS") version.
110 .mask_flags = MTD_WRITEABLE,
114 static struct flash_platform_data palmte_rom_data = {
115 .map_name = "map_rom",
117 .parts = palmte_rom_partitions,
118 .nr_parts = ARRAY_SIZE(palmte_rom_partitions),
121 static struct resource palmte_rom_resource = {
122 .start = OMAP_CS0_PHYS,
123 .end = OMAP_CS0_PHYS + SZ_8M - 1,
124 .flags = IORESOURCE_MEM,
127 static struct platform_device palmte_rom_device = {
131 .platform_data = &palmte_rom_data,
134 .resource = &palmte_rom_resource,
137 static struct platform_device palmte_lcd_device = {
138 .name = "lcd_palmte",
142 static struct omap_backlight_config palmte_backlight_config = {
143 .default_intensity = 0xa0,
146 static struct platform_device palmte_backlight_device = {
150 .platform_data = &palmte_backlight_config,
154 static struct omap_irda_config palmte_irda_config = {
155 .transceiver_cap = IR_SIRMODE,
156 .rx_channel = OMAP_DMA_UART3_RX,
157 .tx_channel = OMAP_DMA_UART3_TX,
158 .dest_start = UART3_THR,
159 .src_start = UART3_RHR,
164 static struct resource palmte_irda_resources[] = {
168 .flags = IORESOURCE_IRQ,
172 static struct platform_device palmte_irda_device = {
176 .platform_data = &palmte_irda_config,
178 .num_resources = ARRAY_SIZE(palmte_irda_resources),
179 .resource = palmte_irda_resources,
182 static struct platform_device *palmte_devices[] __initdata = {
186 &palmte_backlight_device,
190 static struct omap_usb_config palmte_usb_config __initdata = {
191 .register_dev = 1, /* Mini-B only receptacle */
196 static struct omap_lcd_config palmte_lcd_config __initdata = {
197 .ctrl_name = "internal",
200 static struct omap_uart_config palmte_uart_config __initdata = {
201 .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
206 * Values measured in 10 minute intervals averaged over 10 samples.
207 * May differ slightly from device to device but should be accurate
208 * enough to give basic idea of battery life left and trigger
211 static const int palmte_battery_sample[] = {
212 2194, 2157, 2138, 2120,
213 2104, 2089, 2075, 2061,
214 2048, 2038, 2026, 2016,
215 2008, 1998, 1989, 1980,
216 1970, 1958, 1945, 1928,
217 1910, 1888, 1860, 1827,
218 1791, 1751, 1709, 1656,
222 #define BATTERY_HIGH_TRESHOLD 66
223 #define BATTERY_LOW_TRESHOLD 33
225 static void palmte_get_power_status(struct apm_power_info *info, int *battery)
227 int charging, batt, hi, lo, mid;
229 charging = !gpio_get_value(PALMTE_DC_GPIO);
234 hi = ARRAY_SIZE(palmte_battery_sample);
237 info->battery_flag = 0;
238 info->units = APM_UNITS_MINS;
240 if (batt > palmte_battery_sample[lo]) {
241 info->battery_life = 100;
242 info->time = INTERVAL * ARRAY_SIZE(palmte_battery_sample);
243 } else if (batt <= palmte_battery_sample[hi - 1]) {
244 info->battery_life = 0;
247 while (hi > lo + 1) {
248 mid = (hi + lo) >> 1;
249 if (batt <= palmte_battery_sample[mid])
255 mid = palmte_battery_sample[lo] - palmte_battery_sample[hi];
256 hi = palmte_battery_sample[lo] - batt;
257 info->battery_life = 100 - (100 * lo + 100 * hi / mid) /
258 ARRAY_SIZE(palmte_battery_sample);
259 info->time = INTERVAL * (ARRAY_SIZE(palmte_battery_sample) -
260 lo) - INTERVAL * hi / mid;
264 info->ac_line_status = APM_AC_ONLINE;
265 info->battery_status = APM_BATTERY_STATUS_CHARGING;
266 info->battery_flag |= APM_BATTERY_FLAG_CHARGING;
268 info->ac_line_status = APM_AC_OFFLINE;
269 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
270 info->battery_status = APM_BATTERY_STATUS_HIGH;
271 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
272 info->battery_status = APM_BATTERY_STATUS_LOW;
274 info->battery_status = APM_BATTERY_STATUS_CRITICAL;
277 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
278 info->battery_flag |= APM_BATTERY_FLAG_HIGH;
279 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
280 info->battery_flag |= APM_BATTERY_FLAG_LOW;
282 info->battery_flag |= APM_BATTERY_FLAG_CRITICAL;
285 #define palmte_get_power_status NULL
288 static struct omap_board_config_kernel palmte_config[] __initdata = {
289 { OMAP_TAG_USB, &palmte_usb_config },
290 { OMAP_TAG_LCD, &palmte_lcd_config },
291 { OMAP_TAG_UART, &palmte_uart_config },
294 static struct spi_board_info palmte_spi_info[] __initdata = {
296 .modalias = "tsc2102",
297 .bus_num = 2, /* uWire (officially) */
298 .chip_select = 0, /* As opposed to 3 */
299 .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO),
300 .max_speed_hz = 8000000,
304 static void palmte_headphones_detect(void *data, int state)
307 /* Headphones connected, disable speaker */
308 gpio_set_value(PALMTE_SPEAKER_GPIO, 0);
309 printk(KERN_INFO "PM: speaker off\n");
311 /* Headphones unplugged, re-enable speaker */
312 gpio_set_value(PALMTE_SPEAKER_GPIO, 1);
313 printk(KERN_INFO "PM: speaker on\n");
317 static void __init palmte_misc_gpio_setup(void)
319 /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */
320 if (gpio_request(PALMTE_PINTDAV_GPIO, "TSC2102 PINTDAV") < 0) {
321 printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n");
324 gpio_direction_input(PALMTE_PINTDAV_GPIO);
326 /* Set USB-or-DC-IN pin as input (unused) */
327 if (gpio_request(PALMTE_USB_OR_DC_GPIO, "USB/DC-IN") < 0) {
328 printk(KERN_ERR "Could not reserve cable signal GPIO!\n");
331 gpio_direction_input(PALMTE_USB_OR_DC_GPIO);
334 static void __init omap_palmte_init(void)
336 omap_board_config = palmte_config;
337 omap_board_config_size = ARRAY_SIZE(palmte_config);
339 platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
341 spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
342 palmte_misc_gpio_setup();
344 omap_register_i2c_bus(1, 100, NULL, 0);
347 static void __init omap_palmte_map_io(void)
349 omap1_map_common_io();
352 MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
353 .phys_io = 0xfff00000,
354 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
355 .boot_params = 0x10000100,
356 .map_io = omap_palmte_map_io,
357 .init_irq = omap_palmte_init_irq,
358 .init_machine = omap_palmte_init,
359 .timer = &omap_timer,