Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch - Split device_t/softc.



details:   https://anonhg.NetBSD.org/src/rev/49d30e5ecd52
branches:  trunk
changeset: 766256:49d30e5ecd52
user:      nonaka <nonaka%NetBSD.org@localhost>
date:      Sun Jun 19 16:16:42 2011 +0000

description:
- Split device_t/softc.
- Added some functions for i2c framework.

diffstat:

 sys/arch/arm/xscale/pxa2x0_i2c.c |  165 ++++++++++++++++++++++++++++++++++++--
 sys/arch/arm/xscale/pxa2x0_i2c.h |   25 ++++-
 sys/arch/evbarm/gumstix/gxiic.c  |    8 +-
 3 files changed, 181 insertions(+), 17 deletions(-)

diffs (truncated from 302 to 300 lines):

diff -r 5f790b861f63 -r 49d30e5ecd52 sys/arch/arm/xscale/pxa2x0_i2c.c
--- a/sys/arch/arm/xscale/pxa2x0_i2c.c  Sun Jun 19 15:58:28 2011 +0000
+++ b/sys/arch/arm/xscale/pxa2x0_i2c.c  Sun Jun 19 16:16:42 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pxa2x0_i2c.c,v 1.4 2009/04/20 12:55:02 pgoyette Exp $  */
+/*     $NetBSD: pxa2x0_i2c.c,v 1.5 2011/06/19 16:16:42 nonaka Exp $    */
 /*     $OpenBSD: pxa2x0_i2c.c,v 1.2 2005/05/26 03:52:07 pascoe Exp $   */
 
 /*
@@ -18,33 +18,51 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pxa2x0_i2c.c,v 1.4 2009/04/20 12:55:02 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0_i2c.c,v 1.5 2011/06/19 16:16:42 nonaka Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
+#include <sys/bus.h>
 
-#include <machine/bus.h>
+#include <dev/i2c/i2cvar.h>
 
 #include <arm/xscale/pxa2x0reg.h>
 #include <arm/xscale/pxa2x0var.h>
 #include <arm/xscale/pxa2x0_i2c.h>
-#include <arm/xscale/pxa2x0_gpio.h>
+
+#ifdef PXAIIC_DEBUG
+#define        DPRINTF(s)      printf s
+#else
+#define        DPRINTF(s)      do { } while (/*CONSTCOND*/0)
+#endif
 
 #define I2C_RETRY_COUNT        10
 
 int
 pxa2x0_i2c_attach_sub(struct pxa2x0_i2c_softc *sc)
 {
+       int error;
 
-       if (bus_space_map(sc->sc_iot, PXA2X0_I2C_BASE,
-           PXA2X0_I2C_SIZE, 0, &sc->sc_ioh)) {
+       error = bus_space_map(sc->sc_iot, PXA2X0_I2C_BASE, sc->sc_size, 0,
+           &sc->sc_ioh);
+       if (error) {
+               aprint_error_dev(sc->sc_dev, "unable to map register\n");
                sc->sc_size = 0;
-               return EIO;
+               return error;
        }
+
        bus_space_barrier(sc->sc_iot, sc->sc_ioh, 0, sc->sc_size,
            BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
 
+       sc->sc_icr = ICR_GCD | ICR_SCLE | ICR_IUE;
+#if 0
+       if (ISSET(sc->sc_flags, PI2CF_ENABLE_INTR))
+               sc->sc_icr |= ICR_BEIE | ICR_DRFIE | ICR_ITEIE;
+#endif
+       if (ISSET(sc->sc_flags, PI2CF_FAST_MODE))
+               sc->sc_icr |= ICR_FM;
+
        pxa2x0_i2c_init(sc);
 
        return 0;
@@ -54,12 +72,11 @@
 pxa2x0_i2c_detach_sub(struct pxa2x0_i2c_softc *sc)
 {
 
-       if (sc->sc_size) {
+       if (sc->sc_size != 0) {
                bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
                sc->sc_size = 0;
        }
        pxa2x0_clkman_config(CKEN_I2C, 0);
-
        return 0;
 }
 
@@ -382,3 +399,133 @@
 
        return EIO;
 }
+
+/* ----------------------------------------------------------------------------
+ * for i2c_controller
+ */
+
+#define        CSR_READ_4(sc,r)        bus_space_read_4(sc->sc_iot, sc->sc_ioh, r)
+#define        CSR_WRITE_4(sc,r,v)     bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v)
+
+#define        ISR_ALL                 (ISR_RWM | ISR_ACKNAK | ISR_UE | ISR_IBB \
+                                | ISR_SSD | ISR_ALD | ISR_ITE | ISR_IRF \
+                                | ISR_GCAD | ISR_SAD | ISR_BED)
+
+#define        I2C_TIMEOUT             100     /* protocol timeout, in uSecs */
+
+void
+pxa2x0_i2c_reset(struct pxa2x0_i2c_softc *sc)
+{
+
+       CSR_WRITE_4(sc, I2C_ICR, ICR_UR);
+       CSR_WRITE_4(sc, I2C_ISAR, 0);
+       CSR_WRITE_4(sc, I2C_ISR, ISR_ALL);
+       while (CSR_READ_4(sc, I2C_ICR) & ~ICR_UR)
+               continue;
+       CSR_WRITE_4(sc, I2C_ICR, sc->sc_icr);
+}
+
+int
+pxa2x0_i2c_wait(struct pxa2x0_i2c_softc *sc, int bit, int flags)
+{
+       uint32_t isr;
+       int error;
+       int i;
+
+       for (i = I2C_TIMEOUT; i >= 0; --i) {
+               isr = CSR_READ_4(sc, I2C_ISR);
+               if (isr & (bit | ISR_BED))
+                       break;
+               delay(1);
+       }
+
+       if (isr & (ISR_BED | (bit & ISR_ALD)))
+               error = EIO;
+       else if (isr & (bit & ~ISR_ALD))
+               error = 0;
+       else
+               error = ETIMEDOUT;
+
+       CSR_WRITE_4(sc, I2C_ISR, isr);
+
+       return error;
+}
+
+int
+pxa2x0_i2c_send_start(struct pxa2x0_i2c_softc *sc, int flags)
+{
+
+       CSR_WRITE_4(sc, I2C_ICR, sc->sc_icr | ICR_START);
+       delay(I2C_TIMEOUT);
+       return 0;
+}
+
+int
+pxa2x0_i2c_send_stop(struct pxa2x0_i2c_softc *sc, int flags)
+{
+
+       CSR_WRITE_4(sc, I2C_ICR, sc->sc_icr | ICR_STOP);
+       delay(I2C_TIMEOUT);
+       return 0;
+}
+
+int
+pxa2x0_i2c_initiate_xfer(struct pxa2x0_i2c_softc *sc, uint16_t addr, int flags)
+{
+       int rd_req = (flags & I2C_F_READ) ? 1 : 0;
+       int error;
+
+       if ((addr & ~0x7f) != 0) {
+               error = EINVAL;
+               goto error;
+       }
+
+       CSR_WRITE_4(sc, I2C_IDBR, (addr << 1) | rd_req);
+       CSR_WRITE_4(sc, I2C_ICR, sc->sc_icr | ICR_START | ICR_TB);
+
+       error = pxa2x0_i2c_wait(sc, ISR_ITE, flags);
+error:
+       if (error) {
+               DPRINTF(("%s: failed to initiate %s xfer (error=%d)\n",
+                   device_xname(sc->sc_dev),
+                   rd_req ? "read" : "write", error));
+               return error;
+       }
+       return 0;
+}
+
+int
+pxa2x0_i2c_read_byte(struct pxa2x0_i2c_softc *sc, uint8_t *bytep, int flags)
+{
+       int last_byte = flags & I2C_F_LAST;
+       int send_stop = flags & I2C_F_STOP;
+       int error;
+
+       CSR_WRITE_4(sc, I2C_ICR, sc->sc_icr | ICR_TB
+           | (last_byte ? ICR_ACKNAK : 0) | (send_stop ? ICR_STOP : 0));
+       error = pxa2x0_i2c_wait(sc, ISR_IRF | ISR_ALD, flags);
+       if (error) {
+               DPRINTF(("%s: read byte failed\n", device_xname(sc->sc_dev)));
+               return error;
+       }
+
+       *bytep = CSR_READ_4(sc, I2C_IDBR);
+       return 0;
+}
+
+int
+pxa2x0_i2c_write_byte(struct pxa2x0_i2c_softc *sc, uint8_t byte, int flags)
+{
+       int send_stop = flags & I2C_F_STOP;
+       int error;
+
+       CSR_WRITE_4(sc, I2C_IDBR, byte);
+       CSR_WRITE_4(sc, I2C_ICR, sc->sc_icr | ICR_TB
+           | (send_stop ? ICR_STOP : 0));
+       error = pxa2x0_i2c_wait(sc, ISR_ITE | ISR_ALD, flags);
+       if (error) {
+               DPRINTF(("%s: write byte failed\n", device_xname(sc->sc_dev)));
+               return error;
+       }
+       return 0;
+}
diff -r 5f790b861f63 -r 49d30e5ecd52 sys/arch/arm/xscale/pxa2x0_i2c.h
--- a/sys/arch/arm/xscale/pxa2x0_i2c.h  Sun Jun 19 15:58:28 2011 +0000
+++ b/sys/arch/arm/xscale/pxa2x0_i2c.h  Sun Jun 19 16:16:42 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pxa2x0_i2c.h,v 1.2 2009/04/20 12:55:02 pgoyette Exp $  */
+/*     $NetBSD: pxa2x0_i2c.h,v 1.3 2011/06/19 16:16:42 nonaka Exp $    */
 /*     $OpenBSD: pxa2x0_i2c.h,v 1.2 2005/05/26 03:52:07 pascoe Exp $   */
 
 /*
@@ -20,13 +20,19 @@
 #ifndef _PXA2X0_I2C_H_
 #define _PXA2X0_I2C_H_
 
-#include <machine/bus.h>
+#include <sys/bus.h>
 
 struct pxa2x0_i2c_softc {
-       struct device sc_dev;
+       device_t sc_dev;
        bus_space_tag_t sc_iot;
        bus_space_handle_t sc_ioh;
+
        bus_size_t sc_size;
+
+       uint32_t sc_icr;
+
+       uint32_t sc_flags;
+#define        PI2CF_FAST_MODE         (1U << 0)
 };
 
 int    pxa2x0_i2c_attach_sub(struct pxa2x0_i2c_softc *);
@@ -37,6 +43,15 @@
 int    pxa2x0_i2c_read(struct pxa2x0_i2c_softc *sc, u_char, u_char *);
 int    pxa2x0_i2c_write(struct pxa2x0_i2c_softc *, u_char, u_char);
 int    pxa2x0_i2c_write_2(struct pxa2x0_i2c_softc *, u_char, u_short);
-int    pxa2x0_i2c_quick(struct pxa2x0_i2c_softc *sc, u_char slave, u_char rw);
+int    pxa2x0_i2c_quick(struct pxa2x0_i2c_softc *sc, u_char, u_char);
 
-#endif
+int    pxa2x0_i2c_send_start(struct pxa2x0_i2c_softc *, int flags);
+int    pxa2x0_i2c_send_stop(struct pxa2x0_i2c_softc *, int flags);
+int    pxa2x0_i2c_initiate_xfer(struct pxa2x0_i2c_softc *, uint16_t, int);
+int    pxa2x0_i2c_read_byte(struct pxa2x0_i2c_softc *, uint8_t *, int);
+int    pxa2x0_i2c_write_byte(struct pxa2x0_i2c_softc *, uint8_t, int);
+
+void   pxa2x0_i2c_reset(struct pxa2x0_i2c_softc *);
+int    pxa2x0_i2c_wait(struct pxa2x0_i2c_softc *, int, int);
+
+#endif /* _PXA2X0_I2C_H_ */
diff -r 5f790b861f63 -r 49d30e5ecd52 sys/arch/evbarm/gumstix/gxiic.c
--- a/sys/arch/evbarm/gumstix/gxiic.c   Sun Jun 19 15:58:28 2011 +0000
+++ b/sys/arch/evbarm/gumstix/gxiic.c   Sun Jun 19 16:16:42 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gxiic.c,v 1.5 2009/08/09 06:12:34 kiyohara Exp $ */
+/*     $NetBSD: gxiic.c,v 1.6 2011/06/19 16:16:42 nonaka Exp $ */
 /*
  * Copyright (c) 2007 KIYOHARA Takashi
  * All rights reserved.
@@ -25,7 +25,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gxiic.c,v 1.5 2009/08/09 06:12:34 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gxiic.c,v 1.6 2011/06/19 16:16:42 nonaka Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -86,8 +86,10 @@
        aprint_normal("\n");
        aprint_naive("\n");
 
+       sc->sc_pxa_i2c.sc_dev = self;
        sc->sc_pxa_i2c.sc_iot = pxa->pxa_iot;
        sc->sc_pxa_i2c.sc_size = pxa->pxa_size;
+       sc->sc_pxa_i2c.sc_flags = 0;
        if (pxa2x0_i2c_attach_sub(&sc->sc_pxa_i2c)) {
                aprint_error_dev(self, "unable to attach PXA I2C\n");
                return;
@@ -108,7 +110,7 @@
 
        iba.iba_tag = &sc->sc_i2c;
        pxa2x0_i2c_open(&sc->sc_pxa_i2c);
-       config_found_ia(&sc->sc_pxa_i2c.sc_dev, "i2cbus", &iba, iicbus_print);
+       config_found_ia(sc->sc_pxa_i2c.sc_dev, "i2cbus", &iba, iicbus_print);
        pxa2x0_i2c_close(&sc->sc_pxa_i2c);



Home | Main Index | Thread Index | Old Index