diff --git a/prog/dump/i2cdump.8 b/prog/dump/i2cdump.8 index 4f9ea461..d81fc502 100644 --- a/prog/dump/i2cdump.8 +++ b/prog/dump/i2cdump.8 @@ -1,4 +1,4 @@ -.TH I2CDUMP 8 "August 2004" +.TH I2CDUMP 8 "April 2006" .SH NAME i2cdump \- examine I2C registers @@ -31,13 +31,18 @@ scripts. At least two options must be provided to i2cdump. \fIi2cbus\fR indicates the number of the I2C bus to be scanned. This number should correspond to one of the busses listed by \fIi2cdetect -l\fR. \fIaddress\fR indicates the -address to be scanned on that bus, and is an integer between 0x00 and 0x7F. The -\fImode\fR parameter, if specified, is one of the letters \fBb\fP, \fBw\fP, +address to be scanned on that bus, and is an integer between 0x00 and 0x7F. +.PP +The \fImode\fR parameter, if specified, is one of the letters \fBb\fP, \fBw\fP, \fBs\fP, or \fBi\fP, corresponding to a read size of a single byte, a 16-bit word, an SMBus block, an I2C block, respectively. The \fBc\fP mode is a little different, it reads all bytes consecutively, and is useful for chips that -have an address auto-increment feature. A \fBp\fP can also be appended to the -\fImode\fR parameter to enable PEC. If the \fImode\fR parameter is omitted, +have an address auto-increment feature, such as EEPROMs. The \fBW\fP mode is +also special, it is similar to \fBw\fP except that a read command will only +be issued on even register addresses; this is again mainly useful for EEPROMs. +.PP +A \fBp\fP can also be appended to the \fImode\fR parameter (except for +\fBi\fP and \fBW\fP) to enable PEC. If the \fImode\fR parameter is omitted, i2cdump defaults to byte access without PEC. .PP The \fIbank\fR and \fIbankreg\fR parameters are useful on the W83781D and diff --git a/prog/dump/i2cdump.c b/prog/dump/i2cdump.c index 41da0e18..2d72114e 100644 --- a/prog/dump/i2cdump.c +++ b/prog/dump/i2cdump.c @@ -33,9 +33,14 @@ void help(void) fprintf(stderr, "Syntax: i2cdump [-y] I2CBUS ADDRESS [MODE] [BANK " "[BANKREG]]\n" " i2cdump -V\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" + " MODE is one of:\n" + " b (byte, default)\n" + " w (word)\n" + " W (word on even register addresses)\n" + " s (SMBus block)\n" + " i (I2C block)\n" + " c (consecutive byte)\n" + " Append 'p' to 'b', 'w', 's' or 'c' 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 " @@ -52,7 +57,7 @@ int main(int argc, char *argv[]) char filename[20]; long funcs; int block[256]; - int pec = 0; + int pec = 0, even = 0; int flags = 0; int yes = 0, version = 0; @@ -118,6 +123,9 @@ int main(int argc, char *argv[]) } else if (!strncmp(argv[flags+3], "w", 1)) { size = I2C_SMBUS_WORD_DATA; pec = argv[flags+3][1] == 'p'; + } else if (!strncmp(argv[flags+3], "W", 1)) { + size = I2C_SMBUS_WORD_DATA; + even = 1; } else if (!strncmp(argv[flags+3], "s", 1)) { size = I2C_SMBUS_BLOCK_DATA; pec = argv[flags+3][1] == 'p'; @@ -259,6 +267,9 @@ int main(int argc, char *argv[]) size == I2C_SMBUS_BYTE_DATA ? "byte" : "word"); if (pec) fprintf(stderr, "PEC checking enabled.\n"); + if (even) + fprintf(stderr, "Only probing even register " + "addresses.\n"); if (bank) { if (size == I2C_SMBUS_BLOCK_DATA) fprintf(stderr, "Using command 0x%02x.\n", @@ -290,8 +301,7 @@ int main(int argc, char *argv[]) } /* handle all but word data */ - if (size != I2C_SMBUS_WORD_DATA) { - + if (size != I2C_SMBUS_WORD_DATA || even) { /* do the block transaction */ if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) { @@ -338,15 +348,33 @@ int main(int argc, char *argv[]) if (size == I2C_SMBUS_BYTE_DATA) { block[i+j] = res = i2c_smbus_read_byte_data(file, i+j); + } else if (size == I2C_SMBUS_WORD_DATA) { + res = i2c_smbus_read_word_data(file, + i+j); + if (res < 0) { + block[i+j] = res; + block[i+j+1] = res; + } else { + block[i+j] = res & 0xff; + block[i+j+1] = res >> 8; + } } else if (size == I2C_SMBUS_BYTE) { block[i+j] = res = i2c_smbus_read_byte(file); } else res = block[i+j]; - if (res < 0) + + if (res < 0) { printf("XX "); - else - printf("%02x ", res & 0xff); + if (size == I2C_SMBUS_WORD_DATA) + printf("XX "); + } else { + printf("%02x ", block[i+j]); + if (size == I2C_SMBUS_WORD_DATA) + printf("%02x ", block[i+j+1]); + } + if (size == I2C_SMBUS_WORD_DATA) + j++; } printf(" "); for (j = 0; j < 16; j++) {