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/spi/tsc2102.h>
28 #include <linux/interrupt.h>
29 #include <linux/apm-emulation.h>
31 #include <asm/hardware.h>
32 #include <asm/mach-types.h>
33 #include <asm/mach/arch.h>
34 #include <asm/mach/map.h>
35 #include <asm/mach/flash.h>
37 #include <asm/arch/gpio.h>
38 #include <asm/arch/mux.h>
39 #include <asm/arch/usb.h>
40 #include <asm/arch/tc.h>
41 #include <asm/arch/dma.h>
42 #include <asm/arch/board.h>
43 #include <asm/arch/irda.h>
44 #include <asm/arch/keypad.h>
45 #include <asm/arch/common.h>
46 #include <asm/arch/mcbsp.h>
47 #include <asm/arch/omap-alsa.h>
48 #include <asm/arch/gpio-switch.h>
50 static void __init omap_palmte_init_irq(void)
52 omap1_init_common_hw();
57 static const int palmte_keymap[] = {
58 KEY(0, 0, KEY_F1), /* Calendar */
59 KEY(0, 1, KEY_F2), /* Contacts */
60 KEY(0, 2, KEY_F3), /* Tasks List */
61 KEY(0, 3, KEY_F4), /* Note Pad */
67 KEY(1, 4, KEY_CENTER),
71 static struct omap_kp_platform_data palmte_kp_data = {
74 .keymap = (int *) palmte_keymap,
79 static struct resource palmte_kp_resources[] = {
81 .start = INT_KEYBOARD,
83 .flags = IORESOURCE_IRQ,
87 static struct platform_device palmte_kp_device = {
88 .name = "omap-keypad",
91 .platform_data = &palmte_kp_data,
93 .num_resources = ARRAY_SIZE(palmte_kp_resources),
94 .resource = palmte_kp_resources,
97 static struct mtd_partition palmte_rom_partitions[] = {
98 /* PalmOS "Small ROM", contains the bootloader and the debugger */
103 .mask_flags = MTD_WRITEABLE,
105 /* PalmOS "Big ROM", a filesystem with all the OS code and data */
110 * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
111 * 0x7b0000 bytes in the English-only ("enUS") version.
114 .mask_flags = MTD_WRITEABLE,
118 static struct flash_platform_data palmte_rom_data = {
119 .map_name = "map_rom",
121 .parts = palmte_rom_partitions,
122 .nr_parts = ARRAY_SIZE(palmte_rom_partitions),
125 static struct resource palmte_rom_resource = {
126 .start = OMAP_CS0_PHYS,
127 .end = OMAP_CS0_PHYS + SZ_8M - 1,
128 .flags = IORESOURCE_MEM,
131 static struct platform_device palmte_rom_device = {
135 .platform_data = &palmte_rom_data,
138 .resource = &palmte_rom_resource,
141 static struct platform_device palmte_lcd_device = {
142 .name = "lcd_palmte",
146 static struct omap_backlight_config palmte_backlight_config = {
147 .default_intensity = 0xa0,
150 static struct platform_device palmte_backlight_device = {
154 .platform_data = &palmte_backlight_config,
158 static struct omap_irda_config palmte_irda_config = {
159 .transceiver_cap = IR_SIRMODE,
160 .rx_channel = OMAP_DMA_UART3_RX,
161 .tx_channel = OMAP_DMA_UART3_TX,
162 .dest_start = UART3_THR,
163 .src_start = UART3_RHR,
168 static struct resource palmte_irda_resources[] = {
172 .flags = IORESOURCE_IRQ,
176 static struct platform_device palmte_irda_device = {
180 .platform_data = &palmte_irda_config,
182 .num_resources = ARRAY_SIZE(palmte_irda_resources),
183 .resource = palmte_irda_resources,
186 static struct platform_device *palmte_devices[] __initdata = {
190 &palmte_backlight_device,
194 static struct omap_usb_config palmte_usb_config __initdata = {
195 .register_dev = 1, /* Mini-B only receptacle */
200 static struct omap_mmc_config palmte_mmc_config __initdata = {
203 .wp_pin = PALMTE_MMC_WP_GPIO,
204 .power_pin = PALMTE_MMC_POWER_GPIO,
205 .switch_pin = PALMTE_MMC_SWITCH_GPIO,
209 static struct omap_lcd_config palmte_lcd_config __initdata = {
210 .ctrl_name = "internal",
213 static struct omap_uart_config palmte_uart_config __initdata = {
214 .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
217 static struct omap_mcbsp_reg_cfg palmte_mcbsp1_regs = {
218 .spcr2 = FRST | GRST | XRST | XINTM(3),
219 .xcr2 = XDATDLY(1) | XFIG,
220 .xcr1 = XWDLEN1(OMAP_MCBSP_WORD_32),
221 .pcr0 = SCLKME | FSXP | CLKXP,
224 static struct omap_alsa_codec_config palmte_alsa_config = {
225 .name = "TSC2102 audio",
226 .mcbsp_regs_alsa = &palmte_mcbsp1_regs,
227 .codec_configure_dev = NULL, /* tsc2102_configure, */
228 .codec_set_samplerate = NULL, /* tsc2102_set_samplerate, */
229 .codec_clock_setup = NULL, /* tsc2102_clock_setup, */
230 .codec_clock_on = NULL, /* tsc2102_clock_on, */
231 .codec_clock_off = NULL, /* tsc2102_clock_off, */
232 .get_default_samplerate = NULL, /* tsc2102_get_default_samplerate, */
237 * Values measured in 10 minute intervals averaged over 10 samples.
238 * May differ slightly from device to device but should be accurate
239 * enough to give basic idea of battery life left and trigger
242 static const int palmte_battery_sample[] = {
243 2194, 2157, 2138, 2120,
244 2104, 2089, 2075, 2061,
245 2048, 2038, 2026, 2016,
246 2008, 1998, 1989, 1980,
247 1970, 1958, 1945, 1928,
248 1910, 1888, 1860, 1827,
249 1791, 1751, 1709, 1656,
253 #define BATTERY_HIGH_TRESHOLD 66
254 #define BATTERY_LOW_TRESHOLD 33
256 static void palmte_get_power_status(struct apm_power_info *info, int *battery)
258 int charging, batt, hi, lo, mid;
260 charging = !omap_get_gpio_datain(PALMTE_DC_GPIO);
265 hi = ARRAY_SIZE(palmte_battery_sample);
268 info->battery_flag = 0;
269 info->units = APM_UNITS_MINS;
271 if (batt > palmte_battery_sample[lo]) {
272 info->battery_life = 100;
273 info->time = INTERVAL * ARRAY_SIZE(palmte_battery_sample);
274 } else if (batt <= palmte_battery_sample[hi - 1]) {
275 info->battery_life = 0;
278 while (hi > lo + 1) {
279 mid = (hi + lo) >> 1;
280 if (batt <= palmte_battery_sample[mid])
286 mid = palmte_battery_sample[lo] - palmte_battery_sample[hi];
287 hi = palmte_battery_sample[lo] - batt;
288 info->battery_life = 100 - (100 * lo + 100 * hi / mid) /
289 ARRAY_SIZE(palmte_battery_sample);
290 info->time = INTERVAL * (ARRAY_SIZE(palmte_battery_sample) -
291 lo) - INTERVAL * hi / mid;
295 info->ac_line_status = APM_AC_ONLINE;
296 info->battery_status = APM_BATTERY_STATUS_CHARGING;
297 info->battery_flag |= APM_BATTERY_FLAG_CHARGING;
299 info->ac_line_status = APM_AC_OFFLINE;
300 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
301 info->battery_status = APM_BATTERY_STATUS_HIGH;
302 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
303 info->battery_status = APM_BATTERY_STATUS_LOW;
305 info->battery_status = APM_BATTERY_STATUS_CRITICAL;
308 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
309 info->battery_flag |= APM_BATTERY_FLAG_HIGH;
310 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
311 info->battery_flag |= APM_BATTERY_FLAG_LOW;
313 info->battery_flag |= APM_BATTERY_FLAG_CRITICAL;
316 #define palmte_get_power_status NULL
319 static struct tsc2102_config palmte_tsc2102_config = {
321 .monitor = TSC_BAT1 | TSC_AUX | TSC_TEMP,
322 .temp_at25c = { 2200, 2615 },
323 .apm_report = palmte_get_power_status,
324 .alsa_config = &palmte_alsa_config,
327 static struct omap_board_config_kernel palmte_config[] __initdata = {
328 { OMAP_TAG_USB, &palmte_usb_config },
329 { OMAP_TAG_MMC, &palmte_mmc_config },
330 { OMAP_TAG_LCD, &palmte_lcd_config },
331 { OMAP_TAG_UART, &palmte_uart_config },
334 static struct spi_board_info palmte_spi_info[] __initdata = {
336 .modalias = "tsc2102",
337 .bus_num = 2, /* uWire (officially) */
338 .chip_select = 0, /* As opposed to 3 */
339 .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO),
340 .platform_data = &palmte_tsc2102_config,
341 .max_speed_hz = 8000000,
345 static void palmte_headphones_detect(void *data, int state) {
347 /* Headphones connected, disable speaker */
348 omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO, 0);
349 printk(KERN_INFO "PM: speaker off\n");
351 /* Headphones unplugged, re-enable speaker */
352 omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO, 1);
353 printk(KERN_INFO "PM: speaker on\n");
357 static struct omap_gpio_switch palmte_switches[] __initdata = {
358 /* Speaker-enable pin is an output */
360 .name = "speaker-enable",
361 .gpio = PALMTE_SPEAKER_GPIO,
362 .type = OMAP_GPIO_SWITCH_TYPE_ACTIVITY,
363 .flags = OMAP_GPIO_SWITCH_FLAG_OUTPUT |
364 OMAP_GPIO_SWITCH_FLAG_INVERTED,
366 /* Indicates whether power is from DC-IN or battery */
369 .gpio = PALMTE_DC_GPIO,
370 .type = OMAP_GPIO_SWITCH_TYPE_CONNECTION,
371 .flags = OMAP_GPIO_SWITCH_FLAG_INVERTED,
373 /* Indicates whether a USB host is on the other end of the cable */
376 .gpio = PALMTE_USBDETECT_GPIO,
377 .type = OMAP_GPIO_SWITCH_TYPE_CONNECTION,
379 /* High when headphones jack is plugged in */
381 .name = "headphones",
382 .gpio = PALMTE_HEADPHONES_GPIO,
383 .type = OMAP_GPIO_SWITCH_TYPE_CONNECTION,
384 .notify = palmte_headphones_detect,
388 static void __init palmte_misc_gpio_setup(void)
390 /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */
391 if (omap_request_gpio(PALMTE_PINTDAV_GPIO)) {
392 printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n");
395 omap_set_gpio_direction(PALMTE_PINTDAV_GPIO, 1);
397 /* Set USB-or-DC-IN pin as input (unused) */
398 if (omap_request_gpio(PALMTE_USB_OR_DC_GPIO)) {
399 printk(KERN_ERR "Could not reserve cable signal GPIO!\n");
402 omap_set_gpio_direction(PALMTE_USB_OR_DC_GPIO, 1);
405 static void __init omap_palmte_init(void)
407 omap_board_config = palmte_config;
408 omap_board_config_size = ARRAY_SIZE(palmte_config);
410 platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
412 spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
414 omap_register_gpio_switches(palmte_switches,
415 ARRAY_SIZE(palmte_switches));
417 palmte_misc_gpio_setup();
419 omap_register_i2c_bus(1, 100, NULL, 0);
422 static void __init omap_palmte_map_io(void)
424 omap1_map_common_io();
427 MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
428 .phys_io = 0xfff00000,
429 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
430 .boot_params = 0x10000100,
431 .map_io = omap_palmte_map_io,
432 .init_irq = omap_palmte_init_irq,
433 .init_machine = omap_palmte_init,
434 .timer = &omap_timer,