linux/tools/spi/spidev_fdx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <stdio.h>
   3#include <unistd.h>
   4#include <stdlib.h>
   5#include <fcntl.h>
   6#include <string.h>
   7
   8#include <sys/ioctl.h>
   9#include <sys/types.h>
  10#include <sys/stat.h>
  11
  12#include <linux/types.h>
  13#include <linux/spi/spidev.h>
  14
  15
  16static int verbose;
  17
  18static void do_read(int fd, int len)
  19{
  20        unsigned char   buf[32], *bp;
  21        int             status;
  22
  23        /* read at least 2 bytes, no more than 32 */
  24        if (len < 2)
  25                len = 2;
  26        else if (len > sizeof(buf))
  27                len = sizeof(buf);
  28        memset(buf, 0, sizeof buf);
  29
  30        status = read(fd, buf, len);
  31        if (status < 0) {
  32                perror("read");
  33                return;
  34        }
  35        if (status != len) {
  36                fprintf(stderr, "short read\n");
  37                return;
  38        }
  39
  40        printf("read(%2d, %2d): %02x %02x,", len, status,
  41                buf[0], buf[1]);
  42        status -= 2;
  43        bp = buf + 2;
  44        while (status-- > 0)
  45                printf(" %02x", *bp++);
  46        printf("\n");
  47}
  48
  49static void do_msg(int fd, int len)
  50{
  51        struct spi_ioc_transfer xfer[2];
  52        unsigned char           buf[32], *bp;
  53        int                     status;
  54
  55        memset(xfer, 0, sizeof xfer);
  56        memset(buf, 0, sizeof buf);
  57
  58        if (len > sizeof buf)
  59                len = sizeof buf;
  60
  61        buf[0] = 0xaa;
  62        xfer[0].tx_buf = (unsigned long)buf;
  63        xfer[0].len = 1;
  64
  65        xfer[1].rx_buf = (unsigned long) buf;
  66        xfer[1].len = len;
  67
  68        status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
  69        if (status < 0) {
  70                perror("SPI_IOC_MESSAGE");
  71                return;
  72        }
  73
  74        printf("response(%2d, %2d): ", len, status);
  75        for (bp = buf; len; len--)
  76                printf(" %02x", *bp++);
  77        printf("\n");
  78}
  79
  80static void dumpstat(const char *name, int fd)
  81{
  82        __u8    lsb, bits;
  83        __u32   mode, speed;
  84
  85        if (ioctl(fd, SPI_IOC_RD_MODE32, &mode) < 0) {
  86                perror("SPI rd_mode");
  87                return;
  88        }
  89        if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) {
  90                perror("SPI rd_lsb_fist");
  91                return;
  92        }
  93        if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) {
  94                perror("SPI bits_per_word");
  95                return;
  96        }
  97        if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
  98                perror("SPI max_speed_hz");
  99                return;
 100        }
 101
 102        printf("%s: spi mode 0x%x, %d bits %sper word, %d Hz max\n",
 103                name, mode, bits, lsb ? "(lsb first) " : "", speed);
 104}
 105
 106int main(int argc, char **argv)
 107{
 108        int             c;
 109        int             readcount = 0;
 110        int             msglen = 0;
 111        int             fd;
 112        const char      *name;
 113
 114        while ((c = getopt(argc, argv, "hm:r:v")) != EOF) {
 115                switch (c) {
 116                case 'm':
 117                        msglen = atoi(optarg);
 118                        if (msglen < 0)
 119                                goto usage;
 120                        continue;
 121                case 'r':
 122                        readcount = atoi(optarg);
 123                        if (readcount < 0)
 124                                goto usage;
 125                        continue;
 126                case 'v':
 127                        verbose++;
 128                        continue;
 129                case 'h':
 130                case '?':
 131usage:
 132                        fprintf(stderr,
 133                                "usage: %s [-h] [-m N] [-r N] /dev/spidevB.D\n",
 134                                argv[0]);
 135                        return 1;
 136                }
 137        }
 138
 139        if ((optind + 1) != argc)
 140                goto usage;
 141        name = argv[optind];
 142
 143        fd = open(name, O_RDWR);
 144        if (fd < 0) {
 145                perror("open");
 146                return 1;
 147        }
 148
 149        dumpstat(name, fd);
 150
 151        if (msglen)
 152                do_msg(fd, msglen);
 153
 154        if (readcount)
 155                do_read(fd, readcount);
 156
 157        close(fd);
 158        return 0;
 159}
 160