1 /* 2 * (C) Copyright 2012 3 * Ивайло Димитров <freemangordon@abv.bg> 4 * 5 * (C) Copyright 2011-2012 6 * Pali Rohár <pali.rohar@gmail.com> 7 * 8 * (C) Copyright 2010 9 * Alistair Buxton <a.j.buxton@gmail.com> 10 * 11 * Derived from Beagle Board and 3430 SDP code: 12 * (C) Copyright 2004-2008 13 * Texas Instruments, <www.ti.com> 14 * 15 * Author : 16 * Sunil Kumar <sunilsaini05@gmail.com> 17 * Shashi Ranjan <shashiranjanmca05@gmail.com> 18 * 19 * Richard Woodruff <r-woodruff2@ti.com> 20 * Syed Mohammed Khasim <khasim@ti.com> 21 * 22 * See file CREDITS for list of people who contributed to this 23 * project. 24 * 25 * This program is free software; you can redistribute it and/or 26 * modify it under the terms of the GNU General Public License as 27 * published by the Free Software Foundation; either version 2 of 28 * the License, or (at your option) any later version. 29 * 30 * This program is distributed in the hope that it will be useful, 31 * but WITHOUT ANY WARRANTY; without even the implied warranty of 32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 * GNU General Public License for more details. 34 * 35 * You should have received a copy of the GNU General Public License 36 * along with this program; if not, write to the Free Software 37 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 38 * MA 02111-1307 USA 39 */ 40 41 #include <common.h> 42 #include <watchdog.h> 43 #include <malloc.h> 44 #include <twl4030.h> 45 #include <i2c.h> 46 #include <video_fb.h> 47 #include <asm/io.h> 48 #include <asm/setup.h> 49 #include <asm/bitops.h> 50 #include <asm/mach-types.h> 51 #include <asm/arch/mux.h> 52 #include <asm/arch/sys_proto.h> 53 #include <asm/arch/mmc_host_def.h> 54 55 #include "rx51.h" 56 #include "tag_omap.h" 57 58 DECLARE_GLOBAL_DATA_PTR; 59 60 GraphicDevice gdev; 61 62 const omap3_sysinfo sysinfo = { 63 DDR_STACKED, 64 "Nokia RX-51", 65 "OneNAND" 66 }; 67 68 /* This structure contains default omap tags needed for booting Maemo 5 */ 69 static struct tag_omap omap[] = { 70 OMAP_TAG_UART_CONFIG(0x04), 71 OMAP_TAG_SERIAL_CONSOLE_CONFIG(0x03, 0x01C200), 72 OMAP_TAG_LCD_CONFIG("acx565akm", "internal", 90, 0x18), 73 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_focus", 0x44, 0x1, 0x2, 0x0), 74 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_launch", 0x45, 0x1, 0x2, 0x0), 75 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_shutter", 0x6e, 0x1, 0x0, 0x0), 76 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_apeslpx", 0x46, 0x2, 0x2, 0x0), 77 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_bsi", 0x9d, 0x2, 0x2, 0x0), 78 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_en", 0x4a, 0x2, 0x2, 0x0), 79 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_rst", 0x4b, 0x6, 0x2, 0x0), 80 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_rst_rq", 0x49, 0x6, 0x2, 0x0), 81 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_wddis", 0x0d, 0x2, 0x2, 0x0), 82 OMAP_TAG_GPIO_SWITCH_CONFIG("headphone", 0xb1, 0x1, 0x1, 0x0), 83 OMAP_TAG_GPIO_SWITCH_CONFIG("kb_lock", 0x71, 0x1, 0x0, 0x0), 84 OMAP_TAG_GPIO_SWITCH_CONFIG("proximity", 0x59, 0x0, 0x0, 0x0), 85 OMAP_TAG_GPIO_SWITCH_CONFIG("sleep_ind", 0xa2, 0x2, 0x2, 0x0), 86 OMAP_TAG_GPIO_SWITCH_CONFIG("slide", GPIO_SLIDE, 0x0, 0x0, 0x0), 87 OMAP_TAG_WLAN_CX3110X_CONFIG(0x25, 0xff, 87, 42, -1), 88 OMAP_TAG_PARTITION_CONFIG(PART1_NAME, PART1_SIZE * PART1_MULL, 89 PART1_OFFS, PART1_MASK), 90 OMAP_TAG_PARTITION_CONFIG(PART2_NAME, PART2_SIZE * PART2_MULL, 91 PART2_OFFS, PART2_MASK), 92 OMAP_TAG_PARTITION_CONFIG(PART3_NAME, PART3_SIZE * PART3_MULL, 93 PART3_OFFS, PART3_MASK), 94 OMAP_TAG_PARTITION_CONFIG(PART4_NAME, PART4_SIZE * PART4_MULL, 95 PART4_OFFS, PART4_MASK), 96 OMAP_TAG_PARTITION_CONFIG(PART5_NAME, PART5_SIZE * PART5_MULL, 97 PART5_OFFS, PART5_MASK), 98 OMAP_TAG_PARTITION_CONFIG(PART6_NAME, PART6_SIZE * PART6_MULL, 99 PART6_OFFS, PART6_MASK), 100 OMAP_TAG_BOOT_REASON_CONFIG("pwr_key"), 101 OMAP_TAG_VERSION_STR_CONFIG("product", "RX-51"), 102 OMAP_TAG_VERSION_STR_CONFIG("hw-build", "2101"), 103 OMAP_TAG_VERSION_STR_CONFIG("nolo", "1.4.14"), 104 OMAP_TAG_VERSION_STR_CONFIG("boot-mode", "normal"), 105 { } 106 }; 107 108 static char *boot_reason_ptr; 109 static char *hw_build_ptr; 110 static char *nolo_version_ptr; 111 static char *boot_mode_ptr; 112 113 /* 114 * Routine: init_omap_tags 115 * Description: Initialize pointers to values in tag_omap 116 */ 117 static void init_omap_tags(void) 118 { 119 char *component; 120 char *version; 121 int i = 0; 122 while (omap[i].hdr.tag) { 123 switch (omap[i].hdr.tag) { 124 case OMAP_TAG_BOOT_REASON: 125 boot_reason_ptr = omap[i].u.boot_reason.reason_str; 126 break; 127 case OMAP_TAG_VERSION_STR: 128 component = omap[i].u.version.component; 129 version = omap[i].u.version.version; 130 if (strcmp(component, "hw-build") == 0) 131 hw_build_ptr = version; 132 else if (strcmp(component, "nolo") == 0) 133 nolo_version_ptr = version; 134 else if (strcmp(component, "boot-mode") == 0) 135 boot_mode_ptr = version; 136 break; 137 default: 138 break; 139 } 140 i++; 141 } 142 } 143 144 static void reuse_omap_atags(struct tag_omap *t) 145 { 146 char *component; 147 char *version; 148 while (t->hdr.tag) { 149 switch (t->hdr.tag) { 150 case OMAP_TAG_BOOT_REASON: 151 memset(boot_reason_ptr, 0, 12); 152 strcpy(boot_reason_ptr, t->u.boot_reason.reason_str); 153 break; 154 case OMAP_TAG_VERSION_STR: 155 component = t->u.version.component; 156 version = t->u.version.version; 157 if (strcmp(component, "hw-build") == 0) { 158 memset(hw_build_ptr, 0, 12); 159 strcpy(hw_build_ptr, version); 160 } else if (strcmp(component, "nolo") == 0) { 161 memset(nolo_version_ptr, 0, 12); 162 strcpy(nolo_version_ptr, version); 163 } else if (strcmp(component, "boot-mode") == 0) { 164 memset(boot_mode_ptr, 0, 12); 165 strcpy(boot_mode_ptr, version); 166 } 167 break; 168 default: 169 break; 170 } 171 t = tag_omap_next(t); 172 } 173 } 174 175 /* 176 * Routine: reuse_atags 177 * Description: Reuse atags from previous bootloader. 178 * Reuse only only HW build, boot reason, boot mode and nolo 179 */ 180 static void reuse_atags(void) 181 { 182 struct tag *t = (struct tag *)gd->bd->bi_boot_params; 183 184 /* First tag must be ATAG_CORE */ 185 if (t->hdr.tag != ATAG_CORE) 186 return; 187 188 if (!boot_reason_ptr || !hw_build_ptr) 189 return; 190 191 /* Last tag must be ATAG_NONE */ 192 while (t->hdr.tag != ATAG_NONE) { 193 switch (t->hdr.tag) { 194 case ATAG_REVISION: 195 memset(hw_build_ptr, 0, 12); 196 sprintf(hw_build_ptr, "%x", t->u.revision.rev); 197 break; 198 case ATAG_BOARD: 199 reuse_omap_atags((struct tag_omap *)&t->u); 200 break; 201 default: 202 break; 203 } 204 t = tag_next(t); 205 } 206 } 207 208 /* 209 * Routine: board_init 210 * Description: Early hardware init. 211 */ 212 int board_init(void) 213 { 214 /* in SRAM or SDRAM, finish GPMC */ 215 gpmc_init(); 216 /* boot param addr */ 217 gd->bd->bi_boot_params = OMAP34XX_SDRC_CS0 + 0x100; 218 return 0; 219 } 220 221 /* 222 * Routine: get_board_revision 223 * Description: Return board revision. 224 */ 225 u32 get_board_rev(void) 226 { 227 return simple_strtol(hw_build_ptr, NULL, 16); 228 } 229 230 /* 231 * Routine: setup_board_tags 232 * Description: Append board specific boot tags. 233 */ 234 void setup_board_tags(struct tag **in_params) 235 { 236 int setup_console_atag; 237 char *setup_boot_reason_atag; 238 char *setup_boot_mode_atag; 239 char *str; 240 int i; 241 int size; 242 int total_size; 243 struct tag *params; 244 struct tag_omap *t; 245 246 params = (struct tag *)gd->bd->bi_boot_params; 247 248 params->u.core.flags = 0x0; 249 params->u.core.pagesize = 0x1000; 250 params->u.core.rootdev = 0x0; 251 252 /* append omap atag only if env setup_omap_atag is set to 1 */ 253 str = getenv("setup_omap_atag"); 254 if (!str || str[0] != '1') 255 return; 256 257 str = getenv("setup_console_atag"); 258 if (str && str[0] == '1') 259 setup_console_atag = 1; 260 else 261 setup_console_atag = 0; 262 263 setup_boot_reason_atag = getenv("setup_boot_reason_atag"); 264 setup_boot_mode_atag = getenv("setup_boot_mode_atag"); 265 266 params = *in_params; 267 t = (struct tag_omap *)¶ms->u; 268 total_size = sizeof(struct tag_header); 269 270 for (i = 0; omap[i].hdr.tag; i++) { 271 272 /* skip serial console tag */ 273 if (!setup_console_atag && 274 omap[i].hdr.tag == OMAP_TAG_SERIAL_CONSOLE) 275 continue; 276 277 size = omap[i].hdr.size + sizeof(struct tag_omap_header); 278 memcpy(t, &omap[i], size); 279 280 /* set uart tag to 0 - disable serial console */ 281 if (!setup_console_atag && omap[i].hdr.tag == OMAP_TAG_UART) 282 t->u.uart.enabled_uarts = 0; 283 284 /* change boot reason */ 285 if (setup_boot_reason_atag && 286 omap[i].hdr.tag == OMAP_TAG_BOOT_REASON) { 287 memset(t->u.boot_reason.reason_str, 0, 12); 288 strcpy(t->u.boot_reason.reason_str, 289 setup_boot_reason_atag); 290 } 291 292 /* change boot mode */ 293 if (setup_boot_mode_atag && 294 omap[i].hdr.tag == OMAP_TAG_VERSION_STR && 295 strcmp(omap[i].u.version.component, "boot-mode") == 0) { 296 memset(t->u.version.version, 0, 12); 297 strcpy(t->u.version.version, setup_boot_mode_atag); 298 } 299 300 total_size += size; 301 t = tag_omap_next(t); 302 303 } 304 305 params->hdr.tag = ATAG_BOARD; 306 params->hdr.size = total_size >> 2; 307 params = tag_next(params); 308 309 *in_params = params; 310 } 311 312 /* 313 * Routine: video_hw_init 314 * Description: Set up the GraphicDevice depending on sys_boot. 315 */ 316 void *video_hw_init(void) 317 { 318 /* fill in Graphic Device */ 319 gdev.frameAdrs = 0x8f9c0000; 320 gdev.winSizeX = 800; 321 gdev.winSizeY = 480; 322 gdev.gdfBytesPP = 2; 323 gdev.gdfIndex = GDF_16BIT_565RGB; 324 memset((void *)gdev.frameAdrs, 0, 0xbb800); 325 return (void *) &gdev; 326 } 327 328 /* 329 * Routine: twl4030_regulator_set_mode 330 * Description: Set twl4030 regulator mode over i2c powerbus. 331 */ 332 static void twl4030_regulator_set_mode(u8 id, u8 mode) 333 { 334 u16 msg = MSG_SINGULAR(DEV_GRP_P1, id, mode); 335 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, msg >> 8, 336 TWL4030_PM_MASTER_PB_WORD_MSB); 337 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, msg & 0xff, 338 TWL4030_PM_MASTER_PB_WORD_LSB); 339 } 340 341 static void omap3_emu_romcode_call(u32 service_id, u32 *parameters) 342 { 343 u32 i, num_params = *parameters; 344 u32 *sram_scratch_space = (u32 *)OMAP3_PUBLIC_SRAM_SCRATCH_AREA; 345 346 /* 347 * copy the parameters to an un-cached area to avoid coherency 348 * issues 349 */ 350 for (i = 0; i < num_params; i++) { 351 __raw_writel(*parameters, sram_scratch_space); 352 parameters++; 353 sram_scratch_space++; 354 } 355 356 /* Now make the PPA call */ 357 do_omap3_emu_romcode_call(service_id, OMAP3_PUBLIC_SRAM_SCRATCH_AREA); 358 } 359 360 /* 361 * Routine: omap3_update_aux_cr_secure_rx51 362 * Description: Modify the contents Auxiliary Control Register. 363 * Parameters: 364 * set_bits - bits to set in ACR 365 * clr_bits - bits to clear in ACR 366 */ 367 static void omap3_update_aux_cr_secure_rx51(u32 set_bits, u32 clear_bits) 368 { 369 struct emu_hal_params_rx51 emu_romcode_params = { 0, }; 370 u32 acr; 371 372 /* Read ACR */ 373 asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr)); 374 acr &= ~clear_bits; 375 acr |= set_bits; 376 377 emu_romcode_params.num_params = 2; 378 emu_romcode_params.param1 = acr; 379 380 omap3_emu_romcode_call(OMAP3_EMU_HAL_API_WRITE_ACR, 381 (u32 *)&emu_romcode_params); 382 } 383 384 /* 385 * Routine: misc_init_r 386 * Description: Configure board specific parts. 387 */ 388 int misc_init_r(void) 389 { 390 char buf[12]; 391 u8 state; 392 393 /* reset lp5523 led */ 394 i2c_set_bus_num(1); 395 state = 0xff; 396 i2c_write(0x32, 0x3d, 1, &state, 1); 397 i2c_set_bus_num(0); 398 399 /* initialize twl4030 power managment */ 400 twl4030_power_init(); 401 402 /* set VSIM to 1.8V */ 403 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VSIM_DEDICATED, 404 TWL4030_PM_RECEIVER_VSIM_VSEL_18, 405 TWL4030_PM_RECEIVER_VSIM_DEV_GRP, 406 TWL4030_PM_RECEIVER_DEV_GRP_P1); 407 408 /* store I2C access state */ 409 twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, &state, 410 TWL4030_PM_MASTER_PB_CFG); 411 412 /* enable I2C access to powerbus (needed for twl4030 regulator) */ 413 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, 0x02, 414 TWL4030_PM_MASTER_PB_CFG); 415 416 /* set VAUX3, VSIM and VMMC1 state to active - enable eMMC memory */ 417 twl4030_regulator_set_mode(RES_VAUX3, RES_STATE_ACTIVE); 418 twl4030_regulator_set_mode(RES_VSIM, RES_STATE_ACTIVE); 419 twl4030_regulator_set_mode(RES_VMMC1, RES_STATE_ACTIVE); 420 421 /* restore I2C access state */ 422 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, state, 423 TWL4030_PM_MASTER_PB_CFG); 424 425 /* set env variable attkernaddr for relocated kernel */ 426 sprintf(buf, "%#x", KERNEL_ADDRESS); 427 setenv("attkernaddr", buf); 428 429 /* initialize omap tags */ 430 init_omap_tags(); 431 432 /* reuse atags from previous bootloader */ 433 reuse_atags(); 434 435 dieid_num_r(); 436 print_cpuinfo(); 437 438 /* 439 * Cortex-A8(r1p0..r1p2) errata 430973 workaround 440 * Set IBE bit in Auxiliary Control Register 441 */ 442 omap3_update_aux_cr_secure_rx51(1 << 6, 0); 443 444 return 0; 445 } 446 447 /* 448 * Routine: set_muxconf_regs 449 * Description: Setting up the configuration Mux registers specific to the 450 * hardware. Many pins need to be moved from protect to primary 451 * mode. 452 */ 453 void set_muxconf_regs(void) 454 { 455 MUX_RX51(); 456 } 457 458 static unsigned long int twl_wd_time; /* last time of watchdog reset */ 459 static unsigned long int twl_i2c_lock; 460 461 /* 462 * Routine: hw_watchdog_reset 463 * Description: Reset timeout of twl4030 watchdog. 464 */ 465 void hw_watchdog_reset(void) 466 { 467 u8 timeout = 0; 468 469 /* do not reset watchdog too often - max every 4s */ 470 if (get_timer(twl_wd_time) < 4 * CONFIG_SYS_HZ) 471 return; 472 473 /* localy lock twl4030 i2c bus */ 474 if (test_and_set_bit(0, &twl_i2c_lock)) 475 return; 476 477 /* read actual watchdog timeout */ 478 twl4030_i2c_read_u8(TWL4030_CHIP_PM_RECEIVER, &timeout, 479 TWL4030_PM_RECEIVER_WATCHDOG_CFG); 480 481 /* timeout 0 means watchdog is disabled */ 482 /* reset watchdog timeout to 31s (maximum) */ 483 if (timeout != 0) 484 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 31, 485 TWL4030_PM_RECEIVER_WATCHDOG_CFG); 486 487 /* store last watchdog reset time */ 488 twl_wd_time = get_timer(0); 489 490 /* localy unlock twl4030 i2c bus */ 491 test_and_clear_bit(0, &twl_i2c_lock); 492 } 493 494 /* 495 * TWL4030 keypad handler for cfb_console 496 */ 497 498 static const char keymap[] = { 499 /* normal */ 500 'q', 'o', 'p', ',', '\b', 0, 'a', 's', 501 'w', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 502 'e', '.', 0, '\r', 0, 'z', 'x', 'c', 503 'r', 'v', 'b', 'n', 'm', ' ', ' ', 0, 504 't', 0, 0, 0, 0, 0, 0, 0, 505 'y', 0, 0, 0, 0, 0, 0, 0, 506 'u', 0, 0, 0, 0, 0, 0, 0, 507 'i', 5, 6, 0, 0, 0, 0, 0, 508 /* fn */ 509 '1', '9', '0', '=', '\b', 0, '*', '+', 510 '2', '#', '-', '_', '(', ')', '&', '!', 511 '3', '?', '^', '\r', 0, 156, '$', 238, 512 '4', '/', '\\', '"', '\'', '@', 0, '<', 513 '5', '|', '>', 0, 0, 0, 0, 0, 514 '6', 0, 0, 0, 0, 0, 0, 0, 515 '7', 0, 0, 0, 0, 0, 0, 0, 516 '8', 16, 17, 0, 0, 0, 0, 0, 517 }; 518 519 static u8 keys[8]; 520 static u8 old_keys[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 521 #define KEYBUF_SIZE 32 522 static u8 keybuf[KEYBUF_SIZE]; 523 static u8 keybuf_head; 524 static u8 keybuf_tail; 525 526 /* 527 * Routine: rx51_kp_init 528 * Description: Initialize HW keyboard. 529 */ 530 int rx51_kp_init(void) 531 { 532 int ret = 0; 533 u8 ctrl; 534 ret = twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD, &ctrl, 535 TWL4030_KEYPAD_KEYP_CTRL_REG); 536 537 if (ret) 538 return ret; 539 540 /* turn on keyboard and use hardware scanning */ 541 ctrl |= TWL4030_KEYPAD_CTRL_KBD_ON; 542 ctrl |= TWL4030_KEYPAD_CTRL_SOFT_NRST; 543 ctrl |= TWL4030_KEYPAD_CTRL_SOFTMODEN; 544 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD, ctrl, 545 TWL4030_KEYPAD_KEYP_CTRL_REG); 546 /* enable key event status */ 547 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD, 0xfe, 548 TWL4030_KEYPAD_KEYP_IMR1); 549 /* enable interrupt generation on rising and falling */ 550 /* this is a workaround for qemu twl4030 emulation */ 551 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD, 0x57, 552 TWL4030_KEYPAD_KEYP_EDR); 553 /* enable ISR clear on read */ 554 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD, 0x05, 555 TWL4030_KEYPAD_KEYP_SIH_CTRL); 556 return 0; 557 } 558 559 static void rx51_kp_fill(u8 k, u8 mods) 560 { 561 /* check if some cursor key without meta fn key was pressed */ 562 if (!(mods & 2) && (k == 18 || k == 31 || k == 33 || k == 34)) { 563 keybuf[keybuf_tail++] = '\e'; 564 keybuf_tail %= KEYBUF_SIZE; 565 keybuf[keybuf_tail++] = '['; 566 keybuf_tail %= KEYBUF_SIZE; 567 if (k == 18) /* up */ 568 keybuf[keybuf_tail++] = 'A'; 569 else if (k == 31) /* left */ 570 keybuf[keybuf_tail++] = 'D'; 571 else if (k == 33) /* down */ 572 keybuf[keybuf_tail++] = 'B'; 573 else if (k == 34) /* right */ 574 keybuf[keybuf_tail++] = 'C'; 575 keybuf_tail %= KEYBUF_SIZE; 576 return; 577 } 578 579 if (mods & 2) { /* fn meta key was pressed */ 580 k = keymap[k+64]; 581 } else { 582 k = keymap[k]; 583 if (mods & 1) { /* ctrl key was pressed */ 584 if (k >= 'a' && k <= 'z') 585 k -= 'a' - 1; 586 } 587 if (mods & 4) { /* shift key was pressed */ 588 if (k >= 'a' && k <= 'z') 589 k += 'A' - 'a'; 590 else if (k == '.') 591 k = ':'; 592 else if (k == ',') 593 k = ';'; 594 } 595 } 596 keybuf[keybuf_tail++] = k; 597 keybuf_tail %= KEYBUF_SIZE; 598 } 599 600 /* 601 * Routine: rx51_kp_tstc 602 * Description: Test if key was pressed (from buffer). 603 */ 604 int rx51_kp_tstc(void) 605 { 606 u8 c, r, dk, i; 607 u8 intr; 608 u8 mods; 609 610 /* localy lock twl4030 i2c bus */ 611 if (test_and_set_bit(0, &twl_i2c_lock)) 612 return 0; 613 614 /* twl4030 remembers up to 2 events */ 615 for (i = 0; i < 2; i++) { 616 617 /* check interrupt register for events */ 618 twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD, &intr, 619 TWL4030_KEYPAD_KEYP_ISR1+(2*i)); 620 621 /* no event */ 622 if (!(intr&1)) 623 continue; 624 625 /* read the key state */ 626 i2c_read(TWL4030_CHIP_KEYPAD, 627 TWL4030_KEYPAD_FULL_CODE_7_0, 1, keys, 8); 628 629 /* cut out modifier keys from the keystate */ 630 mods = keys[4] >> 4; 631 keys[4] &= 0x0f; 632 633 for (c = 0; c < 8; c++) { 634 635 /* get newly pressed keys only */ 636 dk = ((keys[c] ^ old_keys[c])&keys[c]); 637 old_keys[c] = keys[c]; 638 639 /* fill the keybuf */ 640 for (r = 0; r < 8; r++) { 641 if (dk&1) 642 rx51_kp_fill((c*8)+r, mods); 643 dk = dk >> 1; 644 } 645 646 } 647 648 } 649 650 /* localy unlock twl4030 i2c bus */ 651 test_and_clear_bit(0, &twl_i2c_lock); 652 653 return (KEYBUF_SIZE + keybuf_tail - keybuf_head)%KEYBUF_SIZE; 654 } 655 656 /* 657 * Routine: rx51_kp_getc 658 * Description: Get last pressed key (from buffer). 659 */ 660 int rx51_kp_getc(void) 661 { 662 keybuf_head %= KEYBUF_SIZE; 663 while (!rx51_kp_tstc()) 664 WATCHDOG_RESET(); 665 return keybuf[keybuf_head++]; 666 } 667 668 /* 669 * Routine: board_mmc_init 670 * Description: Initialize mmc devices. 671 */ 672 int board_mmc_init(bd_t *bis) 673 { 674 omap_mmc_init(0, 0, 0, -1, -1); 675 omap_mmc_init(1, 0, 0, -1, -1); 676 return 0; 677 } 678