spi: add the ability to read and write security
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
		
							
								
								
									
										45
									
								
								spi.c
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								spi.c
									
									
									
									
									
								
							@@ -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
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								spi.h
									
									
									
									
									
								
							@@ -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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user