Changeset 2673

Show
Ignore:
Timestamp:
08/26/04 23:01:40 (10 years ago)
Author:
khali
Message:

Mass reindent.

Drop /dev/i2cN support.

Location:
lm-sensors/trunk/prog/dump
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/prog/dump/i2cdump.c

    r2176 r2673  
    11/* 
    2     i2cdump.c - Part of i2cdump, a user-space program to dump I2C registers 
    3     Copyright (c) 2002-2003  Frodo Looijaard <frodol@dds.nl>, and 
    4     Mark D. Studebaker <mdsxyz123@yahoo.com> 
     2    i2cdump.c - a user-space program to dump I2C registers 
     3    Copyright (C) 2002-2003  Frodo Looijaard <frodol@dds.nl>, and 
     4                             Mark D. Studebaker <mdsxyz123@yahoo.com> 
     5    Copyright (C) 2004       The lm_sensors group 
    56 
    67    This program is free software; you can redistribute it and/or modify 
     
    3334   so we use it as a version check. 
    3435*/ 
    35 #ifdef I2C_FUNC_SMBUS_READ_I2C_BLOCK_2  
     36#ifdef I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 
    3637#define USE_I2C_BLOCK 1 
    3738#else 
     
    4748void help(void) 
    4849{ 
    49   fprintf(stderr,"Syntax: i2cdump I2CBUS ADDRESS [MODE] [BANK [BANKREG]]\n"); 
    50   fprintf(stderr,"  MODE is 'b[yte]', 'w[ord]', 's[mbusblock], 'i[2cblock]',\n"); 
    51   fprintf(stderr,"       or 'c[onsecutive byte address mode]' (default b)\n"); 
    52   fprintf(stderr,"  Append MODE with 'p' for PEC checking\n"); 
    53   fprintf(stderr,"  I2CBUS is an integer\n"); 
    54   fprintf(stderr,"  ADDRESS is an integer 0x00 - 0x7f\n"); 
    55   fprintf(stderr,"  BANK and BANKREG are for byte and word accesses (default bank 0, reg 0x4e)\n"); 
    56   fprintf(stderr,"  BANK is the command for smbusblock accesses (default 0)\n"); 
    57   print_i2c_busses(0); 
     50        fprintf(stderr, "Syntax: i2cdump I2CBUS ADDRESS [MODE] [BANK " 
     51                "[BANKREG]]\n" 
     52                "  MODE is 'b[yte]', 'w[ord]', 's[mbusblock], 'i[2cblock]',\n" 
     53                "       or 'c[onsecutive byte address mode]' (default b)\n" 
     54                "  Append MODE with 'p' for PEC checking\n" 
     55                "  I2CBUS is an integer\n" 
     56                "  ADDRESS is an integer 0x00 - 0x7f\n" 
     57                "  BANK and BANKREG are for byte and word accesses (default " 
     58                "bank 0, reg 0x4e)\n" 
     59                "  BANK is the command for smbusblock accesses (default 0)\n"); 
     60        print_i2c_busses(0); 
    5861} 
    5962 
    6063int main(int argc, char *argv[]) 
    6164{ 
    62   char *end; 
    63   int i,j,res,res2,i2cbus,address,size,file; 
    64   int e1, e2, e3; 
    65   int bank = 0, bankreg = 0x4E; 
    66   char filename1[20]; 
    67   char filename2[20]; 
    68   char filename3[20]; 
    69   char *filename; 
    70   long funcs; 
    71   unsigned char cblock[256];   
    72   int block[256];   
    73   int pec = 0; 
    74  
    75   if (argc < 2) { 
    76     fprintf(stderr,"Error: No i2c-bus specified!\n"); 
    77     help(); 
    78     exit(1); 
    79   } 
    80  
    81   if((!strcmp(argv[1], "-v")) || (!strcmp(argv[1], "-V"))) { 
    82     fprintf(stderr,"i2cdump version %s\n", LM_VERSION); 
    83     exit(1); 
    84   } 
    85  
    86   i2cbus = strtol(argv[1],&end,0); 
    87   if (*end) { 
    88     fprintf(stderr,"Error: First argument not a number!\n"); 
    89     help(); 
    90     exit(1); 
    91   } 
    92   if ((i2cbus < 0) || (i2cbus > 0xff)) { 
    93     fprintf(stderr,"Error: I2CBUS argument out of range!\n"); 
    94     help(); 
    95   } 
    96  
    97   if (argc < 3) { 
    98     fprintf(stderr,"Error: No address specified!\n"); 
    99     help(); 
    100     exit(1); 
    101   } 
    102   address = strtol(argv[2],&end,0); 
    103   if (*end) { 
    104     fprintf(stderr,"Error: Second argument not a number!\n"); 
    105     help(); 
    106     exit(1); 
    107   } 
    108   if ((address < 0) || (address > 0x7f)) { 
    109     fprintf(stderr,"Error: Address out of range!\n"); 
    110     help(); 
    111   } 
    112  
    113   if (argc < 4) { 
    114     fprintf(stderr,"No size specified (using byte-data access)\n"); 
    115     size = I2C_SMBUS_BYTE_DATA; 
    116   } else if (!strncmp(argv[3],"b",1)) { 
    117     size = I2C_SMBUS_BYTE_DATA; 
    118     pec = argv[3][1] == 'p'; 
    119   } else if (!strncmp(argv[3],"w",1)) { 
    120     size = I2C_SMBUS_WORD_DATA; 
    121     pec = argv[3][1] == 'p'; 
    122   } else if (!strncmp(argv[3],"s",1)) { 
    123     size = I2C_SMBUS_BLOCK_DATA; 
    124     pec = argv[3][1] == 'p'; 
    125   } else if (!strncmp(argv[3],"c",1)) { 
    126     size = I2C_SMBUS_BYTE; 
    127     pec = argv[3][1] == 'p'; 
    128   } else if (!strcmp(argv[3],"i")) 
    129     size = I2C_SMBUS_I2C_BLOCK_DATA; 
    130   else { 
    131     fprintf(stderr,"Error: Invalid mode!\n"); 
    132     help(); 
    133     exit(1); 
    134   } 
    135  
    136   if(argc > 4) { 
    137     bank = strtol(argv[4],&end,0); 
    138     if (*end || size == I2C_SMBUS_I2C_BLOCK_DATA) { 
    139       fprintf(stderr,"Error: Invalid bank number!\n"); 
    140       help(); 
    141       exit(1); 
    142     } 
    143     if (((size == I2C_SMBUS_BYTE_DATA) || (size == I2C_SMBUS_WORD_DATA)) && 
    144         ((bank < 0) || (bank > 15))) { 
    145       fprintf(stderr,"Error: bank out of range!\n"); 
    146       help(); 
    147       exit(1); 
    148     } 
    149     if (((size == I2C_SMBUS_BLOCK_DATA)) && 
    150         ((bank < 0) || (bank > 0xff))) { 
    151       fprintf(stderr,"Error: block command out of range!\n"); 
    152       help(); 
    153       exit(1); 
    154     } 
    155  
    156     if(argc > 5) { 
    157       bankreg = strtol(argv[5],&end,0); 
    158       if (*end || size == I2C_SMBUS_BLOCK_DATA) { 
    159         fprintf(stderr,"Error: Invalid bank register number!\n"); 
    160         help(); 
    161         exit(1); 
    162       } 
    163       if ((bankreg < 0) || (bankreg > 0xff)) { 
    164         fprintf(stderr,"Error: bank out of range (0-0xff)!\n"); 
    165         help(); 
    166         exit(1); 
    167       } 
    168     } 
    169   } 
    170  
    171 /* 
    172  * Try all three variants and give the correct error message 
    173  * upon failure 
    174  */ 
    175  
    176   sprintf(filename1,"/dev/i2c-%d",i2cbus); 
    177   sprintf(filename2,"/dev/i2c%d",i2cbus); 
    178   sprintf(filename3,"/dev/i2c/%d",i2cbus); 
    179   if ((file = open(filename1,O_RDWR)) < 0) { 
    180     e1 = errno; 
    181     if ((file = open(filename2,O_RDWR)) < 0) { 
    182       e2 = errno; 
    183       if ((file = open(filename3,O_RDWR)) < 0) { 
    184         e3 = errno; 
    185         if(e1 == ENOENT && e2 == ENOENT && e3 == ENOENT) { 
    186           fprintf(stderr,"Error: Could not open file `%s', `%s', or `%s': %s\n", 
    187                      filename1,filename2,filename3,strerror(ENOENT)); 
    188         } 
    189         if (e1 != ENOENT) { 
    190           fprintf(stderr,"Error: Could not open file `%s' : %s\n", 
    191                      filename1,strerror(e1)); 
    192           if(e1 == EACCES) 
    193             fprintf(stderr,"Run as root?\n"); 
    194         } 
    195         if (e2 != ENOENT) { 
    196           fprintf(stderr,"Error: Could not open file `%s' : %s\n", 
    197                      filename2,strerror(e2)); 
    198           if(e2 == EACCES) 
    199             fprintf(stderr,"Run as root?\n"); 
    200         } 
    201         if (e3 != ENOENT) { 
    202           fprintf(stderr,"Error: Could not open file `%s' : %s\n", 
    203                      filename3,strerror(e3)); 
    204           if(e3 == EACCES) 
    205             fprintf(stderr,"Run as root?\n"); 
    206         } 
    207         exit(1); 
    208       } else { 
    209          filename = filename3; 
    210       } 
    211     } else { 
    212        filename = filename2; 
    213     } 
    214   } else { 
    215     filename = filename1; 
    216   } 
    217    
    218   /* check adapter functionality */ 
    219   if (ioctl(file,I2C_FUNCS,&funcs) < 0) { 
    220     fprintf(stderr, 
    221             "Error: Could not get the adapter functionality matrix: %s\n", 
    222             strerror(errno)); 
    223     exit(1); 
    224   } 
    225  
    226   switch(size) { 
    227      case I2C_SMBUS_BYTE: 
     65        char *end; 
     66        int i, j, res, res2, i2cbus, address, size, file; 
     67        int e1, e2; 
     68        int bank = 0, bankreg = 0x4E; 
     69        char filename1[20]; 
     70        char filename2[20]; 
     71        char *filename; 
     72        long funcs; 
     73        unsigned char cblock[256]; 
     74        int block[256]; 
     75        int pec = 0; 
     76 
     77        if (argc < 2) { 
     78                fprintf(stderr, "Error: No i2c-bus specified!\n"); 
     79                help(); 
     80                exit(1); 
     81        } 
     82 
     83        if(!strcmp(argv[1], "-v") || !strcmp(argv[1], "-V")) { 
     84                fprintf(stderr, "i2cdump version %s\n", LM_VERSION); 
     85                exit(1); 
     86        } 
     87 
     88        i2cbus = strtol(argv[1], &end, 0); 
     89        if (*end) { 
     90                fprintf(stderr, "Error: First argument not a number!\n"); 
     91                help(); 
     92                exit(1); 
     93        } 
     94        if (i2cbus < 0 || i2cbus > 0xff) { 
     95                fprintf(stderr, "Error: I2CBUS argument out of range!\n"); 
     96                help(); 
     97                exit(1); 
     98        } 
     99 
     100        if (argc < 3) { 
     101                fprintf(stderr, "Error: No address specified!\n"); 
     102                help(); 
     103                exit(1); 
     104        } 
     105        address = strtol(argv[2], &end, 0); 
     106        if (*end) { 
     107                fprintf(stderr, "Error: Second argument not a number!\n"); 
     108                help(); 
     109                exit(1); 
     110        } 
     111        if (address < 0 || address > 0x7f) { 
     112                fprintf(stderr, "Error: Address out of range!\n"); 
     113                help(); 
     114                exit(1); 
     115        } 
     116 
     117        if (argc < 4) { 
     118                fprintf(stderr, "No size specified (using byte-data access)\n"); 
     119                size = I2C_SMBUS_BYTE_DATA; 
     120        } else if (!strncmp(argv[3], "b", 1)) { 
     121                size = I2C_SMBUS_BYTE_DATA; 
     122                pec = argv[3][1] == 'p'; 
     123        } else if (!strncmp(argv[3], "w", 1)) { 
     124                size = I2C_SMBUS_WORD_DATA; 
     125                pec = argv[3][1] == 'p'; 
     126        } else if (!strncmp(argv[3], "s", 1)) { 
     127                size = I2C_SMBUS_BLOCK_DATA; 
     128                pec = argv[3][1] == 'p'; 
     129        } else if (!strncmp(argv[3], "c", 1)) { 
     130                size = I2C_SMBUS_BYTE; 
     131                pec = argv[3][1] == 'p'; 
     132        } else if (!strcmp(argv[3], "i")) 
     133                size = I2C_SMBUS_I2C_BLOCK_DATA; 
     134        else { 
     135                fprintf(stderr, "Error: Invalid mode!\n"); 
     136                help(); 
     137                exit(1); 
     138        } 
     139 
     140        if (argc > 4) { 
     141                bank = strtol(argv[4], &end, 0); 
     142                if (*end || size == I2C_SMBUS_I2C_BLOCK_DATA) { 
     143                        fprintf(stderr, "Error: Invalid bank number!\n"); 
     144                        help(); 
     145                        exit(1); 
     146                } 
     147                if ((size == I2C_SMBUS_BYTE_DATA || size == I2C_SMBUS_WORD_DATA) 
     148                 && (bank < 0 || bank > 15)) { 
     149                        fprintf(stderr, "Error: bank out of range!\n"); 
     150                        help(); 
     151                        exit(1); 
     152                } 
     153                if (size == I2C_SMBUS_BLOCK_DATA 
     154                 && (bank < 0 || bank > 0xff)) { 
     155                        fprintf(stderr, "Error: block command out of range!\n"); 
     156                        help(); 
     157                        exit(1); 
     158                } 
     159 
     160                if (argc > 5) { 
     161                        bankreg = strtol(argv[5], &end, 0); 
     162                        if (*end || size == I2C_SMBUS_BLOCK_DATA) { 
     163                                fprintf(stderr, "Error: Invalid bank register " 
     164                                        "number!\n"); 
     165                                help(); 
     166                                exit(1); 
     167                        } 
     168                        if (bankreg < 0 || bankreg > 0xff) { 
     169                                fprintf(stderr, "Error: bank out of range " 
     170                                        "(0-0xff)!\n"); 
     171                                help(); 
     172                                exit(1); 
     173                        } 
     174                } 
     175        } 
     176 
     177        /* 
     178         * Try both variants and give the correct error message 
     179         * upon failure 
     180         */ 
     181 
     182        sprintf(filename1, "/dev/i2c-%d", i2cbus); 
     183        sprintf(filename2, "/dev/i2c/%d", i2cbus); 
     184        if ((file = open(filename1, O_RDWR)) < 0) { 
     185                e1 = errno; 
     186                if ((file = open(filename2, O_RDWR)) < 0) { 
     187                        e2 = errno; 
     188                        if (e1 == ENOENT && e2 == ENOENT) { 
     189                                fprintf(stderr, "Error: Could not open file " 
     190                                        "`%s' or `%s': %s\n", filename1, 
     191                                        filename2, strerror(ENOENT)); 
     192                        } 
     193                        if (e1 != ENOENT) { 
     194                                fprintf(stderr, "Error: Could not open file " 
     195                                        "`%s': %s\n", filename1, 
     196                                        strerror(e1)); 
     197                                if (e1 == EACCES) 
     198                                        fprintf(stderr, "Run as root?\n"); 
     199                        } 
     200                        if (e2 != ENOENT) { 
     201                                fprintf(stderr, "Error: Could not open file " 
     202                                        "`%s' : %s\n", filename2, 
     203                                        strerror(e2)); 
     204                                if (e2 == EACCES) 
     205                                        fprintf(stderr, "Run as root?\n"); 
     206                        } 
     207                        exit(1); 
     208                } else { 
     209                        filename = filename2; 
     210                } 
     211        } else { 
     212                filename = filename1; 
     213        } 
     214 
     215        /* check adapter functionality */ 
     216        if (ioctl(file, I2C_FUNCS, &funcs) < 0) { 
     217                fprintf(stderr, "Error: Could not get the adapter " 
     218                        "functionality matrix: %s\n", strerror(errno)); 
     219                exit(1); 
     220        } 
     221 
     222        switch(size) { 
     223        case I2C_SMBUS_BYTE: 
    228224#ifdef HAVE_PEC 
    229         if(pec) { 
    230           if (! (funcs & I2C_FUNC_SMBUS_READ_BYTE_PEC)) { 
    231              fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); 
    232              fprintf(stderr, " does not have read w/ PEC capability\n"); 
    233              exit(1); 
    234           }        
    235         } else 
    236 #endif 
    237         { 
    238           if (! (funcs & I2C_FUNC_SMBUS_READ_BYTE)) { 
    239              fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); 
    240              fprintf(stderr, " does not have read capability\n"); 
    241              exit(1); 
    242           }        
    243         } 
    244         break; 
    245  
    246      case I2C_SMBUS_BYTE_DATA: 
     225                if (pec) { 
     226                        if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE_PEC)) { 
     227                                fprintf(stderr, "Error: Adapter for i2c bus " 
     228                                        "%d does not have read w/ PEC " 
     229                                        "capability\n", i2cbus); 
     230                                exit(1); 
     231                        } 
     232                } else 
     233#endif 
     234                { 
     235                        if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE)) { 
     236                                fprintf(stderr, "Error: Adapter for i2c bus " 
     237                                        "%d does not have read capability\n", 
     238                                        i2cbus); 
     239                                exit(1); 
     240                        } 
     241                } 
     242                break; 
     243 
     244        case I2C_SMBUS_BYTE_DATA: 
    247245#ifdef HAVE_PEC 
    248         if(pec) { 
    249           if (! (funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC)) { 
    250              fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); 
    251              fprintf(stderr, " does not have byte read w/ PEC capability\n"); 
    252              exit(1); 
    253           }        
    254         } else 
    255 #endif 
    256         { 
    257           if (! (funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA)) { 
    258              fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); 
    259              fprintf(stderr, " does not have byte read capability\n"); 
    260              exit(1); 
    261           }        
    262         } 
    263         break; 
    264  
    265      case I2C_SMBUS_WORD_DATA: 
     246                if (pec) { 
     247                        if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC)) { 
     248                                fprintf(stderr, "Error: Adapter for i2c bus " 
     249                                        "%d does not have byte read w/ PEC " 
     250                                        "capability\n", i2cbus); 
     251                                exit(1); 
     252                        } 
     253                } else 
     254#endif 
     255                { 
     256                        if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA)) { 
     257                                fprintf(stderr, "Error: Adapter for i2c bus " 
     258                                        "%d does not have byte read " 
     259                                        "capability\n", i2cbus); 
     260                                exit(1); 
     261                        } 
     262                } 
     263                break; 
     264 
     265        case I2C_SMBUS_WORD_DATA: 
    266266#ifdef HAVE_PEC 
    267         if(pec) { 
    268           if (! (funcs & I2C_FUNC_SMBUS_READ_WORD_DATA_PEC)) { 
    269              fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); 
    270              fprintf(stderr, " does not have word read w/ PEC capability\n"); 
    271              exit(1); 
    272           }        
    273         } else 
    274 #endif 
    275         { 
    276           if (! (funcs & I2C_FUNC_SMBUS_READ_WORD_DATA)) { 
    277              fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); 
    278              fprintf(stderr, " does not have word read capability\n"); 
    279              exit(1); 
    280           }        
    281         } 
    282         break; 
    283  
    284      case I2C_SMBUS_BLOCK_DATA: 
     267                if (pec) { 
     268                        if (!(funcs & I2C_FUNC_SMBUS_READ_WORD_DATA_PEC)) { 
     269                                fprintf(stderr, "Error: Adapter for i2c bus " 
     270                                        "%d does not have word read w/ PEC " 
     271                                        "capability\n", i2cbus); 
     272                                exit(1); 
     273                        } 
     274                } else 
     275#endif 
     276                { 
     277                        if (!(funcs & I2C_FUNC_SMBUS_READ_WORD_DATA)) { 
     278                                fprintf(stderr, "Error: Adapter for i2c bus " 
     279                                        "%d does not have word read " 
     280                                        "capability\n", i2cbus); 
     281                                exit(1); 
     282                        } 
     283                } 
     284                break; 
     285 
     286        case I2C_SMBUS_BLOCK_DATA: 
    285287#ifdef HAVE_PEC 
    286         if(pec) { 
    287           if (! (funcs & I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC)) { 
    288              fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); 
    289              fprintf(stderr, " does not have smbus block read capability\n"); 
    290              exit(1); 
    291           }        
    292         } else 
    293 #endif 
    294         { 
    295           if (! (funcs & I2C_FUNC_SMBUS_READ_BLOCK_DATA)) { 
    296              fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); 
    297              fprintf(stderr, " does not have smbus block read w/ PEC capability\n"); 
    298              exit(1); 
    299           }        
    300         } 
    301         break; 
    302  
    303      case I2C_SMBUS_I2C_BLOCK_DATA: 
    304         if (! (funcs & I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { 
    305            fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); 
    306            fprintf(stderr, " does not have i2c block read capability\n"); 
    307            exit(1); 
    308         }        
    309         break; 
    310  
    311   } 
    312   /* use FORCE so that we can look at registers even when 
    313      a driver is also running */ 
    314   if (ioctl(file,I2C_SLAVE_FORCE,address) < 0) { 
    315     fprintf(stderr,"Error: Could not set address to %d: %s\n",address, 
    316             strerror(errno)); 
    317     exit(1); 
    318   } 
    319   
    320   if(pec) { 
     288                if (pec) { 
     289                        if (!(funcs & I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC)) { 
     290                                fprintf(stderr, "Error: Adapter for i2c bus " 
     291                                        "%d does not have smbus block read " 
     292                                        "w/ PEC capability\n", i2cbus); 
     293                                exit(1); 
     294                        } 
     295                } else 
     296#endif 
     297                { 
     298                        if (!(funcs & I2C_FUNC_SMBUS_READ_BLOCK_DATA)) { 
     299                                fprintf(stderr, "Error: Adapter for i2c bus " 
     300                                        "%d does not have smbus block read " 
     301                                        "capability\n", i2cbus); 
     302                                exit(1); 
     303                        } 
     304                } 
     305                break; 
     306 
     307        case I2C_SMBUS_I2C_BLOCK_DATA: 
     308                if (!(funcs & I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { 
     309                        fprintf(stderr, "Error: Adapter for i2c bus %d does " 
     310                                "not have i2c block read capability\n", 
     311                                i2cbus); 
     312                        exit(1); 
     313                } 
     314                break; 
     315        } 
     316 
     317        /* use FORCE so that we can look at registers even when 
     318           a driver is also running */ 
     319        if (ioctl(file, I2C_SLAVE_FORCE, address) < 0) { 
     320                fprintf(stderr, "Error: Could not set address to %d: %s\n", 
     321                        address, strerror(errno)); 
     322                exit(1); 
     323        } 
     324 
     325        if (pec) { 
    321326#ifdef HAVE_PEC 
    322     if (ioctl(file,I2C_PEC, 1) < 0) { 
    323       fprintf(stderr,"Error: Could not set PEC: %s\n", strerror(errno)); 
    324       exit(1); 
    325     } 
     327                if (ioctl(file, I2C_PEC, 1) < 0) { 
     328                        fprintf(stderr, "Error: Could not set PEC: %s\n", 
     329                                strerror(errno)); 
     330                        exit(1); 
     331                } 
    326332#else 
    327     fprintf(stderr,"Error: PEC not supported in your kernel\n"); 
    328     exit(1); 
    329 #endif 
    330   } 
    331  
    332   fprintf(stderr,"  WARNING! This program can confuse your I2C bus, " 
    333           "cause data loss and worse!\n"); 
    334   fprintf(stderr,"  I will probe file %s, address 0x%x, mode %s\n", 
    335           filename,address,size == I2C_SMBUS_BLOCK_DATA ? "smbus block" : 
    336                            size == I2C_SMBUS_I2C_BLOCK_DATA ? "i2c block" : 
    337                            size == I2C_SMBUS_BYTE ? "byte consecutive read" : 
    338                            size == I2C_SMBUS_BYTE_DATA ? "byte" : "word"); 
    339   if(pec) 
    340     fprintf(stderr,"  with PEC checking.\n"); 
    341   if(bank) {     
    342     if(size == I2C_SMBUS_BLOCK_DATA) 
    343       fprintf(stderr,"  Using command 0x%02x.\n", bank); 
    344     else 
    345       fprintf(stderr,"  Probing bank %d using bank register 0x%02x.\n", 
    346               bank, bankreg); 
    347   } 
    348   fprintf(stderr,"  You have five seconds to reconsider and press CTRL-C!\n\n"); 
    349   sleep(5); 
    350  
    351   /* See Winbond w83781d data sheet for bank details */ 
    352   if(bank && size != I2C_SMBUS_BLOCK_DATA) { 
    353     i2c_smbus_write_byte_data(file,bankreg,bank | 0x80); 
    354   } 
    355  
    356   /* handle all but word data */ 
    357   if (size != I2C_SMBUS_WORD_DATA) { 
    358  
    359     /* do the block transaction */ 
    360     if(size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) { 
    361       if(size == I2C_SMBUS_BLOCK_DATA) { 
    362         res = i2c_smbus_read_block_data(file, bank, cblock); 
    363       } else { 
     333                fprintf(stderr, "Error: PEC not supported in your kernel\n"); 
     334                exit(1); 
     335#endif 
     336        } 
     337 
     338        fprintf(stderr, "WARNING! This program can confuse your I2C bus, " 
     339                "cause data loss and worse!\n"); 
     340        fprintf(stderr, "I will probe file %s, address 0x%x, mode %s\n", 
     341                filename, address, 
     342                size == I2C_SMBUS_BLOCK_DATA ? "smbus block" : 
     343                size == I2C_SMBUS_I2C_BLOCK_DATA ? "i2c block" : 
     344                size == I2C_SMBUS_BYTE ? "byte consecutive read" : 
     345                size == I2C_SMBUS_BYTE_DATA ? "byte" : "word"); 
     346        if (pec) 
     347                fprintf(stderr, "PEC checking enabled.\n"); 
     348        if (bank) { 
     349                if (size == I2C_SMBUS_BLOCK_DATA) 
     350                        fprintf(stderr, "Using command 0x%02x.\n", bank); 
     351                else 
     352                        fprintf(stderr, "Probing bank %d using bank register " 
     353                                "0x%02x.\n", bank, bankreg); 
     354        } 
     355        fprintf(stderr, "You have five seconds to reconsider and press " 
     356                "CTRL-C!\n\n"); 
     357        sleep(5); 
     358 
     359        /* See Winbond w83781d data sheet for bank details */ 
     360        if (bank && size != I2C_SMBUS_BLOCK_DATA) { 
     361                i2c_smbus_write_byte_data(file, bankreg, bank | 0x80); 
     362        } 
     363 
     364        /* handle all but word data */ 
     365        if (size != I2C_SMBUS_WORD_DATA) { 
     366 
     367                /* do the block transaction */ 
     368                if (size == I2C_SMBUS_BLOCK_DATA 
     369                 || size == I2C_SMBUS_I2C_BLOCK_DATA) { 
     370                        if (size == I2C_SMBUS_BLOCK_DATA) { 
     371                                res = i2c_smbus_read_block_data(file, bank, 
     372                                      cblock); 
     373                        } else { 
    364374#if USE_I2C_BLOCK 
    365         res = 0; 
    366         for (i = 0; i < 256; i+=32) { 
    367           res2 = i2c_smbus_read_i2c_block_data(file, i, cblock+i); 
    368           if(res2 <= 0) 
    369             break; 
    370           res += res2; 
    371         } 
     375                                res = 0; 
     376                                for (i = 0; i < 256; i+=32) { 
     377                                        res2 = i2c_smbus_read_i2c_block_data(file, 
     378                                               i, cblock+i); 
     379                                        if (res2 <= 0) 
     380                                                break; 
     381                                        res += res2; 
     382                                } 
    372383#else 
    373         fprintf(stderr, "Error: I2C block read unsupported in i2c-core\n"); 
    374         exit(1); 
    375 #endif 
    376       } 
    377       if(res <= 0) { 
    378         fprintf(stderr, "Error: Block read failed, return code %d\n", res); 
    379         exit(1); 
    380       } 
    381       if(res >= 256) 
    382         res = 256; 
    383       for (i = 0; i < res; i++) 
    384         block[i] = cblock[i]; 
    385       for (i = res; i < 256; i++) 
    386         block[i] = -1; 
    387     } 
    388  
    389     if(size == I2C_SMBUS_BYTE) { 
    390       res = i2c_smbus_write_byte(file, 0); 
    391       if(res != 0) { 
    392         fprintf(stderr, "Error: Write start address failed, return code %d\n", res); 
    393         exit(1); 
    394       } 
    395     } 
    396     printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef\n"); 
    397     for (i = 0; i < 256; i+=16) { 
    398       printf("%02x: ",i); 
    399       for(j = 0; j < 16; j++) { 
    400         if(size == I2C_SMBUS_BYTE_DATA) { 
    401           block[i+j] = res = i2c_smbus_read_byte_data(file,i+j); 
    402         } else if(size == I2C_SMBUS_BYTE) { 
    403           block[i+j] = res = i2c_smbus_read_byte(file); 
    404         } else 
    405           res = block[i+j]; 
    406         if (res < 0) 
    407           printf("XX "); 
    408         else 
    409           printf("%02x ",res & 0xff); 
    410       } 
    411       printf("   "); 
    412       for(j = 0; j < 16; j++) { 
    413         res = block[i+j]; 
    414         if (res < 0) 
    415           printf("X"); 
    416         else if (((res & 0xff) == 0x00) || ((res & 0xff) == 0xff)) 
    417           printf("."); 
    418         else if (((res & 0xff) < 32) || ((res & 0xff) >= 127)) 
    419           printf("?"); 
    420         else 
    421           printf("%c",res & 0xff); 
    422       } 
    423       printf("\n"); 
    424     if(size == I2C_SMBUS_BLOCK_DATA && i == 16) 
    425       break;             
    426     } 
    427   } else { 
    428     printf("     0,8  1,9  2,a  3,b  4,c  5,d  6,e  7,f\n"); 
    429     for (i = 0; i < 256; i+=8) { 
    430       printf("%02x: ",i); 
    431       for(j = 0; j < 8; j++) { 
    432         res = i2c_smbus_read_word_data(file,i+j); 
    433         if (res < 0) 
    434           printf("XXXX "); 
    435         else 
    436           printf("%04x ",res & 0xffff); 
    437       } 
    438       printf("\n"); 
    439     } 
    440   } 
    441   if(bank && size != I2C_SMBUS_BLOCK_DATA) { 
    442     i2c_smbus_write_byte_data(file,bankreg,0x80); 
    443   } 
    444   exit(0); 
     384                                fprintf(stderr, "Error: I2C block read " 
     385                                        "unsupported in i2c-core\n"); 
     386                                exit(1); 
     387#endif 
     388                        } 
     389                        if (res <= 0) { 
     390                                fprintf(stderr, "Error: Block read failed, " 
     391                                        "return code %d\n", res); 
     392                                exit(1); 
     393                        } 
     394                        if (res >= 256) 
     395                                res = 256; 
     396                        for (i = 0; i < res; i++) 
     397                                block[i] = cblock[i]; 
     398                        for (i = res; i < 256; i++) 
     399                                block[i] = -1; 
     400                } 
     401 
     402                if (size == I2C_SMBUS_BYTE) { 
     403                        res = i2c_smbus_write_byte(file, 0); 
     404                        if(res != 0) { 
     405                                fprintf(stderr, "Error: Write start address " 
     406                                        "failed, return code %d\n", res); 
     407                                exit(1); 
     408                        } 
     409                } 
     410 
     411                printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f" 
     412                       "    0123456789abcdef\n"); 
     413                for (i = 0; i < 256; i+=16) { 
     414                        printf("%02x: ", i); 
     415                        for (j = 0; j < 16; j++) { 
     416                                if (size == I2C_SMBUS_BYTE_DATA) { 
     417                                        block[i+j] = res = 
     418                                          i2c_smbus_read_byte_data(file, i+j); 
     419                                } else if (size == I2C_SMBUS_BYTE) { 
     420                                        block[i+j] = res = 
     421                                          i2c_smbus_read_byte(file); 
     422                                } else 
     423                                        res = block[i+j]; 
     424                                if (res < 0) 
     425                                        printf("XX "); 
     426                                else 
     427                                        printf("%02x ", res & 0xff); 
     428                        } 
     429                        printf("   "); 
     430                        for (j = 0; j < 16; j++) { 
     431                                res = block[i+j]; 
     432                                if (res < 0) 
     433                                        printf("X"); 
     434                                else 
     435                                if ((res & 0xff) == 0x00 
     436                                 || (res & 0xff) == 0xff) 
     437                                        printf("."); 
     438                                else 
     439                                if ((res & 0xff) < 32 
     440                                 || (res & 0xff) >= 127) 
     441                                        printf("?"); 
     442                                else 
     443                                        printf("%c", res & 0xff); 
     444                        } 
     445                        printf("\n"); 
     446                        if (size == I2C_SMBUS_BLOCK_DATA && i == 16) 
     447                                break; 
     448                } 
     449        } else { 
     450                printf("     0,8  1,9  2,a  3,b  4,c  5,d  6,e  7,f\n"); 
     451                for (i = 0; i < 256; i+=8) { 
     452                        printf("%02x: ", i); 
     453                        for (j = 0; j < 8; j++) { 
     454                                res = i2c_smbus_read_word_data(file, i+j); 
     455                                if (res < 0) 
     456                                        printf("XXXX "); 
     457                                else 
     458                                        printf("%04x ", res & 0xffff); 
     459                        } 
     460                        printf("\n"); 
     461                } 
     462        } 
     463        if (bank && size != I2C_SMBUS_BLOCK_DATA) { 
     464                i2c_smbus_write_byte_data(file, bankreg, 0x80); 
     465        } 
     466        exit(0); 
    445467} 
  • lm-sensors/trunk/prog/dump/i2cset.c

    r2584 r2673  
    11/* 
    22    i2cset.c - A user-space program to write an I2C register. 
    3     Copyright (c) 2001-2003  Frodo Looijaard <frodol@dds.nl>, and 
    4     Mark D. Studebaker <mdsxyz123@yahoo.com> 
     3    Copyright (C) 2001-2003  Frodo Looijaard <frodol@dds.nl>, and 
     4                             Mark D. Studebaker <mdsxyz123@yahoo.com> 
     5    Copyright (C) 2004       The lm_sensors group 
    56 
    67    This program is free software; you can redistribute it and/or modify 
     
    3334void help(void) 
    3435{ 
    35   fprintf(stderr,"Syntax: i2cset I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE [MODE]\n"); 
    36   fprintf(stderr,"  MODE is 'b[yte]' or 'w[ord]' (default b)\n"); 
    37   fprintf(stderr,"  I2CBUS is an integer\n"); 
    38   print_i2c_busses(0); 
    39   exit(1); 
     36        fprintf(stderr, "Syntax: i2cset I2CBUS CHIP-ADDRESS DATA-ADDRESS " 
     37                "VALUE [MODE]\n"); 
     38        fprintf(stderr, "  MODE is 'b[yte]' or 'w[ord]' (default b)\n"); 
     39        fprintf(stderr, "  I2CBUS is an integer\n"); 
     40        print_i2c_busses(0); 
     41        exit(1); 
    4042} 
    4143 
    4244int main(int argc, char *argv[]) 
    4345{ 
    44   char *end; 
    45   int res,i2cbus,address,size,file; 
    46   int value, daddress; 
    47   int e1, e2, e3; 
    48   char filename1[20]; 
    49   char filename2[20]; 
    50   char filename3[20]; 
    51   char *filename; 
    52   long funcs; 
    53  
    54   if(argc >= 2 && ((!strcmp(argv[1], "-v")) || (!strcmp(argv[1], "-V")))) { 
    55     fprintf(stderr,"i2cset version %s\n", LM_VERSION); 
    56     exit(1); 
    57   } 
    58  
    59   if (argc < 5) 
    60     help(); 
    61  
    62   i2cbus = strtol(argv[1],&end,0); 
    63   if (*end || (i2cbus < 0) || (i2cbus > 0x3f)) { 
    64     fprintf(stderr,"Error: I2CBUS argument invalid!\n"); 
    65     help(); 
    66   } 
    67  
    68   address = strtol(argv[2],&end,0); 
    69   if (*end || (address < 0) || (address > 0x7f)) { 
    70     fprintf(stderr,"Error: Chip address invalid!\n"); 
    71     help(); 
    72   } 
    73  
    74   daddress = strtol(argv[3],&end,0); 
    75   if (*end || (daddress < 0) || (daddress > 0xff)) { 
    76     fprintf(stderr,"Error: Data address invalid!\n"); 
    77     help(); 
    78   } 
    79  
    80   value = strtol(argv[4],&end,0); 
    81   if (*end) { 
    82     fprintf(stderr,"Error: Data value invalid!\n"); 
    83     help(); 
    84   } 
    85  
    86   if (argc < 6) { 
    87     fprintf(stderr,"Warning: no size specified (using byte-data access)\n"); 
    88     size = I2C_SMBUS_BYTE_DATA; 
    89   } else if (!strcmp(argv[5],"b")) 
    90     size = I2C_SMBUS_BYTE_DATA; 
    91   else if (!strcmp(argv[5],"w")) 
    92     size = I2C_SMBUS_WORD_DATA; 
    93   else { 
    94     fprintf(stderr,"Error: Invalid mode!\n"); 
    95     help(); 
    96   } 
    97  
    98   if ((value < 0) || ((size == I2C_SMBUS_BYTE_DATA) && (value > 0xff)) 
    99                   || ((size == I2C_SMBUS_WORD_DATA) && (value > 0x0ffff))) { 
    100     fprintf(stderr,"Error: Data value out of range!\n"); 
    101     help(); 
    102   } 
    103  
    104 /* 
    105  * Try all three variants and give the correct error message 
    106  * upon failure 
    107  */ 
    108  
    109   sprintf(filename1,"/dev/i2c-%d",i2cbus); 
    110   sprintf(filename2,"/dev/i2c%d",i2cbus); 
    111   sprintf(filename3,"/dev/i2c/%d",i2cbus); 
    112   if ((file = open(filename1,O_RDWR)) < 0) { 
    113     e1 = errno; 
    114     if ((file = open(filename2,O_RDWR)) < 0) { 
    115       e2 = errno; 
    116       if ((file = open(filename3,O_RDWR)) < 0) { 
    117         e3 = errno; 
    118         if(e1 == ENOENT && e2 == ENOENT && e3 == ENOENT) { 
    119           fprintf(stderr,"Error: Could not open file `%s', `%s', or `%s': %s\n", 
    120                      filename1,filename2,filename3,strerror(ENOENT)); 
    121         } 
    122         if (e1 != ENOENT) { 
    123           fprintf(stderr,"Error: Could not open file `%s' : %s\n", 
    124                      filename1,strerror(e1)); 
    125           if(e1 == EACCES) 
    126             fprintf(stderr,"Run as root?\n"); 
    127         } 
    128         if (e2 != ENOENT) { 
    129           fprintf(stderr,"Error: Could not open file `%s' : %s\n", 
    130                      filename2,strerror(e2)); 
    131           if(e2 == EACCES) 
    132             fprintf(stderr,"Run as root?\n"); 
    133         } 
    134         if (e3 != ENOENT) { 
    135           fprintf(stderr,"Error: Could not open file `%s' : %s\n", 
    136                      filename3,strerror(e3)); 
    137           if(e3 == EACCES) 
    138             fprintf(stderr,"Run as root?\n"); 
    139         } 
    140         exit(1); 
    141       } else { 
    142          filename = filename3; 
    143       } 
    144     } else { 
    145        filename = filename2; 
    146     } 
    147   } else { 
    148     filename = filename1; 
    149   } 
    150    
    151   /* check adapter functionality */ 
    152   if (ioctl(file,I2C_FUNCS,&funcs) < 0) { 
    153     fprintf(stderr, 
    154             "Error: Could not get the adapter functionality matrix: %s\n", 
    155             strerror(errno)); 
    156     exit(1); 
    157   } 
    158  
    159   switch(size) { 
    160      case I2C_SMBUS_BYTE_DATA: 
    161         if (! (funcs & 
    162             (I2C_FUNC_SMBUS_WRITE_BYTE_DATA | I2C_FUNC_SMBUS_READ_BYTE_DATA))) { 
    163            fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); 
    164            fprintf(stderr, " does not have byte write capability\n"); 
    165            exit(1); 
    166         }        
    167         break; 
    168  
    169      case I2C_SMBUS_WORD_DATA: 
    170         if (! (funcs & 
    171             (I2C_FUNC_SMBUS_WRITE_WORD_DATA | I2C_FUNC_SMBUS_READ_WORD_DATA))) { 
    172            fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); 
    173            fprintf(stderr, " does not have word write capability\n"); 
    174            exit(1); 
    175         }        
    176         break; 
    177  
    178   } 
    179   /* use FORCE so that we can write registers even when 
    180      a driver is also running */ 
    181   if (ioctl(file,I2C_SLAVE_FORCE,address) < 0) { 
    182     fprintf(stderr,"Error: Could not set address to %d: %s\n",address, 
    183             strerror(errno)); 
    184     exit(1); 
    185   } 
    186   
    187   fprintf(stderr,"  WARNING! This program can confuse your I2C bus, " 
    188           "cause data loss and worse!\n"); 
    189   if(address >= 0x50 && address <= 0x57) { 
    190         fprintf(stderr, "DANGEROUS!! Writing to a serial EEPROM on a memory DIMM\n"); 
    191         fprintf(stderr, "may render your memory USELESS and make your system UNBOOTABLE!!!\n"); 
    192         fprintf(stderr, "Are you SURE that you want to write to the chip at address 0x%.2x? (n) ", address); 
    193         res = getchar(); 
    194         if(res != 'y' && res != 'Y') 
     46        char *end; 
     47        int res, i2cbus, address, size, file; 
     48        int value, daddress; 
     49        int e1, e2; 
     50        char filename1[20]; 
     51        char filename2[20]; 
     52        char *filename; 
     53        long funcs; 
     54 
     55        if (argc >= 2 && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "-V"))) { 
     56                fprintf(stderr, "i2cset version %s\n", LM_VERSION); 
    19557                exit(1); 
    196   }      
    197   fprintf(stderr,"  I will write to device file %s, chip address 0x%02x, data address\n" 
    198           "  0x%02x, data 0x%02x, mode %s.\n", 
    199           filename, address, daddress, value, 
    200                            size == I2C_SMBUS_BYTE_DATA ? "byte" : "word"); 
    201   fprintf(stderr,"  You have five seconds to reconsider and press CTRL-C!\n\n"); 
    202   sleep(5); 
    203  
    204   e1 = 0; 
    205   if (size == I2C_SMBUS_WORD_DATA) { 
    206         res = i2c_smbus_write_word_data(file, daddress, value); 
    207   } else { 
    208         res = i2c_smbus_write_byte_data(file, daddress, value); 
    209   } 
    210   if(res < 0) { 
    211         fprintf(stderr, "Warning - write failed\n"); 
    212         e1++; 
    213   } 
    214   if (size == I2C_SMBUS_WORD_DATA) { 
    215         res = i2c_smbus_read_word_data(file, daddress); 
    216   } else { 
    217         res = i2c_smbus_read_byte_data(file, daddress); 
    218   } 
    219   if(res < 0) { 
    220         fprintf(stderr, "Warning - readback failed\n"); 
    221         e1++; 
    222   } else { 
    223         if(res != value) { 
     58        } 
     59 
     60        if (argc < 5) 
     61                help(); 
     62 
     63        i2cbus = strtol(argv[1], &end, 0); 
     64        if (*end || i2cbus < 0 || i2cbus > 0x3f) { 
     65                fprintf(stderr, "Error: I2CBUS argument invalid!\n"); 
     66                help(); 
     67        } 
     68 
     69        address = strtol(argv[2], &end, 0); 
     70        if (*end || address < 0 || address > 0x7f) { 
     71                fprintf(stderr, "Error: Chip address invalid!\n"); 
     72                help(); 
     73        } 
     74 
     75        daddress = strtol(argv[3], &end, 0); 
     76        if (*end || daddress < 0 || daddress > 0xff) { 
     77                fprintf(stderr, "Error: Data address invalid!\n"); 
     78                help(); 
     79        } 
     80 
     81        value = strtol(argv[4], &end, 0); 
     82        if (*end) { 
     83                fprintf(stderr, "Error: Data value invalid!\n"); 
     84                help(); 
     85        } 
     86 
     87        if (argc < 6) { 
     88                fprintf(stderr, "No size specified (using byte-data access)\n"); 
     89                size = I2C_SMBUS_BYTE_DATA; 
     90        } else if (!strcmp(argv[5], "b")) 
     91                size = I2C_SMBUS_BYTE_DATA; 
     92        else if (!strcmp(argv[5], "w")) 
     93                size = I2C_SMBUS_WORD_DATA; 
     94        else { 
     95                fprintf(stderr, "Error: Invalid mode!\n"); 
     96                help(); 
     97        } 
     98 
     99        if (value < 0 
     100         || (size == I2C_SMBUS_BYTE_DATA && value > 0xff) 
     101         || (size == I2C_SMBUS_WORD_DATA && value > 0xffff)) { 
     102                fprintf(stderr, "Error: Data value out of range!\n"); 
     103                help(); 
     104        } 
     105 
     106        /* 
     107         * Try both variants and give the correct error message 
     108         * upon failure 
     109         */ 
     110 
     111        sprintf(filename1, "/dev/i2c-%d", i2cbus); 
     112        sprintf(filename2, "/dev/i2c/%d", i2cbus); 
     113        if ((file = open(filename1, O_RDWR)) < 0) { 
     114                e1 = errno; 
     115                if ((file = open(filename2, O_RDWR)) < 0) { 
     116                        e2 = errno; 
     117                        if (e1 == ENOENT && e2 == ENOENT) { 
     118                                fprintf(stderr, "Error: Could not open file " 
     119                                        "`%s' or `%s': %s\n", filename1, 
     120                                        filename2, strerror(ENOENT)); 
     121                        } 
     122                        if (e1 != ENOENT) { 
     123                                fprintf(stderr, "Error: Could not open file " 
     124                                        ":`%s': %s\n", filename1, 
     125                                        strerror(e1)); 
     126                                if (e1 == EACCES) 
     127                                        fprintf(stderr, "Run as root?\n"); 
     128                        } 
     129                        if (e2 != ENOENT) { 
     130                                fprintf(stderr, "Error: Could not open file " 
     131                                        "`%s' : %s\n", filename2, 
     132                                        strerror(e2)); 
     133                                if (e2 == EACCES) 
     134                                        fprintf(stderr, "Run as root?\n"); 
     135                        } 
     136                        exit(1); 
     137                } else { 
     138                        filename = filename2; 
     139                } 
     140        } else { 
     141                filename = filename1; 
     142        } 
     143 
     144        /* check adapter functionality */ 
     145        if (ioctl(file, I2C_FUNCS, &funcs) < 0) { 
     146                fprintf(stderr, "Error: Could not get the adapter " 
     147                        "functionality matrix: %s\n", strerror(errno)); 
     148                exit(1); 
     149        } 
     150 
     151        switch (size) { 
     152        case I2C_SMBUS_BYTE_DATA: 
     153                if (!(funcs & I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { 
     154                        fprintf(stderr, "Error: Adapter for i2c bus %d does " 
     155                                "not have byte write capability\n", i2cbus); 
     156                        exit(1); 
     157                } 
     158                break; 
     159 
     160        case I2C_SMBUS_WORD_DATA: 
     161                if (!(funcs & I2C_FUNC_SMBUS_WRITE_WORD_DATA)) { 
     162                        fprintf(stderr, "Error: Adapter for i2c bus %d does " 
     163                                "not have word write capability\n", i2cbus); 
     164                        exit(1); 
     165                } 
     166                break; 
     167        } 
     168 
     169        /* use FORCE so that we can write registers even when 
     170           a driver is also running */ 
     171        if (ioctl(file, I2C_SLAVE_FORCE, address) < 0) { 
     172                fprintf(stderr, "Error: Could not set address to %d: %s\n", 
     173                        address, strerror(errno)); 
     174                exit(1); 
     175        } 
     176 
     177        fprintf(stderr, "WARNING! This program can confuse your I2C bus, " 
     178                "cause data loss and worse!\n"); 
     179        if (address >= 0x50 && address <= 0x57) { 
     180                fprintf(stderr, "DANGEROUS!! Writing to a serial EEPROM on " 
     181                        "a memory DIMM\nmay render your memory USELESS and " 
     182                        "make your system UNBOOTABLE!!!\nAre you SURE that " 
     183                        "you want to write to the chip at address 0x%02x? " 
     184                        "(y/N) ", address); 
     185                res = getchar(); 
     186                if (res != 'y' && res != 'Y') 
     187                        exit(1); 
     188        } 
     189 
     190        fprintf(stderr, "I will write to device file %s, chip address 0x%02x, " 
     191                "data address\n0x%02x, data 0x%02x, mode %s.\n", filename, 
     192                address, daddress, value, size == I2C_SMBUS_BYTE_DATA ? 
     193                "byte" : "word"); 
     194        fprintf(stderr, "You have five seconds to reconsider and press " 
     195                "CTRL-C!\n\n"); 
     196        sleep(5); 
     197 
     198        e1 = 0; 
     199        if (size == I2C_SMBUS_WORD_DATA) { 
     200                res = i2c_smbus_write_word_data(file, daddress, value); 
     201        } else { 
     202                res = i2c_smbus_write_byte_data(file, daddress, value); 
     203        } 
     204        if (res < 0) { 
     205                fprintf(stderr, "Warning - write failed\n"); 
     206                e1++; 
     207        } 
     208 
     209        if (size == I2C_SMBUS_WORD_DATA) { 
     210                res = i2c_smbus_read_word_data(file, daddress); 
     211        } else { 
     212                res = i2c_smbus_read_byte_data(file, daddress); 
     213        } 
     214 
     215        if (res < 0) { 
     216                fprintf(stderr, "Warning - readback failed\n"); 
     217                e1++; 
     218        } else 
     219        if (res != value) { 
    224220                e1++; 
    225221                if (size == I2C_SMBUS_WORD_DATA) 
    226                         fprintf(stderr, "Warning - data mismatch - wrote 0x%.4x, read back 0x%.4x\n", value, res); 
     222                        fprintf(stderr, "Warning - data mismatch - wrote " 
     223                                "0x%04x, read back 0x%04x\n", value, res); 
    227224                else 
    228                         fprintf(stderr, "Warning - data mismatch - wrote 0x%.2x, read back 0x%.2x\n", value, res); 
    229         } else { 
    230                 fprintf(stderr, "Value 0x%x written, readback matched\n", value); 
    231         } 
    232   }      
    233   exit(e1); 
     225                        fprintf(stderr, "Warning - data mismatch - wrote " 
     226                                "0x%02x, read back 0x%02x\n", value, res); 
     227        } else { 
     228                fprintf(stderr, "Value 0x%x written, readback matched\n", 
     229                        value); 
     230        } 
     231 
     232        exit(e1); 
    234233}