diff --git a/src/bin/Jamfile b/src/bin/Jamfile index b21968ceee..64cdd49de7 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -251,6 +251,7 @@ SubInclude HAIKU_TOP src bin consoled ; SubInclude HAIKU_TOP src bin desklink ; SubInclude HAIKU_TOP src bin fwcontrol ; SubInclude HAIKU_TOP src bin hid_decode ; +SubInclude HAIKU_TOP src bin i2c ; SubInclude HAIKU_TOP src bin keymap ; SubInclude HAIKU_TOP src bin keystore ; SubInclude HAIKU_TOP src bin listdev ; diff --git a/src/bin/i2c/Jamfile b/src/bin/i2c/Jamfile new file mode 100644 index 0000000000..49b5a5d300 --- /dev/null +++ b/src/bin/i2c/Jamfile @@ -0,0 +1,7 @@ +SubDir HAIKU_TOP src bin i2c ; + +UsePrivateHeaders i2c shared ; + +BinCommand i2c : + i2c.cpp +; diff --git a/src/bin/i2c/i2c.cpp b/src/bin/i2c/i2c.cpp new file mode 100644 index 0000000000..6b4c7c00c0 --- /dev/null +++ b/src/bin/i2c/i2c.cpp @@ -0,0 +1,105 @@ +/* + * Copyright 2020, Jérôme Duval, jerome.duval@gmail.com. + * Distributed under the terms of the MIT license. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "i2c.h" + + +static struct option const kLongOptions[] = { + {"help", no_argument, 0, 'h'}, + {NULL} +}; + + +extern const char *__progname; +static const char *kProgramName = __progname; + + +void +usage(int returnValue) +{ + fprintf(stderr, "Usage: %s \n", kProgramName); + exit(returnValue); +} + + +static int +scan_bus(const char *path) +{ + int err = EXIT_SUCCESS; + int fd = open(path, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "%s: Could not access path: %s\n", kProgramName, + strerror(errno)); + return EXIT_FAILURE; + } + + setbuf(stdout, NULL); + printf("Scanning I2C bus: %s\n", path); + FileDescriptorCloser closer(fd); + + printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); + for (int i = 0; i < 128; i+=16) { + printf("%02x: ", i); + for (int j = 0; j < 16; j++) { + uint16 addr = i + j; + uint8 cmd = 0; + uint8 data = 0; + i2c_ioctl_exec exec; + exec.addr = addr; + exec.op = I2C_OP_READ_STOP; + exec.cmdBuffer = &cmd; + exec.cmdLength = sizeof(cmd); + exec.buffer = &data; + exec.bufferLength = sizeof(data); + if (ioctl(fd, I2CEXEC, &exec, sizeof(exec)) == 0) + printf("%02x ", addr); + else + printf("-- "); + } + printf("\n"); + } + + close(fd); + + return err; +} + + +int +main(int argc, char** argv) +{ + int c; + while ((c = getopt_long(argc, argv, "h", kLongOptions, NULL)) != -1) { + switch (c) { + case 0: + break; + case 'h': + usage(0); + break; + default: + usage(1); + break; + } + } + + if (argc - optind < 1) + usage(1); + const char* path = argv[optind++]; + + exit(scan_bus(path)); +}