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