Add FT4222H support

The FT4222H features a very different engine compared to what we are
used to from other FTDI USB/serial chips. It doesn't do UART (at least
not officially), doesn't have the MPSSE engine, but has a quad-SPI
master, and SPI/I2C slave support.

A few similarities exist, though, so this could probably make use of
libftdi in the future.

There are two config-mode straps that select one of four modes:
0. 1 data interface + 1 GPIO interface
1. 3 data interfaces + 1 GPIO interface
2. 4 data interfaces
3. 1 data interface

With multiple data interfaces, GPIO pins are muxed as additional CS
lines. The advantage of mode 0 and 3 is that apparently a bigger buffer
is available for the data interface. Only in these modes, it gets to
its full speed (52.8MBps according to the datasheet[1]). The CS line is
automatically selected based on the USB interface used. No test using
multiple interfaces at once were performed, though.

All the USB commands and transfer protocols were derived from traces
gathered with the proprietary LibFT4222. The results are summarized
in the flashprog wiki[2].

[1] https://www.ftdichip.com/old2020/Support/Documents/DataSheets/ICs/DS_FT4222H.pdf
[2] https://flashprog.org/wiki/FT4222H

Change-Id: I9ee1287e13113ccf8b5ea2be4a25866413a94844
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/50
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/helpers.c b/helpers.c
index 27b9cf1..5f2b02d 100644
--- a/helpers.c
+++ b/helpers.c
@@ -21,10 +21,14 @@
 #include "flash.h"
 
 int flashprog_read_chunked(struct flashctx *const flash, uint8_t *dst, unsigned int start, unsigned int len,
-			  const unsigned int chunksize, readfunc_t *const read)
+			   unsigned int chunksize, readfunc_t *const read)
 {
 	int ret;
 	size_t to_read;
+
+	if (chunksize > 256 && chunksize & 3)
+		chunksize &= ~3;
+
 	for (; len; len -= to_read, dst += to_read, start += to_read) {
 		to_read = min(chunksize, len);
 		ret = read(flash, dst, start, to_read);