1 /* vi: set sw=4 ts=4: */
3 * Minimal i2c-tools implementation for busybox.
4 * Parts of code ported from i2c-tools:
5 * http://www.lm-sensors.org/wiki/I2CTools.
7 * Copyright (C) 2014 by Bartosz Golaszewski <bartekgola@gmail.com>
9 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
11 //config:config I2CGET
12 //config: bool "i2cget (5.7 kb)"
15 //config: Read from I2C/SMBus chip registers.
17 //config:config I2CSET
18 //config: bool "i2cset (6.9 kb)"
21 //config: Set I2C registers.
23 //config:config I2CDUMP
24 //config: bool "i2cdump (7.2 kb)"
27 //config: Examine I2C registers.
29 //config:config I2CDETECT
30 //config: bool "i2cdetect (7.3 kb)"
33 //config: Detect I2C chips.
35 //config:config I2CTRANSFER
36 //config: bool "i2ctransfer (5.5 kb)"
39 //config: Send user-defined I2C messages in one transfer.
42 //applet:IF_I2CGET(APPLET(i2cget, BB_DIR_USR_SBIN, BB_SUID_DROP))
43 //applet:IF_I2CSET(APPLET(i2cset, BB_DIR_USR_SBIN, BB_SUID_DROP))
44 //applet:IF_I2CDUMP(APPLET(i2cdump, BB_DIR_USR_SBIN, BB_SUID_DROP))
45 //applet:IF_I2CDETECT(APPLET(i2cdetect, BB_DIR_USR_SBIN, BB_SUID_DROP))
46 //applet:IF_I2CTRANSFER(APPLET(i2ctransfer, BB_DIR_USR_SBIN, BB_SUID_DROP))
47 /* not NOEXEC: if hw operation stalls, use less memory in "hung" process */
49 //kbuild:lib-$(CONFIG_I2CGET) += i2c_tools.o
50 //kbuild:lib-$(CONFIG_I2CSET) += i2c_tools.o
51 //kbuild:lib-$(CONFIG_I2CDUMP) += i2c_tools.o
52 //kbuild:lib-$(CONFIG_I2CDETECT) += i2c_tools.o
53 //kbuild:lib-$(CONFIG_I2CTRANSFER) += i2c_tools.o
58 * - upstream i2c-tools can also look-up i2c busses by name, we only accept
60 * - bank and bankreg parameters for i2cdump are not supported because of
61 * their limited usefulness (see i2cdump manual entry for more info),
62 * - i2cdetect doesn't look for bus info in /proc as it does in upstream, but
63 * it shouldn't be a problem in modern kernels.
68 #include <linux/i2c.h>
70 #define I2CDUMP_NUM_REGS 256
72 #define I2CDETECT_MODE_AUTO 0
73 #define I2CDETECT_MODE_QUICK 1
74 #define I2CDETECT_MODE_READ 2
76 /* linux/i2c-dev.h from i2c-tools overwrites the one from linux uapi
77 * and defines symbols already defined by linux/i2c.h.
78 * Also, it defines a bunch of static inlines which we would rather NOT
79 * inline. What a mess.
80 * We need only these definitions from linux/i2c-dev.h:
82 #define I2C_SLAVE 0x0703
83 #define I2C_SLAVE_FORCE 0x0706
84 #define I2C_FUNCS 0x0705
85 #define I2C_PEC 0x0708
86 #define I2C_SMBUS 0x0720
87 #define I2C_RDWR 0x0707
88 #define I2C_RDWR_IOCTL_MAX_MSGS 42
89 #define I2C_RDWR_IOCTL_MAX_MSGS_STR "42"
90 struct i2c_smbus_ioctl_data
{
94 union i2c_smbus_data
*data
;
96 struct i2c_rdwr_ioctl_data
{
97 struct i2c_msg
*msgs
; /* pointers to i2c_msgs */
98 __u32 nmsgs
; /* number of i2c_msgs */
100 /* end linux/i2c-dev.h */
103 * This is needed for ioctl_or_perror_and_die() since it only accepts pointers.
105 static ALWAYS_INLINE
void *itoptr(int i
)
107 return (void*)(intptr_t)i
;
110 #if ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP || ENABLE_I2CDETECT
111 static int32_t i2c_smbus_access(int fd
, char read_write
, uint8_t cmd
,
112 int size
, union i2c_smbus_data
*data
)
114 struct i2c_smbus_ioctl_data args
;
116 args
.read_write
= read_write
;
121 return ioctl(fd
, I2C_SMBUS
, &args
);
124 static int32_t i2c_smbus_read_byte(int fd
)
126 union i2c_smbus_data data
;
129 err
= i2c_smbus_access(fd
, I2C_SMBUS_READ
, 0, I2C_SMBUS_BYTE
, &data
);
137 #if ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP
138 static int32_t i2c_smbus_write_byte(int fd
, uint8_t val
)
140 return i2c_smbus_access(fd
, I2C_SMBUS_WRITE
,
141 val
, I2C_SMBUS_BYTE
, NULL
);
144 static int32_t i2c_smbus_read_byte_data(int fd
, uint8_t cmd
)
146 union i2c_smbus_data data
;
149 err
= i2c_smbus_access(fd
, I2C_SMBUS_READ
, cmd
,
150 I2C_SMBUS_BYTE_DATA
, &data
);
157 static int32_t i2c_smbus_read_word_data(int fd
, uint8_t cmd
)
159 union i2c_smbus_data data
;
162 err
= i2c_smbus_access(fd
, I2C_SMBUS_READ
, cmd
,
163 I2C_SMBUS_WORD_DATA
, &data
);
169 #endif /* ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP */
172 static int32_t i2c_smbus_write_byte_data(int file
,
173 uint8_t cmd
, uint8_t value
)
175 union i2c_smbus_data data
;
179 return i2c_smbus_access(file
, I2C_SMBUS_WRITE
, cmd
,
180 I2C_SMBUS_BYTE_DATA
, &data
);
183 static int32_t i2c_smbus_write_word_data(int file
, uint8_t cmd
, uint16_t value
)
185 union i2c_smbus_data data
;
189 return i2c_smbus_access(file
, I2C_SMBUS_WRITE
, cmd
,
190 I2C_SMBUS_WORD_DATA
, &data
);
193 static int32_t i2c_smbus_write_block_data(int file
, uint8_t cmd
,
194 uint8_t length
, const uint8_t *values
)
196 union i2c_smbus_data data
;
198 if (length
> I2C_SMBUS_BLOCK_MAX
)
199 length
= I2C_SMBUS_BLOCK_MAX
;
201 memcpy(data
.block
+1, values
, length
);
202 data
.block
[0] = length
;
204 return i2c_smbus_access(file
, I2C_SMBUS_WRITE
, cmd
,
205 I2C_SMBUS_BLOCK_DATA
, &data
);
208 static int32_t i2c_smbus_write_i2c_block_data(int file
, uint8_t cmd
,
209 uint8_t length
, const uint8_t *values
)
211 union i2c_smbus_data data
;
213 if (length
> I2C_SMBUS_BLOCK_MAX
)
214 length
= I2C_SMBUS_BLOCK_MAX
;
216 memcpy(data
.block
+1, values
, length
);
217 data
.block
[0] = length
;
219 return i2c_smbus_access(file
, I2C_SMBUS_WRITE
, cmd
,
220 I2C_SMBUS_I2C_BLOCK_BROKEN
, &data
);
222 #endif /* ENABLE_I2CSET */
226 * Returns the number of bytes read, vals must hold at
227 * least I2C_SMBUS_BLOCK_MAX bytes.
229 static int32_t i2c_smbus_read_block_data(int fd
, uint8_t cmd
, uint8_t *vals
)
231 union i2c_smbus_data data
;
234 err
= i2c_smbus_access(fd
, I2C_SMBUS_READ
, cmd
,
235 I2C_SMBUS_BLOCK_DATA
, &data
);
239 for (i
= 1; i
<= data
.block
[0]; i
++)
240 *vals
++ = data
.block
[i
];
241 return data
.block
[0];
244 static int32_t i2c_smbus_read_i2c_block_data(int fd
, uint8_t cmd
,
245 uint8_t len
, uint8_t *vals
)
247 union i2c_smbus_data data
;
250 if (len
> I2C_SMBUS_BLOCK_MAX
)
251 len
= I2C_SMBUS_BLOCK_MAX
;
254 err
= i2c_smbus_access(fd
, I2C_SMBUS_READ
, cmd
,
255 len
== 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN
:
256 I2C_SMBUS_I2C_BLOCK_DATA
, &data
);
260 for (i
= 1; i
<= data
.block
[0]; i
++)
261 *vals
++ = data
.block
[i
];
262 return data
.block
[0];
264 #endif /* ENABLE_I2CDUMP */
267 static int32_t i2c_smbus_write_quick(int fd
, uint8_t val
)
269 return i2c_smbus_access(fd
, val
, 0, I2C_SMBUS_QUICK
, NULL
);
271 #endif /* ENABLE_I2CDETECT */
273 static int i2c_bus_lookup(const char *bus_str
)
275 return xstrtou_range(bus_str
, 10, 0, 0xfffff);
278 #if ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP
279 static int i2c_parse_bus_addr(const char *addr_str
)
281 /* Slave address must be in range 0x03 - 0x77. */
282 return xstrtou_range(addr_str
, 16, 0x03, 0x77);
285 static void i2c_set_pec(int fd
, int pec
)
287 ioctl_or_perror_and_die(fd
, I2C_PEC
,
293 #if ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP || ENABLE_I2CTRANSFER
294 static void i2c_set_slave_addr(int fd
, int addr
, int force
)
296 ioctl_or_perror_and_die(fd
, force
? I2C_SLAVE_FORCE
: I2C_SLAVE
,
298 "can't set address to 0x%02x", addr
);
302 #if ENABLE_I2CGET || ENABLE_I2CSET
303 static int i2c_parse_data_addr(const char *data_addr
)
305 /* Data address must be an 8 bit integer. */
306 return xstrtou_range(data_addr
, 16, 0, 0xff);
308 #endif /* ENABLE_I2CGET || ENABLE_I2CSET */
311 * Opens the device file associated with given i2c bus.
313 * Upstream i2c-tools also support opening devices by i2c bus name
314 * but we drop it here for size reduction.
316 static int i2c_dev_open(int i2cbus
)
318 char filename
[sizeof("/dev/i2c-%d") + sizeof(int)*3];
321 sprintf(filename
, "/dev/i2c-%d", i2cbus
);
322 fd
= open(filename
, O_RDWR
);
324 if (errno
== ENOENT
) {
325 filename
[8] = '/'; /* change to "/dev/i2c/%d" */
326 fd
= xopen(filename
, O_RDWR
);
328 bb_perror_msg_and_die("can't open '%s'", filename
);
335 /* Size reducing helpers for xxx_check_funcs(). */
336 static void get_funcs_matrix(int fd
, unsigned long *funcs
)
338 ioctl_or_perror_and_die(fd
, I2C_FUNCS
, funcs
,
339 "can't get adapter functionality matrix");
342 #if ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP
343 static void check_funcs_test_end(int funcs
, int pec
, const char *err
)
345 if (pec
&& !(funcs
& (I2C_FUNC_SMBUS_PEC
| I2C_FUNC_I2C
)))
346 bb_simple_error_msg("warning: adapter does not support PEC");
349 bb_error_msg_and_die(
350 "adapter has no %s capability", err
);
352 #endif /* ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP */
355 * The below functions emit an error message and exit if the adapter doesn't
356 * support desired functionalities.
358 #if ENABLE_I2CGET || ENABLE_I2CDUMP
359 static void check_read_funcs(int fd
, int mode
, int data_addr
, int pec
)
362 const char *err
= NULL
;
364 get_funcs_matrix(fd
, &funcs
);
367 if (!(funcs
& I2C_FUNC_SMBUS_READ_BYTE
)) {
368 err
= "SMBus receive byte";
371 if (data_addr
>= 0 && !(funcs
& I2C_FUNC_SMBUS_WRITE_BYTE
))
372 err
= "SMBus send byte";
374 case I2C_SMBUS_BYTE_DATA
:
375 if (!(funcs
& I2C_FUNC_SMBUS_READ_BYTE_DATA
))
376 err
= "SMBus read byte";
378 case I2C_SMBUS_WORD_DATA
:
379 if (!(funcs
& I2C_FUNC_SMBUS_READ_WORD_DATA
))
380 err
= "SMBus read word";
383 case I2C_SMBUS_BLOCK_DATA
:
384 if (!(funcs
& I2C_FUNC_SMBUS_READ_BLOCK_DATA
))
385 err
= "SMBus block read";
388 case I2C_SMBUS_I2C_BLOCK_DATA
:
389 if (!(funcs
& I2C_FUNC_SMBUS_READ_I2C_BLOCK
))
390 err
= "I2C block read";
392 #endif /* ENABLE_I2CDUMP */
394 bb_simple_error_msg_and_die("internal error");
396 check_funcs_test_end(funcs
, pec
, err
);
398 #endif /* ENABLE_I2CGET || ENABLE_I2CDUMP */
401 static void check_write_funcs(int fd
, int mode
, int pec
)
404 const char *err
= NULL
;
406 get_funcs_matrix(fd
, &funcs
);
409 if (!(funcs
& I2C_FUNC_SMBUS_WRITE_BYTE
))
410 err
= "SMBus send byte";
413 case I2C_SMBUS_BYTE_DATA
:
414 if (!(funcs
& I2C_FUNC_SMBUS_WRITE_BYTE_DATA
))
415 err
= "SMBus write byte";
418 case I2C_SMBUS_WORD_DATA
:
419 if (!(funcs
& I2C_FUNC_SMBUS_WRITE_WORD_DATA
))
420 err
= "SMBus write word";
423 case I2C_SMBUS_BLOCK_DATA
:
424 if (!(funcs
& I2C_FUNC_SMBUS_WRITE_BLOCK_DATA
))
425 err
= "SMBus block write";
427 case I2C_SMBUS_I2C_BLOCK_DATA
:
428 if (!(funcs
& I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
))
429 err
= "I2C block write";
432 check_funcs_test_end(funcs
, pec
, err
);
434 #endif /* ENABLE_I2CSET */
436 static void confirm_or_abort(void)
438 fprintf(stderr
, "Continue? [y/N] ");
439 if (!bb_ask_y_confirmation())
440 bb_simple_error_msg_and_die("aborting");
444 * Return only if user confirms the action, abort otherwise.
446 * The messages displayed here are much less elaborate than their i2c-tools
447 * counterparts - this is done for size reduction.
449 static void confirm_action(int bus_addr
, int mode
, int data_addr
, int pec
)
451 bb_simple_error_msg("WARNING! This program can confuse your I2C bus");
453 /* Don't let the user break his/her EEPROMs */
454 if (bus_addr
>= 0x50 && bus_addr
<= 0x57 && pec
) {
455 bb_simple_error_msg_and_die("this is I2C not smbus - using PEC on I2C "
456 "devices may result in data loss, aborting");
459 if (mode
== I2C_SMBUS_BYTE
&& data_addr
>= 0 && pec
)
460 bb_simple_error_msg("WARNING! May interpret a write byte command "
461 "with PEC as a write byte data command");
464 bb_simple_error_msg("PEC checking enabled");
470 //usage:#define i2cget_trivial_usage
471 //usage: "[-fy] BUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]"
472 //usage:#define i2cget_full_usage "\n\n"
473 //usage: "Read from I2C/SMBus chip registers"
475 //usage: "\n I2CBUS I2C bus number"
476 //usage: "\n ADDRESS 0x03-0x77"
477 //usage: "\nMODE is:"
478 //usage: "\n b Read byte data (default)"
479 //usage: "\n w Read word data"
480 //usage: "\n c Write byte/read byte"
481 //usage: "\n Append p for SMBus PEC"
483 //usage: "\n -f Force access"
484 //usage: "\n -y Disable interactive mode"
485 int i2cget_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
486 int i2cget_main(int argc UNUSED_PARAM
, char **argv
)
488 const unsigned opt_f
= (1 << 0), opt_y
= (1 << 1);
490 int bus_num
, bus_addr
, data_addr
= -1, status
;
491 int mode
= I2C_SMBUS_BYTE
, pec
= 0, fd
;
494 opts
= getopt32(argv
, "^" "fy" "\0" "-2:?4"/*from 2 to 4 args*/);
497 bus_num
= i2c_bus_lookup(argv
[0]);
498 bus_addr
= i2c_parse_bus_addr(argv
[1]);
501 data_addr
= i2c_parse_data_addr(argv
[2]);
502 mode
= I2C_SMBUS_BYTE_DATA
;
504 switch (argv
[3][0]) {
505 case 'b': /* Already set */ break;
506 case 'w': mode
= I2C_SMBUS_WORD_DATA
; break;
507 case 'c': mode
= I2C_SMBUS_BYTE
; break;
509 bb_simple_error_msg("invalid mode");
512 pec
= argv
[3][1] == 'p';
516 fd
= i2c_dev_open(bus_num
);
517 check_read_funcs(fd
, mode
, data_addr
, pec
);
518 i2c_set_slave_addr(fd
, bus_addr
, opts
& opt_f
);
521 confirm_action(bus_addr
, mode
, data_addr
, pec
);
528 if (data_addr
>= 0) {
529 status
= i2c_smbus_write_byte(fd
, data_addr
);
531 bb_simple_error_msg("warning - write failed");
533 status
= i2c_smbus_read_byte(fd
);
535 case I2C_SMBUS_WORD_DATA
:
536 status
= i2c_smbus_read_word_data(fd
, data_addr
);
538 default: /* I2C_SMBUS_BYTE_DATA */
539 status
= i2c_smbus_read_byte_data(fd
, data_addr
);
544 bb_simple_perror_msg_and_die("read failed");
546 printf("0x%0*x\n", mode
== I2C_SMBUS_WORD_DATA
? 4 : 2, status
);
550 #endif /* ENABLE_I2CGET */
553 //usage:#define i2cset_trivial_usage
554 //usage: "[-fy] [-m MASK] BUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]"
555 //usage:#define i2cset_full_usage "\n\n"
556 //usage: "Set I2C registers"
558 //usage: "\n I2CBUS I2C bus number"
559 //usage: "\n ADDRESS 0x03-0x77"
560 //usage: "\nMODE is:"
561 //usage: "\n c Byte, no value"
562 //usage: "\n b Byte data (default)"
563 //usage: "\n w Word data"
564 //usage: "\n i I2C block data"
565 //usage: "\n s SMBus block data"
566 //usage: "\n Append p for SMBus PEC"
568 //usage: "\n -f Force access"
569 //usage: "\n -y Disable interactive mode"
570 //usage: "\n -r Read back and compare the result"
571 //usage: "\n -m MASK Mask specifying which bits to write"
572 int i2cset_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
573 int i2cset_main(int argc
, char **argv
)
575 const unsigned opt_f
= (1 << 0), opt_y
= (1 << 1),
576 opt_m
= (1 << 2), opt_r
= (1 << 3);
578 int bus_num
, bus_addr
, data_addr
, mode
= I2C_SMBUS_BYTE
, pec
= 0;
579 int val
, blen
, mask
, fd
, status
;
580 unsigned char block
[I2C_SMBUS_BLOCK_MAX
];
581 char *opt_m_arg
= NULL
;
584 opts
= getopt32(argv
, "^"
586 "\0" "-3", /* minimum 3 args */
591 argc
--; /* now argv[argc] is last arg */
593 bus_num
= i2c_bus_lookup(argv
[0]);
594 bus_addr
= i2c_parse_bus_addr(argv
[1]);
595 data_addr
= i2c_parse_data_addr(argv
[2]);
598 if (!argv
[4] && argv
[3][0] != 'c') {
599 mode
= I2C_SMBUS_BYTE_DATA
; /* Implicit b */
601 switch (argv
[argc
][0]) {
602 case 'c': /* Already set */
604 case 'b': mode
= I2C_SMBUS_BYTE_DATA
;
606 case 'w': mode
= I2C_SMBUS_WORD_DATA
;
608 case 's': mode
= I2C_SMBUS_BLOCK_DATA
;
610 case 'i': mode
= I2C_SMBUS_I2C_BLOCK_DATA
;
613 bb_simple_error_msg("invalid mode");
617 pec
= (argv
[argc
][1] == 'p');
618 if (mode
== I2C_SMBUS_BLOCK_DATA
619 || mode
== I2C_SMBUS_I2C_BLOCK_DATA
621 if (pec
&& mode
== I2C_SMBUS_I2C_BLOCK_DATA
)
622 bb_simple_error_msg_and_die(
623 "PEC not supported for I2C "
626 bb_simple_error_msg_and_die(
627 "mask not supported for block "
633 /* Prepare the value(s) to be written according to current mode. */
637 case I2C_SMBUS_BYTE_DATA
:
638 val
= xstrtou_range(argv
[3], 0, 0, 0xff);
640 case I2C_SMBUS_WORD_DATA
:
641 val
= xstrtou_range(argv
[3], 0, 0, 0xffff);
643 case I2C_SMBUS_BLOCK_DATA
:
644 case I2C_SMBUS_I2C_BLOCK_DATA
:
645 for (blen
= 3; blen
< argc
; blen
++)
646 block
[blen
- 3] = xstrtou_range(argv
[blen
], 0, 0, 0xff);
656 mask
= xstrtou_range(opt_m_arg
, 0, 0,
657 (mode
== I2C_SMBUS_BYTE
||
658 mode
== I2C_SMBUS_BYTE_DATA
) ? 0xff : 0xffff);
661 fd
= i2c_dev_open(bus_num
);
662 check_write_funcs(fd
, mode
, pec
);
663 i2c_set_slave_addr(fd
, bus_addr
, opts
& opt_f
);
666 confirm_action(bus_addr
, mode
, data_addr
, pec
);
669 * If we're using mask - read the current value here and adjust the
670 * value to be written.
677 tmpval
= i2c_smbus_read_byte(fd
);
679 case I2C_SMBUS_WORD_DATA
:
680 tmpval
= i2c_smbus_read_word_data(fd
, data_addr
);
683 tmpval
= i2c_smbus_read_byte_data(fd
, data_addr
);
687 bb_simple_perror_msg_and_die("can't read old value");
689 val
= (val
& mask
) | (tmpval
& ~mask
);
691 if (!(opts
& opt_y
)) {
692 bb_error_msg("old value 0x%0*x, write mask "
693 "0x%0*x, will write 0x%0*x to register "
695 mode
== I2C_SMBUS_WORD_DATA
? 4 : 2, tmpval
,
696 mode
== I2C_SMBUS_WORD_DATA
? 4 : 2, mask
,
697 mode
== I2C_SMBUS_WORD_DATA
? 4 : 2, val
,
708 status
= i2c_smbus_write_byte(fd
, data_addr
);
710 case I2C_SMBUS_WORD_DATA
:
711 status
= i2c_smbus_write_word_data(fd
, data_addr
, val
);
713 case I2C_SMBUS_BLOCK_DATA
:
714 status
= i2c_smbus_write_block_data(fd
, data_addr
,
717 case I2C_SMBUS_I2C_BLOCK_DATA
:
718 status
= i2c_smbus_write_i2c_block_data(fd
, data_addr
,
721 default: /* I2C_SMBUS_BYTE_DATA */
722 status
= i2c_smbus_write_byte_data(fd
, data_addr
, val
);
726 bb_simple_perror_msg_and_die("write failed");
729 i2c_set_pec(fd
, 0); /* Clear PEC. */
731 /* No readback required - we're done. */
737 status
= i2c_smbus_read_byte(fd
);
740 case I2C_SMBUS_WORD_DATA
:
741 status
= i2c_smbus_read_word_data(fd
, data_addr
);
743 default: /* I2C_SMBUS_BYTE_DATA */
744 status
= i2c_smbus_read_byte_data(fd
, data_addr
);
748 puts("Warning - readback failed");
751 printf("Warning - data mismatch - wrote "
752 "0x%0*x, read back 0x%0*x\n",
753 mode
== I2C_SMBUS_WORD_DATA
? 4 : 2, val
,
754 mode
== I2C_SMBUS_WORD_DATA
? 4 : 2, status
);
756 printf("Value 0x%0*x written, readback matched\n",
757 mode
== I2C_SMBUS_WORD_DATA
? 4 : 2, val
);
762 #endif /* ENABLE_I2CSET */
765 static int read_block_data(int buf_fd
, int mode
, int *block
)
767 uint8_t cblock
[I2C_SMBUS_BLOCK_MAX
+ I2CDUMP_NUM_REGS
];
768 int res
, blen
= 0, tmp
, i
;
770 if (mode
== I2C_SMBUS_BLOCK_DATA
) {
771 blen
= i2c_smbus_read_block_data(buf_fd
, 0, cblock
);
775 for (res
= 0; res
< I2CDUMP_NUM_REGS
; res
+= tmp
) {
776 tmp
= i2c_smbus_read_i2c_block_data(
777 buf_fd
, res
, I2C_SMBUS_BLOCK_MAX
,
785 if (res
>= I2CDUMP_NUM_REGS
)
786 res
= I2CDUMP_NUM_REGS
;
788 for (i
= 0; i
< res
; i
++)
789 block
[i
] = cblock
[i
];
791 if (mode
!= I2C_SMBUS_BLOCK_DATA
)
792 for (i
= res
; i
< I2CDUMP_NUM_REGS
; i
++)
799 bb_error_msg_and_die("block read failed: %d", blen
);
802 /* Dump all but word data. */
803 static void dump_data(int bus_fd
, int mode
, unsigned first
,
804 unsigned last
, int *block
, int blen
)
808 puts(" 0 1 2 3 4 5 6 7 8 9 a b c d e f"
809 " 0123456789abcdef");
811 for (i
= 0; i
< I2CDUMP_NUM_REGS
; i
+= 0x10) {
812 if (mode
== I2C_SMBUS_BLOCK_DATA
&& i
>= blen
)
820 for (j
= 0; j
< 16; j
++) {
822 /* Skip unwanted registers */
823 if (i
+j
< first
|| i
+j
> last
) {
825 if (mode
== I2C_SMBUS_WORD_DATA
) {
833 case I2C_SMBUS_BYTE_DATA
:
834 res
= i2c_smbus_read_byte_data(bus_fd
, i
+j
);
837 case I2C_SMBUS_WORD_DATA
:
838 res
= i2c_smbus_read_word_data(bus_fd
, i
+j
);
843 block
[i
+j
] = res
& 0xff;
844 block
[i
+j
+1] = res
>> 8;
848 res
= i2c_smbus_read_byte(bus_fd
);
855 if (mode
== I2C_SMBUS_BLOCK_DATA
&&
858 } else if (res
< 0) {
860 if (mode
== I2C_SMBUS_WORD_DATA
)
863 printf("%02x ", block
[i
+j
]);
864 if (mode
== I2C_SMBUS_WORD_DATA
)
865 printf("%02x ", block
[i
+j
+1]);
868 if (mode
== I2C_SMBUS_WORD_DATA
)
873 for (j
= 0; j
< 16; j
++) {
874 if (mode
== I2C_SMBUS_BLOCK_DATA
&& i
+j
>= blen
)
876 /* Skip unwanted registers */
877 if (i
+j
< first
|| i
+j
> last
) {
885 } else if (res
== 0x00 || res
== 0xff) {
887 } else if (res
< 32 || res
>= 127) {
897 static void dump_word_data(int bus_fd
, unsigned first
, unsigned last
)
902 puts(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f");
903 for (i
= 0; i
< 256; i
+= 8) {
910 for (j
= 0; j
< 8; j
++) {
911 /* Skip unwanted registers. */
912 if (i
+j
< first
|| i
+j
> last
) {
917 rv
= i2c_smbus_read_word_data(bus_fd
, i
+j
);
921 printf("%04x ", rv
& 0xffff);
927 //usage:#define i2cdump_trivial_usage
928 //usage: "[-fy] [-r FIRST-LAST] BUS ADDR [MODE]"
929 //usage:#define i2cdump_full_usage "\n\n"
930 //usage: "Examine I2C registers"
932 //usage: "\n I2CBUS I2C bus number"
933 //usage: "\n ADDRESS 0x03-0x77"
934 //usage: "\nMODE is:"
935 //usage: "\n b Byte (default)"
937 //usage: "\n W Word on even register addresses"
938 //usage: "\n i I2C block"
939 //usage: "\n s SMBus block"
940 //usage: "\n c Consecutive byte"
941 //usage: "\n Append p for SMBus PEC"
943 //usage: "\n -f Force access"
944 //usage: "\n -y Disable interactive mode"
945 //usage: "\n -r Limit the number of registers being accessed"
946 int i2cdump_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
947 int i2cdump_main(int argc UNUSED_PARAM
, char **argv
)
949 const unsigned opt_f
= (1 << 0), opt_y
= (1 << 1),
952 int bus_num
, bus_addr
, mode
= I2C_SMBUS_BYTE_DATA
, even
= 0, pec
= 0;
953 unsigned first
= 0x00, last
= 0xff, opts
;
954 int block
[I2CDUMP_NUM_REGS
];
955 char *opt_r_str
, *dash
;
958 opts
= getopt32(argv
, "^"
960 "\0" "-2:?3" /* from 2 to 3 args */,
965 bus_num
= i2c_bus_lookup(argv
[0]);
966 bus_addr
= i2c_parse_bus_addr(argv
[1]);
969 switch (argv
[2][0]) {
970 case 'b': /* Already set. */ break;
971 case 'c': mode
= I2C_SMBUS_BYTE
; break;
972 case 'w': mode
= I2C_SMBUS_WORD_DATA
; break;
974 mode
= I2C_SMBUS_WORD_DATA
;
977 case 's': mode
= I2C_SMBUS_BLOCK_DATA
; break;
978 case 'i': mode
= I2C_SMBUS_I2C_BLOCK_DATA
; break;
980 bb_simple_error_msg_and_die("invalid mode");
983 if (argv
[2][1] == 'p') {
984 if (argv
[2][0] == 'W' || argv
[2][0] == 'i') {
985 bb_simple_error_msg_and_die(
986 "pec not supported for -W and -i");
994 first
= strtol(opt_r_str
, &dash
, 0);
995 if (dash
== opt_r_str
|| *dash
!= '-' || first
> 0xff)
996 bb_simple_error_msg_and_die("invalid range");
997 last
= xstrtou_range(++dash
, 0, first
, 0xff);
999 /* Range is not available for every mode. */
1001 case I2C_SMBUS_BYTE
:
1002 case I2C_SMBUS_BYTE_DATA
:
1004 case I2C_SMBUS_WORD_DATA
:
1005 if (!even
|| (!(first
% 2) && last
% 2))
1009 bb_simple_error_msg_and_die(
1010 "range not compatible with selected mode");
1014 fd
= i2c_dev_open(bus_num
);
1015 check_read_funcs(fd
, mode
, -1 /* data_addr */, pec
);
1016 i2c_set_slave_addr(fd
, bus_addr
, opts
& opt_f
);
1021 if (!(opts
& opt_y
))
1022 confirm_action(bus_addr
, mode
, -1 /* data_addr */, pec
);
1024 /* All but word data. */
1025 if (mode
!= I2C_SMBUS_WORD_DATA
|| even
) {
1028 if (mode
== I2C_SMBUS_BLOCK_DATA
|| mode
== I2C_SMBUS_I2C_BLOCK_DATA
)
1029 blen
= read_block_data(fd
, mode
, block
);
1031 if (mode
== I2C_SMBUS_BYTE
) {
1032 res
= i2c_smbus_write_byte(fd
, first
);
1034 bb_simple_perror_msg_and_die("write start address");
1037 dump_data(fd
, mode
, first
, last
, block
, blen
);
1039 dump_word_data(fd
, first
, last
);
1044 #endif /* ENABLE_I2CDUMP */
1046 #if ENABLE_I2CDETECT
1059 static const struct adap_desc adap_descs
[] ALIGN_PTR
= {
1060 { .funcs
= "dummy", .algo
= "Dummy bus", },
1061 { .funcs
= "isa", .algo
= "ISA bus", },
1062 { .funcs
= "i2c", .algo
= "I2C adapter", },
1063 { .funcs
= "smbus", .algo
= "SMBus adapter", },
1071 static const struct i2c_func i2c_funcs_tab
[] ALIGN_PTR
= {
1072 { .value
= I2C_FUNC_I2C
,
1074 { .value
= I2C_FUNC_SMBUS_QUICK
,
1075 .name
= "SMBus quick command" },
1076 { .value
= I2C_FUNC_SMBUS_WRITE_BYTE
,
1077 .name
= "SMBus send byte" },
1078 { .value
= I2C_FUNC_SMBUS_READ_BYTE
,
1079 .name
= "SMBus receive byte" },
1080 { .value
= I2C_FUNC_SMBUS_WRITE_BYTE_DATA
,
1081 .name
= "SMBus write byte" },
1082 { .value
= I2C_FUNC_SMBUS_READ_BYTE_DATA
,
1083 .name
= "SMBus read byte" },
1084 { .value
= I2C_FUNC_SMBUS_WRITE_WORD_DATA
,
1085 .name
= "SMBus write word" },
1086 { .value
= I2C_FUNC_SMBUS_READ_WORD_DATA
,
1087 .name
= "SMBus read word" },
1088 { .value
= I2C_FUNC_SMBUS_PROC_CALL
,
1089 .name
= "SMBus process call" },
1090 { .value
= I2C_FUNC_SMBUS_WRITE_BLOCK_DATA
,
1091 .name
= "SMBus block write" },
1092 { .value
= I2C_FUNC_SMBUS_READ_BLOCK_DATA
,
1093 .name
= "SMBus block read" },
1094 { .value
= I2C_FUNC_SMBUS_BLOCK_PROC_CALL
,
1095 .name
= "SMBus block process call" },
1096 { .value
= I2C_FUNC_SMBUS_PEC
,
1097 .name
= "SMBus PEC" },
1098 { .value
= I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
,
1099 .name
= "I2C block write" },
1100 { .value
= I2C_FUNC_SMBUS_READ_I2C_BLOCK
,
1101 .name
= "I2C block read" },
1102 { .value
= 0, .name
= NULL
}
1105 static enum adapter_type
i2cdetect_get_funcs(int bus
)
1107 enum adapter_type ret
;
1108 unsigned long funcs
;
1111 fd
= i2c_dev_open(bus
);
1113 get_funcs_matrix(fd
, &funcs
);
1114 if (funcs
& I2C_FUNC_I2C
)
1116 else if (funcs
& (I2C_FUNC_SMBUS_BYTE
|
1117 I2C_FUNC_SMBUS_BYTE_DATA
|
1118 I2C_FUNC_SMBUS_WORD_DATA
))
1128 static void NORETURN
list_i2c_busses_and_exit(void)
1130 const char *const i2cdev_path
= "/sys/class/i2c-dev";
1132 char path
[NAME_MAX
], name
[128];
1133 struct dirent
*de
, *subde
;
1134 enum adapter_type adt
;
1141 * XXX Upstream i2cdetect also looks for i2c bus info in /proc/bus/i2c,
1142 * but we won't bother since it's only useful on older kernels (before
1143 * 2.6.5). We expect sysfs to be present and mounted at /sys/.
1146 dir
= xopendir(i2cdev_path
);
1147 while ((de
= readdir(dir
))) {
1148 if (de
->d_name
[0] == '.')
1151 /* Simple version for ISA chips. */
1152 snprintf(path
, NAME_MAX
, "%s/%s/name",
1153 i2cdev_path
, de
->d_name
);
1154 fp
= fopen_for_read(path
);
1156 snprintf(path
, NAME_MAX
,
1157 "%s/%s/device/name",
1158 i2cdev_path
, de
->d_name
);
1159 fp
= fopen_for_read(path
);
1162 /* Non-ISA chips require the hard-way. */
1164 snprintf(path
, NAME_MAX
,
1165 "%s/%s/device/name",
1166 i2cdev_path
, de
->d_name
);
1167 subdir
= opendir(path
);
1171 while ((subde
= readdir(subdir
))) {
1172 if (subde
->d_name
[0] == '.')
1175 if (is_prefixed_with(subde
->d_name
, "i2c-")) {
1176 snprintf(path
, NAME_MAX
,
1177 "%s/%s/device/%s/name",
1178 i2cdev_path
, de
->d_name
,
1180 fp
= fopen_for_read(path
);
1188 * Get the rest of the info and display a line
1191 memset(name
, 0, sizeof(name
));
1192 pos
= fgets(name
, sizeof(name
), fp
);
1197 pos
= strchr(name
, '\n');
1201 rv
= sscanf(de
->d_name
, "i2c-%d", &bus
);
1205 if (is_prefixed_with(name
, "ISA"))
1208 adt
= i2cdetect_get_funcs(bus
);
1211 "i2c-%d\t%-10s\t%-32s\t%s\n",
1212 bus
, adap_descs
[adt
].funcs
,
1213 name
, adap_descs
[adt
].algo
);
1220 static void NORETURN
no_support(const char *cmd
)
1222 bb_error_msg_and_die("bus doesn't support %s", cmd
);
1225 static void will_skip(const char *cmd
)
1228 "warning: can't use %s command, "
1229 "will skip some addresses", cmd
);
1232 //usage:#define i2cdetect_trivial_usage
1233 //usage: "-l | -F I2CBUS | [-ya] [-q|-r] I2CBUS [FIRST LAST]"
1234 //usage:#define i2cdetect_full_usage "\n\n"
1235 //usage: "Detect I2C chips"
1237 //usage: "\n -l List installed buses"
1238 //usage: "\n -F BUS# List functionalities on this bus"
1239 //usage: "\n -y Disable interactive mode"
1240 //usage: "\n -a Force scanning of non-regular addresses"
1241 //usage: "\n -q Use smbus quick write commands for probing (default)"
1242 //usage: "\n -r Use smbus read byte commands for probing"
1243 //usage: "\n FIRST and LAST limit probing range"
1244 int i2cdetect_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
1245 int i2cdetect_main(int argc UNUSED_PARAM
, char **argv
)
1247 const unsigned opt_y
= (1 << 0), opt_a
= (1 << 1),
1248 opt_q
= (1 << 2), opt_r
= (1 << 3),
1249 opt_F
= (1 << 4), opt_l
= (1 << 5);
1251 int fd
, bus_num
, i
, j
, mode
= I2CDETECT_MODE_AUTO
, status
, cmd
;
1252 unsigned first
= 0x03, last
= 0x77, opts
;
1253 unsigned long funcs
;
1255 opts
= getopt32(argv
, "^"
1258 "q--r:r--q:"/*mutually exclusive*/
1259 "?3"/*up to 3 args*/
1264 list_i2c_busses_and_exit();
1269 bus_num
= i2c_bus_lookup(argv
[0]);
1270 fd
= i2c_dev_open(bus_num
);
1271 get_funcs_matrix(fd
, &funcs
);
1274 /* Only list the functionalities. */
1275 printf("Functionalities implemented by bus #%d\n", bus_num
);
1276 for (i
= 0; i2c_funcs_tab
[i
].value
; i
++) {
1277 printf("%-32s %s\n", i2c_funcs_tab
[i
].name
,
1278 funcs
& i2c_funcs_tab
[i
].value
? "yes" : "no");
1281 return EXIT_SUCCESS
;
1285 mode
= I2CDETECT_MODE_READ
;
1286 else if (opts
& opt_q
)
1287 mode
= I2CDETECT_MODE_QUICK
;
1294 /* Read address range. */
1296 first
= xstrtou_range(argv
[1], 16, first
, last
);
1298 last
= xstrtou_range(argv
[2], 16, first
, last
);
1301 if (!(funcs
& (I2C_FUNC_SMBUS_QUICK
| I2C_FUNC_SMBUS_READ_BYTE
))) {
1302 no_support("detection commands");
1304 if (mode
== I2CDETECT_MODE_QUICK
&& !(funcs
& I2C_FUNC_SMBUS_QUICK
)) {
1305 no_support("SMBus quick write");
1307 if (mode
== I2CDETECT_MODE_READ
&& !(funcs
& I2C_FUNC_SMBUS_READ_BYTE
)) {
1308 no_support("SMBus receive byte");
1311 if (mode
== I2CDETECT_MODE_AUTO
) {
1312 if (!(funcs
& I2C_FUNC_SMBUS_QUICK
))
1313 will_skip("SMBus quick write");
1314 if (!(funcs
& I2C_FUNC_SMBUS_READ_BYTE
))
1315 will_skip("SMBus receive byte");
1318 if (!(opts
& opt_y
))
1319 confirm_action(-1, -1, -1, 0);
1321 puts(" 0 1 2 3 4 5 6 7 8 9 a b c d e f");
1322 for (i
= 0; i
< 128; i
+= 16) {
1323 printf("%02x: ", i
);
1324 for (j
= 0; j
< 16; j
++) {
1328 if (mode
== I2CDETECT_MODE_AUTO
) {
1329 if ((i
+j
>= 0x30 && i
+j
<= 0x37) ||
1330 (i
+j
>= 0x50 && i
+j
<= 0x5F))
1331 cmd
= I2CDETECT_MODE_READ
;
1333 cmd
= I2CDETECT_MODE_QUICK
;
1336 /* Skip unwanted addresses. */
1339 || (cmd
== I2CDETECT_MODE_READ
&& !(funcs
& I2C_FUNC_SMBUS_READ_BYTE
))
1340 || (cmd
== I2CDETECT_MODE_QUICK
&& !(funcs
& I2C_FUNC_SMBUS_QUICK
)))
1346 status
= ioctl(fd
, I2C_SLAVE
, itoptr(i
+ j
));
1348 if (errno
== EBUSY
) {
1353 bb_perror_msg_and_die(
1354 "can't set address to 0x%02x", i
+ j
);
1358 case I2CDETECT_MODE_READ
:
1360 * This is known to lock SMBus on various
1361 * write-only chips (mainly clock chips).
1363 status
= i2c_smbus_read_byte(fd
);
1365 default: /* I2CDETECT_MODE_QUICK: */
1367 * This is known to corrupt the Atmel
1370 status
= i2c_smbus_write_quick(fd
,
1378 printf("%02x ", i
+j
);
1385 #endif /* ENABLE_I2CDETECT */
1387 #if ENABLE_I2CTRANSFER
1388 static void check_i2c_func(int fd
)
1390 unsigned long funcs
;
1392 get_funcs_matrix(fd
, &funcs
);
1394 if (!(funcs
& I2C_FUNC_I2C
))
1395 bb_simple_error_msg_and_die("adapter does not support I2C transfers");
1398 //usage:#define i2ctransfer_trivial_usage
1399 //usage: "[-fay] I2CBUS { rLENGTH[@ADDR] | wLENGTH[@ADDR] DATA...}..."
1400 //usage:#define i2ctransfer_full_usage "\n\n"
1401 //usage: "Read/write I2C data in one transfer"
1403 //usage: "\n -f Force access to busy addresses"
1404 //usage: "\n -a Force access to non-regular addresses"
1405 //usage: "\n -y Disable interactive mode"
1406 int i2ctransfer_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
1407 int i2ctransfer_main(int argc UNUSED_PARAM
, char **argv
)
1414 int bus_num
, bus_addr
;
1416 unsigned opts
, first
, last
;
1417 int nmsgs
, nmsgs_sent
, i
;
1418 struct i2c_msg msgs
[I2C_RDWR_IOCTL_MAX_MSGS
];
1419 struct i2c_rdwr_ioctl_data rdwr
;
1421 memset(msgs
, 0, sizeof(msgs
));
1423 opts
= getopt32(argv
, "^"
1425 "\0" "-2" /* minimum 2 args */
1435 bus_num
= i2c_bus_lookup(argv
[0]);
1436 fd
= i2c_dev_open(bus_num
);
1447 if (nmsgs
>= I2C_RDWR_IOCTL_MAX_MSGS
)
1448 bb_simple_error_msg_and_die("too many messages, max: "I2C_RDWR_IOCTL_MAX_MSGS_STR
);
1452 switch (*arg_ptr
++) {
1453 case 'r': flags
|= I2C_M_RD
; break;
1459 end
= strchr(arg_ptr
, '@');
1460 if (end
) *end
= '\0';
1461 len
= xstrtou_range(arg_ptr
, 0, 0, 0xffff);
1463 bus_addr
= xstrtou_range(end
+ 1, 0, first
, last
);
1464 i2c_set_slave_addr(fd
, bus_addr
, (opts
& opt_f
));
1466 /* Reuse last address if possible */
1468 bb_error_msg_and_die("no address given in '%s'", *argv
);
1471 msgs
[nmsgs
].addr
= bus_addr
;
1472 msgs
[nmsgs
].flags
= flags
;
1473 msgs
[nmsgs
].len
= len
;
1475 msgs
[nmsgs
].buf
= xzalloc(len
);
1477 if (!(flags
& I2C_M_RD
)) {
1478 /* Consume DATA arg(s) */
1479 unsigned buf_idx
= 0;
1481 while (buf_idx
< len
) {
1488 data
= strtoul(arg_ptr
, &end
, 0);
1489 if (data
> 0xff || arg_ptr
== end
)
1490 bb_error_msg_and_die("invalid data byte '%s'", *argv
);
1493 while (buf_idx
< len
) {
1494 msgs
[nmsgs
].buf
[buf_idx
++] = data8
;
1498 /* Pseudo randomness (8 bit AXR with a=13 and b=27) */
1500 data8
= (data8
^ 27) + 13;
1501 data8
= (data8
<< 1) | (data8
>> 7);
1503 case '+': data8
++; break;
1504 case '-': data8
--; break;
1507 bb_error_msg_and_die("invalid data byte suffix: '%s'",
1516 if (!(opts
& opt_y
))
1517 confirm_action(bus_addr
, 0, 0, 0);
1521 nmsgs_sent
= ioctl_or_perror_and_die(fd
, I2C_RDWR
, &rdwr
, "I2C_RDWR");
1522 if (nmsgs_sent
< nmsgs
)
1523 bb_error_msg("warning: only %u/%u messages sent", nmsgs_sent
, nmsgs
);
1525 for (i
= 0; i
< nmsgs_sent
; i
++) {
1526 if (msgs
[i
].len
!= 0 && (msgs
[i
].flags
& I2C_M_RD
)) {
1528 for (j
= 0; j
< msgs
[i
].len
- 1; j
++)
1529 printf("0x%02x ", msgs
[i
].buf
[j
]);
1530 /* Print final byte with newline */
1531 printf("0x%02x\n", msgs
[i
].buf
[j
]);
1535 # if ENABLE_FEATURE_CLEAN_UP
1537 for (i
= 0; i
< nmsgs
; i
++)
1543 #endif /* ENABLE_I2CTRANSFER */