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 * 10 * Maintainers : http://palmtelinux.sf.net 11 * palmtelinux-developpers@lists.sf.net 12 * 13 * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org> 14 * 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> 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> 29 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> 35 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 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) 60 61 static void __init omap_palmte_init_irq(void) 62 { 63 omap1_init_common_hw(); 64 omap_init_irq(); 65 omap_gpio_init(); 66 } 67 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 */ 73 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), 78 KEY(1, 4, KEY_ENTER), 79 0, 80 }; 81 82 static struct omap_kp_platform_data palmte_kp_data = { 83 .rows = 8, 84 .cols = 8, 85 .keymap = (int *) palmte_keymap, 86 .rep = 1, 87 .delay = 12, 88 }; 89 90 static struct resource palmte_kp_resources[] = { 91 [0] = { 92 .start = INT_KEYBOARD, 93 .end = INT_KEYBOARD, 94 .flags = IORESOURCE_IRQ, 95 }, 96 }; 97 98 static 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 108 static 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 129 static 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 136 static struct resource palmte_rom_resource = { 137 .start = OMAP_CS0_PHYS, 138 .end = OMAP_CS0_PHYS + SZ_8M - 1, 139 .flags = IORESOURCE_MEM, 140 }; 141 142 static 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 152 static struct platform_device palmte_lcd_device = { 153 .name = "lcd_palmte", 154 .id = -1, 155 }; 156 157 static struct omap_backlight_config palmte_backlight_config = { 158 .default_intensity = 0xa0, 159 }; 160 161 static struct platform_device palmte_backlight_device = { 162 .name = "omap-bl", 163 .id = -1, 164 .dev = { 165 .platform_data = &palmte_backlight_config, 166 }, 167 }; 168 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, 175 .tx_trigger = 0, 176 .rx_trigger = 0, 177 }; 178 179 static struct resource palmte_irda_resources[] = { 180 [0] = { 181 .start = INT_UART3, 182 .end = INT_UART3, 183 .flags = IORESOURCE_IRQ, 184 }, 185 }; 186 187 static 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 197 static struct platform_device *palmte_devices[] __initdata = { 198 &palmte_rom_device, 199 &palmte_kp_device, 200 &palmte_lcd_device, 201 &palmte_backlight_device, 202 &palmte_irda_device, 203 }; 204 205 static struct omap_usb_config palmte_usb_config __initdata = { 206 .register_dev = 1, /* Mini-B only receptacle */ 207 .hmc_mode = 0, 208 .pins[0] = 2, 209 }; 210 211 static struct omap_lcd_config palmte_lcd_config __initdata = { 212 .ctrl_name = "internal", 213 }; 214 215 static struct omap_uart_config palmte_uart_config __initdata = { 216 .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2), 217 }; 218 219 #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 */ 226 static 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 240 static void palmte_get_power_status(struct apm_power_info *info, int *battery) 241 { 242 int charging, batt, hi, lo, mid; 243 244 charging = !gpio_get_value(PALMTE_DC_GPIO); 245 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) { 263 mid = (hi + lo) >> 1; 264 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 303 static struct omap_board_config_kernel palmte_config[] __initdata = { 304 { OMAP_TAG_LCD, &palmte_lcd_config }, 305 { OMAP_TAG_UART, &palmte_uart_config }, 306 }; 307 308 static 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), 314 .max_speed_hz = 8000000, 315 }, 316 }; 317 318 static void palmte_headphones_detect(void *data, int state) 319 { 320 if (state) { 321 /* Headphones connected, disable speaker */ 322 gpio_set_value(PALMTE_SPEAKER_GPIO, 0); 323 printk(KERN_INFO "PM: speaker off\n"); 324 } else { 325 /* Headphones unplugged, re-enable speaker */ 326 gpio_set_value(PALMTE_SPEAKER_GPIO, 1); 327 printk(KERN_INFO "PM: speaker on\n"); 328 } 329 } 330 331 static void __init palmte_misc_gpio_setup(void) 332 { 333 /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */ 334 if (gpio_request(PALMTE_PINTDAV_GPIO, "TSC2102 PINTDAV") < 0) { 335 printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n"); 336 return; 337 } 338 gpio_direction_input(PALMTE_PINTDAV_GPIO); 339 340 /* Set USB-or-DC-IN pin as input (unused) */ 341 if (gpio_request(PALMTE_USB_OR_DC_GPIO, "USB/DC-IN") < 0) { 342 printk(KERN_ERR "Could not reserve cable signal GPIO!\n"); 343 return; 344 } 345 gpio_direction_input(PALMTE_USB_OR_DC_GPIO); 346 } 347 348 static void __init omap_palmte_init(void) 349 { 350 omap_board_config = palmte_config; 351 omap_board_config_size = ARRAY_SIZE(palmte_config); 352 353 platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices)); 354 355 spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info)); 356 palmte_misc_gpio_setup(); 357 omap_serial_init(); 358 omap_usb_init(&palmte_usb_config); 359 omap_register_i2c_bus(1, 100, NULL, 0); 360 } 361 362 static void __init omap_palmte_map_io(void) 363 { 364 omap1_map_common_io(); 365 } 366 367 MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") 368 .phys_io = 0xfff00000, 369 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, 370 .boot_params = 0x10000100, 371 .map_io = omap_palmte_map_io, 372 .init_irq = omap_palmte_init_irq, 373 .init_machine = omap_palmte_init, 374 .timer = &omap_timer, 375 MACHINE_END 376