diff --git a/CHANGES b/CHANGES index ee386a1f..782e6154 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ SVN HEAD Add dme1737 support Delete support of non-sensor drivers (ddcmon, eeprom) Man page sensors.conf.5: Update the chip statement section + Programs i2cdump, i2cget, i2cset: Do not force the slave address by default Program i2cdump: Use the new I2C block read function Program isadump: Detect when address bit 7 is a busy flag Fix Super-I/O exit sequence for Winbond/Fintek chips diff --git a/prog/dump/i2cbusses.c b/prog/dump/i2cbusses.c index 725dd665..5c511f52 100644 --- a/prog/dump/i2cbusses.c +++ b/prog/dump/i2cbusses.c @@ -243,3 +243,17 @@ int open_i2c_dev(const int i2cbus, char *filename, const int quiet) return file; } + +int set_slave_addr(int file, int address, int force) +{ + /* With force, let the user read from/write to the registers + even when a driver is also running */ + if (ioctl(file, force ? I2C_SLAVE_FORCE : I2C_SLAVE, address) < 0) { + fprintf(stderr, + "Error: Could not set address to 0x%02x: %s\n", + address, strerror(errno)); + return -errno; + } + + return 0; +} diff --git a/prog/dump/i2cbusses.h b/prog/dump/i2cbusses.h index 35edb195..d7ecb664 100644 --- a/prog/dump/i2cbusses.h +++ b/prog/dump/i2cbusses.h @@ -24,5 +24,6 @@ void print_i2c_busses(int procfmt); int open_i2c_dev(const int i2cbus, char *filename, const int quiet); +int set_slave_addr(int file, int address, int force); #endif diff --git a/prog/dump/i2cdump.8 b/prog/dump/i2cdump.8 index 6cc758d2..711c79f3 100644 --- a/prog/dump/i2cdump.8 +++ b/prog/dump/i2cdump.8 @@ -1,9 +1,10 @@ -.TH I2CDUMP 8 "April 2006" +.TH I2CDUMP 8 "June 2007" .SH NAME i2cdump \- examine I2C registers .SH SYNOPSIS .B i2cdump +.RB [ -f ] .RB [ -y ] .I i2cbus .I address @@ -22,6 +23,13 @@ visible through the I2C bus. .B -V Display the version and exit. .TP +.B -f +Force access to the device even if it is already busy. By default, i2cdump +will refuse to access a device which is already under the control of a +kernel driver. Using this flag is dangerous, it can seriously confuse the +kernel driver in question. It can also cause i2cdump to return invalid +results. So use at your own risk and only if you know what you're doing. +.TP .B -y Disable interactive mode. By default, i2cdump will wait for a confirmation from the user before messing with the I2C bus. When this flag is used, it diff --git a/prog/dump/i2cdump.c b/prog/dump/i2cdump.c index 77d53a99..e47663ec 100644 --- a/prog/dump/i2cdump.c +++ b/prog/dump/i2cdump.c @@ -31,8 +31,8 @@ void help(void) { - fprintf(stderr, "Syntax: i2cdump [-y] I2CBUS ADDRESS [MODE] [BANK " - "[BANKREG]]\n" + fprintf(stderr, "Syntax: i2cdump [-f] [-y] I2CBUS ADDRESS [MODE] " + "[BANK [BANKREG]]\n" " i2cdump -V\n" " MODE is one of:\n" " b (byte, default)\n" @@ -60,12 +60,13 @@ int main(int argc, char *argv[]) int block[256], s_length = 0; int pec = 0, even = 0; int flags = 0; - int yes = 0, version = 0; + int force = 0, yes = 0, version = 0; /* handle (optional) flags first */ while (1+flags < argc && argv[1+flags][0] == '-') { switch (argv[1+flags][1]) { case 'V': version = 1; break; + case 'f': force = 1; break; case 'y': yes = 1; break; default: fprintf(stderr, "Warning: Unsupported flag " @@ -234,13 +235,8 @@ int main(int argc, char *argv[]) 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)); + if (set_slave_addr(file, address, force) < 0) exit(1); - } if (pec) { if (ioctl(file, I2C_PEC, 1) < 0) { diff --git a/prog/dump/i2cget.8 b/prog/dump/i2cget.8 index 6d7d469f..642343b7 100644 --- a/prog/dump/i2cget.8 +++ b/prog/dump/i2cget.8 @@ -1,9 +1,10 @@ -.TH I2CGET 8 "September 2005" +.TH I2CGET 8 "June 2007" .SH "NAME" i2cget \- read from I2C/SMBus chip registers .SH SYNOPSIS .B i2cget +.RB [ -f ] .RB [ -y ] .I i2cbus .I chip-address @@ -21,6 +22,13 @@ bus (or SMBus). .B -V Display the version and exit. .TP +.B -f +Force access to the device even if it is already busy. By default, i2cget +will refuse to access a device which is already under the control of a +kernel driver. Using this flag is dangerous, it can seriously confuse the +kernel driver in question. It can also cause i2cget to return an invalid +value. So use at your own risk and only if you know what you're doing. +.TP .B -y Disable interactive mode. By default, i2cget will wait for a confirmation from the user before messing with the I2C bus. When this flag is used, it diff --git a/prog/dump/i2cget.c b/prog/dump/i2cget.c index acadb233..314b5192 100644 --- a/prog/dump/i2cget.c +++ b/prog/dump/i2cget.c @@ -36,8 +36,8 @@ void help(void) __attribute__ ((noreturn)); void help(void) { - fprintf(stderr, "Syntax: i2cget [-y] I2CBUS CHIP-ADDRESS [DATA-ADDRESS " - "[MODE]]\n" + fprintf(stderr, "Syntax: i2cget [-f] [-y] I2CBUS CHIP-ADDRESS " + "[DATA-ADDRESS [MODE]]\n" " i2cget -V\n" " MODE can be: 'b' (read byte data, default)\n" " 'w' (read word data)\n" @@ -102,19 +102,6 @@ int check_funcs(int file, int i2cbus, int size, int daddress, int pec) return 0; } -int set_slave(int file, int address) -{ - /* use FORCE so that we can read 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)); - return -1; - } - - return 0; -} - int confirm(const char *filename, int address, int size, int daddress, int pec) { int dont = 0; @@ -173,12 +160,13 @@ int main(int argc, char *argv[]) char filename[20]; int pec = 0; int flags = 0; - int yes = 0, version = 0; + int force = 0, yes = 0, version = 0; /* handle (optional) flags first */ while (1+flags < argc && argv[1+flags][0] == '-') { switch (argv[1+flags][1]) { case 'V': version = 1; break; + case 'f': force = 1; break; case 'y': yes = 1; break; default: fprintf(stderr, "Warning: Unsupported flag " @@ -235,7 +223,7 @@ int main(int argc, char *argv[]) file = open_i2c_dev(i2cbus, filename, 0); if (file < 0 || check_funcs(file, i2cbus, size, daddress, pec) - || set_slave(file, address)) + || set_slave_addr(file, address, force)) exit(1); if (!yes && !confirm(filename, address, size, daddress, pec)) diff --git a/prog/dump/i2cset.8 b/prog/dump/i2cset.8 index a4b64c33..97a5c9bc 100644 --- a/prog/dump/i2cset.8 +++ b/prog/dump/i2cset.8 @@ -1,9 +1,10 @@ -.TH I2CSET 8 "September 2005" +.TH I2CSET 8 "June 2007" .SH "NAME" i2cset \- set I2C registers .SH SYNOPSIS .B i2cset +.RB [ -f ] .RB [ -y ] .I i2cbus .I chip-address @@ -24,6 +25,14 @@ bus. .B -V Display the version and exit. .TP +.B -f +Force access to the device even if it is already busy. By default, i2cset +will refuse to access a device which is already under the control of a +kernel driver. Using this flag is dangerous, it can seriously confuse the +kernel driver in question. It can also cause i2cset to silently write to +the wrong register. So use at your own risk and only if you know what +you're doing. +.TP .B -y Disable interactive mode. By default, i2cset will wait for a confirmation from the user before messing with the I2C bus. When this flag is used, it diff --git a/prog/dump/i2cset.c b/prog/dump/i2cset.c index 2f0b1d35..3be4a9c4 100644 --- a/prog/dump/i2cset.c +++ b/prog/dump/i2cset.c @@ -33,7 +33,7 @@ void help(void) __attribute__ ((noreturn)); void help(void) { - fprintf(stderr, "Syntax: i2cset [-y] I2CBUS CHIP-ADDRESS DATA-ADDRESS " + fprintf(stderr, "Syntax: i2cset [-f] [-y] I2CBUS CHIP-ADDRESS DATA-ADDRESS " "VALUE [MODE] [MASK]\n" " i2cset -V\n" " MODE is 'b[yte]' or 'w[ord]' (default b)\n" @@ -53,12 +53,13 @@ int main(int argc, char *argv[]) unsigned long funcs; int pec = 0; int flags = 0; - int yes = 0, version = 0; + int force = 0, yes = 0, version = 0; /* handle (optional) flags first */ while (1+flags < argc && argv[1+flags][0] == '-') { switch (argv[1+flags][1]) { case 'V': version = 1; break; + case 'f': force = 1; break; case 'y': yes = 1; break; default: fprintf(stderr, "Warning: Unsupported flag " @@ -160,13 +161,8 @@ int main(int argc, char *argv[]) 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)); + if (set_slave_addr(file, address, force) < 0) exit(1); - } if (!yes) { int dont = 0;