1 /* Direct spi for RC632 transport layer
2 * (based on openpcd reader)
4 * (C) 2007 by Frederic RODO <f.rodo@til-technologies.fr>
6 * This reader use the Linux's spidev interface, so it need a least
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2
13 * as published by the Free Software Foundation
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include <sys/ioctl.h>
32 #include <linux/types.h>
33 #include <linux/spi/spidev.h>
35 #include <librfid/rfid.h>
36 #include <librfid/rfid_reader.h>
37 #include <librfid/rfid_asic.h>
38 #include <librfid/rfid_asic_rc632.h>
39 #include <librfid/rfid_reader_spidev.h>
40 #include <librfid/rfid_layer2.h>
41 #include <librfid/rfid_protocol.h>
43 #include "rfid_reader_rc632_common.h"
49 struct spi_ioc_transfer xfer[1];
51 /* 256bytes max FSD/FSC, plus 1 bytes header, plus 10 bytes reserve */
52 #define SENDBUF_LEN (256+1+10)
53 #define RECVBUF_LEN SENDBUF_LEN
54 static char snd_buf[SENDBUF_LEN];
55 static char rcv_buf[RECVBUF_LEN];
57 static int spidev_read(unsigned char reg, unsigned char len,
65 snd_buf[0] = (reg<<1) | 0x80;
67 memset(&snd_buf[1], reg<<1 , len-1);
70 /* prepare spi buffer */
71 xfer[0].tx_buf = (__u64) snd_buf;
72 xfer[0].rx_buf = (__u64) rcv_buf;
73 xfer[0].len = len + 1;
75 ret = ioctl(spidev_fd, SPI_IOC_MESSAGE(1), xfer);
77 DEBUGPC("ERROR sending command\n");
79 } else if (ret != (len + 1)) {
80 DEBUGPC("ERROR sending command bad length\n");
84 memcpy(buf, &rcv_buf[1], len);
89 static int spidev_write(unsigned char reg, unsigned char len,
90 const unsigned char *buf)
97 snd_buf[0] = (reg << 1) & 0x7E;
98 memcpy(&snd_buf[1], buf, len);
100 /* prepare spi buffer */
101 xfer[0].tx_buf = (__u64) snd_buf;
102 xfer[0].rx_buf = (__u64) NULL;
103 xfer[0].len = len + 1;
105 ret = ioctl(spidev_fd, SPI_IOC_MESSAGE(1), xfer);
107 DEBUGPC("ERROR sending command\n");
110 else if (ret != len+1)
116 static int spidev_reg_read(struct rfid_asic_transport_handle *rath,
117 unsigned char reg, unsigned char *value)
121 ret = spidev_read(reg, 1, value);
124 DEBUGP("%s reg = 0x%02x, val = 0x%02x\n", __FUNCTION__, reg, *value);
129 static int spidev_reg_write(struct rfid_asic_transport_handle *rath,
130 unsigned char reg, unsigned char value)
134 ret = spidev_write(reg, 1, &value);
138 DEBUGP("%s reg = 0x%02x, val = 0x%02x\n", __FUNCTION__, reg, value);
143 static int spidev_fifo_read(struct rfid_asic_transport_handle *rath,
144 unsigned char len, unsigned char *buf)
148 ret = spidev_read(2, len, buf);
152 DEBUGP("%s len=%u, val=%s\n", __FUNCTION__, len,
153 rfid_hexdump(buf, len));
158 static int spidev_fifo_write(struct rfid_asic_transport_handle *rath,
159 unsigned char len, const unsigned char *buf,
164 ret = spidev_write(2, len, buf);
168 DEBUGP("%s len=%u, data=%s\n", __FUNCTION__, len,
169 rfid_hexdump(buf, len));
174 struct rfid_asic_transport spidev_spi = {
178 .reg_write = &spidev_reg_write,
179 .reg_read = &spidev_reg_read,
180 .fifo_write = &spidev_fifo_write,
181 .fifo_read = &spidev_fifo_read,
186 static struct rfid_reader_handle *spidev_open(void *data)
188 struct rfid_reader_handle *rh;
189 struct rfid_asic_transport_handle *rath;
192 /* open spi device */
194 DEBUGP("No device name\n");
197 if ((spidev_fd = open(data, O_RDWR)) < 0) {
198 DEBUGP("Unable to open:\n");
202 rh = malloc(sizeof(*rh));
206 memset(rh, 0, sizeof(*rh));
208 rath = malloc(sizeof(*rath));
211 memset(rath, 0, sizeof(*rath));
213 rath->rat = &spidev_spi;
214 rh->reader = &rfid_reader_spidev;
216 /* Configure spi device, MODE 0 */
218 if (ioctl(spidev_fd, SPI_IOC_WR_MODE, &tmp) < 0)
223 if (ioctl(spidev_fd, SPI_IOC_WR_LSB_FIRST, &tmp) < 0)
226 /* 8 bits per word */
228 if (ioctl(spidev_fd, SPI_IOC_WR_BITS_PER_WORD, &tmp) < 0)
233 if (ioctl(spidev_fd, SPI_IOC_WR_MAX_SPEED_HZ, &tmp) < 0)
237 rh->ah = rc632_open(rath);
241 /* everything is ok, returning reader handler */
252 static void spidev_close(struct rfid_reader_handle *rh)
254 struct rfid_asic_transport_handle *rath = rh->ah->rath;
269 struct rfid_reader rfid_reader_spidev = {
270 .name = "spidev reader",
271 .id = RFID_READER_SPIDEV,
272 .open = &spidev_open,
273 .close = &spidev_close,
274 .l2_supported = (1 << RFID_LAYER2_ISO14443A) |
275 (1 << RFID_LAYER2_ISO14443B) |
276 (1 << RFID_LAYER2_ISO15693),
277 .proto_supported = (1 << RFID_PROTOCOL_TCL) |
278 (1 << RFID_PROTOCOL_MIFARE_UL) |
279 (1 << RFID_PROTOCOL_MIFARE_CLASSIC),
280 .getopt = &_rdr_rc632_getopt,
281 .setopt = &_rdr_rc632_setopt,
282 .init = &_rdr_rc632_l2_init,
283 .transceive = &_rdr_rc632_transceive,
285 .transceive_sf = &_rdr_rc632_transceive_sf,
286 .transceive_acf = &_rdr_rc632_transceive_acf,
287 .speed = RFID_14443A_SPEED_106K |
288 RFID_14443A_SPEED_212K |
289 RFID_14443A_SPEED_424K,
290 .set_speed = &_rdr_rc632_14443a_set_speed,
293 .transceive_ac = &_rdr_rc632_iso15693_transceive_ac,
296 .setkey = &_rdr_rc632_mifare_setkey,
297 .auth = &_rdr_rc632_mifare_auth,