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