[PATCH v2] i2c-tools: i2cdetect: Set I2C adapter timeout and retries using ioctl

From: Vasantha Likitha T

Date: Mon Nov 09 2026 - 12:29:16 EST


Add -T TIMEOUT and -R RETRIES to i2cdetect to set the adapter
timeout and retry count through the I2C_TIMEOUT and I2C_RETRIES
ioctls before probing the bus.

TIMEOUT is given in units of 10 ms, as the I2C_TIMEOUT ioctl expects.
Both values are applied only when the option is given, so the default
behaviour is unchanged. Non-numeric or negative values are rejected
with an error.

Signed-off-by: Vasantha Likitha T <vasanthalikitha.tandra@xxxxxxx>
---
Changes in v2:
- Move the change from i2ctransfer to i2cdetect and add -T and -R options,
as suggested in review.
---
tools/i2cdetect.c | 41 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/tools/i2cdetect.c b/tools/i2cdetect.c
index 3c22f17..8b08e55 100644
--- a/tools/i2cdetect.c
+++ b/tools/i2cdetect.c
@@ -35,11 +35,14 @@
static void help(void)
{
fprintf(stderr,
- "Usage: i2cdetect [-y] [-a] [-q|-r] I2CBUS [FIRST LAST]\n"
+ "Usage: i2cdetect [-y] [-a] [-q|-r] [-T TIMEOUT] [-R RETRIES]\n"
+ " I2CBUS [FIRST LAST]\n"
" i2cdetect -F I2CBUS\n"
" i2cdetect -l\n"
" I2CBUS is an integer or an I2C bus name\n"
- " If provided, FIRST and LAST limit the probing range.\n");
+ " If provided, FIRST and LAST limit the probing range.\n"
+ " TIMEOUT sets the adapter timeout (unit: 10 ms)\n"
+ " RETRIES sets the adapter retry count\n");
}

static int scan_i2c_bus(int file, int mode, unsigned long funcs,
@@ -220,9 +223,10 @@ int main(int argc, char *argv[])
int first = 0x08, last = 0x77;
int opt;
int yes = 0, version = 0, list = 0;
+ long timeout = -1, retries = -1;

/* handle (optional) flags first */
- while ((opt = getopt(argc, argv, "FVahlqry")) != -1) {
+ while ((opt = getopt(argc, argv, "FR:T:Vahlqry")) != -1) {
switch (opt) {
case 'V': version = 1; break;
case 'y': yes = 1; break;
@@ -235,6 +239,23 @@ int main(int argc, char *argv[])
}
mode = MODE_FUNC;
break;
+ case 'R':
+ retries = strtol(optarg, &end, 0);
+ if (*end || !*optarg || retries < 0) {
+ fprintf(stderr, "Error: Invalid number of "
+ "retries!\n");
+ help();
+ exit(1);
+ }
+ break;
+ case 'T':
+ timeout = strtol(optarg, &end, 0);
+ if (*end || !*optarg || timeout < 0) {
+ fprintf(stderr, "Error: Invalid timeout!\n");
+ help();
+ exit(1);
+ }
+ break;
case 'r':
if (mode == MODE_QUICK) {
fprintf(stderr, "Error: Different modes "
@@ -326,6 +347,20 @@ int main(int argc, char *argv[])
exit(1);
}

+ if (timeout >= 0 && ioctl(file, I2C_TIMEOUT, timeout) < 0) {
+ fprintf(stderr, "Error: Could not set the adapter timeout: %s\n",
+ strerror(errno));
+ close(file);
+ exit(1);
+ }
+
+ if (retries >= 0 && ioctl(file, I2C_RETRIES, retries) < 0) {
+ fprintf(stderr, "Error: Could not set the adapter retry count: %s\n",
+ strerror(errno));
+ close(file);
+ exit(1);
+ }
+
if (ioctl(file, I2C_FUNCS, &funcs) < 0) {
fprintf(stderr, "Error: Could not get the adapter "
"functionality matrix: %s\n", strerror(errno));
--
2.43.0