Changeset 2467

Show
Ignore:
Timestamp:
04/22/04 21:47:08 (9 years ago)
Author:
khali
Message:

Move i2c device opening to a separate function.

Move actual scanning to a separate function.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/prog/detect/i2cdetect.c

    r2465 r2467  
    22    i2cdetect.c - Part of i2cdetect, a user-space program to scan for I2C  
    33                  devices. 
    4     Copyright (c) 1999-2004  Frodo Looijaard <frodol@dds.nl> and 
    5                              Mark D. Studebaker <mdsxyz123@yahoo.com> 
     4    Copyright (C) 1999-2004  Frodo Looijaard <frodol@dds.nl>, 
     5                             Mark D. Studebaker <mdsxyz123@yahoo.com> and 
     6                             Jean Delvare <khali@linux-fr.org> 
    67 
    78    This program is free software; you can redistribute it and/or modify 
     
    4647} 
    4748 
     49int open_i2c_dev(const int i2cbus, char *filename) 
     50{ 
     51        int file; 
     52 
     53        sprintf(filename, "/dev/i2c-%d", i2cbus); 
     54        file = open(filename, O_RDWR); 
     55 
     56        if (file >= 0 || errno != ENOENT) { 
     57                return file; 
     58        } 
     59 
     60        sprintf(filename, "/dev/i2c/%d", i2cbus); 
     61        file = open(filename, O_RDWR); 
     62         
     63        return file; 
     64} 
     65 
     66int scan_i2c_bus(int file, const int mode, const int first, const int last) 
     67{ 
     68        int i, j; 
     69        int res; 
     70 
     71        printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n"); 
     72 
     73        for (i = 0; i < 128; i += 16) { 
     74                printf("%02x: ", i); 
     75                for(j = 0; j < 16; j++) { 
     76                        /* Skip unwanted addresses */ 
     77                        if (i+j < first || i+j > last) { 
     78                                printf("   "); 
     79                                continue; 
     80                        } 
     81 
     82                        /* Set slave address */ 
     83                        if (ioctl(file, I2C_SLAVE, i+j) < 0) { 
     84                                if (errno == EBUSY) { 
     85                                        printf("UU "); 
     86                                        continue; 
     87                                } else { 
     88                                        fprintf(stderr, 
     89                                                "Error: Could not set address to 0x%02x: %s\n", 
     90                                                i+j, strerror(errno)); 
     91                                        return -1; 
     92                                } 
     93                        } 
     94 
     95                        /* Probe this address */ 
     96                        switch (mode) { 
     97                        case MODE_QUICK: 
     98                                /* This is known to corrupt the Atmel AT24RF08 EEPROM */ 
     99                                res = i2c_smbus_write_quick(file, I2C_SMBUS_WRITE); 
     100                                break; 
     101                        case MODE_READ: 
     102                                /* This is known to lock SMBus on various write-only chips 
     103                                (mainly clock chips) */ 
     104                                res = i2c_smbus_read_byte(file); 
     105                                break; 
     106                        default: 
     107                                if ((i+j >= 0x30 && i+j <= 0x37) 
     108                                 || (i+j >= 0x50 && i+j <= 0x5F)) 
     109                                        res = i2c_smbus_write_quick(file, I2C_SMBUS_WRITE); 
     110                                else 
     111                                        res = i2c_smbus_read_byte(file); 
     112                        } 
     113 
     114                        if (res < 0) 
     115                                printf("XX "); 
     116                        else 
     117                                printf("%02x ", i+j); 
     118                } 
     119                printf("\n"); 
     120        } 
     121 
     122        return 0; 
     123} 
     124 
    48125int main(int argc, char *argv[]) 
    49126{ 
    50127  char *end; 
    51   int i=1,j,res,i2cbus=-1,file; 
    52   int e1, e2, e3; 
    53   char filename1[20]; 
    54   char filename2[20]; 
    55   char filename3[20]; 
    56   char *filename; 
     128  int i = 1, i2cbus = -1, file, res; 
     129  char filename[20]; 
    57130  long funcs; 
    58131  int force = 0; 
     
    110183    } 
    111184  } 
    112 /* 
    113  * Try all three variants and give the correct error message 
    114  * upon failure 
    115  */ 
    116  
    117   sprintf(filename1,"/dev/i2c-%d",i2cbus); 
    118   sprintf(filename2,"/dev/i2c%d",i2cbus); 
    119   sprintf(filename3,"/dev/i2c/%d",i2cbus); 
    120   if ((file = open(filename1,O_RDWR)) < 0) { 
    121     e1 = errno; 
    122     if ((file = open(filename2,O_RDWR)) < 0) { 
    123       e2 = errno; 
    124       if ((file = open(filename3,O_RDWR)) < 0) { 
    125         e3 = errno; 
    126         if(e1 == ENOENT && e2 == ENOENT && e3 == ENOENT) { 
    127           fprintf(stderr,"Error: Could not open file `%s', `%s', or `%s': %s\n", 
    128                      filename1,filename2,filename3,strerror(ENOENT)); 
    129         } 
    130         if (e1 != ENOENT) { 
    131           fprintf(stderr,"Error: Could not open file `%s' : %s\n", 
    132                      filename1,strerror(e1)); 
    133           if(e1 == EACCES) 
    134             fprintf(stderr,"Run as root?\n"); 
    135         } 
    136         if (e2 != ENOENT) { 
    137           fprintf(stderr,"Error: Could not open file `%s' : %s\n", 
    138                      filename2,strerror(e2)); 
    139           if(e2 == EACCES) 
    140             fprintf(stderr,"Run as root?\n"); 
    141         } 
    142         if (e3 != ENOENT) { 
    143           fprintf(stderr,"Error: Could not open file `%s' : %s\n", 
    144                      filename3,strerror(e3)); 
    145           if(e3 == EACCES) 
    146             fprintf(stderr,"Run as root?\n"); 
    147         } 
    148         exit(1); 
    149       } else { 
    150          filename = filename3; 
    151       } 
     185 
     186  file = open_i2c_dev(i2cbus, filename); 
     187  if (file < 0) { 
     188    if (errno == ENOENT) { 
     189      fprintf(stderr, "Error: Could not open file `/dev/i2c-%d' or `/dev/i2c/%d': %s\n", 
     190              i2cbus, i2cbus, strerror(ENOENT)); 
    152191    } else { 
    153        filename = filename2; 
    154     } 
    155   } else { 
    156     filename = filename1; 
     192      fprintf(stderr, "Error: Could not open file `%s': %s\n", 
     193              filename, strerror(errno)); 
     194      if (errno == EACCES) 
     195        fprintf(stderr, "Run as root?\n"); 
     196    } 
     197    exit(1); 
    157198  } 
    158199 
     
    187228  sleep(5); 
    188229 
    189   printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n"); 
    190   for (i = 0; i < 128; i+=16) { 
    191     printf("%02x: ",i); 
    192     for(j = 0; j < 16; j++) { 
    193       if (!force && (i+j<0x03 || i+j>0x77)) { 
    194         printf("   "); 
    195         continue; 
    196       } 
    197       if (ioctl(file,I2C_SLAVE,i+j) < 0) { 
    198         if (errno == EBUSY) { 
    199           printf("UU "); 
    200           continue; 
    201         } else { 
    202           fprintf(stderr,"Error: Could not set address to %02x: %s\n",i+j, 
    203                   strerror(errno)); 
    204           close(file); 
    205           exit(1); 
    206         } 
    207       } 
    208  
    209       switch(mode) { 
    210       case MODE_QUICK: 
    211         /* This is known to corrupt the Atmel AT24RF08 EEPROM */ 
    212         res = i2c_smbus_write_quick(file, I2C_SMBUS_WRITE); 
    213         break; 
    214       case MODE_READ: 
    215         /* This is known to lock SMBus on various write-only chips 
    216            (mainly clock chips) */ 
    217         res = i2c_smbus_read_byte(file); 
    218         break; 
    219       default: 
    220         if((i+j>=0x30 && i+j<=0x37) 
    221         || (i+j>=0x50 && i+j<=0x5F)) { 
    222           res = i2c_smbus_write_quick(file, I2C_SMBUS_WRITE); 
    223         } else { 
    224           res = i2c_smbus_read_byte(file); 
    225         } 
    226       } 
    227  
    228       if (res < 0) 
    229         printf("XX "); 
    230       else 
    231         printf("%02x ",i+j); 
    232     } 
    233     printf("\n"); 
    234   } 
     230  if (force) 
     231    res = scan_i2c_bus(file, mode, 0x00, 0x7F); 
     232  else 
     233    res = scan_i2c_bus(file, mode, 0x03, 0x77); 
     234 
    235235  close(file); 
    236   exit(0); 
    237 } 
     236 
     237  exit(res?1:0); 
     238}