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 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
18 #include <linux/kernel.h>
19 #include <linux/init.h>
20 #include <linux/input.h>
21 #include <linux/platform_device.h>
22 #include <linux/mtd/mtd.h>
23 #include <linux/mtd/partitions.h>
24 #include <linux/spi/spi.h>
25 #include <linux/spi/tsc2102.h>
26 #include <linux/interrupt.h>
29 #include <asm/hardware.h>
30 #include <asm/mach-types.h>
31 #include <asm/mach/arch.h>
32 #include <asm/mach/map.h>
33 #include <asm/mach/flash.h>
35 #include <asm/arch/gpio.h>
36 #include <asm/arch/mux.h>
37 #include <asm/arch/usb.h>
38 #include <asm/arch/tc.h>
39 #include <asm/arch/dma.h>
40 #include <asm/arch/board.h>
41 #include <asm/arch/irda.h>
42 #include <asm/arch/keypad.h>
43 #include <asm/arch/common.h>
44 #include <asm/arch/mcbsp.h>
45 #include <asm/arch/omap-alsa.h>
47 static void __init
omap_palmte_init_irq(void)
49 omap1_init_common_hw();
54 static int palmte_keymap
[] = {
64 KEY(1, 4, KEY_CENTER
),
68 static struct omap_kp_platform_data palmte_kp_data
= {
71 .keymap
= palmte_keymap
,
76 static struct resource palmte_kp_resources
[] = {
78 .start
= INT_KEYBOARD
,
80 .flags
= IORESOURCE_IRQ
,
84 static struct platform_device palmte_kp_device
= {
85 .name
= "omap-keypad",
88 .platform_data
= &palmte_kp_data
,
90 .num_resources
= ARRAY_SIZE(palmte_kp_resources
),
91 .resource
= palmte_kp_resources
,
94 static struct mtd_partition palmte_rom_partitions
[] = {
95 /* PalmOS "Small ROM", contains the bootloader and the debugger */
100 .mask_flags
= MTD_WRITEABLE
,
102 /* PalmOS "Big ROM", a filesystem with all the OS code and data */
107 * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
108 * 0x7b0000 bytes in the English-only ("enUS") version.
111 .mask_flags
= MTD_WRITEABLE
,
115 static struct flash_platform_data palmte_rom_data
= {
116 .map_name
= "map_rom",
118 .parts
= palmte_rom_partitions
,
119 .nr_parts
= ARRAY_SIZE(palmte_rom_partitions
),
122 static struct resource palmte_rom_resource
= {
123 .start
= OMAP_CS0_PHYS
,
124 .end
= OMAP_CS0_PHYS
+ SZ_8M
- 1,
125 .flags
= IORESOURCE_MEM
,
128 static struct platform_device palmte_rom_device
= {
132 .platform_data
= &palmte_rom_data
,
135 .resource
= &palmte_rom_resource
,
138 static struct platform_device palmte_lcd_device
= {
139 .name
= "lcd_palmte",
143 static struct omap_backlight_config palmte_backlight_config
= {
144 .default_intensity
= 0xa0,
147 static struct platform_device palmte_backlight_device
= {
151 .platform_data
= &palmte_backlight_config
,
155 static struct omap_irda_config palmte_irda_config
= {
156 .transceiver_cap
= IR_SIRMODE
,
157 .rx_channel
= OMAP_DMA_UART3_RX
,
158 .tx_channel
= OMAP_DMA_UART3_TX
,
159 .dest_start
= UART3_THR
,
160 .src_start
= UART3_RHR
,
165 static struct resource palmte_irda_resources
[] = {
169 .flags
= IORESOURCE_IRQ
,
173 static struct platform_device palmte_irda_device
= {
177 .platform_data
= &palmte_irda_config
,
179 .num_resources
= ARRAY_SIZE(palmte_irda_resources
),
180 .resource
= palmte_irda_resources
,
183 static struct platform_device
*devices
[] __initdata
= {
187 &palmte_backlight_device
,
191 static struct omap_usb_config palmte_usb_config __initdata
= {
192 .register_dev
= 1, /* Mini-B only receptacle */
197 static struct omap_mmc_config palmte_mmc_config __initdata
= {
200 .wp_pin
= PALMTE_MMC_WP_GPIO
,
201 .power_pin
= PALMTE_MMC_POWER_GPIO
,
202 .switch_pin
= PALMTE_MMC_SWITCH_GPIO
,
206 static struct omap_lcd_config palmte_lcd_config __initdata
= {
207 .ctrl_name
= "internal",
210 static struct omap_uart_config palmte_uart_config __initdata
= {
211 .enabled_uarts
= (1 << 0) | (1 << 1) | (0 << 2),
214 static struct omap_mcbsp_reg_cfg palmte_mcbsp1_regs
= {
215 .spcr2
= FRST
| GRST
| XRST
| XINTM(3),
216 .xcr2
= XDATDLY(1) | XFIG
,
217 .xcr1
= XWDLEN1(OMAP_MCBSP_WORD_32
),
218 .pcr0
= SCLKME
| FSXP
| CLKXP
,
221 static struct omap_alsa_codec_config palmte_alsa_config
= {
222 .name
= "TSC2102 audio",
223 .mcbsp_regs_alsa
= &palmte_mcbsp1_regs
,
224 .codec_configure_dev
= NULL
, /* tsc2102_configure, */
225 .codec_set_samplerate
= NULL
, /* tsc2102_set_samplerate, */
226 .codec_clock_setup
= NULL
, /* tsc2102_clock_setup, */
227 .codec_clock_on
= NULL
, /* tsc2102_clock_on, */
228 .codec_clock_off
= NULL
, /* tsc2102_clock_off, */
229 .get_default_samplerate
= NULL
, /* tsc2102_get_default_samplerate, */
234 * Values measured in 10 minute intervals averaged over 10 samples.
235 * May differ slightly from device to device but should be accurate
236 * enough to give basic idea of battery life left and trigger
239 static const int palmte_battery_sample
[] = {
240 2194, 2157, 2138, 2120,
241 2104, 2089, 2075, 2061,
242 2048, 2038, 2026, 2016,
243 2008, 1998, 1989, 1980,
244 1970, 1958, 1945, 1928,
245 1910, 1888, 1860, 1827,
246 1791, 1751, 1709, 1656,
250 #define BATTERY_HIGH_TRESHOLD 66
251 #define BATTERY_LOW_TRESHOLD 33
253 static void palmte_get_power_status(struct apm_power_info
*info
, int *battery
)
255 int charging
, batt
, hi
, lo
, mid
;
257 charging
= !omap_get_gpio_datain(PALMTE_DC_GPIO
);
262 hi
= ARRAY_SIZE(palmte_battery_sample
);
265 info
->battery_flag
= 0;
266 info
->units
= APM_UNITS_MINS
;
268 if (batt
> palmte_battery_sample
[lo
]) {
269 info
->battery_life
= 100;
270 info
->time
= INTERVAL
* ARRAY_SIZE(palmte_battery_sample
);
271 } else if (batt
<= palmte_battery_sample
[hi
- 1]) {
272 info
->battery_life
= 0;
275 while (hi
> lo
+ 1) {
276 mid
= (hi
+ lo
) >> 2;
277 if (batt
<= palmte_battery_sample
[mid
])
283 mid
= palmte_battery_sample
[lo
] - palmte_battery_sample
[hi
];
284 hi
= palmte_battery_sample
[lo
] - batt
;
285 info
->battery_life
= 100 - (100 * lo
+ 100 * hi
/ mid
) /
286 ARRAY_SIZE(palmte_battery_sample
);
287 info
->time
= INTERVAL
* (ARRAY_SIZE(palmte_battery_sample
) -
288 lo
) - INTERVAL
* hi
/ mid
;
292 info
->ac_line_status
= APM_AC_ONLINE
;
293 info
->battery_status
= APM_BATTERY_STATUS_CHARGING
;
294 info
->battery_flag
|= APM_BATTERY_FLAG_CHARGING
;
296 info
->ac_line_status
= APM_AC_OFFLINE
;
297 if (info
->battery_life
> BATTERY_HIGH_TRESHOLD
)
298 info
->battery_status
= APM_BATTERY_STATUS_HIGH
;
299 else if (info
->battery_life
> BATTERY_LOW_TRESHOLD
)
300 info
->battery_status
= APM_BATTERY_STATUS_LOW
;
302 info
->battery_status
= APM_BATTERY_STATUS_CRITICAL
;
305 if (info
->battery_life
> BATTERY_HIGH_TRESHOLD
)
306 info
->battery_flag
|= APM_BATTERY_FLAG_HIGH
;
307 else if (info
->battery_life
> BATTERY_LOW_TRESHOLD
)
308 info
->battery_flag
|= APM_BATTERY_FLAG_LOW
;
310 info
->battery_flag
|= APM_BATTERY_FLAG_CRITICAL
;
313 #define palmte_get_power_status NULL
316 static struct tsc2102_config palmte_tsc2102_config
= {
318 .monitor
= TSC_BAT1
| TSC_AUX
| TSC_TEMP
,
319 .temp_at25c
= { 2200, 2615 },
320 .apm_report
= palmte_get_power_status
,
321 .alsa_config
= &palmte_alsa_config
,
324 static struct omap_board_config_kernel palmte_config
[] = {
325 { OMAP_TAG_USB
, &palmte_usb_config
},
326 { OMAP_TAG_MMC
, &palmte_mmc_config
},
327 { OMAP_TAG_LCD
, &palmte_lcd_config
},
328 { OMAP_TAG_UART
, &palmte_uart_config
},
331 static struct spi_board_info palmte_spi_info
[] __initdata
= {
333 .modalias
= "tsc2102",
334 .bus_num
= 2, /* uWire (officially) */
335 .chip_select
= 0, /* As opposed to 3 */
336 .irq
= OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO
),
337 .platform_data
= &palmte_tsc2102_config
,
338 .max_speed_hz
= 8000000,
342 /* Periodically check for changes on important input pins */
343 struct timer_list palmte_pin_timer
;
344 int prev_power
, prev_headphones
;
346 static void palmte_pin_handler(unsigned long data
) {
347 int power
, headphones
;
349 power
= !omap_get_gpio_datain(PALMTE_DC_GPIO
);
350 headphones
= omap_get_gpio_datain(PALMTE_HEADPHONES_GPIO
);
352 if (power
&& !prev_power
)
353 printk(KERN_INFO
"PM: cable connected\n");
354 else if (!power
&& prev_power
)
355 printk(KERN_INFO
"PM: cable disconnected\n");
357 if (headphones
&& !prev_headphones
) {
358 /* Headphones connected, disable speaker */
359 omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO
, 0);
360 printk(KERN_INFO
"PM: speaker off\n");
361 } else if (!headphones
&& prev_headphones
) {
362 /* Headphones unplugged, re-enable speaker */
363 omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO
, 1);
364 printk(KERN_INFO
"PM: speaker on\n");
368 prev_headphones
= headphones
;
369 mod_timer(&palmte_pin_timer
, jiffies
+ msecs_to_jiffies(500));
372 static void __init
palmte_gpio_setup(void)
374 /* Set TSC2102 PINTDAV pin as input */
375 if (omap_request_gpio(PALMTE_PINTDAV_GPIO
)) {
376 printk(KERN_ERR
"Could not reserve PINTDAV GPIO!\n");
379 omap_set_gpio_direction(PALMTE_PINTDAV_GPIO
, 1);
381 /* Monitor cable-connected signals */
382 if (omap_request_gpio(PALMTE_DC_GPIO
) ||
383 omap_request_gpio(PALMTE_USB_OR_DC_GPIO
) ||
384 omap_request_gpio(PALMTE_USBDETECT_GPIO
)) {
385 printk(KERN_ERR
"Could not reserve cable signal GPIO!\n");
388 omap_set_gpio_direction(PALMTE_DC_GPIO
, 1);
389 omap_set_gpio_direction(PALMTE_USB_OR_DC_GPIO
, 1);
390 omap_set_gpio_direction(PALMTE_USBDETECT_GPIO
, 1);
392 /* Set speaker-enable pin as output */
393 if (omap_request_gpio(PALMTE_SPEAKER_GPIO
)) {
394 printk(KERN_ERR
"Could not reserve speaker GPIO!\n");
397 omap_set_gpio_direction(PALMTE_SPEAKER_GPIO
, 0);
399 /* Monitor the headphones-connected signal */
400 if (omap_request_gpio(PALMTE_HEADPHONES_GPIO
)) {
401 printk(KERN_ERR
"Could not reserve headphones signal GPIO!\n");
404 omap_set_gpio_direction(PALMTE_HEADPHONES_GPIO
, 1);
406 prev_power
= omap_get_gpio_datain(PALMTE_DC_GPIO
);
407 prev_headphones
= !omap_get_gpio_datain(PALMTE_HEADPHONES_GPIO
);
408 setup_timer(&palmte_pin_timer
, palmte_pin_handler
, 0);
409 palmte_pin_handler(0);
412 static void __init
omap_palmte_init(void)
414 omap_board_config
= palmte_config
;
415 omap_board_config_size
= ARRAY_SIZE(palmte_config
);
417 platform_add_devices(devices
, ARRAY_SIZE(devices
));
419 spi_register_board_info(palmte_spi_info
, ARRAY_SIZE(palmte_spi_info
));
425 static void __init
omap_palmte_map_io(void)
427 omap1_map_common_io();
430 MACHINE_START(OMAP_PALMTE
, "OMAP310 based Palm Tungsten E")
431 .phys_io
= 0xfff00000,
432 .io_pg_offst
= ((0xfef00000) >> 18) & 0xfffc,
433 .boot_params
= 0x10000100,
434 .map_io
= omap_palmte_map_io
,
435 .init_irq
= omap_palmte_init_irq
,
436 .init_machine
= omap_palmte_init
,
437 .timer
= &omap_timer
,