version 1.2, 2007/12/19 16:08:56 |
version 1.3, 2007/12/20 15:25:44 |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/device.h> |
#include <sys/device.h> |
#include <sys/bus.h> |
#include <sys/bus.h> |
#include <sys/spi_bus.h> |
#include <sys/bus_spi.h> |
|
|
#include <libkern/printf.h> |
#include <libkern/printf.h> |
#include <arch/sa7s64/dev/at91sam7s64.h> |
#include <arch/sam7s64/dev/at91sam7.h> |
|
|
/* |
/* |
* SPI driver. |
* SPI driver. |
|
|
|
|
|
|
int saspi_attach(struct device *, uint32_t, uint8_t); |
int saspi_attach(struct device *, uint32_t, uint8_t); |
void saspi_init(struct saspi_dd *ddp) |
void saspi_init(struct saspi_dd *ddp); |
uint8_t saspi_transmit(struct saspi_dd *ddp, uint8_t data); |
uint8_t saspi_transmit(void *selfdd, uint8_t data); |
|
|
|
|
struct driver spi_dr = { |
struct driver saspi_dr = { |
sizeof(struct saspi_dd), |
sizeof(struct saspi_dd), |
spi_attach, |
saspi_attach, |
NULL, |
NULL, |
NULL |
NULL |
}; |
}; |
|
|
/* grab bus_handle */ |
/* grab bus_handle */ |
ddp->sd_bhp = self->dv_parent->dv_aux; |
ddp->sd_bhp = self->dv_parent->dv_aux; |
|
|
printf("SAM7 SPI\n"); |
printf("SAM7 SPI: "); |
|
/* |
|
* XXX Check if card present and fail if it is not. |
|
*/ |
|
/* 'Card Present' on PA15 */ |
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ODR, 1 << 15); |
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PER, 1 << 15); |
|
/* Write Protect' on PA16 */ |
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ODR, 1 << 16); |
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PER, 1 << 16); |
|
|
|
if((bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PDSR) & 1 << 15) == 0) |
|
printf("card present; "); |
|
else { |
|
printf("card is not presented\n"); |
|
|
|
return(-1); |
|
} |
|
printf("write %s\n", (bus_read_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PDSR) & 1 << 16) ? "protect" : "allowed"); |
|
|
/* |
/* |
* Initialize ourselfes and provide spi_bus_handle to children throught dv_aux. |
* Initialize ourselfes and provide spi_bus_handle to children throught dv_aux. |
*/ |
*/ |
|
|
saspi_init(ddp); |
saspi_init(ddp); |
|
|
ddp->sd_sbh.sb_transmitfunc = saspi_transmit; |
ddp->sd_sbh.sb_transmitfunc = saspi_transmit; |
ddp->sd_dd = ddp; |
ddp->sd_sbh.sb_dd = ddp; |
|
|
|
self->dv_aux = &ddp->sd_sbh; |
|
|
|
|
return(0); |
return(0); |
} |
} |
|
|
|
|
* Initialize on-chip SPI controller. |
* Initialize on-chip SPI controller. |
*/ |
*/ |
|
|
/* 'Card Present' on PA15 */ |
|
// bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_ODR, 1 << 15); |
|
// bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PIOA_PER, 1 << 15); |
|
|
|
/* |
/* |
* Disassociate SPI chip select, clock and data lines from PIO. |
* Disassociate SPI chip select, clock and data lines from PIO. |
* |
* |
|
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_SPIEN); |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_SPIEN); |
|
|
/* set SPI mode to master; disable decoding of Chip Select; PCS 1110 (using fixed CS line) */ |
/* set SPI mode to master; disable decoding of Chip Select; PCS 1110 (using fixed CS line) */ |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | 0x0e << 15); |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CR, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | 0x0e << 16); /* XXX 15|16 */ |
|
|
/* |
/* |
* Configure Chip Select Register no. 0 (so no offset from SPI_CSR). |
* Configure Chip Select Register no. 0 (so no offset from SPI_CSR). |
|
|
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CSR, AT91C_SPI_NCPHA | 0x4a00); |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_CSR, AT91C_SPI_NCPHA | 0x4a00); |
|
|
/* enable PDC transfers to/from SPI */ |
/* enable PDC transfers to/from SPI */ |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PDC_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN); |
// bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_PDC_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN); |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN); |
bus_write_4(ddp->sd_bhp, (uint32_t)AT91C_SPI_PTCR, AT91C_PDC_TXTEN | AT91C_PDC_RXTEN); |
|
|
} |
} |
|
|
|
|
uint8_t |
uint8_t |
saspi_transmit(struct saspi_dd *ddp, uint8_t data) |
saspi_transmit(void *selfdd, uint8_t data) |
{ |
{ |
|
struct saspi_dd *ddp = (struct saspi_dd *)selfdd; |
/* |
/* |
* Shift byte on the SPI bus. |
* Shift byte on the SPI bus. |
*/ |
*/ |