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