source: SVN/rincon/u-boot/board/trab/trab_fkt.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 33.0 KB
Line 
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#define DEBUG
25
26#include <common.h>
27#include <exports.h>
28#include <s3c2400.h>
29#include "tsc2000.h"
30#include "rs485.h"
31
32/*
33 * define, to wait for the touch to be pressed, before reading coordinates in
34 * command do_touch. If not defined, an error message is printed, when the
35 * command do_touch is invoked and the touch is not pressed within an specific
36 * interval.
37 */
38#undef  CONFIG_TOUCH_WAIT_PRESSED
39
40/* max time to wait for touch is pressed */
41#ifndef CONFIG_TOUCH_WAIT_PRESSED
42#define TOUCH_TIMEOUT   5
43#endif /* !CONFIG_TOUCH_WAIT_PRESSED */
44
45/* assignment of CPU internal ADC channels with TRAB hardware */
46#define VCC5V   2
47#define VCC12V  3
48
49/* CPLD-Register for controlling TRAB hardware functions */
50#define CPLD_BUTTONS            ((volatile unsigned long *)0x04020000)
51#define CPLD_FILL_LEVEL         ((volatile unsigned long *)0x04008000)
52#define CPLD_ROTARY_SWITCH      ((volatile unsigned long *)0x04018000)
53#define CPLD_RS485_RE           ((volatile unsigned long *)0x04028000)
54
55/* timer configuration bits for buzzer and PWM */
56#define START2          (1 << 12)
57#define UPDATE2         (1 << 13)
58#define INVERT2         (1 << 14)
59#define RELOAD2         (1 << 15)
60#define START3          (1 << 16)
61#define UPDATE3         (1 << 17)
62#define INVERT3         (1 << 18)
63#define RELOAD3         (1 << 19)
64
65#define PCLK            66000000
66#define BUZZER_FREQ     1000    /* frequency in Hz */
67#define PWM_FREQ        500
68
69
70/* definitions of I2C EEPROM device address */
71#define I2C_EEPROM_DEV_ADDR     0x54
72
73/* definition for touch panel calibration points */
74#define CALIB_TL 0              /* calibration point in (T)op (L)eft corner */
75#define CALIB_DR 1              /* calibration point in (D)own (R)ight corner */
76
77/* EEPROM address map */
78#define SERIAL_NUMBER           8
79#define TOUCH_X0                52
80#define TOUCH_Y0                54
81#define TOUCH_X1                56
82#define TOUCH_Y1                58
83#define CRC16                   60
84
85/* EEPROM stuff */
86#define EEPROM_MAX_CRC_BUF      64
87
88/* RS485 stuff */
89#define RS485_MAX_RECEIVE_BUF_LEN  100
90
91/* Bit definitions for ADCCON */
92#define ADC_ENABLE_START     0x1
93#define ADC_READ_START       0x2
94#define ADC_STDBM            0x4
95#define ADC_INP_AIN0         (0x0 << 3)
96#define ADC_INP_AIN1         (0x1 << 3)
97#define ADC_INP_AIN2         (0x2 << 3)
98#define ADC_INP_AIN3         (0x3 << 3)
99#define ADC_INP_AIN4         (0x4 << 3)
100#define ADC_INP_AIN5         (0x5 << 3)
101#define ADC_INP_AIN6         (0x6 << 3)
102#define ADC_INP_AIN7         (0x7 << 3)
103#define ADC_PRSCEN           0x4000
104#define ADC_ECFLG            0x8000
105
106/* function test functions */
107int do_dip (void);
108int do_info (void);
109int do_vcc5v (void);
110int do_vcc12v (void);
111int do_buttons (void);
112int do_fill_level (void);
113int do_rotary_switch (void);
114int do_pressure (void);
115int do_v_bat (void);
116int do_vfd_id (void);
117int do_buzzer (char **);
118int do_led (char **);
119int do_full_bridge (char **);
120int do_dac (char **);
121int do_motor_contact (void);
122int do_motor (char **);
123int do_pwm (char **);
124int do_thermo (char **);
125int do_touch (char **);
126int do_rs485 (char **);
127int do_serial_number (char **);
128int do_crc16 (void);
129int do_power_switch (void);
130int do_gain (char **);
131int do_eeprom (char **);
132
133/* helper functions */
134static void adc_init (void);
135static int adc_read (unsigned int channel);
136static void print_identifier (void);
137
138#ifdef CONFIG_TOUCH_WAIT_PRESSED
139static void touch_wait_pressed (void);
140#else
141static int touch_check_pressed (void);
142#endif /* CONFIG_TOUCH_WAIT_PRESSED */
143
144static void touch_read_x_y (int *x, int *y);
145static int touch_write_clibration_values (int calib_point, int x, int y);
146static int rs485_send_line (const char *data);
147static int rs485_receive_chars (char *data, int timeout);
148static unsigned short updcrc(unsigned short icrc, unsigned char *icp,
149                             unsigned int icnt);
150
151#if defined(CONFIG_CMD_I2C)
152static int trab_eeprom_read (char **argv);
153static int trab_eeprom_write (char **argv);
154int i2c_write_multiple (uchar chip, uint addr, int alen, uchar *buffer,
155                        int len);
156int i2c_read_multiple ( uchar chip, uint addr, int alen, uchar *buffer,
157                        int len);
158#endif
159
160/*
161 * TRAB board specific commands. Especially commands for burn-in and function
162 * test.
163 */
164
165int trab_fkt (int argc, char *argv[])
166{
167        int i;
168
169        app_startup(argv);
170        if (get_version () != XF_VERSION) {
171                printf ("Wrong XF_VERSION. Please re-compile with actual "
172                        "u-boot sources\n");
173                printf ("Example expects ABI version %d\n", XF_VERSION);
174                printf ("Actual U-Boot ABI version %d\n", (int)get_version());
175                return 1;
176        }
177
178        debug ("argc = %d\n", argc);
179
180        for (i=0; i<=argc; ++i) {
181                debug ("argv[%d] = \"%s\"\n", i, argv[i] ? argv[i] : "<NULL>");
182        }
183
184        adc_init ();
185
186        switch (argc) {
187
188        case 0:
189        case 1:
190                break;
191
192        case 2:
193                if (strcmp (argv[1], "info") == 0) {
194                        return (do_info ());
195                }
196                if (strcmp (argv[1], "dip") == 0) {
197                        return (do_dip ());
198                }
199                if (strcmp (argv[1], "vcc5v") == 0) {
200                        return (do_vcc5v ());
201                }
202                if (strcmp (argv[1], "vcc12v") == 0) {
203                        return (do_vcc12v ());
204                }
205                if (strcmp (argv[1], "buttons") == 0) {
206                        return (do_buttons ());
207                }
208                if (strcmp (argv[1], "fill_level") == 0) {
209                        return (do_fill_level ());
210                }
211                if (strcmp (argv[1], "rotary_switch") == 0) {
212                        return (do_rotary_switch ());
213                }
214                if (strcmp (argv[1], "pressure") == 0) {
215                        return (do_pressure ());
216                }
217                if (strcmp (argv[1], "v_bat") == 0) {
218                        return (do_v_bat ());
219                }
220                if (strcmp (argv[1], "vfd_id") == 0) {
221                        return (do_vfd_id ());
222                }
223                if (strcmp (argv[1], "motor_contact") == 0) {
224                        return (do_motor_contact ());
225                }
226                if (strcmp (argv[1], "crc16") == 0) {
227                        return (do_crc16 ());
228                }
229                if (strcmp (argv[1], "power_switch") == 0) {
230                        return (do_power_switch ());
231                }
232                break;
233
234        case 3:
235                if (strcmp (argv[1], "full_bridge") == 0) {
236                        return (do_full_bridge (argv));
237                }
238                if (strcmp (argv[1], "dac") == 0) {
239                        return (do_dac (argv));
240                }
241                if (strcmp (argv[1], "motor") == 0) {
242                        return (do_motor (argv));
243                }
244                if (strcmp (argv[1], "pwm") == 0) {
245                        return (do_pwm (argv));
246                }
247                if (strcmp (argv[1], "thermo") == 0) {
248                        return (do_thermo (argv));
249                }
250                if (strcmp (argv[1], "touch") == 0) {
251                        return (do_touch (argv));
252                }
253                if (strcmp (argv[1], "serial_number") == 0) {
254                        return (do_serial_number (argv));
255                }
256                if (strcmp (argv[1], "buzzer") == 0) {
257                        return (do_buzzer (argv));
258                }
259                if (strcmp (argv[1], "gain") == 0) {
260                        return (do_gain (argv));
261                }
262                break;
263
264        case 4:
265                if (strcmp (argv[1], "led") == 0) {
266                        return (do_led (argv));
267                }
268                if (strcmp (argv[1], "rs485") == 0) {
269                        return (do_rs485 (argv));
270                }
271                if (strcmp (argv[1], "serial_number") == 0) {
272                        return (do_serial_number (argv));
273                }
274                break;
275
276        case 5:
277                if (strcmp (argv[1], "eeprom") == 0) {
278                        return (do_eeprom (argv));
279                }
280                break;
281
282        case 6:
283                if (strcmp (argv[1], "eeprom") == 0) {
284                        return (do_eeprom (argv));
285                }
286                break;
287
288        default:
289                break;
290        }
291
292        printf ("Usage:\n<command> <parameter1> <parameter2> ...\n");
293        return 1;
294}
295
296int do_info (void)
297{
298        printf ("Stand-alone application for TRAB board function test\n");
299        printf ("Built: %s at %s\n", __DATE__ , __TIME__ );
300
301        return 0;
302}
303
304int do_dip (void)
305{
306        unsigned int result = 0;
307        int adc_val;
308        int i;
309
310        /***********************************************************
311         DIP switch connection (according to wa4-cpu.sp.301.pdf, page 3):
312           SW1 - AIN4
313           SW2 - AIN5
314           SW3 - AIN6
315           SW4 - AIN7
316
317           "On" DIP switch position short-circuits the voltage from
318           the input channel (i.e. '0' conversion result means "on").
319        *************************************************************/
320
321        for (i = 7; i > 3; i--) {
322
323                if ((adc_val = adc_read (i)) == -1) {
324                        printf ("Channel %d could not be read\n", i);
325                        return 1;
326                }
327
328                /*
329                 * Input voltage (switch open) is 1.8 V.
330                 * (Vin_High/VRef)*adc_res = (1,8V/2,5V)*1023) = 736
331                 * Set trigger at halve that value.
332                 */
333                if (adc_val < 368)
334                        result |= (1 << (i-4));
335        }
336
337        /* print result to console */
338        print_identifier ();
339        for (i = 0; i < 4; i++) {
340                if ((result & (1 << i)) == 0)
341                        printf("0");
342                else
343                        printf("1");
344        }
345        printf("\n");
346
347        return 0;
348}
349
350
351int do_vcc5v (void)
352{
353        int result;
354
355        /* VCC5V is connected to channel 2 */
356
357        if ((result = adc_read (VCC5V)) == -1) {
358                printf ("VCC5V could not be read\n");
359                return 1;
360        }
361
362        /*
363         * Calculate voltage value. Split in two parts because there is no
364         * floating point support.  VCC5V is connected over an resistor divider:
365         * VCC5V=ADCval*2,5V/1023*(10K+30K)/10K.
366         */
367        print_identifier ();
368        printf ("%d", (result & 0x3FF)* 10 / 1023);
369        printf (".%d", ((result & 0x3FF)* 10 % 1023)* 10 / 1023);
370        printf ("%d V\n", (((result & 0x3FF) * 10 % 1023 ) * 10 % 1023)
371                * 10 / 1024);
372
373        return 0;
374}
375
376
377int do_vcc12v (void)
378{
379        int result;
380
381        if ((result = adc_read (VCC12V)) == -1) {
382                printf ("VCC12V could not be read\n");
383                return 1;
384        }
385
386        /*
387         * Calculate voltage value. Split in two parts because there is no
388         * floating point support.  VCC5V is connected over an resistor divider:
389         * VCC12V=ADCval*2,5V/1023*(30K+270K)/30K.
390         */
391        print_identifier ();
392        printf ("%d", (result & 0x3FF)* 25 / 1023);
393        printf (".%d V\n", ((result & 0x3FF)* 25 % 1023) * 10 / 1023);
394
395        return 0;
396}
397
398static int adc_read (unsigned int channel)
399{
400        int j = 1000; /* timeout value for wait loop in us */
401        int result;
402        S3C2400_ADC *padc;
403
404        padc = S3C2400_GetBase_ADC();
405        channel &= 0x7;
406
407        padc->ADCCON &= ~ADC_STDBM; /* select normal mode */
408        padc->ADCCON &= ~(0x7 << 3); /* clear the channel bits */
409        padc->ADCCON |= ((channel << 3) | ADC_ENABLE_START);
410
411        while (j--) {
412                if ((padc->ADCCON & ADC_ENABLE_START) == 0)
413                        break;
414                udelay (1);
415        }
416
417        if (j == 0) {
418                printf("%s: ADC timeout\n", __FUNCTION__);
419                padc->ADCCON |= ADC_STDBM; /* select standby mode */
420                return -1;
421        }
422
423        result = padc->ADCDAT & 0x3FF;
424
425        padc->ADCCON |= ADC_STDBM; /* select standby mode */
426
427        debug ("%s: channel %d, result[DIGIT]=%d\n", __FUNCTION__,
428               (padc->ADCCON >> 3) & 0x7, result);
429
430        /*
431         * Wait for ADC to be ready for next conversion. This delay value was
432         * estimated, because the datasheet does not specify a value.
433         */
434        udelay (1000);
435
436        return (result);
437}
438
439
440static void adc_init (void)
441{
442        S3C2400_ADC *padc;
443
444        padc = S3C2400_GetBase_ADC();
445
446        padc->ADCCON &= ~(0xff << 6); /* clear prescaler bits */
447        padc->ADCCON |= ((65 << 6) | ADC_PRSCEN); /* set prescaler */
448
449        /*
450         * Wait some time to avoid problem with very first call of
451         * adc_read(). Without * this delay, sometimes the first read adc
452         * value is 0. Perhaps because the * adjustment of prescaler takes
453         * some clock cycles?
454         */
455        udelay (1000);
456
457        return;
458}
459
460
461int do_buttons (void)
462{
463        int result;
464        int i;
465
466        result = *CPLD_BUTTONS; /* read CPLD */
467        debug ("%s: cpld_taster (32 bit) %#x\n", __FUNCTION__, result);
468
469        /* print result to console */
470        print_identifier ();
471        for (i = 16; i <= 19; i++) {
472                if ((result & (1 << i)) == 0)
473                        printf("0");
474                else
475                        printf("1");
476        }
477        printf("\n");
478        return 0;
479}
480
481
482int do_power_switch (void)
483{
484        int result;
485
486        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
487
488        /* configure GPE7 as input */
489        gpio->PECON &= ~(0x3 << (2 * 7));
490
491        /* signal GPE7 from power switch is low active: 0=on , 1=off */
492        result = ((gpio->PEDAT & (1 << 7)) == (1 << 7)) ? 0 : 1;
493
494        print_identifier ();
495        printf("%d\n", result);
496        return 0;
497}
498
499
500int do_fill_level (void)
501{
502        int result;
503
504        result = *CPLD_FILL_LEVEL; /* read CPLD */
505        debug ("%s: cpld_fuellstand (32 bit) %#x\n", __FUNCTION__, result);
506
507        /* print result to console */
508        print_identifier ();
509        if ((result & (1 << 16)) == 0)
510                printf("0\n");
511        else
512                printf("1\n");
513        return 0;
514}
515
516
517int do_rotary_switch (void)
518{
519        int result;
520        /*
521         * Please note, that the default values of the direction bits are
522         * undefined after reset. So it is a good idea, to make first a dummy
523         * call to this function, to clear the direction bits and set so to
524         * proper values.
525         */
526
527        result = *CPLD_ROTARY_SWITCH; /* read CPLD */
528        debug ("%s: cpld_inc (32 bit) %#x\n", __FUNCTION__, result);
529
530        *CPLD_ROTARY_SWITCH |= (3 << 16); /* clear direction bits in CPLD */
531
532        /* print result to console */
533        print_identifier ();
534        if ((result & (1 << 16)) == (1 << 16))
535                printf("R");
536        if ((result & (1 << 17)) == (1 << 17))
537                printf("L");
538        if (((result & (1 << 16)) == 0) && ((result & (1 << 17)) == 0))
539                printf("0");
540        if ((result & (1 << 18)) == 0)
541                printf("0\n");
542        else
543                printf("1\n");
544        return 0;
545}
546
547
548int do_vfd_id (void)
549{
550        int i;
551        long int pcup_old, pccon_old;
552        int vfd_board_id;
553        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
554
555        /* try to red vfd board id from the value defined by pull-ups */
556
557        pcup_old = gpio->PCUP;
558        pccon_old = gpio->PCCON;
559
560        gpio->PCUP = (gpio->PCUP & 0xFFF0); /* activate  GPC0...GPC3 pull-ups */
561        gpio->PCCON = (gpio->PCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as
562                                                   * inputs */
563        udelay (10);            /* allow signals to settle */
564        vfd_board_id = (~gpio->PCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
565
566        gpio->PCCON = pccon_old;
567        gpio->PCUP = pcup_old;
568
569        /* print vfd_board_id to console */
570        print_identifier ();
571        for (i = 0; i < 4; i++) {
572                if ((vfd_board_id & (1 << i)) == 0)
573                        printf("0");
574                else
575                        printf("1");
576        }
577        printf("\n");
578        return 0;
579}
580
581int do_buzzer (char **argv)
582{
583        int counter;
584
585        S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
586        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
587
588        /* set prescaler for timer 2, 3 and 4 */
589        timers->TCFG0 &= ~0xFF00;
590        timers->TCFG0 |=  0x0F00;
591
592        /* set divider for timer 2 */
593        timers->TCFG1 &= ~0xF00;
594        timers->TCFG1 |=  0x300;
595
596        /* set frequency */
597        counter = (PCLK / BUZZER_FREQ) >> 9;
598        timers->ch[2].TCNTB = counter;
599        timers->ch[2].TCMPB = counter / 2;
600
601        if (strcmp (argv[2], "on") == 0) {
602                debug ("%s: frequency: %d\n", __FUNCTION__,
603                       BUZZER_FREQ);
604
605                /* configure pin GPD7 as TOUT2 */
606                gpio->PDCON &= ~0xC000;
607                gpio->PDCON |= 0x8000;
608
609                /* start */
610                timers->TCON = (timers->TCON | UPDATE2 | RELOAD2) &
611                                ~INVERT2;
612                timers->TCON = (timers->TCON | START2) & ~UPDATE2;
613                return (0);
614        }
615        else if (strcmp (argv[2], "off") == 0) {
616                /* stop */
617                timers->TCON &= ~(START2 | RELOAD2);
618
619                /* configure GPD7 as output and set to low */
620                gpio->PDCON &= ~0xC000;
621                gpio->PDCON |= 0x4000;
622                gpio->PDDAT &= ~0x80;
623                return (0);
624        }
625
626        printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
627        return 1;
628}
629
630
631int do_led (char **argv)
632{
633        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
634
635        /* configure PC14 and PC15 as output */
636        gpio->PCCON &= ~(0xF << 28);
637        gpio->PCCON |= (0x5 << 28);
638
639        /* configure PD0 and PD4 as output */
640        gpio->PDCON &= ~((0x3 << 8) | 0x3);
641        gpio->PDCON |= ((0x1 << 8) | 0x1);
642
643        switch (simple_strtoul(argv[2], NULL, 10)) {
644
645        case 0:
646        case 1:
647                break;
648
649        case 2:
650                if (strcmp (argv[3], "on") == 0)
651                        gpio->PCDAT |= (1 << 14);
652                else
653                        gpio->PCDAT &= ~(1 << 14);
654                return 0;
655
656        case 3:
657                if (strcmp (argv[3], "on") == 0)
658                        gpio->PCDAT |= (1 << 15);
659                else
660                        gpio->PCDAT &= ~(1 << 15);
661                return 0;
662
663        case 4:
664                if (strcmp (argv[3], "on") == 0)
665                        gpio->PDDAT |= (1 << 0);
666                else
667                        gpio->PDDAT &= ~(1 << 0);
668                return 0;
669
670        case 5:
671                if (strcmp (argv[3], "on") == 0)
672                        gpio->PDDAT |= (1 << 4);
673                else
674                        gpio->PDDAT &= ~(1 << 4);
675                return 0;
676
677        default:
678                break;
679
680        }
681        printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
682        return 1;
683}
684
685
686int do_full_bridge (char **argv)
687{
688        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
689
690        /* configure PD5 and PD6 as output */
691        gpio->PDCON &= ~((0x3 << 5*2) | (0x3 << 6*2));
692        gpio->PDCON |= ((0x1 << 5*2) | (0x1 << 6*2));
693
694        if (strcmp (argv[2], "+") == 0) {
695              gpio->PDDAT |= (1 << 5);
696              gpio->PDDAT |= (1 << 6);
697              return 0;
698        }
699        else if (strcmp (argv[2], "-") == 0) {
700                gpio->PDDAT &= ~(1 << 5);
701                gpio->PDDAT |= (1 << 6);
702                return 0;
703        }
704        else if (strcmp (argv[2], "off") == 0) {
705                gpio->PDDAT &= ~(1 << 5);
706                gpio->PDDAT &= ~(1 << 6);
707                return 0;
708        }
709        printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
710        return 1;
711}
712
713/* val must be in [0, 4095] */
714static inline unsigned long tsc2000_to_uv (u16 val)
715{
716        return ((250000 * val) / 4096) * 10;
717}
718
719
720int do_dac (char **argv)
721{
722        int brightness;
723
724        /* initialize SPI */
725        spi_init ();
726
727        if  (((brightness = simple_strtoul (argv[2], NULL, 10)) < 0) ||
728             (brightness > 255)) {
729                printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
730                return 1;
731        }
732        tsc2000_write(TSC2000_REG_DACCTL, 0x0); /* Power up DAC */
733        tsc2000_write(TSC2000_REG_DAC, brightness & 0xff);
734
735        return 0;
736}
737
738
739int do_v_bat (void)
740{
741        unsigned long ret, res;
742
743        /* initialize SPI */
744        spi_init ();
745
746        tsc2000_write(TSC2000_REG_ADC, 0x1836);
747
748        /* now wait for data available */
749        adc_wait_conversion_done();
750
751        ret = tsc2000_read(TSC2000_REG_BAT1);
752        res = (tsc2000_to_uv(ret) + 1250) / 2500;
753        res += (ERROR_BATTERY * res) / 1000;
754
755        print_identifier ();
756        printf ("%ld", (res / 100));
757        printf (".%ld", ((res % 100) / 10));
758        printf ("%ld V\n", (res % 10));
759        return 0;
760}
761
762
763int do_pressure (void)
764{
765        /* initialize SPI */
766        spi_init ();
767
768        tsc2000_write(TSC2000_REG_ADC, 0x2436);
769
770        /* now wait for data available */
771        adc_wait_conversion_done();
772
773        print_identifier ();
774        printf ("%d\n", tsc2000_read(TSC2000_REG_AUX2));
775        return 0;
776}
777
778
779int do_motor_contact (void)
780{
781        int result;
782
783        result = *CPLD_FILL_LEVEL; /* read CPLD */
784        debug ("%s: cpld_fuellstand (32 bit) %#x\n", __FUNCTION__, result);
785
786        /* print result to console */
787        print_identifier ();
788        if ((result & (1 << 17)) == 0)
789                printf("0\n");
790        else
791                printf("1\n");
792        return 0;
793}
794
795int do_motor (char **argv)
796{
797        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
798
799        /* Configure I/O port */
800        gpio->PGCON &= ~(0x3 << 0);
801        gpio->PGCON |= (0x1 << 0);
802
803        if (strcmp (argv[2], "on") == 0) {
804                gpio->PGDAT &= ~(1 << 0);
805                return 0;
806        }
807        if (strcmp (argv[2], "off") == 0) {
808                gpio->PGDAT |= (1 << 0);
809                return 0;
810        }
811        printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
812        return 1;
813}
814
815static void print_identifier (void)
816{
817        printf ("## FKT: ");
818}
819
820int do_pwm (char **argv)
821{
822        int counter;
823        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
824        S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
825
826        if (strcmp (argv[2], "on") == 0) {
827                /* configure pin GPD8 as TOUT3 */
828                gpio->PDCON &= ~(0x3 << 8*2);
829                gpio->PDCON |= (0x2 << 8*2);
830
831                /* set prescaler for timer 2, 3 and 4 */
832                timers->TCFG0 &= ~0xFF00;
833                timers->TCFG0 |= 0x0F00;
834
835                /* set divider for timer 3 */
836                timers->TCFG1 &= ~(0xf << 12);
837                timers->TCFG1 |= (0x3 << 12);
838
839                /* set frequency */
840                counter = (PCLK / PWM_FREQ) >> 9;
841                timers->ch[3].TCNTB = counter;
842                timers->ch[3].TCMPB = counter / 2;
843
844                /* start timer */
845                timers->TCON = (timers->TCON | UPDATE3 | RELOAD3) & ~INVERT3;
846                timers->TCON = (timers->TCON | START3) & ~UPDATE3;
847                return 0;
848        }
849        if (strcmp (argv[2], "off") == 0) {
850
851                /* stop timer */
852                timers->TCON &= ~(START2 | RELOAD2);
853
854                /* configure pin GPD8 as output and set to 0 */
855                gpio->PDCON &= ~(0x3 << 8*2);
856                gpio->PDCON |= (0x1 << 8*2);
857                gpio->PDDAT &= ~(1 << 8);
858                return 0;
859        }
860        printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
861        return 1;
862}
863
864
865int do_thermo (char **argv)
866{
867        int     channel, res;
868
869        tsc2000_reg_init ();
870
871        if (strcmp (argv[2], "all") == 0) {
872                int i;
873                for (i=0; i <= 15; i++) {
874                        res = tsc2000_read_channel(i);
875                        print_identifier ();
876                        printf ("c%d: %d\n", i, res);
877                }
878                return 0;
879        }
880        channel = simple_strtoul (argv[2], NULL, 10);
881        res = tsc2000_read_channel(channel);
882        print_identifier ();
883        printf ("%d\n", res);
884        return 0;                 /* return OK */
885}
886
887
888int do_touch (char **argv)
889{
890        int     x, y;
891
892        if (strcmp (argv[2], "tl") == 0) {
893#ifdef CONFIG_TOUCH_WAIT_PRESSED
894                touch_wait_pressed();
895#else
896                {
897                        int i;
898                        for (i = 0; i < (TOUCH_TIMEOUT * 1000); i++) {
899                                if (touch_check_pressed ()) {
900                                        break;
901                                }
902                                udelay (1000);  /* pause 1 ms */
903                        }
904                }
905                if (!touch_check_pressed()) {
906                        print_identifier ();
907                        printf ("error: touch not pressed\n");
908                        return 1;
909                }
910#endif /* CONFIG_TOUCH_WAIT_PRESSED */
911                touch_read_x_y (&x, &y);
912
913                print_identifier ();
914                printf ("x=%d y=%d\n", x, y);
915                return touch_write_clibration_values (CALIB_TL, x, y);
916        }
917        else if (strcmp (argv[2], "dr") == 0) {
918#ifdef CONFIG_TOUCH_WAIT_PRESSED
919                touch_wait_pressed();
920#else
921                {
922                        int i;
923                        for (i = 0; i < (TOUCH_TIMEOUT * 1000); i++) {
924                                if (touch_check_pressed ()) {
925                                        break;
926                                }
927                                udelay (1000);  /* pause 1 ms */
928                        }
929                }
930                if (!touch_check_pressed()) {
931                        print_identifier ();
932                        printf ("error: touch not pressed\n");
933                        return 1;
934                }
935#endif /* CONFIG_TOUCH_WAIT_PRESSED */
936                touch_read_x_y (&x, &y);
937
938                print_identifier ();
939                printf ("x=%d y=%d\n", x, y);
940
941                return touch_write_clibration_values (CALIB_DR, x, y);
942        }
943        return 1;                 /* not "tl", nor "dr", so return error */
944}
945
946
947#ifdef CONFIG_TOUCH_WAIT_PRESSED
948static void touch_wait_pressed (void)
949{
950        while (!(tsc2000_read(TSC2000_REG_ADC) & TC_PSM));
951}
952
953#else
954static int touch_check_pressed (void)
955{
956        return (tsc2000_read(TSC2000_REG_ADC) & TC_PSM);
957}
958#endif /* CONFIG_TOUCH_WAIT_PRESSED */
959
960static int touch_write_clibration_values (int calib_point, int x, int y)
961{
962#if defined(CONFIG_CMD_I2C)
963        int x_verify = 0;
964        int y_verify = 0;
965
966        tsc2000_reg_init ();
967
968        if (calib_point == CALIB_TL) {
969                if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X0, 1,
970                               (unsigned char *)&x, 2)) {
971                        return 1;
972                }
973                if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y0, 1,
974                               (unsigned char *)&y, 2)) {
975                        return 1;
976                }
977
978                /* verify written values */
979                if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X0, 1,
980                              (unsigned char *)&x_verify, 2)) {
981                        return 1;
982                }
983                if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y0, 1,
984                               (unsigned char *)&y_verify, 2)) {
985                        return 1;
986                }
987                if ((y != y_verify) || (x != x_verify)) {
988                        print_identifier ();
989                        printf ("error: verify error\n");
990                        return 1;
991                }
992                return 0;       /* no error */
993        }
994        else if (calib_point == CALIB_DR) {
995                  if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X1, 1,
996                               (unsigned char *)&x, 2)) {
997                        return 1;
998                  }
999                if (i2c_write_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y1, 1,
1000                               (unsigned char *)&y, 2)) {
1001                        return 1;
1002                }
1003
1004                /* verify written values */
1005                if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_X1, 1,
1006                                       (unsigned char *)&x_verify, 2)) {
1007                        return 1;
1008                }
1009                if (i2c_read_multiple (I2C_EEPROM_DEV_ADDR, TOUCH_Y1, 1,
1010                               (unsigned char *)&y_verify, 2)) {
1011                        return 1;
1012                }
1013                if ((y != y_verify) || (x != x_verify)) {
1014                        print_identifier ();
1015                        printf ("error: verify error\n");
1016                        return 1;
1017                }
1018                return 0;
1019        }
1020        return 1;
1021#else
1022        printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1023                "to EEPROM\n");
1024        return (1);
1025#endif
1026}
1027
1028
1029static void touch_read_x_y (int *px, int *py)
1030{
1031        tsc2000_write(TSC2000_REG_ADC, DEFAULT_ADC | TC_AD0 | TC_AD1);
1032        adc_wait_conversion_done();
1033        *px = tsc2000_read(TSC2000_REG_X);
1034
1035        tsc2000_write(TSC2000_REG_ADC, DEFAULT_ADC | TC_AD2);
1036        adc_wait_conversion_done();
1037        *py = tsc2000_read(TSC2000_REG_Y);
1038}
1039
1040
1041int do_rs485 (char **argv)
1042{
1043        int timeout;
1044        char data[RS485_MAX_RECEIVE_BUF_LEN];
1045
1046        if (strcmp (argv[2], "send") == 0) {
1047                return (rs485_send_line (argv[3]));
1048        }
1049        else if (strcmp (argv[2], "receive") == 0) {
1050                timeout = simple_strtoul(argv[3], NULL, 10);
1051                if (rs485_receive_chars (data, timeout) != 0) {
1052                        print_identifier ();
1053                        printf ("## nothing received\n");
1054                        return (1);
1055                }
1056                else {
1057                        print_identifier ();
1058                        printf ("%s\n", data);
1059                        return (0);
1060                }
1061        }
1062        printf ("%s: unknown command %s\n", __FUNCTION__, argv[2]);
1063        return (1);             /* unknown command, return error */
1064}
1065
1066
1067static int rs485_send_line (const char *data)
1068{
1069        rs485_init ();
1070        trab_rs485_enable_tx ();
1071        rs485_puts (data);
1072        rs485_putc ('\n');
1073
1074        return (0);
1075}
1076
1077
1078static int rs485_receive_chars (char *data, int timeout)
1079{
1080        int i;
1081        int receive_count = 0;
1082
1083        rs485_init ();
1084        trab_rs485_enable_rx ();
1085
1086        /* test every 1 ms for received characters to avoid a receive FIFO
1087         * overrun (@ 38.400 Baud) */
1088        for (i = 0; i < (timeout * 1000); i++) {
1089                while (rs485_tstc ()) {
1090                        if (receive_count >= RS485_MAX_RECEIVE_BUF_LEN-1)
1091                                break;
1092                        *data++ = rs485_getc ();
1093                        receive_count++;
1094                }
1095                udelay (1000);  /* pause 1 ms */
1096        }
1097        *data = '\0';           /* terminate string */
1098
1099        if (receive_count == 0)
1100                return (1);
1101        else
1102                return (0);
1103}
1104
1105
1106int do_serial_number (char **argv)
1107{
1108#if defined(CONFIG_CMD_I2C)
1109        unsigned int serial_number;
1110
1111        if (strcmp (argv[2], "read") == 0) {
1112                if (i2c_read (I2C_EEPROM_DEV_ADDR, SERIAL_NUMBER, 1,
1113                              (unsigned char *)&serial_number, 4)) {
1114                        printf ("could not read from eeprom\n");
1115                        return (1);
1116                }
1117                print_identifier ();
1118                printf ("%08d\n", serial_number);
1119                return (0);
1120        }
1121        else if (strcmp (argv[2], "write") == 0) {
1122                serial_number = simple_strtoul(argv[3], NULL, 10);
1123                if (i2c_write (I2C_EEPROM_DEV_ADDR, SERIAL_NUMBER, 1,
1124                              (unsigned char *)&serial_number, 4)) {
1125                        printf ("could not write to eeprom\n");
1126                        return (1);
1127                }
1128                return (0);
1129        }
1130        printf ("%s: unknown command %s\n", __FUNCTION__, argv[2]);
1131        return (1);             /* unknown command, return error */
1132#else
1133        printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1134                "to EEPROM\n");
1135        return (1);
1136#endif
1137}
1138
1139
1140int do_crc16 (void)
1141{
1142#if defined(CONFIG_CMD_I2C)
1143        int crc;
1144        unsigned char buf[EEPROM_MAX_CRC_BUF];
1145
1146        if (i2c_read (I2C_EEPROM_DEV_ADDR, 0, 1, buf, 60)) {
1147                printf ("could not read from eeprom\n");
1148                return (1);
1149        }
1150        crc = 0;                /* start value of crc calculation */
1151        crc = updcrc (crc, buf, 60);
1152
1153        print_identifier ();
1154        printf ("crc16=%#04x\n", crc);
1155
1156        if (i2c_write (I2C_EEPROM_DEV_ADDR, CRC16, 1, (unsigned char *)&crc,
1157                       sizeof (crc))) {
1158                printf ("could not read from eeprom\n");
1159                return (1);
1160        }
1161        return (0);
1162#else
1163        printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1164                "to EEPROM\n");
1165        return (1);
1166#endif
1167}
1168
1169
1170/*
1171 * Calculate, intelligently, the CRC of a dataset incrementally given a
1172 * buffer full at a time.
1173 * Initialize crc to 0 for XMODEM, -1 for CCITT.
1174 *
1175 * Usage:
1176 *   newcrc = updcrc( oldcrc, bufadr, buflen )
1177 *        unsigned int oldcrc, buflen;
1178 *        char *bufadr;
1179 *
1180 * Compile with -DTEST to generate program that prints CRC of stdin to stdout.
1181 * Compile with -DMAKETAB to print values for crctab to stdout
1182 */
1183
1184    /* the CRC polynomial. This is used by XMODEM (almost CCITT).
1185     * If you change P, you must change crctab[]'s initial value to what is
1186     * printed by initcrctab()
1187     */
1188#define   P    0x1021
1189
1190    /* number of bits in CRC: don't change it. */
1191#define W 16
1192
1193    /* this the number of bits per char: don't change it. */
1194#define B 8
1195
1196static unsigned short crctab[1<<B] = { /* as calculated by initcrctab() */
1197    0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
1198    0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
1199    0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
1200    0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
1201    0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
1202    0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
1203    0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
1204    0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
1205    0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
1206    0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
1207    0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
1208    0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
1209    0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
1210    0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
1211    0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
1212    0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
1213    0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
1214    0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
1215    0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
1216    0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
1217    0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
1218    0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
1219    0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
1220    0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
1221    0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
1222    0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
1223    0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
1224    0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
1225    0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
1226    0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
1227    0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
1228    0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
1229    };
1230
1231static unsigned short updcrc(unsigned short icrc, unsigned char *icp,
1232                             unsigned int icnt )
1233{
1234        register unsigned short crc = icrc;
1235        register unsigned char *cp = icp;
1236        register unsigned int cnt = icnt;
1237
1238        while (cnt--)
1239                crc = (crc<<B) ^ crctab[(crc>>(W-B)) ^ *cp++];
1240
1241        return (crc);
1242}
1243
1244
1245int do_gain (char **argv)
1246{
1247        int range;
1248
1249        range = simple_strtoul (argv[2], NULL, 10);
1250        if ((range < 1) || (range > 3))
1251        {
1252                printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
1253                return 1;
1254        }
1255
1256        tsc2000_set_range (range);
1257        return (0);
1258}
1259
1260
1261int do_eeprom (char **argv)
1262{
1263#if defined(CONFIG_CMD_I2C)
1264        if (strcmp (argv[2], "read") == 0) {
1265                return (trab_eeprom_read (argv));
1266        }
1267
1268        else if (strcmp (argv[2], "write") == 0) {
1269                return (trab_eeprom_write (argv));
1270        }
1271
1272        printf ("%s: invalid parameter %s\n", __FUNCTION__, argv[2]);
1273        return (1);
1274#else
1275        printf ("No I2C support enabled (CONFIG_CMD_I2C), could not write "
1276                "to EEPROM\n");
1277        return (1);
1278#endif
1279}
1280
1281#if defined(CONFIG_CMD_I2C)
1282static int trab_eeprom_read (char **argv)
1283{
1284        int i;
1285        int len;
1286        unsigned int addr;
1287        long int value = 0;
1288        uchar *buffer;
1289
1290        buffer = (uchar *) &value;
1291        addr = simple_strtoul (argv[3], NULL, 10);
1292        addr &= 0xfff;
1293        len = simple_strtoul (argv[4], NULL, 10);
1294        if ((len < 1) || (len > 4)) {
1295                printf ("%s: invalid parameter %s\n", __FUNCTION__,
1296                        argv[4]);
1297                return (1);
1298        }
1299        for (i = 0; i < len; i++) {
1300                if (i2c_read (I2C_EEPROM_DEV_ADDR, addr+i, 1, buffer+i, 1)) {
1301                        printf ("%s: could not read from i2c device %#x"
1302                                ", addr %d\n", __FUNCTION__,
1303                                I2C_EEPROM_DEV_ADDR, addr);
1304                        return (1);
1305                }
1306        }
1307        print_identifier ();
1308        if (strcmp (argv[5], "-") == 0) {
1309                if (len == 1)
1310                        printf ("%d\n", (signed char) value);
1311                else if (len == 2)
1312                        printf ("%d\n", (signed short int) value);
1313                else
1314                        printf ("%ld\n", value);
1315        }
1316        else {
1317                if (len == 1)
1318                        printf ("%d\n", (unsigned char) value);
1319                else if (len == 2)
1320                        printf ("%d\n", (unsigned short int) value);
1321                else
1322                        printf ("%ld\n", (unsigned long int) value);
1323        }
1324        return (0);
1325}
1326
1327static int trab_eeprom_write (char **argv)
1328{
1329        int i;
1330        int len;
1331        unsigned int addr;
1332        long int value = 0;
1333        uchar *buffer;
1334
1335        buffer = (uchar *) &value;
1336        addr = simple_strtoul (argv[3], NULL, 10);
1337        addr &= 0xfff;
1338        len = simple_strtoul (argv[4], NULL, 10);
1339        if ((len < 1) || (len > 4)) {
1340                printf ("%s: invalid parameter %s\n", __FUNCTION__,
1341                        argv[4]);
1342                return (1);
1343        }
1344        value = simple_strtol (argv[5], NULL, 10);
1345        debug ("value=%ld\n", value);
1346        for (i = 0; i < len; i++) {
1347                if (i2c_write (I2C_EEPROM_DEV_ADDR, addr+i, 1, buffer+i, 1)) {
1348                        printf ("%s: could not write to i2c device %d"
1349                                ", addr %d\n", __FUNCTION__,
1350                                I2C_EEPROM_DEV_ADDR, addr);
1351                        return (1);
1352                }
1353#if 0
1354                printf ("chip=%#x, addr+i=%#x+%d=%p, alen=%d, *buffer+i="
1355                        "%#x+%d=%p=%#x \n",I2C_EEPROM_DEV_ADDR_DEV_ADDR , addr,
1356                        i, addr+i, 1, buffer, i, buffer+i, *(buffer+i));
1357#endif
1358                udelay (30000); /* wait for EEPROM ready */
1359        }
1360        return (0);
1361}
1362
1363int i2c_write_multiple (uchar chip, uint addr, int alen,
1364                        uchar *buffer, int len)
1365{
1366        int i;
1367
1368        if (alen != 1) {
1369                printf ("%s: addr len other than 1 not supported\n",
1370                         __FUNCTION__);
1371                return (1);
1372        }
1373
1374        for (i = 0; i < len; i++) {
1375                if (i2c_write (chip, addr+i, alen, buffer+i, 1)) {
1376                        printf ("%s: could not write to i2c device %d"
1377                                 ", addr %d\n", __FUNCTION__, chip, addr);
1378                        return (1);
1379                }
1380#if 0
1381                printf ("chip=%#x, addr+i=%#x+%d=%p, alen=%d, *buffer+i="
1382                        "%#x+%d=%p=\"%.1s\"\n", chip, addr, i, addr+i,
1383                        alen, buffer, i, buffer+i, buffer+i);
1384#endif
1385
1386                udelay (30000);
1387        }
1388        return (0);
1389}
1390
1391int i2c_read_multiple ( uchar chip, uint addr, int alen,
1392                        uchar *buffer, int len)
1393{
1394        int i;
1395
1396        if (alen != 1) {
1397                printf ("%s: addr len other than 1 not supported\n",
1398                         __FUNCTION__);
1399                return (1);
1400        }
1401
1402        for (i = 0; i < len; i++) {
1403                if (i2c_read (chip, addr+i, alen, buffer+i, 1)) {
1404                        printf ("%s: could not read from i2c device %#x"
1405                                 ", addr %d\n", __FUNCTION__, chip, addr);
1406                        return (1);
1407                }
1408        }
1409        return (0);
1410}
1411#endif
Note: See TracBrowser for help on using the repository browser.