From ee87ae146f5384d6e91470765ac555f0c3e9185f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 28 Mar 2020 23:12:33 +0100 Subject: [PATCH] i2c: add diagnostic utility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I7e87457ff6e4210e256f9e41e5555e2d0e1ba20d Reviewed-on: https://review.haiku-os.org/c/haiku/+/2459 Reviewed-by: Jérôme Duval Reviewed-by: Adrien Destugues --- src/bin/Jamfile | 1 + src/bin/i2c/Jamfile | 7 +++ src/bin/i2c/i2c.cpp | 105 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 src/bin/i2c/Jamfile create mode 100644 src/bin/i2c/i2c.cpp 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)); +}