diff options
author | Andrzej Zaborowski <balrog@zabor.org> | 2006-12-06 20:13:51 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2007-09-20 21:34:49 -0400 |
commit | c3695015087e21ff30606bf7fc661de1582af81b (patch) | |
tree | 39bbd9b6e10997dd7448a2dd64e48832ef575def /arch/arm/mach-omap1/board-palmte.c | |
parent | 6ea59bb3083dea3b48003ea49de12a3e3c868b05 (diff) |
ARM: OMAP: Palm Tungsten E board update
General update of the board file for Palm Tungsten E. Registers the
platform devices contained in the PDA (ROM chip, keypad, infra-red)
and updates the configuration for USB and MMC, whose config values
were previously guessed in most cases due to lack of documentation
(and now are confirmed by a number of users). Macros for GPIO pins are
moved to a file in include/asm-arm/arch-omap.
Signed-off-by: Andrzej Zaborowski <balrog@zabor.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap1/board-palmte.c')
-rw-r--r-- | arch/arm/mach-omap1/board-palmte.c | 377 |
1 files changed, 359 insertions, 18 deletions
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 015824185629..2f9d00a00135 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c | |||
@@ -17,49 +17,189 @@ | |||
17 | 17 | ||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/input.h> | ||
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | #include <linux/notifier.h> | 22 | #include <linux/mtd/mtd.h> |
22 | #include <linux/clk.h> | 23 | #include <linux/mtd/partitions.h> |
24 | #include <linux/spi/spi.h> | ||
25 | #include <linux/spi/tsc2102.h> | ||
26 | #include <linux/interrupt.h> | ||
23 | 27 | ||
28 | #include <asm/apm.h> | ||
24 | #include <asm/hardware.h> | 29 | #include <asm/hardware.h> |
25 | #include <asm/mach-types.h> | 30 | #include <asm/mach-types.h> |
26 | #include <asm/mach/arch.h> | 31 | #include <asm/mach/arch.h> |
27 | #include <asm/mach/map.h> | 32 | #include <asm/mach/map.h> |
33 | #include <asm/mach/flash.h> | ||
28 | 34 | ||
29 | #include <asm/arch/gpio.h> | 35 | #include <asm/arch/gpio.h> |
30 | #include <asm/arch/mux.h> | 36 | #include <asm/arch/mux.h> |
31 | #include <asm/arch/usb.h> | 37 | #include <asm/arch/usb.h> |
38 | #include <asm/arch/tc.h> | ||
39 | #include <asm/arch/dma.h> | ||
32 | #include <asm/arch/board.h> | 40 | #include <asm/arch/board.h> |
41 | #include <asm/arch/irda.h> | ||
42 | #include <asm/arch/keypad.h> | ||
33 | #include <asm/arch/common.h> | 43 | #include <asm/arch/common.h> |
44 | #include <asm/arch/mcbsp.h> | ||
45 | #include <asm/arch/omap-alsa.h> | ||
34 | 46 | ||
35 | static void __init omap_generic_init_irq(void) | 47 | static void __init omap_palmte_init_irq(void) |
36 | { | 48 | { |
37 | omap1_init_common_hw(); | 49 | omap1_init_common_hw(); |
38 | omap_init_irq(); | 50 | omap_init_irq(); |
51 | omap_gpio_init(); | ||
39 | } | 52 | } |
40 | 53 | ||
54 | static int palmte_keymap[] = { | ||
55 | KEY(0, 0, KEY_F1), | ||
56 | KEY(0, 1, KEY_F2), | ||
57 | KEY(0, 2, KEY_F3), | ||
58 | KEY(0, 3, KEY_F4), | ||
59 | KEY(0, 4, KEY_POWER), | ||
60 | KEY(1, 0, KEY_LEFT), | ||
61 | KEY(1, 1, KEY_DOWN), | ||
62 | KEY(1, 2, KEY_UP), | ||
63 | KEY(1, 3, KEY_RIGHT), | ||
64 | KEY(1, 4, KEY_CENTER), | ||
65 | 0, | ||
66 | }; | ||
67 | |||
68 | static struct omap_kp_platform_data palmte_kp_data = { | ||
69 | .rows = 8, | ||
70 | .cols = 8, | ||
71 | .keymap = palmte_keymap, | ||
72 | .rep = 1, | ||
73 | .delay = 12, | ||
74 | }; | ||
75 | |||
76 | static struct resource palmte_kp_resources[] = { | ||
77 | [0] = { | ||
78 | .start = INT_KEYBOARD, | ||
79 | .end = INT_KEYBOARD, | ||
80 | .flags = IORESOURCE_IRQ, | ||
81 | }, | ||
82 | }; | ||
83 | |||
84 | static struct platform_device palmte_kp_device = { | ||
85 | .name = "omap-keypad", | ||
86 | .id = -1, | ||
87 | .dev = { | ||
88 | .platform_data = &palmte_kp_data, | ||
89 | }, | ||
90 | .num_resources = ARRAY_SIZE(palmte_kp_resources), | ||
91 | .resource = palmte_kp_resources, | ||
92 | }; | ||
93 | |||
94 | static struct mtd_partition palmte_rom_partitions[] = { | ||
95 | /* PalmOS "Small ROM", contains the bootloader and the debugger */ | ||
96 | { | ||
97 | .name = "smallrom", | ||
98 | .offset = 0, | ||
99 | .size = 0xa000, | ||
100 | .mask_flags = MTD_WRITEABLE, | ||
101 | }, | ||
102 | /* PalmOS "Big ROM", a filesystem with all the OS code and data */ | ||
103 | { | ||
104 | .name = "bigrom", | ||
105 | .offset = SZ_128K, | ||
106 | /* | ||
107 | * 0x5f0000 bytes big in the multi-language ("EFIGS") version, | ||
108 | * 0x7b0000 bytes in the English-only ("enUS") version. | ||
109 | */ | ||
110 | .size = 0x7b0000, | ||
111 | .mask_flags = MTD_WRITEABLE, | ||
112 | }, | ||
113 | }; | ||
114 | |||
115 | static struct flash_platform_data palmte_rom_data = { | ||
116 | .map_name = "map_rom", | ||
117 | .width = 2, | ||
118 | .parts = palmte_rom_partitions, | ||
119 | .nr_parts = ARRAY_SIZE(palmte_rom_partitions), | ||
120 | }; | ||
121 | |||
122 | static struct resource palmte_rom_resource = { | ||
123 | .start = OMAP_CS0_PHYS, | ||
124 | .end = OMAP_CS0_PHYS + SZ_8M - 1, | ||
125 | .flags = IORESOURCE_MEM, | ||
126 | }; | ||
127 | |||
128 | static struct platform_device palmte_rom_device = { | ||
129 | .name = "omapflash", | ||
130 | .id = -1, | ||
131 | .dev = { | ||
132 | .platform_data = &palmte_rom_data, | ||
133 | }, | ||
134 | .num_resources = 1, | ||
135 | .resource = &palmte_rom_resource, | ||
136 | }; | ||
137 | |||
41 | static struct platform_device palmte_lcd_device = { | 138 | static struct platform_device palmte_lcd_device = { |
42 | .name = "lcd_palmte", | 139 | .name = "lcd_palmte", |
43 | .id = -1, | 140 | .id = -1, |
44 | }; | 141 | }; |
45 | 142 | ||
143 | static struct omap_backlight_config palmte_backlight_config = { | ||
144 | .default_intensity = 0xa0, | ||
145 | }; | ||
146 | |||
147 | static struct platform_device palmte_backlight_device = { | ||
148 | .name = "omap-bl", | ||
149 | .id = -1, | ||
150 | .dev = { | ||
151 | .platform_data = &palmte_backlight_config, | ||
152 | }, | ||
153 | }; | ||
154 | |||
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, | ||
161 | .tx_trigger = 0, | ||
162 | .rx_trigger = 0, | ||
163 | }; | ||
164 | |||
165 | static struct resource palmte_irda_resources[] = { | ||
166 | [0] = { | ||
167 | .start = INT_UART3, | ||
168 | .end = INT_UART3, | ||
169 | .flags = IORESOURCE_IRQ, | ||
170 | }, | ||
171 | }; | ||
172 | |||
173 | static struct platform_device palmte_irda_device = { | ||
174 | .name = "omapirda", | ||
175 | .id = -1, | ||
176 | .dev = { | ||
177 | .platform_data = &palmte_irda_config, | ||
178 | }, | ||
179 | .num_resources = ARRAY_SIZE(palmte_irda_resources), | ||
180 | .resource = palmte_irda_resources, | ||
181 | }; | ||
182 | |||
46 | static struct platform_device *devices[] __initdata = { | 183 | static struct platform_device *devices[] __initdata = { |
184 | &palmte_rom_device, | ||
185 | &palmte_kp_device, | ||
47 | &palmte_lcd_device, | 186 | &palmte_lcd_device, |
187 | &palmte_backlight_device, | ||
188 | &palmte_irda_device, | ||
48 | }; | 189 | }; |
49 | 190 | ||
50 | static struct omap_usb_config palmte_usb_config __initdata = { | 191 | static struct omap_usb_config palmte_usb_config __initdata = { |
51 | .register_dev = 1, | 192 | .register_dev = 1, /* Mini-B only receptacle */ |
52 | .hmc_mode = 0, | 193 | .hmc_mode = 0, |
53 | .pins[0] = 3, | 194 | .pins[0] = 2, |
54 | }; | 195 | }; |
55 | 196 | ||
56 | static struct omap_mmc_config palmte_mmc_config __initdata = { | 197 | static struct omap_mmc_config palmte_mmc_config __initdata = { |
57 | .mmc [0] = { | 198 | .mmc[0] = { |
58 | .enabled = 1, | 199 | .enabled = 1, |
59 | .wire4 = 1, | 200 | .wp_pin = PALMTE_MMC_WP_GPIO, |
60 | .wp_pin = OMAP_MPUIO(3), | 201 | .power_pin = PALMTE_MMC_POWER_GPIO, |
61 | .power_pin = -1, | 202 | .switch_pin = PALMTE_MMC_SWITCH_GPIO, |
62 | .switch_pin = -1, | ||
63 | }, | 203 | }, |
64 | }; | 204 | }; |
65 | 205 | ||
@@ -67,21 +207,222 @@ static struct omap_lcd_config palmte_lcd_config __initdata = { | |||
67 | .ctrl_name = "internal", | 207 | .ctrl_name = "internal", |
68 | }; | 208 | }; |
69 | 209 | ||
210 | static struct omap_uart_config palmte_uart_config __initdata = { | ||
211 | .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2), | ||
212 | }; | ||
213 | |||
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, | ||
219 | }; | ||
220 | |||
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, */ | ||
230 | }; | ||
231 | |||
232 | #ifdef CONFIG_APM | ||
233 | /* | ||
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 | ||
237 | * potential alerts. | ||
238 | */ | ||
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, | ||
247 | }; | ||
248 | |||
249 | #define INTERVAL 10 | ||
250 | #define BATTERY_HIGH_TRESHOLD 66 | ||
251 | #define BATTERY_LOW_TRESHOLD 33 | ||
252 | |||
253 | static void palmte_get_power_status(struct apm_power_info *info, int *battery) | ||
254 | { | ||
255 | int charging, batt, hi, lo, mid; | ||
256 | |||
257 | charging = !omap_get_gpio_datain(PALMTE_DC_GPIO); | ||
258 | batt = battery[0]; | ||
259 | if (charging) | ||
260 | batt -= 60; | ||
261 | |||
262 | hi = ARRAY_SIZE(palmte_battery_sample); | ||
263 | lo = 0; | ||
264 | |||
265 | info->battery_flag = 0; | ||
266 | info->units = APM_UNITS_MINS; | ||
267 | |||
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; | ||
273 | info->time = 0; | ||
274 | } else { | ||
275 | while (hi > lo + 1) { | ||
276 | mid = (hi + lo) >> 2; | ||
277 | if (batt <= palmte_battery_sample[mid]) | ||
278 | lo = mid; | ||
279 | else | ||
280 | hi = mid; | ||
281 | } | ||
282 | |||
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; | ||
289 | } | ||
290 | |||
291 | if (charging) { | ||
292 | info->ac_line_status = APM_AC_ONLINE; | ||
293 | info->battery_status = APM_BATTERY_STATUS_CHARGING; | ||
294 | info->battery_flag |= APM_BATTERY_FLAG_CHARGING; | ||
295 | } else { | ||
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; | ||
301 | else | ||
302 | info->battery_status = APM_BATTERY_STATUS_CRITICAL; | ||
303 | } | ||
304 | |||
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; | ||
309 | else | ||
310 | info->battery_flag |= APM_BATTERY_FLAG_CRITICAL; | ||
311 | } | ||
312 | #else | ||
313 | #define palmte_get_power_status NULL | ||
314 | #endif | ||
315 | |||
316 | static struct tsc2102_config palmte_tsc2102_config = { | ||
317 | .use_internal = 0, | ||
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, | ||
322 | }; | ||
323 | |||
70 | static struct omap_board_config_kernel palmte_config[] = { | 324 | static struct omap_board_config_kernel palmte_config[] = { |
71 | { OMAP_TAG_USB, &palmte_usb_config }, | 325 | { OMAP_TAG_USB, &palmte_usb_config }, |
72 | { OMAP_TAG_MMC, &palmte_mmc_config }, | 326 | { OMAP_TAG_MMC, &palmte_mmc_config }, |
73 | { OMAP_TAG_LCD, &palmte_lcd_config }, | 327 | { OMAP_TAG_LCD, &palmte_lcd_config }, |
328 | { OMAP_TAG_UART, &palmte_uart_config }, | ||
74 | }; | 329 | }; |
75 | 330 | ||
76 | static void __init omap_generic_init(void) | 331 | static struct spi_board_info palmte_spi_info[] __initdata = { |
332 | { | ||
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, | ||
339 | }, | ||
340 | }; | ||
341 | |||
342 | /* Periodically check for changes on important input pins */ | ||
343 | struct timer_list palmte_pin_timer; | ||
344 | int prev_power, prev_headphones; | ||
345 | |||
346 | static void palmte_pin_handler(unsigned long data) { | ||
347 | int power, headphones; | ||
348 | |||
349 | power = !omap_get_gpio_datain(PALMTE_DC_GPIO); | ||
350 | headphones = omap_get_gpio_datain(PALMTE_HEADPHONES_GPIO); | ||
351 | |||
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"); | ||
356 | |||
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"); | ||
365 | } | ||
366 | |||
367 | prev_power = power; | ||
368 | prev_headphones = headphones; | ||
369 | mod_timer(&palmte_pin_timer, jiffies + msecs_to_jiffies(500)); | ||
370 | } | ||
371 | |||
372 | static void __init palmte_gpio_setup(void) | ||
373 | { | ||
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"); | ||
377 | return; | ||
378 | } | ||
379 | omap_set_gpio_direction(PALMTE_PINTDAV_GPIO, 1); | ||
380 | |||
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"); | ||
386 | return; | ||
387 | } | ||
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); | ||
391 | |||
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"); | ||
395 | return; | ||
396 | } | ||
397 | omap_set_gpio_direction(PALMTE_SPEAKER_GPIO, 0); | ||
398 | |||
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"); | ||
402 | return; | ||
403 | } | ||
404 | omap_set_gpio_direction(PALMTE_HEADPHONES_GPIO, 1); | ||
405 | |||
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); | ||
410 | } | ||
411 | |||
412 | static void __init omap_palmte_init(void) | ||
77 | { | 413 | { |
78 | omap_board_config = palmte_config; | 414 | omap_board_config = palmte_config; |
79 | omap_board_config_size = ARRAY_SIZE(palmte_config); | 415 | omap_board_config_size = ARRAY_SIZE(palmte_config); |
80 | 416 | ||
81 | platform_add_devices(devices, ARRAY_SIZE(devices)); | 417 | platform_add_devices(devices, ARRAY_SIZE(devices)); |
418 | |||
419 | spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info)); | ||
420 | |||
421 | omap_serial_init(); | ||
422 | palmte_gpio_setup(); | ||
82 | } | 423 | } |
83 | 424 | ||
84 | static void __init omap_generic_map_io(void) | 425 | static void __init omap_palmte_map_io(void) |
85 | { | 426 | { |
86 | omap1_map_common_io(); | 427 | omap1_map_common_io(); |
87 | } | 428 | } |
@@ -90,8 +431,8 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") | |||
90 | .phys_io = 0xfff00000, | 431 | .phys_io = 0xfff00000, |
91 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, | 432 | .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, |
92 | .boot_params = 0x10000100, | 433 | .boot_params = 0x10000100, |
93 | .map_io = omap_generic_map_io, | 434 | .map_io = omap_palmte_map_io, |
94 | .init_irq = omap_generic_init_irq, | 435 | .init_irq = omap_palmte_init_irq, |
95 | .init_machine = omap_generic_init, | 436 | .init_machine = omap_palmte_init, |
96 | .timer = &omap_timer, | 437 | .timer = &omap_timer, |
97 | MACHINE_END | 438 | MACHINE_END |