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