spi25: Add SPI25_EEPROM enum and handle < 3-byte addresses

Change-Id: I043f6ea987a07853b8c50e34b3cd63faf995ecbc
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/314
diff --git a/include/flash.h b/include/flash.h
index 5d5efb7..67853cb 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -279,6 +279,7 @@
 		/* SPI25 is very common. Keep it at zero so we don't have
 		   to specify it for each and every chip in the database.*/
 		SPI25 = 0,
+		SPI25_EEPROM,
 		SPI95,
 		SPI_EDI,
 	} spi_cmd_set;
diff --git a/spi25.c b/spi25.c
index 0f49a13..c43ffc6 100644
--- a/spi25.c
+++ b/spi25.c
@@ -377,10 +377,29 @@
 	return 0;
 }
 
+static size_t spi_address_length(struct flashctx *const flash, const bool native_4ba)
+{
+	if (flash->chip->spi_cmd_set == SPI25_EEPROM) {
+		if (flashprog_flash_getsize(flash) > 64*KiB)
+			return 3;
+		if (flashprog_flash_getsize(flash) > 256)
+			return 2;
+		return 1;
+	}
+
+	if (native_4ba || flash->in_4ba_mode)
+		return 4;
+
+	return 3;
+}
+
 static int spi_prepare_address(struct flashctx *const flash, uint8_t cmd_buf[],
 			       const bool native_4ba, const unsigned int addr)
 {
-	if (native_4ba || flash->in_4ba_mode) {
+	const size_t len = spi_address_length(flash, native_4ba);
+
+	switch (len) {
+	case 4:
 		if (!spi_master_4ba(flash)) {
 			msg_cwarn("4-byte address requested but master can't handle 4-byte addresses.\n");
 			return -1;
@@ -389,8 +408,8 @@
 		cmd_buf[2] = (addr >> 16) & 0xff;
 		cmd_buf[3] = (addr >>  8) & 0xff;
 		cmd_buf[4] = (addr >>  0) & 0xff;
-		return 4;
-	} else {
+		return len;
+	case 3:
 		if (flash->chip->feature_bits & FEATURE_4BA_EAR_ANY) {
 			if (spi_set_extended_address(flash, addr >> 24))
 				return -1;
@@ -402,7 +421,14 @@
 		cmd_buf[1] = (addr >> 16) & 0xff;
 		cmd_buf[2] = (addr >>  8) & 0xff;
 		cmd_buf[3] = (addr >>  0) & 0xff;
-		return 3;
+		return len;
+	case 2:
+		cmd_buf[1] = (addr >> 8) & 0xff;
+		cmd_buf[2] = (addr >> 0) & 0xff;
+		return len;
+	default:
+		cmd_buf[1] = addr & 0xff;
+		return len;
 	}
 }