uboot/board/delta/delta.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2006
   3 * DENX Software Engineering
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <common.h>
  25#include <netdev.h>
  26#include <i2c.h>
  27#include <da9030.h>
  28#include <malloc.h>
  29#include <command.h>
  30#include <asm/arch/pxa-regs.h>
  31
  32DECLARE_GLOBAL_DATA_PTR;
  33
  34/* ------------------------------------------------------------------------- */
  35
  36static void init_DA9030(void);
  37static void keys_init(void);
  38static void get_pressed_keys(uchar *s);
  39static uchar *key_match(uchar *kbd_data);
  40
  41/*
  42 * Miscelaneous platform dependent initialisations
  43 */
  44
  45int board_init (void)
  46{
  47        /* memory and cpu-speed are setup before relocation */
  48        /* so we do _nothing_ here */
  49
  50        /* arch number of Lubbock-Board mk@tbd: fix this! */
  51        gd->bd->bi_arch_number = MACH_TYPE_LUBBOCK;
  52
  53        /* adress of boot parameters */
  54        gd->bd->bi_boot_params = 0xa0000100;
  55
  56        return 0;
  57}
  58
  59int board_late_init(void)
  60{
  61#ifdef DELTA_CHECK_KEYBD
  62        uchar kbd_data[KEYBD_DATALEN];
  63        char keybd_env[2 * KEYBD_DATALEN + 1];
  64        char *str;
  65        int i;
  66#endif /* DELTA_CHECK_KEYBD */
  67
  68        setenv("stdout", "serial");
  69        setenv("stderr", "serial");
  70
  71#ifdef DELTA_CHECK_KEYBD
  72        keys_init();
  73
  74        memset(kbd_data, '\0', KEYBD_DATALEN);
  75
  76        /* check for pressed keys and setup keybd_env */
  77        get_pressed_keys(kbd_data);
  78
  79        for (i = 0; i < KEYBD_DATALEN; ++i) {
  80                sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
  81        }
  82        setenv ("keybd", keybd_env);
  83
  84        str = strdup ((char *)key_match (kbd_data));    /* decode keys */
  85
  86# ifdef CONFIG_PREBOOT  /* automatically configure "preboot" command on key match */
  87        setenv ("preboot", str);        /* set or delete definition */
  88# endif /* CONFIG_PREBOOT */
  89        if (str != NULL) {
  90                free (str);
  91        }
  92#endif /* DELTA_CHECK_KEYBD */
  93
  94        init_DA9030();
  95        return 0;
  96}
  97
  98/*
  99 * Magic Key Handling, mainly copied from board/lwmon/lwmon.c
 100 */
 101#ifdef DELTA_CHECK_KEYBD
 102
 103static uchar kbd_magic_prefix[] = "key_magic";
 104static uchar kbd_command_prefix[] = "key_cmd";
 105
 106/*
 107 * Get pressed keys
 108 * s is a buffer of size KEYBD_DATALEN-1
 109 */
 110static void get_pressed_keys(uchar *s)
 111{
 112        unsigned long val;
 113        val = GPLR3;
 114
 115        if(val & (1<<31))
 116                *s++ = KEYBD_KP_DKIN0;
 117        if(val & (1<<18))
 118                *s++ = KEYBD_KP_DKIN1;
 119        if(val & (1<<29))
 120                *s++ = KEYBD_KP_DKIN2;
 121        if(val & (1<<22))
 122                *s++ = KEYBD_KP_DKIN5;
 123}
 124
 125static void keys_init()
 126{
 127        CKENB |= CKENB_7_GPIO;
 128        udelay(100);
 129
 130        /* Configure GPIOs */
 131        GPIO127 = 0xa840;       /* KP_DKIN0 */
 132        GPIO114 = 0xa840;       /* KP_DKIN1 */
 133        GPIO125 = 0xa840;       /* KP_DKIN2 */
 134        GPIO118 = 0xa840;       /* KP_DKIN5 */
 135
 136        /* Configure GPIOs as inputs */
 137        GPDR3 &= ~(1<<31 | 1<<18 | 1<<29 | 1<<22);
 138        GCDR3 = (1<<31 | 1<<18 | 1<<29 | 1<<22);
 139
 140        udelay(100);
 141}
 142
 143static int compare_magic (uchar *kbd_data, uchar *str)
 144{
 145        /* uchar compare[KEYBD_DATALEN-1]; */
 146        uchar compare[KEYBD_DATALEN];
 147        char *nxt;
 148        int i;
 149
 150        /* Don't include modifier byte */
 151        /* memcpy (compare, kbd_data+1, KEYBD_DATALEN-1); */
 152        memcpy (compare, kbd_data, KEYBD_DATALEN);
 153
 154        for (; str != NULL; str = (*nxt) ? (uchar *)(nxt+1) : (uchar *)nxt) {
 155                uchar c;
 156                int k;
 157
 158                c = (uchar) simple_strtoul ((char *)str, (char **) (&nxt), 16);
 159
 160                if (str == (uchar *)nxt) {      /* invalid character */
 161                        break;
 162                }
 163
 164                /*
 165                 * Check if this key matches the input.
 166                 * Set matches to zero, so they match only once
 167                 * and we can find duplicates or extra keys
 168                 */
 169                for (k = 0; k < sizeof(compare); ++k) {
 170                        if (compare[k] == '\0') /* only non-zero entries */
 171                                continue;
 172                        if (c == compare[k]) {  /* found matching key */
 173                                compare[k] = '\0';
 174                                break;
 175                        }
 176                }
 177                if (k == sizeof(compare)) {
 178                        return -1;              /* unmatched key */
 179                }
 180        }
 181
 182        /*
 183         * A full match leaves no keys in the `compare' array,
 184         */
 185        for (i = 0; i < sizeof(compare); ++i) {
 186                if (compare[i])
 187                {
 188                        return -1;
 189                }
 190        }
 191
 192        return 0;
 193}
 194
 195
 196static uchar *key_match (uchar *kbd_data)
 197{
 198        char magic[sizeof (kbd_magic_prefix) + 1];
 199        uchar *suffix;
 200        char *kbd_magic_keys;
 201
 202        /*
 203         * The following string defines the characters that can pe appended
 204         * to "key_magic" to form the names of environment variables that
 205         * hold "magic" key codes, i. e. such key codes that can cause
 206         * pre-boot actions. If the string is empty (""), then only
 207         * "key_magic" is checked (old behaviour); the string "125" causes
 208         * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
 209         */
 210        if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
 211                kbd_magic_keys = "";
 212
 213        /* loop over all magic keys;
 214         * use '\0' suffix in case of empty string
 215         */
 216        for (suffix=(uchar *)kbd_magic_keys; *suffix || suffix==(uchar *)kbd_magic_keys; ++suffix) {
 217                sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
 218#if 0
 219                printf ("### Check magic \"%s\"\n", magic);
 220#endif
 221                if (compare_magic(kbd_data, (uchar *)getenv(magic)) == 0) {
 222                        char cmd_name[sizeof (kbd_command_prefix) + 1];
 223                        char *cmd;
 224
 225                        sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
 226
 227                        cmd = getenv (cmd_name);
 228#if 0
 229                        printf ("### Set PREBOOT to $(%s): \"%s\"\n",
 230                                cmd_name, cmd ? cmd : "<<NULL>>");
 231#endif
 232                        *kbd_data = *suffix;
 233                        return ((uchar *)cmd);
 234                }
 235        }
 236#if 0
 237        printf ("### Delete PREBOOT\n");
 238#endif
 239        *kbd_data = '\0';
 240        return (NULL);
 241}
 242
 243int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 244{
 245        uchar kbd_data[KEYBD_DATALEN];
 246        char keybd_env[2 * KEYBD_DATALEN + 1];
 247        int i;
 248
 249        /* Read keys */
 250        get_pressed_keys(kbd_data);
 251        puts ("Keys:");
 252        for (i = 0; i < KEYBD_DATALEN; ++i) {
 253                sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
 254                printf (" %02x", kbd_data[i]);
 255        }
 256        putc ('\n');
 257        setenv ("keybd", keybd_env);
 258        return 0;
 259}
 260
 261U_BOOT_CMD(
 262           kbd, 1,      1,      do_kbd,
 263           "read keyboard status",
 264           ""
 265);
 266
 267#endif /* DELTA_CHECK_KEYBD */
 268
 269
 270int dram_init (void)
 271{
 272        gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
 273        gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
 274        gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
 275        gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
 276        gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
 277        gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
 278        gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
 279        gd->bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
 280
 281        return 0;
 282}
 283
 284void i2c_init_board()
 285{
 286        CKENB |= (CKENB_4_I2C);
 287
 288        /* setup I2C GPIO's */
 289        GPIO32 = 0x801;         /* SCL = Alt. Fkt. 1 */
 290        GPIO33 = 0x801;         /* SDA = Alt. Fkt. 1 */
 291}
 292
 293/* initialize the DA9030 Power Controller */
 294static void init_DA9030()
 295{
 296        uchar addr = (uchar) DA9030_I2C_ADDR, val = 0;
 297
 298        CKENB |= CKENB_7_GPIO;
 299        udelay(100);
 300
 301        /* Rising Edge on EXTON to reset DA9030 */
 302        GPIO17 = 0x8800;        /* configure GPIO17, no pullup, -down */
 303        GPDR0 |= (1<<17);       /* GPIO17 is output */
 304        GSDR0 = (1<<17);
 305        GPCR0 = (1<<17);        /* drive GPIO17 low */
 306        GPSR0 = (1<<17);        /* drive GPIO17 high */
 307
 308#if CONFIG_SYS_DA9030_EXTON_DELAY
 309        udelay((unsigned long) CONFIG_SYS_DA9030_EXTON_DELAY);  /* wait for DA9030 */
 310#endif
 311        GPCR0 = (1<<17);        /* drive GPIO17 low */
 312
 313        /* reset the watchdog and go active (0xec) */
 314        val = (SYS_CONTROL_A_HWRES_ENABLE |
 315               (0x6<<4) |
 316               SYS_CONTROL_A_WDOG_ACTION |
 317               SYS_CONTROL_A_WATCHDOG);
 318        if(i2c_write(addr, SYS_CONTROL_A, 1, &val, 1)) {
 319                printf("Error accessing DA9030 via i2c.\n");
 320                return;
 321        }
 322
 323        val = 0x80;
 324        if(i2c_write(addr, IRQ_MASK_B, 1, &val, 1)) {
 325                printf("Error accessing DA9030 via i2c.\n");
 326                return;
 327        }
 328
 329        i2c_reg_write(addr, REG_CONTROL_1_97, 0xfd); /* disable LDO1, enable LDO6 */
 330        i2c_reg_write(addr, LDO2_3, 0xd1);      /* LDO2 =1,9V, LDO3=3,1V */
 331        i2c_reg_write(addr, LDO4_5, 0xcc);      /* LDO2 =1,9V, LDO3=3,1V */
 332        i2c_reg_write(addr, LDO6_SIMCP, 0x3e);  /* LDO6=3,2V, SIMCP = 5V support */
 333        i2c_reg_write(addr, LDO7_8, 0xc9);      /* LDO7=2,7V, LDO8=3,0V */
 334        i2c_reg_write(addr, LDO9_12, 0xec);     /* LDO9=3,0V, LDO12=3,2V */
 335        i2c_reg_write(addr, BUCK, 0x0c);        /* Buck=1.2V */
 336        i2c_reg_write(addr, REG_CONTROL_2_98, 0x7f); /* All LDO'S on 8,9,10,11,12,14 */
 337        i2c_reg_write(addr, LDO_10_11, 0xcc);   /* LDO10=3.0V  LDO11=3.0V */
 338        i2c_reg_write(addr, LDO_15, 0xae);      /* LDO15=1.8V, dislock first 3bit */
 339        i2c_reg_write(addr, LDO_14_16, 0x05);   /* LDO14=2.8V, LDO16=NB */
 340        i2c_reg_write(addr, LDO_18_19, 0x9c);   /* LDO18=3.0V, LDO19=2.7V */
 341        i2c_reg_write(addr, LDO_17_SIMCP0, 0x2c); /* LDO17=3.0V, SIMCP=3V support */
 342        i2c_reg_write(addr, BUCK2_DVC1, 0x9a);  /* Buck2=1.5V plus Update support of 520 MHz */
 343        i2c_reg_write(addr, REG_CONTROL_2_18, 0x43); /* Ball on */
 344        i2c_reg_write(addr, MISC_CONTROLB, 0x08); /* session valid enable */
 345        i2c_reg_write(addr, USBPUMP, 0xc1);     /* start pump, ignore HW signals */
 346
 347        val = i2c_reg_read(addr, STATUS);
 348        if(val & STATUS_CHDET)
 349                printf("Charger detected, turning on LED.\n");
 350        else {
 351                printf("No charger detetected.\n");
 352                /* undervoltage? print error and power down */
 353        }
 354}
 355
 356
 357#if 0
 358/* reset the DA9030 watchdog */
 359void hw_watchdog_reset(void)
 360{
 361        uchar addr = (uchar) DA9030_I2C_ADDR, val = 0;
 362        val = i2c_reg_read(addr, SYS_CONTROL_A);
 363        val |= SYS_CONTROL_A_WATCHDOG;
 364        i2c_reg_write(addr, SYS_CONTROL_A, val);
 365}
 366#endif
 367
 368#ifdef CONFIG_CMD_NET
 369int board_eth_init(bd_t *bis)
 370{
 371        int rc = 0;
 372#ifdef CONFIG_SMC91111
 373        rc = smc91111_initialize(0, CONFIG_SMC91111_BASE);
 374#endif
 375        return rc;
 376}
 377#endif
 378