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