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