Date: Sat, 8 Jul 2006 00:52:36 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 100951 for review Message-ID: <200607080052.k680qaOu011544@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100951 Change 100951 by imp@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607080052.k680qaOu011544>