uboot/board/tqc/tqm5200/cmd_stk52xx.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2005
   3 * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8/*
   9 * STK52XX specific functions
  10 */
  11/*#define DEBUG*/
  12
  13#include <common.h>
  14#include <command.h>
  15#include <console.h>
  16
  17#if defined(CONFIG_CMD_BSP)
  18
  19#if defined(CONFIG_STK52XX) || defined(CONFIG_FO300)
  20#define DEFAULT_VOL     45
  21#define DEFAULT_FREQ    500
  22#define DEFAULT_DURATION        200
  23#define LEFT            1
  24#define RIGHT           2
  25#define LEFT_RIGHT      3
  26#define BL_OFF          0
  27#define BL_ON           1
  28
  29#define SM501_GPIO_CTRL_LOW             0x00000008UL
  30#define SM501_GPIO_CTRL_HIGH            0x0000000CUL
  31#define SM501_POWER_MODE0_GATE          0x00000040UL
  32#define SM501_POWER_MODE1_GATE          0x00000048UL
  33#define POWER_MODE_GATE_GPIO_PWM_I2C    0x00000040UL
  34#define SM501_GPIO_DATA_LOW             0x00010000UL
  35#define SM501_GPIO_DATA_HIGH            0x00010004UL
  36#define SM501_GPIO_DATA_DIR_LOW         0x00010008UL
  37#define SM501_GPIO_DATA_DIR_HIGH        0x0001000CUL
  38#define SM501_PANEL_DISPLAY_CONTROL     0x00080000UL
  39
  40static int i2s_squarewave(unsigned long duration, unsigned int freq,
  41                          unsigned int channel);
  42static int i2s_sawtooth(unsigned long duration, unsigned int freq,
  43                        unsigned int channel);
  44static void spi_init(void);
  45static int spi_transmit(unsigned char data);
  46static void pcm1772_write_reg(unsigned char addr, unsigned char data);
  47static void set_attenuation(unsigned char attenuation);
  48
  49static void spi_init(void)
  50{
  51        struct mpc5xxx_spi *spi = (struct mpc5xxx_spi*)MPC5XXX_SPI;
  52        struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio*)MPC5XXX_GPIO;
  53
  54        /* PSC3 as SPI and GPIOs */
  55        gpio->port_config &= 0xFFFFF0FF;
  56        gpio->port_config |= 0x00000800;
  57        /*
  58         * Its important to use the correct order when initializing the
  59         * registers
  60         */
  61        spi->ddr = 0x0F; /* set all SPI pins as output */
  62        spi->pdr = 0x08; /* set SS high */
  63        spi->cr1 = 0x50; /* SPI is master, SS is general purpose output */
  64        spi->cr2 = 0x00; /* normal operation */
  65        spi->brr = 0xFF; /* baud rate: IPB clock / 2048 */
  66}
  67
  68static int spi_transmit(unsigned char data)
  69{
  70        struct mpc5xxx_spi *spi = (struct mpc5xxx_spi*)MPC5XXX_SPI;
  71
  72        spi->dr = data;
  73        /* wait for SPI transmission completed */
  74        while (!(spi->sr & 0x80)) {
  75                if (spi->sr & 0x40) {   /* if write collision occurred */
  76                        int dummy;
  77
  78                        /* do dummy read to clear status register */
  79                        dummy = spi->dr;
  80                        printf("SPI write collision: dr=0x%x\n", dummy);
  81                        return -1;
  82                }
  83        }
  84        return (spi->dr);
  85}
  86
  87static void pcm1772_write_reg(unsigned char addr, unsigned char data)
  88{
  89        struct mpc5xxx_spi *spi = (struct mpc5xxx_spi*)MPC5XXX_SPI;
  90
  91        spi->pdr = 0x00; /* Set SS low */
  92        spi_transmit(addr);
  93        spi_transmit(data);
  94        /* wait some time to meet MS# hold time of PCM1772 */
  95        udelay (1);
  96        spi->pdr = 0x08; /* set SS high */
  97}
  98
  99static void set_attenuation(unsigned char attenuation)
 100{
 101        pcm1772_write_reg(0x01, attenuation); /* left channel */
 102        debug ("PCM1772 attenuation left set to %d.\n", attenuation);
 103        pcm1772_write_reg(0x02, attenuation); /* right channel */
 104        debug ("PCM1772 attenuation right set to %d.\n", attenuation);
 105}
 106
 107void amplifier_init(void)
 108{
 109        static int init_done = 0;
 110        int i;
 111        struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio*)MPC5XXX_GPIO;
 112
 113        /* Do this only once, because of the long time delay */
 114        if (!init_done) {
 115                /* configure PCM1772 audio format as I2S */
 116                pcm1772_write_reg(0x03, 0x01);
 117                /* enable audio amplifier */
 118                gpio->sint_gpioe |=  0x02;      /* PSC3_5 as GPIO */
 119                gpio->sint_ode &= ~0x02;        /* PSC3_5 is not open Drain */
 120                gpio->sint_dvo &= ~0x02;        /* PSC3_5 is LOW */
 121                gpio->sint_ddr |=  0x02;        /* PSC3_5 as output */
 122                /*
 123                 * wait some time to allow amplifier to recover from shutdown
 124                 * mode.
 125                 */
 126                for(i = 0; i < 350; i++)
 127                        udelay(1000);
 128                /*
 129                 * The used amplifier (LM4867) has a so called "pop and click"
 130                 * elmination filter. The input signal of the amplifier must
 131                 * exceed a certain level once after power up to activate the
 132                 * generation of the output signal. This is achieved by
 133                 * sending a low frequent (nearly inaudible) sawtooth with a
 134                 * sufficient signal level.
 135                 */
 136                set_attenuation(50);
 137                i2s_sawtooth (200, 5, LEFT_RIGHT);
 138                init_done = 1;
 139        }
 140}
 141
 142static void i2s_init(void)
 143{
 144        unsigned long i;
 145        struct mpc5xxx_psc *psc = (struct mpc5xxx_psc*)MPC5XXX_PSC2;;
 146        struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio*)MPC5XXX_GPIO;
 147
 148        gpio->port_config |= 0x00000070; /* PSC2 ports as Codec with MCLK */
 149        psc->command = (PSC_RX_DISABLE | PSC_TX_DISABLE);
 150        psc->sicr = 0x22E00000;         /* 16 bit data; I2S */
 151
 152        *(vu_long *)(CONFIG_SYS_MBAR + 0x22C) = 0x805d; /* PSC2 CDM MCLK config; MCLK
 153                                                  * 5.617 MHz */
 154        *(vu_long *)(CONFIG_SYS_MBAR + 0x214) |= 0x00000040; /* CDM clock enable
 155                                                       * register */
 156        psc->ccr = 0x1F03;      /* 16 bit data width; 5.617MHz MCLK */
 157        psc->ctur = 0x0F;       /* 16 bit frame width */
 158
 159        for (i = 0; i < 128; i++)
 160                psc->psc_buffer_32 = 0; /* clear tx fifo */
 161}
 162
 163static int i2s_play_wave(unsigned long addr, unsigned long len)
 164{
 165        unsigned long i;
 166        unsigned char *wave_file = (uchar *)addr + 44;  /* quick'n dirty: skip
 167                                                         * wav header*/
 168        struct mpc5xxx_psc *psc = (struct mpc5xxx_psc*)MPC5XXX_PSC2;
 169
 170        /*
 171         * play wave file in memory; bytes/words are be swapped
 172         */
 173        psc->command = (PSC_RX_ENABLE | PSC_TX_ENABLE);
 174
 175        for(i = 0;i < (len / 4); i++) {
 176                unsigned char swapped[4];
 177                unsigned long *p = (unsigned long*)swapped;
 178
 179                swapped[3] = *wave_file++;
 180                swapped[2] = *wave_file++;
 181                swapped[1] = *wave_file++;
 182                swapped[0] = *wave_file++;
 183
 184                psc->psc_buffer_32 =  *p;
 185
 186                while (psc->tfnum > 400) {
 187                        if(ctrlc())
 188                                return 0;
 189                }
 190        }
 191        while (psc->tfnum > 0);         /* wait for fifo empty */
 192        udelay (100);
 193        psc->command = (PSC_RX_DISABLE | PSC_TX_DISABLE);
 194        return 0;
 195}
 196
 197static int i2s_sawtooth(unsigned long duration, unsigned int freq,
 198                        unsigned int channel)
 199{
 200        long i,j;
 201        unsigned long data;
 202        struct mpc5xxx_psc *psc = (struct mpc5xxx_psc*)MPC5XXX_PSC2;
 203
 204        psc->command = (PSC_RX_ENABLE | PSC_TX_ENABLE);
 205
 206        /*
 207         * Generate sawtooth. Start with middle level up to highest level. Then
 208         * go to lowest level and back to middle level.
 209         */
 210        for(j = 0; j < ((duration * freq) / 1000); j++) {
 211                for(i = 0; i <= 0x7FFF; i += (0x7FFF/(44100/(freq*4)))) {
 212                        data = (i & 0xFFFF);
 213                        /* data format: right data left data) */
 214                        if (channel == LEFT_RIGHT)
 215                                data |= (data<<16);
 216                        if (channel == RIGHT)
 217                                data = (data<<16);
 218                        psc->psc_buffer_32 = data;
 219                        while (psc->tfnum > 400);
 220                }
 221                for(i = 0x7FFF; i >= -0x7FFF; i -= (0xFFFF/(44100/(freq*2)))) {
 222                        data = (i & 0xFFFF);
 223                        /* data format: right data left data) */
 224                        if (channel == LEFT_RIGHT)
 225                                data |= (data<<16);
 226                        if (channel == RIGHT)
 227                                data = (data<<16);
 228                        psc->psc_buffer_32 = data;
 229                        while (psc->tfnum > 400);
 230                }
 231                for(i = -0x7FFF; i <= 0; i += (0x7FFF/(44100/(freq*4)))) {
 232                        data = (i & 0xFFFF);
 233                        /* data format: right data left data) */
 234                        if (channel == LEFT_RIGHT)
 235                                data |= (data<<16);
 236                        if (channel == RIGHT)
 237                                data = (data<<16);
 238                        psc->psc_buffer_32 = data;
 239                        while (psc->tfnum > 400);
 240                }
 241        }
 242        while (psc->tfnum > 0);         /* wait for fifo empty */
 243        udelay (100);
 244        psc->command = (PSC_RX_DISABLE | PSC_TX_DISABLE);
 245
 246        return 0;
 247}
 248
 249static int i2s_squarewave(unsigned long duration, unsigned int freq,
 250                         unsigned int channel)
 251{
 252        long i,j;
 253        unsigned long data;
 254        struct mpc5xxx_psc *psc = (struct mpc5xxx_psc*)MPC5XXX_PSC2;
 255
 256        psc->command = (PSC_RX_ENABLE | PSC_TX_ENABLE);
 257
 258        /*
 259         * Generate sqarewave. Start with high level, duty cycle 1:1.
 260         */
 261        for(j = 0; j < ((duration * freq) / 1000); j++) {
 262                for(i = 0; i < (44100/(freq*2)); i ++) {
 263                        data = 0x7FFF;
 264                        /* data format: right data left data) */
 265                        if (channel == LEFT_RIGHT)
 266                                data |= (data<<16);
 267                        if (channel == RIGHT)
 268                                data = (data<<16);
 269                        psc->psc_buffer_32 = data;
 270                        while (psc->tfnum > 400);
 271                }
 272                for(i = 0; i < (44100/(freq*2)); i ++) {
 273                        data = 0x8000;
 274                        /* data format: right data left data) */
 275                        if (channel == LEFT_RIGHT)
 276                                data |= (data<<16);
 277                        if (channel == RIGHT)
 278                                data = (data<<16);
 279                        psc->psc_buffer_32 = data;
 280                        while (psc->tfnum > 400);
 281                }
 282        }
 283        while (psc->tfnum > 0);         /* wait for fifo empty */
 284        udelay (100);
 285        psc->command = (PSC_RX_DISABLE | PSC_TX_DISABLE);
 286
 287        return 0;
 288}
 289
 290static int cmd_sound(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 291{
 292        unsigned long reg, val, duration;
 293        char *tmp;
 294        unsigned int freq, channel;
 295        unsigned char volume;
 296        int rcode = 1;
 297
 298#ifdef CONFIG_STK52XX_REV100
 299        printf ("Revision 100 of STK52XX not supported!\n");
 300        return 1;
 301#endif
 302        spi_init();
 303        i2s_init();
 304        amplifier_init();
 305
 306        if ((tmp = getenv ("volume")) != NULL) {
 307                volume = simple_strtoul (tmp, NULL, 10);
 308        } else {
 309                volume = DEFAULT_VOL;
 310        }
 311        set_attenuation(volume);
 312
 313        switch (argc) {
 314        case 0:
 315        case 1:
 316                return cmd_usage(cmdtp);
 317        case 2:
 318                if (strncmp(argv[1],"saw",3) == 0) {
 319                        printf ("Play sawtooth\n");
 320                        rcode = i2s_sawtooth (DEFAULT_DURATION, DEFAULT_FREQ,
 321                                              LEFT_RIGHT);
 322                        return rcode;
 323                } else if (strncmp(argv[1],"squ",3) == 0) {
 324                        printf ("Play squarewave\n");
 325                        rcode = i2s_squarewave (DEFAULT_DURATION, DEFAULT_FREQ,
 326                                                LEFT_RIGHT);
 327                        return rcode;
 328                }
 329
 330                return cmd_usage(cmdtp);
 331        case 3:
 332                if (strncmp(argv[1],"saw",3) == 0) {
 333                        duration = simple_strtoul(argv[2], NULL, 10);
 334                        printf ("Play sawtooth\n");
 335                        rcode = i2s_sawtooth (duration, DEFAULT_FREQ,
 336                                              LEFT_RIGHT);
 337                        return rcode;
 338                } else if (strncmp(argv[1],"squ",3) == 0) {
 339                        duration = simple_strtoul(argv[2], NULL, 10);
 340                        printf ("Play squarewave\n");
 341                        rcode = i2s_squarewave (duration, DEFAULT_FREQ,
 342                                                LEFT_RIGHT);
 343                        return rcode;
 344                }
 345                return cmd_usage(cmdtp);
 346        case 4:
 347                if (strncmp(argv[1],"saw",3) == 0) {
 348                        duration = simple_strtoul(argv[2], NULL, 10);
 349                        freq = (unsigned int)simple_strtoul(argv[3], NULL, 10);
 350                        printf ("Play sawtooth\n");
 351                        rcode = i2s_sawtooth (duration, freq,
 352                                              LEFT_RIGHT);
 353                        return rcode;
 354                } else if (strncmp(argv[1],"squ",3) == 0) {
 355                        duration = simple_strtoul(argv[2], NULL, 10);
 356                        freq = (unsigned int)simple_strtoul(argv[3], NULL, 10);
 357                        printf ("Play squarewave\n");
 358                        rcode = i2s_squarewave (duration, freq,
 359                                                LEFT_RIGHT);
 360                        return rcode;
 361                } else if (strcmp(argv[1],"pcm1772") == 0) {
 362                        reg = simple_strtoul(argv[2], NULL, 10);
 363                        val = simple_strtoul(argv[3], NULL, 10);
 364                        printf("Set PCM1772 %lu. %lu\n", reg, val);
 365                        pcm1772_write_reg((uchar)reg, (uchar)val);
 366                        return 0;
 367                }
 368                return cmd_usage(cmdtp);
 369        case 5:
 370                if (strncmp(argv[1],"saw",3) == 0) {
 371                        duration = simple_strtoul(argv[2], NULL, 10);
 372                        freq = (unsigned int)simple_strtoul(argv[3], NULL, 10);
 373                        if (strncmp(argv[4],"l",1) == 0)
 374                                channel = LEFT;
 375                        else if (strncmp(argv[4],"r",1) == 0)
 376                                channel = RIGHT;
 377                        else
 378                                channel = LEFT_RIGHT;
 379                        printf ("Play squarewave\n");
 380                        rcode = i2s_sawtooth (duration, freq,
 381                                              channel);
 382                        return rcode;
 383                } else if (strncmp(argv[1],"squ",3) == 0) {
 384                        duration = simple_strtoul(argv[2], NULL, 10);
 385                        freq = (unsigned int)simple_strtoul(argv[3], NULL, 10);
 386                        if (strncmp(argv[4],"l",1) == 0)
 387                                channel = LEFT;
 388                        else if (strncmp(argv[4],"r",1) == 0)
 389                                channel = RIGHT;
 390                        else
 391                                channel = LEFT_RIGHT;
 392                        printf ("Play squarewave\n");
 393                        rcode = i2s_squarewave (duration, freq,
 394                                                channel);
 395                        return rcode;
 396                }
 397                return cmd_usage(cmdtp);
 398        }
 399        printf ("Usage:\nsound cmd [arg1] [arg2] ...\n");
 400        return 1;
 401}
 402
 403static int cmd_wav(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 404{
 405        unsigned long length, addr;
 406        unsigned char volume;
 407        int rcode = 1;
 408        char *tmp;
 409
 410#ifdef CONFIG_STK52XX_REV100
 411        printf ("Revision 100 of STK52XX not supported!\n");
 412        return 1;
 413#endif
 414        spi_init();
 415        i2s_init();
 416        amplifier_init();
 417
 418        switch (argc) {
 419
 420        case 3:
 421                length = simple_strtoul(argv[2], NULL, 16);
 422                addr = simple_strtoul(argv[1], NULL, 16);
 423                break;
 424
 425        case 2:
 426                if ((tmp = getenv ("filesize")) != NULL) {
 427                        length = simple_strtoul (tmp, NULL, 16);
 428                } else {
 429                        puts ("No filesize provided\n");
 430                        return 1;
 431                }
 432                addr = simple_strtoul(argv[1], NULL, 16);
 433
 434        case 1:
 435                if ((tmp = getenv ("filesize")) != NULL) {
 436                        length = simple_strtoul (tmp, NULL, 16);
 437                } else {
 438                        puts ("No filesize provided\n");
 439                        return 1;
 440                }
 441                if ((tmp = getenv ("loadaddr")) != NULL) {
 442                        addr = simple_strtoul (tmp, NULL, 16);
 443                } else {
 444                        puts ("No loadaddr provided\n");
 445                        return 1;
 446                }
 447                break;
 448
 449        default:
 450                printf("Usage:\nwav <addr> <length[s]\n");
 451                return 1;
 452                break;
 453        }
 454
 455        if ((tmp = getenv ("volume")) != NULL) {
 456                volume = simple_strtoul (tmp, NULL, 10);
 457        } else {
 458                volume = DEFAULT_VOL;
 459        }
 460        set_attenuation(volume);
 461
 462        printf("Play wave file at %lX with length %lX\n", addr, length);
 463        rcode = i2s_play_wave(addr, length);
 464
 465        return rcode;
 466}
 467
 468static int cmd_beep(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 469{
 470        unsigned char volume;
 471        unsigned int channel;
 472        int rcode;
 473        char *tmp;
 474
 475#ifdef CONFIG_STK52XX_REV100
 476        printf ("Revision 100 of STK52XX not supported!\n");
 477        return 1;
 478#endif
 479        spi_init();
 480        i2s_init();
 481        amplifier_init();
 482
 483        switch (argc) {
 484        case 0:
 485        case 1:
 486                channel = LEFT_RIGHT;
 487                break;
 488        case 2:
 489                if (strncmp(argv[1],"l",1) == 0)
 490                        channel = LEFT;
 491                else if (strncmp(argv[1],"r",1) == 0)
 492                        channel = RIGHT;
 493                else
 494                        channel = LEFT_RIGHT;
 495                break;
 496        default:
 497                return cmd_usage(cmdtp);
 498        }
 499
 500        if ((tmp = getenv ("volume")) != NULL) {
 501                volume = simple_strtoul (tmp, NULL, 10);
 502        } else {
 503                volume = DEFAULT_VOL;
 504        }
 505        set_attenuation(volume);
 506
 507        printf("Beep on ");
 508        if (channel == LEFT)
 509                printf ("left ");
 510        else if (channel == RIGHT)
 511                printf ("right ");
 512        else
 513                printf ("left and right ");
 514        printf ("channel\n");
 515
 516        rcode = i2s_squarewave (DEFAULT_DURATION, DEFAULT_FREQ, channel);
 517
 518        return rcode;
 519}
 520#endif
 521
 522#if defined(CONFIG_STK52XX)
 523void led_init(void)
 524{
 525        struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio *)MPC5XXX_GPIO;
 526        struct mpc5xxx_gpt_0_7 *gpt = (struct mpc5xxx_gpt_0_7 *)MPC5XXX_GPT;
 527
 528        /* configure PSC3 for SPI and GPIO */
 529        gpio->port_config &= ~(0x00000F00);
 530        gpio->port_config |=   0x00000800;
 531
 532        gpio->simple_gpioe &= ~(0x00000F00);
 533        gpio->simple_gpioe |=   0x00000F00;
 534
 535        gpio->simple_ddr &= ~(0x00000F00);
 536        gpio->simple_ddr |=   0x00000F00;
 537
 538        /* configure timer 4-7 for simple GPIO output */
 539        gpt->gpt4.emsr |=  0x00000024;
 540        gpt->gpt5.emsr |=  0x00000024;
 541        gpt->gpt6.emsr |=  0x00000024;
 542        gpt->gpt7.emsr |=  0x00000024;
 543
 544#ifndef CONFIG_TQM5200S
 545        /* enable SM501 GPIO control (in both power modes) */
 546        *(vu_long *) (SM501_MMIO_BASE+SM501_POWER_MODE0_GATE) |=
 547                POWER_MODE_GATE_GPIO_PWM_I2C;
 548        *(vu_long *) (SM501_MMIO_BASE+SM501_POWER_MODE1_GATE) |=
 549                POWER_MODE_GATE_GPIO_PWM_I2C;
 550
 551        /* configure SM501 gpio pins 24-27 as output */
 552        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_CTRL_LOW) &= ~(0xF << 24);
 553        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_DIR_LOW) |= (0xF << 24);
 554
 555        /* configure SM501 gpio pins 48-51 as output */
 556        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_DIR_HIGH) |= (0xF << 16);
 557#endif /* !CONFIG_TQM5200S */
 558}
 559
 560/*
 561 * return 1 if led number unknown
 562 * return 0 else
 563 */
 564int do_led(char * const argv[])
 565{
 566        struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio *)MPC5XXX_GPIO;
 567        struct mpc5xxx_gpt_0_7 *gpt = (struct mpc5xxx_gpt_0_7 *)MPC5XXX_GPT;
 568
 569        switch  (simple_strtoul(argv[2], NULL, 10)) {
 570
 571        case 0:
 572                if (strcmp (argv[3], "on") == 0) {
 573                        gpio->simple_dvo |=   (1 << 8);
 574                } else {
 575                        gpio->simple_dvo &= ~(1 << 8);
 576                }
 577                break;
 578
 579        case 1:
 580                if (strcmp (argv[3], "on") == 0) {
 581                        gpio->simple_dvo |=   (1 << 9);
 582                } else {
 583                        gpio->simple_dvo &= ~(1 << 9);
 584                }
 585                break;
 586
 587        case 2:
 588                if (strcmp (argv[3], "on") == 0) {
 589                        gpio->simple_dvo |=   (1 << 10);
 590                } else {
 591                        gpio->simple_dvo &= ~(1 << 10);
 592                }
 593                break;
 594
 595        case 3:
 596                if (strcmp (argv[3], "on") == 0) {
 597                        gpio->simple_dvo |=   (1 << 11);
 598                } else {
 599                        gpio->simple_dvo &= ~(1 << 11);
 600                }
 601                break;
 602
 603        case 4:
 604                if (strcmp (argv[3], "on") == 0) {
 605                        gpt->gpt4.emsr |=  (1 << 4);
 606                } else {
 607                        gpt->gpt4.emsr &=  ~(1 << 4);
 608                }
 609                break;
 610
 611        case 5:
 612                if (strcmp (argv[3], "on") == 0) {
 613                        gpt->gpt5.emsr |=  (1 << 4);
 614                } else {
 615                        gpt->gpt5.emsr &=  ~(1 << 4);
 616                }
 617                break;
 618
 619        case 6:
 620                if (strcmp (argv[3], "on") == 0) {
 621                        gpt->gpt6.emsr |=  (1 << 4);
 622                } else {
 623                        gpt->gpt6.emsr &=  ~(1 << 4);
 624                }
 625                break;
 626
 627        case 7:
 628                if (strcmp (argv[3], "on") == 0) {
 629                        gpt->gpt7.emsr |=  (1 << 4);
 630                } else {
 631                        gpt->gpt7.emsr &=  ~(1 << 4);
 632                }
 633                break;
 634#ifndef CONFIG_TQM5200S
 635        case 24:
 636                if (strcmp (argv[3], "on") == 0) {
 637                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_LOW) |=
 638                                (0x1 << 24);
 639                } else {
 640                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_LOW) &=
 641                                ~(0x1 << 24);
 642                }
 643                break;
 644
 645        case 25:
 646                if (strcmp (argv[3], "on") == 0) {
 647                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_LOW) |=
 648                                (0x1 << 25);
 649                } else {
 650                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_LOW) &=
 651                                ~(0x1 << 25);
 652                }
 653                break;
 654
 655        case 26:
 656                if (strcmp (argv[3], "on") == 0) {
 657                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_LOW) |=
 658                                (0x1 << 26);
 659                } else {
 660                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_LOW) &=
 661                                ~(0x1 << 26);
 662                }
 663                break;
 664
 665        case 27:
 666                if (strcmp (argv[3], "on") == 0) {
 667                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_LOW) |=
 668                                (0x1 << 27);
 669                } else {
 670                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_LOW) &=
 671                                ~(0x1 << 27);
 672                }
 673                break;
 674
 675        case 48:
 676                if (strcmp (argv[3], "on") == 0) {
 677                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) |=
 678                                (0x1 << 16);
 679                } else {
 680                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) &=
 681                                ~(0x1 << 16);
 682                }
 683                break;
 684
 685        case 49:
 686                if (strcmp (argv[3], "on") == 0) {
 687                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) |=
 688                                (0x1 << 17);
 689                } else {
 690                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) &=
 691                                ~(0x1 << 17);
 692                }
 693                break;
 694
 695        case 50:
 696                if (strcmp (argv[3], "on") == 0) {
 697                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) |=
 698                                (0x1 << 18);
 699                } else {
 700                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) &=
 701                                ~(0x1 << 18);
 702                }
 703                break;
 704
 705        case 51:
 706                if (strcmp (argv[3], "on") == 0) {
 707                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) |=
 708                                (0x1 << 19);
 709                } else {
 710                        *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) &=
 711                                ~(0x1 << 19);
 712                }
 713                break;
 714#endif /* !CONFIG_TQM5200S */
 715        default:
 716                printf ("%s: invalid led number %s\n", __FUNCTION__, argv[2]);
 717                return 1;
 718        }
 719
 720        return 0;
 721}
 722#endif
 723
 724#if defined(CONFIG_STK52XX) || defined(CONFIG_FO300)
 725/*
 726 * return 1 on CAN initialization failure
 727 * return 0 if no failure
 728 */
 729int can_init(void)
 730{
 731        static int init_done = 0;
 732        int i;
 733        struct mpc5xxx_mscan *can1 =
 734                (struct mpc5xxx_mscan *)(CONFIG_SYS_MBAR + 0x0900);
 735        struct mpc5xxx_mscan *can2 =
 736                (struct mpc5xxx_mscan *)(CONFIG_SYS_MBAR + 0x0980);
 737
 738        /* GPIO configuration of the CAN pins is done in TQM5200.h */
 739
 740        if (!init_done) {
 741                /* init CAN 1 */
 742                can1->canctl1 |= 0x80;  /* CAN enable */
 743                udelay(100);
 744
 745                i = 0;
 746                can1->canctl0 |= 0x02;  /* sleep mode */
 747                /* wait until sleep mode reached */
 748                while (!(can1->canctl1 & 0x02)) {
 749                        udelay(10);
 750                i++;
 751                if (i == 10) {
 752                        printf ("%s: CAN1 initialize error, "
 753                                "can not enter sleep mode!\n",
 754                                __FUNCTION__);
 755                        return 1;
 756                }
 757                }
 758                i = 0;
 759                can1->canctl0 = 0x01;   /* enter init mode */
 760                /* wait until init mode reached */
 761                while (!(can1->canctl1 & 0x01)) {
 762                        udelay(10);
 763                        i++;
 764                        if (i == 10) {
 765                                printf ("%s: CAN1 initialize error, "
 766                                        "can not enter init mode!\n",
 767                                        __FUNCTION__);
 768                                return 1;
 769                        }
 770                }
 771                can1->canctl1 = 0x80;
 772                can1->canctl1 |= 0x40;
 773                can1->canbtr0 = 0x0F;
 774                can1->canbtr1 = 0x7F;
 775                can1->canidac &= ~(0x30);
 776                can1->canidar1 = 0x00;
 777                can1->canidar3 = 0x00;
 778                can1->canidar5 = 0x00;
 779                can1->canidar7 = 0x00;
 780                can1->canidmr0 = 0xFF;
 781                can1->canidmr1 = 0xFF;
 782                can1->canidmr2 = 0xFF;
 783                can1->canidmr3 = 0xFF;
 784                can1->canidmr4 = 0xFF;
 785                can1->canidmr5 = 0xFF;
 786                can1->canidmr6 = 0xFF;
 787                can1->canidmr7 = 0xFF;
 788
 789                i = 0;
 790                can1->canctl0 &= ~(0x01);       /* leave init mode */
 791                can1->canctl0 &= ~(0x02);
 792                /* wait until init and sleep mode left */
 793                while ((can1->canctl1 & 0x01) || (can1->canctl1 & 0x02)) {
 794                        udelay(10);
 795                        i++;
 796                        if (i == 10) {
 797                                printf ("%s: CAN1 initialize error, "
 798                                        "can not leave init/sleep mode!\n",
 799                                        __FUNCTION__);
 800                                return 1;
 801                        }
 802                }
 803
 804                /* init CAN 2 */
 805                can2->canctl1 |= 0x80;  /* CAN enable */
 806                udelay(100);
 807
 808                i = 0;
 809                can2->canctl0 |= 0x02;  /* sleep mode */
 810                /* wait until sleep mode reached */
 811                while (!(can2->canctl1 & 0x02)) {
 812                        udelay(10);
 813                        i++;
 814                        if (i == 10) {
 815                                printf ("%s: CAN2 initialize error, "
 816                                        "can not enter sleep mode!\n",
 817                                        __FUNCTION__);
 818                                return 1;
 819                        }
 820                }
 821                i = 0;
 822                can2->canctl0 = 0x01;   /* enter init mode */
 823                /* wait until init mode reached */
 824                while (!(can2->canctl1 & 0x01)) {
 825                        udelay(10);
 826                        i++;
 827                        if (i == 10) {
 828                                printf ("%s: CAN2 initialize error, "
 829                                        "can not enter init mode!\n",
 830                                        __FUNCTION__);
 831                                return 1;
 832                        }
 833                }
 834                can2->canctl1 = 0x80;
 835                can2->canctl1 |= 0x40;
 836                can2->canbtr0 = 0x0F;
 837                can2->canbtr1 = 0x7F;
 838                can2->canidac &= ~(0x30);
 839                can2->canidar1 = 0x00;
 840                can2->canidar3 = 0x00;
 841                can2->canidar5 = 0x00;
 842                can2->canidar7 = 0x00;
 843                can2->canidmr0 = 0xFF;
 844                can2->canidmr1 = 0xFF;
 845                can2->canidmr2 = 0xFF;
 846                can2->canidmr3 = 0xFF;
 847                can2->canidmr4 = 0xFF;
 848                can2->canidmr5 = 0xFF;
 849                can2->canidmr6 = 0xFF;
 850                can2->canidmr7 = 0xFF;
 851                can2->canctl0 &= ~(0x01);       /* leave init mode */
 852                can2->canctl0 &= ~(0x02);
 853
 854                i = 0;
 855                /* wait until init mode left */
 856                while ((can2->canctl1 & 0x01) || (can2->canctl1 & 0x02)) {
 857                        udelay(10);
 858                        i++;
 859                        if (i == 10) {
 860                                printf ("%s: CAN2 initialize error, "
 861                                        "can not leave init/sleep mode!\n",
 862                                        __FUNCTION__);
 863                                return 1;
 864                        }
 865                }
 866                init_done = 1;
 867        }
 868        return 0;
 869}
 870
 871/*
 872 * return 1 on CAN failure
 873 * return 0 if no failure
 874 */
 875int do_can(char * const argv[])
 876{
 877        int i;
 878        struct mpc5xxx_mscan *can1 =
 879                (struct mpc5xxx_mscan *)(CONFIG_SYS_MBAR + 0x0900);
 880        struct mpc5xxx_mscan *can2 =
 881                (struct mpc5xxx_mscan *)(CONFIG_SYS_MBAR + 0x0980);
 882
 883        /* send a message on CAN1 */
 884        can1->cantbsel = 0x01;
 885        can1->cantxfg.idr[0] = 0x55;
 886        can1->cantxfg.idr[1] = 0x00;
 887        can1->cantxfg.idr[1] &= ~0x8;
 888        can1->cantxfg.idr[1] &= ~0x10;
 889        can1->cantxfg.dsr[0] = 0xCC;
 890        can1->cantxfg.dlr = 1;
 891        can1->cantxfg.tbpr = 0;
 892        can1->cantflg = 0x01;
 893
 894        i = 0;
 895        while ((can1->cantflg & 0x01) == 0) {
 896                i++;
 897                if (i == 10) {
 898                        printf ("%s: CAN1 send timeout, "
 899                                "can not send message!\n",
 900                                __FUNCTION__);
 901                        return 1;
 902                }
 903                udelay(1000);
 904        }
 905        udelay(1000);
 906
 907        i = 0;
 908        while (!(can2->canrflg & 0x01)) {
 909                i++;
 910                if (i == 10) {
 911                        printf ("%s: CAN2 receive timeout, "
 912                                "no message received!\n",
 913                                __FUNCTION__);
 914                        return 1;
 915                }
 916                udelay(1000);
 917        }
 918
 919        if (can2->canrxfg.dsr[0] != 0xCC) {
 920                printf ("%s: CAN2 receive error, "
 921                         "data mismatch!\n",
 922                        __FUNCTION__);
 923                return 1;
 924        }
 925
 926        /* send a message on CAN2 */
 927        can2->cantbsel = 0x01;
 928        can2->cantxfg.idr[0] = 0x55;
 929        can2->cantxfg.idr[1] = 0x00;
 930        can2->cantxfg.idr[1] &= ~0x8;
 931        can2->cantxfg.idr[1] &= ~0x10;
 932        can2->cantxfg.dsr[0] = 0xCC;
 933        can2->cantxfg.dlr = 1;
 934        can2->cantxfg.tbpr = 0;
 935        can2->cantflg = 0x01;
 936
 937        i = 0;
 938        while ((can2->cantflg & 0x01) == 0) {
 939                i++;
 940                if (i == 10) {
 941                        printf ("%s: CAN2 send error, "
 942                                "can not send message!\n",
 943                                __FUNCTION__);
 944                        return 1;
 945                }
 946                udelay(1000);
 947        }
 948        udelay(1000);
 949
 950        i = 0;
 951        while (!(can1->canrflg & 0x01)) {
 952                i++;
 953                if (i == 10) {
 954                        printf ("%s: CAN1 receive timeout, "
 955                                "no message received!\n",
 956                                __FUNCTION__);
 957                        return 1;
 958                }
 959                udelay(1000);
 960        }
 961
 962        if (can1->canrxfg.dsr[0] != 0xCC) {
 963                printf ("%s: CAN1 receive error 0x%02x\n",
 964                        __FUNCTION__, (can1->canrxfg.dsr[0]));
 965                return 1;
 966        }
 967
 968        return 0;
 969}
 970
 971/*
 972 * return 1 if rs232 port unknown
 973 * return 2 on txd/rxd failure (only rs232 2)
 974 * return 3 on rts/cts failure
 975 * return 0 if no failure
 976 */
 977int do_rs232(char * const argv[])
 978{
 979        int error_status = 0;
 980        struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio *)MPC5XXX_GPIO;
 981        struct mpc5xxx_psc *psc1 = (struct mpc5xxx_psc *)MPC5XXX_PSC1;
 982
 983        switch  (simple_strtoul(argv[2], NULL, 10)) {
 984
 985        case 1:
 986                /* check RTS <-> CTS loop */
 987                /* set rts to 0 */
 988                psc1->op1 |= 0x01;
 989
 990                /* wait some time before requesting status */
 991                udelay(10);
 992
 993                /* check status at cts */
 994                if ((psc1->ip & 0x01) != 0) {
 995                        error_status = 3;
 996                        printf ("%s: failure at rs232_1, cts status is %d "
 997                                "(should be 0)\n",
 998                                __FUNCTION__, (psc1->ip & 0x01));
 999                }
1000
1001                /* set rts to 1 */
1002                psc1->op0 |= 0x01;
1003
1004                /* wait some time before requesting status */
1005                udelay(10);
1006
1007                /* check status at cts */
1008                if ((psc1->ip & 0x01) != 1) {
1009                        error_status = 3;
1010                        printf ("%s: failure at rs232_1, cts status is %d "
1011                                "(should be 1)\n",
1012                                __FUNCTION__, (psc1->ip & 0x01));
1013                }
1014
1015                break;
1016
1017        case 2:
1018                /* set PSC3_0, PSC3_2 as output and PSC3_1, PSC3_3 as input */
1019                gpio->simple_ddr &= ~(0x00000F00);
1020                gpio->simple_ddr |=   0x00000500;
1021
1022                /* check TXD <-> RXD loop */
1023                /* set TXD to 1 */
1024                gpio->simple_dvo |=   (1 << 8);
1025
1026                /* wait some time before requesting status */
1027                udelay(10);
1028
1029                if ((gpio->simple_ival & 0x00000200) != 0x00000200) {
1030                        error_status = 2;
1031                        printf ("%s: failure at rs232_2, rxd status is %d "
1032                                "(should be 1)\n",
1033                                __FUNCTION__,
1034                                (gpio->simple_ival & 0x00000200) >> 9);
1035                }
1036
1037                /* set TXD to 0 */
1038                gpio->simple_dvo &= ~(1 << 8);
1039
1040                /* wait some time before requesting status */
1041                udelay(10);
1042
1043                if ((gpio->simple_ival & 0x00000200) != 0x00000000) {
1044                        error_status = 2;
1045                        printf ("%s: failure at rs232_2, rxd status is %d "
1046                                "(should be 0)\n",
1047                                __FUNCTION__,
1048                                (gpio->simple_ival & 0x00000200) >> 9);
1049                }
1050
1051                /* check RTS <-> CTS loop */
1052                /* set RTS to 1 */
1053                gpio->simple_dvo |=   (1 << 10);
1054
1055                /* wait some time before requesting status */
1056                udelay(10);
1057
1058                if ((gpio->simple_ival & 0x00000800) != 0x00000800) {
1059                        error_status = 3;
1060                        printf ("%s: failure at rs232_2, cts status is %d "
1061                                "(should be 1)\n",
1062                                __FUNCTION__,
1063                                (gpio->simple_ival & 0x00000800) >> 11);
1064                }
1065
1066                /* set RTS to 0 */
1067                gpio->simple_dvo &= ~(1 << 10);
1068
1069                /* wait some time before requesting status */
1070                udelay(10);
1071
1072                if ((gpio->simple_ival & 0x00000800) != 0x00000000) {
1073                        error_status = 3;
1074                        printf ("%s: failure at rs232_2, cts status is %d "
1075                                "(should be 0)\n",
1076                                __FUNCTION__,
1077                                (gpio->simple_ival & 0x00000800) >> 11);
1078                }
1079
1080                /* set PSC3_0, PSC3_1, PSC3_2 and PSC3_3 as output */
1081                gpio->simple_ddr &= ~(0x00000F00);
1082                gpio->simple_ddr |=   0x00000F00;
1083                break;
1084
1085        default:
1086                printf ("%s: invalid rs232 number %s\n", __FUNCTION__, argv[2]);
1087                error_status = 1;
1088                break;
1089        }
1090
1091        return error_status;
1092}
1093
1094#if !defined(CONFIG_FO300) && !defined(CONFIG_TQM5200S)
1095static void sm501_backlight (unsigned int state)
1096{
1097        if (state == BL_ON) {
1098                *(vu_long *)(SM501_MMIO_BASE+SM501_PANEL_DISPLAY_CONTROL) |=
1099                        (1 << 26) | (1 << 27);
1100        } else if (state == BL_OFF)
1101                *(vu_long *)(SM501_MMIO_BASE+SM501_PANEL_DISPLAY_CONTROL) &=
1102                        ~((1 << 26) | (1 << 27));
1103}
1104#endif /* !CONFIG_FO300 & !CONFIG_TQM5200S */
1105
1106int cmd_fkt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1107{
1108        int rcode;
1109
1110#ifdef CONFIG_STK52XX_REV100
1111        printf ("Revision 100 of STK52XX not supported!\n");
1112        return 1;
1113#endif
1114#if defined(CONFIG_STK52XX)
1115        led_init();
1116#endif
1117        can_init();
1118
1119        switch (argc) {
1120
1121        case 0:
1122        case 1:
1123                break;
1124
1125        case 2:
1126                if (strncmp (argv[1], "can", 3) == 0) {
1127                        rcode = do_can (argv);
1128                        if (rcode == 0)
1129                                printf ("OK\n");
1130                        else
1131                                printf ("Error\n");
1132                        return rcode;
1133                }
1134                break;
1135
1136        case 3:
1137                if (strncmp (argv[1], "rs232", 3) == 0) {
1138                        rcode = do_rs232 (argv);
1139                        if (rcode == 0)
1140                                printf ("OK\n");
1141                        else
1142                                printf ("Error\n");
1143                        return rcode;
1144#if !defined(CONFIG_FO300) && !defined(CONFIG_TQM5200S)
1145                } else if (strncmp (argv[1], "backlight", 4) == 0) {
1146                        if (strncmp (argv[2], "on", 2) == 0) {
1147                                sm501_backlight (BL_ON);
1148                                return 0;
1149                        }
1150                        else if (strncmp (argv[2], "off", 3) == 0) {
1151                                sm501_backlight (BL_OFF);
1152                                return 0;
1153                        }
1154#endif /* !CONFIG_FO300 & !CONFIG_TQM5200S */
1155                }
1156                break;
1157
1158#if defined(CONFIG_STK52XX)
1159        case 4:
1160                if (strcmp (argv[1], "led") == 0) {
1161                        return (do_led (argv));
1162                }
1163                break;
1164#endif
1165
1166        default:
1167                break;
1168        }
1169
1170        printf ("Usage:\nfkt cmd [arg1] [arg2] ...\n");
1171        return 1;
1172}
1173
1174
1175U_BOOT_CMD(
1176        sound ,    5,    1,     cmd_sound,
1177        "Sound sub-system",
1178        "saw [duration] [freq] [channel]\n"
1179        "    - generate sawtooth for 'duration' ms with frequency 'freq'\n"
1180        "      on left \"l\" or right \"r\" channel\n"
1181        "sound square [duration] [freq] [channel]\n"
1182        "    - generate squarewave for 'duration' ms with frequency 'freq'\n"
1183        "      on left \"l\" or right \"r\" channel\n"
1184        "pcm1772 reg val"
1185);
1186
1187U_BOOT_CMD(
1188        wav ,    3,    1,     cmd_wav,
1189        "play wav file",
1190        "[addr] [bytes]\n"
1191        "    - play wav file at address 'addr' with length 'bytes'"
1192);
1193
1194U_BOOT_CMD(
1195        beep ,    2,    1,     cmd_beep,
1196        "play short beep",
1197        "[channel]\n"
1198        "    - play short beep on \"l\"eft or \"r\"ight channel"
1199);
1200#endif /* CONFIG_STK52XX  || CONFIG_FO300 */
1201
1202#if defined(CONFIG_STK52XX)
1203U_BOOT_CMD(
1204        fkt ,   4,      1,      cmd_fkt,
1205        "Function test routines",
1206        "led number on/off\n"
1207        "     - 'number's like printed on STK52XX board\n"
1208        "fkt can\n"
1209        "     - loopback plug for X83 required\n"
1210        "fkt rs232 number\n"
1211        "     - loopback plug(s) for X2 required"
1212#ifndef CONFIG_TQM5200S
1213        "\n"
1214        "fkt backlight on/off\n"
1215        "     - switch backlight on or off"
1216#endif /* !CONFIG_TQM5200S */
1217);
1218#elif defined(CONFIG_FO300)
1219U_BOOT_CMD(
1220        fkt ,   3,      1,      cmd_fkt,
1221        "Function test routines",
1222        "fkt can\n"
1223        "     - loopback plug for X16/X29 required\n"
1224        "fkt rs232 number\n"
1225        "     - loopback plug(s) for X21/X22 required"
1226);
1227#endif
1228#endif
1229