Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.29 202 lines 4.2 kB view raw
1/* 2 * SPI testing utility (using spidev driver) 3 * 4 * Copyright (c) 2007 MontaVista Software, Inc. 5 * Copyright (c) 2007 Anton Vorontsov <avorontsov@ru.mvista.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License. 10 * 11 * Cross-compile with cross-gcc -I/path/to/cross-kernel/include 12 */ 13 14#include <stdint.h> 15#include <unistd.h> 16#include <stdio.h> 17#include <stdlib.h> 18#include <getopt.h> 19#include <fcntl.h> 20#include <sys/ioctl.h> 21#include <linux/types.h> 22#include <linux/spi/spidev.h> 23 24#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 25 26static void pabort(const char *s) 27{ 28 perror(s); 29 abort(); 30} 31 32static const char *device = "/dev/spidev1.1"; 33static uint8_t mode; 34static uint8_t bits = 8; 35static uint32_t speed = 500000; 36static uint16_t delay; 37 38static void transfer(int fd) 39{ 40 int ret; 41 uint8_t tx[] = { 42 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 43 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, 44 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 45 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 46 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 47 0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 48 0xF0, 0x0D, 49 }; 50 uint8_t rx[ARRAY_SIZE(tx)] = {0, }; 51 struct spi_ioc_transfer tr = { 52 .tx_buf = (unsigned long)tx, 53 .rx_buf = (unsigned long)rx, 54 .len = ARRAY_SIZE(tx), 55 .delay_usecs = delay, 56 .speed_hz = speed, 57 .bits_per_word = bits, 58 }; 59 60 ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); 61 if (ret == 1) 62 pabort("can't send spi message"); 63 64 for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { 65 if (!(ret % 6)) 66 puts(""); 67 printf("%.2X ", rx[ret]); 68 } 69 puts(""); 70} 71 72void print_usage(const char *prog) 73{ 74 printf("Usage: %s [-DsbdlHOLC3]\n", prog); 75 puts(" -D --device device to use (default /dev/spidev1.1)\n" 76 " -s --speed max speed (Hz)\n" 77 " -d --delay delay (usec)\n" 78 " -b --bpw bits per word \n" 79 " -l --loop loopback\n" 80 " -H --cpha clock phase\n" 81 " -O --cpol clock polarity\n" 82 " -L --lsb least significant bit first\n" 83 " -C --cs-high chip select active high\n" 84 " -3 --3wire SI/SO signals shared\n"); 85 exit(1); 86} 87 88void parse_opts(int argc, char *argv[]) 89{ 90 while (1) { 91 static const struct option lopts[] = { 92 { "device", 1, 0, 'D' }, 93 { "speed", 1, 0, 's' }, 94 { "delay", 1, 0, 'd' }, 95 { "bpw", 1, 0, 'b' }, 96 { "loop", 0, 0, 'l' }, 97 { "cpha", 0, 0, 'H' }, 98 { "cpol", 0, 0, 'O' }, 99 { "lsb", 0, 0, 'L' }, 100 { "cs-high", 0, 0, 'C' }, 101 { "3wire", 0, 0, '3' }, 102 { NULL, 0, 0, 0 }, 103 }; 104 int c; 105 106 c = getopt_long(argc, argv, "D:s:d:b:lHOLC3", lopts, NULL); 107 108 if (c == -1) 109 break; 110 111 switch (c) { 112 case 'D': 113 device = optarg; 114 break; 115 case 's': 116 speed = atoi(optarg); 117 break; 118 case 'd': 119 delay = atoi(optarg); 120 break; 121 case 'b': 122 bits = atoi(optarg); 123 break; 124 case 'l': 125 mode |= SPI_LOOP; 126 break; 127 case 'H': 128 mode |= SPI_CPHA; 129 break; 130 case 'O': 131 mode |= SPI_CPOL; 132 break; 133 case 'L': 134 mode |= SPI_LSB_FIRST; 135 break; 136 case 'C': 137 mode |= SPI_CS_HIGH; 138 break; 139 case '3': 140 mode |= SPI_3WIRE; 141 break; 142 default: 143 print_usage(argv[0]); 144 break; 145 } 146 } 147} 148 149int main(int argc, char *argv[]) 150{ 151 int ret = 0; 152 int fd; 153 154 parse_opts(argc, argv); 155 156 fd = open(device, O_RDWR); 157 if (fd < 0) 158 pabort("can't open device"); 159 160 /* 161 * spi mode 162 */ 163 ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); 164 if (ret == -1) 165 pabort("can't set spi mode"); 166 167 ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); 168 if (ret == -1) 169 pabort("can't get spi mode"); 170 171 /* 172 * bits per word 173 */ 174 ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); 175 if (ret == -1) 176 pabort("can't set bits per word"); 177 178 ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); 179 if (ret == -1) 180 pabort("can't get bits per word"); 181 182 /* 183 * max speed hz 184 */ 185 ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); 186 if (ret == -1) 187 pabort("can't set max speed hz"); 188 189 ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); 190 if (ret == -1) 191 pabort("can't get max speed hz"); 192 193 printf("spi mode: %d\n", mode); 194 printf("bits per word: %d\n", bits); 195 printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); 196 197 transfer(fd); 198 199 close(fd); 200 201 return ret; 202}