[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.5

1.1       nbrk        1: /*
1.5     ! nbrk        2:  * $Id: saspi.c,v 1.4 2007/12/21 17:40:29 nbrk Exp $
1.1       nbrk        3:  */
                      4: #include <sys/types.h>
                      5: #include <sys/device.h>
                      6: #include <sys/bus.h>
1.3       nbrk        7: #include <sys/bus_spi.h>
1.1       nbrk        8:
1.2       nbrk        9: #include <libkern/printf.h>
1.3       nbrk       10: #include <arch/sam7s64/dev/at91sam7.h>
1.1       nbrk       11:
1.5     ! nbrk       12: /* #define SASPI_DEBUG */
        !            13:
        !            14: #ifdef SASPI_DEBUG
        !            15: #define DPRINTF(x...)  do { printf(x); } while (0)
        !            16: #else
        !            17: #define DPRINTF(x...)  { }
        !            18: #endif
        !            19:
1.1       nbrk       20: /*
                     21:  * SPI driver.
                     22:  */
                     23:
1.2       nbrk       24: struct saspi_dd {
                     25:        struct spi_bus_handle   sd_sbh;
                     26:
                     27:        struct bus_handle               *sd_bhp;
                     28: };
                     29:
                     30:
1.1       nbrk       31: int    saspi_attach(struct device *, uint32_t, uint8_t);
1.3       nbrk       32: void   saspi_init(struct saspi_dd *ddp);
                     33: uint8_t saspi_transmit(void *selfdd, uint8_t data);
1.4       nbrk       34: void   saspi_cs_low(void *selfdd);
                     35: void   saspi_cs_high(void *selfdd);
1.2       nbrk       36:
1.1       nbrk       37:
1.3       nbrk       38: struct driver saspi_dr = {
1.2       nbrk       39:        sizeof(struct saspi_dd),
1.3       nbrk       40:        saspi_attach,
1.1       nbrk       41:        NULL,
                     42:        NULL
                     43: };
                     44:
                     45:
                     46: int
1.2       nbrk       47: saspi_attach(struct device *self, uint32_t loc, uint8_t flags)
1.1       nbrk       48: {
1.2       nbrk       49:        struct saspi_dd *ddp = self->dv_devdata;
                     50:
                     51:        /* grab bus_handle */
                     52:        ddp->sd_bhp = self->dv_parent->dv_aux;
                     53:
1.3       nbrk       54:        printf("SAM7 SPI: ");
                     55:        /*
                     56:         * XXX Check if card present and fail if it is not.
                     57:         */
                     58:        /* 'Card Present' on PA15 */
                     59:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ODR, 1 << 15);
                     60:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PER, 1 << 15);
                     61:        /* Write Protect' on PA16 */
                     62:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ODR, 1 << 16);
                     63:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PER, 1 << 16);
                     64:
                     65:        if((bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PDSR) & 1 << 15) == 0)
                     66:                printf("card present; ");
                     67:        else {
                     68:                printf("card is not presented\n");
                     69:
                     70:                return(-1);
                     71:        }
                     72:        printf("write %s\n", (bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PDSR) & 1 << 16) ? "protect" : "allowed");
1.2       nbrk       73:
                     74:        /*
                     75:         * Initialize ourselfes and provide spi_bus_handle to children throught dv_aux.
                     76:         */
1.1       nbrk       77:
1.2       nbrk       78:        saspi_init(ddp);
                     79:
                     80:        ddp->sd_sbh.sb_transmitfunc = saspi_transmit;
1.4       nbrk       81:        ddp->sd_sbh.sb_cslowfunc = saspi_cs_low;
                     82:        ddp->sd_sbh.sb_cshighfunc = saspi_cs_high;
1.3       nbrk       83:        ddp->sd_sbh.sb_dd = ddp;
                     84:
                     85:        self->dv_aux = &ddp->sd_sbh;
                     86:
1.1       nbrk       87:
                     88:        return(0);
1.2       nbrk       89: }
                     90:
                     91:
                     92: void
                     93: saspi_init(struct saspi_dd *ddp)
                     94: {
                     95:        /*
                     96:         * Initialize on-chip SPI controller.
                     97:         */
                     98:
                     99:        /*
1.5     ! nbrk      100:         * Disassociate SPI clock and data lines from PIO.
1.2       nbrk      101:         *
1.5     ! nbrk      102:         * PA11 - NPCS0 (we will drive this as gpio pin)
1.2       nbrk      103:         * PA12 - MISO
                    104:         * PA13 - MOSI
                    105:         * PA14 - SPCK
                    106:         */
1.5     ! nbrk      107:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PDR, 1 << 12 | 1 << 13 | 1 << 14);
1.2       nbrk      108:
                    109:        /* assign pins to Peripheral A */
1.5     ! nbrk      110:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ASR, 1 << 12 | 1 << 13 | 1 << 14);
        !           111:
        !           112:        /*
        !           113:         * Configure NCPS0 (CS):
        !           114:         * Enable PIO; Set high; Enable output.
        !           115:         */
        !           116:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PER, 1 << 11);
        !           117:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_SODR, 1 << 11);
        !           118:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_OER, 1 << 11);
1.2       nbrk      119:
1.4       nbrk      120:
1.2       nbrk      121:        /* reset and enable SPI */
                    122:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_SPIEN | AT91C_SPI_SWRST);
                    123:        /* XXX just to be sure */
                    124:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_SPIEN);
                    125:
                    126:        /* set SPI mode to master; disable decoding of Chip Select; PCS 1110 (using fixed CS line) */
1.4       nbrk      127:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_MR, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | 0x0e << 16); /* XXX 15|16 */
1.2       nbrk      128:
                    129:        /*
                    130:         * Configure Chip Select Register no. 0 (so no offset from SPI_CSR).
                    131:         * CPOL (Clock Polarity) is 0 (SPCK inactive is logic 0);
                    132:         * NCPHA (Clock Phase) is 1;
                    133:         * 8 bits per transfer;
                    134:         * XXX SCBR=4a;
                    135:         */
1.5     ! nbrk      136:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CSR, AT91C_SPI_NCPHA | 0x4a00 );
1.2       nbrk      137:
                    138:        /* enable PDC transfers to/from SPI */
                    139:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN);
1.3       nbrk      140:
1.2       nbrk      141: }
                    142:
                    143:
                    144: uint8_t
1.3       nbrk      145: saspi_transmit(void *selfdd, uint8_t data)
1.2       nbrk      146: {
1.3       nbrk      147:        struct saspi_dd *ddp = (struct saspi_dd *)selfdd;
1.2       nbrk      148:        /*
                    149:         * Shift byte on the SPI bus.
                    150:         */
                    151:        /* wait for Transmit Data Register Empty flag */
                    152:        while((bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_SR) & AT91C_SPI_TDRE) == 0)
                    153:                ;
                    154:
                    155:        /* okay, send our byte */
1.5     ! nbrk      156:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_TDR, 0x000000ff & data);
        !           157:        DPRINTF("saspi_transmit: tx byte 0x%x\n", 0x000000ff & data);
1.2       nbrk      158:
                    159:        /* wait while Receive Register is full and read it */
1.4       nbrk      160:        while(((bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_SR)) & AT91C_SPI_RDRF) == 0)
1.2       nbrk      161:                ;
1.5     ! nbrk      162:        data = bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_RDR) & 0x000000ff;
        !           163:        DPRINTF("saspi_transmit: rx byte 0x%x\n", data);
        !           164:
        !           165:        return( data );
1.4       nbrk      166: }
                    167:
                    168:
                    169: void
1.5     ! nbrk      170: saspi_cs_high(void *selfdd)
1.4       nbrk      171: {
                    172:        struct saspi_dd *ddp = selfdd;
1.5     ! nbrk      173:
        !           174:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_SODR, 1 << 11);
1.4       nbrk      175: }
                    176:
                    177:
                    178: void
1.5     ! nbrk      179: saspi_cs_low(void *selfdd)
1.4       nbrk      180: {
                    181:        struct saspi_dd *ddp = selfdd;
                    182:
1.5     ! nbrk      183:        bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_CODR, 1 << 11);
1.1       nbrk      184: }
                    185:

CVSweb