blob: 886b4c0569bddb0958a5766273da6b600c3268d8 [file] [log] [blame]
Tony Lindgren3179a012005-11-10 14:26:48 +00001/*
2 * linux/arch/arm/mach-omap1/board-palmte.c
3 *
4 * Modified from board-generic.c
5 *
6 * Support for the Palm Tungsten E PDA.
7 *
8 * Original version : Laurent Gonzalez
9 *
Simon Arlott6cbdc8c2007-05-11 20:40:30 +010010 * Maintainers : http://palmtelinux.sf.net
Tony Lindgren3179a012005-11-10 14:26:48 +000011 * palmtelinux-developpers@lists.sf.net
12 *
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -080013 * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
14 *
Tony Lindgren3179a012005-11-10 14:26:48 +000015 * 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.
18 */
19
20#include <linux/kernel.h>
21#include <linux/init.h>
Andrzej Zaborowskic3695012006-12-06 17:13:51 -080022#include <linux/input.h>
Tony Lindgren3179a012005-11-10 14:26:48 +000023#include <linux/platform_device.h>
Andrzej Zaborowskic3695012006-12-06 17:13:51 -080024#include <linux/mtd/mtd.h>
25#include <linux/mtd/partitions.h>
26#include <linux/spi/spi.h>
Andrzej Zaborowskic3695012006-12-06 17:13:51 -080027#include <linux/interrupt.h>
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -080028#include <linux/apm-emulation.h>
Tony Lindgren3179a012005-11-10 14:26:48 +000029
Russell Kinga09e64f2008-08-05 16:14:15 +010030#include <mach/hardware.h>
Tony Lindgren3179a012005-11-10 14:26:48 +000031#include <asm/mach-types.h>
32#include <asm/mach/arch.h>
33#include <asm/mach/map.h>
Andrzej Zaborowskic3695012006-12-06 17:13:51 -080034#include <asm/mach/flash.h>
Tony Lindgren3179a012005-11-10 14:26:48 +000035
Russell Kinga09e64f2008-08-05 16:14:15 +010036#include <mach/gpio.h>
37#include <mach/mux.h>
38#include <mach/usb.h>
39#include <mach/tc.h>
40#include <mach/dma.h>
41#include <mach/board.h>
42#include <mach/irda.h>
43#include <mach/keypad.h>
44#include <mach/common.h>
Tony Lindgren3179a012005-11-10 14:26:48 +000045
Tony Lindgrenb2830812009-03-23 18:07:35 -070046#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)
60
Andrzej Zaborowskic3695012006-12-06 17:13:51 -080061static void __init omap_palmte_init_irq(void)
Tony Lindgren3179a012005-11-10 14:26:48 +000062{
Tony Lindgren87bd63f2006-02-08 22:06:46 +000063 omap1_init_common_hw();
Tony Lindgren3179a012005-11-10 14:26:48 +000064 omap_init_irq();
Andrzej Zaborowskic3695012006-12-06 17:13:51 -080065 omap_gpio_init();
Tony Lindgren3179a012005-11-10 14:26:48 +000066}
67
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -080068static 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 */
Andrzej Zaborowskic3695012006-12-06 17:13:51 -080073 KEY(0, 4, KEY_POWER),
74 KEY(1, 0, KEY_LEFT),
75 KEY(1, 1, KEY_DOWN),
76 KEY(1, 2, KEY_UP),
77 KEY(1, 3, KEY_RIGHT),
Eduardo Valentinec44dfa2008-03-27 11:09:42 -040078 KEY(1, 4, KEY_ENTER),
Andrzej Zaborowskic3695012006-12-06 17:13:51 -080079 0,
80};
81
82static struct omap_kp_platform_data palmte_kp_data = {
83 .rows = 8,
84 .cols = 8,
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -080085 .keymap = (int *) palmte_keymap,
Andrzej Zaborowskic3695012006-12-06 17:13:51 -080086 .rep = 1,
87 .delay = 12,
88};
89
90static struct resource palmte_kp_resources[] = {
91 [0] = {
92 .start = INT_KEYBOARD,
93 .end = INT_KEYBOARD,
94 .flags = IORESOURCE_IRQ,
95 },
96};
97
98static struct platform_device palmte_kp_device = {
99 .name = "omap-keypad",
100 .id = -1,
101 .dev = {
102 .platform_data = &palmte_kp_data,
103 },
104 .num_resources = ARRAY_SIZE(palmte_kp_resources),
105 .resource = palmte_kp_resources,
106};
107
108static struct mtd_partition palmte_rom_partitions[] = {
109 /* PalmOS "Small ROM", contains the bootloader and the debugger */
110 {
111 .name = "smallrom",
112 .offset = 0,
113 .size = 0xa000,
114 .mask_flags = MTD_WRITEABLE,
115 },
116 /* PalmOS "Big ROM", a filesystem with all the OS code and data */
117 {
118 .name = "bigrom",
119 .offset = SZ_128K,
120 /*
121 * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
122 * 0x7b0000 bytes in the English-only ("enUS") version.
123 */
124 .size = 0x7b0000,
125 .mask_flags = MTD_WRITEABLE,
126 },
127};
128
129static struct flash_platform_data palmte_rom_data = {
130 .map_name = "map_rom",
131 .width = 2,
132 .parts = palmte_rom_partitions,
133 .nr_parts = ARRAY_SIZE(palmte_rom_partitions),
134};
135
136static struct resource palmte_rom_resource = {
137 .start = OMAP_CS0_PHYS,
138 .end = OMAP_CS0_PHYS + SZ_8M - 1,
139 .flags = IORESOURCE_MEM,
140};
141
142static struct platform_device palmte_rom_device = {
143 .name = "omapflash",
144 .id = -1,
145 .dev = {
146 .platform_data = &palmte_rom_data,
147 },
148 .num_resources = 1,
149 .resource = &palmte_rom_resource,
150};
151
Tony Lindgren9b6553c2006-04-02 17:46:30 +0100152static struct platform_device palmte_lcd_device = {
153 .name = "lcd_palmte",
154 .id = -1,
155};
156
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800157static struct omap_backlight_config palmte_backlight_config = {
158 .default_intensity = 0xa0,
159};
160
161static struct platform_device palmte_backlight_device = {
162 .name = "omap-bl",
163 .id = -1,
164 .dev = {
165 .platform_data = &palmte_backlight_config,
166 },
167};
168
169static 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,
175 .tx_trigger = 0,
176 .rx_trigger = 0,
177};
178
179static struct resource palmte_irda_resources[] = {
180 [0] = {
181 .start = INT_UART3,
182 .end = INT_UART3,
183 .flags = IORESOURCE_IRQ,
184 },
185};
186
187static struct platform_device palmte_irda_device = {
188 .name = "omapirda",
189 .id = -1,
190 .dev = {
191 .platform_data = &palmte_irda_config,
192 },
193 .num_resources = ARRAY_SIZE(palmte_irda_resources),
194 .resource = palmte_irda_resources,
195};
196
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -0800197static struct platform_device *palmte_devices[] __initdata = {
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800198 &palmte_rom_device,
199 &palmte_kp_device,
Tony Lindgren9b6553c2006-04-02 17:46:30 +0100200 &palmte_lcd_device,
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800201 &palmte_backlight_device,
202 &palmte_irda_device,
Tony Lindgren9b6553c2006-04-02 17:46:30 +0100203};
204
Tony Lindgren3179a012005-11-10 14:26:48 +0000205static struct omap_usb_config palmte_usb_config __initdata = {
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800206 .register_dev = 1, /* Mini-B only receptacle */
Tony Lindgren3179a012005-11-10 14:26:48 +0000207 .hmc_mode = 0,
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800208 .pins[0] = 2,
Tony Lindgren3179a012005-11-10 14:26:48 +0000209};
210
Tony Lindgren3179a012005-11-10 14:26:48 +0000211static struct omap_lcd_config palmte_lcd_config __initdata = {
Tony Lindgren3179a012005-11-10 14:26:48 +0000212 .ctrl_name = "internal",
213};
214
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800215static struct omap_uart_config palmte_uart_config __initdata = {
216 .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
Tony Lindgren3179a012005-11-10 14:26:48 +0000217};
218
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800219#ifdef CONFIG_APM
220/*
221 * Values measured in 10 minute intervals averaged over 10 samples.
222 * May differ slightly from device to device but should be accurate
223 * enough to give basic idea of battery life left and trigger
224 * potential alerts.
225 */
226static const int palmte_battery_sample[] = {
227 2194, 2157, 2138, 2120,
228 2104, 2089, 2075, 2061,
229 2048, 2038, 2026, 2016,
230 2008, 1998, 1989, 1980,
231 1970, 1958, 1945, 1928,
232 1910, 1888, 1860, 1827,
233 1791, 1751, 1709, 1656,
234};
235
236#define INTERVAL 10
237#define BATTERY_HIGH_TRESHOLD 66
238#define BATTERY_LOW_TRESHOLD 33
239
240static void palmte_get_power_status(struct apm_power_info *info, int *battery)
241{
242 int charging, batt, hi, lo, mid;
243
David Brownell0b84b5c2008-12-10 17:35:25 -0800244 charging = !gpio_get_value(PALMTE_DC_GPIO);
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800245 batt = battery[0];
246 if (charging)
247 batt -= 60;
248
249 hi = ARRAY_SIZE(palmte_battery_sample);
250 lo = 0;
251
252 info->battery_flag = 0;
253 info->units = APM_UNITS_MINS;
254
255 if (batt > palmte_battery_sample[lo]) {
256 info->battery_life = 100;
257 info->time = INTERVAL * ARRAY_SIZE(palmte_battery_sample);
258 } else if (batt <= palmte_battery_sample[hi - 1]) {
259 info->battery_life = 0;
260 info->time = 0;
261 } else {
262 while (hi > lo + 1) {
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -0800263 mid = (hi + lo) >> 1;
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800264 if (batt <= palmte_battery_sample[mid])
265 lo = mid;
266 else
267 hi = mid;
268 }
269
270 mid = palmte_battery_sample[lo] - palmte_battery_sample[hi];
271 hi = palmte_battery_sample[lo] - batt;
272 info->battery_life = 100 - (100 * lo + 100 * hi / mid) /
273 ARRAY_SIZE(palmte_battery_sample);
274 info->time = INTERVAL * (ARRAY_SIZE(palmte_battery_sample) -
275 lo) - INTERVAL * hi / mid;
276 }
277
278 if (charging) {
279 info->ac_line_status = APM_AC_ONLINE;
280 info->battery_status = APM_BATTERY_STATUS_CHARGING;
281 info->battery_flag |= APM_BATTERY_FLAG_CHARGING;
282 } else {
283 info->ac_line_status = APM_AC_OFFLINE;
284 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
285 info->battery_status = APM_BATTERY_STATUS_HIGH;
286 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
287 info->battery_status = APM_BATTERY_STATUS_LOW;
288 else
289 info->battery_status = APM_BATTERY_STATUS_CRITICAL;
290 }
291
292 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
293 info->battery_flag |= APM_BATTERY_FLAG_HIGH;
294 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
295 info->battery_flag |= APM_BATTERY_FLAG_LOW;
296 else
297 info->battery_flag |= APM_BATTERY_FLAG_CRITICAL;
298}
299#else
300#define palmte_get_power_status NULL
301#endif
302
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -0800303static struct omap_board_config_kernel palmte_config[] __initdata = {
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800304 { OMAP_TAG_LCD, &palmte_lcd_config },
305 { OMAP_TAG_UART, &palmte_uart_config },
306};
307
308static struct spi_board_info palmte_spi_info[] __initdata = {
309 {
310 .modalias = "tsc2102",
311 .bus_num = 2, /* uWire (officially) */
312 .chip_select = 0, /* As opposed to 3 */
313 .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO),
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800314 .max_speed_hz = 8000000,
315 },
316};
317
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -0800318static void palmte_headphones_detect(void *data, int state)
319{
320 if (state) {
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800321 /* Headphones connected, disable speaker */
David Brownell0b84b5c2008-12-10 17:35:25 -0800322 gpio_set_value(PALMTE_SPEAKER_GPIO, 0);
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800323 printk(KERN_INFO "PM: speaker off\n");
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -0800324 } else {
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800325 /* Headphones unplugged, re-enable speaker */
David Brownell0b84b5c2008-12-10 17:35:25 -0800326 gpio_set_value(PALMTE_SPEAKER_GPIO, 1);
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800327 printk(KERN_INFO "PM: speaker on\n");
328 }
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800329}
330
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -0800331static void __init palmte_misc_gpio_setup(void)
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800332{
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -0800333 /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */
Jarkko Nikulaf2d18fe2008-12-10 17:35:30 -0800334 if (gpio_request(PALMTE_PINTDAV_GPIO, "TSC2102 PINTDAV") < 0) {
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800335 printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n");
336 return;
337 }
David Brownell40e39252008-12-10 17:35:26 -0800338 gpio_direction_input(PALMTE_PINTDAV_GPIO);
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800339
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -0800340 /* Set USB-or-DC-IN pin as input (unused) */
Jarkko Nikulaf2d18fe2008-12-10 17:35:30 -0800341 if (gpio_request(PALMTE_USB_OR_DC_GPIO, "USB/DC-IN") < 0) {
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800342 printk(KERN_ERR "Could not reserve cable signal GPIO!\n");
343 return;
344 }
David Brownell40e39252008-12-10 17:35:26 -0800345 gpio_direction_input(PALMTE_USB_OR_DC_GPIO);
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800346}
347
348static void __init omap_palmte_init(void)
Tony Lindgren3179a012005-11-10 14:26:48 +0000349{
350 omap_board_config = palmte_config;
351 omap_board_config_size = ARRAY_SIZE(palmte_config);
Tony Lindgren9b6553c2006-04-02 17:46:30 +0100352
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -0800353 platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800354
355 spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
Andrzej Zaborowskid7730cc2006-12-07 17:13:51 -0800356 palmte_misc_gpio_setup();
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800357 omap_serial_init();
Felipe Balbib0b5aa32009-03-23 18:07:49 -0700358 omap_usb_init(&palmte_usb_config);
Jarkko Nikula1ed16a82007-11-07 06:54:32 +0200359 omap_register_i2c_bus(1, 100, NULL, 0);
Tony Lindgren3179a012005-11-10 14:26:48 +0000360}
361
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800362static void __init omap_palmte_map_io(void)
Tony Lindgren3179a012005-11-10 14:26:48 +0000363{
Tony Lindgren87bd63f2006-02-08 22:06:46 +0000364 omap1_map_common_io();
Tony Lindgren3179a012005-11-10 14:26:48 +0000365}
366
367MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
Tony Lindgren3179a012005-11-10 14:26:48 +0000368 .phys_io = 0xfff00000,
369 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
370 .boot_params = 0x10000100,
Andrzej Zaborowskic3695012006-12-06 17:13:51 -0800371 .map_io = omap_palmte_map_io,
372 .init_irq = omap_palmte_init_irq,
373 .init_machine = omap_palmte_init,
Tony Lindgren3179a012005-11-10 14:26:48 +0000374 .timer = &omap_timer,
375MACHINE_END