* implement rfid_reader_{get,set}opt()
[librfid] / src / rfid_reader_spidev.c
1 /* Direct spi for RC632 transport layer
2  * (based on openpcd reader)
3  *
4  * (C) 2007 by Frederic RODO <f.rodo@til-technologies.fr>
5  *
6  * This reader use the Linux's spidev interface, so it need a least
7  * kernel 2.6.22
8  */
9
10 /*
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
14  *
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.
19  *
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
23  */
24
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <errno.h>
29
30 #include <fcntl.h>
31 #include <sys/ioctl.h>
32 #include <linux/types.h>
33 #include <linux/spi/spidev.h>
34
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>
42
43 #include "rfid_reader_rc632_common.h"
44
45 /* FIXME */
46 #include "rc632.h"
47 static int spidev_fd;
48
49 struct spi_ioc_transfer xfer[1];
50
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];
56
57 static int spidev_read(unsigned char reg, unsigned char len,
58                        unsigned char *buf)
59 {
60         int ret;
61
62         if (!len)
63                 return -EINVAL;
64
65         snd_buf[0] = (reg<<1) | 0x80;
66         if (len > 1)
67                 memset(&snd_buf[1], reg<<1 , len-1);
68         snd_buf[len] = 0;
69
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;
74
75         ret = ioctl(spidev_fd, SPI_IOC_MESSAGE(1), xfer);
76         if (ret < 0) {
77                 DEBUGPC("ERROR sending command\n");
78                 return ret;
79         } else if (ret != (len + 1)) {
80                 DEBUGPC("ERROR sending command bad length\n");
81                 return -EINVAL;
82         }
83
84         memcpy(buf, &rcv_buf[1], len);
85
86         return len;
87 }
88
89 static int spidev_write(unsigned char reg, unsigned char len,
90                        const unsigned char *buf)
91 {
92         int ret;
93
94         if (!len)
95                 return -EINVAL;
96
97         snd_buf[0] = (reg << 1) & 0x7E;
98         memcpy(&snd_buf[1], buf, len);
99
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;
104
105         ret = ioctl(spidev_fd, SPI_IOC_MESSAGE(1), xfer);
106         if (ret < 0) {
107                 DEBUGPC("ERROR sending command\n");
108                 return ret;
109         }
110         else if (ret != len+1)
111                 return -EINVAL;
112
113         return len;
114 }
115
116 static int spidev_reg_read(struct rfid_asic_transport_handle *rath,
117                            unsigned char reg, unsigned char *value)
118 {
119         int ret;
120
121         ret = spidev_read(reg, 1, value);
122         if (ret < 0)
123                 return ret;
124         DEBUGP("%s reg = 0x%02x, val = 0x%02x\n", __FUNCTION__, reg, *value);
125
126         return 1;
127 }
128
129 static int spidev_reg_write(struct rfid_asic_transport_handle *rath,
130                             unsigned char reg, unsigned char value)
131 {
132         int ret;
133
134         ret = spidev_write(reg, 1, &value);
135         if (ret < 0)
136                 return ret;
137
138         DEBUGP("%s reg = 0x%02x, val = 0x%02x\n", __FUNCTION__, reg, value);
139
140         return 1;
141 }
142
143 static int spidev_fifo_read(struct rfid_asic_transport_handle *rath,
144                             unsigned char len, unsigned char *buf)
145 {
146         int ret;
147
148         ret = spidev_read(2, len, buf);
149         if (ret < 0)
150                 return ret;
151
152         DEBUGP("%s len=%u, val=%s\n", __FUNCTION__, len,
153                rfid_hexdump(buf, len));
154
155         return len;
156 }
157
158 static int spidev_fifo_write(struct rfid_asic_transport_handle *rath,
159                              unsigned char len, const unsigned char *buf,
160                              unsigned char flags)
161 {
162         int ret;
163
164         ret = spidev_write(2, len, buf);
165         if (ret < 0)
166                 return ret;
167
168         DEBUGP("%s len=%u, data=%s\n", __FUNCTION__, len,
169                rfid_hexdump(buf, len));
170
171         return len;
172 }
173
174 struct rfid_asic_transport spidev_spi = {
175         .name = "spidev",
176         .priv.rc632 = {
177                 .fn = {
178                         .reg_write = &spidev_reg_write,
179                         .reg_read = &spidev_reg_read,
180                         .fifo_write = &spidev_fifo_write,
181                         .fifo_read = &spidev_fifo_read,
182                 },
183         },
184 };
185
186 static struct rfid_reader_handle *spidev_open(void *data)
187 {
188         struct rfid_reader_handle *rh;
189         struct rfid_asic_transport_handle *rath;
190         __u32 tmp;
191
192         /* open spi device */
193         if (!data) {
194                 DEBUGP("No device name\n");
195                 return NULL;
196         }
197         if ((spidev_fd = open(data, O_RDWR)) < 0) {
198                 DEBUGP("Unable to open:\n");
199                 return NULL;
200         }
201
202         rh = malloc(sizeof(*rh));
203         if (!rh)
204                 goto out_close_spi;
205
206         memset(rh, 0, sizeof(*rh));
207
208         rath = malloc(sizeof(*rath));
209         if (!rath)
210                 goto out_rh;
211         memset(rath, 0, sizeof(*rath));
212
213         rath->rat = &spidev_spi;
214         rh->reader = &rfid_reader_spidev;
215
216         /* Configure spi device, MODE 0 */
217         tmp = SPI_MODE_0;
218         if (ioctl(spidev_fd, SPI_IOC_WR_MODE, &tmp) < 0)
219                 goto out_rath;
220
221         /* MSB First */
222         tmp = 0;
223         if (ioctl(spidev_fd, SPI_IOC_WR_LSB_FIRST, &tmp) < 0)
224                 goto out_rath;
225
226         /* 8 bits per word */
227         tmp = 8;
228         if (ioctl(spidev_fd, SPI_IOC_WR_BITS_PER_WORD, &tmp) < 0)
229                 goto out_rath;
230
231         /* 1 MHz */
232         tmp = 1e6;
233         if (ioctl(spidev_fd, SPI_IOC_WR_MAX_SPEED_HZ, &tmp) < 0)
234                 goto out_rath;
235
236         /* turn on rc632 */
237         rh->ah = rc632_open(rath);
238         if (!rh->ah)
239                 goto out_rath;
240
241         /* everything is ok, returning reader handler */
242         return rh;
243 out_rath:
244         free(rath);
245 out_rh:
246         free(rh);
247 out_close_spi:
248         close(spidev_fd);
249         return NULL;
250 }
251
252 static void spidev_close(struct rfid_reader_handle *rh)
253 {
254         struct rfid_asic_transport_handle *rath = rh->ah->rath;
255
256         if (rh->ah)
257                 rc632_close(rh->ah);
258
259         if (spidev_fd > 0)
260                 close(spidev_fd);
261
262         if (rath)
263                 free(rath);
264
265         if (rh)
266                 free(rh);
267 }
268
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,
284         .iso14443a = {
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,
291         },
292         .iso15693 = {
293                      .transceive_ac = &_rdr_rc632_iso15693_transceive_ac,
294         },
295         .mifare_classic = {
296                 .setkey = &_rdr_rc632_mifare_setkey,
297                 .auth = &_rdr_rc632_mifare_auth,
298         },
299 };
300