16784e948fc192ce355a4b54f74fe687a9f5eddc
[oweals/busybox.git] / miscutils / i2c_tools.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Minimal i2c-tools implementation for busybox.
4  * Parts of code ported from i2c-tools:
5  *              http://www.lm-sensors.org/wiki/I2CTools.
6  *
7  * Copyright (C) 2014 by Bartosz Golaszewski <bartekgola@gmail.com>
8  *
9  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
10  */
11
12 //config:config I2CGET
13 //config:       bool "i2cget"
14 //config:       default y
15 //config:       select PLATFORM_LINUX
16 //config:       help
17 //config:         Read from I2C/SMBus chip registers.
18 //config:
19 //config:config I2CSET
20 //config:       bool "i2cset"
21 //config:       default y
22 //config:       select PLATFORM_LINUX
23 //config:       help
24 //config:         Set I2C registers.
25 //config:
26 //config:config I2CDUMP
27 //config:       bool "i2cdump"
28 //config:       default y
29 //config:       select PLATFORM_LINUX
30 //config:       help
31 //config:         Examine I2C registers.
32 //config:
33 //config:config I2CDETECT
34 //config:       bool "i2cdetect"
35 //config:       default y
36 //config:       select PLATFORM_LINUX
37 //config:       help
38 //config:         Detect I2C chips.
39 //config:
40
41 //applet:IF_I2CGET(APPLET(i2cget, BB_DIR_USR_SBIN, BB_SUID_DROP))
42 //applet:IF_I2CSET(APPLET(i2cset, BB_DIR_USR_SBIN, BB_SUID_DROP))
43 //applet:IF_I2CDUMP(APPLET(i2cdump, BB_DIR_USR_SBIN, BB_SUID_DROP))
44 //applet:IF_I2CDETECT(APPLET(i2cdetect, BB_DIR_USR_SBIN, BB_SUID_DROP))
45
46 //kbuild:lib-$(CONFIG_I2CGET) += i2c_tools.o
47 //kbuild:lib-$(CONFIG_I2CSET) += i2c_tools.o
48 //kbuild:lib-$(CONFIG_I2CDUMP) += i2c_tools.o
49 //kbuild:lib-$(CONFIG_I2CDETECT) += i2c_tools.o
50
51 /*
52  * Unsupported stuff:
53  *
54  * - upstream i2c-tools can also look-up i2c busses by name, we only accept
55  *   numbers,
56  * - bank and bankreg parameters for i2cdump are not supported because of
57  *   their limited usefulness (see i2cdump manual entry for more info),
58  * - i2cdetect doesn't look for bus info in /proc as it does in upstream, but
59  *   it shouldn't be a problem in modern kernels.
60  */
61
62 #include "libbb.h"
63
64 /*
65  * /dev/i2c-X ioctl commands. The ioctl's parameter is always an unsigned long,
66  * except for:
67  *    - I2C_FUNCS, takes pointer to an unsigned long
68  *    - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data
69  *    - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data
70  */
71
72 /*
73  * NOTE: Slave address is 7 or 10 bits, but 10-bit addresses
74  * are not supported due to code brokenness.
75  */
76
77 /* Use this slave address. */
78 #define I2C_SLAVE       0x0703
79 /* Use this slave address, even if it is already in use by a driver. */
80 #define I2C_SLAVE_FORCE 0x0706
81 /* 0 for 7 bit addrs, != 0 for 10 bit. */
82 #define I2C_TENBIT      0x0704
83 /* Get the adapter functionality mask. */
84 #define I2C_FUNCS       0x0705
85 /* Combined R/W transfer (one STOP only). */
86 #define I2C_RDWR        0x0707
87 /* != 0 to use PEC with SMBus. */
88 #define I2C_PEC         0x0708
89 /* SMBus transfer. */
90 #define I2C_SMBUS       0x0720
91
92 /* Structure used in the I2C_SMBUS ioctl call. */
93 struct i2c_smbus_ioctl_data {
94         uint8_t read_write;
95         uint8_t command;
96         uint32_t size;
97         union i2c_smbus_data *data;
98 };
99
100 /* Structure used in the I2C_RDWR ioctl call. */
101 struct i2c_rdwr_ioctl_data {
102         struct i2c_msg *msgs;   /* Pointers to i2c_msgs. */
103         uint32_t nmsgs;         /* Number of i2c_msgs. */
104 };
105
106 /* As specified in SMBus standard. */
107 #define I2C_SMBUS_BLOCK_MAX             32
108 /* Not specified but we use same structure. */
109 #define I2C_SMBUS_I2C_BLOCK_MAX         32
110
111 /* Data for SMBus Messages. */
112 union i2c_smbus_data {
113         uint8_t byte;
114         uint16_t word;
115         /* block[0] is used for length and one more for PEC */
116         uint8_t block[I2C_SMBUS_BLOCK_MAX + 2];
117 };
118
119 #define I2C_RDRW_IOCTL_MAX_MSGS         42
120 #define I2C_MAX_REGS                    256
121
122 /* Smbus_access read or write markers. */
123 #define I2C_SMBUS_READ                  1
124 #define I2C_SMBUS_WRITE                 0
125
126 /* SMBus transaction types (size parameter in the below functions). */
127 #define I2C_SMBUS_QUICK                 0
128 #define I2C_SMBUS_BYTE                  1
129 #define I2C_SMBUS_BYTE_DATA             2
130 #define I2C_SMBUS_WORD_DATA             3
131 #define I2C_SMBUS_PROC_CALL             4
132 #define I2C_SMBUS_BLOCK_DATA            5
133 #define I2C_SMBUS_I2C_BLOCK_BROKEN      6
134 #define I2C_SMBUS_BLOCK_PROC_CALL       7
135 #define I2C_SMBUS_I2C_BLOCK_DATA        8
136
137 #define DETECT_MODE_AUTO                0
138 #define DETECT_MODE_QUICK               1
139 #define DETECT_MODE_READ                2
140
141 /* Defines to determine what functionality is present. */
142 #define I2C_FUNC_I2C                            0x00000001
143 #define I2C_FUNC_10BIT_ADDR                     0x00000002
144 #define I2C_FUNC_PROTOCOL_MANGLING              0x00000004
145 #define I2C_FUNC_SMBUS_PEC                      0x00000008
146 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL          0x00008000
147 #define I2C_FUNC_SMBUS_QUICK                    0x00010000
148 #define I2C_FUNC_SMBUS_READ_BYTE                0x00020000
149 #define I2C_FUNC_SMBUS_WRITE_BYTE               0x00040000
150 #define I2C_FUNC_SMBUS_READ_BYTE_DATA           0x00080000
151 #define I2C_FUNC_SMBUS_WRITE_BYTE_DATA          0x00100000
152 #define I2C_FUNC_SMBUS_READ_WORD_DATA           0x00200000
153 #define I2C_FUNC_SMBUS_WRITE_WORD_DATA          0x00400000
154 #define I2C_FUNC_SMBUS_PROC_CALL                0x00800000
155 #define I2C_FUNC_SMBUS_READ_BLOCK_DATA          0x01000000
156 #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA         0x02000000
157 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK           0x04000000
158 #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK          0x08000000
159
160 #define I2C_FUNC_SMBUS_BYTE             (I2C_FUNC_SMBUS_READ_BYTE | \
161                                          I2C_FUNC_SMBUS_WRITE_BYTE)
162 #define I2C_FUNC_SMBUS_BYTE_DATA        (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
163                                          I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
164 #define I2C_FUNC_SMBUS_WORD_DATA        (I2C_FUNC_SMBUS_READ_WORD_DATA | \
165                                          I2C_FUNC_SMBUS_WRITE_WORD_DATA)
166 #define I2C_FUNC_SMBUS_BLOCK_DATA       (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
167                                          I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
168 #define I2C_FUNC_SMBUS_I2C_BLOCK        (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
169                                          I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
170
171 /*
172  * This is needed for ioctl_or_perror_and_die() since it only accepts pointers.
173  */
174 static ALWAYS_INLINE void *itoptr(int i)
175 {
176         return (void*)(intptr_t)i;
177 }
178
179 static int32_t i2c_smbus_access(int fd, char read_write, uint8_t cmd,
180                                 int size, union i2c_smbus_data *data)
181 {
182         struct i2c_smbus_ioctl_data args;
183
184         args.read_write = read_write;
185         args.command = cmd;
186         args.size = size;
187         args.data = data;
188
189         return ioctl(fd, I2C_SMBUS, &args);
190 }
191
192 static int32_t i2c_smbus_read_byte(int fd)
193 {
194         union i2c_smbus_data data;
195         int err;
196
197         err = i2c_smbus_access(fd, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data);
198         if (err < 0)
199                 return err;
200
201         return data.byte;
202 }
203
204 #if ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP
205 static int32_t i2c_smbus_write_byte(int fd, uint8_t val)
206 {
207         return i2c_smbus_access(fd, I2C_SMBUS_WRITE,
208                                 val, I2C_SMBUS_BYTE, NULL);
209 }
210
211 static int32_t i2c_smbus_read_byte_data(int fd, uint8_t cmd)
212 {
213         union i2c_smbus_data data;
214         int err;
215
216         err = i2c_smbus_access(fd, I2C_SMBUS_READ, cmd,
217                                I2C_SMBUS_BYTE_DATA, &data);
218         if (err < 0)
219                 return err;
220
221         return data.byte;
222 }
223
224 static int32_t i2c_smbus_read_word_data(int fd, uint8_t cmd)
225 {
226         union i2c_smbus_data data;
227         int err;
228
229         err = i2c_smbus_access(fd, I2C_SMBUS_READ, cmd,
230                                I2C_SMBUS_WORD_DATA, &data);
231         if (err < 0)
232                 return err;
233
234         return data.word;
235 }
236 #endif /* ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP */
237
238 #if ENABLE_I2CSET
239 static int32_t i2c_smbus_write_byte_data(int file,
240                                          uint8_t cmd, uint8_t value)
241 {
242         union i2c_smbus_data data;
243
244         data.byte = value;
245
246         return i2c_smbus_access(file, I2C_SMBUS_WRITE, cmd,
247                                 I2C_SMBUS_BYTE_DATA, &data);
248 }
249
250 static int32_t i2c_smbus_write_word_data(int file, uint8_t cmd, uint16_t value)
251 {
252         union i2c_smbus_data data;
253
254         data.word = value;
255
256         return i2c_smbus_access(file, I2C_SMBUS_WRITE, cmd,
257                                 I2C_SMBUS_WORD_DATA, &data);
258 }
259
260 static int32_t i2c_smbus_write_block_data(int file, uint8_t cmd,
261                                    uint8_t length, const uint8_t *values)
262 {
263         union i2c_smbus_data data;
264
265         if (length > I2C_SMBUS_BLOCK_MAX)
266                 length = I2C_SMBUS_BLOCK_MAX;
267
268         memcpy(data.block+1, values, length);
269         data.block[0] = length;
270
271         return i2c_smbus_access(file, I2C_SMBUS_WRITE, cmd,
272                                 I2C_SMBUS_BLOCK_DATA, &data);
273 }
274
275 static int32_t i2c_smbus_write_i2c_block_data(int file, uint8_t cmd,
276                                        uint8_t length, const uint8_t *values)
277 {
278         union i2c_smbus_data data;
279
280         if (length > I2C_SMBUS_BLOCK_MAX)
281                 length = I2C_SMBUS_BLOCK_MAX;
282
283         memcpy(data.block+1, values, length);
284         data.block[0] = length;
285
286         return i2c_smbus_access(file, I2C_SMBUS_WRITE, cmd,
287                                 I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
288 }
289 #endif /* ENABLE_I2CSET */
290
291 #if ENABLE_I2CDUMP
292 /*
293  * Returns the number of bytes read, vals must hold at
294  * least I2C_SMBUS_BLOCK_MAX bytes.
295  */
296 static int32_t i2c_smbus_read_block_data(int fd, uint8_t cmd, uint8_t *vals)
297 {
298         union i2c_smbus_data data;
299         int i, err;
300
301         err = i2c_smbus_access(fd, I2C_SMBUS_READ, cmd,
302                                I2C_SMBUS_BLOCK_DATA, &data);
303         if (err < 0)
304                 return err;
305
306         for (i = 1; i <= data.block[0]; i++)
307                 *vals++ = data.block[i];
308         return data.block[0];
309 }
310
311 static int32_t i2c_smbus_read_i2c_block_data(int fd, uint8_t cmd,
312                                              uint8_t len, uint8_t *vals)
313 {
314         union i2c_smbus_data data;
315         int i, err;
316
317         if (len > I2C_SMBUS_BLOCK_MAX)
318                 len = I2C_SMBUS_BLOCK_MAX;
319         data.block[0] = len;
320
321         err = i2c_smbus_access(fd, I2C_SMBUS_READ, cmd,
322                                len == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
323                                            I2C_SMBUS_I2C_BLOCK_DATA, &data);
324         if (err < 0)
325                 return err;
326
327         for (i = 1; i <= data.block[0]; i++)
328                 *vals++ = data.block[i];
329         return data.block[0];
330 }
331 #endif /* ENABLE_I2CDUMP */
332
333 #if ENABLE_I2CDETECT
334 static int32_t i2c_smbus_write_quick(int fd, uint8_t val)
335 {
336         return i2c_smbus_access(fd, val, 0, I2C_SMBUS_QUICK, NULL);
337 }
338 #endif /* ENABLE_I2CDETECT */
339
340 static int i2c_bus_lookup(const char *bus_str)
341 {
342         return xstrtou_range(bus_str, 10, 0, 0xfffff);
343 }
344
345 #if ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP
346 static int i2c_parse_bus_addr(const char *addr_str)
347 {
348         /* Slave address must be in range 0x03 - 0x77. */
349         return xstrtou_range(addr_str, 16, 0x03, 0x77);
350 }
351
352 static void i2c_set_pec(int fd, int pec)
353 {
354         ioctl_or_perror_and_die(fd, I2C_PEC,
355                                 itoptr(pec ? 1 : 0),
356                                 "can't set PEC");
357 }
358
359 static void i2c_set_slave_addr(int fd, int addr, int force)
360 {
361         ioctl_or_perror_and_die(fd, force ? I2C_SLAVE_FORCE : I2C_SLAVE,
362                                 itoptr(addr),
363                                 "can't set address to 0x%02x", addr);
364 }
365 #endif /* ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP */
366
367 #if ENABLE_I2CGET || ENABLE_I2CSET
368 static int i2c_parse_data_addr(const char *data_addr)
369 {
370         /* Data address must be an 8 bit integer. */
371         return xstrtou_range(data_addr, 16, 0, 0xff);
372 }
373 #endif /* ENABLE_I2CGET || ENABLE_I2CSET */
374
375 /*
376  * Opens the device file associated with given i2c bus.
377  *
378  * Upstream i2c-tools also support opening devices by i2c bus name
379  * but we drop it here for size reduction.
380  */
381 static int i2c_dev_open(int i2cbus)
382 {
383         char filename[sizeof("/dev/i2c-%d") + sizeof(int)*3];
384         int fd;
385
386         sprintf(filename, "/dev/i2c-%d", i2cbus);
387         fd = open(filename, O_RDWR);
388         if (fd < 0) {
389                 if (errno == ENOENT) {
390                         filename[8] = '/'; /* change to "/dev/i2c/%d" */
391                         fd = xopen(filename, O_RDWR);
392                 } else {
393                         bb_perror_msg_and_die("can't open '%s'", filename);
394                 }
395         }
396
397         return fd;
398 }
399
400 /* Size reducing helpers for xxx_check_funcs(). */
401 static void get_funcs_matrix(int fd, unsigned long *funcs)
402 {
403         ioctl_or_perror_and_die(fd, I2C_FUNCS, funcs,
404                         "can't get adapter functionality matrix");
405 }
406
407 #if ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP
408 static void check_funcs_test_end(int funcs, int pec, const char *err)
409 {
410         if (pec && !(funcs & (I2C_FUNC_SMBUS_PEC | I2C_FUNC_I2C)))
411                 bb_error_msg("warning: adapter does not support PEC");
412
413         if (err)
414                 bb_error_msg_and_die(
415                         "adapter has no %s capability", err);
416 }
417 #endif /* ENABLE_I2CGET || ENABLE_I2CSET || ENABLE_I2CDUMP */
418
419 /*
420  * The below functions emit an error message and exit if the adapter doesn't
421  * support desired functionalities.
422  */
423 #if ENABLE_I2CGET || ENABLE_I2CDUMP
424 static void check_read_funcs(int fd, int mode, int data_addr, int pec)
425 {
426         unsigned long funcs;
427         const char *err = NULL;
428
429         get_funcs_matrix(fd, &funcs);
430         switch (mode) {
431         case I2C_SMBUS_BYTE:
432                 if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE)) {
433                         err = "SMBus receive byte";
434                         break;
435                 }
436                 if (data_addr >= 0 && !(funcs & I2C_FUNC_SMBUS_WRITE_BYTE))
437                         err = "SMBus send byte";
438                 break;
439         case I2C_SMBUS_BYTE_DATA:
440                 if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA))
441                         err = "SMBus read byte";
442                 break;
443         case I2C_SMBUS_WORD_DATA:
444                 if (!(funcs & I2C_FUNC_SMBUS_READ_WORD_DATA))
445                         err = "SMBus read word";
446                 break;
447 #if ENABLE_I2CDUMP
448         case I2C_SMBUS_BLOCK_DATA:
449                 if (!(funcs & I2C_FUNC_SMBUS_READ_BLOCK_DATA))
450                         err = "SMBus block read";
451                 break;
452
453         case I2C_SMBUS_I2C_BLOCK_DATA:
454                 if (!(funcs & I2C_FUNC_SMBUS_READ_I2C_BLOCK))
455                         err = "I2C block read";
456                 break;
457 #endif /* ENABLE_I2CDUMP */
458         default:
459                 bb_error_msg_and_die("Programmer goofed!");
460         }
461         check_funcs_test_end(funcs, pec, err);
462 }
463 #endif /* ENABLE_I2CGET || ENABLE_I2CDUMP */
464
465 #if ENABLE_I2CSET
466 static void check_write_funcs(int fd, int mode, int pec)
467 {
468         unsigned long funcs;
469         const char *err = NULL;
470
471         get_funcs_matrix(fd, &funcs);
472         switch (mode) {
473         case I2C_SMBUS_BYTE:
474                 if (!(funcs & I2C_FUNC_SMBUS_WRITE_BYTE))
475                         err = "SMBus send byte";
476                 break;
477
478         case I2C_SMBUS_BYTE_DATA:
479                 if (!(funcs & I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
480                         err = "SMBus write byte";
481                 break;
482
483         case I2C_SMBUS_WORD_DATA:
484                 if (!(funcs & I2C_FUNC_SMBUS_WRITE_WORD_DATA))
485                         err = "SMBus write word";
486                 break;
487
488         case I2C_SMBUS_BLOCK_DATA:
489                 if (!(funcs & I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))
490                         err = "SMBus block write";
491                 break;
492         case I2C_SMBUS_I2C_BLOCK_DATA:
493                 if (!(funcs & I2C_FUNC_SMBUS_WRITE_I2C_BLOCK))
494                         err = "I2C block write";
495                 break;
496         }
497         check_funcs_test_end(funcs, pec, err);
498 }
499 #endif /* ENABLE_I2CSET */
500
501 static void confirm_or_abort(void)
502 {
503         fprintf(stderr, "Continue? [y/N] ");
504         fflush_all();
505         if (!bb_ask_confirmation())
506                 bb_error_msg_and_die("aborting");
507 }
508
509 /*
510  * Return only if user confirms the action, abort otherwise.
511  *
512  * The messages displayed here are much less elaborate than their i2c-tools
513  * counterparts - this is done for size reduction.
514  */
515 static void confirm_action(int bus_addr, int mode, int data_addr, int pec)
516 {
517         bb_error_msg("WARNING! This program can confuse your I2C bus");
518
519         /* Don't let the user break his/her EEPROMs */
520         if (bus_addr >= 0x50 && bus_addr <= 0x57 && pec) {
521                 bb_error_msg_and_die("this is I2C not smbus - using PEC on I2C "
522                         "devices may result in data loss, aborting");
523         }
524
525         if (mode == I2C_SMBUS_BYTE && data_addr >= 0 && pec)
526                 bb_error_msg("WARNING! May interpret a write byte command "
527                         "with PEC as a write byte data command");
528
529         if (pec)
530                 bb_error_msg("PEC checking enabled");
531
532         confirm_or_abort();
533 }
534
535 #if ENABLE_I2CGET
536 //usage:#define i2cget_trivial_usage
537 //usage:       "[-f] [-y] BUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]"
538 //usage:#define i2cget_full_usage "\n\n"
539 //usage:       "Read from I2C/SMBus chip registers\n"
540 //usage:     "\n        I2CBUS  i2c bus number"
541 //usage:     "\n        ADDRESS 0x03 - 0x77"
542 //usage:     "\nMODE is:"
543 //usage:     "\n        b       read byte data (default)"
544 //usage:     "\n        w       read word data"
545 //usage:     "\n        c       write byte/read byte"
546 //usage:     "\n        Append p for SMBus PEC"
547 //usage:     "\n"
548 //usage:     "\n        -f      force access"
549 //usage:     "\n        -y      disable interactive mode"
550 int i2cget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
551 int i2cget_main(int argc UNUSED_PARAM, char **argv)
552 {
553         const unsigned opt_f = (1 << 0), opt_y = (1 << 1);
554         const char *const optstr = "fy";
555
556         int bus_num, bus_addr, data_addr = -1, status;
557         int mode = I2C_SMBUS_BYTE, pec = 0, fd;
558         unsigned opts;
559
560         opt_complementary = "-2:?4"; /* from 2 to 4 args */
561         opts = getopt32(argv, optstr);
562         argv += optind;
563
564         bus_num = i2c_bus_lookup(argv[0]);
565         bus_addr = i2c_parse_bus_addr(argv[1]);
566
567         if (argv[2]) {
568                 data_addr = i2c_parse_data_addr(argv[2]);
569                 mode = I2C_SMBUS_BYTE_DATA;
570                 if (argv[3]) {
571                         switch (argv[3][0]) {
572                         case 'b':       /* Already set */               break;
573                         case 'w':       mode = I2C_SMBUS_WORD_DATA;     break;
574                         case 'c':       mode = I2C_SMBUS_BYTE;          break;
575                         default:
576                                 bb_error_msg("invalid mode");
577                                 bb_show_usage();
578                         }
579                         pec = argv[3][1] == 'p';
580                 }
581         }
582
583         fd = i2c_dev_open(bus_num);
584         check_read_funcs(fd, mode, data_addr, pec);
585         i2c_set_slave_addr(fd, bus_addr, opts & opt_f);
586
587         if (!(opts & opt_y))
588                 confirm_action(bus_addr, mode, data_addr, pec);
589
590         if (pec)
591                 i2c_set_pec(fd, 1);
592
593         switch (mode) {
594         case I2C_SMBUS_BYTE:
595                 if (data_addr >= 0) {
596                         status = i2c_smbus_write_byte(fd, data_addr);
597                         if (status < 0)
598                                 bb_error_msg("warning - write failed");
599                 }
600                 status = i2c_smbus_read_byte(fd);
601                 break;
602         case I2C_SMBUS_WORD_DATA:
603                 status = i2c_smbus_read_word_data(fd, data_addr);
604                 break;
605         default: /* I2C_SMBUS_BYTE_DATA */
606                 status = i2c_smbus_read_byte_data(fd, data_addr);
607         }
608         close(fd);
609
610         if (status < 0)
611                 bb_perror_msg_and_die("read failed");
612
613         printf("0x%0*x\n", mode == I2C_SMBUS_WORD_DATA ? 4 : 2, status);
614
615         return 0;
616 }
617 #endif /* ENABLE_I2CGET */
618
619 #if ENABLE_I2CSET
620 //usage:#define i2cset_trivial_usage
621 //usage:       "[-f] [-y] [-m MASK] BUS CHIP-ADDR DATA-ADDR [VALUE] ... [MODE]"
622 //usage:#define i2cset_full_usage "\n\n"
623 //usage:       "Set I2C registers\n"
624 //usage:     "\n        I2CBUS  i2c bus number"
625 //usage:     "\n        ADDRESS 0x03 - 0x77"
626 //usage:     "\nMODE is:"
627 //usage:     "\n        c       byte, no value"
628 //usage:     "\n        b       byte data (default)"
629 //usage:     "\n        w       word data"
630 //usage:     "\n        i       I2C block data"
631 //usage:     "\n        s       SMBus block data"
632 //usage:     "\n        Append p for SMBus PEC"
633 //usage:     "\n"
634 //usage:     "\n        -f      force access"
635 //usage:     "\n        -y      disable interactive mode"
636 //usage:     "\n        -r      read back and compare the result"
637 //usage:     "\n        -m MASK mask specifying which bits to write"
638 int i2cset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
639 int i2cset_main(int argc, char **argv)
640 {
641         const unsigned opt_f = (1 << 0), opt_y = (1 << 1),
642                               opt_m = (1 << 2), opt_r = (1 << 3);
643         const char *const optstr = "fym:r";
644
645         int bus_num, bus_addr, data_addr, mode = I2C_SMBUS_BYTE, pec = 0;
646         int val, blen = 0, mask = 0, fd, status;
647         unsigned char block[I2C_SMBUS_BLOCK_MAX];
648         char *opt_m_arg = NULL;
649         unsigned opts;
650
651         opt_complementary = "-3"; /* from 3 to ? args */
652         opts = getopt32(argv, optstr, &opt_m_arg);
653         argv += optind;
654         argc -= optind;
655
656         bus_num = i2c_bus_lookup(argv[0]);
657         bus_addr = i2c_parse_bus_addr(argv[1]);
658         data_addr = i2c_parse_data_addr(argv[2]);
659
660         if (argv[3]) {
661                 if (!argv[4] && argv[3][0] != 'c') {
662                         mode = I2C_SMBUS_BYTE_DATA; /* Implicit b */
663                 } else {
664                         switch (argv[argc-1][0]) {
665                         case 'c': /* Already set */                     break;
666                         case 'b': mode = I2C_SMBUS_BYTE_DATA;           break;
667                         case 'w': mode = I2C_SMBUS_WORD_DATA;           break;
668                         case 's': mode = I2C_SMBUS_BLOCK_DATA;          break;
669                         case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA;      break;
670                         default:
671                                 bb_error_msg("invalid mode");
672                                 bb_show_usage();
673                         }
674
675                         pec = argv[argc-1][1] == 'p';
676                         if (mode == I2C_SMBUS_BLOCK_DATA ||
677                                         mode == I2C_SMBUS_I2C_BLOCK_DATA) {
678                                 if (pec && mode == I2C_SMBUS_I2C_BLOCK_DATA)
679                                         bb_error_msg_and_die(
680                                                 "PEC not supported for I2C "
681                                                 "block writes");
682                                 if (opts & opt_m)
683                                         bb_error_msg_and_die(
684                                                 "mask not supported for block "
685                                                 "writes");
686                         }
687                 }
688         }
689
690         /* Prepare the value(s) to be written according to current mode. */
691         switch (mode) {
692         case I2C_SMBUS_BYTE_DATA:
693                 val = xstrtou_range(argv[3], 0, 0, 0xff);
694                 break;
695         case I2C_SMBUS_WORD_DATA:
696                 val = xstrtou_range(argv[3], 0, 0, 0xffff);
697                 break;
698         case I2C_SMBUS_BLOCK_DATA:
699         case I2C_SMBUS_I2C_BLOCK_DATA:
700                 for (blen = 3; blen < (argc - 1); blen++)
701                         block[blen] = xstrtou_range(argv[blen], 0, 0, 0xff);
702                 val = -1;
703                 break;
704         default:
705                 val = -1;
706                 break;
707         }
708
709         if (opts & opt_m) {
710                 mask = xstrtou_range(opt_m_arg, 0, 0,
711                                 (mode == I2C_SMBUS_BYTE ||
712                                  mode == I2C_SMBUS_BYTE_DATA) ? 0xff : 0xffff);
713         }
714
715         fd = i2c_dev_open(bus_num);
716         check_write_funcs(fd, mode, pec);
717         i2c_set_slave_addr(fd, bus_addr, opts & opt_f);
718
719         if (!(opts & opt_y))
720                 confirm_action(bus_addr, mode, data_addr, pec);
721
722         /*
723          * If we're using mask - read the current value here and adjust the
724          * value to be written.
725          */
726         if (opts & opt_m) {
727                 int tmpval;
728
729                 switch (mode) {
730                 case I2C_SMBUS_BYTE:
731                         tmpval = i2c_smbus_read_byte(fd);
732                         break;
733                 case I2C_SMBUS_WORD_DATA:
734                         tmpval = i2c_smbus_read_word_data(fd, data_addr);
735                         break;
736                 default:
737                         tmpval = i2c_smbus_read_byte_data(fd, data_addr);
738                 }
739
740                 if (tmpval < 0)
741                         bb_perror_msg_and_die("can't read old value");
742
743                 val = (val & mask) | (tmpval & ~mask);
744
745                 if (!(opts & opt_y)) {
746                         bb_error_msg("old value 0x%0*x, write mask "
747                                 "0x%0*x, will write 0x%0*x to register "
748                                 "0x%02x",
749                                 mode == I2C_SMBUS_WORD_DATA ? 4 : 2, tmpval,
750                                 mode == I2C_SMBUS_WORD_DATA ? 4 : 2, mask,
751                                 mode == I2C_SMBUS_WORD_DATA ? 4 : 2, val,
752                                 data_addr);
753                         confirm_or_abort();
754                 }
755         }
756
757         if (pec)
758                 i2c_set_pec(fd, 1);
759
760         switch (mode) {
761         case I2C_SMBUS_BYTE:
762                 status = i2c_smbus_write_byte(fd, data_addr);
763                 break;
764         case I2C_SMBUS_WORD_DATA:
765                 status = i2c_smbus_write_word_data(fd, data_addr, val);
766                 break;
767         case I2C_SMBUS_BLOCK_DATA:
768                 status = i2c_smbus_write_block_data(fd, data_addr,
769                                                     blen, block);
770                 break;
771         case I2C_SMBUS_I2C_BLOCK_DATA:
772                 status = i2c_smbus_write_i2c_block_data(fd, data_addr,
773                                                         blen, block);
774                 break;
775         default: /* I2C_SMBUS_BYTE_DATA */
776                 status = i2c_smbus_write_byte_data(fd, data_addr, val);
777                 break;
778         }
779         if (status < 0)
780                 bb_perror_msg_and_die("write failed");
781
782         if (pec)
783                 i2c_set_pec(fd, 0); /* Clear PEC. */
784
785         /* No readback required - we're done. */
786         if (!(opts & opt_r))
787                 return 0;
788
789         switch (mode) {
790         case I2C_SMBUS_BYTE:
791                 status = i2c_smbus_read_byte(fd);
792                 val = data_addr;
793                 break;
794         case I2C_SMBUS_WORD_DATA:
795                 status = i2c_smbus_read_word_data(fd, data_addr);
796                 break;
797         default: /* I2C_SMBUS_BYTE_DATA */
798                 status = i2c_smbus_read_byte_data(fd, data_addr);
799         }
800
801         if (status < 0) {
802                 printf("Warning - readback failed\n");
803         } else
804         if (status != val) {
805                 printf("Warning - data mismatch - wrote "
806                        "0x%0*x, read back 0x%0*x\n",
807                        mode == I2C_SMBUS_WORD_DATA ? 4 : 2, val,
808                        mode == I2C_SMBUS_WORD_DATA ? 4 : 2, status);
809         } else {
810                 printf("Value 0x%0*x written, readback matched\n",
811                        mode == I2C_SMBUS_WORD_DATA ? 4 : 2, val);
812         }
813
814         return 0;
815 }
816 #endif /* ENABLE_I2CSET */
817
818 #if ENABLE_I2CDUMP
819 //usage:#define i2cdump_trivial_usage
820 //usage:       "[-f] [-r FIRST-LAST] [-y] BUS ADDR [MODE]"
821 //usage:#define i2cdump_full_usage "\n\n"
822 //usage:       "Examine I2C registers\n"
823 //usage:     "\n        I2CBUS  i2c bus number"
824 //usage:     "\n        ADDRESS 0x03 - 0x77"
825 //usage:     "\nMODE is:"
826 //usage:     "\n        b       byte (default)"
827 //usage:     "\n        w       word"
828 //usage:     "\n        W       word on even register addresses"
829 //usage:     "\n        i       I2C block"
830 //usage:     "\n        s       SMBus block"
831 //usage:     "\n        c       consecutive byte"
832 //usage:     "\n        Append p for SMBus PEC"
833 //usage:     "\n"
834 //usage:     "\n        -f      force access"
835 //usage:     "\n        -y      disable interactive mode"
836 //usage:     "\n        -r      limit the number of registers being accessed"
837 int i2cdump_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
838 int i2cdump_main(int argc UNUSED_PARAM, char **argv)
839 {
840         const unsigned opt_f = (1 << 0), opt_y = (1 << 1),
841                               opt_r = (1 << 2);
842         const char *const optstr = "fyr:";
843
844         int bus_num, bus_addr, mode = I2C_SMBUS_BYTE_DATA, even = 0, pec = 0;
845         unsigned first = 0x00, last = 0xff;
846         int fd, i, j, res, blen = 0, tmp;
847         unsigned char cblock[I2C_SMBUS_BLOCK_MAX + I2C_MAX_REGS];
848         unsigned char block[I2C_SMBUS_BLOCK_MAX];
849         char *opt_r_str, *dash;
850         unsigned opts;
851
852         opt_complementary = "-2:?3"; /* from 2 to 3 args */
853         opts = getopt32(argv, optstr, &opt_r_str);
854         argv += optind;
855
856         bus_num = i2c_bus_lookup(argv[0]);
857         bus_addr = i2c_parse_bus_addr(argv[1]);
858
859         if (argv[2]) {
860                 switch (argv[2][0]) {
861                 case 'b': /* Already set */                     break;
862                 case 'c': mode = I2C_SMBUS_BYTE;                break;
863                 case 'w': mode = I2C_SMBUS_WORD_DATA;           break;
864                 case 'W':
865                         mode = I2C_SMBUS_WORD_DATA;
866                         even = 1;
867                         break;
868                 case 's': mode = I2C_SMBUS_BLOCK_DATA;          break;
869                 case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA;      break;
870                 default:
871                         bb_error_msg_and_die("invalid mode");
872                 }
873
874                 if (argv[2][1] == 'p') {
875                         if (argv[2][0] == 'W' || argv[2][0] == 'i') {
876                                 bb_error_msg_and_die(
877                                         "pec not supported for -W and -i");
878                         } else {
879                                 pec = 1;
880                         }
881                 }
882         }
883
884         if (opts & opt_r) {
885                 first = strtol(opt_r_str, &dash, 0);
886                 if (dash == opt_r_str || *dash != '-' || first > 0xff)
887                         bb_error_msg_and_die("invalid range");
888                 last = xstrtou_range(++dash, 0, first, 0xff);
889
890                 /* Range is not available for every mode */
891                 switch (mode) {
892                 case I2C_SMBUS_BYTE:
893                 case I2C_SMBUS_BYTE_DATA:
894                         break;
895                 case I2C_SMBUS_WORD_DATA:
896                         if (!even || (!(first % 2) && last % 2))
897                                 break;
898                         /* Fall through */
899                 default:
900                         bb_error_msg_and_die(
901                                 "range not compatible with selected mode");
902                 }
903         }
904
905         fd = i2c_dev_open(bus_num);
906         check_read_funcs(fd, mode, -1 /* data_addr */, pec);
907         i2c_set_slave_addr(fd, bus_addr, opts & opt_f);
908
909         if (pec)
910                 i2c_set_pec(fd, 1);
911
912         if (!(opts & opt_y))
913                 confirm_action(bus_addr, mode, -1 /* data_addr */, pec);
914
915         /* All but word data */
916         if (mode != I2C_SMBUS_WORD_DATA || even) {
917                 /*
918                  * FIXME This section has been ported from upstream i2cdump.
919                  * It has been reworked a bit but is still pretty spaghetti
920                  * and needs splitting into several functions.
921                  */
922                 if (mode == I2C_SMBUS_BLOCK_DATA ||
923                     mode == I2C_SMBUS_I2C_BLOCK_DATA) {
924                         res = i2c_smbus_read_block_data(fd, 0, cblock);
925                         blen = res;
926                 } else {
927                         for (res = 0; res < I2C_MAX_REGS; res += tmp) {
928                                 tmp = i2c_smbus_read_i2c_block_data(
929                                         fd, res, I2C_SMBUS_BLOCK_MAX,
930                                         cblock + res);
931                                 if (tmp < 0) {
932                                         bb_error_msg_and_die(
933                                                 "block read failed");
934                                 }
935                         }
936                         if (res >= I2C_MAX_REGS)
937                                 res = I2C_MAX_REGS;
938                         for (i = 0; i < res; i++)
939                                 block[i] = cblock[i];
940                         if (mode != I2C_SMBUS_BLOCK_DATA)
941                                 for (i = res; i < I2C_MAX_REGS; i++)
942                                         cblock[i] = -1;
943                 }
944
945                 if (mode == I2C_SMBUS_BYTE) {
946                         res = i2c_smbus_write_byte(fd, first);
947                         if (res < 0)
948                                 bb_perror_msg_and_die(
949                                         "write start address failed");
950                 }
951
952                 printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f"
953                        "    0123456789abcdef\n");
954
955                 for (i = 0; i < I2C_MAX_REGS; i += 0x10) {
956                         if (mode == I2C_SMBUS_BLOCK_DATA && i >= blen)
957                                 break;
958                         if (i/16 < first/16)
959                                 continue;
960                         if (i/16 > last/16)
961                                 break;
962
963                         printf("%02x: ", i);
964                         for (j = 0; j < 16; j++) {
965                                 fflush_all();
966                                 /* Skip unwanted registers */
967                                 if (i+j < first || i+j > last) {
968                                         printf("   ");
969                                         if (mode == I2C_SMBUS_WORD_DATA) {
970                                                 printf("   ");
971                                                 j++;
972                                         }
973                                         continue;
974                                 }
975
976                                 switch (mode) {
977                                 case I2C_SMBUS_BYTE_DATA:
978                                         res = i2c_smbus_read_byte_data(fd, i+j);
979                                         block[i+j] = res;
980                                         break;
981                                 case I2C_SMBUS_WORD_DATA:
982                                         res = i2c_smbus_read_word_data(fd, i+j);
983                                         if (res < 0) {
984                                                 block[i+j] = res;
985                                                 block[i+j+1] = res;
986                                         } else {
987                                                 block[i+j] = res & 0xff;
988                                                 block[i+j+1] = res >> 8;
989                                         }
990                                         break;
991                                 case I2C_SMBUS_BYTE:
992                                         res = i2c_smbus_read_byte(fd);
993                                         block[i+j] = res;
994                                         break;
995                                 default:
996                                         res = block[i+j];
997                                 }
998
999                                 if (mode == I2C_SMBUS_BLOCK_DATA &&
1000                                     i+j >= blen) {
1001                                         printf("   ");
1002                                 } else if (res < 0) {
1003                                         printf("XX ");
1004                                         if (mode == I2C_SMBUS_WORD_DATA)
1005                                                 printf("XX ");
1006                                 } else {
1007                                         printf("%02x ", block[i+j]);
1008                                         if (mode == I2C_SMBUS_WORD_DATA)
1009                                                 printf("%02x ", block[i+j+1]);
1010                                 }
1011
1012                                 if (mode == I2C_SMBUS_WORD_DATA)
1013                                         j++;
1014                         }
1015                         printf("   ");
1016
1017                         for (j = 0; j < 16; j++) {
1018                                 if (mode == I2C_SMBUS_BLOCK_DATA && i+j >= blen)
1019                                         break;
1020                                 /* Skip unwanted registers */
1021                                 if (i+j < first || i+j > last) {
1022                                         printf(" ");
1023                                         continue;
1024                                 }
1025
1026                                 res = block[i+j];
1027                                 if (res < 0) {
1028 //FIXME: impossible, block[] is uchar[]
1029                                         printf("X");
1030                                 } else if (res == 0x00 || res == 0xff) {
1031                                         printf(".");
1032                                 } else if (res < 32 || res >= 127) {
1033                                         printf("?");
1034                                 } else {
1035                                         printf("%c", res);
1036                                 }
1037                         }
1038                         printf("\n");
1039                 }
1040         } else {
1041                 /* Word data. */
1042                 printf("     0,8  1,9  2,a  3,b  4,c  5,d  6,e  7,f\n");
1043                 for (i = 0; i < 256; i += 8) {
1044                         if (i/8 < first/8)
1045                                 continue;
1046                         if (i/8 > last/8)
1047                                 break;
1048
1049                         printf("%02x: ", i);
1050                         for (j = 0; j < 8; j++) {
1051                                 /* Skip unwanted registers. */
1052                                 if (i+j < first || i+j > last) {
1053                                         printf("     ");
1054                                         continue;
1055                                 }
1056
1057                                 res = i2c_smbus_read_word_data(fd, i+j);
1058                                 if (res < 0)
1059                                         printf("XXXX ");
1060                                 else
1061                                         printf("%04x ", res & 0xffff);
1062                         }
1063                         printf("\n");
1064                 }
1065         }
1066
1067         return 0;
1068 }
1069 #endif /* ENABLE_I2CDUMP */
1070
1071 #if ENABLE_I2CDETECT
1072 enum adapter_type {
1073         ADT_DUMMY = 0,
1074         ADT_ISA,
1075         ADT_I2C,
1076         ADT_SMBUS,
1077 };
1078
1079 struct adap_desc {
1080         const char *funcs;
1081         const char *algo;
1082 };
1083
1084 static const struct adap_desc adap_descs[] = {
1085         { .funcs        = "dummy",
1086           .algo         = "Dummy bus", },
1087         { .funcs        = "isa",
1088           .algo         = "ISA bus", },
1089         { .funcs        = "i2c",
1090           .algo         = "I2C adapter", },
1091         { .funcs        = "smbus",
1092           .algo         = "SMBus adapter", },
1093 };
1094
1095 struct i2c_func
1096 {
1097         long value;
1098         const char* name;
1099 };
1100
1101 static const struct i2c_func i2c_funcs_tab[] = {
1102         { .value = I2C_FUNC_I2C,
1103           .name = "I2C" },
1104         { .value = I2C_FUNC_SMBUS_QUICK,
1105           .name = "SMBus Quick Command" },
1106         { .value = I2C_FUNC_SMBUS_WRITE_BYTE,
1107           .name = "SMBus Send Byte" },
1108         { .value = I2C_FUNC_SMBUS_READ_BYTE,
1109           .name = "SMBus Receive Byte" },
1110         { .value = I2C_FUNC_SMBUS_WRITE_BYTE_DATA,
1111           .name = "SMBus Write Byte" },
1112         { .value = I2C_FUNC_SMBUS_READ_BYTE_DATA,
1113           .name = "SMBus Read Byte" },
1114         { .value = I2C_FUNC_SMBUS_WRITE_WORD_DATA,
1115           .name = "SMBus Write Word" },
1116         { .value = I2C_FUNC_SMBUS_READ_WORD_DATA,
1117           .name = "SMBus Read Word" },
1118         { .value = I2C_FUNC_SMBUS_PROC_CALL,
1119           .name = "SMBus Process Call" },
1120         { .value = I2C_FUNC_SMBUS_WRITE_BLOCK_DATA,
1121           .name = "SMBus Block Write" },
1122         { .value = I2C_FUNC_SMBUS_READ_BLOCK_DATA,
1123           .name = "SMBus Block Read" },
1124         { .value = I2C_FUNC_SMBUS_BLOCK_PROC_CALL,
1125           .name = "SMBus Block Process Call" },
1126         { .value = I2C_FUNC_SMBUS_PEC,
1127           .name = "SMBus PEC" },
1128         { .value = I2C_FUNC_SMBUS_WRITE_I2C_BLOCK,
1129           .name = "I2C Block Write" },
1130         { .value = I2C_FUNC_SMBUS_READ_I2C_BLOCK,
1131           .name = "I2C Block Read" },
1132         { .value = 0, .name = NULL }
1133 };
1134
1135 static enum adapter_type i2cdetect_get_funcs(int bus)
1136 {
1137         enum adapter_type ret;
1138         unsigned long funcs;
1139         int fd;
1140
1141         fd = i2c_dev_open(bus);
1142
1143         get_funcs_matrix(fd, &funcs);
1144         if (funcs & I2C_FUNC_I2C)
1145                 ret = ADT_I2C;
1146         else if (funcs & (I2C_FUNC_SMBUS_BYTE |
1147                           I2C_FUNC_SMBUS_BYTE_DATA |
1148                           I2C_FUNC_SMBUS_WORD_DATA))
1149                 ret = ADT_SMBUS;
1150         else
1151                 ret = ADT_DUMMY;
1152
1153         close(fd);
1154
1155         return ret;
1156 }
1157
1158 static void NORETURN list_i2c_busses_and_exit(void)
1159 {
1160         const char *const i2cdev_path = "/sys/class/i2c-dev";
1161
1162         char path[NAME_MAX], name[128];
1163         struct dirent *de, *subde;
1164         enum adapter_type adt;
1165         DIR *dir, *subdir;
1166         int rv, bus;
1167         char *pos;
1168         FILE *fp;
1169
1170         /*
1171          * XXX Upstream i2cdetect also looks for i2c bus info in /proc/bus/i2c,
1172          * but we won't bother since it's only useful on older kernels (before
1173          * 2.6.5). We expect sysfs to be present and mounted at /sys/.
1174          */
1175
1176         dir = xopendir(i2cdev_path);
1177         while ((de = readdir(dir))) {
1178                 if (de->d_name[0] == '.')
1179                         continue;
1180
1181                 /* Simple version for ISA chips. */
1182                 snprintf(path, NAME_MAX, "%s/%s/name",
1183                          i2cdev_path, de->d_name);
1184                 fp = fopen(path, "r");
1185                 if (fp == NULL) {
1186                         snprintf(path, NAME_MAX,
1187                                  "%s/%s/device/name",
1188                                  i2cdev_path, de->d_name);
1189                         fp = fopen(path, "r");
1190                 }
1191
1192                 /* Non-ISA chips require the hard-way. */
1193                 if (fp == NULL) {
1194                         snprintf(path, NAME_MAX,
1195                                  "%s/%s/device/name",
1196                                  i2cdev_path, de->d_name);
1197                         subdir = opendir(path);
1198                         if (subdir == NULL)
1199                                 continue;
1200
1201                         while ((subde = readdir(subdir))) {
1202                                 if (subde->d_name[0] == '.')
1203                                         continue;
1204
1205                                 if (is_prefixed_with(subde->d_name, "i2c-")) {
1206                                         snprintf(path, NAME_MAX,
1207                                                  "%s/%s/device/%s/name",
1208                                                  i2cdev_path, de->d_name,
1209                                                  subde->d_name);
1210                                         fp = fopen(path, "r");
1211                                         goto found;
1212                                 }
1213                         }
1214                 }
1215
1216 found:
1217                 if (fp != NULL) {
1218                         /*
1219                          * Get the rest of the info and display a line
1220                          * for a single bus.
1221                          */
1222                         memset(name, 0, sizeof(name));
1223                         pos = fgets(name, sizeof(name), fp);
1224                         fclose(fp);
1225                         if (pos == NULL)
1226                                 continue;
1227
1228                         pos = strchr(name, '\n');
1229                         if (pos != NULL)
1230                                 *pos = '\0';
1231
1232                         rv = sscanf(de->d_name, "i2c-%d", &bus);
1233                         if (rv != 1)
1234                                 continue;
1235
1236                         if (is_prefixed_with(name, "ISA"))
1237                                 adt = ADT_ISA;
1238                         else
1239                                 adt = i2cdetect_get_funcs(bus);
1240
1241                         printf(
1242                                 "i2c-%d\t%-10s\t%-32s\t%s\n",
1243                                 bus, adap_descs[adt].funcs,
1244                                 name, adap_descs[adt].algo);
1245                 }
1246         }
1247
1248         exit(EXIT_SUCCESS);
1249 }
1250
1251 static void NORETURN no_support(const char *cmd)
1252 {
1253         bb_error_msg_and_die("bus doesn't support %s", cmd);
1254 }
1255
1256 static void will_skip(const char *cmd)
1257 {
1258         bb_error_msg(
1259                 "warning: can't use %s command, "
1260                 "will skip some addresses", cmd);
1261 }
1262
1263 //usage:#define i2cdetect_trivial_usage
1264 //usage:       "[-F I2CBUS] [-l] [-y] [-a] [-q|-r] I2CBUS [FIRST LAST]"
1265 //usage:#define i2cdetect_full_usage "\n\n"
1266 //usage:       "Detect I2C chips.\n"
1267 //usage:     "\n        I2CBUS  i2c bus number"
1268 //usage:     "\n        FIRST and LAST limit the probing range"
1269 //usage:     "\n"
1270 //usage:     "\n        -l      output list of installed busses"
1271 //usage:     "\n        -y      disable interactive mode"
1272 //usage:     "\n        -a      force scanning of non-regular addresses"
1273 //usage:     "\n        -q      use smbus quick write commands for probing (default)"
1274 //usage:     "\n        -r      use smbus read byte commands for probing"
1275 //usage:     "\n        -F      display list of functionalities"
1276 int i2cdetect_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1277 int i2cdetect_main(int argc UNUSED_PARAM, char **argv)
1278 {
1279         const unsigned opt_y = (1 << 0), opt_a = (1 << 1),
1280                               opt_q = (1 << 2), opt_r = (1 << 3),
1281                               opt_F = (1 << 4), opt_l = (1 << 5);
1282         const char *const optstr = "yaqrFl";
1283
1284         int fd, bus_num, i, j, mode = DETECT_MODE_AUTO, status;
1285         unsigned first = 0x03, last = 0x77, opts;
1286         unsigned long funcs;
1287
1288         opt_complementary = "q--r:r--q:" /* mutually exclusive */
1289                         "?3"; /* up to 3 args */
1290         opts = getopt32(argv, optstr);
1291         argv += optind;
1292
1293         if (opts & opt_l)
1294                 list_i2c_busses_and_exit();
1295
1296         if (!argv[0])
1297                 bb_show_usage();
1298
1299         bus_num = i2c_bus_lookup(argv[0]);
1300         fd = i2c_dev_open(bus_num);
1301         get_funcs_matrix(fd, &funcs);
1302
1303         if (opts & opt_F) {
1304                 /* Only list the functionalities. */
1305                 printf("Functionalities implemented by bus #%d\n", bus_num);
1306                 for (i = 0; i2c_funcs_tab[i].value; i++) {
1307                         printf("%-32s %s\n", i2c_funcs_tab[i].name,
1308                                funcs & i2c_funcs_tab[i].value ? "yes" : "no");
1309                 }
1310
1311                 return EXIT_SUCCESS;
1312         }
1313
1314         if (opts & opt_r)
1315                 mode = DETECT_MODE_READ;
1316         else if (opts & opt_q)
1317                 mode = DETECT_MODE_QUICK;
1318
1319         if (opts & opt_a) {
1320                 first = 0x00;
1321                 last = 0x7f;
1322         }
1323
1324         /* Read address range. */
1325         if (argv[1]) {
1326                 first = xstrtou_range(argv[1], 16, first, last);
1327                 if (argv[2])
1328                         last = xstrtou_range(argv[2], 16, first, last);
1329         }
1330
1331         if (!(funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE))) {
1332                 no_support("detection commands");
1333         } else
1334         if (mode == DETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK)) {
1335                 no_support("SMBus Quick Write command");
1336         } else
1337         if (mode == DETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) {
1338                 no_support("SMBus Receive Byte command");
1339         }
1340
1341         if (mode == DETECT_MODE_AUTO) {
1342                 if (!(funcs & I2C_FUNC_SMBUS_QUICK))
1343                         will_skip("SMBus Quick Write");
1344                 if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE))
1345                         will_skip("SMBus Receive Byte");
1346         }
1347
1348         if (!(opts & opt_y))
1349                 confirm_action(-1, -1, -1, 0);
1350
1351         printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n");
1352         for (i = 0; i < 128; i += 16) {
1353                 printf("%02x: ", i);
1354                 for(j = 0; j < 16; j++) {
1355                         fflush_all();
1356
1357                         if (mode == DETECT_MODE_AUTO) {
1358                                 if ((i+j >= 0x30 && i+j <= 0x37) ||
1359                                     (i+j >= 0x50 && i+j <= 0x5F))
1360                                         mode = DETECT_MODE_READ;
1361                                 else
1362                                         mode = DETECT_MODE_QUICK;
1363                         }
1364
1365                         /* Skip unwanted addresses. */
1366                         if (i+j < first
1367                          || i+j > last
1368                          || (mode == DETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE))
1369                          || (mode == DETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK)))
1370                         {
1371                                 printf("   ");
1372                                 continue;
1373                         }
1374
1375                         status = ioctl(fd, I2C_SLAVE, itoptr(i + j));
1376                         if (status < 0) {
1377                                 if (errno == EBUSY) {
1378                                         printf("UU ");
1379                                         continue;
1380                                 }
1381
1382                                 bb_perror_msg_and_die(
1383                                         "can't set address to 0x%02x", i + j);
1384                         }
1385
1386                         switch (mode) {
1387                         case DETECT_MODE_READ:
1388                                 /*
1389                                  * This is known to lock SMBus on various
1390                                  * write-only chips (mainly clock chips).
1391                                  */
1392                                 status = i2c_smbus_read_byte(fd);
1393                                 break;
1394                         default: /* DETECT_MODE_QUICK: */
1395                                 /*
1396                                  * This is known to corrupt the Atmel
1397                                  * AT24RF08 EEPROM.
1398                                  */
1399                                 status = i2c_smbus_write_quick(fd,
1400                                                                I2C_SMBUS_WRITE);
1401                                 break;
1402                         }
1403
1404                         if (status < 0)
1405                                 printf("-- ");
1406                         else
1407                                 printf("%02x ", i+j);
1408                 }
1409                 printf("\n");
1410         }
1411
1412         return 0;
1413 }
1414 #endif /* ENABLE_I2CDETECT */