Module Name:    src
Committed By:   jmcneill
Date:           Sun Oct  2 16:48:47 UTC 2011

Modified Files:
        src/distrib/sets/lists/base: mi
Added Files:
        src/usr.sbin/i2cscan: Makefile i2cscan.c

Log Message:
add userland implementation of I2C_SCAN code


To generate a diff of this commit:
cvs rdiff -u -r1.956 -r1.957 src/distrib/sets/lists/base/mi
cvs rdiff -u -r0 -r1.1 src/usr.sbin/i2cscan/Makefile \
    src/usr.sbin/i2cscan/i2cscan.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/base/mi
diff -u src/distrib/sets/lists/base/mi:1.956 src/distrib/sets/lists/base/mi:1.957
--- src/distrib/sets/lists/base/mi:1.956	Sun Sep 11 19:10:56 2011
+++ src/distrib/sets/lists/base/mi	Sun Oct  2 16:48:47 2011
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.956 2011/09/11 19:10:56 christos Exp $
+# $NetBSD: mi,v 1.957 2011/10/02 16:48:47 jmcneill Exp $
 #
 # Note:	Don't delete entries from here - mark them as "obsolete" instead,
 #	unless otherwise stated below.
@@ -1224,6 +1224,7 @@
 ./usr/sbin/hostapd_cli				base-sysutil-bin
 ./usr/sbin/hprop				base-krb5-bin		kerberos
 ./usr/sbin/htable				base-obsolete		obsolete
+./usr/sbin/i2cscan				base-sysutil-bin
 ./usr/sbin/ifmcstat				base-netutil-bin	inet6
 ./usr/sbin/ifwatchd				base-netutil-bin
 ./usr/sbin/inetd				base-netutil-bin

Added files:

Index: src/usr.sbin/i2cscan/Makefile
diff -u /dev/null src/usr.sbin/i2cscan/Makefile:1.1
--- /dev/null	Sun Oct  2 16:48:47 2011
+++ src/usr.sbin/i2cscan/Makefile	Sun Oct  2 16:48:47 2011
@@ -0,0 +1,6 @@
+# $NetBSD: Makefile,v 1.1 2011/10/02 16:48:47 jmcneill Exp $
+
+PROG=	i2cscan
+NOMAN=	# defined
+
+.include <bsd.prog.mk>
Index: src/usr.sbin/i2cscan/i2cscan.c
diff -u /dev/null src/usr.sbin/i2cscan/i2cscan.c:1.1
--- /dev/null	Sun Oct  2 16:48:47 2011
+++ src/usr.sbin/i2cscan/i2cscan.c	Sun Oct  2 16:48:47 2011
@@ -0,0 +1,176 @@
+/* $NetBSD: i2cscan.c,v 1.1 2011/10/02 16:48:47 jmcneill Exp $ */
+
+/*
+ * Copyright (c) 2003 Wasabi Systems, Inc.
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: i2cscan.c,v 1.1 2011/10/02 16:48:47 jmcneill Exp $");
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <dev/i2c/i2c_io.h>
+
+static void
+usage(const char *pn)
+{
+	fprintf(stderr, "usage: %s <i2cdev>\n", pn);
+	exit(EXIT_FAILURE);
+}
+
+static int
+iic_smbus_quick_write(int fd, i2c_addr_t addr, int flags)
+{
+	i2c_ioctl_exec_t iie;
+
+	iie.iie_op = I2C_OP_WRITE_WITH_STOP;
+	iie.iie_addr = addr;
+	iie.iie_cmd = NULL;
+	iie.iie_cmdlen = 0;
+	iie.iie_buf = NULL;
+	iie.iie_buflen = 0;
+
+	if (ioctl(fd, I2C_IOCTL_EXEC, &iie) == -1)
+		return errno;
+	return 0;
+}
+
+static int
+iic_smbus_receive_byte(int fd, i2c_addr_t addr, uint8_t *valp, int flags)
+{
+	i2c_ioctl_exec_t iie;
+
+	iie.iie_op = I2C_OP_READ_WITH_STOP;
+	iie.iie_addr = addr;
+	iie.iie_cmd = NULL;
+	iie.iie_cmdlen = 0;
+	iie.iie_buf = valp;
+	iie.iie_buflen = 1;
+
+	if (ioctl(fd, I2C_IOCTL_EXEC, &iie) == -1)
+		return errno;
+	return 0;
+	
+}
+
+static void
+do_i2c_scan(const char *dname, int fd)
+{
+	int error;
+	int found = 0;
+	i2c_addr_t addr;
+	uint8_t val;
+
+	for (addr = 0x09; addr < 0x78; addr++) {
+		/*
+		 * Skip certain i2c addresses:
+		 *	0x00		General Call / START
+		 *	0x01		CBUS Address
+		 *	0x02		Different Bus format
+		 *	0x03 - 0x07	Reserved
+		 *	0x08		Host Address
+		 *	0x0c		Alert Response Address
+		 *	0x28		ACCESS.Bus host
+		 *	0x37		ACCESS.Bus default address
+		 *	0x48 - 0x4b	Prototypes
+		 *	0x61		Device Default Address
+		 *	0x78 - 0x7b	10-bit addresses
+		 *	0x7c - 0x7f	Reserved
+		 *
+		 * Some of these are skipped by judicious selection
+		 * of the range of the above for (;;) statement.
+		 *
+		 * if (addr <= 0x08 || addr >= 0x78)
+		 *	continue;
+		 */
+		if (addr == 0x0c || addr == 0x28 || addr == 0x37 ||
+		    addr == 0x61 || (addr & 0x7c) == 0x48)
+			continue;
+
+		/*
+		 * Use SMBus quick_write command to detect most
+		 * addresses;  should avoid hanging the bus on
+		 * some write-only devices (like clocks that show
+		 * up at address 0x69)
+		 *
+		 * XXX The quick_write() is allegedly known to
+		 * XXX corrupt the Atmel AT24RF08 EEPROM found
+		 * XXX on some IBM Thinkpads!
+		 */
+		printf("\r%s: scanning 0x%02x", dname, addr);
+		fflush(stdout);
+		if ((addr & 0xf8) == 0x30 ||
+		    (addr & 0xf0) == 0x50)
+			error = iic_smbus_receive_byte(fd, addr, &val, 0);
+		else
+			error = iic_smbus_quick_write(fd, addr, 0);
+		if (error == 0) {
+			printf("\r%s: found device at 0x%02x\n",
+			    dname, addr);
+			++found;
+		}
+	}
+	if (found == 0)
+		printf("\r%s: no devices found\n", dname);
+	else
+		printf("\r%s: %d devices found\n", dname, found);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int fd;
+
+	if (argc != 2)
+		usage(argv[0]);
+
+	fd = open(argv[1], O_RDWR);
+	if (fd == -1)
+		err(EXIT_FAILURE, "couldn't open %s", argv[1]);
+
+	do_i2c_scan(argv[1], fd);
+
+	close(fd);
+
+	return EXIT_SUCCESS;
+}

Reply via email to