X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=miscutils%2Fi2c_tools.c;h=6a213406317ad5478b4b86049ae69f209203246b;hb=4c9455f967e21d30db0de2e13b6e1115ab8f36ce;hp=2f501cd9cad1b26fb592ef04440607599977df72;hpb=aeb11a949667f82173c733e55e9f762c56a1fcba;p=oweals%2Fbusybox.git diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index 2f501cd9c..6a2134063 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -8,40 +8,40 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - //config:config I2CGET -//config: bool "i2cget" +//config: bool "i2cget (5.6 kb)" //config: default y //config: select PLATFORM_LINUX //config: help -//config: Read from I2C/SMBus chip registers. +//config: Read from I2C/SMBus chip registers. //config: //config:config I2CSET -//config: bool "i2cset" +//config: bool "i2cset (6.9 kb)" //config: default y //config: select PLATFORM_LINUX //config: help -//config: Set I2C registers. +//config: Set I2C registers. //config: //config:config I2CDUMP -//config: bool "i2cdump" +//config: bool "i2cdump (7.2 kb)" //config: default y //config: select PLATFORM_LINUX //config: help -//config: Examine I2C registers. +//config: Examine I2C registers. //config: //config:config I2CDETECT -//config: bool "i2cdetect" +//config: bool "i2cdetect (7.2 kb)" //config: default y //config: select PLATFORM_LINUX //config: help -//config: Detect I2C chips. +//config: Detect I2C chips. //config: //applet:IF_I2CGET(APPLET(i2cget, BB_DIR_USR_SBIN, BB_SUID_DROP)) //applet:IF_I2CSET(APPLET(i2cset, BB_DIR_USR_SBIN, BB_SUID_DROP)) //applet:IF_I2CDUMP(APPLET(i2cdump, BB_DIR_USR_SBIN, BB_SUID_DROP)) //applet:IF_I2CDETECT(APPLET(i2cdetect, BB_DIR_USR_SBIN, BB_SUID_DROP)) +/* not NOEXEC: if hw operation stalls, use less memory in "hung" process */ //kbuild:lib-$(CONFIG_I2CGET) += i2c_tools.o //kbuild:lib-$(CONFIG_I2CSET) += i2c_tools.o @@ -61,112 +61,32 @@ #include "libbb.h" -/* - * /dev/i2c-X ioctl commands. The ioctl's parameter is always an unsigned long, - * except for: - * - I2C_FUNCS, takes pointer to an unsigned long - * - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data - * - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data - */ +#include -/* - * NOTE: Slave address is 7 or 10 bits, but 10-bit addresses - * are not supported due to code brokenness. - */ +#define I2CDUMP_NUM_REGS 256 + +#define I2CDETECT_MODE_AUTO 0 +#define I2CDETECT_MODE_QUICK 1 +#define I2CDETECT_MODE_READ 2 -/* Use this slave address. */ -#define I2C_SLAVE 0x0703 -/* Use this slave address, even if it is already in use by a driver. */ -#define I2C_SLAVE_FORCE 0x0706 -/* 0 for 7 bit addrs, != 0 for 10 bit. */ -#define I2C_TENBIT 0x0704 -/* Get the adapter functionality mask. */ -#define I2C_FUNCS 0x0705 -/* Combined R/W transfer (one STOP only). */ -#define I2C_RDWR 0x0707 -/* != 0 to use PEC with SMBus. */ -#define I2C_PEC 0x0708 -/* SMBus transfer. */ -#define I2C_SMBUS 0x0720 - -/* Structure used in the I2C_SMBUS ioctl call. */ +/* linux/i2c-dev.h from i2c-tools overwrites the one from linux uapi + * and defines symbols already defined by linux/i2c.h. + * Also, it defines a bunch of static inlines which we would rather NOT + * inline. What a mess. + * We need only these definitions from linux/i2c-dev.h: + */ +#define I2C_SLAVE 0x0703 +#define I2C_SLAVE_FORCE 0x0706 +#define I2C_FUNCS 0x0705 +#define I2C_PEC 0x0708 +#define I2C_SMBUS 0x0720 struct i2c_smbus_ioctl_data { - uint8_t read_write; - uint8_t command; - uint32_t size; + __u8 read_write; + __u8 command; + __u32 size; union i2c_smbus_data *data; }; - -/* Structure used in the I2C_RDWR ioctl call. */ -struct i2c_rdwr_ioctl_data { - struct i2c_msg *msgs; /* Pointers to i2c_msgs. */ - uint32_t nmsgs; /* Number of i2c_msgs. */ -}; - -/* As specified in SMBus standard. */ -#define I2C_SMBUS_BLOCK_MAX 32 -/* Not specified but we use same structure. */ -#define I2C_SMBUS_I2C_BLOCK_MAX 32 - -/* Data for SMBus Messages. */ -union i2c_smbus_data { - uint8_t byte; - uint16_t word; - /* block[0] is used for length and one more for PEC */ - uint8_t block[I2C_SMBUS_BLOCK_MAX + 2]; -}; - -#define I2C_RDRW_IOCTL_MAX_MSGS 42 -#define I2C_MAX_REGS 256 - -/* Smbus_access read or write markers. */ -#define I2C_SMBUS_READ 1 -#define I2C_SMBUS_WRITE 0 - -/* SMBus transaction types (size parameter in the below functions). */ -#define I2C_SMBUS_QUICK 0 -#define I2C_SMBUS_BYTE 1 -#define I2C_SMBUS_BYTE_DATA 2 -#define I2C_SMBUS_WORD_DATA 3 -#define I2C_SMBUS_PROC_CALL 4 -#define I2C_SMBUS_BLOCK_DATA 5 -#define I2C_SMBUS_I2C_BLOCK_BROKEN 6 -#define I2C_SMBUS_BLOCK_PROC_CALL 7 -#define I2C_SMBUS_I2C_BLOCK_DATA 8 - -#define DETECT_MODE_AUTO 0 -#define DETECT_MODE_QUICK 1 -#define DETECT_MODE_READ 2 - -/* Defines to determine what functionality is present. */ -#define I2C_FUNC_I2C 0x00000001 -#define I2C_FUNC_10BIT_ADDR 0x00000002 -#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 -#define I2C_FUNC_SMBUS_PEC 0x00000008 -#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 -#define I2C_FUNC_SMBUS_QUICK 0x00010000 -#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 -#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 -#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 -#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 -#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 -#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 -#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 -#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 -#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 -#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 -#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 - -#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ - I2C_FUNC_SMBUS_WRITE_BYTE) -#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ - I2C_FUNC_SMBUS_WRITE_BYTE_DATA) -#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ - I2C_FUNC_SMBUS_WRITE_WORD_DATA) -#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) -#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ - I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) +/* end linux/i2c-dev.h */ /* * This is needed for ioctl_or_perror_and_die() since it only accepts pointers. @@ -456,7 +376,7 @@ static void check_read_funcs(int fd, int mode, int data_addr, int pec) break; #endif /* ENABLE_I2CDUMP */ default: - bb_error_msg_and_die("Programmer goofed!"); + bb_error_msg_and_die("internal error"); } check_funcs_test_end(funcs, pec, err); } @@ -501,8 +421,7 @@ static void check_write_funcs(int fd, int mode, int pec) static void confirm_or_abort(void) { fprintf(stderr, "Continue? [y/N] "); - fflush_all(); - if (!bb_ask_confirmation()) + if (!bb_ask_y_confirmation()) bb_error_msg_and_die("aborting"); } @@ -534,31 +453,30 @@ static void confirm_action(int bus_addr, int mode, int data_addr, int pec) #if ENABLE_I2CGET //usage:#define i2cget_trivial_usage -//usage: "[-f] [-y] BUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]" +//usage: "[-fy] BUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]" //usage:#define i2cget_full_usage "\n\n" -//usage: "Read from I2C/SMBus chip registers\n" -//usage: "\n I2CBUS i2c bus number" -//usage: "\n ADDRESS 0x03 - 0x77" +//usage: "Read from I2C/SMBus chip registers" +//usage: "\n" +//usage: "\n I2CBUS I2C bus number" +//usage: "\n ADDRESS 0x03-0x77" //usage: "\nMODE is:" -//usage: "\n b read byte data (default)" -//usage: "\n w read word data" -//usage: "\n c write byte/read byte" +//usage: "\n b Read byte data (default)" +//usage: "\n w Read word data" +//usage: "\n c Write byte/read byte" //usage: "\n Append p for SMBus PEC" //usage: "\n" -//usage: "\n -f force access" -//usage: "\n -y disable interactive mode" +//usage: "\n -f Force access" +//usage: "\n -y Disable interactive mode" int i2cget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int i2cget_main(int argc UNUSED_PARAM, char **argv) { const unsigned opt_f = (1 << 0), opt_y = (1 << 1); - const char *const optstr = "fy"; int bus_num, bus_addr, data_addr = -1, status; int mode = I2C_SMBUS_BYTE, pec = 0, fd; unsigned opts; - opt_complementary = "-2:?4"; /* from 2 to 4 args */ - opts = getopt32(argv, optstr); + opts = getopt32(argv, "^" "fy" "\0" "-2:?4"/*from 2 to 4 args*/); argv += optind; bus_num = i2c_bus_lookup(argv[0]); @@ -618,40 +536,44 @@ int i2cget_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_I2CSET //usage:#define i2cset_trivial_usage -//usage: "[-f] [-y] [-m MASK] BUS CHIP-ADDR DATA-ADDR [VALUE] ... [MODE]" +//usage: "[-fy] [-m MASK] BUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]" //usage:#define i2cset_full_usage "\n\n" -//usage: "Set I2C registers\n" -//usage: "\n I2CBUS i2c bus number" -//usage: "\n ADDRESS 0x03 - 0x77" +//usage: "Set I2C registers" +//usage: "\n" +//usage: "\n I2CBUS I2C bus number" +//usage: "\n ADDRESS 0x03-0x77" //usage: "\nMODE is:" -//usage: "\n c byte, no value" -//usage: "\n b byte data (default)" -//usage: "\n w word data" +//usage: "\n c Byte, no value" +//usage: "\n b Byte data (default)" +//usage: "\n w Word data" //usage: "\n i I2C block data" //usage: "\n s SMBus block data" //usage: "\n Append p for SMBus PEC" //usage: "\n" -//usage: "\n -f force access" -//usage: "\n -y disable interactive mode" -//usage: "\n -r read back and compare the result" -//usage: "\n -m MASK mask specifying which bits to write" +//usage: "\n -f Force access" +//usage: "\n -y Disable interactive mode" +//usage: "\n -r Read back and compare the result" +//usage: "\n -m MASK Mask specifying which bits to write" int i2cset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int i2cset_main(int argc, char **argv) { const unsigned opt_f = (1 << 0), opt_y = (1 << 1), opt_m = (1 << 2), opt_r = (1 << 3); - const char *const optstr = "fym:r"; int bus_num, bus_addr, data_addr, mode = I2C_SMBUS_BYTE, pec = 0; - int val, blen = 0, mask = 0, fd, status; + int val, blen, mask, fd, status; unsigned char block[I2C_SMBUS_BLOCK_MAX]; char *opt_m_arg = NULL; unsigned opts; - opt_complementary = "-3"; /* from 3 to ? args */ - opts = getopt32(argv, optstr, &opt_m_arg); + opts = getopt32(argv, "^" + "fym:r" + "\0" "-3", /* minimum 3 args */ + &opt_m_arg + ); argv += optind; argc -= optind; + argc--; /* now argv[argc] is last arg */ bus_num = i2c_bus_lookup(argv[0]); bus_addr = i2c_parse_bus_addr(argv[1]); @@ -661,20 +583,26 @@ int i2cset_main(int argc, char **argv) if (!argv[4] && argv[3][0] != 'c') { mode = I2C_SMBUS_BYTE_DATA; /* Implicit b */ } else { - switch (argv[argc-1][0]) { - case 'c': /* Already set */ break; - case 'b': mode = I2C_SMBUS_BYTE_DATA; break; - case 'w': mode = I2C_SMBUS_WORD_DATA; break; - case 's': mode = I2C_SMBUS_BLOCK_DATA; break; - case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA; break; + switch (argv[argc][0]) { + case 'c': /* Already set */ + break; + case 'b': mode = I2C_SMBUS_BYTE_DATA; + break; + case 'w': mode = I2C_SMBUS_WORD_DATA; + break; + case 's': mode = I2C_SMBUS_BLOCK_DATA; + break; + case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA; + break; default: bb_error_msg("invalid mode"); bb_show_usage(); } - pec = argv[argc-1][1] == 'p'; - if (mode == I2C_SMBUS_BLOCK_DATA || - mode == I2C_SMBUS_I2C_BLOCK_DATA) { + pec = (argv[argc][1] == 'p'); + if (mode == I2C_SMBUS_BLOCK_DATA + || mode == I2C_SMBUS_I2C_BLOCK_DATA + ) { if (pec && mode == I2C_SMBUS_I2C_BLOCK_DATA) bb_error_msg_and_die( "PEC not supported for I2C " @@ -688,6 +616,8 @@ int i2cset_main(int argc, char **argv) } /* Prepare the value(s) to be written according to current mode. */ + mask = 0; + blen = 0; switch (mode) { case I2C_SMBUS_BYTE_DATA: val = xstrtou_range(argv[3], 0, 0, 0xff); @@ -697,8 +627,9 @@ int i2cset_main(int argc, char **argv) break; case I2C_SMBUS_BLOCK_DATA: case I2C_SMBUS_I2C_BLOCK_DATA: - for (blen = 3; blen < (argc - 1); blen++) - block[blen] = xstrtou_range(argv[blen], 0, 0, 0xff); + for (blen = 3; blen < argc; blen++) + block[blen - 3] = xstrtou_range(argv[blen], 0, 0, 0xff); + blen -= 3; val = -1; break; default: @@ -799,7 +730,7 @@ int i2cset_main(int argc, char **argv) } if (status < 0) { - printf("Warning - readback failed\n"); + puts("Warning - readback failed"); } else if (status != val) { printf("Warning - data mismatch - wrote " @@ -818,34 +749,39 @@ int i2cset_main(int argc, char **argv) #if ENABLE_I2CDUMP static int read_block_data(int buf_fd, int mode, int *block) { - uint8_t cblock[I2C_SMBUS_BLOCK_MAX + I2C_MAX_REGS]; + uint8_t cblock[I2C_SMBUS_BLOCK_MAX + I2CDUMP_NUM_REGS]; int res, blen = 0, tmp, i; - if (mode == I2C_SMBUS_BLOCK_DATA || mode == I2C_SMBUS_I2C_BLOCK_DATA) { - res = i2c_smbus_read_block_data(buf_fd, 0, cblock); - blen = res; + if (mode == I2C_SMBUS_BLOCK_DATA) { + blen = i2c_smbus_read_block_data(buf_fd, 0, cblock); + if (blen <= 0) + goto fail; } else { - for (res = 0; res < I2C_MAX_REGS; res += tmp) { + for (res = 0; res < I2CDUMP_NUM_REGS; res += tmp) { tmp = i2c_smbus_read_i2c_block_data( buf_fd, res, I2C_SMBUS_BLOCK_MAX, cblock + res); - if (tmp < 0) { - bb_error_msg_and_die("block read failed"); + if (tmp <= 0) { + blen = tmp; + goto fail; } } - if (res >= I2C_MAX_REGS) - res = I2C_MAX_REGS; + if (res >= I2CDUMP_NUM_REGS) + res = I2CDUMP_NUM_REGS; for (i = 0; i < res; i++) block[i] = cblock[i]; if (mode != I2C_SMBUS_BLOCK_DATA) - for (i = res; i < I2C_MAX_REGS; i++) + for (i = res; i < I2CDUMP_NUM_REGS; i++) block[i] = -1; } return blen; + + fail: + bb_error_msg_and_die("block read failed: %d", blen); } /* Dump all but word data. */ @@ -854,10 +790,10 @@ static void dump_data(int bus_fd, int mode, unsigned first, { int i, j, res; - printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f" - " 0123456789abcdef\n"); + puts(" 0 1 2 3 4 5 6 7 8 9 a b c d e f" + " 0123456789abcdef"); - for (i = 0; i < I2C_MAX_REGS; i += 0x10) { + for (i = 0; i < I2CDUMP_NUM_REGS; i += 0x10) { if (mode == I2C_SMBUS_BLOCK_DATA && i >= blen) break; if (i/16 < first/16) @@ -924,22 +860,22 @@ static void dump_data(int bus_fd, int mode, unsigned first, break; /* Skip unwanted registers */ if (i+j < first || i+j > last) { - printf(" "); + bb_putchar(' '); continue; } res = block[i+j]; if (res < 0) { - printf("X"); + bb_putchar('X'); } else if (res == 0x00 || res == 0xff) { - printf("."); + bb_putchar('.'); } else if (res < 32 || res >= 127) { - printf("?"); + bb_putchar('?'); } else { - printf("%c", res); + bb_putchar(res); } } - printf("\n"); + bb_putchar('\n'); } } @@ -948,7 +884,7 @@ static void dump_word_data(int bus_fd, unsigned first, unsigned last) int i, j, rv; /* Word data. */ - printf(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f\n"); + puts(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f"); for (i = 0; i < 256; i += 8) { if (i/8 < first/8) continue; @@ -969,43 +905,46 @@ static void dump_word_data(int bus_fd, unsigned first, unsigned last) else printf("%04x ", rv & 0xffff); } - printf("\n"); + bb_putchar('\n'); } } //usage:#define i2cdump_trivial_usage -//usage: "[-f] [-r FIRST-LAST] [-y] BUS ADDR [MODE]" +//usage: "[-fy] [-r FIRST-LAST] BUS ADDR [MODE]" //usage:#define i2cdump_full_usage "\n\n" -//usage: "Examine I2C registers\n" -//usage: "\n I2CBUS i2c bus number" -//usage: "\n ADDRESS 0x03 - 0x77" +//usage: "Examine I2C registers" +//usage: "\n" +//usage: "\n I2CBUS I2C bus number" +//usage: "\n ADDRESS 0x03-0x77" //usage: "\nMODE is:" -//usage: "\n b byte (default)" -//usage: "\n w word" -//usage: "\n W word on even register addresses" +//usage: "\n b Byte (default)" +//usage: "\n w Word" +//usage: "\n W Word on even register addresses" //usage: "\n i I2C block" //usage: "\n s SMBus block" -//usage: "\n c consecutive byte" +//usage: "\n c Consecutive byte" //usage: "\n Append p for SMBus PEC" //usage: "\n" -//usage: "\n -f force access" -//usage: "\n -y disable interactive mode" -//usage: "\n -r limit the number of registers being accessed" +//usage: "\n -f Force access" +//usage: "\n -y Disable interactive mode" +//usage: "\n -r Limit the number of registers being accessed" int i2cdump_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int i2cdump_main(int argc UNUSED_PARAM, char **argv) { const unsigned opt_f = (1 << 0), opt_y = (1 << 1), opt_r = (1 << 2); - const char *const optstr = "fyr:"; int bus_num, bus_addr, mode = I2C_SMBUS_BYTE_DATA, even = 0, pec = 0; unsigned first = 0x00, last = 0xff, opts; - int *block = (int *)bb_common_bufsiz1; + int block[I2CDUMP_NUM_REGS]; char *opt_r_str, *dash; - int fd, res, blen; + int fd, res; - opt_complementary = "-2:?3"; /* from 2 to 3 args */ - opts = getopt32(argv, optstr, &opt_r_str); + opts = getopt32(argv, "^" + "fyr:" + "\0" "-2:?3" /* from 2 to 3 args */, + &opt_r_str + ); argv += optind; bus_num = i2c_bus_lookup(argv[0]); @@ -1069,7 +1008,10 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv) /* All but word data. */ if (mode != I2C_SMBUS_WORD_DATA || even) { - blen = read_block_data(fd, mode, block); + int blen = 0; + + if (mode == I2C_SMBUS_BLOCK_DATA || mode == I2C_SMBUS_I2C_BLOCK_DATA) + blen = read_block_data(fd, mode, block); if (mode == I2C_SMBUS_BYTE) { res = i2c_smbus_write_byte(fd, first); @@ -1120,33 +1062,33 @@ static const struct i2c_func i2c_funcs_tab[] = { { .value = I2C_FUNC_I2C, .name = "I2C" }, { .value = I2C_FUNC_SMBUS_QUICK, - .name = "SMBus Quick Command" }, + .name = "SMBus quick command" }, { .value = I2C_FUNC_SMBUS_WRITE_BYTE, - .name = "SMBus Send Byte" }, + .name = "SMBus send byte" }, { .value = I2C_FUNC_SMBUS_READ_BYTE, - .name = "SMBus Receive Byte" }, + .name = "SMBus receive byte" }, { .value = I2C_FUNC_SMBUS_WRITE_BYTE_DATA, - .name = "SMBus Write Byte" }, + .name = "SMBus write byte" }, { .value = I2C_FUNC_SMBUS_READ_BYTE_DATA, - .name = "SMBus Read Byte" }, + .name = "SMBus read byte" }, { .value = I2C_FUNC_SMBUS_WRITE_WORD_DATA, - .name = "SMBus Write Word" }, + .name = "SMBus write word" }, { .value = I2C_FUNC_SMBUS_READ_WORD_DATA, - .name = "SMBus Read Word" }, + .name = "SMBus read word" }, { .value = I2C_FUNC_SMBUS_PROC_CALL, - .name = "SMBus Process Call" }, + .name = "SMBus process call" }, { .value = I2C_FUNC_SMBUS_WRITE_BLOCK_DATA, - .name = "SMBus Block Write" }, + .name = "SMBus block write" }, { .value = I2C_FUNC_SMBUS_READ_BLOCK_DATA, - .name = "SMBus Block Read" }, + .name = "SMBus block read" }, { .value = I2C_FUNC_SMBUS_BLOCK_PROC_CALL, - .name = "SMBus Block Process Call" }, + .name = "SMBus block process call" }, { .value = I2C_FUNC_SMBUS_PEC, .name = "SMBus PEC" }, { .value = I2C_FUNC_SMBUS_WRITE_I2C_BLOCK, - .name = "I2C Block Write" }, + .name = "I2C block write" }, { .value = I2C_FUNC_SMBUS_READ_I2C_BLOCK, - .name = "I2C Block Read" }, + .name = "I2C block read" }, { .value = 0, .name = NULL } }; @@ -1226,12 +1168,11 @@ static void NORETURN list_i2c_busses_and_exit(void) i2cdev_path, de->d_name, subde->d_name); fp = fopen(path, "r"); - goto found; + break; } } } -found: if (fp != NULL) { /* * Get the rest of the info and display a line @@ -1279,33 +1220,34 @@ static void will_skip(const char *cmd) } //usage:#define i2cdetect_trivial_usage -//usage: "[-F I2CBUS] [-l] [-y] [-a] [-q|-r] I2CBUS [FIRST LAST]" +//usage: "-l | -F I2CBUS | [-ya] [-q|-r] I2CBUS [FIRST LAST]" //usage:#define i2cdetect_full_usage "\n\n" -//usage: "Detect I2C chips.\n" -//usage: "\n I2CBUS i2c bus number" -//usage: "\n FIRST and LAST limit the probing range" +//usage: "Detect I2C chips" //usage: "\n" -//usage: "\n -l output list of installed busses" -//usage: "\n -y disable interactive mode" -//usage: "\n -a force scanning of non-regular addresses" -//usage: "\n -q use smbus quick write commands for probing (default)" -//usage: "\n -r use smbus read byte commands for probing" -//usage: "\n -F display list of functionalities" +//usage: "\n -l List installed buses" +//usage: "\n -F BUS# List functionalities on this bus" +//usage: "\n -y Disable interactive mode" +//usage: "\n -a Force scanning of non-regular addresses" +//usage: "\n -q Use smbus quick write commands for probing (default)" +//usage: "\n -r Use smbus read byte commands for probing" +//usage: "\n FIRST and LAST limit probing range" int i2cdetect_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int i2cdetect_main(int argc UNUSED_PARAM, char **argv) { const unsigned opt_y = (1 << 0), opt_a = (1 << 1), opt_q = (1 << 2), opt_r = (1 << 3), opt_F = (1 << 4), opt_l = (1 << 5); - const char *const optstr = "yaqrFl"; - int fd, bus_num, i, j, mode = DETECT_MODE_AUTO, status; + int fd, bus_num, i, j, mode = I2CDETECT_MODE_AUTO, status, cmd; unsigned first = 0x03, last = 0x77, opts; unsigned long funcs; - opt_complementary = "q--r:r--q:" /* mutually exclusive */ - "?3"; /* up to 3 args */ - opts = getopt32(argv, optstr); + opts = getopt32(argv, "^" + "yaqrFl" + "\0" + "q--r:r--q:"/*mutually exclusive*/ + "?3"/*up to 3 args*/ + ); argv += optind; if (opts & opt_l) @@ -1330,9 +1272,9 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) } if (opts & opt_r) - mode = DETECT_MODE_READ; + mode = I2CDETECT_MODE_READ; else if (opts & opt_q) - mode = DETECT_MODE_QUICK; + mode = I2CDETECT_MODE_QUICK; if (opts & opt_a) { first = 0x00; @@ -1349,42 +1291,43 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) if (!(funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE))) { no_support("detection commands"); } else - if (mode == DETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK)) { - no_support("SMBus Quick Write command"); + if (mode == I2CDETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK)) { + no_support("SMBus quick write"); } else - if (mode == DETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) { - no_support("SMBus Receive Byte command"); + if (mode == I2CDETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) { + no_support("SMBus receive byte"); } - if (mode == DETECT_MODE_AUTO) { + if (mode == I2CDETECT_MODE_AUTO) { if (!(funcs & I2C_FUNC_SMBUS_QUICK)) - will_skip("SMBus Quick Write"); + will_skip("SMBus quick write"); if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE)) - will_skip("SMBus Receive Byte"); + will_skip("SMBus receive byte"); } if (!(opts & opt_y)) confirm_action(-1, -1, -1, 0); - printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); + puts(" 0 1 2 3 4 5 6 7 8 9 a b c d e f"); for (i = 0; i < 128; i += 16) { printf("%02x: ", i); - for(j = 0; j < 16; j++) { + for (j = 0; j < 16; j++) { fflush_all(); - if (mode == DETECT_MODE_AUTO) { + cmd = mode; + if (mode == I2CDETECT_MODE_AUTO) { if ((i+j >= 0x30 && i+j <= 0x37) || (i+j >= 0x50 && i+j <= 0x5F)) - mode = DETECT_MODE_READ; + cmd = I2CDETECT_MODE_READ; else - mode = DETECT_MODE_QUICK; + cmd = I2CDETECT_MODE_QUICK; } /* Skip unwanted addresses. */ if (i+j < first || i+j > last - || (mode == DETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) - || (mode == DETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK))) + || (cmd == I2CDETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) + || (cmd == I2CDETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK))) { printf(" "); continue; @@ -1401,15 +1344,15 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) "can't set address to 0x%02x", i + j); } - switch (mode) { - case DETECT_MODE_READ: + switch (cmd) { + case I2CDETECT_MODE_READ: /* * This is known to lock SMBus on various * write-only chips (mainly clock chips). */ status = i2c_smbus_read_byte(fd); break; - default: /* DETECT_MODE_QUICK: */ + default: /* I2CDETECT_MODE_QUICK: */ /* * This is known to corrupt the Atmel * AT24RF08 EEPROM. @@ -1424,7 +1367,7 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) else printf("%02x ", i+j); } - printf("\n"); + bb_putchar('\n'); } return 0;