diff options
| -rw-r--r-- | spi25.c | 72 | 
1 files changed, 14 insertions, 58 deletions
| @@ -764,63 +764,19 @@ int spi_write_status_enable(struct flashctx *flash)   * This is according the SST25VF016 datasheet, who knows it is more   * generic that this...   */ -static int spi_write_status_register_ewsr(struct flashctx *flash, int status) +static int spi_write_status_register_flag(struct flashctx *flash, int status, const unsigned char enable_opcode)  {  	int result;  	int i = 0; -	struct spi_command cmds[] = { -	{ -	/* WRSR requires either EWSR or WREN depending on chip type. */ -		.writecnt	= JEDEC_EWSR_OUTSIZE, -		.writearr	= (const unsigned char[]){ JEDEC_EWSR }, -		.readcnt	= 0, -		.readarr	= NULL, -	}, { -		.writecnt	= JEDEC_WRSR_OUTSIZE, -		.writearr	= (const unsigned char[]){ JEDEC_WRSR, (unsigned char) status }, -		.readcnt	= 0, -		.readarr	= NULL, -	}, { -		.writecnt	= 0, -		.writearr	= NULL, -		.readcnt	= 0, -		.readarr	= NULL, -	}}; - -	result = spi_send_multicommand(flash, cmds); -	if (result) { -		msg_cerr("%s failed during command execution\n", -			__func__); -		/* No point in waiting for the command to complete if execution -		 * failed. -		 */ -		return result; -	} -	/* WRSR performs a self-timed erase before the changes take effect. -	 * This may take 50-85 ms in most cases, and some chips apparently -	 * allow running RDSR only once. Therefore pick an initial delay of -	 * 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed. +	/* +	 * WRSR requires either EWSR or WREN depending on chip type. +	 * The code below relies on the fact hat EWSR and WREN have the same +	 * INSIZE and OUTSIZE.  	 */ -	programmer_delay(100 * 1000); -	while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP) { -		if (++i > 490) { -			msg_cerr("Error: WIP bit after WRSR never cleared\n"); -			return TIMEOUT_ERROR; -		} -		programmer_delay(10 * 1000); -	} -	return 0; -} - -static int spi_write_status_register_wren(struct flashctx *flash, int status) -{ -	int result; -	int i = 0;  	struct spi_command cmds[] = {  	{ -	/* WRSR requires either EWSR or WREN depending on chip type. */  		.writecnt	= JEDEC_WREN_OUTSIZE, -		.writearr	= (const unsigned char[]){ JEDEC_WREN }, +		.writearr	= (const unsigned char[]){ enable_opcode },  		.readcnt	= 0,  		.readarr	= NULL,  	}, { @@ -837,8 +793,7 @@ static int spi_write_status_register_wren(struct flashctx *flash, int status)  	result = spi_send_multicommand(flash, cmds);  	if (result) { -		msg_cerr("%s failed during command execution\n", -			__func__); +		msg_cerr("%s failed during command execution\n", __func__);  		/* No point in waiting for the command to complete if execution  		 * failed.  		 */ @@ -862,17 +817,18 @@ static int spi_write_status_register_wren(struct flashctx *flash, int status)  int spi_write_status_register(struct flashctx *flash, int status)  { +	int feature_bits = flash->feature_bits;  	int ret = 1; -	if (!(flash->feature_bits & (FEATURE_WRSR_WREN | FEATURE_WRSR_EWSR))) { +	if (!(feature_bits & (FEATURE_WRSR_WREN | FEATURE_WRSR_EWSR))) {  		msg_cdbg("Missing status register write definition, assuming "  			 "EWSR is needed\n"); -		flash->feature_bits |= FEATURE_WRSR_EWSR; +		feature_bits |= FEATURE_WRSR_EWSR;  	} -	if (flash->feature_bits & FEATURE_WRSR_WREN) -		ret = spi_write_status_register_wren(flash, status); -	if (ret && (flash->feature_bits & FEATURE_WRSR_EWSR)) -		ret = spi_write_status_register_ewsr(flash, status); +	if (feature_bits & FEATURE_WRSR_WREN) +		ret = spi_write_status_register_flag(flash, status, JEDEC_WREN); +	if (ret && (feature_bits & FEATURE_WRSR_EWSR)) +		ret = spi_write_status_register_flag(flash, status, JEDEC_EWSR);  	return ret;  } | 
