]>
Commit | Line | Data |
---|---|---|
6617aae9 WD |
1 | /* |
2 | * (C) Copyright 2005 | |
3 | * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de. | |
4 | * | |
1a459660 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
6617aae9 WD |
6 | */ |
7 | ||
8 | /* | |
45a212c4 | 9 | * STK52XX specific functions |
6617aae9 WD |
10 | */ |
11 | /*#define DEBUG*/ | |
12 | ||
13 | #include <common.h> | |
14 | #include <command.h> | |
15 | ||
ab3abcba | 16 | #if defined(CONFIG_CMD_BSP) |
6617aae9 | 17 | |
6d3bc9b8 | 18 | #if defined(CONFIG_STK52XX) || defined(CONFIG_FO300) |
6617aae9 WD |
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 | |
53677ef1 | 33 | #define SM501_GPIO_DATA_LOW 0x00010000UL |
6617aae9 WD |
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 | ||
6617aae9 WD |
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 | { | |
6617aae9 WD |
69 | struct mpc5xxx_spi *spi = (struct mpc5xxx_spi*)MPC5XXX_SPI; |
70 | ||
71 | spi->dr = data; | |
72 | /* wait for SPI transmission completed */ | |
65766f38 WD |
73 | while (!(spi->sr & 0x80)) { |
74 | if (spi->sr & 0x40) { /* if write collision occured */ | |
75 | int dummy; | |
76 | ||
6617aae9 WD |
77 | /* do dummy read to clear status register */ |
78 | dummy = spi->dr; | |
65766f38 | 79 | printf("SPI write collision: dr=0x%x\n", dummy); |
6617aae9 WD |
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 | ||
6d0f6bcf | 151 | *(vu_long *)(CONFIG_SYS_MBAR + 0x22C) = 0x805d; /* PSC2 CDM MCLK config; MCLK |
6617aae9 | 152 | * 5.617 MHz */ |
6d0f6bcf | 153 | *(vu_long *)(CONFIG_SYS_MBAR + 0x214) |= 0x00000040; /* CDM clock enable |
6617aae9 WD |
154 | * register */ |
155 | psc->ccr = 0x1F03; /* 16 bit data width; 5.617MHz MCLK */ | |
156 | psc->ctur = 0x0F; /* 16 bit frame width */ | |
157 | ||
65766f38 | 158 | for (i = 0; i < 128; i++) |
6617aae9 | 159 | psc->psc_buffer_32 = 0; /* clear tx fifo */ |
6617aae9 WD |
160 | } |
161 | ||
162 | static int i2s_play_wave(unsigned long addr, unsigned long len) | |
163 | { | |
164 | unsigned long i; | |
77ddac94 | 165 | unsigned char *wave_file = (uchar *)addr + 44; /* quick'n dirty: skip |
6617aae9 | 166 | * wav header*/ |
6617aae9 WD |
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++) { | |
65766f38 WD |
175 | unsigned char swapped[4]; |
176 | unsigned long *p = (unsigned long*)swapped; | |
177 | ||
d0ff51ba WD |
178 | swapped[3] = *wave_file++; |
179 | swapped[2] = *wave_file++; | |
180 | swapped[1] = *wave_file++; | |
181 | swapped[0] = *wave_file++; | |
65766f38 WD |
182 | |
183 | psc->psc_buffer_32 = *p; | |
184 | ||
6617aae9 WD |
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 | ||
54841ab5 | 289 | static int cmd_sound(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
6617aae9 WD |
290 | { |
291 | unsigned long reg, val, duration; | |
77ddac94 | 292 | char *tmp; |
6617aae9 WD |
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: | |
47e26b1b | 315 | return cmd_usage(cmdtp); |
6617aae9 WD |
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 | ||
47e26b1b | 329 | return cmd_usage(cmdtp); |
6617aae9 WD |
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 | } | |
47e26b1b | 344 | return cmd_usage(cmdtp); |
6617aae9 WD |
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 | } | |
47e26b1b | 367 | return cmd_usage(cmdtp); |
6617aae9 WD |
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 | } | |
47e26b1b | 396 | return cmd_usage(cmdtp); |
6617aae9 WD |
397 | } |
398 | printf ("Usage:\nsound cmd [arg1] [arg2] ...\n"); | |
399 | return 1; | |
400 | } | |
401 | ||
54841ab5 | 402 | static int cmd_wav(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
6617aae9 WD |
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 | ||
9b55a253 | 461 | printf("Play wave file at %lX with length %lX\n", addr, length); |
6617aae9 WD |
462 | rcode = i2s_play_wave(addr, length); |
463 | ||
464 | return rcode; | |
465 | } | |
466 | ||
54841ab5 | 467 | static int cmd_beep(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
6617aae9 WD |
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: | |
47e26b1b | 496 | return cmd_usage(cmdtp); |
6617aae9 WD |
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 | } | |
6d3bc9b8 | 519 | #endif |
6617aae9 | 520 | |
6d3bc9b8 | 521 | #if defined(CONFIG_STK52XX) |
6617aae9 WD |
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 | ||
0fc0f91b | 543 | #ifndef CONFIG_TQM5200S |
6617aae9 WD |
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); | |
0fc0f91b | 556 | #endif /* !CONFIG_TQM5200S */ |
6617aae9 WD |
557 | } |
558 | ||
559 | /* | |
560 | * return 1 if led number unknown | |
561 | * return 0 else | |
562 | */ | |
54841ab5 | 563 | int do_led(char * const argv[]) |
6617aae9 WD |
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 | ||
53677ef1 | 568 | switch (simple_strtoul(argv[2], NULL, 10)) { |
6617aae9 WD |
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; | |
0fc0f91b | 633 | #ifndef CONFIG_TQM5200S |
6617aae9 WD |
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; | |
0fc0f91b | 713 | #endif /* !CONFIG_TQM5200S */ |
6617aae9 WD |
714 | default: |
715 | printf ("%s: invalid led number %s\n", __FUNCTION__, argv[2]); | |
716 | return 1; | |
717 | } | |
718 | ||
719 | return 0; | |
720 | } | |
6d3bc9b8 | 721 | #endif |
6617aae9 | 722 | |
6d3bc9b8 | 723 | #if defined(CONFIG_STK52XX) || defined(CONFIG_FO300) |
6617aae9 WD |
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 = | |
6d0f6bcf | 733 | (struct mpc5xxx_mscan *)(CONFIG_SYS_MBAR + 0x0900); |
6617aae9 | 734 | struct mpc5xxx_mscan *can2 = |
6d0f6bcf | 735 | (struct mpc5xxx_mscan *)(CONFIG_SYS_MBAR + 0x0980); |
6617aae9 WD |
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 | */ | |
54841ab5 | 874 | int do_can(char * const argv[]) |
6617aae9 WD |
875 | { |
876 | int i; | |
877 | struct mpc5xxx_mscan *can1 = | |
6d0f6bcf | 878 | (struct mpc5xxx_mscan *)(CONFIG_SYS_MBAR + 0x0900); |
6617aae9 | 879 | struct mpc5xxx_mscan *can2 = |
6d0f6bcf | 880 | (struct mpc5xxx_mscan *)(CONFIG_SYS_MBAR + 0x0980); |
6617aae9 WD |
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 | */ | |
54841ab5 | 976 | int do_rs232(char * const argv[]) |
6617aae9 WD |
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 | ||
53677ef1 | 982 | switch (simple_strtoul(argv[2], NULL, 10)) { |
6617aae9 WD |
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 | ||
0fc0f91b | 1093 | #if !defined(CONFIG_FO300) && !defined(CONFIG_TQM5200S) |
6617aae9 WD |
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 | } | |
0fc0f91b | 1103 | #endif /* !CONFIG_FO300 & !CONFIG_TQM5200S */ |
6617aae9 | 1104 | |
54841ab5 | 1105 | int cmd_fkt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
6617aae9 WD |
1106 | { |
1107 | int rcode; | |
1108 | ||
1109 | #ifdef CONFIG_STK52XX_REV100 | |
1110 | printf ("Revision 100 of STK52XX not supported!\n"); | |
1111 | return 1; | |
1112 | #endif | |
6d3bc9b8 | 1113 | #if defined(CONFIG_STK52XX) |
6617aae9 | 1114 | led_init(); |
6d3bc9b8 | 1115 | #endif |
6617aae9 WD |
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; | |
0fc0f91b | 1143 | #if !defined(CONFIG_FO300) && !defined(CONFIG_TQM5200S) |
6617aae9 WD |
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 | } | |
0fc0f91b | 1153 | #endif /* !CONFIG_FO300 & !CONFIG_TQM5200S */ |
6617aae9 WD |
1154 | } |
1155 | break; | |
1156 | ||
6d3bc9b8 | 1157 | #if defined(CONFIG_STK52XX) |
6617aae9 WD |
1158 | case 4: |
1159 | if (strcmp (argv[1], "led") == 0) { | |
1160 | return (do_led (argv)); | |
1161 | } | |
1162 | break; | |
6d3bc9b8 | 1163 | #endif |
6617aae9 WD |
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, | |
2fb2604d | 1176 | "Sound sub-system", |
6617aae9 WD |
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" | |
a89c33db | 1183 | "pcm1772 reg val" |
6617aae9 WD |
1184 | ); |
1185 | ||
1186 | U_BOOT_CMD( | |
1187 | wav , 3, 1, cmd_wav, | |
2fb2604d | 1188 | "play wav file", |
6617aae9 | 1189 | "[addr] [bytes]\n" |
a89c33db | 1190 | " - play wav file at address 'addr' with length 'bytes'" |
6617aae9 WD |
1191 | ); |
1192 | ||
1193 | U_BOOT_CMD( | |
1194 | beep , 2, 1, cmd_beep, | |
2fb2604d | 1195 | "play short beep", |
6617aae9 | 1196 | "[channel]\n" |
a89c33db | 1197 | " - play short beep on \"l\"eft or \"r\"ight channel" |
6617aae9 | 1198 | ); |
6d3bc9b8 | 1199 | #endif /* CONFIG_STK52XX || CONFIG_FO300 */ |
6617aae9 | 1200 | |
6d3bc9b8 | 1201 | #if defined(CONFIG_STK52XX) |
6617aae9 WD |
1202 | U_BOOT_CMD( |
1203 | fkt , 4, 1, cmd_fkt, | |
2fb2604d | 1204 | "Function test routines", |
6617aae9 | 1205 | "led number on/off\n" |
45a212c4 | 1206 | " - 'number's like printed on STK52XX board\n" |
6617aae9 WD |
1207 | "fkt can\n" |
1208 | " - loopback plug for X83 required\n" | |
1209 | "fkt rs232 number\n" | |
a89c33db | 1210 | " - loopback plug(s) for X2 required" |
0fc0f91b | 1211 | #ifndef CONFIG_TQM5200S |
a89c33db | 1212 | "\n" |
6617aae9 | 1213 | "fkt backlight on/off\n" |
a89c33db | 1214 | " - switch backlight on or off" |
0fc0f91b | 1215 | #endif /* !CONFIG_TQM5200S */ |
6617aae9 | 1216 | ); |
6d3bc9b8 MB |
1217 | #elif defined(CONFIG_FO300) |
1218 | U_BOOT_CMD( | |
1219 | fkt , 3, 1, cmd_fkt, | |
2fb2604d | 1220 | "Function test routines", |
6d3bc9b8 MB |
1221 | "fkt can\n" |
1222 | " - loopback plug for X16/X29 required\n" | |
1223 | "fkt rs232 number\n" | |
a89c33db | 1224 | " - loopback plug(s) for X21/X22 required" |
6d3bc9b8 MB |
1225 | ); |
1226 | #endif | |
d39b5741 | 1227 | #endif |