]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/trab/cmd_trab.c
cmd_usage(): simplify return code handling
[karo-tx-uboot.git] / board / trab / cmd_trab.c
1 /*
2  * (C) Copyright 2003
3  * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #undef DEBUG
25
26 #include <common.h>
27 #include <command.h>
28 #include <asm/arch/s3c24x0_cpu.h>
29 #include <rtc.h>
30
31 /*
32  * TRAB board specific commands. Especially commands for burn-in and function
33  * test.
34  */
35 #if defined(CONFIG_CMD_BSP)
36
37 /* limits for valid range of VCC5V in mV  */
38 #define VCC5V_MIN       4500
39 #define VCC5V_MAX       5500
40
41 /*
42  * Test strings for EEPROM test. Length of string 2 must not exceed length of
43  * string 1. Otherwise a buffer overrun could occur!
44  */
45 #define EEPROM_TEST_STRING_1    "0987654321 :tset a si siht"
46 #define EEPROM_TEST_STRING_2    "this is a test: 1234567890"
47
48 /*
49  * min/max limits for valid contact temperature during burn in test (in
50  * degree Centigrade * 100)
51  */
52 #define MIN_CONTACT_TEMP        -1000
53 #define MAX_CONTACT_TEMP        +9000
54
55 /* blinking frequency of status LED */
56 #define LED_BLINK_FREQ          5
57
58 /* delay time between burn in cycles in seconds */
59 #ifndef BURN_IN_CYCLE_DELAY     /* if not defined in include/configs/trab.h */
60 #define BURN_IN_CYCLE_DELAY     5
61 #endif
62
63 /* physical SRAM parameters */
64 #define SRAM_ADDR       0x02000000 /* GCS1 */
65 #define SRAM_SIZE       0x40000 /* 256 kByte */
66
67 /* CPLD-Register for controlling TRAB hardware functions */
68 #define CPLD_BUTTONS            ((volatile unsigned long *)0x04020000)
69 #define CPLD_FILL_LEVEL         ((volatile unsigned long *)0x04008000)
70 #define CPLD_ROTARY_SWITCH      ((volatile unsigned long *)0x04018000)
71 #define CPLD_RS485_RE           ((volatile unsigned long *)0x04028000)
72
73 /* I2C EEPROM device address */
74 #define I2C_EEPROM_DEV_ADDR     0x54
75
76 /* EEPROM address map */
77 #define EE_ADDR_TEST                    192
78 #define EE_ADDR_MAX_CYCLES              256
79 #define EE_ADDR_STATUS                  258
80 #define EE_ADDR_PASS_CYCLES             259
81 #define EE_ADDR_FIRST_ERROR_CYCLE       261
82 #define EE_ADDR_FIRST_ERROR_NUM         263
83 #define EE_ADDR_FIRST_ERROR_NAME        264
84 #define EE_ADDR_ACT_CYCLE               280
85
86 /* Bit definitions for ADCCON */
87 #define ADC_ENABLE_START     0x1
88 #define ADC_READ_START       0x2
89 #define ADC_STDBM            0x4
90 #define ADC_INP_AIN0         (0x0 << 3)
91 #define ADC_INP_AIN1         (0x1 << 3)
92 #define ADC_INP_AIN2         (0x2 << 3)
93 #define ADC_INP_AIN3         (0x3 << 3)
94 #define ADC_INP_AIN4         (0x4 << 3)
95 #define ADC_INP_AIN5         (0x5 << 3)
96 #define ADC_INP_AIN6         (0x6 << 3)
97 #define ADC_INP_AIN7         (0x7 << 3)
98 #define ADC_PRSCEN           0x4000
99 #define ADC_ECFLG            0x800
100
101 /* misc */
102
103 /* externals */
104 extern int memory_post_tests (unsigned long start, unsigned long size);
105 extern int i2c_write (uchar, uint, int , uchar* , int);
106 extern int i2c_read (uchar, uint, int , uchar* , int);
107 extern void tsc2000_reg_init (void);
108 extern s32 tsc2000_contact_temp (void);
109 extern void tsc2000_spi_init(void);
110
111 /* function declarations */
112 int do_dip (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
113 int do_vcc5v (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
114 int do_burn_in (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
115 int do_contact_temp (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
116 int do_burn_in_status (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
117 int i2c_write_multiple (uchar chip, uint addr, int alen,
118                         uchar *buffer, int len);
119 int i2c_read_multiple (uchar chip, uint addr, int alen,
120                         uchar *buffer, int len);
121 int do_temp_log (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
122
123 /* helper functions */
124 static void adc_init (void);
125 static int adc_read (unsigned int channel);
126 static int read_dip (void);
127 static int read_vcc5v (void);
128 static int test_dip (void);
129 static int test_vcc5v (void);
130 static int test_rotary_switch (void);
131 static int test_sram (void);
132 static int test_eeprom (void);
133 static int test_contact_temp (void);
134 static void led_set (unsigned int);
135 static void led_blink (void);
136 static void led_init (void);
137 static void sdelay (unsigned long seconds); /* delay in seconds */
138 static int dummy (void);
139 static int read_max_cycles(void);
140 static void test_function_table_init (void);
141 static void global_vars_init (void);
142 static int global_vars_write_to_eeprom (void);
143
144 /* globals */
145 u16 max_cycles;
146 u8 status;
147 u16 pass_cycles;
148 u16 first_error_cycle;
149 u8 first_error_num;
150 char first_error_name[16];
151 u16 act_cycle;
152
153 typedef struct test_function_s {
154         char *name;
155         int (*pf)(void);
156 } test_function_t;
157
158 /* max number of Burn In Functions */
159 #define BIF_MAX 6
160
161 /* table with burn in functions */
162 test_function_t test_function[BIF_MAX];
163
164
165 int do_burn_in (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
166 {
167         int i;
168         int cycle_status;
169
170         if (argc > 1)
171                 return cmd_usage(cmdtp);
172
173         led_init ();
174         global_vars_init ();
175         test_function_table_init ();
176         tsc2000_spi_init ();
177
178         if (global_vars_write_to_eeprom () != 0) {
179                 printf ("%s: error writing global_vars to eeprom\n",
180                         __FUNCTION__);
181                 return (1);
182         }
183
184         if (read_max_cycles () != 0) {
185                 printf ("%s: error reading max_cycles from eeprom\n",
186                         __FUNCTION__);
187                 return (1);
188         }
189
190         if (max_cycles == 0) {
191                 printf ("%s: error, burn in max_cycles = 0\n", __FUNCTION__);
192                 return (1);
193         }
194
195         status = 0;
196         for (act_cycle = 1; act_cycle <= max_cycles; act_cycle++) {
197
198                 cycle_status = 0;
199
200                 /*
201                  * avoid timestamp overflow problem after about 68 minutes of
202                  * udelay() time.
203                  */
204                 reset_timer_masked ();
205                 for (i = 0; i < BIF_MAX; i++) {
206
207                         /* call test function */
208                         if ((*test_function[i].pf)() != 0) {
209                                 printf ("error in %s test\n",
210                                         test_function[i].name);
211
212                                 /* is it the first error? */
213                                 if (status == 0) {
214                                         status = 1;
215                                         first_error_cycle = act_cycle;
216
217                                         /* do not use error_num 0 */
218                                         first_error_num = i+1;
219                                         strncpy (first_error_name,
220                                                  test_function[i].name,
221                                                  sizeof (first_error_name));
222                                         led_set (0);
223                                 }
224                                 cycle_status = 1;
225                         }
226                 }
227                 /* were all tests of actual cycle OK? */
228                 if (cycle_status == 0)
229                         pass_cycles++;
230
231                 /* set status LED if no error is occoured since yet */
232                 if (status == 0)
233                         led_set (1);
234
235                 printf ("%s: cycle %d finished\n", __FUNCTION__, act_cycle);
236
237                 /* pause between cycles */
238                 sdelay (BURN_IN_CYCLE_DELAY);
239         }
240
241         if (global_vars_write_to_eeprom () != 0) {
242                 led_set (0);
243                 printf ("%s: error writing global_vars to eeprom\n",
244                         __FUNCTION__);
245                 status = 1;
246         }
247
248         if (status == 0) {
249                 led_blink ();   /* endless loop!! */
250                 return (0);
251         } else {
252                 led_set (0);
253                 return (1);
254         }
255 }
256
257 U_BOOT_CMD(
258         burn_in,        1,      1,      do_burn_in,
259         "start burn-in test application on TRAB",
260         "\n"
261         "    -  start burn-in test application\n"
262         "       The burn-in test could took a while to finish!\n"
263         "       The content of the onboard EEPROM is modified!"
264 );
265
266
267 int do_dip (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
268 {
269         int i, dip;
270
271         if (argc > 1)
272                 return cmd_usage(cmdtp);
273
274         if ((dip = read_dip ()) == -1)
275                 return 1;
276
277         for (i = 0; i < 4; i++) {
278                 if ((dip & (1 << i)) == 0)
279                         printf("0");
280                 else
281                         printf("1");
282         }
283         printf("\n");
284
285         return 0;
286 }
287
288 U_BOOT_CMD(
289         dip,    1,      1,      do_dip,
290         "read dip switch on TRAB",
291         "\n"
292         "    - read state of dip switch (S1) on TRAB board\n"
293         "      read sequence: 1-2-3-4; ON=1; OFF=0; e.g.: \"0100\""
294 );
295
296
297 int do_vcc5v (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
298 {
299         int vcc5v;
300
301         if (argc > 1)
302                 return cmd_usage(cmdtp);
303
304         if ((vcc5v = read_vcc5v ()) == -1)
305                 return (1);
306
307         printf ("%d", (vcc5v / 1000));
308         printf (".%d", (vcc5v % 1000) / 100);
309         printf ("%d V\n", (vcc5v % 100) / 10) ;
310
311         return 0;
312 }
313
314 U_BOOT_CMD(
315         vcc5v,  1,      1,      do_vcc5v,
316         "read VCC5V on TRAB",
317         "\n"
318         "    - read actual value of voltage VCC5V"
319 );
320
321
322 int do_contact_temp (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
323 {
324         int contact_temp;
325
326         if (argc > 1)
327                 return cmd_usage(cmdtp);
328
329         tsc2000_spi_init ();
330
331         contact_temp = tsc2000_contact_temp();
332         printf ("%d degree C * 100\n", contact_temp) ;
333
334         return 0;
335 }
336
337 U_BOOT_CMD(
338         c_temp, 1,      1,      do_contact_temp,
339         "read contact temperature on TRAB",
340         ""
341         "    -  reads the onboard temperature (=contact temperature)\n"
342 );
343
344
345 int do_burn_in_status (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
346 {
347         if (argc > 1)
348                 return cmd_usage(cmdtp);
349
350         if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_STATUS, 1,
351                                 (unsigned char*) &status, 1))
352                 return (1);
353
354         if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_PASS_CYCLES, 1,
355                                 (unsigned char*) &pass_cycles, 2))
356                 return (1);
357
358         if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_CYCLE,
359                                 1, (unsigned char*) &first_error_cycle, 2))
360                 return (1);
361
362         if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_NUM,
363                                 1, (unsigned char*) &first_error_num, 1))
364                 return (1);
365
366         if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_NAME,
367                                1, (unsigned char*)first_error_name,
368                                sizeof (first_error_name)))
369                 return (1);
370
371         if (read_max_cycles () != 0)
372                 return (1);
373
374         printf ("max_cycles = %d\n", max_cycles);
375         printf ("status = %d\n", status);
376         printf ("pass_cycles = %d\n", pass_cycles);
377         printf ("first_error_cycle = %d\n", first_error_cycle);
378         printf ("first_error_num = %d\n", first_error_num);
379         printf ("first_error_name = %.*s\n",(int) sizeof(first_error_name),
380                 first_error_name);
381
382         return 0;
383 }
384
385 U_BOOT_CMD(
386         bis,    1,      1,      do_burn_in_status,
387         "print burn in status on TRAB",
388         "\n"
389         "    -  prints the status variables of the last burn in test\n"
390         "       stored in the onboard EEPROM on TRAB board"
391 );
392
393 static int read_dip (void)
394 {
395         unsigned int result = 0;
396         int adc_val;
397         int i;
398
399         /***********************************************************
400          DIP switch connection (according to wa4-cpu.sp.301.pdf, page 3):
401            SW1 - AIN4
402            SW2 - AIN5
403            SW3 - AIN6
404            SW4 - AIN7
405
406            "On" DIP switch position short-circuits the voltage from
407            the input channel (i.e. '0' conversion result means "on").
408         *************************************************************/
409
410         for (i = 7; i > 3; i--) {
411
412                 if ((adc_val = adc_read (i)) == -1) {
413                         printf ("%s: Channel %d could not be read\n",
414                                  __FUNCTION__, i);
415                         return (-1);
416                 }
417
418                 /*
419                  * Input voltage (switch open) is 1.8 V.
420                  * (Vin_High/VRef)*adc_res = (1,8V/2,5V)*1023) = 736
421                  * Set trigger at halve that value.
422                  */
423                 if (adc_val < 368)
424                         result |= (1 << (i-4));
425         }
426         return (result);
427 }
428
429
430 static int read_vcc5v (void)
431 {
432         s32 result;
433
434         /* VCC5V is connected to channel 2 */
435
436         if ((result = adc_read (2)) == -1) {
437                 printf ("%s: VCC5V could not be read\n", __FUNCTION__);
438                 return (-1);
439         }
440         /*
441          * Calculate voltage value. Split in two parts because there is no
442          * floating point support.  VCC5V is connected over an resistor divider:
443          * VCC5V=ADCval*2,5V/1023*(10K+30K)/10K.
444          */
445         result = result * 10 * 1000 / 1023; /* result in mV */
446
447         return (result);
448 }
449
450
451 static int test_dip (void)
452 {
453         static int first_run = 1;
454         static int first_dip;
455
456         if (first_run) {
457                 if ((first_dip = read_dip ()) == -1) {
458                         return (1);
459                 }
460                 first_run = 0;
461                 debug ("%s: first_dip=%d\n", __FUNCTION__, first_dip);
462         }
463         if (first_dip != read_dip ()) {
464                 return (1);
465         } else {
466                 return (0);
467         }
468 }
469
470
471 static int test_vcc5v (void)
472 {
473         int vcc5v;
474
475         if ((vcc5v = read_vcc5v ()) == -1) {
476                 return (1);
477         }
478
479         if ((vcc5v > VCC5V_MAX) || (vcc5v < VCC5V_MIN)) {
480                 printf ("%s: vcc5v[V/100]=%d\n", __FUNCTION__, vcc5v);
481                 return (1);
482         } else {
483                 return (0);
484         }
485 }
486
487
488 static int test_rotary_switch (void)
489 {
490         static int first_run = 1;
491         static int first_rs;
492
493         if (first_run) {
494                 /*
495                  * clear bits in CPLD, because they have random values after
496                  * power-up or reset.
497                  */
498                 *CPLD_ROTARY_SWITCH |= (1 << 16) | (1 << 17);
499
500                 first_rs = ((*CPLD_ROTARY_SWITCH >> 16) & 0x7);
501                 first_run = 0;
502                 debug ("%s: first_rs=%d\n", __FUNCTION__, first_rs);
503         }
504
505         if (first_rs != ((*CPLD_ROTARY_SWITCH >> 16) & 0x7)) {
506                 return (1);
507         } else {
508                 return (0);
509         }
510 }
511
512
513 static int test_sram (void)
514 {
515         return (memory_post_tests (SRAM_ADDR, SRAM_SIZE));
516 }
517
518
519 static int test_eeprom (void)
520 {
521         unsigned char temp[sizeof (EEPROM_TEST_STRING_1)];
522         int result = 0;
523
524         /* write test string 1, read back and verify */
525         if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_TEST, 1,
526                                 (unsigned char*)EEPROM_TEST_STRING_1,
527                                 sizeof (EEPROM_TEST_STRING_1))) {
528                 return (1);
529         }
530
531         if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_TEST, 1,
532                                temp, sizeof (EEPROM_TEST_STRING_1))) {
533                 return (1);
534         }
535
536         if (strcmp ((char *)temp, EEPROM_TEST_STRING_1) != 0) {
537                 result = 1;
538                 printf ("%s: error; read_str = \"%s\"\n", __FUNCTION__, temp);
539         }
540
541         /* write test string 2, read back and verify */
542         if (result == 0) {
543                 if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_TEST, 1,
544                                         (unsigned char*)EEPROM_TEST_STRING_2,
545                                         sizeof (EEPROM_TEST_STRING_2))) {
546                         return (1);
547                 }
548
549                 if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_TEST, 1,
550                                        temp, sizeof (EEPROM_TEST_STRING_2))) {
551                         return (1);
552                 }
553
554                 if (strcmp ((char *)temp, EEPROM_TEST_STRING_2) != 0) {
555                         result = 1;
556                         printf ("%s: error; read str = \"%s\"\n",
557                                 __FUNCTION__, temp);
558                 }
559         }
560         return (result);
561 }
562
563
564 static int test_contact_temp (void)
565 {
566         int contact_temp;
567
568         contact_temp = tsc2000_contact_temp ();
569
570         if ((contact_temp < MIN_CONTACT_TEMP)
571             || (contact_temp > MAX_CONTACT_TEMP))
572                 return (1);
573         else
574                 return (0);
575 }
576
577
578 int i2c_write_multiple (uchar chip, uint addr, int alen,
579                         uchar *buffer, int len)
580 {
581         int i;
582
583         if (alen != 1) {
584                 printf ("%s: addr len other than 1 not supported\n",
585                          __FUNCTION__);
586                 return (1);
587         }
588
589         for (i = 0; i < len; i++) {
590                 if (i2c_write (chip, addr+i, alen, buffer+i, 1)) {
591                         printf ("%s: could not write to i2c device %d"
592                                  ", addr %d\n", __FUNCTION__, chip, addr);
593                         return (1);
594                 }
595 #if 0
596                 printf ("chip=%#x, addr+i=%#x+%d=%p, alen=%d, *buffer+i="
597                         "%#x+%d=%p=\"%.1s\"\n", chip, addr, i, addr+i,
598                         alen, buffer, i, buffer+i, buffer+i);
599 #endif
600
601                 udelay (30000);
602         }
603         return (0);
604 }
605
606
607 int i2c_read_multiple ( uchar chip, uint addr, int alen,
608                         uchar *buffer, int len)
609 {
610         int i;
611
612         if (alen != 1) {
613                 printf ("%s: addr len other than 1 not supported\n",
614                          __FUNCTION__);
615                 return (1);
616         }
617
618         for (i = 0; i < len; i++) {
619                 if (i2c_read (chip, addr+i, alen, buffer+i, 1)) {
620                         printf ("%s: could not read from i2c device %#x"
621                                  ", addr %d\n", __FUNCTION__, chip, addr);
622                         return (1);
623                 }
624         }
625         return (0);
626 }
627
628
629 static int adc_read (unsigned int channel)
630 {
631         int j = 1000; /* timeout value for wait loop in us */
632         int result;
633         struct s3c2400_adc *padc;
634
635         padc = s3c2400_get_base_adc();
636         channel &= 0x7;
637
638         adc_init ();
639
640         padc->ADCCON &= ~ADC_STDBM; /* select normal mode */
641         padc->ADCCON &= ~(0x7 << 3); /* clear the channel bits */
642         padc->ADCCON |= ((channel << 3) | ADC_ENABLE_START);
643
644         while (j--) {
645                 if ((padc->ADCCON & ADC_ENABLE_START) == 0)
646                         break;
647                 udelay (1);
648         }
649
650         if (j == 0) {
651                 printf("%s: ADC timeout\n", __FUNCTION__);
652                 padc->ADCCON |= ADC_STDBM; /* select standby mode */
653                 return -1;
654         }
655
656         result = padc->ADCDAT & 0x3FF;
657
658         padc->ADCCON |= ADC_STDBM; /* select standby mode */
659
660         debug ("%s: channel %d, result[DIGIT]=%d\n", __FUNCTION__,
661                (padc->ADCCON >> 3) & 0x7, result);
662
663         /*
664          * Wait for ADC to be ready for next conversion. This delay value was
665          * estimated, because the datasheet does not specify a value.
666          */
667         udelay (1000);
668
669         return (result);
670 }
671
672
673 static void adc_init (void)
674 {
675         struct s3c2400_adc *padc;
676
677         padc = s3c2400_get_base_adc();
678
679         padc->ADCCON &= ~(0xff << 6); /* clear prescaler bits */
680         padc->ADCCON |= ((65 << 6) | ADC_PRSCEN); /* set prescaler */
681
682         /*
683          * Wait some time to avoid problem with very first call of
684          * adc_read(). Without this delay, sometimes the first read
685          * adc value is 0. Perhaps because the adjustment of prescaler
686          * takes some clock cycles?
687          */
688         udelay (1000);
689
690         return;
691 }
692
693
694 static void led_set (unsigned int state)
695 {
696         struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
697
698         led_init ();
699
700         switch (state) {
701         case 0: /* turn LED off */
702                 gpio->PADAT |= (1 << 12);
703                 break;
704         case 1: /* turn LED on */
705                 gpio->PADAT &= ~(1 << 12);
706                 break;
707         default:
708                 break;
709         }
710 }
711
712 static void led_blink (void)
713 {
714         led_init ();
715
716         /* blink LED. This function does not return! */
717         while (1) {
718                 reset_timer_masked ();
719                 led_set (1);
720                 udelay (1000000 / LED_BLINK_FREQ / 2);
721                 led_set (0);
722                 udelay (1000000 / LED_BLINK_FREQ / 2);
723         }
724 }
725
726
727 static void led_init (void)
728 {
729         struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
730
731         /* configure GPA12 as output and set to High -> LED off */
732         gpio->PACON &= ~(1 << 12);
733         gpio->PADAT |= (1 << 12);
734 }
735
736
737 static void sdelay (unsigned long seconds)
738 {
739         unsigned long i;
740
741         for (i = 0; i < seconds; i++) {
742                 udelay (1000000);
743         }
744 }
745
746
747 static int global_vars_write_to_eeprom (void)
748 {
749         if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_STATUS, 1,
750                                 (unsigned char*) &status, 1)) {
751                 return (1);
752         }
753         if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_PASS_CYCLES, 1,
754                                 (unsigned char*) &pass_cycles, 2)) {
755                 return (1);
756         }
757         if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_CYCLE,
758                                 1, (unsigned char*) &first_error_cycle, 2)) {
759                 return (1);
760         }
761         if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_NUM,
762                                 1, (unsigned char*) &first_error_num, 1)) {
763                 return (1);
764         }
765         if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_FIRST_ERROR_NAME,
766                                 1, (unsigned char*) first_error_name,
767                                 sizeof(first_error_name))) {
768                 return (1);
769         }
770         return (0);
771 }
772
773 static void global_vars_init (void)
774 {
775         status                  = 1; /* error */
776         pass_cycles             = 0;
777         first_error_cycle       = 0;
778         first_error_num         = 0;
779         first_error_name[0]     = '\0';
780         act_cycle               = 0;
781         max_cycles              = 0;
782 }
783
784
785 static void test_function_table_init (void)
786 {
787         int i;
788
789         for (i = 0; i < BIF_MAX; i++)
790                 test_function[i].pf = dummy;
791
792         /*
793          * the length of "name" must not exceed 16, including the '\0'
794          * termination. See also the EEPROM address map.
795          */
796         test_function[0].pf = test_dip;
797         test_function[0].name = "dip";
798
799         test_function[1].pf = test_vcc5v;
800         test_function[1].name = "vcc5v";
801
802         test_function[2].pf = test_rotary_switch;
803         test_function[2].name = "rotary_switch";
804
805         test_function[3].pf = test_sram;
806         test_function[3].name = "sram";
807
808         test_function[4].pf = test_eeprom;
809         test_function[4].name = "eeprom";
810
811         test_function[5].pf = test_contact_temp;
812         test_function[5].name = "contact_temp";
813 }
814
815
816 static int read_max_cycles (void)
817 {
818         if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, EE_ADDR_MAX_CYCLES, 1,
819                                (unsigned char *) &max_cycles, 2) != 0) {
820                 return (1);
821         }
822
823         return (0);
824 }
825
826 static int dummy(void)
827 {
828         return (0);
829 }
830
831 int do_temp_log (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
832 {
833         int contact_temp;
834         int delay = 0;
835 #if defined(CONFIG_CMD_DATE)
836         struct rtc_time tm;
837 #endif
838
839         if (argc > 2)
840                 return cmd_usage(cmdtp);
841
842         if (argc > 1)
843                 delay = simple_strtoul(argv[1], NULL, 10);
844
845         tsc2000_spi_init ();
846         while (1) {
847
848 #if defined(CONFIG_CMD_DATE)
849                 rtc_get (&tm);
850                 printf ("%4d-%02d-%02d %2d:%02d:%02d - ",
851                         tm.tm_year, tm.tm_mon, tm.tm_mday,
852                         tm.tm_hour, tm.tm_min, tm.tm_sec);
853 #endif
854
855                 contact_temp = tsc2000_contact_temp();
856                 printf ("%d\n", contact_temp) ;
857
858                 if (delay != 0)
859                         /*
860                          * reset timer to avoid timestamp overflow problem
861                          * after about 68 minutes of udelay() time.
862                          */
863                         reset_timer_masked ();
864                         sdelay (delay);
865         }
866
867         return 0;
868 }
869
870 U_BOOT_CMD(
871         tlog,   2,      1,      do_temp_log,
872         "log contact temperature [1/100 C] to console (endlessly)",
873         "delay\n"
874         "    - contact temperature [1/100 C] is printed endlessly to console\n"
875         "      <delay> specifies the seconds to wait between two measurements\n"
876         "      For each measurment a timestamp is printeted"
877 );
878
879 #endif