Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/spi/spidev_fdx.c
26295 views
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
16
static int verbose;
17
18
static 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
49
static 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
80
static 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, %u Hz max\n",
103
name, mode, bits, lsb ? "(lsb first) " : "", speed);
104
}
105
106
int 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 '?':
131
usage:
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
161