PERFORCE change 100951 for review

Warner Losh imp at FreeBSD.org
Sat Jul 8 00:52:37 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=100951

Change 100951 by imp at imp_lighthouse on 2006/07/08 00:52:29

	First cut at converting to new spibus

Affected files ...

.. //depot/projects/arm/src/sys/arm/at91/at91_spi.c#4 edit
.. //depot/projects/arm/src/sys/arm/at91/at91_spireg.h#4 edit
.. //depot/projects/arm/src/sys/arm/at91/files.at91#9 edit

Differences ...

==== //depot/projects/arm/src/sys/arm/at91/at91_spi.c#4 (text+ko) ====

@@ -39,7 +39,10 @@
 #include <machine/bus.h>
 
 #include <arm/at91/at91_spireg.h>
-#include <arm/at91/at91_spiio.h>
+#include <arm/at91/at91_pdcreg.h>
+
+#include <dev/spibus/spi.h>
+#include "spibus_if.h"
 
 struct at91_spi_softc
 {
@@ -77,7 +80,6 @@
 #define AT91_SPI_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
 #define AT91_SPI_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
 #define AT91_SPI_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
-#define CDEV2SOFTC(dev)		((dev)->si_drv1)
 
 static devclass_t at91_spi_devclass;
 
@@ -86,25 +88,11 @@
 static int at91_spi_probe(device_t dev);
 static int at91_spi_attach(device_t dev);
 static int at91_spi_detach(device_t dev);
-static void at91_spi_intr(void *);
 
 /* helper routines */
 static int at91_spi_activate(device_t dev);
 static void at91_spi_deactivate(device_t dev);
 
-/* cdev routines */
-static d_open_t at91_spi_open;
-static d_close_t at91_spi_close;
-static d_ioctl_t at91_spi_ioctl;
-
-static struct cdevsw at91_spi_cdevsw =
-{
-	.d_version = D_VERSION,
-	.d_open = at91_spi_open,
-	.d_close = at91_spi_close,
-	.d_ioctl = at91_spi_ioctl
-};
-
 static int
 at91_spi_probe(device_t dev)
 {
@@ -125,32 +113,32 @@
 
 	AT91_SPI_LOCK_INIT(sc);
 
-	/*
-	 * Activate the interrupt
-	 */
-	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
-	    at91_spi_intr, sc, &sc->intrhand);
-	if (err) {
-		AT91_SPI_LOCK_DESTROY(sc);
-		goto out;
-	}
-	sc->cdev = make_dev(&at91_spi_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
-	    "spi%d", device_get_unit(dev));
-	if (sc->cdev == NULL) {
-		err = ENOMEM;
-		goto out;
-	}
-	sc->cdev->si_drv1 = sc;
-#if 0
-	/* init */
-	sc->cwgr = SPI_CWGR_CKDIV(1) |
-	    SPI_CWGR_CHDIV(SPI_CWGR_DIV(SPI_DEF_CLK)) |
-	    SPI_CWGR_CLDIV(SPI_CWGR_DIV(SPI_DEF_CLK));
+	// reset the SPI
+	WR4(sc, SPI_CR, SPI_CR_SWRST);
+
+	WR4(sc, SPI_MR, (0xf << 24) | SPI_MR_MSTR | SPI_MR_MODFDIS |
+	    (0xE << 16));
+
+	WR4(sc, SPI_CSR0, SPI_CSR_CPOL | (4 << 16) | (2 << 8));
+	WR4(sc, SPI_CR, SPI_CR_SPIEN);
+
+	WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS);
+	WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS);
+	WR4(sc, PDC_RNPR, 0);
+	WR4(sc, PDC_RNCR, 0);
+	WR4(sc, PDC_TNPR, 0);
+	WR4(sc, PDC_TNCR, 0);
+	WR4(sc, PDC_RPR, 0);
+	WR4(sc, PDC_RCR, 0);
+	WR4(sc, PDC_TPR, 0);
+	WR4(sc, PDC_TCR, 0);
+	WR4(sc, PDC_PTCR, PDC_PTCR_RXTEN);
+	WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN);
+	RD4(sc, SPI_RDR);
+	RD4(sc, SPI_SR);
 
-	WR4(sc, SPI_CR, SPI_CR_SWRST);
-	WR4(sc, SPI_CR, SPI_CR_MSEN | SPI_CR_SVDIS);
-	WR4(sc, SPI_CWGR, sc->cwgr);
-#endif
+	device_add_child(dev, "spibus", -1);
+	bus_generic_attach(dev);
 out:;
 	if (err)
 		at91_spi_deactivate(dev);
@@ -207,230 +195,10 @@
 	return;
 }
 
-static void
-at91_spi_intr(void *xsc)
-{
-	struct at91_spi_softc *sc = xsc;
-#if 0
-	uint32_t status;
-
-	/* Reading the status also clears the interrupt */
-	status = RD4(sc, SPI_SR);
-	if (status == 0)
-		return;
-	AT91_SPI_LOCK(sc);
-	if (status & SPI_SR_RXRDY)
-		sc->flags |= RXRDY;
-	if (status & SPI_SR_TXCOMP)
-		sc->flags |= TXCOMP;
-	if (status & SPI_SR_TXRDY)
-		sc->flags |= TXRDY;
-	AT91_SPI_UNLOCK(sc);
-#endif
-	wakeup(sc);
-	return;
-}
-
-static int 
-at91_spi_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
-{
-	struct at91_spi_softc *sc;
-
-	sc = CDEV2SOFTC(dev);
-	AT91_SPI_LOCK(sc);
-	if (!(sc->flags & OPENED)) {
-		sc->flags |= OPENED;
-#if 0
-		WR4(sc, SPI_IER, SPI_SR_TXCOMP | SPI_SR_RXRDY | SPI_SR_TXRDY |
-		    SPI_SR_OVRE | SPI_SR_UNRE | SPI_SR_NACK);
-#endif
-	}
-	AT91_SPI_UNLOCK(sc);
-    	return (0);
-}
-
 static int
-at91_spi_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
+at91_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
 {
-	struct at91_spi_softc *sc;
-
-	sc = CDEV2SOFTC(dev);
-	AT91_SPI_LOCK(sc);
-	sc->flags &= ~OPENED;
-#if 0
-	WR4(sc, SPI_IDR, SPI_SR_TXCOMP | SPI_SR_RXRDY | SPI_SR_TXRDY |
-	    SPI_SR_OVRE | SPI_SR_UNRE | SPI_SR_NACK);
-#endif
-	AT91_SPI_UNLOCK(sc);
-	return (0);
-}
-
-static int
-at91_spi_read_master(struct at91_spi_softc *sc, struct at91_spi_io *xfr)
-{
-#if 1
-    return ENOTTY;
-#else
-	uint8_t *walker;
-	uint8_t buffer[256];
-	size_t len;
-	int err = 0;
-
-	if (xfr->xfer_len > sizeof(buffer))
-		return (EINVAL);
-	walker = buffer;
-	len = xfr->xfer_len;
-	RD4(sc, SPI_RHR);
-	// Master mode, with the right address and interal addr size
-	WR4(sc, SPI_MMR, SPI_MMR_IADRSZ(xfr->iadrsz) | SPI_MMR_MREAD |
-	    SPI_MMR_DADR(xfr->dadr));
-	WR4(sc, SPI_IADR, xfr->iadr);
-	WR4(sc, SPI_CR, SPI_CR_START);
-	while (len-- > 1) {
-		while (!(sc->flags & RXRDY)) {
-			err = msleep(sc, &sc->sc_mtx, PZERO | PCATCH, "spird",
-			    0);
-			if (err)
-				return (err);
-		}
-		sc->flags &= ~RXRDY;
-		*walker++ = RD4(sc, SPI_RHR) & 0xff;
-	}
-	WR4(sc, SPI_CR, SPI_CR_STOP);
-	while (!(sc->flags & TXCOMP)) {
-		err = msleep(sc, &sc->sc_mtx, PZERO | PCATCH, "spird2", 0);
-		if (err)
-			return (err);
-	}
-	sc->flags &= ~TXCOMP;
-	*walker = RD4(sc, SPI_RHR) & 0xff;
-	if (xfr->xfer_buf) {
-		AT91_SPI_UNLOCK(sc);
-		err = copyout(buffer, xfr->xfer_buf, xfr->xfer_len);
-		AT91_SPI_LOCK(sc);
-	}
-	return (err);
-#endif
-}
-
-static int
-at91_spi_write_master(struct at91_spi_softc *sc, struct at91_spi_io *xfr)
-{
-#if 1
-    return ENOTTY;
-#else
-	uint8_t *walker;
-	uint8_t buffer[256];
-	size_t len;
-	int err;
-
-	if (xfr->xfer_len > sizeof(buffer))
-		return (EINVAL);
-	walker = buffer;
-	len = xfr->xfer_len;
-	AT91_SPI_UNLOCK(sc);
-	err = copyin(xfr->xfer_buf, buffer, xfr->xfer_len);
-	AT91_SPI_LOCK(sc);
-	if (err)
-		return (err);
-	/* Setup the xfr for later readback */
-	xfr->xfer_buf = 0;
-	xfr->xfer_len = 1;
-	while (len--) {
-		WR4(sc, SPI_MMR, SPI_MMR_IADRSZ(xfr->iadrsz) | SPI_MMR_MWRITE |
-		    SPI_MMR_DADR(xfr->dadr));
-		WR4(sc, SPI_IADR, xfr->iadr++);
-		WR4(sc, SPI_THR, *walker++);
-		WR4(sc, SPI_CR, SPI_CR_START);
-		/*
-		 * If we get signal while waiting for TXRDY, make sure we
-		 * try to stop this device
-		 */
-		while (!(sc->flags & TXRDY)) {
-			err = msleep(sc, &sc->sc_mtx, PZERO | PCATCH, "spiwr",
-			    0);
-			if (err)
-				break;
-		}
-		WR4(sc, SPI_CR, SPI_CR_STOP);
-		if (err)
-			return (err);
-		while (!(sc->flags & TXCOMP)) {
-			err = msleep(sc, &sc->sc_mtx, PZERO | PCATCH, "spiwr2",
-			    0);
-			if (err)
-				return (err);
-		}
-		/* Readback */
-		at91_spi_read_master(sc, xfr);
-	}
-	return (err);
-#endif
-}
-
-static int
-at91_spi_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
-    struct thread *td)
-{
-	int err = 0;
-	struct at91_spi_softc *sc;
-
-	sc = CDEV2SOFTC(dev);
-	AT91_SPI_LOCK(sc);
-	while (sc->flags & XFER_PENDING) {
-		err = msleep(sc, &sc->sc_mtx, PZERO | PCATCH,
-		    "spiwait", 0);
-		if (err) {
-			AT91_SPI_UNLOCK(sc);
-			return (err);
-		}
-	}
-	sc->flags |= XFER_PENDING;
-
-	switch (cmd)
-	{
-	case SPIIOCXFER:
-	{
-		struct at91_spi_io *xfr = (struct at91_spi_io *)data;
-		switch (xfr->type)
-		{
-		case SPI_IO_READ_MASTER:
-			err = at91_spi_read_master(sc, xfr);
-			break;
-		case SPI_IO_WRITE_MASTER:
-			err = at91_spi_write_master(sc, xfr);
-			break;
-		default:
-			err = EINVAL;
-			break;
-		}
-		break;
-	}
-
-	case SPIIOCSETCLOCK:
-	{
-#if 0
-		struct at91_spi_clock *spick = (struct at91_spi_clock *)data;
-
-		sc->cwgr = SPI_CWGR_CKDIV(spick->ckdiv) |
-		    SPI_CWGR_CHDIV(SPI_CWGR_DIV(spick->high_rate)) |
-		    SPI_CWGR_CLDIV(SPI_CWGR_DIV(spick->low_rate));
-		WR4(sc, SPI_CR, SPI_CR_SWRST);
-		WR4(sc, SPI_CR, SPI_CR_MSEN | SPI_CR_SVDIS);
-		WR4(sc, SPI_CWGR, sc->cwgr);
-#else
-		err = ENOTTY;
-#endif
-		break;
-	}
-	default:
-		err = ENOTTY;
-		break;
-	}
-	sc->flags &= ~XFER_PENDING;
-	AT91_SPI_UNLOCK(sc);
-	wakeup(sc);
-	return err;
+	return EIO;
 }
 
 static device_method_t at91_spi_methods[] = {
@@ -439,6 +207,8 @@
 	DEVMETHOD(device_attach,	at91_spi_attach),
 	DEVMETHOD(device_detach,	at91_spi_detach),
 
+	/* spibus interface */
+	DEVMETHOD(spibus_transfer,	at91_spi_transfer),
 	{ 0, 0 }
 };
 

==== //depot/projects/arm/src/sys/arm/at91/at91_spireg.h#4 (text+ko) ====

@@ -27,4 +27,23 @@
 #ifndef ARM_AT91_AT91_SPIREG_H
 #define ARM_AT91_AT91_SPIREG_H
 
+#define SPI_CR		0x00		/* CR: Control Register */
+#define	  SPI_CR_SPIEN		0x1
+#define	  SPI_CR_SPIDIS		0x2
+#define	  SPI_CR_SWRST		0x8
+#define SPI_MR		0x04		/* MR: Mode Register */
+#define	  SPI_MR_MSTR		0x01
+#define	  SPI_MR_MODFDIS	0x10
+#define SPI_RDR		0x08		/* RDR: Receive Data Register */
+#define SPI_TDR		0x0c		/* TDR: Transmit Data Register */
+#define SPI_SR		0x10		/* SR: Status Register */
+#define	SPI_IER		0x14		/* IER: Interrupt Enable Regsiter */
+#define	SPI_IDR		0x18		/* IDR: Interrupt Disable Regsiter */
+#define	SPI_IMR		0x1c		/* IMR: Interrupt Mask Regsiter */
+#define SPI_CSR0	0x30		/* CS0: Chip Select 0 */
+#define   SPI_CSR_CPOL		0x01
+#define SPI_CSR1	0x34		/* CS1: Chip Select 1 */
+#define SPI_CSR2	0x38		/* CS2: Chip Select 2 */
+#define SPI_CSR3	0x3c		/* CS3: Chip Select 3 */
+
 #endif /* ARM_AT91_AT91_SPIREG_H */

==== //depot/projects/arm/src/sys/arm/at91/files.at91#9 (text) ====

@@ -8,7 +8,8 @@
 arm/at91/at91_pmc.c		standard
 arm/at91/at91_rtc.c		standard
 arm/at91/at91_ssc.c		optional	at91_ssc
-arm/at91/at91_spi.c		optional	at91_spi
+arm/at91/at91_spi.c		optional	at91_spi		\
+	dependency	"spibus_if.h"
 arm/at91/at91_tc.c		optional	at91_tc
 arm/at91/at91_twi.c		optional	at91_twi
 arm/at91/at91_udp.c		optional	at91_udp


More information about the p4-projects mailing list