brintos

brintos / linux-shallow public Read only

0
0
Text · 2.7 KiB · bc9c4f6 Raw
160 lines · c
1// SPDX-License-Identifier: GPL-2.02#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, %u 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