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

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

CVSweb