spi25: Introduce generic spi_prepare_io()/spi_finish_io()

Introduce two new functions to be hooked up in the chip database:
* spi_prepare_io(), and
* spi_finish_io().

These will be used to prepare multi-i/o and QPI operations. Hence,
hook them up to all the chips that support those. spi_prepare_4ba()
is wrapped to account for overlaps with 4BA support.

Change-Id: I444f6322b6d6a26a040cb0ca972b2c411838d702
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/163
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/flashchips.c b/flashchips.c
index 32fce30..8f06019 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -1407,6 +1407,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -2473,6 +2475,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -3617,6 +3621,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -5250,6 +5256,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -5292,6 +5300,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -5344,6 +5354,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -5389,6 +5401,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -5441,6 +5455,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25_64k_block,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -5484,6 +5500,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -5564,6 +5582,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -5644,6 +5664,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -5721,6 +5743,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6235,6 +6259,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6280,6 +6306,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6325,6 +6353,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6573,6 +6603,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6627,6 +6659,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6671,6 +6705,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1695, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6715,6 +6751,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1695, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6759,6 +6797,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1695, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6813,6 +6853,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6857,6 +6899,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1695, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6899,6 +6943,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -6953,6 +6999,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7005,6 +7053,8 @@
 			.cmp    = {STATUS2, 6, RW},
 		},
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7048,6 +7098,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7089,6 +7141,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7150,7 +7204,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7204,6 +7259,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7246,6 +7303,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7285,6 +7344,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7338,6 +7399,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7381,6 +7444,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7464,6 +7529,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2300, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7508,6 +7575,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2300, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7552,6 +7621,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2300, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7596,6 +7667,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2300, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7640,6 +7713,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2300, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7682,6 +7757,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -7911,7 +7988,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2300, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -8091,7 +8169,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 1950},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -8831,6 +8910,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -8913,6 +8994,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -8988,6 +9071,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9024,6 +9109,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9065,6 +9152,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9106,6 +9195,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9145,6 +9236,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9200,7 +9293,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9272,6 +9366,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9311,6 +9407,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9352,6 +9450,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9395,6 +9495,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600}, /* 33F 2.65V..3.6V */
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9434,6 +9536,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9584,6 +9688,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9624,6 +9730,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9671,6 +9779,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9793,6 +9903,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9836,6 +9948,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9887,6 +10001,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read,
 		.voltage	= {1650, 2000},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9937,6 +10053,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 2000},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -9993,7 +10111,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read,
 		.voltage	= {1650, 2000},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -10045,6 +10164,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 2000},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -10101,7 +10222,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read,
 		.voltage	= {1650, 2000},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -10153,6 +10275,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 2000},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -10198,6 +10322,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 2000},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -10726,7 +10852,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read, /* Fast read (0x0B) supported */
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -10776,7 +10903,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read, /* Fast read (0x0B) supported */
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	/* The ST M25P05 is a bit of a problem. It has the same ID as the
@@ -11631,7 +11759,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {1700, 2000},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -11672,7 +11801,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12010,7 +12140,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {1700, 2000},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12051,7 +12182,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12092,7 +12224,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {1700, 2000},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12133,7 +12266,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12180,7 +12314,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12227,7 +12362,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {1700, 2000},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12274,7 +12410,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12321,7 +12458,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {1700, 2000},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12451,7 +12589,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12501,7 +12640,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {1700, 2000},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12561,7 +12701,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -12611,7 +12752,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {1700, 2000},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -17521,7 +17663,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -17568,7 +17711,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -17606,7 +17750,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported, IGNORE for now */
 		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18050,6 +18195,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18103,6 +18250,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18158,6 +18307,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18211,6 +18362,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18255,6 +18408,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18299,6 +18454,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1700, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18343,6 +18500,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1700, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18400,7 +18559,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18460,7 +18620,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18522,7 +18683,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18574,7 +18736,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 1950},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18645,7 +18808,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18700,6 +18864,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18757,6 +18923,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18813,6 +18981,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18869,6 +19039,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18923,6 +19095,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -18979,6 +19153,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19034,6 +19210,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19091,6 +19269,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19135,6 +19315,8 @@
 		.write		= spi_chip_write_256, /* Multi I/O supported */
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19178,6 +19360,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1700, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19223,6 +19407,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19272,7 +19458,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19336,7 +19523,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19392,6 +19580,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19448,6 +19638,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19493,6 +19685,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19546,6 +19740,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19601,6 +19797,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19658,6 +19856,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19702,6 +19902,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19745,6 +19947,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1700, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19790,6 +19994,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19823,6 +20029,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2300, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19856,6 +20064,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19894,6 +20104,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19927,6 +20139,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19965,6 +20179,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -19998,6 +20214,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -20036,6 +20254,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -20069,6 +20289,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	/* W29EE011, W29EE012, W29C010M, W29C011A do not support probe_jedec according to the datasheet, but it works for newer(?) steppings. */
@@ -20996,6 +21218,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -21055,7 +21279,8 @@
 		.wp_read_cfg	= spi_wp_read_cfg,
 		.wp_get_ranges	= spi_wp_get_available_ranges,
 		.decode_range	= decode_range_spi25,
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -21099,6 +21324,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {2700, 3600},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -21143,6 +21370,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -21194,7 +21423,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 1950},
-		.prepare_access	= spi_prepare_4ba,
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
@@ -21238,6 +21468,8 @@
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 		.voltage	= {1650, 1950},
+		.prepare_access	= spi_prepare_io,
+		.finish_access	= spi_finish_io,
 	},
 
 	{
diff --git a/flashprog.c b/flashprog.c
index 704fd2e..ec19f46 100644
--- a/flashprog.c
+++ b/flashprog.c
@@ -1539,6 +1539,16 @@
 					 "Please report a bug at flashprog@flashprog.org\n", i,
 					 chip->name == NULL ? "unnamed" : chip->name);
 			}
+			if (chip->feature_bits &
+			    (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_ENTER_EAR7 |
+			     FEATURE_ANY_DUAL | FEATURE_ANY_QUAD)
+			    && !chip->prepare_access) {
+				msg_gerr("ERROR: Flash chip #%d (%s) misses chip\n"
+					 "preparation function for 4BA and multi-i/o modes.\n"
+					 "Please report a bug at flashprog@flashprog.org\n", i,
+					 chip->name == NULL ? "unnamed" : chip->name);
+				ret = 1;
+			}
 			if (selfcheck_eraseblocks(chip)) {
 				ret = 1;
 			}
diff --git a/include/chipdrivers.h b/include/chipdrivers.h
index 272b65c..94db44b 100644
--- a/include/chipdrivers.h
+++ b/include/chipdrivers.h
@@ -61,7 +61,8 @@
 int spi_set_extended_address(struct flashctx *, uint8_t addr_high);
 
 /* spi25_prepare.c */
-int spi_prepare_4ba(struct flashctx *, enum preparation_steps);
+int spi_prepare_io(struct flashctx *, enum preparation_steps);
+void spi_finish_io(struct flashctx *);
 
 
 /* spi25_statusreg.c */
diff --git a/include/flash.h b/include/flash.h
index 0b34184..da73df5 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -171,6 +171,11 @@
 #define FEATURE_QPI_38		(FEATURE_QIO | FEATURE_QPI_38_FF)
 #define FEATURE_QPI_SRP		(FEATURE_QPI_38 | FEATURE_SET_READ_PARAMS)
 
+/* Catch all dual/quad features to be able to mask them */
+#define FEATURE_ANY_DUAL	(FEATURE_FAST_READ_DOUT | FEATURE_FAST_READ_DIO)
+#define FEATURE_ANY_QUAD	(FEATURE_QPI_35_F5 | FEATURE_QPI_38_FF | \
+				 FEATURE_FAST_READ_QOUT | FEATURE_FAST_READ_QIO | FEATURE_FAST_READ_QPI4B)
+
 #define ERASED_VALUE(flash)	(((flash)->chip->feature_bits & FEATURE_ERASED_ZERO) ? 0x00 : 0xff)
 
 enum test_state {
diff --git a/spi25_prepare.c b/spi25_prepare.c
index 7fb1a10..76ad9a7 100644
--- a/spi25_prepare.c
+++ b/spi25_prepare.c
@@ -46,11 +46,8 @@
 	return spi_enter_exit_4ba(flash, false);
 }
 
-int spi_prepare_4ba(struct flashctx *const flash, const enum preparation_steps prep)
+static int spi_prepare_4ba(struct flashctx *const flash)
 {
-	if (prep != PREPARE_FULL)
-		return 0;
-
 	flash->address_high_byte = -1;
 	flash->in_4ba_mode = false;
 
@@ -79,3 +76,19 @@
 
 	return 0;
 }
+
+int spi_prepare_io(struct flashctx *const flash, const enum preparation_steps prep)
+{
+	if (prep != PREPARE_FULL)
+		return 0;
+
+	int ret = spi_prepare_4ba(flash);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+void spi_finish_io(struct flashctx *const flash)
+{
+}