[BACK]Return to saspi.c CVS log [TXT][DIR] Up to [local] / funnyos / arch / sam7s64 / dev

Annotation of funnyos/arch/sam7s64/dev/saspi.c, Revision 1.2

1.1       nbrk        1: /*
1.2     ! nbrk        2:  * $Id: saspi.c,v 1.1 2007/12/18 15:44:21 nbrk Exp $
1.1       nbrk        3:  */
                      4: #include <sys/types.h>
                      5: #include <sys/device.h>
                      6: #include <sys/bus.h>
1.2     ! nbrk        7: #include <sys/spi_bus.h>
1.1       nbrk        8:
1.2     ! nbrk        9: #include <libkern/printf.h>
1.1       nbrk       10: #include <arch/sa7s64/dev/at91sam7s64.h>
                     11:
                     12: /*
                     13:  * SPI driver.
                     14:  */
                     15:
1.2     ! nbrk       16: struct saspi_dd {
        !            17:        struct spi_bus_handle   sd_sbh;
        !            18:
        !            19:        struct bus_handle               *sd_bhp;
        !            20: };
        !            21:
        !            22:
1.1       nbrk       23: int    saspi_attach(struct device *, uint32_t, uint8_t);
1.2     ! nbrk       24: void   saspi_init(struct saspi_dd *ddp)
        !            25: uint8_t saspi_transmit(struct saspi_dd *ddp, uint8_t data);
        !            26:
1.1       nbrk       27:
                     28: struct driver spi_dr = {
1.2     ! nbrk       29:        sizeof(struct saspi_dd),
1.1       nbrk       30:        spi_attach,
                     31:        NULL,
                     32:        NULL
                     33: };
                     34:
                     35:
                     36: int
1.2     ! nbrk       37: saspi_attach(struct device *self, uint32_t loc, uint8_t flags)
1.1       nbrk       38: {
1.2     ! nbrk       39:        struct saspi_dd *ddp = self->dv_devdata;
        !            40:
        !            41:        /* grab bus_handle */
        !            42:        ddp->sd_bhp = self->dv_parent->dv_aux;
        !            43:
        !            44:        printf("SAM7 SPI\n");
        !            45:
        !            46:        /*
        !            47:         * Initialize ourselfes and provide spi_bus_handle to children throught dv_aux.
        !            48:         */
1.1       nbrk       49:
1.2     ! nbrk       50:        saspi_init(ddp);
        !            51:
        !            52:        ddp->sd_sbh.sb_transmitfunc = saspi_transmit;
        !            53:        ddp->sd_dd = ddp;
1.1       nbrk       54:
                     55:        return(0);
1.2     ! nbrk       56: }
        !            57:
        !            58:
        !            59: void
        !            60: saspi_init(struct saspi_dd *ddp)
        !            61: {
        !            62:        /*
        !            63:         * Initialize on-chip SPI controller.
        !            64:         */
        !            65:
        !            66:        /* 'Card Present' on PA15 */
        !            67: //     bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ODR, 1 << 15);
        !            68: //     bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PER, 1 << 15);
        !            69:
        !            70:        /*
        !            71:         * Disassociate SPI chip select, clock and data lines from PIO.
        !            72:         *
        !            73:         * PA11 - NPCS0
        !            74:         * PA12 - MISO
        !            75:         * PA13 - MOSI
        !            76:         * PA14 - SPCK
        !            77:         */
        !            78:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PDR, 1 << 11 | 1 << 12 | 1 << 13 | 1 << 14);
        !            79:
        !            80:        /* assign pins to Peripheral A */
        !            81:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ASR, 1 << 11 | 1 << 12 | 1 << 13 | 1 << 14);
        !            82:
        !            83:        /* reset and enable SPI */
        !            84:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_SPIEN | AT91C_SPI_SWRST);
        !            85:        /* XXX just to be sure */
        !            86:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_SPIEN);
        !            87:
        !            88:        /* set SPI mode to master; disable decoding of Chip Select; PCS 1110 (using fixed CS line) */
        !            89:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | 0x0e << 15);
        !            90:
        !            91:        /*
        !            92:         * Configure Chip Select Register no. 0 (so no offset from SPI_CSR).
        !            93:         * CPOL (Clock Polarity) is 0 (SPCK inactive is logic 0);
        !            94:         * NCPHA (Clock Phase) is 1;
        !            95:         * 8 bits per transfer;
        !            96:         * XXX SCBR=4a;
        !            97:         */
        !            98:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CSR, AT91C_SPI_NCPHA | 0x4a00);
        !            99:
        !           100:        /* enable PDC transfers to/from SPI */
        !           101:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PDC_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN);
        !           102:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN);
        !           103: }
        !           104:
        !           105:
        !           106: uint8_t
        !           107: saspi_transmit(struct saspi_dd *ddp, uint8_t data)
        !           108: {
        !           109:        /*
        !           110:         * Shift byte on the SPI bus.
        !           111:         */
        !           112:        /* wait for Transmit Data Register Empty flag */
        !           113:        while((bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_SR) & AT91C_SPI_TDRE) == 0)
        !           114:                ;
        !           115:
        !           116:        /* okay, send our byte */
        !           117:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_TDR, 0x0000ffff & data);
        !           118:
        !           119:        /* wait while Receive Register is full and read it */
        !           120:        while((bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_SR) & AT91C_SPI_RDRF) == 0)
        !           121:                ;
        !           122:        return( bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_RDR) & 0x0000ffff );
1.1       nbrk      123: }
                    124:

CVSweb