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