Module Name:    src
Committed By:   jdc
Date:           Fri Feb  8 15:14:11 UTC 2013

Modified Files:
        src/sys/dev/i2c: at24cxx.c

Log Message:
Handle direct configuration if ia->ia_name is set, using iic_compat_match().
If ia->ia_name is set, display the name on attach.
Display the size (if known) on attach.
Move the iic_acquire_bus() and iic_release_bus() calls inside the read and
write loops, to avoid holding the bus for the full duration of the read or
write.


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/i2c/at24cxx.c

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

Modified files:

Index: src/sys/dev/i2c/at24cxx.c
diff -u src/sys/dev/i2c/at24cxx.c:1.12 src/sys/dev/i2c/at24cxx.c:1.13
--- src/sys/dev/i2c/at24cxx.c:1.12	Sun Jun  8 03:49:26 2008
+++ src/sys/dev/i2c/at24cxx.c	Fri Feb  8 15:14:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: at24cxx.c,v 1.12 2008/06/08 03:49:26 tsutsui Exp $	*/
+/*	$NetBSD: at24cxx.c,v 1.13 2013/02/08 15:14:11 jdc Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: at24cxx.c,v 1.12 2008/06/08 03:49:26 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: at24cxx.c,v 1.13 2013/02/08 15:14:11 jdc Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -100,14 +100,23 @@ const struct cdevsw seeprom_cdevsw = {
 
 static int seeprom_wait_idle(struct seeprom_softc *);
 
+static const char * seeprom_compats[] = {
+	"i2c-at24c64",
+	NULL
+};
 
 static int
 seeprom_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct i2c_attach_args *ia = aux;
 
-	if ((ia->ia_addr & AT24CXX_ADDRMASK) == AT24CXX_ADDR)
-		return (1);
+	if (ia->ia_name) {
+		if (iic_compat_match(ia, seeprom_compats))
+			return (1);
+	} else {
+		if ((ia->ia_addr & AT24CXX_ADDRMASK) == AT24CXX_ADDR)
+			return (1);
+	}
 
 	return (0);
 }
@@ -122,8 +131,13 @@ seeprom_attach(device_t parent, device_t
 	sc->sc_address = ia->ia_addr;
 	sc->sc_dev = self;
 
-	aprint_naive(": EEPROM\n");
-	aprint_normal(": AT24Cxx EEPROM\n");
+	if (ia->ia_name != NULL) {
+		aprint_naive(": %s", ia->ia_name);
+		aprint_normal(": %s", ia->ia_name);
+	} else {
+		aprint_naive(": EEPROM");
+		aprint_normal(": AT24Cxx EEPROM");
+	}
 
 	/*
 	 * The AT24C01A/02/04/08/16 EEPROMs use a 1 byte command
@@ -147,6 +161,7 @@ seeprom_attach(device_t parent, device_t
 	case 1024:		/* 8Kbit */
 	case 2048:		/* 16Kbit */
 		sc->sc_cmdlen = 1;
+		aprint_normal(": size %d\n", sc->sc_size);
 		break;
 
 	case 4096:		/* 32Kbit */
@@ -155,6 +170,7 @@ seeprom_attach(device_t parent, device_t
 	case 32768:		/* 256Kbit */
 	case 65536:		/* 512Kbit */
 		sc->sc_cmdlen = 2;
+		aprint_normal(": size %d\n", sc->sc_size);
 		break;
 
 	default:
@@ -168,6 +184,7 @@ seeprom_attach(device_t parent, device_t
 		 * Obviously this will not work for 4KB or 8KB
 		 * EEPROMs, but them's the breaks.
 		 */
+		aprint_normal("\n");
 		aprint_error_dev(self, "invalid size specified; "
 		    "assuming 2KB (16Kb)\n");
 		sc->sc_size = 2048;
@@ -223,9 +240,6 @@ seeprom_read(dev_t dev, struct uio *uio,
 	if (uio->uio_offset >= sc->sc_size)
 		return (EINVAL);
 
-	if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0)
-		return (error);
-
 	/*
 	 * Even though the AT24Cxx EEPROMs support sequential
 	 * reads within a page, some I2C controllers do not
@@ -234,6 +248,9 @@ seeprom_read(dev_t dev, struct uio *uio,
 	 */
 
 	while (uio->uio_resid > 0 && uio->uio_offset < sc->sc_size) {
+		if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0)
+			return (error);
+
 		a = (int)uio->uio_offset;
 		if (sc->sc_cmdlen == 1) {
 			addr = sc->sc_address + (a >> 8);
@@ -255,10 +272,9 @@ seeprom_read(dev_t dev, struct uio *uio,
 			iic_release_bus(sc->sc_tag, 0);
 			return (error);
 		}
+		iic_release_bus(sc->sc_tag, 0);
 	}
 
-	iic_release_bus(sc->sc_tag, 0);
-
 	return (0);
 }
 
@@ -277,15 +293,15 @@ seeprom_write(dev_t dev, struct uio *uio
 	if (uio->uio_offset >= sc->sc_size)
 		return (EINVAL);
 
-	if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0)
-		return (error);
-
 	/*
 	 * See seeprom_read() for why we don't use sequential
 	 * writes within a page.
 	 */
 
 	while (uio->uio_resid > 0 && uio->uio_offset < sc->sc_size) {
+		if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0)
+			return (error);
+
 		a = (int)uio->uio_offset;
 		if (sc->sc_cmdlen == 1) {
 			addr = sc->sc_address + (a >> 8);
@@ -313,10 +329,9 @@ seeprom_write(dev_t dev, struct uio *uio
 			iic_release_bus(sc->sc_tag, 0);
 			return (error);
 		}
+		iic_release_bus(sc->sc_tag, 0);
 	}
 
-	iic_release_bus(sc->sc_tag, 0);
-
 	return (0);
 }
 

Reply via email to