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); }