1 /* $NetBSD: i2cscan.c,v 1.4 2013/07/10 15:18:54 tcort Exp $ */
4 * Copyright (c) 2011, 2013 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Paul Goyette and Jared McNeill
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: i2cscan.c,v 1.4 2013/07/10 15:18:54 tcort Exp $");
35 #include <sys/types.h>
36 #include <sys/ioctl.h>
45 #include <dev/i2c/i2c_io.h>
47 #define MODE_DEFAULT 0
53 fprintf(stderr
, "usage: %s [-r] <i2cdev>\n", getprogname());
58 iic_smbus_quick_write(int fd
, i2c_addr_t addr
, int flags
)
62 iie
.iie_op
= I2C_OP_WRITE_WITH_STOP
;
69 if (ioctl(fd
, I2C_IOCTL_EXEC
, &iie
) == -1)
75 iic_smbus_receive_byte(int fd
, i2c_addr_t addr
, uint8_t *valp
, int flags
)
79 iie
.iie_op
= I2C_OP_READ_WITH_STOP
;
86 if (ioctl(fd
, I2C_IOCTL_EXEC
, &iie
) == -1)
93 do_i2c_scan(const char *dname
, int fd
, int mode
)
100 for (addr
= 0x09; addr
< 0x78; addr
++) {
102 * Skip certain i2c addresses:
103 * 0x00 General Call / START
105 * 0x02 Different Bus format
106 * 0x03 - 0x07 Reserved
108 * 0x0c Alert Response Address
109 * 0x28 ACCESS.Bus host
110 * 0x37 ACCESS.Bus default address
111 * 0x48 - 0x4b Prototypes
112 * 0x61 Device Default Address
113 * 0x78 - 0x7b 10-bit addresses
114 * 0x7c - 0x7f Reserved
116 * Some of these are skipped by judicious selection
117 * of the range of the above for (;;) statement.
119 * if (addr <= 0x08 || addr >= 0x78)
122 if (addr
== 0x0c || addr
== 0x28 || addr
== 0x37 ||
123 addr
== 0x61 || (addr
& 0x7c) == 0x48)
127 * Use SMBus quick_write command to detect most
128 * addresses; should avoid hanging the bus on
129 * some write-only devices (like clocks that show
130 * up at address 0x69)
132 * XXX The quick_write() is allegedly known to
133 * XXX corrupt the Atmel AT24RF08 EEPROM found
134 * XXX on some IBM Thinkpads!
136 printf("\r%s: scanning 0x%02x", dname
, addr
);
138 if ((addr
& 0xf8) == 0x30 ||
139 (addr
& 0xf0) == 0x50 ||
141 error
= iic_smbus_receive_byte(fd
, addr
, &val
, 0);
143 error
= iic_smbus_quick_write(fd
, addr
, 0);
145 printf("\r%s: found device at 0x%02x\n",
151 printf("\r%s: no devices found\n", dname
);
153 printf("\r%s: %d devices found\n", dname
, found
);
157 main(int argc
, char *argv
[])
167 while ((ch
= getopt(argc
, argv
, "r")) != -1)
186 fd
= open(*argv
, O_RDWR
);
188 err(EXIT_FAILURE
, "couldn't open %s", *argv
);
190 do_i2c_scan(*argv
, fd
, mode
);