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