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