diff --git a/prog/detect/i2cdetect.8 b/prog/detect/i2cdetect.8 index 6be6cc04..04d1fbd6 100644 --- a/prog/detect/i2cdetect.8 +++ b/prog/detect/i2cdetect.8 @@ -1,4 +1,4 @@ -.TH I2CDETECT 8 "September 2004" +.TH I2CDETECT 8 "April 2006" .SH NAME i2cdetect \- detect I2C chips @@ -10,6 +10,10 @@ i2cdetect \- detect I2C chips .I i2cbus .br .B i2cdetect +.I -F +.I i2cbus +.br +.B i2cdetect .I -V .br .B i2cdetect @@ -20,6 +24,9 @@ i2cdetect is a userspace program to scan an I2C bus for devices. It outputs a table with the list of detected devices on the specified bus. \fIi2cbus\fR indicates the number of the I2C bus to be scanned, and should correspond to one of the busses listed by \fIi2cdetect -l\fR. +.PP +i2cdetect can also be used to query the functionalities of an I2C bus +(see option \fB-F\fP.) .SH WARNING This program can confuse your I2C bus, cause data loss and worse! @@ -47,6 +54,9 @@ used is the one believed to be the safest for each address). Not recommended. This is known to lock SMBus on various write-only chips (most notably clock chips at address 0x69). .TP +.B "\-F" +Display the list of functionalities implemented by the adapter and exit. +.TP .B "\-V" Display the version and exit. .TP diff --git a/prog/detect/i2cdetect.c b/prog/detect/i2cdetect.c index 1869af64..9a037500 100644 --- a/prog/detect/i2cdetect.c +++ b/prog/detect/i2cdetect.c @@ -31,11 +31,13 @@ #define MODE_AUTO 0 #define MODE_QUICK 1 #define MODE_READ 2 +#define MODE_FUNC 3 void help(void) { fprintf(stderr, "Syntax: i2cdetect [-y] [-a] [-q|-r] I2CBUS [FIRST LAST]\n" + " i2cdetect -F I2CBUS\n" " i2cdetect -l\n" " i2cdetect -V\n" " I2CBUS is an integer\n" @@ -111,6 +113,56 @@ int scan_i2c_bus(int file, const int mode, const int first, const int last) return 0; } +struct func +{ + long value; + const char* name; +}; + +static const struct func all_func[] = { + { .value = I2C_FUNC_I2C, + .name = "I2C" }, + { .value = I2C_FUNC_SMBUS_QUICK, + .name = "SMBus Quick Command" }, + { .value = I2C_FUNC_SMBUS_WRITE_BYTE, + .name = "SMBus Send Byte" }, + { .value = I2C_FUNC_SMBUS_READ_BYTE, + .name = "SMBus Receive Byte" }, + { .value = I2C_FUNC_SMBUS_WRITE_BYTE_DATA, + .name = "SMBus Write Byte" }, + { .value = I2C_FUNC_SMBUS_READ_BYTE_DATA, + .name = "SMBus Read Byte" }, + { .value = I2C_FUNC_SMBUS_WRITE_WORD_DATA, + .name = "SMBus Write Word" }, + { .value = I2C_FUNC_SMBUS_READ_WORD_DATA, + .name = "SMBus Read Word" }, + { .value = I2C_FUNC_SMBUS_PROC_CALL, + .name = "SMBus Process Call" }, + { .value = I2C_FUNC_SMBUS_WRITE_BLOCK_DATA, + .name = "SMBus Block Write" }, + { .value = I2C_FUNC_SMBUS_READ_BLOCK_DATA, + .name = "SMBus Block Read" }, + { .value = I2C_FUNC_SMBUS_BLOCK_PROC_CALL, + .name = "SMBus Block Process Call" }, + { .value = I2C_FUNC_SMBUS_HWPEC_CALC, + .name = "SMBus PEC" }, + { .value = I2C_FUNC_SMBUS_WRITE_I2C_BLOCK, + .name = "I2C Block Write" }, + { .value = I2C_FUNC_SMBUS_READ_I2C_BLOCK, + .name = "I2C Block Read" }, + { } +}; + +void print_functionality(long funcs) +{ + int i; + + for (i = 0; all_func[i].value; i++) { + printf("%-32s %s\n", all_func[i].name, + (funcs & all_func[i].value) ? "yes" : "no"); + } +} + int main(int argc, char *argv[]) { char *end; @@ -128,6 +180,14 @@ int main(int argc, char *argv[]) case 'V': version = 1; break; case 'y': yes = 1; break; case 'l': list = 1; break; + case 'F': + if (mode != MODE_AUTO && mode != MODE_FUNC) { + fprintf(stderr, "Error: Different modes " + "specified!\n"); + exit(1); + } + mode = MODE_FUNC; + break; case 'r': if (mode == MODE_QUICK) { fprintf(stderr, "Error: Different modes " @@ -186,7 +246,7 @@ int main(int argc, char *argv[]) } /* read address range if present */ - if (argc == flags + 4) { + if (argc == flags + 4 && mode != MODE_FUNC) { int tmp; tmp = strtol(argv[flags+2], &end, 0); @@ -234,6 +294,15 @@ int main(int argc, char *argv[]) close(file); exit(1); } + + /* Special case, we only list the implemented functionalities */ + if (mode == MODE_FUNC) { + close(file); + printf("Functionalities implemented by %s:\n", filename); + print_functionality(funcs); + exit(0); + } + if (mode != MODE_READ && !(funcs & I2C_FUNC_SMBUS_QUICK)) { fprintf(stderr, "Error: Can't use SMBus Quick Write command " "on this bus (ISA bus?)\n");