summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorkhali <khali@7894878c-1315-0410-8ee3-d5d059ff63e0>2008-05-05 12:38:22 +0000
committerkhali <khali@7894878c-1315-0410-8ee3-d5d059ff63e0>2008-05-05 12:38:22 +0000
commit9271ba9758533a49f00f44016d86d48cd824ed38 (patch)
tree8e4e64aa265d71a865e5c599ee90551b90c9ed78 /tools
parentd7be9fb71c03ce7383ed64194b4fb9891d14521f (diff)
downloadi2c-tools-9271ba9758533a49f00f44016d86d48cd824ed38.tar.gz
Add support for short writes (SMBus send byte).
git-svn-id: http://lm-sensors.org/svn/i2c-tools/trunk@5237 7894878c-1315-0410-8ee3-d5d059ff63e0
Diffstat (limited to 'tools')
-rw-r--r--tools/i2cset.815
-rw-r--r--tools/i2cset.c63
2 files changed, 55 insertions, 23 deletions
diff --git a/tools/i2cset.8 b/tools/i2cset.8
index 196f7e4..136a9ea 100644
--- a/tools/i2cset.8
+++ b/tools/i2cset.8
@@ -9,8 +9,7 @@ i2cset \- set I2C registers
.I i2cbus
.I chip-address
.I data-address
-.I value
-.RI [ "mode " [ mask ]]
+.RI [ "value " [ "mode " [ mask ]]]
.br
.B i2cset
.B -V
@@ -38,13 +37,19 @@ from the user before messing with the I2C bus. When this flag is used, it
will perform the operation directly. This is mainly meant to be used in
scripts.
.PP
-There are four required options to i2cset. \fIi2cbus\fR indicates the number
+There are three required options to i2cset. \fIi2cbus\fR indicates the number
or name of the I2C bus to be scanned. This number should correspond to one of
the busses listed by \fIi2cdetect -l\fR. \fIchip-address\fR specifies the
address of the chip on that bus, and is an integer between 0x03 and 0x77.
\fIdata-address\fR specifies the address on that chip to write to, and is an
-integer between 0x00 and 0xFF. \fIvalue\fR is the value to write to that
-location on the chip.
+integer between 0x00 and 0xFF.
+.PP
+The \fIvalue\fR parameter, if specified, is the value to write to that
+location on the chip. If this parameter is omited, then a short write is
+issued. For most chips, it simply sets an internal pointer to the target
+location, but doesn't actually write to that location. For a few chips
+though, in particular simple ones with a single register, this short write
+is an actual write.
.PP
The \fImode\fR parameter, if specified, is one of the letters \fBb\fP or
\fBw\fP, corresponding to a write size of a single byte or a 16-bit word,
diff --git a/tools/i2cset.c b/tools/i2cset.c
index 938ad54..c7a3923 100644
--- a/tools/i2cset.c
+++ b/tools/i2cset.c
@@ -35,7 +35,7 @@ static void help(void) __attribute__ ((noreturn));
static void help(void)
{
fprintf(stderr,
- "Usage: i2cset [-f] [-y] I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE [MODE [MASK]]\n"
+ "Usage: i2cset [-f] [-y] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE [MODE [MASK]]]\n"
" I2CBUS is an integer or an I2C bus name\n"
" ADDRESS is an integer (0x03 - 0x77)\n"
" MODE is one of:\n"
@@ -57,6 +57,14 @@ static int check_funcs(int file, int i2cbus, int size, int pec)
}
switch (size) {
+ case I2C_SMBUS_BYTE:
+ if (!(funcs & I2C_FUNC_SMBUS_WRITE_BYTE)) {
+ fprintf(stderr, "Error: Adapter for i2c bus %d does "
+ "not have byte send capability\n", i2cbus);
+ return -1;
+ }
+ break;
+
case I2C_SMBUS_BYTE_DATA:
if (!(funcs & I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
fprintf(stderr, "Error: Adapter for i2c bus %d does "
@@ -100,10 +108,13 @@ static int confirm(const char *filename, int address, int size, int daddress,
}
fprintf(stderr, "I will write to device file %s, chip address "
- "0x%02x, data address\n0x%02x, data 0x%02x%s, mode "
- "%s.\n", filename, address, daddress, value,
- vmask ? " (masked)" : "",
- size == I2C_SMBUS_BYTE_DATA ? "byte" : "word");
+ "0x%02x, data address\n0x%02x, ", filename, address, daddress);
+ if (size == I2C_SMBUS_BYTE)
+ fprintf(stderr, "no data.\n");
+ else
+ fprintf(stderr, "data 0x%02x%s, mode %s.\n", value,
+ vmask ? " (masked)" : "",
+ size == I2C_SMBUS_BYTE_DATA ? "byte" : "word");
if (pec)
fprintf(stderr, "PEC checking enabled.\n");
@@ -147,7 +158,7 @@ int main(int argc, char *argv[])
exit(0);
}
- if (argc < flags + 5)
+ if (argc < flags + 4)
help();
i2cbus = lookup_i2c_bus(argv[flags+1]);
@@ -164,10 +175,16 @@ int main(int argc, char *argv[])
help();
}
- value = strtol(argv[flags+4], &end, 0);
- if (*end) {
- fprintf(stderr, "Error: Data value invalid!\n");
- help();
+ if (argc > flags + 4) {
+ size = I2C_SMBUS_BYTE_DATA;
+ value = strtol(argv[flags+4], &end, 0);
+ if (*end || value < 0) {
+ fprintf(stderr, "Error: Data value invalid!\n");
+ help();
+ }
+ } else {
+ size = I2C_SMBUS_BYTE;
+ value = -1;
}
if (argc > flags + 5) {
@@ -179,8 +196,6 @@ int main(int argc, char *argv[])
help();
}
pec = argv[flags+5][1] == 'p';
- } else {
- size = I2C_SMBUS_BYTE_DATA;
}
if (argc > flags + 6) {
@@ -191,8 +206,7 @@ int main(int argc, char *argv[])
}
}
- if (value < 0
- || (size == I2C_SMBUS_BYTE_DATA && value > 0xff)
+ if ((size == I2C_SMBUS_BYTE_DATA && value > 0xff)
|| (size == I2C_SMBUS_WORD_DATA && value > 0xffff)) {
fprintf(stderr, "Error: Data value out of range!\n");
help();
@@ -249,9 +263,14 @@ int main(int argc, char *argv[])
exit(1);
}
- if (size == I2C_SMBUS_WORD_DATA) {
+ switch (size) {
+ case I2C_SMBUS_BYTE:
+ res = i2c_smbus_write_byte(file, daddress);
+ break;
+ case I2C_SMBUS_WORD_DATA:
res = i2c_smbus_write_word_data(file, daddress, value);
- } else {
+ break;
+ default: /* I2C_SMBUS_BYTE_DATA */
res = i2c_smbus_write_byte_data(file, daddress, value);
}
if (res < 0) {
@@ -269,13 +288,21 @@ int main(int argc, char *argv[])
}
}
- if (size == I2C_SMBUS_WORD_DATA) {
+ switch (size) {
+ case I2C_SMBUS_BYTE:
+ /* No readback */
+ break;
+ case I2C_SMBUS_WORD_DATA:
res = i2c_smbus_read_word_data(file, daddress);
- } else {
+ break;
+ default: /* I2C_SMBUS_BYTE_DATA */
res = i2c_smbus_read_byte_data(file, daddress);
}
close(file);
+ if (size == I2C_SMBUS_BYTE) /* We're done */
+ exit(0);
+
if (res < 0) {
printf("Warning - readback failed\n");
} else