spi: add the ability to read and write security

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
Sean Cross 2018-12-18 22:18:26 -05:00
parent 70591122af
commit c0c9f22748
2 changed files with 41 additions and 10 deletions

45
spi.c
View File

@ -41,6 +41,8 @@ struct ff_spi {
} pins; } pins;
}; };
static void spi_get_id(struct ff_spi *spi);
static void spi_set_state(struct ff_spi *spi, enum spi_state state) { static void spi_set_state(struct ff_spi *spi, enum spi_state state) {
if (spi->state == state) if (spi->state == state)
return; return;
@ -299,7 +301,7 @@ uint8_t spiCommandRx(struct ff_spi *spi) {
return spiSingleRx(spi); return spiSingleRx(spi);
} }
uint8_t spiReadSr(struct ff_spi *spi, int sr) { uint8_t spiReadStatus(struct ff_spi *spi, uint8_t sr) {
uint8_t val = 0xff; uint8_t val = 0xff;
switch (sr) { switch (sr) {
@ -332,7 +334,24 @@ uint8_t spiReadSr(struct ff_spi *spi, int sr) {
return val; return val;
} }
void spiWriteSr(struct ff_spi *spi, int sr, uint8_t val) { void spiWriteSecurity(struct ff_spi *spi, uint8_t sr, uint8_t val) {
spiBegin(spi);
spiCommand(spi, 0x06);
spiEnd(spi);
spiBegin(spi);
spiCommand(spi, 0x42);
spiCommand(spi, 0x00);
spiCommand(spi, sr);
spiCommand(spi, 0x00);
spiCommand(spi, val);
spiEnd(spi);
spi_get_id(spi);
}
void spiWriteStatus(struct ff_spi *spi, uint8_t sr, uint8_t val) {
switch (sr) { switch (sr) {
case 1: case 1:
@ -355,7 +374,7 @@ void spiWriteSr(struct ff_spi *spi, int sr, uint8_t val) {
case 2: { case 2: {
uint8_t sr1 = 0x00; uint8_t sr1 = 0x00;
if (spi->quirks & SQ_SR2_FROM_SR1) if (spi->quirks & SQ_SR2_FROM_SR1)
sr1 = spiReadSr(spi, 1); sr1 = spiReadStatus(spi, 1);
if (!(spi->quirks & SQ_SKIP_SR_WEL)) { if (!(spi->quirks & SQ_SKIP_SR_WEL)) {
spiBegin(spi); spiBegin(spi);
@ -476,6 +495,16 @@ static void spi_get_id(struct ff_spi *spi) {
spi->id.serial[3] = spiCommandRx(spi); spi->id.serial[3] = spiCommandRx(spi);
spiEnd(spi); spiEnd(spi);
spiBegin(spi);
spiCommand(spi, 0x48); // Read security registers
spiCommand(spi, 0x00); // Dummy byte 1
spiCommand(spi, 0x00); // Dummy byte 2
spiCommand(spi, 0x00); // Dummy byte 3
spi->id.security[0] = spiCommandRx(spi);
spi->id.security[1] = spiCommandRx(spi);
spi->id.security[2] = spiCommandRx(spi);
spiEnd(spi);
spi_decode_id(spi); spi_decode_id(spi);
return; return;
} }
@ -515,7 +544,7 @@ int spiSetType(struct ff_spi *spi, enum spi_type type) {
} }
// Enable QE bit // Enable QE bit
spiWriteSr(spi, 2, spiReadSr(spi, 2) | (1 << 1)); spiWriteStatus(spi, 2, spiReadStatus(spi, 2) | (1 << 1));
spi->type = type; spi->type = type;
spi_set_state(spi, SS_QUAD_TX); spi_set_state(spi, SS_QUAD_TX);
@ -523,7 +552,7 @@ int spiSetType(struct ff_spi *spi, enum spi_type type) {
case ST_QPI: case ST_QPI:
// Enable QE bit // Enable QE bit
spiWriteSr(spi, 2, spiReadSr(spi, 2) | (1 << 1)); spiWriteStatus(spi, 2, spiReadStatus(spi, 2) | (1 << 1));
spiBegin(spi); spiBegin(spi);
spiCommand(spi, 0x38); // Enter QPI Mode spiCommand(spi, 0x38); // Enter QPI Mode
@ -573,10 +602,10 @@ int spiRead(struct ff_spi *spi, uint32_t addr, uint8_t *data, unsigned int count
static int spi_wait_for_not_busy(struct ff_spi *spi) { static int spi_wait_for_not_busy(struct ff_spi *spi) {
uint8_t sr1; uint8_t sr1;
sr1 = spiReadSr(spi, 1); sr1 = spiReadStatus(spi, 1);
do { do {
sr1 = spiReadSr(spi, 1); sr1 = spiReadStatus(spi, 1);
} while (sr1 & (1 << 0)); } while (sr1 & (1 << 0));
return 0; return 0;
} }
@ -643,7 +672,7 @@ int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned in
spiCommand(spi, 0x06); spiCommand(spi, 0x06);
spiEnd(spi); spiEnd(spi);
uint8_t sr1 = spiReadSr(spi, 1); uint8_t sr1 = spiReadStatus(spi, 1);
if (!(sr1 & (1 << 1))) if (!(sr1 & (1 << 1)))
fprintf(stderr, "error: write-enable latch (WEL) not set, write will probably fail\n"); fprintf(stderr, "error: write-enable latch (WEL) not set, write will probably fail\n");

6
spi.h
View File

@ -42,6 +42,7 @@ struct spi_id {
uint8_t memory_size; // Result from 0x9f uint8_t memory_size; // Result from 0x9f
uint8_t signature; // Result from 0xab uint8_t signature; // Result from 0xab
uint8_t serial[4]; // Result from 0x4b uint8_t serial[4]; // Result from 0x4b
uint8_t security[3]; // Result from 0x48
const char *manufacturer; const char *manufacturer;
const char *model; const char *model;
const char *capacity; const char *capacity;
@ -62,8 +63,9 @@ void spiCommand(struct ff_spi *spi, uint8_t cmd);
//uint8_t spiQuadRx(struct ff_spi *spi); //uint8_t spiQuadRx(struct ff_spi *spi);
int spiTx(struct ff_spi *spi, uint8_t word); int spiTx(struct ff_spi *spi, uint8_t word);
uint8_t spiRx(struct ff_spi *spi); uint8_t spiRx(struct ff_spi *spi);
uint8_t spiReadSr(struct ff_spi *spi, int sr); uint8_t spiReadStatus(struct ff_spi *spi, uint8_t sr);
void spiWriteSr(struct ff_spi *spi, int sr, uint8_t val); void spiWriteStatus(struct ff_spi *spi, uint8_t sr, uint8_t val);
void spiWriteSecurity(struct ff_spi *spi, uint8_t sr, uint8_t val);
int spiSetType(struct ff_spi *spi, enum spi_type type); int spiSetType(struct ff_spi *spi, enum spi_type type);
int spiRead(struct ff_spi *spi, uint32_t addr, uint8_t *data, unsigned int count); int spiRead(struct ff_spi *spi, uint32_t addr, uint8_t *data, unsigned int count);