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