spidev_fdx.c 2.7 KB

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