]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - arch/arm/mach-omap1/board-palmte.c
Merge branch 'for_rmk' of git://git.mnementh.co.uk/linux-2.6-im into devel
[mirror_ubuntu-zesty-kernel.git] / arch / arm / mach-omap1 / board-palmte.c
CommitLineData
3179a019
TL
1/*
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 *
6cbdc8c5 10 * Maintainers : http://palmtelinux.sf.net
3179a019
TL
11 * palmtelinux-developpers@lists.sf.net
12 *
d7730cc0
AZ
13 * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
14 *
3179a019
TL
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.
18 */
19
20#include <linux/kernel.h>
21#include <linux/init.h>
c3695015 22#include <linux/input.h>
3179a019 23#include <linux/platform_device.h>
c3695015
AZ
24#include <linux/mtd/mtd.h>
25#include <linux/mtd/partitions.h>
26#include <linux/spi/spi.h>
c3695015 27#include <linux/interrupt.h>
d7730cc0 28#include <linux/apm-emulation.h>
3179a019 29
a09e64fb 30#include <mach/hardware.h>
3179a019
TL
31#include <asm/mach-types.h>
32#include <asm/mach/arch.h>
33#include <asm/mach/map.h>
c3695015 34#include <asm/mach/flash.h>
3179a019 35
a09e64fb
RK
36#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>
45#include <mach/mcbsp.h>
46#include <mach/omap-alsa.h>
3179a019 47
c3695015 48static void __init omap_palmte_init_irq(void)
3179a019 49{
87bd63f6 50 omap1_init_common_hw();
3179a019 51 omap_init_irq();
c3695015 52 omap_gpio_init();
3179a019
TL
53}
54
d7730cc0
AZ
55static const int palmte_keymap[] = {
56 KEY(0, 0, KEY_F1), /* Calendar */
57 KEY(0, 1, KEY_F2), /* Contacts */
58 KEY(0, 2, KEY_F3), /* Tasks List */
59 KEY(0, 3, KEY_F4), /* Note Pad */
c3695015
AZ
60 KEY(0, 4, KEY_POWER),
61 KEY(1, 0, KEY_LEFT),
62 KEY(1, 1, KEY_DOWN),
63 KEY(1, 2, KEY_UP),
64 KEY(1, 3, KEY_RIGHT),
ec44dfa8 65 KEY(1, 4, KEY_ENTER),
c3695015
AZ
66 0,
67};
68
69static struct omap_kp_platform_data palmte_kp_data = {
70 .rows = 8,
71 .cols = 8,
d7730cc0 72 .keymap = (int *) palmte_keymap,
c3695015
AZ
73 .rep = 1,
74 .delay = 12,
75};
76
77static struct resource palmte_kp_resources[] = {
78 [0] = {
79 .start = INT_KEYBOARD,
80 .end = INT_KEYBOARD,
81 .flags = IORESOURCE_IRQ,
82 },
83};
84
85static struct platform_device palmte_kp_device = {
86 .name = "omap-keypad",
87 .id = -1,
88 .dev = {
89 .platform_data = &palmte_kp_data,
90 },
91 .num_resources = ARRAY_SIZE(palmte_kp_resources),
92 .resource = palmte_kp_resources,
93};
94
95static struct mtd_partition palmte_rom_partitions[] = {
96 /* PalmOS "Small ROM", contains the bootloader and the debugger */
97 {
98 .name = "smallrom",
99 .offset = 0,
100 .size = 0xa000,
101 .mask_flags = MTD_WRITEABLE,
102 },
103 /* PalmOS "Big ROM", a filesystem with all the OS code and data */
104 {
105 .name = "bigrom",
106 .offset = SZ_128K,
107 /*
108 * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
109 * 0x7b0000 bytes in the English-only ("enUS") version.
110 */
111 .size = 0x7b0000,
112 .mask_flags = MTD_WRITEABLE,
113 },
114};
115
116static struct flash_platform_data palmte_rom_data = {
117 .map_name = "map_rom",
118 .width = 2,
119 .parts = palmte_rom_partitions,
120 .nr_parts = ARRAY_SIZE(palmte_rom_partitions),
121};
122
123static struct resource palmte_rom_resource = {
124 .start = OMAP_CS0_PHYS,
125 .end = OMAP_CS0_PHYS + SZ_8M - 1,
126 .flags = IORESOURCE_MEM,
127};
128
129static struct platform_device palmte_rom_device = {
130 .name = "omapflash",
131 .id = -1,
132 .dev = {
133 .platform_data = &palmte_rom_data,
134 },
135 .num_resources = 1,
136 .resource = &palmte_rom_resource,
137};
138
9b6553cd
TL
139static struct platform_device palmte_lcd_device = {
140 .name = "lcd_palmte",
141 .id = -1,
142};
143
c3695015
AZ
144static struct omap_backlight_config palmte_backlight_config = {
145 .default_intensity = 0xa0,
146};
147
148static struct platform_device palmte_backlight_device = {
149 .name = "omap-bl",
150 .id = -1,
151 .dev = {
152 .platform_data = &palmte_backlight_config,
153 },
154};
155
156static struct omap_irda_config palmte_irda_config = {
157 .transceiver_cap = IR_SIRMODE,
158 .rx_channel = OMAP_DMA_UART3_RX,
159 .tx_channel = OMAP_DMA_UART3_TX,
160 .dest_start = UART3_THR,
161 .src_start = UART3_RHR,
162 .tx_trigger = 0,
163 .rx_trigger = 0,
164};
165
166static struct resource palmte_irda_resources[] = {
167 [0] = {
168 .start = INT_UART3,
169 .end = INT_UART3,
170 .flags = IORESOURCE_IRQ,
171 },
172};
173
174static struct platform_device palmte_irda_device = {
175 .name = "omapirda",
176 .id = -1,
177 .dev = {
178 .platform_data = &palmte_irda_config,
179 },
180 .num_resources = ARRAY_SIZE(palmte_irda_resources),
181 .resource = palmte_irda_resources,
182};
183
d7730cc0 184static struct platform_device *palmte_devices[] __initdata = {
c3695015
AZ
185 &palmte_rom_device,
186 &palmte_kp_device,
9b6553cd 187 &palmte_lcd_device,
c3695015
AZ
188 &palmte_backlight_device,
189 &palmte_irda_device,
9b6553cd
TL
190};
191
3179a019 192static struct omap_usb_config palmte_usb_config __initdata = {
c3695015 193 .register_dev = 1, /* Mini-B only receptacle */
3179a019 194 .hmc_mode = 0,
c3695015 195 .pins[0] = 2,
3179a019
TL
196};
197
198static struct omap_mmc_config palmte_mmc_config __initdata = {
c3695015 199 .mmc[0] = {
3179a019 200 .enabled = 1,
c3695015
AZ
201 .wp_pin = PALMTE_MMC_WP_GPIO,
202 .power_pin = PALMTE_MMC_POWER_GPIO,
203 .switch_pin = PALMTE_MMC_SWITCH_GPIO,
3179a019
TL
204 },
205};
206
207static struct omap_lcd_config palmte_lcd_config __initdata = {
3179a019
TL
208 .ctrl_name = "internal",
209};
210
c3695015
AZ
211static struct omap_uart_config palmte_uart_config __initdata = {
212 .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
213};
214
215static struct omap_mcbsp_reg_cfg palmte_mcbsp1_regs = {
216 .spcr2 = FRST | GRST | XRST | XINTM(3),
217 .xcr2 = XDATDLY(1) | XFIG,
218 .xcr1 = XWDLEN1(OMAP_MCBSP_WORD_32),
219 .pcr0 = SCLKME | FSXP | CLKXP,
220};
221
222static struct omap_alsa_codec_config palmte_alsa_config = {
223 .name = "TSC2102 audio",
224 .mcbsp_regs_alsa = &palmte_mcbsp1_regs,
225 .codec_configure_dev = NULL, /* tsc2102_configure, */
226 .codec_set_samplerate = NULL, /* tsc2102_set_samplerate, */
227 .codec_clock_setup = NULL, /* tsc2102_clock_setup, */
228 .codec_clock_on = NULL, /* tsc2102_clock_on, */
229 .codec_clock_off = NULL, /* tsc2102_clock_off, */
230 .get_default_samplerate = NULL, /* tsc2102_get_default_samplerate, */
231};
232
233#ifdef CONFIG_APM
234/*
235 * Values measured in 10 minute intervals averaged over 10 samples.
236 * May differ slightly from device to device but should be accurate
237 * enough to give basic idea of battery life left and trigger
238 * potential alerts.
239 */
240static const int palmte_battery_sample[] = {
241 2194, 2157, 2138, 2120,
242 2104, 2089, 2075, 2061,
243 2048, 2038, 2026, 2016,
244 2008, 1998, 1989, 1980,
245 1970, 1958, 1945, 1928,
246 1910, 1888, 1860, 1827,
247 1791, 1751, 1709, 1656,
248};
249
250#define INTERVAL 10
251#define BATTERY_HIGH_TRESHOLD 66
252#define BATTERY_LOW_TRESHOLD 33
253
254static void palmte_get_power_status(struct apm_power_info *info, int *battery)
255{
256 int charging, batt, hi, lo, mid;
257
0b84b5ca 258 charging = !gpio_get_value(PALMTE_DC_GPIO);
c3695015
AZ
259 batt = battery[0];
260 if (charging)
261 batt -= 60;
262
263 hi = ARRAY_SIZE(palmte_battery_sample);
264 lo = 0;
265
266 info->battery_flag = 0;
267 info->units = APM_UNITS_MINS;
268
269 if (batt > palmte_battery_sample[lo]) {
270 info->battery_life = 100;
271 info->time = INTERVAL * ARRAY_SIZE(palmte_battery_sample);
272 } else if (batt <= palmte_battery_sample[hi - 1]) {
273 info->battery_life = 0;
274 info->time = 0;
275 } else {
276 while (hi > lo + 1) {
d7730cc0 277 mid = (hi + lo) >> 1;
c3695015
AZ
278 if (batt <= palmte_battery_sample[mid])
279 lo = mid;
280 else
281 hi = mid;
282 }
283
284 mid = palmte_battery_sample[lo] - palmte_battery_sample[hi];
285 hi = palmte_battery_sample[lo] - batt;
286 info->battery_life = 100 - (100 * lo + 100 * hi / mid) /
287 ARRAY_SIZE(palmte_battery_sample);
288 info->time = INTERVAL * (ARRAY_SIZE(palmte_battery_sample) -
289 lo) - INTERVAL * hi / mid;
290 }
291
292 if (charging) {
293 info->ac_line_status = APM_AC_ONLINE;
294 info->battery_status = APM_BATTERY_STATUS_CHARGING;
295 info->battery_flag |= APM_BATTERY_FLAG_CHARGING;
296 } else {
297 info->ac_line_status = APM_AC_OFFLINE;
298 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
299 info->battery_status = APM_BATTERY_STATUS_HIGH;
300 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
301 info->battery_status = APM_BATTERY_STATUS_LOW;
302 else
303 info->battery_status = APM_BATTERY_STATUS_CRITICAL;
304 }
305
306 if (info->battery_life > BATTERY_HIGH_TRESHOLD)
307 info->battery_flag |= APM_BATTERY_FLAG_HIGH;
308 else if (info->battery_life > BATTERY_LOW_TRESHOLD)
309 info->battery_flag |= APM_BATTERY_FLAG_LOW;
310 else
311 info->battery_flag |= APM_BATTERY_FLAG_CRITICAL;
312}
313#else
314#define palmte_get_power_status NULL
315#endif
316
d7730cc0 317static struct omap_board_config_kernel palmte_config[] __initdata = {
c3695015 318 { OMAP_TAG_USB, &palmte_usb_config },
c3695015
AZ
319 { OMAP_TAG_LCD, &palmte_lcd_config },
320 { OMAP_TAG_UART, &palmte_uart_config },
3179a019
TL
321};
322
c3695015
AZ
323static struct spi_board_info palmte_spi_info[] __initdata = {
324 {
325 .modalias = "tsc2102",
326 .bus_num = 2, /* uWire (officially) */
327 .chip_select = 0, /* As opposed to 3 */
328 .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO),
c3695015
AZ
329 .max_speed_hz = 8000000,
330 },
331};
332
d7730cc0
AZ
333static void palmte_headphones_detect(void *data, int state)
334{
335 if (state) {
c3695015 336 /* Headphones connected, disable speaker */
0b84b5ca 337 gpio_set_value(PALMTE_SPEAKER_GPIO, 0);
c3695015 338 printk(KERN_INFO "PM: speaker off\n");
d7730cc0 339 } else {
c3695015 340 /* Headphones unplugged, re-enable speaker */
0b84b5ca 341 gpio_set_value(PALMTE_SPEAKER_GPIO, 1);
c3695015
AZ
342 printk(KERN_INFO "PM: speaker on\n");
343 }
c3695015
AZ
344}
345
d7730cc0 346static void __init palmte_misc_gpio_setup(void)
c3695015 347{
d7730cc0 348 /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */
f2d18fea 349 if (gpio_request(PALMTE_PINTDAV_GPIO, "TSC2102 PINTDAV") < 0) {
c3695015
AZ
350 printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n");
351 return;
352 }
40e3925b 353 gpio_direction_input(PALMTE_PINTDAV_GPIO);
c3695015 354
d7730cc0 355 /* Set USB-or-DC-IN pin as input (unused) */
f2d18fea 356 if (gpio_request(PALMTE_USB_OR_DC_GPIO, "USB/DC-IN") < 0) {
c3695015
AZ
357 printk(KERN_ERR "Could not reserve cable signal GPIO!\n");
358 return;
359 }
40e3925b 360 gpio_direction_input(PALMTE_USB_OR_DC_GPIO);
c3695015
AZ
361}
362
363static void __init omap_palmte_init(void)
3179a019
TL
364{
365 omap_board_config = palmte_config;
366 omap_board_config_size = ARRAY_SIZE(palmte_config);
9b6553cd 367
d7730cc0 368 platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
c3695015
AZ
369
370 spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
d7730cc0 371 palmte_misc_gpio_setup();
c3695015 372 omap_serial_init();
1ed16a86 373 omap_register_i2c_bus(1, 100, NULL, 0);
3179a019
TL
374}
375
c3695015 376static void __init omap_palmte_map_io(void)
3179a019 377{
87bd63f6 378 omap1_map_common_io();
3179a019
TL
379}
380
381MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
3179a019
TL
382 .phys_io = 0xfff00000,
383 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
384 .boot_params = 0x10000100,
c3695015
AZ
385 .map_io = omap_palmte_map_io,
386 .init_irq = omap_palmte_init_irq,
387 .init_machine = omap_palmte_init,
3179a019
TL
388 .timer = &omap_timer,
389MACHINE_END