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