Nico Huber submitted this change.

View Change

Approvals: build bot (Jenkins): Verified Nico Huber: Looks good to me, approved
ft2232_spi: reintroduce generic GPIOL control

This reintroduces a reworked version of the GPIOL pin control first
introduced in commit 3207844 (CB:49637), which was reverted in commit
6518cf3 (CB:55692) due to breakage.

This change introduces a new argument `gpiolX` to allow use of the four
GPIOL pins either as generic gpios or as additional CS# signal(s). `X`
specifies the GPIOL pin (0-3) to be set to one of [HLC] with the
following meaning:

* H - set the pin as output high
* L - set the pin as output low
* C - use the pin as additional CS# signal

The third value, `C`, aims to replace the parameter `csgpiol`, that is
now marked as deprecated and can be removed at some point in the future.
`gpiol` and `csgpiol` are mutually exclusive and use of both results in
an error.

Multiple pins may be set by specifying the parameter multiple times.

Documentation was updated/added accordingly.

Test: All pin levels/modes have been verified to behave correctly with a
logic analyzer.

Change-Id: I3989f0f9596c090de52dca67183b1363dae59d3a
Signed-off-by: Alan Green <avg@google.com>
Signed-off-by: Michael Niewöhner <foss@mniewoehner.de>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/57810
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
---
M flashrom.8.tmpl
M ft2232_spi.c
2 files changed, 109 insertions(+), 9 deletions(-)

diff --git a/flashrom.8.tmpl b/flashrom.8.tmpl
index de93453..989d677 100644
--- a/flashrom.8.tmpl
+++ b/flashrom.8.tmpl
@@ -883,12 +883,42 @@
syntax.
.sp
Using the parameter
-.B csgpiol
+.B csgpiol (DEPRECATED - use gpiol instead)
an additional CS# pin can be chosen, where the value can be a number between 0 and 3, denoting GPIOL0-GPIOL3
correspondingly. Example:
.sp
.B " flashrom \-p ft2232_spi:csgpiol=3"
.sp
+The parameter
+.B gpiolX=[HLC]
+allows use of the GPIOL pins either as generic gpios with a fixed value during flashing or as addtional CS#
+signal, where
+.B X
+can be a number between 0 and 3, denoting GPIOL0-GPIOL3 correspondingly. The parameter may be specified
+multiple times, one time per GPIOL pin.
+Valid values are
+.B H
+,
+.B L
+and
+.B C
+:
+.br
+.B " H "
+- Set GPIOL output high
+.br
+.B " L "
+- Set GPIOL output low
+.br
+.B " C "
+- Use GPIOL as additional CS# output
+.sp
+.B Example:
+.sp
+.B " flashrom \-p ft2232_spi:gpiol0=H"
+.sp
+.B Note
+that not all GPIOL pins are freely usable with all programmers as some have special functionality.
.SS
.BR "serprog " programmer
.IP
diff --git a/ft2232_spi.c b/ft2232_spi.c
index 110bdec..65326f9 100644
--- a/ft2232_spi.c
+++ b/ft2232_spi.c
@@ -91,9 +91,10 @@
* to high and will be toggled during SPI transactions. All other
* output pins will be kept low all the time. For some programmers,
* some reserved GPIOL* pins are used as outputs. Free GPIOL* pins
- * are configured as inputs, while it's possible to use one of them
- * as additional CS# signal through the parameter `csgpiol`. On exit,
- * all pins will be reconfigured as inputs.
+ * are configured as inputs, while it's possible to use them either
+ * as generic gpios or as additional CS# signal(s) through the
+ * parameter(s) `gpiolX`. On exit, all pins will be reconfigured
+ * as inputs.
*
* The pin offsets are as follows:
* TCK/SK is bit 0.
@@ -112,6 +113,7 @@
*/
struct ft2232_data {
uint8_t cs_bits;
+ uint8_t aux_bits;
uint8_t pindir;
struct ftdi_context ftdic_context;
};
@@ -233,7 +235,8 @@

msg_pspew("Assert CS#\n");
buf[i++] = SET_BITS_LOW;
- buf[i++] = 0; /* assert CS# pins, all other output pins stay low */
+ /* assert CS# pins, keep aux_bits, all other output pins stay low */
+ buf[i++] = spi_data->aux_bits;
buf[i++] = spi_data->pindir;

/* WREN, OP(PROGRAM, ERASE), ADDR, DATA */
@@ -255,7 +258,7 @@
/* Add final de-assert CS# */
msg_pspew("De-assert CS#\n");
buf[i++] = SET_BITS_LOW;
- buf[i++] = spi_data->cs_bits;
+ buf[i++] = spi_data->cs_bits | spi_data->aux_bits;
buf[i++] = spi_data->pindir;

/* continue if there is no read-cmd and further cmds exist */
@@ -325,6 +328,7 @@
double mpsse_clk;

uint8_t cs_bits = 0x08;
+ uint8_t aux_bits = 0x00;
uint8_t pindir = 0x0b;
struct ftdi_context ftdic;
struct ft2232_data *spi_data;
@@ -470,8 +474,13 @@
}
free(arg);

+ bool csgpiol_set = false;
arg = extract_programmer_param("csgpiol");
if (arg) {
+ csgpiol_set = true;
+ msg_pwarn("Deprecation warning: `csgpiol` is deprectated and will be removed "
+ "in the future.\nUse `gpiolX=C` instead.\n");
+
char *endptr;
unsigned int temp = strtoul(arg, &endptr, 10);
if (*endptr || endptr == arg || temp > 3) {
@@ -480,8 +489,8 @@
free(arg);
return -2;
}
- unsigned int pin = temp + 4;

+ unsigned int pin = temp + 4;
if (rsv_bits & 1 << pin) {
msg_perr("Error: Invalid GPIOL specified: \"%s\".\n"
"The pin is reserved on this programmer.\n",
@@ -491,10 +500,70 @@
}

cs_bits |= 1 << pin;
- pindir |= 1 << pin;
+ pindir |= 1 << pin;
}
free(arg);

+ /* gpiolX */
+ for (int pin = 0; pin < 4; pin++) {
+ char gpiol_param[7];
+ snprintf(gpiol_param, sizeof(gpiol_param), "gpiol%d", pin);
+ arg = extract_programmer_param(gpiol_param);
+
+ if (!arg)
+ continue;
+
+ if (csgpiol_set) {
+ msg_perr("Error: `csgpiol` and `gpiolX` are mutually exclusive.\n"
+ "Since `csgpiol` is deprecated and will be removed in the "
+ "future, use of `gpiolX=C` is recommended.\n");
+ free(arg);
+ return -2;
+ }
+
+ uint8_t bit = 1 << (pin + 4);
+ if (rsv_bits & bit) {
+ msg_perr("Error: Invalid GPIOL specified: \"gpiol%d=%s\".\n"
+ "Pin GPIOL%i is reserved on this programmer.\n",
+ pin, arg, pin);
+ free(arg);
+ return -2;
+ }
+
+ if (strlen(arg) != 1)
+ goto format_error;
+
+ switch (toupper(arg[0])) {
+ case 'H':
+ aux_bits |= bit;
+ pindir |= bit;
+ break;
+ case 'L':
+ pindir |= bit;
+ break;
+ case 'C':
+ cs_bits |= bit;
+ pindir |= bit;
+ break;
+ default:
+ goto format_error;
+ }
+
+ free(arg);
+ continue;
+
+format_error:
+ msg_perr("Error: Invalid GPIOL specified: \"gpiol%d=%s\".\n"
+ "Valid values are H, L and C.\n"
+ " H - Set GPIOL output high\n"
+ " L - Set GPIOL output low\n"
+ " C - Use GPIOL as additional CS# output\n",
+ pin, arg);
+
+ free(arg);
+ return -2;
+ }
+
msg_pdbg("Using device type %s %s ",
get_ft2232_vendorname(ft2232_vid, ft2232_type),
get_ft2232_devicename(ft2232_vid, ft2232_type));
@@ -577,7 +646,7 @@

msg_pdbg("Set data bits\n");
buf[0] = SET_BITS_LOW;
- buf[1] = cs_bits;
+ buf[1] = cs_bits | aux_bits;
buf[2] = pindir;
if (send_buf(&ftdic, buf, 3)) {
ret = -8;
@@ -590,6 +659,7 @@
return SPI_GENERIC_ERROR;
}
spi_data->cs_bits = cs_bits;
+ spi_data->aux_bits = aux_bits;
spi_data->pindir = pindir;
spi_data->ftdic_context = ftdic;


To view, visit change 57810. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I3989f0f9596c090de52dca67183b1363dae59d3a
Gerrit-Change-Number: 57810
Gerrit-PatchSet: 19
Gerrit-Owner: Michael Niewöhner <foss@mniewoehner.de>
Gerrit-Reviewer: Felix Singer <felixsinger@posteo.net>
Gerrit-Reviewer: Alan Green <avg@google.com>
Gerrit-Reviewer: Angel Pons <th3fanbus@gmail.com>
Gerrit-Reviewer: Nico Huber <nico.h@gmx.de>
Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org>
Gerrit-CC: Paul Menzel <paulepanter@mailbox.org>
Gerrit-MessageType: merged