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>
47 #include <mach/gpio-switch.h>
49 static void __init omap_palmte_init_irq(void)
51 omap1_init_common_hw();
56 static 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 */
70 static struct omap_kp_platform_data palmte_kp_data = {
73 .keymap = (int *) palmte_keymap,
78 static struct resource palmte_kp_resources[] = {
80 .start = INT_KEYBOARD,
82 .flags = IORESOURCE_IRQ,
86 static struct platform_device palmte_kp_device = {
87 .name = "omap-keypad",
90 .platform_data = &palmte_kp_data,
92 .num_resources = ARRAY_SIZE(palmte_kp_resources),
93 .resource = palmte_kp_resources,
96 static struct mtd_partition palmte_rom_partitions[] = {
97 /* PalmOS "Small ROM", contains the bootloader and the debugger */
102 .mask_flags = MTD_WRITEABLE,
104 /* PalmOS "Big ROM", a filesystem with all the OS code and data */
109 * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
110 * 0x7b0000 bytes in the English-only ("enUS") version.
113 .mask_flags = MTD_WRITEABLE,
117 static struct flash_platform_data palmte_rom_data = {
118 .map_name = "map_rom",
120 .parts = palmte_rom_partitions,
121 .nr_parts = ARRAY_SIZE(palmte_rom_partitions),
124 static struct resource palmte_rom_resource = {
125 .start = OMAP_CS0_PHYS,
126 .end = OMAP_CS0_PHYS + SZ_8M - 1,
127 .flags = IORESOURCE_MEM,
130 static struct platform_device palmte_rom_device = {
134 .platform_data = &palmte_rom_data,
137 .resource = &palmte_rom_resource,
140 static struct platform_device palmte_lcd_device = {
141 .name = "lcd_palmte",
145 static struct omap_backlight_config palmte_backlight_config = {
146 .default_intensity = 0xa0,
149 static struct platform_device palmte_backlight_device = {
153 .platform_data = &palmte_backlight_config,
157 static 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,
167 static struct resource palmte_irda_resources[] = {
171 .flags = IORESOURCE_IRQ,
175 static struct platform_device palmte_irda_device = {
179 .platform_data = &palmte_irda_config,
181 .num_resources = ARRAY_SIZE(palmte_irda_resources),
182 .resource = palmte_irda_resources,
185 static struct platform_device *palmte_devices[] __initdata = {
189 &palmte_backlight_device,
193 static struct omap_usb_config palmte_usb_config __initdata = {
194 .register_dev = 1, /* Mini-B only receptacle */
199 static struct omap_lcd_config palmte_lcd_config __initdata = {
200 .ctrl_name = "internal",
203 static struct omap_uart_config palmte_uart_config __initdata = {
204 .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
207 static struct omap_mcbsp_reg_cfg palmte_mcbsp1_regs = {
208 .spcr2 = FRST | GRST | XRST | XINTM(3),
209 .xcr2 = XDATDLY(1) | XFIG,
210 .xcr1 = XWDLEN1(OMAP_MCBSP_WORD_32),
211 .pcr0 = SCLKME | FSXP | CLKXP,
214 static struct omap_alsa_codec_config palmte_alsa_config = {
215 .name = "TSC2102 audio",
216 .mcbsp_regs_alsa = &palmte_mcbsp1_regs,
217 .codec_configure_dev = NULL, /* tsc2102_configure, */
218 .codec_set_samplerate = NULL, /* tsc2102_set_samplerate, */
219 .codec_clock_setup = NULL, /* tsc2102_clock_setup, */
220 .codec_clock_on = NULL, /* tsc2102_clock_on, */
221 .codec_clock_off = NULL, /* tsc2102_clock_off, */
222 .get_default_samplerate = NULL, /* tsc2102_get_default_samplerate, */
227 * Values measured in 10 minute intervals averaged over 10 samples.
228 * May differ slightly from device to device but should be accurate
229 * enough to give basic idea of battery life left and trigger
232 static const int palmte_battery_sample[] = {
233 2194, 2157, 2138, 2120,
234 2104, 2089, 2075, 2061,
235 2048, 2038, 2026, 2016,
236 2008, 1998, 1989, 1980,
237 1970, 1958, 1945, 1928,
238 1910, 1888, 1860, 1827,
239 1791, 1751, 1709, 1656,
243 #define BATTERY_HIGH_TRESHOLD 66
244 #define BATTERY_LOW_TRESHOLD 33
246 static void palmte_get_power_status(struct apm_power_info *info, int *battery)
248 int charging, batt, hi, lo, mid;
250 charging = !omap_get_gpio_datain(PALMTE_DC_GPIO);
255 hi = ARRAY_SIZE(palmte_battery_sample);
258 info->battery_flag = 0;
259 info->units = APM_UNITS_MINS;
261 if (batt > palmte_battery_sample[lo]) {
262 info->battery_life = 100;
263 info->time = INTERVAL * ARRAY_SIZE(palmte_battery_sample);
264 } else if (batt <= palmte_battery_sample[hi - 1]) {
265 info->battery_life = 0;
268 while (hi > lo + 1) {
269 mid = (hi + lo) >> 1;
270 if (batt <= palmte_battery_sample[mid])
276 mid = palmte_battery_sample[lo] - palmte_battery_sample[hi];
277 hi = palmte_battery_sample[lo] - batt;
278 info->battery_life = 100 - (100 * lo + 100 * hi / mid) /
279 ARRAY_SIZE(palmte_battery_sample);
280 info->time = INTERVAL * (ARRAY_SIZE(palmte_battery_sample) -
281 lo) - INTERVAL * hi / mid;
285 info->ac_line_status = APM_AC_ONLINE;
286 info->battery_status = APM_BATTERY_STATUS_CHARGING;
287 info->battery_flag |= APM_BATTERY_FLAG_CHARGING;
289 info->ac_line_status = APM_AC_OFFLINE;
290 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
291 info->battery_status = APM_BATTERY_STATUS_HIGH;
292 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
293 info->battery_status = APM_BATTERY_STATUS_LOW;
295 info->battery_status = APM_BATTERY_STATUS_CRITICAL;
298 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
299 info->battery_flag |= APM_BATTERY_FLAG_HIGH;
300 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
301 info->battery_flag |= APM_BATTERY_FLAG_LOW;
303 info->battery_flag |= APM_BATTERY_FLAG_CRITICAL;
306 #define palmte_get_power_status NULL
309 static struct omap_board_config_kernel palmte_config[] __initdata = {
310 { OMAP_TAG_USB, &palmte_usb_config },
311 { OMAP_TAG_LCD, &palmte_lcd_config },
312 { OMAP_TAG_UART, &palmte_uart_config },
315 static struct spi_board_info palmte_spi_info[] __initdata = {
317 .modalias = "tsc2102",
318 .bus_num = 2, /* uWire (officially) */
319 .chip_select = 0, /* As opposed to 3 */
320 .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO),
321 .max_speed_hz = 8000000,
325 static void palmte_headphones_detect(void *data, int state)
328 /* Headphones connected, disable speaker */
329 omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO, 0);
330 printk(KERN_INFO "PM: speaker off\n");
332 /* Headphones unplugged, re-enable speaker */
333 omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO, 1);
334 printk(KERN_INFO "PM: speaker on\n");
338 static struct omap_gpio_switch palmte_switches[] __initdata = {
339 /* Speaker-enable pin is an output */
341 .name = "speaker-enable",
342 .gpio = PALMTE_SPEAKER_GPIO,
343 .type = OMAP_GPIO_SWITCH_TYPE_ACTIVITY,
344 .flags = OMAP_GPIO_SWITCH_FLAG_OUTPUT |
345 OMAP_GPIO_SWITCH_FLAG_INVERTED,
347 /* Indicates whether power is from DC-IN or battery */
350 .gpio = PALMTE_DC_GPIO,
351 .type = OMAP_GPIO_SWITCH_TYPE_CONNECTION,
352 .flags = OMAP_GPIO_SWITCH_FLAG_INVERTED,
354 /* Indicates whether a USB host is on the other end of the cable */
357 .gpio = PALMTE_USBDETECT_GPIO,
358 .type = OMAP_GPIO_SWITCH_TYPE_CONNECTION,
360 /* High when headphones jack is plugged in */
362 .name = "headphones",
363 .gpio = PALMTE_HEADPHONES_GPIO,
364 .type = OMAP_GPIO_SWITCH_TYPE_CONNECTION,
365 .notify = palmte_headphones_detect,
369 static void __init palmte_misc_gpio_setup(void)
371 /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */
372 if (omap_request_gpio(PALMTE_PINTDAV_GPIO)) {
373 printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n");
376 omap_set_gpio_direction(PALMTE_PINTDAV_GPIO, 1);
378 /* Set USB-or-DC-IN pin as input (unused) */
379 if (omap_request_gpio(PALMTE_USB_OR_DC_GPIO)) {
380 printk(KERN_ERR "Could not reserve cable signal GPIO!\n");
383 omap_set_gpio_direction(PALMTE_USB_OR_DC_GPIO, 1);
386 static void __init omap_palmte_init(void)
388 omap_board_config = palmte_config;
389 omap_board_config_size = ARRAY_SIZE(palmte_config);
391 platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
393 spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
395 omap_register_gpio_switches(palmte_switches,
396 ARRAY_SIZE(palmte_switches));
398 palmte_misc_gpio_setup();
400 omap_register_i2c_bus(1, 100, NULL, 0);
403 static void __init omap_palmte_map_io(void)
405 omap1_map_common_io();
408 MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
409 .phys_io = 0xfff00000,
410 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
411 .boot_params = 0x10000100,
412 .map_io = omap_palmte_map_io,
413 .init_irq = omap_palmte_init_irq,
414 .init_machine = omap_palmte_init,
415 .timer = &omap_timer,