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/mcbsp.h>
46 #include <mach/omap-alsa.h>
48 static void __init omap_palmte_init_irq(void)
50 omap1_init_common_hw();
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 */
69 static struct omap_kp_platform_data palmte_kp_data = {
72 .keymap = (int *) palmte_keymap,
77 static struct resource palmte_kp_resources[] = {
79 .start = INT_KEYBOARD,
81 .flags = IORESOURCE_IRQ,
85 static struct platform_device palmte_kp_device = {
86 .name = "omap-keypad",
89 .platform_data = &palmte_kp_data,
91 .num_resources = ARRAY_SIZE(palmte_kp_resources),
92 .resource = palmte_kp_resources,
95 static struct mtd_partition palmte_rom_partitions[] = {
96 /* PalmOS "Small ROM", contains the bootloader and the debugger */
101 .mask_flags = MTD_WRITEABLE,
103 /* PalmOS "Big ROM", a filesystem with all the OS code and data */
108 * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
109 * 0x7b0000 bytes in the English-only ("enUS") version.
112 .mask_flags = MTD_WRITEABLE,
116 static struct flash_platform_data palmte_rom_data = {
117 .map_name = "map_rom",
119 .parts = palmte_rom_partitions,
120 .nr_parts = ARRAY_SIZE(palmte_rom_partitions),
123 static struct resource palmte_rom_resource = {
124 .start = OMAP_CS0_PHYS,
125 .end = OMAP_CS0_PHYS + SZ_8M - 1,
126 .flags = IORESOURCE_MEM,
129 static struct platform_device palmte_rom_device = {
133 .platform_data = &palmte_rom_data,
136 .resource = &palmte_rom_resource,
139 static struct platform_device palmte_lcd_device = {
140 .name = "lcd_palmte",
144 static struct omap_backlight_config palmte_backlight_config = {
145 .default_intensity = 0xa0,
148 static struct platform_device palmte_backlight_device = {
152 .platform_data = &palmte_backlight_config,
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,
166 static struct resource palmte_irda_resources[] = {
170 .flags = IORESOURCE_IRQ,
174 static struct platform_device palmte_irda_device = {
178 .platform_data = &palmte_irda_config,
180 .num_resources = ARRAY_SIZE(palmte_irda_resources),
181 .resource = palmte_irda_resources,
184 static struct platform_device *palmte_devices[] __initdata = {
188 &palmte_backlight_device,
192 static struct omap_usb_config palmte_usb_config __initdata = {
193 .register_dev = 1, /* Mini-B only receptacle */
198 static struct omap_lcd_config palmte_lcd_config __initdata = {
199 .ctrl_name = "internal",
202 static struct omap_uart_config palmte_uart_config __initdata = {
203 .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
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,
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, */
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
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,
242 #define BATTERY_HIGH_TRESHOLD 66
243 #define BATTERY_LOW_TRESHOLD 33
245 static void palmte_get_power_status(struct apm_power_info *info, int *battery)
247 int charging, batt, hi, lo, mid;
249 charging = !gpio_get_value(PALMTE_DC_GPIO);
254 hi = ARRAY_SIZE(palmte_battery_sample);
257 info->battery_flag = 0;
258 info->units = APM_UNITS_MINS;
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;
267 while (hi > lo + 1) {
268 mid = (hi + lo) >> 1;
269 if (batt <= palmte_battery_sample[mid])
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;
284 info->ac_line_status = APM_AC_ONLINE;
285 info->battery_status = APM_BATTERY_STATUS_CHARGING;
286 info->battery_flag |= APM_BATTERY_FLAG_CHARGING;
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;
294 info->battery_status = APM_BATTERY_STATUS_CRITICAL;
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;
302 info->battery_flag |= APM_BATTERY_FLAG_CRITICAL;
305 #define palmte_get_power_status NULL
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 },
314 static struct spi_board_info palmte_spi_info[] __initdata = {
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,
324 static void palmte_headphones_detect(void *data, int state)
327 /* Headphones connected, disable speaker */
328 gpio_set_value(PALMTE_SPEAKER_GPIO, 0);
329 printk(KERN_INFO "PM: speaker off\n");
331 /* Headphones unplugged, re-enable speaker */
332 gpio_set_value(PALMTE_SPEAKER_GPIO, 1);
333 printk(KERN_INFO "PM: speaker on\n");
337 static void __init palmte_misc_gpio_setup(void)
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");
344 gpio_direction_input(PALMTE_PINTDAV_GPIO);
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");
351 gpio_direction_input(PALMTE_USB_OR_DC_GPIO);
354 static void __init omap_palmte_init(void)
356 omap_board_config = palmte_config;
357 omap_board_config_size = ARRAY_SIZE(palmte_config);
359 platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
361 spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
362 palmte_misc_gpio_setup();
364 omap_register_i2c_bus(1, 100, NULL, 0);
367 static void __init omap_palmte_map_io(void)
369 omap1_map_common_io();
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,