From 2f3df5d0cb2d61ec6208fea9a2a5469fec3b065a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 26 Aug 2004 21:01:40 +0000 Subject: [PATCH] Mass reindent. Drop /dev/i2cN support. git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@2673 7894878c-1315-0410-8ee3-d5d059ff63e0 --- prog/dump/i2cdump.c | 774 +++++++++++++++++++++++--------------------- prog/dump/i2cset.c | 377 +++++++++++---------- 2 files changed, 586 insertions(+), 565 deletions(-) diff --git a/prog/dump/i2cdump.c b/prog/dump/i2cdump.c index c708dc15..c5376601 100644 --- a/prog/dump/i2cdump.c +++ b/prog/dump/i2cdump.c @@ -1,7 +1,8 @@ /* - i2cdump.c - Part of i2cdump, a user-space program to dump I2C registers - Copyright (c) 2002-2003 Frodo Looijaard , and - Mark D. Studebaker + i2cdump.c - a user-space program to dump I2C registers + Copyright (C) 2002-2003 Frodo Looijaard , and + Mark D. Studebaker + Copyright (C) 2004 The lm_sensors group This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,7 +33,7 @@ i2c_smbus_read_i2c_block_data() was implemented (i2c 2.6.3), so we use it as a version check. */ -#ifdef I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 +#ifdef I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 #define USE_I2C_BLOCK 1 #else #define USE_I2C_BLOCK 0 @@ -46,400 +47,421 @@ void print_i2c_busses(int); void help(void) { - fprintf(stderr,"Syntax: i2cdump I2CBUS ADDRESS [MODE] [BANK [BANKREG]]\n"); - fprintf(stderr," MODE is 'b[yte]', 'w[ord]', 's[mbusblock], 'i[2cblock]',\n"); - fprintf(stderr," or 'c[onsecutive byte address mode]' (default b)\n"); - fprintf(stderr," Append MODE with 'p' for PEC checking\n"); - fprintf(stderr," I2CBUS is an integer\n"); - fprintf(stderr," ADDRESS is an integer 0x00 - 0x7f\n"); - fprintf(stderr," BANK and BANKREG are for byte and word accesses (default bank 0, reg 0x4e)\n"); - fprintf(stderr," BANK is the command for smbusblock accesses (default 0)\n"); - print_i2c_busses(0); + fprintf(stderr, "Syntax: i2cdump I2CBUS ADDRESS [MODE] [BANK " + "[BANKREG]]\n" + " MODE is 'b[yte]', 'w[ord]', 's[mbusblock], 'i[2cblock]',\n" + " or 'c[onsecutive byte address mode]' (default b)\n" + " Append MODE with 'p' for PEC checking\n" + " I2CBUS is an integer\n" + " ADDRESS is an integer 0x00 - 0x7f\n" + " BANK and BANKREG are for byte and word accesses (default " + "bank 0, reg 0x4e)\n" + " BANK is the command for smbusblock accesses (default 0)\n"); + print_i2c_busses(0); } int main(int argc, char *argv[]) { - char *end; - int i,j,res,res2,i2cbus,address,size,file; - int e1, e2, e3; - int bank = 0, bankreg = 0x4E; - char filename1[20]; - char filename2[20]; - char filename3[20]; - char *filename; - long funcs; - unsigned char cblock[256]; - int block[256]; - int pec = 0; + char *end; + int i, j, res, res2, i2cbus, address, size, file; + int e1, e2; + int bank = 0, bankreg = 0x4E; + char filename1[20]; + char filename2[20]; + char *filename; + long funcs; + unsigned char cblock[256]; + int block[256]; + int pec = 0; - if (argc < 2) { - fprintf(stderr,"Error: No i2c-bus specified!\n"); - help(); - exit(1); - } - - if((!strcmp(argv[1], "-v")) || (!strcmp(argv[1], "-V"))) { - fprintf(stderr,"i2cdump version %s\n", LM_VERSION); - exit(1); - } - - i2cbus = strtol(argv[1],&end,0); - if (*end) { - fprintf(stderr,"Error: First argument not a number!\n"); - help(); - exit(1); - } - if ((i2cbus < 0) || (i2cbus > 0xff)) { - fprintf(stderr,"Error: I2CBUS argument out of range!\n"); - help(); - } - - if (argc < 3) { - fprintf(stderr,"Error: No address specified!\n"); - help(); - exit(1); - } - address = strtol(argv[2],&end,0); - if (*end) { - fprintf(stderr,"Error: Second argument not a number!\n"); - help(); - exit(1); - } - if ((address < 0) || (address > 0x7f)) { - fprintf(stderr,"Error: Address out of range!\n"); - help(); - } - - if (argc < 4) { - fprintf(stderr,"No size specified (using byte-data access)\n"); - size = I2C_SMBUS_BYTE_DATA; - } else if (!strncmp(argv[3],"b",1)) { - size = I2C_SMBUS_BYTE_DATA; - pec = argv[3][1] == 'p'; - } else if (!strncmp(argv[3],"w",1)) { - size = I2C_SMBUS_WORD_DATA; - pec = argv[3][1] == 'p'; - } else if (!strncmp(argv[3],"s",1)) { - size = I2C_SMBUS_BLOCK_DATA; - pec = argv[3][1] == 'p'; - } else if (!strncmp(argv[3],"c",1)) { - size = I2C_SMBUS_BYTE; - pec = argv[3][1] == 'p'; - } else if (!strcmp(argv[3],"i")) - size = I2C_SMBUS_I2C_BLOCK_DATA; - else { - fprintf(stderr,"Error: Invalid mode!\n"); - help(); - exit(1); - } - - if(argc > 4) { - bank = strtol(argv[4],&end,0); - if (*end || size == I2C_SMBUS_I2C_BLOCK_DATA) { - fprintf(stderr,"Error: Invalid bank number!\n"); - help(); - exit(1); - } - if (((size == I2C_SMBUS_BYTE_DATA) || (size == I2C_SMBUS_WORD_DATA)) && - ((bank < 0) || (bank > 15))) { - fprintf(stderr,"Error: bank out of range!\n"); - help(); - exit(1); - } - if (((size == I2C_SMBUS_BLOCK_DATA)) && - ((bank < 0) || (bank > 0xff))) { - fprintf(stderr,"Error: block command out of range!\n"); - help(); - exit(1); - } - - if(argc > 5) { - bankreg = strtol(argv[5],&end,0); - if (*end || size == I2C_SMBUS_BLOCK_DATA) { - fprintf(stderr,"Error: Invalid bank register number!\n"); - help(); - exit(1); - } - if ((bankreg < 0) || (bankreg > 0xff)) { - fprintf(stderr,"Error: bank out of range (0-0xff)!\n"); - help(); - exit(1); - } - } - } - -/* - * Try all three variants and give the correct error message - * upon failure - */ - - sprintf(filename1,"/dev/i2c-%d",i2cbus); - sprintf(filename2,"/dev/i2c%d",i2cbus); - sprintf(filename3,"/dev/i2c/%d",i2cbus); - if ((file = open(filename1,O_RDWR)) < 0) { - e1 = errno; - if ((file = open(filename2,O_RDWR)) < 0) { - e2 = errno; - if ((file = open(filename3,O_RDWR)) < 0) { - e3 = errno; - if(e1 == ENOENT && e2 == ENOENT && e3 == ENOENT) { - fprintf(stderr,"Error: Could not open file `%s', `%s', or `%s': %s\n", - filename1,filename2,filename3,strerror(ENOENT)); - } - if (e1 != ENOENT) { - fprintf(stderr,"Error: Could not open file `%s' : %s\n", - filename1,strerror(e1)); - if(e1 == EACCES) - fprintf(stderr,"Run as root?\n"); - } - if (e2 != ENOENT) { - fprintf(stderr,"Error: Could not open file `%s' : %s\n", - filename2,strerror(e2)); - if(e2 == EACCES) - fprintf(stderr,"Run as root?\n"); - } - if (e3 != ENOENT) { - fprintf(stderr,"Error: Could not open file `%s' : %s\n", - filename3,strerror(e3)); - if(e3 == EACCES) - fprintf(stderr,"Run as root?\n"); - } - exit(1); - } else { - filename = filename3; - } - } else { - filename = filename2; - } - } else { - filename = filename1; - } - - /* check adapter functionality */ - if (ioctl(file,I2C_FUNCS,&funcs) < 0) { - fprintf(stderr, - "Error: Could not get the adapter functionality matrix: %s\n", - strerror(errno)); - exit(1); - } - - switch(size) { - case I2C_SMBUS_BYTE: -#ifdef HAVE_PEC - if(pec) { - if (! (funcs & I2C_FUNC_SMBUS_READ_BYTE_PEC)) { - fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); - fprintf(stderr, " does not have read w/ PEC capability\n"); - exit(1); - } - } else -#endif - { - if (! (funcs & I2C_FUNC_SMBUS_READ_BYTE)) { - fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); - fprintf(stderr, " does not have read capability\n"); - exit(1); - } + if (argc < 2) { + fprintf(stderr, "Error: No i2c-bus specified!\n"); + help(); + exit(1); } - break; - case I2C_SMBUS_BYTE_DATA: -#ifdef HAVE_PEC - if(pec) { - if (! (funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC)) { - fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); - fprintf(stderr, " does not have byte read w/ PEC capability\n"); - exit(1); - } - } else -#endif - { - if (! (funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA)) { - fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); - fprintf(stderr, " does not have byte read capability\n"); - exit(1); - } + if(!strcmp(argv[1], "-v") || !strcmp(argv[1], "-V")) { + fprintf(stderr, "i2cdump version %s\n", LM_VERSION); + exit(1); } - break; - case I2C_SMBUS_WORD_DATA: -#ifdef HAVE_PEC - if(pec) { - if (! (funcs & I2C_FUNC_SMBUS_READ_WORD_DATA_PEC)) { - fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); - fprintf(stderr, " does not have word read w/ PEC capability\n"); - exit(1); - } - } else -#endif - { - if (! (funcs & I2C_FUNC_SMBUS_READ_WORD_DATA)) { - fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); - fprintf(stderr, " does not have word read capability\n"); - exit(1); - } + i2cbus = strtol(argv[1], &end, 0); + if (*end) { + fprintf(stderr, "Error: First argument not a number!\n"); + help(); + exit(1); } - break; - - case I2C_SMBUS_BLOCK_DATA: -#ifdef HAVE_PEC - if(pec) { - if (! (funcs & I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC)) { - fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); - fprintf(stderr, " does not have smbus block read capability\n"); - exit(1); - } - } else -#endif - { - if (! (funcs & I2C_FUNC_SMBUS_READ_BLOCK_DATA)) { - fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); - fprintf(stderr, " does not have smbus block read w/ PEC capability\n"); - exit(1); - } + if (i2cbus < 0 || i2cbus > 0xff) { + fprintf(stderr, "Error: I2CBUS argument out of range!\n"); + help(); + exit(1); } - break; - case I2C_SMBUS_I2C_BLOCK_DATA: - if (! (funcs & I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { - fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); - fprintf(stderr, " does not have i2c block read capability\n"); - exit(1); - } - break; + if (argc < 3) { + fprintf(stderr, "Error: No address specified!\n"); + help(); + exit(1); + } + address = strtol(argv[2], &end, 0); + if (*end) { + fprintf(stderr, "Error: Second argument not a number!\n"); + help(); + exit(1); + } + if (address < 0 || address > 0x7f) { + fprintf(stderr, "Error: Address out of range!\n"); + help(); + exit(1); + } - } - /* use FORCE so that we can look at registers even when - a driver is also running */ - if (ioctl(file,I2C_SLAVE_FORCE,address) < 0) { - fprintf(stderr,"Error: Could not set address to %d: %s\n",address, - strerror(errno)); - exit(1); - } - - if(pec) { + if (argc < 4) { + fprintf(stderr, "No size specified (using byte-data access)\n"); + size = I2C_SMBUS_BYTE_DATA; + } else if (!strncmp(argv[3], "b", 1)) { + size = I2C_SMBUS_BYTE_DATA; + pec = argv[3][1] == 'p'; + } else if (!strncmp(argv[3], "w", 1)) { + size = I2C_SMBUS_WORD_DATA; + pec = argv[3][1] == 'p'; + } else if (!strncmp(argv[3], "s", 1)) { + size = I2C_SMBUS_BLOCK_DATA; + pec = argv[3][1] == 'p'; + } else if (!strncmp(argv[3], "c", 1)) { + size = I2C_SMBUS_BYTE; + pec = argv[3][1] == 'p'; + } else if (!strcmp(argv[3], "i")) + size = I2C_SMBUS_I2C_BLOCK_DATA; + else { + fprintf(stderr, "Error: Invalid mode!\n"); + help(); + exit(1); + } + + if (argc > 4) { + bank = strtol(argv[4], &end, 0); + if (*end || size == I2C_SMBUS_I2C_BLOCK_DATA) { + fprintf(stderr, "Error: Invalid bank number!\n"); + help(); + exit(1); + } + if ((size == I2C_SMBUS_BYTE_DATA || size == I2C_SMBUS_WORD_DATA) + && (bank < 0 || bank > 15)) { + fprintf(stderr, "Error: bank out of range!\n"); + help(); + exit(1); + } + if (size == I2C_SMBUS_BLOCK_DATA + && (bank < 0 || bank > 0xff)) { + fprintf(stderr, "Error: block command out of range!\n"); + help(); + exit(1); + } + + if (argc > 5) { + bankreg = strtol(argv[5], &end, 0); + if (*end || size == I2C_SMBUS_BLOCK_DATA) { + fprintf(stderr, "Error: Invalid bank register " + "number!\n"); + help(); + exit(1); + } + if (bankreg < 0 || bankreg > 0xff) { + fprintf(stderr, "Error: bank out of range " + "(0-0xff)!\n"); + help(); + exit(1); + } + } + } + + /* + * Try both variants and give the correct error message + * upon failure + */ + + sprintf(filename1, "/dev/i2c-%d", i2cbus); + sprintf(filename2, "/dev/i2c/%d", i2cbus); + if ((file = open(filename1, O_RDWR)) < 0) { + e1 = errno; + if ((file = open(filename2, O_RDWR)) < 0) { + e2 = errno; + if (e1 == ENOENT && e2 == ENOENT) { + fprintf(stderr, "Error: Could not open file " + "`%s' or `%s': %s\n", filename1, + filename2, strerror(ENOENT)); + } + if (e1 != ENOENT) { + fprintf(stderr, "Error: Could not open file " + "`%s': %s\n", filename1, + strerror(e1)); + if (e1 == EACCES) + fprintf(stderr, "Run as root?\n"); + } + if (e2 != ENOENT) { + fprintf(stderr, "Error: Could not open file " + "`%s' : %s\n", filename2, + strerror(e2)); + if (e2 == EACCES) + fprintf(stderr, "Run as root?\n"); + } + exit(1); + } else { + filename = filename2; + } + } else { + filename = filename1; + } + + /* check adapter functionality */ + if (ioctl(file, I2C_FUNCS, &funcs) < 0) { + fprintf(stderr, "Error: Could not get the adapter " + "functionality matrix: %s\n", strerror(errno)); + exit(1); + } + + switch(size) { + case I2C_SMBUS_BYTE: #ifdef HAVE_PEC - if (ioctl(file,I2C_PEC, 1) < 0) { - fprintf(stderr,"Error: Could not set PEC: %s\n", strerror(errno)); - exit(1); - } + if (pec) { + if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE_PEC)) { + fprintf(stderr, "Error: Adapter for i2c bus " + "%d does not have read w/ PEC " + "capability\n", i2cbus); + exit(1); + } + } else +#endif + { + if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE)) { + fprintf(stderr, "Error: Adapter for i2c bus " + "%d does not have read capability\n", + i2cbus); + exit(1); + } + } + break; + + case I2C_SMBUS_BYTE_DATA: +#ifdef HAVE_PEC + if (pec) { + if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC)) { + fprintf(stderr, "Error: Adapter for i2c bus " + "%d does not have byte read w/ PEC " + "capability\n", i2cbus); + exit(1); + } + } else +#endif + { + if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + fprintf(stderr, "Error: Adapter for i2c bus " + "%d does not have byte read " + "capability\n", i2cbus); + exit(1); + } + } + break; + + case I2C_SMBUS_WORD_DATA: +#ifdef HAVE_PEC + if (pec) { + if (!(funcs & I2C_FUNC_SMBUS_READ_WORD_DATA_PEC)) { + fprintf(stderr, "Error: Adapter for i2c bus " + "%d does not have word read w/ PEC " + "capability\n", i2cbus); + exit(1); + } + } else +#endif + { + if (!(funcs & I2C_FUNC_SMBUS_READ_WORD_DATA)) { + fprintf(stderr, "Error: Adapter for i2c bus " + "%d does not have word read " + "capability\n", i2cbus); + exit(1); + } + } + break; + + case I2C_SMBUS_BLOCK_DATA: +#ifdef HAVE_PEC + if (pec) { + if (!(funcs & I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC)) { + fprintf(stderr, "Error: Adapter for i2c bus " + "%d does not have smbus block read " + "w/ PEC capability\n", i2cbus); + exit(1); + } + } else +#endif + { + if (!(funcs & I2C_FUNC_SMBUS_READ_BLOCK_DATA)) { + fprintf(stderr, "Error: Adapter for i2c bus " + "%d does not have smbus block read " + "capability\n", i2cbus); + exit(1); + } + } + break; + + case I2C_SMBUS_I2C_BLOCK_DATA: + if (!(funcs & I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + fprintf(stderr, "Error: Adapter for i2c bus %d does " + "not have i2c block read capability\n", + i2cbus); + exit(1); + } + break; + } + + /* use FORCE so that we can look at registers even when + a driver is also running */ + if (ioctl(file, I2C_SLAVE_FORCE, address) < 0) { + fprintf(stderr, "Error: Could not set address to %d: %s\n", + address, strerror(errno)); + exit(1); + } + + if (pec) { +#ifdef HAVE_PEC + if (ioctl(file, I2C_PEC, 1) < 0) { + fprintf(stderr, "Error: Could not set PEC: %s\n", + strerror(errno)); + exit(1); + } #else - fprintf(stderr,"Error: PEC not supported in your kernel\n"); - exit(1); + fprintf(stderr, "Error: PEC not supported in your kernel\n"); + exit(1); #endif - } + } - fprintf(stderr," WARNING! This program can confuse your I2C bus, " - "cause data loss and worse!\n"); - fprintf(stderr," I will probe file %s, address 0x%x, mode %s\n", - filename,address,size == I2C_SMBUS_BLOCK_DATA ? "smbus block" : - size == I2C_SMBUS_I2C_BLOCK_DATA ? "i2c block" : - size == I2C_SMBUS_BYTE ? "byte consecutive read" : - size == I2C_SMBUS_BYTE_DATA ? "byte" : "word"); - if(pec) - fprintf(stderr," with PEC checking.\n"); - if(bank) { - if(size == I2C_SMBUS_BLOCK_DATA) - fprintf(stderr," Using command 0x%02x.\n", bank); - else - fprintf(stderr," Probing bank %d using bank register 0x%02x.\n", - bank, bankreg); - } - fprintf(stderr," You have five seconds to reconsider and press CTRL-C!\n\n"); - sleep(5); + fprintf(stderr, "WARNING! This program can confuse your I2C bus, " + "cause data loss and worse!\n"); + fprintf(stderr, "I will probe file %s, address 0x%x, mode %s\n", + filename, address, + size == I2C_SMBUS_BLOCK_DATA ? "smbus block" : + size == I2C_SMBUS_I2C_BLOCK_DATA ? "i2c block" : + size == I2C_SMBUS_BYTE ? "byte consecutive read" : + size == I2C_SMBUS_BYTE_DATA ? "byte" : "word"); + if (pec) + fprintf(stderr, "PEC checking enabled.\n"); + if (bank) { + if (size == I2C_SMBUS_BLOCK_DATA) + fprintf(stderr, "Using command 0x%02x.\n", bank); + else + fprintf(stderr, "Probing bank %d using bank register " + "0x%02x.\n", bank, bankreg); + } + fprintf(stderr, "You have five seconds to reconsider and press " + "CTRL-C!\n\n"); + sleep(5); - /* See Winbond w83781d data sheet for bank details */ - if(bank && size != I2C_SMBUS_BLOCK_DATA) { - i2c_smbus_write_byte_data(file,bankreg,bank | 0x80); - } + /* See Winbond w83781d data sheet for bank details */ + if (bank && size != I2C_SMBUS_BLOCK_DATA) { + i2c_smbus_write_byte_data(file, bankreg, bank | 0x80); + } - /* handle all but word data */ - if (size != I2C_SMBUS_WORD_DATA) { + /* handle all but word data */ + if (size != I2C_SMBUS_WORD_DATA) { - /* do the block transaction */ - if(size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) { - if(size == I2C_SMBUS_BLOCK_DATA) { - res = i2c_smbus_read_block_data(file, bank, cblock); - } else { + /* do the block transaction */ + if (size == I2C_SMBUS_BLOCK_DATA + || size == I2C_SMBUS_I2C_BLOCK_DATA) { + if (size == I2C_SMBUS_BLOCK_DATA) { + res = i2c_smbus_read_block_data(file, bank, + cblock); + } else { #if USE_I2C_BLOCK - res = 0; - for (i = 0; i < 256; i+=32) { - res2 = i2c_smbus_read_i2c_block_data(file, i, cblock+i); - if(res2 <= 0) - break; - res += res2; - } + res = 0; + for (i = 0; i < 256; i+=32) { + res2 = i2c_smbus_read_i2c_block_data(file, + i, cblock+i); + if (res2 <= 0) + break; + res += res2; + } #else - fprintf(stderr, "Error: I2C block read unsupported in i2c-core\n"); - exit(1); + fprintf(stderr, "Error: I2C block read " + "unsupported in i2c-core\n"); + exit(1); #endif - } - if(res <= 0) { - fprintf(stderr, "Error: Block read failed, return code %d\n", res); - exit(1); - } - if(res >= 256) - res = 256; - for (i = 0; i < res; i++) - block[i] = cblock[i]; - for (i = res; i < 256; i++) - block[i] = -1; - } + } + if (res <= 0) { + fprintf(stderr, "Error: Block read failed, " + "return code %d\n", res); + exit(1); + } + if (res >= 256) + res = 256; + for (i = 0; i < res; i++) + block[i] = cblock[i]; + for (i = res; i < 256; i++) + block[i] = -1; + } - if(size == I2C_SMBUS_BYTE) { - res = i2c_smbus_write_byte(file, 0); - if(res != 0) { - fprintf(stderr, "Error: Write start address failed, return code %d\n", res); - exit(1); - } - } - printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef\n"); - for (i = 0; i < 256; i+=16) { - printf("%02x: ",i); - for(j = 0; j < 16; j++) { - if(size == I2C_SMBUS_BYTE_DATA) { - block[i+j] = res = i2c_smbus_read_byte_data(file,i+j); - } else if(size == I2C_SMBUS_BYTE) { - block[i+j] = res = i2c_smbus_read_byte(file); - } else - res = block[i+j]; - if (res < 0) - printf("XX "); - else - printf("%02x ",res & 0xff); - } - printf(" "); - for(j = 0; j < 16; j++) { - res = block[i+j]; - if (res < 0) - printf("X"); - else if (((res & 0xff) == 0x00) || ((res & 0xff) == 0xff)) - printf("."); - else if (((res & 0xff) < 32) || ((res & 0xff) >= 127)) - printf("?"); - else - printf("%c",res & 0xff); - } - printf("\n"); - if(size == I2C_SMBUS_BLOCK_DATA && i == 16) - break; - } - } else { - printf(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f\n"); - for (i = 0; i < 256; i+=8) { - printf("%02x: ",i); - for(j = 0; j < 8; j++) { - res = i2c_smbus_read_word_data(file,i+j); - if (res < 0) - printf("XXXX "); - else - printf("%04x ",res & 0xffff); - } - printf("\n"); - } - } - if(bank && size != I2C_SMBUS_BLOCK_DATA) { - i2c_smbus_write_byte_data(file,bankreg,0x80); - } - exit(0); + if (size == I2C_SMBUS_BYTE) { + res = i2c_smbus_write_byte(file, 0); + if(res != 0) { + fprintf(stderr, "Error: Write start address " + "failed, return code %d\n", res); + exit(1); + } + } + + printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f" + " 0123456789abcdef\n"); + for (i = 0; i < 256; i+=16) { + printf("%02x: ", i); + for (j = 0; j < 16; j++) { + if (size == I2C_SMBUS_BYTE_DATA) { + block[i+j] = res = + i2c_smbus_read_byte_data(file, i+j); + } else if (size == I2C_SMBUS_BYTE) { + block[i+j] = res = + i2c_smbus_read_byte(file); + } else + res = block[i+j]; + if (res < 0) + printf("XX "); + else + printf("%02x ", res & 0xff); + } + printf(" "); + for (j = 0; j < 16; j++) { + res = block[i+j]; + if (res < 0) + printf("X"); + else + if ((res & 0xff) == 0x00 + || (res & 0xff) == 0xff) + printf("."); + else + if ((res & 0xff) < 32 + || (res & 0xff) >= 127) + printf("?"); + else + printf("%c", res & 0xff); + } + printf("\n"); + if (size == I2C_SMBUS_BLOCK_DATA && i == 16) + break; + } + } else { + printf(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f\n"); + for (i = 0; i < 256; i+=8) { + printf("%02x: ", i); + for (j = 0; j < 8; j++) { + res = i2c_smbus_read_word_data(file, i+j); + if (res < 0) + printf("XXXX "); + else + printf("%04x ", res & 0xffff); + } + printf("\n"); + } + } + if (bank && size != I2C_SMBUS_BLOCK_DATA) { + i2c_smbus_write_byte_data(file, bankreg, 0x80); + } + exit(0); } diff --git a/prog/dump/i2cset.c b/prog/dump/i2cset.c index f1f2bb6b..8d19334f 100644 --- a/prog/dump/i2cset.c +++ b/prog/dump/i2cset.c @@ -1,7 +1,8 @@ /* i2cset.c - A user-space program to write an I2C register. - Copyright (c) 2001-2003 Frodo Looijaard , and - Mark D. Studebaker + Copyright (C) 2001-2003 Frodo Looijaard , and + Mark D. Studebaker + Copyright (C) 2004 The lm_sensors group This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,203 +33,201 @@ void help(void) __attribute__ ((noreturn)); void help(void) { - fprintf(stderr,"Syntax: i2cset I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE [MODE]\n"); - fprintf(stderr," MODE is 'b[yte]' or 'w[ord]' (default b)\n"); - fprintf(stderr," I2CBUS is an integer\n"); - print_i2c_busses(0); - exit(1); + fprintf(stderr, "Syntax: i2cset I2CBUS CHIP-ADDRESS DATA-ADDRESS " + "VALUE [MODE]\n"); + fprintf(stderr, " MODE is 'b[yte]' or 'w[ord]' (default b)\n"); + fprintf(stderr, " I2CBUS is an integer\n"); + print_i2c_busses(0); + exit(1); } int main(int argc, char *argv[]) { - char *end; - int res,i2cbus,address,size,file; - int value, daddress; - int e1, e2, e3; - char filename1[20]; - char filename2[20]; - char filename3[20]; - char *filename; - long funcs; + char *end; + int res, i2cbus, address, size, file; + int value, daddress; + int e1, e2; + char filename1[20]; + char filename2[20]; + char *filename; + long funcs; - if(argc >= 2 && ((!strcmp(argv[1], "-v")) || (!strcmp(argv[1], "-V")))) { - fprintf(stderr,"i2cset version %s\n", LM_VERSION); - exit(1); - } - - if (argc < 5) - help(); - - i2cbus = strtol(argv[1],&end,0); - if (*end || (i2cbus < 0) || (i2cbus > 0x3f)) { - fprintf(stderr,"Error: I2CBUS argument invalid!\n"); - help(); - } - - address = strtol(argv[2],&end,0); - if (*end || (address < 0) || (address > 0x7f)) { - fprintf(stderr,"Error: Chip address invalid!\n"); - help(); - } - - daddress = strtol(argv[3],&end,0); - if (*end || (daddress < 0) || (daddress > 0xff)) { - fprintf(stderr,"Error: Data address invalid!\n"); - help(); - } - - value = strtol(argv[4],&end,0); - if (*end) { - fprintf(stderr,"Error: Data value invalid!\n"); - help(); - } - - if (argc < 6) { - fprintf(stderr,"Warning: no size specified (using byte-data access)\n"); - size = I2C_SMBUS_BYTE_DATA; - } else if (!strcmp(argv[5],"b")) - size = I2C_SMBUS_BYTE_DATA; - else if (!strcmp(argv[5],"w")) - size = I2C_SMBUS_WORD_DATA; - else { - fprintf(stderr,"Error: Invalid mode!\n"); - help(); - } - - if ((value < 0) || ((size == I2C_SMBUS_BYTE_DATA) && (value > 0xff)) - || ((size == I2C_SMBUS_WORD_DATA) && (value > 0x0ffff))) { - fprintf(stderr,"Error: Data value out of range!\n"); - help(); - } - -/* - * Try all three variants and give the correct error message - * upon failure - */ - - sprintf(filename1,"/dev/i2c-%d",i2cbus); - sprintf(filename2,"/dev/i2c%d",i2cbus); - sprintf(filename3,"/dev/i2c/%d",i2cbus); - if ((file = open(filename1,O_RDWR)) < 0) { - e1 = errno; - if ((file = open(filename2,O_RDWR)) < 0) { - e2 = errno; - if ((file = open(filename3,O_RDWR)) < 0) { - e3 = errno; - if(e1 == ENOENT && e2 == ENOENT && e3 == ENOENT) { - fprintf(stderr,"Error: Could not open file `%s', `%s', or `%s': %s\n", - filename1,filename2,filename3,strerror(ENOENT)); - } - if (e1 != ENOENT) { - fprintf(stderr,"Error: Could not open file `%s' : %s\n", - filename1,strerror(e1)); - if(e1 == EACCES) - fprintf(stderr,"Run as root?\n"); - } - if (e2 != ENOENT) { - fprintf(stderr,"Error: Could not open file `%s' : %s\n", - filename2,strerror(e2)); - if(e2 == EACCES) - fprintf(stderr,"Run as root?\n"); - } - if (e3 != ENOENT) { - fprintf(stderr,"Error: Could not open file `%s' : %s\n", - filename3,strerror(e3)); - if(e3 == EACCES) - fprintf(stderr,"Run as root?\n"); - } - exit(1); - } else { - filename = filename3; - } - } else { - filename = filename2; - } - } else { - filename = filename1; - } - - /* check adapter functionality */ - if (ioctl(file,I2C_FUNCS,&funcs) < 0) { - fprintf(stderr, - "Error: Could not get the adapter functionality matrix: %s\n", - strerror(errno)); - exit(1); - } - - switch(size) { - case I2C_SMBUS_BYTE_DATA: - if (! (funcs & - (I2C_FUNC_SMBUS_WRITE_BYTE_DATA | I2C_FUNC_SMBUS_READ_BYTE_DATA))) { - fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); - fprintf(stderr, " does not have byte write capability\n"); - exit(1); - } - break; - - case I2C_SMBUS_WORD_DATA: - if (! (funcs & - (I2C_FUNC_SMBUS_WRITE_WORD_DATA | I2C_FUNC_SMBUS_READ_WORD_DATA))) { - fprintf(stderr, "Error: Adapter for i2c bus %d", i2cbus); - fprintf(stderr, " does not have word write capability\n"); - exit(1); - } - break; - - } - /* use FORCE so that we can write registers even when - a driver is also running */ - if (ioctl(file,I2C_SLAVE_FORCE,address) < 0) { - fprintf(stderr,"Error: Could not set address to %d: %s\n",address, - strerror(errno)); - exit(1); - } - - fprintf(stderr," WARNING! This program can confuse your I2C bus, " - "cause data loss and worse!\n"); - if(address >= 0x50 && address <= 0x57) { - fprintf(stderr, "DANGEROUS!! Writing to a serial EEPROM on a memory DIMM\n"); - fprintf(stderr, "may render your memory USELESS and make your system UNBOOTABLE!!!\n"); - fprintf(stderr, "Are you SURE that you want to write to the chip at address 0x%.2x? (n) ", address); - res = getchar(); - if(res != 'y' && res != 'Y') + if (argc >= 2 && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "-V"))) { + fprintf(stderr, "i2cset version %s\n", LM_VERSION); exit(1); - } - fprintf(stderr," I will write to device file %s, chip address 0x%02x, data address\n" - " 0x%02x, data 0x%02x, mode %s.\n", - filename, address, daddress, value, - size == I2C_SMBUS_BYTE_DATA ? "byte" : "word"); - fprintf(stderr," You have five seconds to reconsider and press CTRL-C!\n\n"); - sleep(5); + } - e1 = 0; - if (size == I2C_SMBUS_WORD_DATA) { - res = i2c_smbus_write_word_data(file, daddress, value); - } else { - res = i2c_smbus_write_byte_data(file, daddress, value); - } - if(res < 0) { - fprintf(stderr, "Warning - write failed\n"); - e1++; - } - if (size == I2C_SMBUS_WORD_DATA) { - res = i2c_smbus_read_word_data(file, daddress); - } else { - res = i2c_smbus_read_byte_data(file, daddress); - } - if(res < 0) { - fprintf(stderr, "Warning - readback failed\n"); - e1++; - } else { - if(res != value) { + if (argc < 5) + help(); + + i2cbus = strtol(argv[1], &end, 0); + if (*end || i2cbus < 0 || i2cbus > 0x3f) { + fprintf(stderr, "Error: I2CBUS argument invalid!\n"); + help(); + } + + address = strtol(argv[2], &end, 0); + if (*end || address < 0 || address > 0x7f) { + fprintf(stderr, "Error: Chip address invalid!\n"); + help(); + } + + daddress = strtol(argv[3], &end, 0); + if (*end || daddress < 0 || daddress > 0xff) { + fprintf(stderr, "Error: Data address invalid!\n"); + help(); + } + + value = strtol(argv[4], &end, 0); + if (*end) { + fprintf(stderr, "Error: Data value invalid!\n"); + help(); + } + + if (argc < 6) { + fprintf(stderr, "No size specified (using byte-data access)\n"); + size = I2C_SMBUS_BYTE_DATA; + } else if (!strcmp(argv[5], "b")) + size = I2C_SMBUS_BYTE_DATA; + else if (!strcmp(argv[5], "w")) + size = I2C_SMBUS_WORD_DATA; + else { + fprintf(stderr, "Error: Invalid mode!\n"); + help(); + } + + if (value < 0 + || (size == I2C_SMBUS_BYTE_DATA && value > 0xff) + || (size == I2C_SMBUS_WORD_DATA && value > 0xffff)) { + fprintf(stderr, "Error: Data value out of range!\n"); + help(); + } + + /* + * Try both variants and give the correct error message + * upon failure + */ + + sprintf(filename1, "/dev/i2c-%d", i2cbus); + sprintf(filename2, "/dev/i2c/%d", i2cbus); + if ((file = open(filename1, O_RDWR)) < 0) { + e1 = errno; + if ((file = open(filename2, O_RDWR)) < 0) { + e2 = errno; + if (e1 == ENOENT && e2 == ENOENT) { + fprintf(stderr, "Error: Could not open file " + "`%s' or `%s': %s\n", filename1, + filename2, strerror(ENOENT)); + } + if (e1 != ENOENT) { + fprintf(stderr, "Error: Could not open file " + ":`%s': %s\n", filename1, + strerror(e1)); + if (e1 == EACCES) + fprintf(stderr, "Run as root?\n"); + } + if (e2 != ENOENT) { + fprintf(stderr, "Error: Could not open file " + "`%s' : %s\n", filename2, + strerror(e2)); + if (e2 == EACCES) + fprintf(stderr, "Run as root?\n"); + } + exit(1); + } else { + filename = filename2; + } + } else { + filename = filename1; + } + + /* check adapter functionality */ + if (ioctl(file, I2C_FUNCS, &funcs) < 0) { + fprintf(stderr, "Error: Could not get the adapter " + "functionality matrix: %s\n", strerror(errno)); + exit(1); + } + + switch (size) { + case I2C_SMBUS_BYTE_DATA: + if (!(funcs & I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + fprintf(stderr, "Error: Adapter for i2c bus %d does " + "not have byte write capability\n", i2cbus); + exit(1); + } + break; + + case I2C_SMBUS_WORD_DATA: + if (!(funcs & I2C_FUNC_SMBUS_WRITE_WORD_DATA)) { + fprintf(stderr, "Error: Adapter for i2c bus %d does " + "not have word write capability\n", i2cbus); + exit(1); + } + break; + } + + /* use FORCE so that we can write registers even when + a driver is also running */ + if (ioctl(file, I2C_SLAVE_FORCE, address) < 0) { + fprintf(stderr, "Error: Could not set address to %d: %s\n", + address, strerror(errno)); + exit(1); + } + + fprintf(stderr, "WARNING! This program can confuse your I2C bus, " + "cause data loss and worse!\n"); + if (address >= 0x50 && address <= 0x57) { + fprintf(stderr, "DANGEROUS!! Writing to a serial EEPROM on " + "a memory DIMM\nmay render your memory USELESS and " + "make your system UNBOOTABLE!!!\nAre you SURE that " + "you want to write to the chip at address 0x%02x? " + "(y/N) ", address); + res = getchar(); + if (res != 'y' && res != 'Y') + exit(1); + } + + fprintf(stderr, "I will write to device file %s, chip address 0x%02x, " + "data address\n0x%02x, data 0x%02x, mode %s.\n", filename, + address, daddress, value, size == I2C_SMBUS_BYTE_DATA ? + "byte" : "word"); + fprintf(stderr, "You have five seconds to reconsider and press " + "CTRL-C!\n\n"); + sleep(5); + + e1 = 0; + if (size == I2C_SMBUS_WORD_DATA) { + res = i2c_smbus_write_word_data(file, daddress, value); + } else { + res = i2c_smbus_write_byte_data(file, daddress, value); + } + if (res < 0) { + fprintf(stderr, "Warning - write failed\n"); + e1++; + } + + if (size == I2C_SMBUS_WORD_DATA) { + res = i2c_smbus_read_word_data(file, daddress); + } else { + res = i2c_smbus_read_byte_data(file, daddress); + } + + if (res < 0) { + fprintf(stderr, "Warning - readback failed\n"); + e1++; + } else + if (res != value) { e1++; if (size == I2C_SMBUS_WORD_DATA) - fprintf(stderr, "Warning - data mismatch - wrote 0x%.4x, read back 0x%.4x\n", value, res); + fprintf(stderr, "Warning - data mismatch - wrote " + "0x%04x, read back 0x%04x\n", value, res); else - fprintf(stderr, "Warning - data mismatch - wrote 0x%.2x, read back 0x%.2x\n", value, res); + fprintf(stderr, "Warning - data mismatch - wrote " + "0x%02x, read back 0x%02x\n", value, res); } else { - fprintf(stderr, "Value 0x%x written, readback matched\n", value); + fprintf(stderr, "Value 0x%x written, readback matched\n", + value); } - } - exit(e1); + + exit(e1); }