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 #define PALMTE_USBDETECT_GPIO 0
47 #define PALMTE_USB_OR_DC_GPIO 1
48 #define PALMTE_TSC_GPIO 4
49 #define PALMTE_PINTDAV_GPIO 6
50 #define PALMTE_MMC_WP_GPIO 8
51 #define PALMTE_MMC_POWER_GPIO 9
52 #define PALMTE_HDQ_GPIO 11
53 #define PALMTE_HEADPHONES_GPIO 14
54 #define PALMTE_SPEAKER_GPIO 15
55 #define PALMTE_DC_GPIO OMAP_MPUIO(2)
56 #define PALMTE_MMC_SWITCH_GPIO OMAP_MPUIO(4)
57 #define PALMTE_MMC1_GPIO OMAP_MPUIO(6)
58 #define PALMTE_MMC2_GPIO OMAP_MPUIO(7)
59 #define PALMTE_MMC3_GPIO OMAP_MPUIO(11)
61 static void __init
omap_palmte_init_irq(void)
63 omap1_init_common_hw();
68 static const int palmte_keymap
[] = {
69 KEY(0, 0, KEY_F1
), /* Calendar */
70 KEY(0, 1, KEY_F2
), /* Contacts */
71 KEY(0, 2, KEY_F3
), /* Tasks List */
72 KEY(0, 3, KEY_F4
), /* Note Pad */
82 static struct omap_kp_platform_data palmte_kp_data
= {
85 .keymap
= (int *) palmte_keymap
,
90 static struct resource palmte_kp_resources
[] = {
92 .start
= INT_KEYBOARD
,
94 .flags
= IORESOURCE_IRQ
,
98 static struct platform_device palmte_kp_device
= {
99 .name
= "omap-keypad",
102 .platform_data
= &palmte_kp_data
,
104 .num_resources
= ARRAY_SIZE(palmte_kp_resources
),
105 .resource
= palmte_kp_resources
,
108 static struct mtd_partition palmte_rom_partitions
[] = {
109 /* PalmOS "Small ROM", contains the bootloader and the debugger */
114 .mask_flags
= MTD_WRITEABLE
,
116 /* PalmOS "Big ROM", a filesystem with all the OS code and data */
121 * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
122 * 0x7b0000 bytes in the English-only ("enUS") version.
125 .mask_flags
= MTD_WRITEABLE
,
129 static struct flash_platform_data palmte_rom_data
= {
130 .map_name
= "map_rom",
132 .parts
= palmte_rom_partitions
,
133 .nr_parts
= ARRAY_SIZE(palmte_rom_partitions
),
136 static struct resource palmte_rom_resource
= {
137 .start
= OMAP_CS0_PHYS
,
138 .end
= OMAP_CS0_PHYS
+ SZ_8M
- 1,
139 .flags
= IORESOURCE_MEM
,
142 static struct platform_device palmte_rom_device
= {
146 .platform_data
= &palmte_rom_data
,
149 .resource
= &palmte_rom_resource
,
152 static struct platform_device palmte_lcd_device
= {
153 .name
= "lcd_palmte",
157 static struct omap_backlight_config palmte_backlight_config
= {
158 .default_intensity
= 0xa0,
161 static struct platform_device palmte_backlight_device
= {
165 .platform_data
= &palmte_backlight_config
,
169 static struct omap_irda_config palmte_irda_config
= {
170 .transceiver_cap
= IR_SIRMODE
,
171 .rx_channel
= OMAP_DMA_UART3_RX
,
172 .tx_channel
= OMAP_DMA_UART3_TX
,
173 .dest_start
= UART3_THR
,
174 .src_start
= UART3_RHR
,
179 static struct resource palmte_irda_resources
[] = {
183 .flags
= IORESOURCE_IRQ
,
187 static struct platform_device palmte_irda_device
= {
191 .platform_data
= &palmte_irda_config
,
193 .num_resources
= ARRAY_SIZE(palmte_irda_resources
),
194 .resource
= palmte_irda_resources
,
197 static struct platform_device
*palmte_devices
[] __initdata
= {
201 &palmte_backlight_device
,
205 static struct omap_usb_config palmte_usb_config __initdata
= {
206 .register_dev
= 1, /* Mini-B only receptacle */
211 static struct omap_lcd_config palmte_lcd_config __initdata
= {
212 .ctrl_name
= "internal",
217 * Values measured in 10 minute intervals averaged over 10 samples.
218 * May differ slightly from device to device but should be accurate
219 * enough to give basic idea of battery life left and trigger
222 static const int palmte_battery_sample
[] = {
223 2194, 2157, 2138, 2120,
224 2104, 2089, 2075, 2061,
225 2048, 2038, 2026, 2016,
226 2008, 1998, 1989, 1980,
227 1970, 1958, 1945, 1928,
228 1910, 1888, 1860, 1827,
229 1791, 1751, 1709, 1656,
233 #define BATTERY_HIGH_TRESHOLD 66
234 #define BATTERY_LOW_TRESHOLD 33
236 static void palmte_get_power_status(struct apm_power_info
*info
, int *battery
)
238 int charging
, batt
, hi
, lo
, mid
;
240 charging
= !gpio_get_value(PALMTE_DC_GPIO
);
245 hi
= ARRAY_SIZE(palmte_battery_sample
);
248 info
->battery_flag
= 0;
249 info
->units
= APM_UNITS_MINS
;
251 if (batt
> palmte_battery_sample
[lo
]) {
252 info
->battery_life
= 100;
253 info
->time
= INTERVAL
* ARRAY_SIZE(palmte_battery_sample
);
254 } else if (batt
<= palmte_battery_sample
[hi
- 1]) {
255 info
->battery_life
= 0;
258 while (hi
> lo
+ 1) {
259 mid
= (hi
+ lo
) >> 1;
260 if (batt
<= palmte_battery_sample
[mid
])
266 mid
= palmte_battery_sample
[lo
] - palmte_battery_sample
[hi
];
267 hi
= palmte_battery_sample
[lo
] - batt
;
268 info
->battery_life
= 100 - (100 * lo
+ 100 * hi
/ mid
) /
269 ARRAY_SIZE(palmte_battery_sample
);
270 info
->time
= INTERVAL
* (ARRAY_SIZE(palmte_battery_sample
) -
271 lo
) - INTERVAL
* hi
/ mid
;
275 info
->ac_line_status
= APM_AC_ONLINE
;
276 info
->battery_status
= APM_BATTERY_STATUS_CHARGING
;
277 info
->battery_flag
|= APM_BATTERY_FLAG_CHARGING
;
279 info
->ac_line_status
= APM_AC_OFFLINE
;
280 if (info
->battery_life
> BATTERY_HIGH_TRESHOLD
)
281 info
->battery_status
= APM_BATTERY_STATUS_HIGH
;
282 else if (info
->battery_life
> BATTERY_LOW_TRESHOLD
)
283 info
->battery_status
= APM_BATTERY_STATUS_LOW
;
285 info
->battery_status
= APM_BATTERY_STATUS_CRITICAL
;
288 if (info
->battery_life
> BATTERY_HIGH_TRESHOLD
)
289 info
->battery_flag
|= APM_BATTERY_FLAG_HIGH
;
290 else if (info
->battery_life
> BATTERY_LOW_TRESHOLD
)
291 info
->battery_flag
|= APM_BATTERY_FLAG_LOW
;
293 info
->battery_flag
|= APM_BATTERY_FLAG_CRITICAL
;
296 #define palmte_get_power_status NULL
299 static struct omap_board_config_kernel palmte_config
[] __initdata
= {
300 { OMAP_TAG_LCD
, &palmte_lcd_config
},
303 static struct spi_board_info palmte_spi_info
[] __initdata
= {
305 .modalias
= "tsc2102",
306 .bus_num
= 2, /* uWire (officially) */
307 .chip_select
= 0, /* As opposed to 3 */
308 .irq
= OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO
),
309 .max_speed_hz
= 8000000,
313 static void palmte_headphones_detect(void *data
, int state
)
316 /* Headphones connected, disable speaker */
317 gpio_set_value(PALMTE_SPEAKER_GPIO
, 0);
318 printk(KERN_INFO
"PM: speaker off\n");
320 /* Headphones unplugged, re-enable speaker */
321 gpio_set_value(PALMTE_SPEAKER_GPIO
, 1);
322 printk(KERN_INFO
"PM: speaker on\n");
326 static void __init
palmte_misc_gpio_setup(void)
328 /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */
329 if (gpio_request(PALMTE_PINTDAV_GPIO
, "TSC2102 PINTDAV") < 0) {
330 printk(KERN_ERR
"Could not reserve PINTDAV GPIO!\n");
333 gpio_direction_input(PALMTE_PINTDAV_GPIO
);
335 /* Set USB-or-DC-IN pin as input (unused) */
336 if (gpio_request(PALMTE_USB_OR_DC_GPIO
, "USB/DC-IN") < 0) {
337 printk(KERN_ERR
"Could not reserve cable signal GPIO!\n");
340 gpio_direction_input(PALMTE_USB_OR_DC_GPIO
);
343 static void __init
omap_palmte_init(void)
345 omap_board_config
= palmte_config
;
346 omap_board_config_size
= ARRAY_SIZE(palmte_config
);
348 platform_add_devices(palmte_devices
, ARRAY_SIZE(palmte_devices
));
350 spi_register_board_info(palmte_spi_info
, ARRAY_SIZE(palmte_spi_info
));
351 palmte_misc_gpio_setup();
353 omap_usb_init(&palmte_usb_config
);
354 omap_register_i2c_bus(1, 100, NULL
, 0);
357 static void __init
omap_palmte_map_io(void)
359 omap1_map_common_io();
362 MACHINE_START(OMAP_PALMTE
, "OMAP310 based Palm Tungsten E")
363 .phys_io
= 0xfff00000,
364 .io_pg_offst
= ((0xfef00000) >> 18) & 0xfffc,
365 .boot_params
= 0x10000100,
366 .map_io
= omap_palmte_map_io
,
367 .init_irq
= omap_palmte_init_irq
,
368 .init_machine
= omap_palmte_init
,
369 .timer
= &omap_timer
,