Index: chipdrivers.h
===================================================================
--- chipdrivers.h	(revision 1955)
+++ chipdrivers.h	(working copy)
@@ -34,6 +34,7 @@
 
 /* spi25.c */
 int probe_spi_rdid(struct flashctx *flash);
+int probe_spi_rdid_jedec_addr_len(struct flashctx *flash);
 int probe_spi_rdid4(struct flashctx *flash);
 int probe_spi_rems(struct flashctx *flash);
 int probe_spi_res1(struct flashctx *flash);
Index: flash.h
===================================================================
--- flash.h	(revision 1955)
+++ flash.h	(working copy)
@@ -208,6 +208,7 @@
 		uint16_t max;
 	} voltage;
 	enum write_granularity gran;
+	bool is_4byte_addr;
 };
 
 struct flashctx {
Index: flashchips.c
===================================================================
--- flashchips.c	(revision 1955)
+++ flashchips.c	(working copy)
@@ -7632,6 +7632,33 @@
 
 	{
 		.vendor		= "Macronix",
+			.name		= "MX25L25635F/MX25L25735F",
+			.bustype	= BUS_SPI,
+			.manufacture_id	= MACRONIX_ID,
+			.model_id	= MACRONIX_MX25L25635F,
+			.total_size	= 32768,
+			.page_size	= 256,
+			/* OTP: 512B total; enter 0xB1, exit 0xC1 */
+			.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
+			.tested		= TEST_OK_PREW,
+			.probe		= probe_spi_rdid_jedec_addr_len,
+			.probe_timing	= TIMING_ZERO,
+			.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 8192} },
+				.block_erase = spi_block_erase_20,
+			},
+		},
+			.printlock	= spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+			.unlock		= spi_disable_blockprotect_bp3_srwd,
+			.write		= spi_chip_write_256,
+			.read		= spi_chip_read, /* Fast read (0x0B) supported */
+			.voltage	= {2700, 3600},
+	},
+	
+	{
+		.vendor		= "Macronix",
 		.name		= "MX25L3205(A)",
 		.bustype	= BUS_SPI,
 		.manufacture_id	= MACRONIX_ID,
Index: sfdp.c
===================================================================
--- sfdp.c	(revision 1955)
+++ sfdp.c	(working copy)
@@ -158,6 +158,7 @@
 	case 0x2:
 		msg_cdbg("  4-Byte only addressing (not supported by "
 			 "flashrom).\n");
+		chip->is_4byte_addr = 1;
 		return 1;
 	default:
 		msg_cdbg("  Required addressing mode (0x%x) not supported.\n",
Index: spi.c
===================================================================
--- spi.c	(revision 1955)
+++ spi.c	(working copy)
@@ -110,20 +110,23 @@
 	 * means 0xffffff, the highest unsigned 24bit number.
 	 */
 	addrbase = spi_get_valid_read_addr(flash);
-	if (addrbase + flash->chip->total_size * 1024 > (1 << 24)) {
-		msg_perr("Flash chip size exceeds the allowed access window. ");
-		msg_perr("Read will probably fail.\n");
-		/* Try to get the best alignment subject to constraints. */
-		addrbase = (1 << 24) - flash->chip->total_size * 1024;
+	if( !(flash->chip->is_4byte_addr) )
+	{
+		if (addrbase + flash->chip->total_size * 1024 > (1 << 24)) {
+			msg_perr("Flash chip size exceeds the allowed access window. ");
+			msg_perr("Read will probably fail.\n");
+			/* Try to get the best alignment subject to constraints. */
+			addrbase = (1 << 24) - flash->chip->total_size * 1024;
+		}
+		/* Check if alignment is native (at least the largest power of two which
+		 * is a factor of the mapped size of the chip).
+		 */
+		if (ffs(flash->chip->total_size * 1024) > (ffs(addrbase) ? : 33)) {
+			msg_perr("Flash chip is not aligned natively in the allowed "
+					 "access window.\n");
+			msg_perr("Read will probably return garbage.\n");
+		}
 	}
-	/* Check if alignment is native (at least the largest power of two which
-	 * is a factor of the mapped size of the chip).
-	 */
-	if (ffs(flash->chip->total_size * 1024) > (ffs(addrbase) ? : 33)) {
-		msg_perr("Flash chip is not aligned natively in the allowed "
-			 "access window.\n");
-		msg_perr("Read will probably return garbage.\n");
-	}
 	return flash->mst->spi.read(flash, buf, addrbase + start, len);
 }
 
Index: spi25.c
===================================================================
--- spi25.c	(revision 1955)
+++ spi25.c	(working copy)
@@ -29,6 +29,13 @@
 #include "programmer.h"
 #include "spi.h"
 
+#define FOUR_BYTE_ADDR_NOT_SUPPORTED \
+if( flash->chip->is_4byte_addr ) { \
+	msg_cerr("%s 4 byte address not supported\n", __func__); \
+	return(SPI_INVALID_LENGTH); \
+}
+	
+
 static int spi_rdid(struct flashctx *flash, unsigned char *readarr, int bytes)
 {
 	static const unsigned char cmd[JEDEC_RDID_OUTSIZE] = { JEDEC_RDID };
@@ -167,6 +174,69 @@
 	return probe_spi_rdid_generic(flash, 3);
 }
 
+int probe_spi_rdid_jedec_addr_len(struct flashctx *flash)
+{
+	int rc;
+	
+	rc = probe_spi_rdid_generic(flash, 3);
+	
+	if(!rc)
+	{
+		return(rc);
+	}
+	
+	rc = probe_spi_sfdp(flash);
+	
+	if( (!rc) && flash->chip->is_4byte_addr )
+	{
+		/* Probe failed due to 4-byte only,
+		 * that's OK
+		 */
+		rc = 1;
+		
+		switch(flash->mst->spi.type)
+		{
+			case SPI_CONTROLLER_FT2232:
+				break;
+			default:
+				msg_cerr("%s 4 byte address only chip, but controller does not support 4 byte mode\n", __func__);
+				return(0);
+		}
+		msg_cinfo("%s: Using 4 byte address mode\n", __func__ );
+	}
+	else
+	{
+		/* If the chip is bigger then 16MBytes, and using SPI_CONTROLLER_FT2232
+		 * put into 4-byte mode
+		 */
+		if( flash->chip->total_size > ( 16 * 1024 ) )
+		{
+			static const unsigned char cmd[] = { 0xB7 };
+			int result;
+
+			switch(flash->mst->spi.type)
+			{
+				case SPI_CONTROLLER_FT2232:
+					break;
+				default:
+					msg_cerr("%s 4 byte address mode needed chip, but controller does not support 4 byte mode\n", __func__);
+					return(0);
+			}
+			
+			result = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL);
+
+			if (result)
+			{
+				msg_cerr("%s Send EN4B failed\n", __func__);
+				return(0);
+			}
+			msg_cinfo("%s: Switched to 4 byte address mode\n", __func__ );
+		}
+	}
+	
+	return(rc);
+}
+
 int probe_spi_rdid4(struct flashctx *flash)
 {
 	/* Some SPI controllers do not support commands with writecnt=1 and
@@ -458,6 +528,8 @@
 		.readarr	= NULL,
 	}};
 
+	FOUR_BYTE_ADDR_NOT_SUPPORTED;
+	
 	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n",
@@ -502,6 +574,8 @@
 		.readarr	= NULL,
 	}};
 
+	FOUR_BYTE_ADDR_NOT_SUPPORTED;
+
 	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr);
@@ -548,6 +622,8 @@
 		.readarr	= NULL,
 	}};
 
+	FOUR_BYTE_ADDR_NOT_SUPPORTED;
+
 	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n",
@@ -593,6 +669,8 @@
 		.readarr	= NULL,
 	}};
 
+	FOUR_BYTE_ADDR_NOT_SUPPORTED;
+
 	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n",
@@ -635,6 +713,8 @@
 		.readarr	= NULL,
 	} };
 
+	FOUR_BYTE_ADDR_NOT_SUPPORTED;
+
 	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr);
@@ -654,6 +734,9 @@
 		       unsigned int blocklen)
 {
 	int result;
+	int i = 1;
+	unsigned char cmd[JEDEC_SE_OUTSIZE+1] = {
+		JEDEC_SE };
 	struct spi_command cmds[] = {
 	{
 		.writecnt	= JEDEC_WREN_OUTSIZE,
@@ -662,12 +745,7 @@
 		.readarr	= NULL,
 	}, {
 		.writecnt	= JEDEC_SE_OUTSIZE,
-		.writearr	= (const unsigned char[]){
-					JEDEC_SE,
-					(addr >> 16) & 0xff,
-					(addr >> 8) & 0xff,
-					(addr & 0xff)
-				},
+		.writearr	= cmd,
 		.readcnt	= 0,
 		.readarr	= NULL,
 	}, {
@@ -677,6 +755,15 @@
 		.readarr	= NULL,
 	}};
 
+	if( flash->chip->is_4byte_addr )
+	{
+		cmds[1].writecnt++;
+		cmd[i++] = (addr >> 24) & 0xff;
+	}
+	cmd[i++] = (addr >> 16) & 0xff;
+	cmd[i++] = (addr >>  8) & 0xff;
+	cmd[i++] = (addr >>  0) & 0xff;	
+	
 	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n",
@@ -718,6 +805,8 @@
 		.readarr	= NULL,
 	}};
 
+	FOUR_BYTE_ADDR_NOT_SUPPORTED;
+
 	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr);
@@ -758,6 +847,8 @@
 		.readarr	= NULL,
 	}};
 
+	FOUR_BYTE_ADDR_NOT_SUPPORTED;
+
 	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr);
@@ -868,6 +959,8 @@
 		.readarr	= NULL,
 	}};
 
+	FOUR_BYTE_ADDR_NOT_SUPPORTED;
+
 	result = spi_send_multicommand(flash, cmds);
 	if (result) {
 		msg_cerr("%s failed during command execution at address 0x%x\n",
@@ -879,13 +972,10 @@
 int spi_nbyte_program(struct flashctx *flash, unsigned int addr, const uint8_t *bytes, unsigned int len)
 {
 	int result;
+	int i = 1;
 	/* FIXME: Switch to malloc based on len unless that kills speed. */
 	unsigned char cmd[JEDEC_BYTE_PROGRAM_OUTSIZE - 1 + 256] = {
-		JEDEC_BYTE_PROGRAM,
-		(addr >> 16) & 0xff,
-		(addr >> 8) & 0xff,
-		(addr >> 0) & 0xff,
-	};
+		JEDEC_BYTE_PROGRAM };
 	struct spi_command cmds[] = {
 	{
 		.writecnt	= JEDEC_WREN_OUTSIZE,
@@ -904,6 +994,15 @@
 		.readarr	= NULL,
 	}};
 
+	if( flash->chip->is_4byte_addr )
+	{
+		cmds[1].writecnt++;
+		cmd[i++] = (addr >> 24) & 0xff;
+	}
+	cmd[i++] = (addr >> 16) & 0xff;
+	cmd[i++] = (addr >>  8) & 0xff;
+	cmd[i++] = (addr >>  0) & 0xff;	
+	
 	if (!len) {
 		msg_cerr("%s called for zero-length write\n", __func__);
 		return 1;
@@ -913,7 +1012,7 @@
 		return 1;
 	}
 
-	memcpy(&cmd[4], bytes, len);
+	memcpy(&cmd[i], bytes, len);
 
 	result = spi_send_multicommand(flash, cmds);
 	if (result) {
@@ -926,15 +1025,23 @@
 int spi_nbyte_read(struct flashctx *flash, unsigned int address, uint8_t *bytes,
 		   unsigned int len)
 {
-	const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
-		JEDEC_READ,
-		(address >> 16) & 0xff,
-		(address >> 8) & 0xff,
-		(address >> 0) & 0xff,
-	};
+	int i = 1;
+	unsigned int cmd_len = JEDEC_READ_OUTSIZE;
+	unsigned char cmd[JEDEC_READ_OUTSIZE+1];
+	
+	cmd[0] = JEDEC_READ;
+	
+	if( flash->chip->is_4byte_addr )
+	{
+		cmd_len++;
+		cmd[i++] = (address >> 24) & 0xff;
+	}
+	cmd[i++] = (address >> 16) & 0xff;
+	cmd[i++] = (address >>  8) & 0xff;
+	cmd[i++] = (address >>  0) & 0xff;
 
 	/* Send Read */
-	return spi_send_command(flash, sizeof(cmd), len, cmd, bytes);
+	return spi_send_command(flash, cmd_len, len, cmd, bytes);
 }
 
 /*
