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