Browse files

[I2C] update to I2C Tools library v3.1.0

Signed-off-by: Patrick Titiano <p-titiano@ti.com>
  • Loading branch information...
1 parent dab4f67 commit 89f80ab71b7ddea459d49e8f089cebc934437dcf Patrick Titiano committed Nov 19, 2012
Showing with 163 additions and 74 deletions.
  1. +4 −3 i2c-tools/i2c-dev.h
  2. +11 −10 i2c-tools/i2cbusses.c
  3. +4 −2 i2c-tools/i2cbusses.h
  4. +4 −4 i2c-tools/i2cget.c
  5. +129 −53 i2c-tools/i2cset.c
  6. +10 −1 i2c-tools/util.h
  7. +1 −1 i2c-tools/version.h
View
7 i2c-tools/i2c-dev.h
@@ -26,7 +26,7 @@
MA 02110-1301 USA.
*/
-/* $Id: i2c-dev.h 5361 2008-10-19 09:47:02Z khali $ */
+/* $Id: i2c-dev.h 5894 2010-12-12 13:22:29Z khali $ */
#ifndef LIB_I2CDEV_H
#define LIB_I2CDEV_H
@@ -264,7 +264,7 @@ static inline __s32 i2c_smbus_read_block_data(int file, __u8 command,
}
static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
- __u8 length, __u8 *values)
+ __u8 length, const __u8 *values)
{
union i2c_smbus_data data;
int i;
@@ -302,7 +302,8 @@ static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
}
static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
- __u8 length, __u8 *values)
+ __u8 length,
+ const __u8 *values)
{
union i2c_smbus_data data;
int i;
View
21 i2c-tools/i2cbusses.c
@@ -11,7 +11,7 @@
devices.
Copyright (c) 1999-2003 Frodo Looijaard <frodol@dds.nl> and
Mark D. Studebaker <mdsxyz123@yahoo.com>
- Copyright (C) 2008 Jean Delvare <khali@linux-fr.org>
+ Copyright (C) 2008-2010 Jean Delvare <khali@linux-fr.org>
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
@@ -29,7 +29,7 @@
MA 02110-1301 USA.
*/
-/* For strdup */
+/* For strdup and snprintf */
#define _BSD_SOURCE 1
#include <sys/types.h>
@@ -74,7 +74,7 @@ static enum adt i2c_get_funcs(int i2cbus)
char filename[20];
enum adt ret;
- file = open_i2c_dev(i2cbus, filename, 1);
+ file = open_i2c_dev(i2cbus, filename, sizeof(filename), 1);
if (file < 0)
return adt_unknown;
@@ -339,16 +339,16 @@ static int lookup_i2c_bus_by_name(const char *bus_name)
*/
int lookup_i2c_bus(const char *i2cbus_arg)
{
- long i2cbus;
+ unsigned long i2cbus;
char *end;
- i2cbus = strtol(i2cbus_arg, &end, 0);
+ i2cbus = strtoul(i2cbus_arg, &end, 0);
if (*end || !*i2cbus_arg) {
/* Not a number, maybe a name? */
return lookup_i2c_bus_by_name(i2cbus_arg);
}
- if (i2cbus < 0 || i2cbus > 0xff) {
- fprintf(stderr, "Error: I2C bus out of range (0-255)!\n");
+ if (i2cbus > 0xFFFFF) {
+ fprintf(stderr, "Error: I2C bus out of range!\n");
return -2;
}
@@ -378,14 +378,15 @@ int parse_i2c_address(const char *address_arg)
return address;
}
-int open_i2c_dev(const int i2cbus, char *filename, const int quiet)
+int open_i2c_dev(int i2cbus, char *filename, size_t size, int quiet)
{
int file;
- sprintf(filename, "/dev/i2c/%d", i2cbus);
+ snprintf(filename, size, "/dev/i2c/%d", i2cbus);
+ filename[size - 1] = '\0';
file = open(filename, O_RDWR);
- if (file < 0 && errno == ENOENT) {
+ if (file < 0 && (errno == ENOENT || errno == ENOTDIR)) {
sprintf(filename, "/dev/i2c-%d", i2cbus);
file = open(filename, O_RDWR);
}
View
6 i2c-tools/i2cbusses.h
@@ -7,7 +7,7 @@
/*
i2cbusses.h - Part of the i2c-tools package
- Copyright (C) 2004-2007 Jean Delvare <khali@linux-fr.org>
+ Copyright (C) 2004-2010 Jean Delvare <khali@linux-fr.org>
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
@@ -28,6 +28,8 @@
#ifndef _I2CBUSSES_H
#define _I2CBUSSES_H
+#include <unistd.h>
+
struct i2c_adap {
int nr;
char *name;
@@ -40,7 +42,7 @@ void free_adapters(struct i2c_adap *adapters);
int lookup_i2c_bus(const char *i2cbus_arg);
int parse_i2c_address(const char *address_arg);
-int open_i2c_dev(const int i2cbus, char *filename, const int quiet);
+int open_i2c_dev(int i2cbus, char *filename, size_t size, int quiet);
int set_slave_addr(int file, int address, int force);
#define MISSING_FUNC_FMT "Error: Adapter does not have %s capability\n"
View
8 i2c-tools/i2cget.c
@@ -6,7 +6,7 @@
*//*======================================================================== */
/*
i2cget.c - A user-space program to read an I2C register.
- Copyright (C) 2005-2008 Jean Delvare <khali@linux-fr.org>
+ Copyright (C) 2005-2010 Jean Delvare <khali@linux-fr.org>
Based on i2cset.c:
Copyright (C) 2001-2003 Frodo Looijaard <frodol@dds.nl>, and
@@ -218,7 +218,7 @@ int main_i2cget(int argc, char *argv[])
pec = argv[flags+4][1] == 'p';
}
- file = open_i2c_dev(i2cbus, filename, 0);
+ file = open_i2c_dev(i2cbus, filename, sizeof(filename), 0);
if (file < 0
|| check_funcs(file, size, daddress, pec)
|| set_slave_addr(file, address, force))
@@ -299,7 +299,7 @@ int i2cget(
return -1;
}
- file = open_i2c_dev(i2cbus, filename, 1);
+ file = open_i2c_dev(i2cbus, filename, sizeof(filename), 1);
if (file < 0
|| check_funcs(file, I2C_SMBUS_BYTE_DATA, daddress, 0)
|| set_slave_addr(file, address, 1))
@@ -354,7 +354,7 @@ int i2cget_word(
return -1;
}
- file = open_i2c_dev(i2cbus, filename, 1);
+ file = open_i2c_dev(i2cbus, filename, sizeof(filename), 1);
if (file < 0
|| check_funcs(file, I2C_SMBUS_WORD_DATA, daddress, 0)
|| set_slave_addr(file, address, 1))
View
182 i2c-tools/i2cset.c
@@ -8,7 +8,7 @@
i2cset.c - A user-space program to write an I2C register.
Copyright (C) 2001-2003 Frodo Looijaard <frodol@dds.nl>, and
Mark D. Studebaker <mdsxyz123@yahoo.com>
- Copyright (C) 2004-2008 Jean Delvare <khali@linux-fr.org>
+ Copyright (C) 2004-2010 Jean Delvare <khali@linux-fr.org>
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
@@ -41,13 +41,15 @@ static void help(void) __attribute__ ((noreturn));
static void help(void)
{
fprintf(stderr,
- "Usage: i2cset [-f] [-y] [-m MASK] "\
- "I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE [MODE]]\n"
+ "Usage: i2cset [-f] [-y] [-m MASK] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]\n"
" I2CBUS is an integer or an I2C bus name\n"
" ADDRESS is an integer (0x03 - 0x77)\n"
" MODE is one of:\n"
- " b (byte, default)\n"
- " w (word)\n"
+ " c (byte, no value)\n"
+ " b (byte data, default)\n"
+ " w (word data)\n"
+ " i (I2C block data)\n"
+ " s (SMBus block data)\n"
" Append p for SMBus PEC\n");
exit(1);
}
@@ -84,6 +86,19 @@ static int check_funcs(int file, int size, int pec)
return -1;
}
break;
+
+ case I2C_SMBUS_BLOCK_DATA:
+ if (!(funcs & I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)) {
+ fprintf(stderr, MISSING_FUNC_FMT, "SMBus block write");
+ return -1;
+ }
+ break;
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ if (!(funcs & I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
+ fprintf(stderr, MISSING_FUNC_FMT, "I2C block write");
+ return -1;
+ }
+ break;
}
if (pec
@@ -96,7 +111,8 @@ static int check_funcs(int file, int size, int pec)
}
static int confirm(const char *filename, int address, int size, int daddress,
- int value, int vmask, int pec)
+ int value, int vmask, const unsigned char *block, int len,
+ int pec)
{
int dont = 0;
@@ -115,7 +131,16 @@ static int confirm(const char *filename, int address, int size, int daddress,
"0x%02x, data address\n0x%02x, ", filename, address, daddress);
if (size == I2C_SMBUS_BYTE)
fprintf(stderr, "no data.\n");
- else
+ else if (size == I2C_SMBUS_BLOCK_DATA ||
+ size == I2C_SMBUS_I2C_BLOCK_DATA) {
+ int i;
+
+ fprintf(stderr, "data");
+ for (i = 0; i < len; i++)
+ fprintf(stderr, " 0x%02x", block[i]);
+ fprintf(stderr, ", mode %s.\n", size == I2C_SMBUS_BLOCK_DATA
+ ? "smbus block" : "i2c block");
+ } else
fprintf(stderr, "data 0x%02x%s, mode %s.\n", value,
vmask ? " (masked)" : "",
size == I2C_SMBUS_BYTE_DATA ? "byte" : "word");
@@ -142,7 +167,8 @@ int main_i2cset(int argc, char *argv[])
int pec = 0;
int flags = 0;
int force = 0, yes = 0, version = 0, readback = 0;
- int index, loopcount = 1;
+ unsigned char block[I2C_SMBUS_BLOCK_MAX];
+ int len;
/* handle (optional) flags first */
while (1+flags < argc && argv[1+flags][0] == '-') {
@@ -187,45 +213,91 @@ int main_i2cset(int argc, char *argv[])
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();
+ /* check for command/mode */
+ if (argc == flags + 4) {
+ /* Implicit "c" */
+ size = I2C_SMBUS_BYTE;
+ } else if (argc == flags + 5) {
+ /* "c", "cp", or implicit "b" */
+ if (!strcmp(argv[flags+4], "c")
+ || !strcmp(argv[flags+4], "cp")) {
+ size = I2C_SMBUS_BYTE;
+ pec = argv[flags+4][1] == 'p';
+ } else {
+ size = I2C_SMBUS_BYTE_DATA;
}
} else {
- size = I2C_SMBUS_BYTE;
- value = -1;
- }
-
- if (argc > flags + 5) {
- switch (argv[flags+5][0]) {
+ /* All other commands */
+ if (strlen(argv[argc-1]) > 2
+ || (strlen(argv[argc-1]) == 2 && argv[argc-1][1] != 'p')) {
+ fprintf(stderr, "Error: Invalid mode '%s'!\n", argv[argc-1]);
+ help();
+ }
+ switch (argv[argc-1][0]) {
case 'b': size = I2C_SMBUS_BYTE_DATA; break;
case 'w': size = I2C_SMBUS_WORD_DATA; break;
+ case 's': size = I2C_SMBUS_BLOCK_DATA; break;
+ case 'i': size = I2C_SMBUS_I2C_BLOCK_DATA; break;
default:
- fprintf(stderr, "Error: Invalid mode!\n");
+ fprintf(stderr, "Error: Invalid mode '%s'!\n", argv[argc-1]);
+ help();
+ }
+ pec = argv[argc-1][1] == 'p';
+ if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) {
+ if (pec && size == I2C_SMBUS_I2C_BLOCK_DATA) {
+ fprintf(stderr, "Error: PEC not supported for I2C block writes!\n");
+ help();
+ }
+ if (maskp) {
+ fprintf(stderr, "Error: Mask not supported for block writes!\n");
+ help();
+ }
+ if (argc > (int)sizeof(block) + flags + 5) {
+ fprintf(stderr, "Error: Too many arguments!\n");
+ help();
+ }
+ } else if (argc != flags + 6) {
+ fprintf(stderr, "Error: Too many arguments!\n");
help();
}
- pec = argv[flags+5][1] == 'p';
}
- /* Old method to provide the value mask, deprecated and no longer
- documented but still supported for compatibility */
- if (argc > flags + 6) {
- if (maskp) {
- fprintf(stderr, "Error: Data value mask provided twice!\n");
+ len = 0; /* Must always initialize len since it is passed to confirm() */
+
+ /* read values from command line */
+ switch (size) {
+ case I2C_SMBUS_BYTE_DATA:
+ case I2C_SMBUS_WORD_DATA:
+ value = strtol(argv[flags+4], &end, 0);
+ if (*end || value < 0) {
+ fprintf(stderr, "Error: Data value invalid!\n");
help();
}
- fprintf(stderr, "Warning: Using deprecated way to set the data value mask!\n");
- fprintf(stderr, " Please switch to using -m.\n");
- maskp = argv[flags+6];
- }
- if (argc > flags + 7)
- loopcount = strtol(argv[flags+7], &end, 0);
- if (*end || loopcount < 1) {
- fprintf(stderr, "Error: Loop Count invalid!\n");
- help();
+ 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();
+ }
+ break;
+ case I2C_SMBUS_BLOCK_DATA:
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ for (len = 0; len + flags + 5 < argc; len++) {
+ value = strtol(argv[flags + len + 4], &end, 0);
+ if (*end || value < 0) {
+ fprintf(stderr, "Error: Data value invalid!\n");
+ help();
+ }
+ if (value > 0xff) {
+ fprintf(stderr, "Error: Data value out of range!\n");
+ help();
+ }
+ block[len] = value;
+ }
+ value = -1;
+ break;
+ default:
+ value = -1;
+ break;
}
if (maskp) {
@@ -234,22 +306,21 @@ int main_i2cset(int argc, char *argv[])
fprintf(stderr, "Error: Data value mask invalid!\n");
help();
}
+ if (((size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA)
+ && vmask > 0xff) || vmask > 0xffff) {
+ fprintf(stderr, "Error: Data value mask out of range!\n");
+ help();
+ }
}
- 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();
- }
-
- file = open_i2c_dev(i2cbus, filename, 0);
+ file = open_i2c_dev(i2cbus, filename, sizeof(filename), 0);
if (file < 0
|| check_funcs(file, size, pec)
|| set_slave_addr(file, address, force))
exit(1);
if (!yes && !confirm(filename, address, size, daddress,
- value, vmask, pec))
+ value, vmask, block, len, pec))
exit(0);
if (vmask) {
@@ -297,16 +368,23 @@ int main_i2cset(int argc, char *argv[])
close(file);
exit(1);
}
- for (index = 0; index < loopcount; index++) {
+
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);
break;
+ case I2C_SMBUS_BLOCK_DATA:
+ res = i2c_smbus_write_block_data(file, daddress, len, block);
+ break;
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ res = i2c_smbus_write_i2c_block_data(file, daddress, len, block);
+ break;
default: /* I2C_SMBUS_BYTE_DATA */
res = i2c_smbus_write_byte_data(file, daddress, value);
+ break;
}
if (res < 0) {
fprintf(stderr, "Error: Write failed\n");
@@ -323,8 +401,7 @@ int main_i2cset(int argc, char *argv[])
}
}
- if (!readback) {
- /* We're done */
+ if (!readback) { /* We're done */
close(file);
exit(0);
}
@@ -340,10 +417,11 @@ int main_i2cset(int argc, char *argv[])
default: /* I2C_SMBUS_BYTE_DATA */
res = i2c_smbus_read_byte_data(file, daddress);
}
+ close(file);
- if (res < 0)
+ if (res < 0) {
printf("Warning - readback failed\n");
- else
+ } else
if (res != value) {
printf("Warning - data mismatch - wrote "
"0x%0*x, read back 0x%0*x\n",
@@ -354,8 +432,6 @@ int main_i2cset(int argc, char *argv[])
size == I2C_SMBUS_WORD_DATA ? 4 : 2, value);
}
-}
- close(file);
exit(0);
}
@@ -401,7 +477,7 @@ int i2cset(
return -1;
}
- file = open_i2c_dev(i2cbus, filename, 1);
+ file = open_i2c_dev(i2cbus, filename, sizeof(filename), 1);
if (file < 0
|| check_funcs(file, I2C_SMBUS_BYTE_DATA, 0)
|| set_slave_addr(file, address, 1))
@@ -472,7 +548,7 @@ int i2cset_word(
return -1;
}
- file = open_i2c_dev(i2cbus, filename, 1);
+ file = open_i2c_dev(i2cbus, filename, sizeof(filename), 1);
if (file < 0
|| check_funcs(file, I2C_SMBUS_WORD_DATA, 0)
|| set_slave_addr(file, address, 1))
View
11 i2c-tools/util.h
@@ -14,8 +14,17 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-*/
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301 USA.
+*/
#ifndef _UTIL_H
#define _UTIL_H
View
2 i2c-tools/version.h
@@ -15,4 +15,4 @@
*/
-#define VERSION "3.0.2"
+#define VERSION "3.1.0"

0 comments on commit 89f80ab

Please sign in to comment.