[PATCH v2 3/8] spi: spidev_test: allow disabling rx or tx buffers
From: Jonas Rebmann
Date: Wed Sep 16 2026 - 13:51:55 EST
From: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx>
Allow not providing rx or tx buffers. This is useful to check if drivers
that don't use SPI_CONTROLLER_MUST_RX (or -TX respectively) handle their
operations correctly without a buffer.
Signed-off-by: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx>
Signed-off-by: Jonas Rebmann <jre@xxxxxxxxxxxxxx>
---
tools/spi/spidev_test.c | 66 ++++++++++++++++++++++++++++++++++---------------
1 file changed, 46 insertions(+), 20 deletions(-)
diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c
index 6ff103bdea5c..b4f9c40a246a 100644
--- a/tools/spi/spidev_test.c
+++ b/tools/spi/spidev_test.c
@@ -47,6 +47,8 @@ static int transfer_size;
static int iterations;
static int interval = 5; /* interval in seconds for showing transfer rate */
static int compare;
+static int do_tx = 1, do_rx = 1;
+static int input_choices = 0;
static uint8_t default_tx[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
@@ -153,7 +155,7 @@ static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
if (ret < 1)
pabort("can't send spi message");
- if (verbose)
+ if (verbose && tx)
hex_dump(tx, len, 32, "TX");
if (output_file) {
@@ -168,13 +170,13 @@ static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
close(out_fd);
}
- if (verbose)
+ if (verbose && rx)
hex_dump(rx, len, 32, "RX");
}
static void print_usage(const char *prog)
{
- printf("Usage: %s [-2348CDFHILMNORSZbcdilopsvw]\n", prog);
+ printf("Usage: %s [-2348CDFHILMNORSZbcdiloprstvw]\n", prog);
puts("general device settings:\n"
" -D --device device to use (default /dev/spidev1.1)\n"
" -s --speed max speed (Hz)\n"
@@ -182,6 +184,8 @@ static void print_usage(const char *prog)
" -w --word-delay word delay (usec)\n"
" -l --loop loopback\n"
" -c --compare compare RX'ed and TX'ed data\n"
+ " -t --no-tx don't send data\n"
+ " -r --no-rx don't receive data\n"
"spi mode:\n"
" -H --cpha clock phase\n"
" -O --cpol clock polarity\n"
@@ -220,6 +224,8 @@ static void parse_opts(int argc, char *argv[])
{ "word-delay", 1, 0, 'w' },
{ "loop", 0, 0, 'l' },
{ "compare", 0, 0, 'c' },
+ { "no-tx", 0, 0, 't' },
+ { "no-rx", 0, 0, 'r' },
{ "cpha", 0, 0, 'H' },
{ "cpol", 0, 0, 'O' },
{ "rx-cpha-flip", 0, 0, 'F' },
@@ -243,7 +249,7 @@ static void parse_opts(int argc, char *argv[])
};
int c;
- c = getopt_long(argc, argv, "D:s:d:w:b:i:o:lcHOLC3ZFMNR248p:vS:I:",
+ c = getopt_long(argc, argv, "D:s:d:w:b:i:o:lctrHOLC3ZFMNR248p:vS:I:",
lopts, NULL);
if (c == -1)
@@ -267,6 +273,7 @@ static void parse_opts(int argc, char *argv[])
break;
case 'i':
input_file = optarg;
+ input_choices++;
break;
case 'o':
output_file = optarg;
@@ -278,6 +285,13 @@ static void parse_opts(int argc, char *argv[])
case 'c':
compare = 1;
break;
+ case 't':
+ do_tx = 0;
+ input_choices++;
+ break;
+ case 'r':
+ do_rx = 0;
+ break;
case 'H':
mode |= SPI_CPHA;
break;
@@ -313,6 +327,7 @@ static void parse_opts(int argc, char *argv[])
break;
case 'p':
input_tx = optarg;
+ input_choices++;
break;
case '2':
mode |= SPI_TX_DUAL;
@@ -415,26 +430,31 @@ static void show_transfer_rate(void)
static void transfer_buf(int fd, int len)
{
- uint8_t *tx;
- uint8_t *rx;
+ uint8_t *tx = NULL;
+ uint8_t *rx = NULL;
int i;
- tx = malloc(len);
- if (!tx)
- pabort("can't allocate tx buffer");
- for (i = 0; i < len; i++)
- tx[i] = random();
+ if (do_tx) {
+ tx = malloc(len);
+ if (!tx)
+ pabort("can't allocate tx buffer");
+ for (i = 0; i < len; i++)
+ tx[i] = random();
+ }
- rx = malloc(len);
- if (!rx)
- pabort("can't allocate rx buffer");
+ if (do_rx) {
+ rx = malloc(len);
+ if (!rx)
+ pabort("can't allocate rx buffer");
+ }
transfer(fd, tx, rx, len);
+ if (do_tx)
+ _write_count += len;
+ if (do_rx)
+ _read_count += len;
- _write_count += len;
- _read_count += len;
-
- if (compare) {
+ if (tx && rx && compare) {
if (memcmp(tx, rx, len)) {
fprintf(stderr, "transfer error !\n");
hex_dump(tx, len, 32, "TX");
@@ -455,8 +475,14 @@ int main(int argc, char *argv[])
parse_opts(argc, argv);
- if (input_tx && input_file)
- pabort("only one of -p and --input may be selected");
+ if (input_choices > 1)
+ pabort("only one of -p, -i (--input), -t (--no-tx) may be selected");
+
+ if (compare && (!do_tx || !do_rx))
+ pabort("-l/-c (--loop/--compare) conflict with -t (--no-tx) or -r (--no-rx)");
+
+ if (!do_rx && output_file)
+ pabort("-t (--no-rx) conflicts with -o (--output)");
if (compare & (SPI_TX_OCTAL | SPI_TX_QUAD | SPI_TX_DUAL))
pabort("-c (--compare) conflicts with -2 (--dual), -4 (--quad) or -8 (--octal)");
--
2.56.0.rc0.108.gf0ef1b96a0