Changeset 2673
- Timestamp:
- 08/26/04 23:01:40 (9 years ago)
- Location:
- lm-sensors/trunk/prog/dump
- Files:
-
- 2 modified
Legend:
- Unmodified
- Added
- Removed
-
lm-sensors/trunk/prog/dump/i2cdump.c
r2176 r2673 1 1 /* 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 5 6 6 7 This program is free software; you can redistribute it and/or modify … … 33 34 so we use it as a version check. 34 35 */ 35 #ifdef I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 36 #ifdef I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 36 37 #define USE_I2C_BLOCK 1 37 38 #else … … 47 48 void help(void) 48 49 { 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); 58 61 } 59 62 60 63 int main(int argc, char *argv[]) 61 64 { 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: 228 224 #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: 247 245 #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: 266 266 #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: 285 287 #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) { 321 326 #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 } 326 332 #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 { 364 374 #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 } 372 383 #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); 445 467 } -
lm-sensors/trunk/prog/dump/i2cset.c
r2584 r2673 1 1 /* 2 2 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 5 6 6 7 This program is free software; you can redistribute it and/or modify … … 33 34 void help(void) 34 35 { 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); 40 42 } 41 43 42 44 int main(int argc, char *argv[]) 43 45 { 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); 195 57 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) { 224 220 e1++; 225 221 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); 227 224 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); 234 233 }
