xref: /openbmc/u-boot/board/nokia/rx51/rx51.c (revision 9d86f0c3)
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 *)&params->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);
675 	omap_mmc_init(1, 0, 0);
676 	return 0;
677 }
678