blob: 5f3459d11e73d7f63fb0dab64408be1c1e482298 [file] [log] [blame]
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001/*
2 * Copyright (C) 2011 Instituto Nokia de Tecnologia
3 *
4 * Authors:
5 * Lauro Ramos Venancio <lauro.venancio@openbossa.org>
6 * Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the
20 * Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <linux/device.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/slab.h>
28#include <linux/usb.h>
29#include <linux/nfc.h>
30#include <linux/netdevice.h>
Ilan Elias55eb94f2011-09-18 11:19:34 +030031#include <net/nfc/nfc.h>
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -030032
33#define VERSION "0.1"
34
35#define PN533_VENDOR_ID 0x4CC
36#define PN533_PRODUCT_ID 0x2533
37
38#define SCM_VENDOR_ID 0x4E6
39#define SCL3711_PRODUCT_ID 0x5591
40
Samuel Ortiz5c7b0532012-07-02 20:04:01 +020041#define SONY_VENDOR_ID 0x054c
42#define PASORI_PRODUCT_ID 0x02e1
43
Samuel Ortiz5c7b0532012-07-02 20:04:01 +020044#define PN533_DEVICE_STD 0x1
45#define PN533_DEVICE_PASORI 0x2
46
Samuel Ortiz01d719a2012-07-04 00:14:04 +020047#define PN533_ALL_PROTOCOLS (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK |\
48 NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK |\
49 NFC_PROTO_NFC_DEP_MASK |\
50 NFC_PROTO_ISO14443_B_MASK)
Samuel Ortiz5c7b0532012-07-02 20:04:01 +020051
52#define PN533_NO_TYPE_B_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
53 NFC_PROTO_MIFARE_MASK | \
54 NFC_PROTO_FELICA_MASK | \
Samuel Ortiz01d719a2012-07-04 00:14:04 +020055 NFC_PROTO_ISO14443_MASK | \
Samuel Ortiz5c7b0532012-07-02 20:04:01 +020056 NFC_PROTO_NFC_DEP_MASK)
57
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -030058static const struct usb_device_id pn533_table[] = {
Samuel Ortiz5c7b0532012-07-02 20:04:01 +020059 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
60 .idVendor = PN533_VENDOR_ID,
61 .idProduct = PN533_PRODUCT_ID,
62 .driver_info = PN533_DEVICE_STD,
63 },
64 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
65 .idVendor = SCM_VENDOR_ID,
66 .idProduct = SCL3711_PRODUCT_ID,
67 .driver_info = PN533_DEVICE_STD,
68 },
69 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
70 .idVendor = SONY_VENDOR_ID,
71 .idProduct = PASORI_PRODUCT_ID,
72 .driver_info = PN533_DEVICE_PASORI,
73 },
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -030074 { }
75};
76MODULE_DEVICE_TABLE(usb, pn533_table);
77
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +020078/* How much time we spend listening for initiators */
79#define PN533_LISTEN_TIME 2
80
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -030081/* frame definitions */
Waldemar Rymarkiewicz82dec342012-10-11 14:03:58 +020082#define PN533_NORMAL_FRAME_MAX_LEN 262 /* 6 (PREAMBLE, SOF, LEN, LCS, TFI)
83 254 (DATA)
84 2 (DCS, postamble) */
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +010085#define PN533_FRAME_HEADER_LEN (sizeof(struct pn533_frame) \
86 + 2) /* data[0] TFI, data[1] CC */
87#define PN533_FRAME_TAIL_LEN 2 /* data[len] DCS, data[len + 1] postamble*/
Waldemar Rymarkiewicz82dec342012-10-11 14:03:58 +020088
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -030089#define PN533_FRAME_SIZE(f) (sizeof(struct pn533_frame) + f->datalen + \
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +010090 PN533_FRAME_TAIL_LEN)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -030091#define PN533_FRAME_ACK_SIZE (sizeof(struct pn533_frame) + 1)
92#define PN533_FRAME_CHECKSUM(f) (f->data[f->datalen])
93#define PN533_FRAME_POSTAMBLE(f) (f->data[f->datalen + 1])
94
95/* start of frame */
96#define PN533_SOF 0x00FF
97
98/* frame identifier: in/out/error */
99#define PN533_FRAME_IDENTIFIER(f) (f->data[0])
100#define PN533_DIR_OUT 0xD4
101#define PN533_DIR_IN 0xD5
102
103/* PN533 Commands */
104#define PN533_FRAME_CMD(f) (f->data[1])
105#define PN533_FRAME_CMD_PARAMS_PTR(f) (&f->data[2])
106#define PN533_FRAME_CMD_PARAMS_LEN(f) (f->datalen - 2)
107
108#define PN533_CMD_GET_FIRMWARE_VERSION 0x02
109#define PN533_CMD_RF_CONFIGURATION 0x32
110#define PN533_CMD_IN_DATA_EXCHANGE 0x40
Samuel Ortiz5c7b0532012-07-02 20:04:01 +0200111#define PN533_CMD_IN_COMM_THRU 0x42
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300112#define PN533_CMD_IN_LIST_PASSIVE_TARGET 0x4A
113#define PN533_CMD_IN_ATR 0x50
114#define PN533_CMD_IN_RELEASE 0x52
Samuel Ortiz361f3cb2011-12-14 16:43:11 +0100115#define PN533_CMD_IN_JUMP_FOR_DEP 0x56
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300116
Samuel Ortizad3823c2012-05-30 23:54:55 +0200117#define PN533_CMD_TG_INIT_AS_TARGET 0x8c
Samuel Ortiz103b34c2012-05-31 00:07:51 +0200118#define PN533_CMD_TG_GET_DATA 0x86
Samuel Ortizdadb06f2012-05-31 00:09:11 +0200119#define PN533_CMD_TG_SET_DATA 0x8e
Samuel Ortizad3823c2012-05-30 23:54:55 +0200120
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300121#define PN533_CMD_RESPONSE(cmd) (cmd + 1)
122
123/* PN533 Return codes */
124#define PN533_CMD_RET_MASK 0x3F
125#define PN533_CMD_MI_MASK 0x40
126#define PN533_CMD_RET_SUCCESS 0x00
127
128struct pn533;
129
130typedef int (*pn533_cmd_complete_t) (struct pn533 *dev, void *arg,
131 u8 *params, int params_len);
132
133/* structs for pn533 commands */
134
135/* PN533_CMD_GET_FIRMWARE_VERSION */
136struct pn533_fw_version {
137 u8 ic;
138 u8 ver;
139 u8 rev;
140 u8 support;
141};
142
143/* PN533_CMD_RF_CONFIGURATION */
Samuel Ortiz34a85bf2012-05-29 21:34:08 +0200144#define PN533_CFGITEM_TIMING 0x02
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300145#define PN533_CFGITEM_MAX_RETRIES 0x05
Samuel Ortiz5c7b0532012-07-02 20:04:01 +0200146#define PN533_CFGITEM_PASORI 0x82
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300147
Samuel Ortiz34a85bf2012-05-29 21:34:08 +0200148#define PN533_CONFIG_TIMING_102 0xb
149#define PN533_CONFIG_TIMING_204 0xc
150#define PN533_CONFIG_TIMING_409 0xd
151#define PN533_CONFIG_TIMING_819 0xe
152
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300153#define PN533_CONFIG_MAX_RETRIES_NO_RETRY 0x00
154#define PN533_CONFIG_MAX_RETRIES_ENDLESS 0xFF
155
156struct pn533_config_max_retries {
157 u8 mx_rty_atr;
158 u8 mx_rty_psl;
159 u8 mx_rty_passive_act;
160} __packed;
161
Samuel Ortiz34a85bf2012-05-29 21:34:08 +0200162struct pn533_config_timing {
163 u8 rfu;
164 u8 atr_res_timeout;
165 u8 dep_timeout;
166} __packed;
167
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300168/* PN533_CMD_IN_LIST_PASSIVE_TARGET */
169
170/* felica commands opcode */
171#define PN533_FELICA_OPC_SENSF_REQ 0
172#define PN533_FELICA_OPC_SENSF_RES 1
173/* felica SENSF_REQ parameters */
174#define PN533_FELICA_SENSF_SC_ALL 0xFFFF
175#define PN533_FELICA_SENSF_RC_NO_SYSTEM_CODE 0
176#define PN533_FELICA_SENSF_RC_SYSTEM_CODE 1
177#define PN533_FELICA_SENSF_RC_ADVANCED_PROTOCOL 2
178
179/* type B initiator_data values */
180#define PN533_TYPE_B_AFI_ALL_FAMILIES 0
181#define PN533_TYPE_B_POLL_METHOD_TIMESLOT 0
182#define PN533_TYPE_B_POLL_METHOD_PROBABILISTIC 1
183
184union pn533_cmd_poll_initdata {
185 struct {
186 u8 afi;
187 u8 polling_method;
188 } __packed type_b;
189 struct {
190 u8 opcode;
191 __be16 sc;
192 u8 rc;
193 u8 tsn;
194 } __packed felica;
195};
196
197/* Poll modulations */
198enum {
199 PN533_POLL_MOD_106KBPS_A,
200 PN533_POLL_MOD_212KBPS_FELICA,
201 PN533_POLL_MOD_424KBPS_FELICA,
202 PN533_POLL_MOD_106KBPS_JEWEL,
203 PN533_POLL_MOD_847KBPS_B,
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +0200204 PN533_LISTEN_MOD,
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300205
206 __PN533_POLL_MOD_AFTER_LAST,
207};
208#define PN533_POLL_MOD_MAX (__PN533_POLL_MOD_AFTER_LAST - 1)
209
210struct pn533_poll_modulations {
211 struct {
212 u8 maxtg;
213 u8 brty;
214 union pn533_cmd_poll_initdata initiator_data;
215 } __packed data;
216 u8 len;
217};
218
219const struct pn533_poll_modulations poll_mod[] = {
220 [PN533_POLL_MOD_106KBPS_A] = {
221 .data = {
222 .maxtg = 1,
223 .brty = 0,
224 },
225 .len = 2,
226 },
227 [PN533_POLL_MOD_212KBPS_FELICA] = {
228 .data = {
229 .maxtg = 1,
230 .brty = 1,
231 .initiator_data.felica = {
232 .opcode = PN533_FELICA_OPC_SENSF_REQ,
233 .sc = PN533_FELICA_SENSF_SC_ALL,
234 .rc = PN533_FELICA_SENSF_RC_NO_SYSTEM_CODE,
235 .tsn = 0,
236 },
237 },
238 .len = 7,
239 },
240 [PN533_POLL_MOD_424KBPS_FELICA] = {
241 .data = {
242 .maxtg = 1,
243 .brty = 2,
244 .initiator_data.felica = {
245 .opcode = PN533_FELICA_OPC_SENSF_REQ,
246 .sc = PN533_FELICA_SENSF_SC_ALL,
247 .rc = PN533_FELICA_SENSF_RC_NO_SYSTEM_CODE,
248 .tsn = 0,
249 },
250 },
251 .len = 7,
252 },
253 [PN533_POLL_MOD_106KBPS_JEWEL] = {
254 .data = {
255 .maxtg = 1,
256 .brty = 4,
257 },
258 .len = 2,
259 },
260 [PN533_POLL_MOD_847KBPS_B] = {
261 .data = {
262 .maxtg = 1,
263 .brty = 8,
264 .initiator_data.type_b = {
265 .afi = PN533_TYPE_B_AFI_ALL_FAMILIES,
266 .polling_method =
267 PN533_TYPE_B_POLL_METHOD_TIMESLOT,
268 },
269 },
270 .len = 3,
271 },
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +0200272 [PN533_LISTEN_MOD] = {
273 .len = 0,
274 },
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300275};
276
277/* PN533_CMD_IN_ATR */
278
279struct pn533_cmd_activate_param {
280 u8 tg;
281 u8 next;
282} __packed;
283
284struct pn533_cmd_activate_response {
285 u8 status;
286 u8 nfcid3t[10];
287 u8 didt;
288 u8 bst;
289 u8 brt;
290 u8 to;
291 u8 ppt;
292 /* optional */
293 u8 gt[];
294} __packed;
295
Samuel Ortiz361f3cb2011-12-14 16:43:11 +0100296/* PN533_CMD_IN_JUMP_FOR_DEP */
297struct pn533_cmd_jump_dep {
298 u8 active;
299 u8 baud;
300 u8 next;
Samuel Ortizd7f33452012-05-29 21:45:21 +0200301 u8 data[];
Samuel Ortiz361f3cb2011-12-14 16:43:11 +0100302} __packed;
303
304struct pn533_cmd_jump_dep_response {
305 u8 status;
306 u8 tg;
307 u8 nfcid3t[10];
308 u8 didt;
309 u8 bst;
310 u8 brt;
311 u8 to;
312 u8 ppt;
313 /* optional */
314 u8 gt[];
315} __packed;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300316
Samuel Ortizad3823c2012-05-30 23:54:55 +0200317
318/* PN533_TG_INIT_AS_TARGET */
319#define PN533_INIT_TARGET_PASSIVE 0x1
320#define PN533_INIT_TARGET_DEP 0x2
321
Samuel Ortizfc40a8c2012-06-01 13:21:13 +0200322#define PN533_INIT_TARGET_RESP_FRAME_MASK 0x3
323#define PN533_INIT_TARGET_RESP_ACTIVE 0x1
324#define PN533_INIT_TARGET_RESP_DEP 0x4
325
Samuel Ortizad3823c2012-05-30 23:54:55 +0200326struct pn533_cmd_init_target {
327 u8 mode;
328 u8 mifare[6];
329 u8 felica[18];
330 u8 nfcid3[10];
331 u8 gb_len;
332 u8 gb[];
333} __packed;
334
335struct pn533_cmd_init_target_response {
336 u8 mode;
337 u8 cmd[];
338} __packed;
339
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300340struct pn533 {
341 struct usb_device *udev;
342 struct usb_interface *interface;
343 struct nfc_dev *nfc_dev;
344
345 struct urb *out_urb;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300346 struct pn533_frame *out_frame;
347
348 struct urb *in_urb;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300349 struct pn533_frame *in_frame;
350
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +0200351 struct sk_buff_head resp_q;
352
Samuel Ortiz4849f852012-04-10 19:43:17 +0200353 struct workqueue_struct *wq;
354 struct work_struct cmd_work;
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200355 struct work_struct cmd_complete_work;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +0200356 struct work_struct poll_work;
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +0200357 struct work_struct mi_work;
Samuel Ortiz103b34c2012-05-31 00:07:51 +0200358 struct work_struct tg_work;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +0200359 struct timer_list listen_timer;
Samuel Ortiz4849f852012-04-10 19:43:17 +0200360 struct pn533_frame *wq_in_frame;
361 int wq_in_error;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +0200362 int cancel_listen;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300363
364 pn533_cmd_complete_t cmd_complete;
365 void *cmd_complete_arg;
Samuel Ortiz0201ed02012-05-31 17:56:46 +0200366 struct mutex cmd_lock;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300367 u8 cmd;
368
369 struct pn533_poll_modulations *poll_mod_active[PN533_POLL_MOD_MAX + 1];
370 u8 poll_mod_count;
371 u8 poll_mod_curr;
372 u32 poll_protocols;
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +0200373 u32 listen_protocols;
374
375 u8 *gb;
376 size_t gb_len;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300377
378 u8 tgt_available_prots;
379 u8 tgt_active_prot;
Samuel Ortiz51ad3042012-05-31 20:01:32 +0200380 u8 tgt_mode;
Samuel Ortiz5c7b0532012-07-02 20:04:01 +0200381
382 u32 device_type;
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200383
384 struct list_head cmd_queue;
385 u8 cmd_pending;
386};
387
388struct pn533_cmd {
389 struct list_head queue;
390 struct pn533_frame *out_frame;
391 struct pn533_frame *in_frame;
392 int in_frame_len;
393 pn533_cmd_complete_t cmd_complete;
394 void *arg;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300395};
396
397struct pn533_frame {
398 u8 preamble;
399 __be16 start_frame;
400 u8 datalen;
401 u8 datalen_checksum;
402 u8 data[];
403} __packed;
404
405/* The rule: value + checksum = 0 */
406static inline u8 pn533_checksum(u8 value)
407{
408 return ~value + 1;
409}
410
411/* The rule: sum(data elements) + checksum = 0 */
412static u8 pn533_data_checksum(u8 *data, int datalen)
413{
414 u8 sum = 0;
415 int i;
416
417 for (i = 0; i < datalen; i++)
418 sum += data[i];
419
420 return pn533_checksum(sum);
421}
422
423/**
424 * pn533_tx_frame_ack - create a ack frame
425 * @frame: The frame to be set as ack
426 *
427 * Ack is different type of standard frame. As a standard frame, it has
428 * preamble and start_frame. However the checksum of this frame must fail,
429 * i.e. datalen + datalen_checksum must NOT be zero. When the checksum test
430 * fails and datalen = 0 and datalen_checksum = 0xFF, the frame is a ack.
431 * After datalen_checksum field, the postamble is placed.
432 */
433static void pn533_tx_frame_ack(struct pn533_frame *frame)
434{
435 frame->preamble = 0;
436 frame->start_frame = cpu_to_be16(PN533_SOF);
437 frame->datalen = 0;
438 frame->datalen_checksum = 0xFF;
439 /* data[0] is used as postamble */
440 frame->data[0] = 0;
441}
442
443static void pn533_tx_frame_init(struct pn533_frame *frame, u8 cmd)
444{
445 frame->preamble = 0;
446 frame->start_frame = cpu_to_be16(PN533_SOF);
447 PN533_FRAME_IDENTIFIER(frame) = PN533_DIR_OUT;
448 PN533_FRAME_CMD(frame) = cmd;
449 frame->datalen = 2;
450}
451
452static void pn533_tx_frame_finish(struct pn533_frame *frame)
453{
454 frame->datalen_checksum = pn533_checksum(frame->datalen);
455
456 PN533_FRAME_CHECKSUM(frame) =
457 pn533_data_checksum(frame->data, frame->datalen);
458
459 PN533_FRAME_POSTAMBLE(frame) = 0;
460}
461
462static bool pn533_rx_frame_is_valid(struct pn533_frame *frame)
463{
464 u8 checksum;
465
466 if (frame->start_frame != cpu_to_be16(PN533_SOF))
467 return false;
468
469 checksum = pn533_checksum(frame->datalen);
470 if (checksum != frame->datalen_checksum)
471 return false;
472
473 checksum = pn533_data_checksum(frame->data, frame->datalen);
474 if (checksum != PN533_FRAME_CHECKSUM(frame))
475 return false;
476
477 return true;
478}
479
480static bool pn533_rx_frame_is_ack(struct pn533_frame *frame)
481{
482 if (frame->start_frame != cpu_to_be16(PN533_SOF))
483 return false;
484
485 if (frame->datalen != 0 || frame->datalen_checksum != 0xFF)
486 return false;
487
488 return true;
489}
490
491static bool pn533_rx_frame_is_cmd_response(struct pn533_frame *frame, u8 cmd)
492{
493 return (PN533_FRAME_CMD(frame) == PN533_CMD_RESPONSE(cmd));
494}
495
Samuel Ortiz4849f852012-04-10 19:43:17 +0200496
497static void pn533_wq_cmd_complete(struct work_struct *work)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300498{
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200499 struct pn533 *dev = container_of(work, struct pn533, cmd_complete_work);
Samuel Ortiz4849f852012-04-10 19:43:17 +0200500 struct pn533_frame *in_frame;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300501 int rc;
502
Samuel Ortiz4849f852012-04-10 19:43:17 +0200503 in_frame = dev->wq_in_frame;
504
505 if (dev->wq_in_error)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300506 rc = dev->cmd_complete(dev, dev->cmd_complete_arg, NULL,
Samuel Ortiz4849f852012-04-10 19:43:17 +0200507 dev->wq_in_error);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300508 else
509 rc = dev->cmd_complete(dev, dev->cmd_complete_arg,
510 PN533_FRAME_CMD_PARAMS_PTR(in_frame),
511 PN533_FRAME_CMD_PARAMS_LEN(in_frame));
512
513 if (rc != -EINPROGRESS)
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200514 queue_work(dev->wq, &dev->cmd_work);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300515}
516
517static void pn533_recv_response(struct urb *urb)
518{
519 struct pn533 *dev = urb->context;
520 struct pn533_frame *in_frame;
521
Samuel Ortiz4849f852012-04-10 19:43:17 +0200522 dev->wq_in_frame = NULL;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300523
524 switch (urb->status) {
525 case 0:
526 /* success */
527 break;
528 case -ECONNRESET:
529 case -ENOENT:
530 case -ESHUTDOWN:
531 nfc_dev_dbg(&dev->interface->dev, "Urb shutting down with"
532 " status: %d", urb->status);
Samuel Ortiz4849f852012-04-10 19:43:17 +0200533 dev->wq_in_error = urb->status;
534 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300535 default:
536 nfc_dev_err(&dev->interface->dev, "Nonzero urb status received:"
537 " %d", urb->status);
Samuel Ortiz4849f852012-04-10 19:43:17 +0200538 dev->wq_in_error = urb->status;
539 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300540 }
541
542 in_frame = dev->in_urb->transfer_buffer;
543
544 if (!pn533_rx_frame_is_valid(in_frame)) {
545 nfc_dev_err(&dev->interface->dev, "Received an invalid frame");
Samuel Ortiz4849f852012-04-10 19:43:17 +0200546 dev->wq_in_error = -EIO;
547 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300548 }
549
550 if (!pn533_rx_frame_is_cmd_response(in_frame, dev->cmd)) {
551 nfc_dev_err(&dev->interface->dev, "The received frame is not "
552 "response to the last command");
Samuel Ortiz4849f852012-04-10 19:43:17 +0200553 dev->wq_in_error = -EIO;
554 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300555 }
556
557 nfc_dev_dbg(&dev->interface->dev, "Received a valid frame");
Samuel Ortiz4849f852012-04-10 19:43:17 +0200558 dev->wq_in_error = 0;
559 dev->wq_in_frame = in_frame;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300560
Samuel Ortiz4849f852012-04-10 19:43:17 +0200561sched_wq:
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200562 queue_work(dev->wq, &dev->cmd_complete_work);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300563}
564
565static int pn533_submit_urb_for_response(struct pn533 *dev, gfp_t flags)
566{
567 dev->in_urb->complete = pn533_recv_response;
568
569 return usb_submit_urb(dev->in_urb, flags);
570}
571
572static void pn533_recv_ack(struct urb *urb)
573{
574 struct pn533 *dev = urb->context;
575 struct pn533_frame *in_frame;
576 int rc;
577
578 switch (urb->status) {
579 case 0:
580 /* success */
581 break;
582 case -ECONNRESET:
583 case -ENOENT:
584 case -ESHUTDOWN:
585 nfc_dev_dbg(&dev->interface->dev, "Urb shutting down with"
586 " status: %d", urb->status);
Samuel Ortiz4849f852012-04-10 19:43:17 +0200587 dev->wq_in_error = urb->status;
588 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300589 default:
590 nfc_dev_err(&dev->interface->dev, "Nonzero urb status received:"
591 " %d", urb->status);
Samuel Ortiz4849f852012-04-10 19:43:17 +0200592 dev->wq_in_error = urb->status;
593 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300594 }
595
596 in_frame = dev->in_urb->transfer_buffer;
597
598 if (!pn533_rx_frame_is_ack(in_frame)) {
599 nfc_dev_err(&dev->interface->dev, "Received an invalid ack");
Samuel Ortiz4849f852012-04-10 19:43:17 +0200600 dev->wq_in_error = -EIO;
601 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300602 }
603
604 nfc_dev_dbg(&dev->interface->dev, "Received a valid ack");
605
606 rc = pn533_submit_urb_for_response(dev, GFP_ATOMIC);
607 if (rc) {
608 nfc_dev_err(&dev->interface->dev, "usb_submit_urb failed with"
609 " result %d", rc);
Samuel Ortiz4849f852012-04-10 19:43:17 +0200610 dev->wq_in_error = rc;
611 goto sched_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300612 }
613
614 return;
615
Samuel Ortiz4849f852012-04-10 19:43:17 +0200616sched_wq:
617 dev->wq_in_frame = NULL;
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200618 queue_work(dev->wq, &dev->cmd_complete_work);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300619}
620
621static int pn533_submit_urb_for_ack(struct pn533 *dev, gfp_t flags)
622{
623 dev->in_urb->complete = pn533_recv_ack;
624
625 return usb_submit_urb(dev->in_urb, flags);
626}
627
628static int pn533_send_ack(struct pn533 *dev, gfp_t flags)
629{
630 int rc;
631
632 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
633
634 pn533_tx_frame_ack(dev->out_frame);
635
636 dev->out_urb->transfer_buffer = dev->out_frame;
637 dev->out_urb->transfer_buffer_length = PN533_FRAME_ACK_SIZE;
638 rc = usb_submit_urb(dev->out_urb, flags);
639
640 return rc;
641}
642
643static int __pn533_send_cmd_frame_async(struct pn533 *dev,
644 struct pn533_frame *out_frame,
645 struct pn533_frame *in_frame,
646 int in_frame_len,
647 pn533_cmd_complete_t cmd_complete,
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +0100648 void *arg)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300649{
650 int rc;
651
652 nfc_dev_dbg(&dev->interface->dev, "Sending command 0x%x",
653 PN533_FRAME_CMD(out_frame));
654
655 dev->cmd = PN533_FRAME_CMD(out_frame);
656 dev->cmd_complete = cmd_complete;
657 dev->cmd_complete_arg = arg;
658
659 dev->out_urb->transfer_buffer = out_frame;
660 dev->out_urb->transfer_buffer_length =
661 PN533_FRAME_SIZE(out_frame);
662
663 dev->in_urb->transfer_buffer = in_frame;
664 dev->in_urb->transfer_buffer_length = in_frame_len;
665
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +0100666 rc = usb_submit_urb(dev->out_urb, GFP_KERNEL);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300667 if (rc)
668 return rc;
669
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +0100670 rc = pn533_submit_urb_for_ack(dev, GFP_KERNEL);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300671 if (rc)
672 goto error;
673
674 return 0;
675
676error:
677 usb_unlink_urb(dev->out_urb);
678 return rc;
679}
680
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200681static void pn533_wq_cmd(struct work_struct *work)
682{
683 struct pn533 *dev = container_of(work, struct pn533, cmd_work);
684 struct pn533_cmd *cmd;
685
686 mutex_lock(&dev->cmd_lock);
687
688 if (list_empty(&dev->cmd_queue)) {
689 dev->cmd_pending = 0;
690 mutex_unlock(&dev->cmd_lock);
691 return;
692 }
693
694 cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue);
695
Szymon Janc60ad07a2012-10-25 17:29:45 +0200696 list_del(&cmd->queue);
697
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200698 mutex_unlock(&dev->cmd_lock);
699
700 __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame,
701 cmd->in_frame_len, cmd->cmd_complete,
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +0100702 cmd->arg);
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200703
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200704 kfree(cmd);
705}
706
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300707static int pn533_send_cmd_frame_async(struct pn533 *dev,
708 struct pn533_frame *out_frame,
709 struct pn533_frame *in_frame,
710 int in_frame_len,
711 pn533_cmd_complete_t cmd_complete,
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +0100712 void *arg)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300713{
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200714 struct pn533_cmd *cmd;
Szymon Jancee5e8d82012-09-27 09:16:54 +0200715 int rc = 0;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300716
717 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
718
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200719 mutex_lock(&dev->cmd_lock);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300720
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200721 if (!dev->cmd_pending) {
722 rc = __pn533_send_cmd_frame_async(dev, out_frame, in_frame,
723 in_frame_len, cmd_complete,
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +0100724 arg);
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200725 if (!rc)
726 dev->cmd_pending = 1;
727
Szymon Jancee5e8d82012-09-27 09:16:54 +0200728 goto unlock;
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200729 }
730
731 nfc_dev_dbg(&dev->interface->dev, "%s Queueing command", __func__);
732
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +0100733 cmd = kzalloc(sizeof(struct pn533_cmd), GFP_KERNEL);
Szymon Jancee5e8d82012-09-27 09:16:54 +0200734 if (!cmd) {
735 rc = -ENOMEM;
736 goto unlock;
737 }
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200738
739 INIT_LIST_HEAD(&cmd->queue);
740 cmd->out_frame = out_frame;
741 cmd->in_frame = in_frame;
742 cmd->in_frame_len = in_frame_len;
743 cmd->cmd_complete = cmd_complete;
744 cmd->arg = arg;
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200745
746 list_add_tail(&cmd->queue, &dev->cmd_queue);
747
Szymon Jancee5e8d82012-09-27 09:16:54 +0200748unlock:
Samuel Ortiz5d50b362012-08-17 23:47:54 +0200749 mutex_unlock(&dev->cmd_lock);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300750
Szymon Jancee5e8d82012-09-27 09:16:54 +0200751 return rc;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300752}
753
754struct pn533_sync_cmd_response {
755 int rc;
756 struct completion done;
757};
758
759static int pn533_sync_cmd_complete(struct pn533 *dev, void *_arg,
760 u8 *params, int params_len)
761{
762 struct pn533_sync_cmd_response *arg = _arg;
763
764 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
765
766 arg->rc = 0;
767
768 if (params_len < 0) /* error */
769 arg->rc = params_len;
770
771 complete(&arg->done);
772
773 return 0;
774}
775
776static int pn533_send_cmd_frame_sync(struct pn533 *dev,
777 struct pn533_frame *out_frame,
778 struct pn533_frame *in_frame,
779 int in_frame_len)
780{
781 int rc;
782 struct pn533_sync_cmd_response arg;
783
784 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
785
786 init_completion(&arg.done);
787
788 rc = pn533_send_cmd_frame_async(dev, out_frame, in_frame, in_frame_len,
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +0100789 pn533_sync_cmd_complete, &arg);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300790 if (rc)
791 return rc;
792
793 wait_for_completion(&arg.done);
794
795 return arg.rc;
796}
797
798static void pn533_send_complete(struct urb *urb)
799{
800 struct pn533 *dev = urb->context;
801
802 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
803
804 switch (urb->status) {
805 case 0:
806 /* success */
807 break;
808 case -ECONNRESET:
809 case -ENOENT:
810 case -ESHUTDOWN:
811 nfc_dev_dbg(&dev->interface->dev, "Urb shutting down with"
812 " status: %d", urb->status);
813 break;
814 default:
815 nfc_dev_dbg(&dev->interface->dev, "Nonzero urb status received:"
816 " %d", urb->status);
817 }
818}
819
820struct pn533_target_type_a {
821 __be16 sens_res;
822 u8 sel_res;
823 u8 nfcid_len;
824 u8 nfcid_data[];
825} __packed;
826
827
828#define PN533_TYPE_A_SENS_RES_NFCID1(x) ((u8)((be16_to_cpu(x) & 0x00C0) >> 6))
829#define PN533_TYPE_A_SENS_RES_SSD(x) ((u8)((be16_to_cpu(x) & 0x001F) >> 0))
830#define PN533_TYPE_A_SENS_RES_PLATCONF(x) ((u8)((be16_to_cpu(x) & 0x0F00) >> 8))
831
832#define PN533_TYPE_A_SENS_RES_SSD_JEWEL 0x00
833#define PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL 0x0C
834
835#define PN533_TYPE_A_SEL_PROT(x) (((x) & 0x60) >> 5)
836#define PN533_TYPE_A_SEL_CASCADE(x) (((x) & 0x04) >> 2)
837
838#define PN533_TYPE_A_SEL_PROT_MIFARE 0
839#define PN533_TYPE_A_SEL_PROT_ISO14443 1
840#define PN533_TYPE_A_SEL_PROT_DEP 2
841#define PN533_TYPE_A_SEL_PROT_ISO14443_DEP 3
842
843static bool pn533_target_type_a_is_valid(struct pn533_target_type_a *type_a,
844 int target_data_len)
845{
846 u8 ssd;
847 u8 platconf;
848
849 if (target_data_len < sizeof(struct pn533_target_type_a))
850 return false;
851
852 /* The lenght check of nfcid[] and ats[] are not being performed because
853 the values are not being used */
854
855 /* Requirement 4.6.3.3 from NFC Forum Digital Spec */
856 ssd = PN533_TYPE_A_SENS_RES_SSD(type_a->sens_res);
857 platconf = PN533_TYPE_A_SENS_RES_PLATCONF(type_a->sens_res);
858
859 if ((ssd == PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
860 platconf != PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL) ||
861 (ssd != PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
862 platconf == PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL))
863 return false;
864
865 /* Requirements 4.8.2.1, 4.8.2.3, 4.8.2.5 and 4.8.2.7 from NFC Forum */
866 if (PN533_TYPE_A_SEL_CASCADE(type_a->sel_res) != 0)
867 return false;
868
869 return true;
870}
871
872static int pn533_target_found_type_a(struct nfc_target *nfc_tgt, u8 *tgt_data,
873 int tgt_data_len)
874{
875 struct pn533_target_type_a *tgt_type_a;
876
877 tgt_type_a = (struct pn533_target_type_a *) tgt_data;
878
879 if (!pn533_target_type_a_is_valid(tgt_type_a, tgt_data_len))
880 return -EPROTO;
881
882 switch (PN533_TYPE_A_SEL_PROT(tgt_type_a->sel_res)) {
883 case PN533_TYPE_A_SEL_PROT_MIFARE:
884 nfc_tgt->supported_protocols = NFC_PROTO_MIFARE_MASK;
885 break;
886 case PN533_TYPE_A_SEL_PROT_ISO14443:
887 nfc_tgt->supported_protocols = NFC_PROTO_ISO14443_MASK;
888 break;
889 case PN533_TYPE_A_SEL_PROT_DEP:
890 nfc_tgt->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
891 break;
892 case PN533_TYPE_A_SEL_PROT_ISO14443_DEP:
893 nfc_tgt->supported_protocols = NFC_PROTO_ISO14443_MASK |
894 NFC_PROTO_NFC_DEP_MASK;
895 break;
896 }
897
898 nfc_tgt->sens_res = be16_to_cpu(tgt_type_a->sens_res);
899 nfc_tgt->sel_res = tgt_type_a->sel_res;
Samuel Ortizc3b1e1e2012-03-05 01:03:33 +0100900 nfc_tgt->nfcid1_len = tgt_type_a->nfcid_len;
901 memcpy(nfc_tgt->nfcid1, tgt_type_a->nfcid_data, nfc_tgt->nfcid1_len);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300902
903 return 0;
904}
905
906struct pn533_target_felica {
907 u8 pol_res;
908 u8 opcode;
909 u8 nfcid2[8];
910 u8 pad[8];
911 /* optional */
912 u8 syst_code[];
913} __packed;
914
915#define PN533_FELICA_SENSF_NFCID2_DEP_B1 0x01
916#define PN533_FELICA_SENSF_NFCID2_DEP_B2 0xFE
917
918static bool pn533_target_felica_is_valid(struct pn533_target_felica *felica,
919 int target_data_len)
920{
921 if (target_data_len < sizeof(struct pn533_target_felica))
922 return false;
923
924 if (felica->opcode != PN533_FELICA_OPC_SENSF_RES)
925 return false;
926
927 return true;
928}
929
930static int pn533_target_found_felica(struct nfc_target *nfc_tgt, u8 *tgt_data,
931 int tgt_data_len)
932{
933 struct pn533_target_felica *tgt_felica;
934
935 tgt_felica = (struct pn533_target_felica *) tgt_data;
936
937 if (!pn533_target_felica_is_valid(tgt_felica, tgt_data_len))
938 return -EPROTO;
939
940 if (tgt_felica->nfcid2[0] == PN533_FELICA_SENSF_NFCID2_DEP_B1 &&
941 tgt_felica->nfcid2[1] ==
942 PN533_FELICA_SENSF_NFCID2_DEP_B2)
943 nfc_tgt->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
944 else
945 nfc_tgt->supported_protocols = NFC_PROTO_FELICA_MASK;
946
Samuel Ortiz79757542012-03-05 01:03:45 +0100947 memcpy(nfc_tgt->sensf_res, &tgt_felica->opcode, 9);
948 nfc_tgt->sensf_res_len = 9;
949
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300950 return 0;
951}
952
953struct pn533_target_jewel {
954 __be16 sens_res;
955 u8 jewelid[4];
956} __packed;
957
958static bool pn533_target_jewel_is_valid(struct pn533_target_jewel *jewel,
959 int target_data_len)
960{
961 u8 ssd;
962 u8 platconf;
963
964 if (target_data_len < sizeof(struct pn533_target_jewel))
965 return false;
966
967 /* Requirement 4.6.3.3 from NFC Forum Digital Spec */
968 ssd = PN533_TYPE_A_SENS_RES_SSD(jewel->sens_res);
969 platconf = PN533_TYPE_A_SENS_RES_PLATCONF(jewel->sens_res);
970
971 if ((ssd == PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
972 platconf != PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL) ||
973 (ssd != PN533_TYPE_A_SENS_RES_SSD_JEWEL &&
974 platconf == PN533_TYPE_A_SENS_RES_PLATCONF_JEWEL))
975 return false;
976
977 return true;
978}
979
980static int pn533_target_found_jewel(struct nfc_target *nfc_tgt, u8 *tgt_data,
981 int tgt_data_len)
982{
983 struct pn533_target_jewel *tgt_jewel;
984
985 tgt_jewel = (struct pn533_target_jewel *) tgt_data;
986
987 if (!pn533_target_jewel_is_valid(tgt_jewel, tgt_data_len))
988 return -EPROTO;
989
990 nfc_tgt->supported_protocols = NFC_PROTO_JEWEL_MASK;
991 nfc_tgt->sens_res = be16_to_cpu(tgt_jewel->sens_res);
Samuel Ortizd8dc1072012-03-05 01:03:46 +0100992 nfc_tgt->nfcid1_len = 4;
993 memcpy(nfc_tgt->nfcid1, tgt_jewel->jewelid, nfc_tgt->nfcid1_len);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -0300994
995 return 0;
996}
997
998struct pn533_type_b_prot_info {
999 u8 bitrate;
1000 u8 fsci_type;
1001 u8 fwi_adc_fo;
1002} __packed;
1003
1004#define PN533_TYPE_B_PROT_FCSI(x) (((x) & 0xF0) >> 4)
1005#define PN533_TYPE_B_PROT_TYPE(x) (((x) & 0x0F) >> 0)
1006#define PN533_TYPE_B_PROT_TYPE_RFU_MASK 0x8
1007
1008struct pn533_type_b_sens_res {
1009 u8 opcode;
1010 u8 nfcid[4];
1011 u8 appdata[4];
1012 struct pn533_type_b_prot_info prot_info;
1013} __packed;
1014
1015#define PN533_TYPE_B_OPC_SENSB_RES 0x50
1016
1017struct pn533_target_type_b {
1018 struct pn533_type_b_sens_res sensb_res;
1019 u8 attrib_res_len;
1020 u8 attrib_res[];
1021} __packed;
1022
1023static bool pn533_target_type_b_is_valid(struct pn533_target_type_b *type_b,
1024 int target_data_len)
1025{
1026 if (target_data_len < sizeof(struct pn533_target_type_b))
1027 return false;
1028
1029 if (type_b->sensb_res.opcode != PN533_TYPE_B_OPC_SENSB_RES)
1030 return false;
1031
1032 if (PN533_TYPE_B_PROT_TYPE(type_b->sensb_res.prot_info.fsci_type) &
1033 PN533_TYPE_B_PROT_TYPE_RFU_MASK)
1034 return false;
1035
1036 return true;
1037}
1038
1039static int pn533_target_found_type_b(struct nfc_target *nfc_tgt, u8 *tgt_data,
1040 int tgt_data_len)
1041{
1042 struct pn533_target_type_b *tgt_type_b;
1043
1044 tgt_type_b = (struct pn533_target_type_b *) tgt_data;
1045
1046 if (!pn533_target_type_b_is_valid(tgt_type_b, tgt_data_len))
1047 return -EPROTO;
1048
Samuel Ortiz01d719a2012-07-04 00:14:04 +02001049 nfc_tgt->supported_protocols = NFC_PROTO_ISO14443_B_MASK;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001050
1051 return 0;
1052}
1053
1054struct pn533_poll_response {
1055 u8 nbtg;
1056 u8 tg;
1057 u8 target_data[];
1058} __packed;
1059
1060static int pn533_target_found(struct pn533 *dev,
1061 struct pn533_poll_response *resp, int resp_len)
1062{
1063 int target_data_len;
1064 struct nfc_target nfc_tgt;
1065 int rc;
1066
1067 nfc_dev_dbg(&dev->interface->dev, "%s - modulation=%d", __func__,
1068 dev->poll_mod_curr);
1069
1070 if (resp->tg != 1)
1071 return -EPROTO;
1072
Samuel Ortiz98b3ac12012-03-05 01:03:39 +01001073 memset(&nfc_tgt, 0, sizeof(struct nfc_target));
1074
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001075 target_data_len = resp_len - sizeof(struct pn533_poll_response);
1076
1077 switch (dev->poll_mod_curr) {
1078 case PN533_POLL_MOD_106KBPS_A:
1079 rc = pn533_target_found_type_a(&nfc_tgt, resp->target_data,
1080 target_data_len);
1081 break;
1082 case PN533_POLL_MOD_212KBPS_FELICA:
1083 case PN533_POLL_MOD_424KBPS_FELICA:
1084 rc = pn533_target_found_felica(&nfc_tgt, resp->target_data,
1085 target_data_len);
1086 break;
1087 case PN533_POLL_MOD_106KBPS_JEWEL:
1088 rc = pn533_target_found_jewel(&nfc_tgt, resp->target_data,
1089 target_data_len);
1090 break;
1091 case PN533_POLL_MOD_847KBPS_B:
1092 rc = pn533_target_found_type_b(&nfc_tgt, resp->target_data,
1093 target_data_len);
1094 break;
1095 default:
1096 nfc_dev_err(&dev->interface->dev, "Unknown current poll"
1097 " modulation");
1098 return -EPROTO;
1099 }
1100
1101 if (rc)
1102 return rc;
1103
1104 if (!(nfc_tgt.supported_protocols & dev->poll_protocols)) {
1105 nfc_dev_dbg(&dev->interface->dev, "The target found does not"
1106 " have the desired protocol");
1107 return -EAGAIN;
1108 }
1109
1110 nfc_dev_dbg(&dev->interface->dev, "Target found - supported protocols: "
1111 "0x%x", nfc_tgt.supported_protocols);
1112
1113 dev->tgt_available_prots = nfc_tgt.supported_protocols;
1114
1115 nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1);
1116
1117 return 0;
1118}
1119
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001120static inline void pn533_poll_next_mod(struct pn533 *dev)
1121{
1122 dev->poll_mod_curr = (dev->poll_mod_curr + 1) % dev->poll_mod_count;
1123}
1124
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001125static void pn533_poll_reset_mod_list(struct pn533 *dev)
1126{
1127 dev->poll_mod_count = 0;
1128}
1129
1130static void pn533_poll_add_mod(struct pn533 *dev, u8 mod_index)
1131{
1132 dev->poll_mod_active[dev->poll_mod_count] =
1133 (struct pn533_poll_modulations *) &poll_mod[mod_index];
1134 dev->poll_mod_count++;
1135}
1136
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001137static void pn533_poll_create_mod_list(struct pn533 *dev,
1138 u32 im_protocols, u32 tm_protocols)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001139{
1140 pn533_poll_reset_mod_list(dev);
1141
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001142 if (im_protocols & NFC_PROTO_MIFARE_MASK
1143 || im_protocols & NFC_PROTO_ISO14443_MASK
1144 || im_protocols & NFC_PROTO_NFC_DEP_MASK)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001145 pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_A);
1146
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001147 if (im_protocols & NFC_PROTO_FELICA_MASK
1148 || im_protocols & NFC_PROTO_NFC_DEP_MASK) {
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001149 pn533_poll_add_mod(dev, PN533_POLL_MOD_212KBPS_FELICA);
1150 pn533_poll_add_mod(dev, PN533_POLL_MOD_424KBPS_FELICA);
1151 }
1152
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001153 if (im_protocols & NFC_PROTO_JEWEL_MASK)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001154 pn533_poll_add_mod(dev, PN533_POLL_MOD_106KBPS_JEWEL);
1155
Samuel Ortiz01d719a2012-07-04 00:14:04 +02001156 if (im_protocols & NFC_PROTO_ISO14443_B_MASK)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001157 pn533_poll_add_mod(dev, PN533_POLL_MOD_847KBPS_B);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001158
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001159 if (tm_protocols)
1160 pn533_poll_add_mod(dev, PN533_LISTEN_MOD);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001161}
1162
Waldemar Rymarkiewiczab34a182012-10-11 14:04:01 +02001163static int pn533_start_poll_complete(struct pn533 *dev, u8 *params, int params_len)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001164{
1165 struct pn533_poll_response *resp;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001166 int rc;
1167
1168 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1169
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001170 resp = (struct pn533_poll_response *) params;
1171 if (resp->nbtg) {
1172 rc = pn533_target_found(dev, resp, params_len);
1173
1174 /* We must stop the poll after a valid target found */
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001175 if (rc == 0) {
1176 pn533_poll_reset_mod_list(dev);
1177 return 0;
1178 }
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001179 }
1180
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001181 return -EAGAIN;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001182}
1183
Samuel Ortizad3823c2012-05-30 23:54:55 +02001184static int pn533_init_target_frame(struct pn533_frame *frame,
1185 u8 *gb, size_t gb_len)
1186{
1187 struct pn533_cmd_init_target *cmd;
1188 size_t cmd_len;
Samuel Ortiz51d9e802012-05-30 01:48:46 +02001189 u8 felica_params[18] = {0x1, 0xfe, /* DEP */
1190 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* random */
1191 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
1192 0xff, 0xff}; /* System code */
1193 u8 mifare_params[6] = {0x1, 0x1, /* SENS_RES */
1194 0x0, 0x0, 0x0,
1195 0x40}; /* SEL_RES for DEP */
Samuel Ortizad3823c2012-05-30 23:54:55 +02001196
1197 cmd_len = sizeof(struct pn533_cmd_init_target) + gb_len + 1;
1198 cmd = kzalloc(cmd_len, GFP_KERNEL);
1199 if (cmd == NULL)
1200 return -ENOMEM;
1201
1202 pn533_tx_frame_init(frame, PN533_CMD_TG_INIT_AS_TARGET);
1203
1204 /* DEP support only */
1205 cmd->mode |= PN533_INIT_TARGET_DEP;
Samuel Ortiz51d9e802012-05-30 01:48:46 +02001206
1207 /* Felica params */
1208 memcpy(cmd->felica, felica_params, 18);
1209 get_random_bytes(cmd->felica + 2, 6);
1210
1211 /* NFCID3 */
1212 memset(cmd->nfcid3, 0, 10);
1213 memcpy(cmd->nfcid3, cmd->felica, 8);
1214
1215 /* MIFARE params */
1216 memcpy(cmd->mifare, mifare_params, 6);
1217
1218 /* General bytes */
Samuel Ortizad3823c2012-05-30 23:54:55 +02001219 cmd->gb_len = gb_len;
1220 memcpy(cmd->gb, gb, gb_len);
Samuel Ortiz51d9e802012-05-30 01:48:46 +02001221
Samuel Ortizad3823c2012-05-30 23:54:55 +02001222 /* Len Tk */
1223 cmd->gb[gb_len] = 0;
1224
1225 memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), cmd, cmd_len);
Samuel Ortiz51d9e802012-05-30 01:48:46 +02001226
Samuel Ortizad3823c2012-05-30 23:54:55 +02001227 frame->datalen += cmd_len;
1228
1229 pn533_tx_frame_finish(frame);
1230
Samuel Ortiz51d9e802012-05-30 01:48:46 +02001231 kfree(cmd);
1232
Samuel Ortizad3823c2012-05-30 23:54:55 +02001233 return 0;
1234}
1235
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01001236#define PN533_CMD_DATAEXCH_HEAD_LEN 1
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001237#define PN533_CMD_DATAEXCH_DATA_MAXLEN 262
1238static int pn533_tm_get_data_complete(struct pn533 *dev, void *arg,
1239 u8 *params, int params_len)
1240{
1241 struct sk_buff *skb_resp = arg;
1242 struct pn533_frame *in_frame = (struct pn533_frame *) skb_resp->data;
1243
1244 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1245
1246 if (params_len < 0) {
1247 nfc_dev_err(&dev->interface->dev,
1248 "Error %d when starting as a target",
1249 params_len);
1250
1251 return params_len;
1252 }
1253
1254 if (params_len > 0 && params[0] != 0) {
1255 nfc_tm_deactivated(dev->nfc_dev);
1256
Samuel Ortiz51ad3042012-05-31 20:01:32 +02001257 dev->tgt_mode = 0;
1258
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001259 kfree_skb(skb_resp);
1260 return 0;
1261 }
1262
1263 skb_put(skb_resp, PN533_FRAME_SIZE(in_frame));
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01001264 skb_pull(skb_resp,
1265 PN533_FRAME_HEADER_LEN + PN533_CMD_DATAEXCH_HEAD_LEN);
1266 skb_trim(skb_resp, skb_resp->len - PN533_FRAME_TAIL_LEN);
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001267
1268 return nfc_tm_data_received(dev->nfc_dev, skb_resp);
1269}
1270
1271static void pn533_wq_tg_get_data(struct work_struct *work)
1272{
1273 struct pn533 *dev = container_of(work, struct pn533, tg_work);
1274 struct pn533_frame *in_frame;
1275 struct sk_buff *skb_resp;
1276 size_t skb_resp_len;
1277
1278 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1279
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01001280 skb_resp_len = PN533_FRAME_HEADER_LEN +
1281 PN533_CMD_DATAEXCH_HEAD_LEN +
1282 PN533_CMD_DATAEXCH_DATA_MAXLEN +
1283 PN533_FRAME_TAIL_LEN;
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001284
1285 skb_resp = nfc_alloc_recv_skb(skb_resp_len, GFP_KERNEL);
1286 if (!skb_resp)
1287 return;
1288
1289 in_frame = (struct pn533_frame *)skb_resp->data;
1290
1291 pn533_tx_frame_init(dev->out_frame, PN533_CMD_TG_GET_DATA);
1292 pn533_tx_frame_finish(dev->out_frame);
1293
1294 pn533_send_cmd_frame_async(dev, dev->out_frame, in_frame,
1295 skb_resp_len,
1296 pn533_tm_get_data_complete,
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +01001297 skb_resp);
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001298
1299 return;
1300}
1301
Samuel Ortizfc40a8c2012-06-01 13:21:13 +02001302#define ATR_REQ_GB_OFFSET 17
Waldemar Rymarkiewiczab34a182012-10-11 14:04:01 +02001303static int pn533_init_target_complete(struct pn533 *dev, u8 *params, int params_len)
Samuel Ortizad3823c2012-05-30 23:54:55 +02001304{
1305 struct pn533_cmd_init_target_response *resp;
Samuel Ortizfc40a8c2012-06-01 13:21:13 +02001306 u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb;
1307 size_t gb_len;
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001308 int rc;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001309
1310 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1311
1312 if (params_len < 0) {
1313 nfc_dev_err(&dev->interface->dev,
1314 "Error %d when starting as a target",
1315 params_len);
1316
1317 return params_len;
1318 }
1319
Samuel Ortizfc40a8c2012-06-01 13:21:13 +02001320 if (params_len < ATR_REQ_GB_OFFSET + 1)
1321 return -EINVAL;
1322
Samuel Ortizad3823c2012-05-30 23:54:55 +02001323 resp = (struct pn533_cmd_init_target_response *) params;
1324
Samuel Ortizfc40a8c2012-06-01 13:21:13 +02001325 nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x param len %d\n",
1326 resp->mode, params_len);
Samuel Ortizad3823c2012-05-30 23:54:55 +02001327
Samuel Ortizfc40a8c2012-06-01 13:21:13 +02001328 frame = resp->mode & PN533_INIT_TARGET_RESP_FRAME_MASK;
1329 if (frame == PN533_INIT_TARGET_RESP_ACTIVE)
1330 comm_mode = NFC_COMM_ACTIVE;
1331
1332 /* Again, only DEP */
1333 if ((resp->mode & PN533_INIT_TARGET_RESP_DEP) == 0)
1334 return -EOPNOTSUPP;
1335
1336 gb = resp->cmd + ATR_REQ_GB_OFFSET;
1337 gb_len = params_len - (ATR_REQ_GB_OFFSET + 1);
1338
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001339 rc = nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
1340 comm_mode, gb, gb_len);
1341 if (rc < 0) {
1342 nfc_dev_err(&dev->interface->dev,
1343 "Error when signaling target activation");
1344 return rc;
1345 }
1346
Samuel Ortiz51ad3042012-05-31 20:01:32 +02001347 dev->tgt_mode = 1;
1348
Samuel Ortiz103b34c2012-05-31 00:07:51 +02001349 queue_work(dev->wq, &dev->tg_work);
1350
1351 return 0;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001352}
1353
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001354static void pn533_listen_mode_timer(unsigned long data)
Samuel Ortizfe7c5802012-05-15 15:57:06 +02001355{
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001356 struct pn533 *dev = (struct pn533 *) data;
1357
1358 nfc_dev_dbg(&dev->interface->dev, "Listen mode timeout");
1359
1360 /* An ack will cancel the last issued command (poll) */
1361 pn533_send_ack(dev, GFP_ATOMIC);
1362
1363 dev->cancel_listen = 1;
1364
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001365 pn533_poll_next_mod(dev);
1366
1367 queue_work(dev->wq, &dev->poll_work);
1368}
1369
1370static int pn533_poll_complete(struct pn533 *dev, void *arg,
1371 u8 *params, int params_len)
1372{
1373 struct pn533_poll_modulations *cur_mod;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001374 int rc;
1375
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001376 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1377
1378 if (params_len == -ENOENT) {
1379 if (dev->poll_mod_count != 0)
1380 return 0;
1381
1382 nfc_dev_err(&dev->interface->dev,
1383 "Polling operation has been stopped");
1384
1385 goto stop_poll;
1386 }
1387
1388 if (params_len < 0) {
1389 nfc_dev_err(&dev->interface->dev,
1390 "Error %d when running poll", params_len);
1391
1392 goto stop_poll;
1393 }
1394
1395 cur_mod = dev->poll_mod_active[dev->poll_mod_curr];
1396
1397 if (cur_mod->len == 0) {
1398 del_timer(&dev->listen_timer);
1399
Waldemar Rymarkiewiczab34a182012-10-11 14:04:01 +02001400 return pn533_init_target_complete(dev, params, params_len);
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001401 } else {
Waldemar Rymarkiewiczab34a182012-10-11 14:04:01 +02001402 rc = pn533_start_poll_complete(dev, params, params_len);
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001403 if (!rc)
1404 return rc;
1405 }
1406
1407 pn533_poll_next_mod(dev);
1408
1409 queue_work(dev->wq, &dev->poll_work);
1410
1411 return 0;
1412
1413stop_poll:
Samuel Ortizad3823c2012-05-30 23:54:55 +02001414 pn533_poll_reset_mod_list(dev);
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001415 dev->poll_protocols = 0;
1416 return 0;
1417}
Samuel Ortizad3823c2012-05-30 23:54:55 +02001418
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001419static void pn533_build_poll_frame(struct pn533 *dev,
1420 struct pn533_frame *frame,
1421 struct pn533_poll_modulations *mod)
1422{
1423 nfc_dev_dbg(&dev->interface->dev, "mod len %d\n", mod->len);
Samuel Ortizad3823c2012-05-30 23:54:55 +02001424
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001425 if (mod->len == 0) {
1426 /* Listen mode */
1427 pn533_init_target_frame(frame, dev->gb, dev->gb_len);
1428 } else {
1429 /* Polling mode */
1430 pn533_tx_frame_init(frame, PN533_CMD_IN_LIST_PASSIVE_TARGET);
1431
1432 memcpy(PN533_FRAME_CMD_PARAMS_PTR(frame), &mod->data, mod->len);
1433 frame->datalen += mod->len;
1434
1435 pn533_tx_frame_finish(frame);
1436 }
1437}
1438
1439static int pn533_send_poll_frame(struct pn533 *dev)
1440{
1441 struct pn533_poll_modulations *cur_mod;
1442 int rc;
1443
1444 cur_mod = dev->poll_mod_active[dev->poll_mod_curr];
1445
1446 pn533_build_poll_frame(dev, dev->out_frame, cur_mod);
Samuel Ortizad3823c2012-05-30 23:54:55 +02001447
1448 rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame,
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01001449 PN533_NORMAL_FRAME_MAX_LEN,
1450 pn533_poll_complete,
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +01001451 NULL);
Samuel Ortizad3823c2012-05-30 23:54:55 +02001452 if (rc)
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001453 nfc_dev_err(&dev->interface->dev, "Polling loop error %d", rc);
Samuel Ortizad3823c2012-05-30 23:54:55 +02001454
1455 return rc;
Samuel Ortizfe7c5802012-05-15 15:57:06 +02001456}
1457
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001458static void pn533_wq_poll(struct work_struct *work)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001459{
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001460 struct pn533 *dev = container_of(work, struct pn533, poll_work);
1461 struct pn533_poll_modulations *cur_mod;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001462 int rc;
1463
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001464 cur_mod = dev->poll_mod_active[dev->poll_mod_curr];
1465
1466 nfc_dev_dbg(&dev->interface->dev,
1467 "%s cancel_listen %d modulation len %d",
1468 __func__, dev->cancel_listen, cur_mod->len);
1469
1470 if (dev->cancel_listen == 1) {
1471 dev->cancel_listen = 0;
1472 usb_kill_urb(dev->in_urb);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001473 }
1474
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001475 rc = pn533_send_poll_frame(dev);
1476 if (rc)
1477 return;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001478
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001479 if (cur_mod->len == 0 && dev->poll_mod_count > 1)
1480 mod_timer(&dev->listen_timer, jiffies + PN533_LISTEN_TIME * HZ);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001481
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001482 return;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001483}
1484
Samuel Ortizfe7c5802012-05-15 15:57:06 +02001485static int pn533_start_poll(struct nfc_dev *nfc_dev,
1486 u32 im_protocols, u32 tm_protocols)
1487{
1488 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1489
1490 nfc_dev_dbg(&dev->interface->dev,
1491 "%s: im protocols 0x%x tm protocols 0x%x",
1492 __func__, im_protocols, tm_protocols);
1493
1494 if (dev->tgt_active_prot) {
1495 nfc_dev_err(&dev->interface->dev,
1496 "Cannot poll with a target already activated");
1497 return -EBUSY;
1498 }
1499
Samuel Ortiz51ad3042012-05-31 20:01:32 +02001500 if (dev->tgt_mode) {
1501 nfc_dev_err(&dev->interface->dev,
1502 "Cannot poll while already being activated");
1503 return -EBUSY;
1504 }
1505
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001506 if (tm_protocols) {
1507 dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len);
1508 if (dev->gb == NULL)
1509 tm_protocols = 0;
1510 }
Samuel Ortizad3823c2012-05-30 23:54:55 +02001511
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001512 dev->poll_mod_curr = 0;
1513 pn533_poll_create_mod_list(dev, im_protocols, tm_protocols);
1514 dev->poll_protocols = im_protocols;
1515 dev->listen_protocols = tm_protocols;
Samuel Ortizad3823c2012-05-30 23:54:55 +02001516
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001517 return pn533_send_poll_frame(dev);
Samuel Ortizfe7c5802012-05-15 15:57:06 +02001518}
1519
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001520static void pn533_stop_poll(struct nfc_dev *nfc_dev)
1521{
1522 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1523
1524 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1525
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001526 del_timer(&dev->listen_timer);
1527
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001528 if (!dev->poll_mod_count) {
1529 nfc_dev_dbg(&dev->interface->dev, "Polling operation was not"
1530 " running");
1531 return;
1532 }
1533
1534 /* An ack will cancel the last issued command (poll) */
1535 pn533_send_ack(dev, GFP_KERNEL);
1536
1537 /* prevent pn533_start_poll_complete to issue a new poll meanwhile */
1538 usb_kill_urb(dev->in_urb);
Samuel Ortiz7c2a04a932012-05-21 16:20:01 +02001539
1540 pn533_poll_reset_mod_list(dev);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001541}
1542
1543static int pn533_activate_target_nfcdep(struct pn533 *dev)
1544{
1545 struct pn533_cmd_activate_param param;
1546 struct pn533_cmd_activate_response *resp;
Samuel Ortiz541d9202011-12-14 16:43:10 +01001547 u16 gt_len;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001548 int rc;
1549
1550 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1551
1552 pn533_tx_frame_init(dev->out_frame, PN533_CMD_IN_ATR);
1553
1554 param.tg = 1;
1555 param.next = 0;
1556 memcpy(PN533_FRAME_CMD_PARAMS_PTR(dev->out_frame), &param,
1557 sizeof(struct pn533_cmd_activate_param));
1558 dev->out_frame->datalen += sizeof(struct pn533_cmd_activate_param);
1559
1560 pn533_tx_frame_finish(dev->out_frame);
1561
1562 rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame,
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01001563 PN533_NORMAL_FRAME_MAX_LEN);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001564 if (rc)
1565 return rc;
1566
1567 resp = (struct pn533_cmd_activate_response *)
1568 PN533_FRAME_CMD_PARAMS_PTR(dev->in_frame);
1569 rc = resp->status & PN533_CMD_RET_MASK;
1570 if (rc != PN533_CMD_RET_SUCCESS)
1571 return -EIO;
1572
Samuel Ortiz541d9202011-12-14 16:43:10 +01001573 /* ATR_RES general bytes are located at offset 16 */
1574 gt_len = PN533_FRAME_CMD_PARAMS_LEN(dev->in_frame) - 16;
1575 rc = nfc_set_remote_general_bytes(dev->nfc_dev, resp->gt, gt_len);
1576
1577 return rc;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001578}
1579
Eric Lapuyade90099432012-05-07 12:31:13 +02001580static int pn533_activate_target(struct nfc_dev *nfc_dev,
1581 struct nfc_target *target, u32 protocol)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001582{
1583 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1584 int rc;
1585
1586 nfc_dev_dbg(&dev->interface->dev, "%s - protocol=%u", __func__,
1587 protocol);
1588
1589 if (dev->poll_mod_count) {
1590 nfc_dev_err(&dev->interface->dev, "Cannot activate while"
1591 " polling");
1592 return -EBUSY;
1593 }
1594
1595 if (dev->tgt_active_prot) {
1596 nfc_dev_err(&dev->interface->dev, "There is already an active"
1597 " target");
1598 return -EBUSY;
1599 }
1600
1601 if (!dev->tgt_available_prots) {
1602 nfc_dev_err(&dev->interface->dev, "There is no available target"
1603 " to activate");
1604 return -EINVAL;
1605 }
1606
1607 if (!(dev->tgt_available_prots & (1 << protocol))) {
1608 nfc_dev_err(&dev->interface->dev, "The target does not support"
1609 " the requested protocol %u", protocol);
1610 return -EINVAL;
1611 }
1612
1613 if (protocol == NFC_PROTO_NFC_DEP) {
1614 rc = pn533_activate_target_nfcdep(dev);
1615 if (rc) {
1616 nfc_dev_err(&dev->interface->dev, "Error %d when"
1617 " activating target with"
1618 " NFC_DEP protocol", rc);
1619 return rc;
1620 }
1621 }
1622
1623 dev->tgt_active_prot = protocol;
1624 dev->tgt_available_prots = 0;
1625
1626 return 0;
1627}
1628
Eric Lapuyade90099432012-05-07 12:31:13 +02001629static void pn533_deactivate_target(struct nfc_dev *nfc_dev,
1630 struct nfc_target *target)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001631{
1632 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1633 u8 tg;
1634 u8 status;
1635 int rc;
1636
1637 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1638
1639 if (!dev->tgt_active_prot) {
1640 nfc_dev_err(&dev->interface->dev, "There is no active target");
1641 return;
1642 }
1643
1644 dev->tgt_active_prot = 0;
1645
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02001646 skb_queue_purge(&dev->resp_q);
1647
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001648 pn533_tx_frame_init(dev->out_frame, PN533_CMD_IN_RELEASE);
1649
1650 tg = 1;
1651 memcpy(PN533_FRAME_CMD_PARAMS_PTR(dev->out_frame), &tg, sizeof(u8));
1652 dev->out_frame->datalen += sizeof(u8);
1653
1654 pn533_tx_frame_finish(dev->out_frame);
1655
1656 rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame,
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01001657 PN533_NORMAL_FRAME_MAX_LEN);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001658 if (rc) {
1659 nfc_dev_err(&dev->interface->dev, "Error when sending release"
1660 " command to the controller");
1661 return;
1662 }
1663
1664 status = PN533_FRAME_CMD_PARAMS_PTR(dev->in_frame)[0];
1665 rc = status & PN533_CMD_RET_MASK;
1666 if (rc != PN533_CMD_RET_SUCCESS)
1667 nfc_dev_err(&dev->interface->dev, "Error 0x%x when releasing"
1668 " the target", rc);
1669
1670 return;
1671}
1672
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001673
1674static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
1675 u8 *params, int params_len)
1676{
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001677 struct pn533_cmd_jump_dep_response *resp;
1678 struct nfc_target nfc_target;
1679 u8 target_gt_len;
1680 int rc;
Waldemar Rymarkiewicz70418e62012-10-11 14:04:00 +02001681 struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg;
1682 u8 active = cmd->active;
1683
1684 kfree(arg);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001685
1686 if (params_len == -ENOENT) {
1687 nfc_dev_dbg(&dev->interface->dev, "");
1688 return 0;
1689 }
1690
1691 if (params_len < 0) {
1692 nfc_dev_err(&dev->interface->dev,
1693 "Error %d when bringing DEP link up",
1694 params_len);
1695 return 0;
1696 }
1697
1698 if (dev->tgt_available_prots &&
1699 !(dev->tgt_available_prots & (1 << NFC_PROTO_NFC_DEP))) {
1700 nfc_dev_err(&dev->interface->dev,
1701 "The target does not support DEP");
1702 return -EINVAL;
1703 }
1704
1705 resp = (struct pn533_cmd_jump_dep_response *) params;
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001706 rc = resp->status & PN533_CMD_RET_MASK;
1707 if (rc != PN533_CMD_RET_SUCCESS) {
1708 nfc_dev_err(&dev->interface->dev,
1709 "Bringing DEP link up failed %d", rc);
1710 return 0;
1711 }
1712
1713 if (!dev->tgt_available_prots) {
1714 nfc_dev_dbg(&dev->interface->dev, "Creating new target");
1715
1716 nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
Samuel Ortiz2fbabfa2012-03-05 01:03:47 +01001717 nfc_target.nfcid1_len = 10;
1718 memcpy(nfc_target.nfcid1, resp->nfcid3t, nfc_target.nfcid1_len);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001719 rc = nfc_targets_found(dev->nfc_dev, &nfc_target, 1);
1720 if (rc)
1721 return 0;
1722
1723 dev->tgt_available_prots = 0;
1724 }
1725
1726 dev->tgt_active_prot = NFC_PROTO_NFC_DEP;
1727
1728 /* ATR_RES general bytes are located at offset 17 */
1729 target_gt_len = PN533_FRAME_CMD_PARAMS_LEN(dev->in_frame) - 17;
1730 rc = nfc_set_remote_general_bytes(dev->nfc_dev,
1731 resp->gt, target_gt_len);
1732 if (rc == 0)
1733 rc = nfc_dep_link_is_up(dev->nfc_dev,
1734 dev->nfc_dev->targets[0].idx,
Waldemar Rymarkiewicz70418e62012-10-11 14:04:00 +02001735 !active, NFC_RF_INITIATOR);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001736
1737 return 0;
1738}
1739
Samuel Ortiz41a8ec42012-05-31 17:44:44 +02001740static int pn533_mod_to_baud(struct pn533 *dev)
1741{
1742 switch (dev->poll_mod_curr) {
1743 case PN533_POLL_MOD_106KBPS_A:
1744 return 0;
1745 case PN533_POLL_MOD_212KBPS_FELICA:
1746 return 1;
1747 case PN533_POLL_MOD_424KBPS_FELICA:
1748 return 2;
1749 default:
1750 return -EINVAL;
1751 }
1752}
1753
Samuel Ortizd7f33452012-05-29 21:45:21 +02001754#define PASSIVE_DATA_LEN 5
Eric Lapuyade90099432012-05-07 12:31:13 +02001755static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
Samuel Ortiz47807d32012-03-05 01:03:50 +01001756 u8 comm_mode, u8* gb, size_t gb_len)
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001757{
1758 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1759 struct pn533_cmd_jump_dep *cmd;
Samuel Ortizd7f33452012-05-29 21:45:21 +02001760 u8 cmd_len, *data_ptr;
1761 u8 passive_data[PASSIVE_DATA_LEN] = {0x00, 0xff, 0xff, 0x00, 0x3};
Samuel Ortiz41a8ec42012-05-31 17:44:44 +02001762 int rc, baud;
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001763
1764 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1765
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001766 if (dev->poll_mod_count) {
1767 nfc_dev_err(&dev->interface->dev,
1768 "Cannot bring the DEP link up while polling");
1769 return -EBUSY;
1770 }
1771
1772 if (dev->tgt_active_prot) {
1773 nfc_dev_err(&dev->interface->dev,
1774 "There is already an active target");
1775 return -EBUSY;
1776 }
1777
Samuel Ortiz41a8ec42012-05-31 17:44:44 +02001778 baud = pn533_mod_to_baud(dev);
1779 if (baud < 0) {
1780 nfc_dev_err(&dev->interface->dev,
1781 "Invalid curr modulation %d", dev->poll_mod_curr);
1782 return baud;
1783 }
1784
Samuel Ortiz47807d32012-03-05 01:03:50 +01001785 cmd_len = sizeof(struct pn533_cmd_jump_dep) + gb_len;
Samuel Ortizd7f33452012-05-29 21:45:21 +02001786 if (comm_mode == NFC_COMM_PASSIVE)
1787 cmd_len += PASSIVE_DATA_LEN;
1788
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001789 cmd = kzalloc(cmd_len, GFP_KERNEL);
1790 if (cmd == NULL)
1791 return -ENOMEM;
1792
1793 pn533_tx_frame_init(dev->out_frame, PN533_CMD_IN_JUMP_FOR_DEP);
1794
1795 cmd->active = !comm_mode;
Samuel Ortizd7f33452012-05-29 21:45:21 +02001796 cmd->next = 0;
Samuel Ortiz41a8ec42012-05-31 17:44:44 +02001797 cmd->baud = baud;
Samuel Ortizd7f33452012-05-29 21:45:21 +02001798 data_ptr = cmd->data;
1799 if (comm_mode == NFC_COMM_PASSIVE && cmd->baud > 0) {
1800 memcpy(data_ptr, passive_data, PASSIVE_DATA_LEN);
1801 cmd->next |= 1;
1802 data_ptr += PASSIVE_DATA_LEN;
1803 }
1804
Samuel Ortiz47807d32012-03-05 01:03:50 +01001805 if (gb != NULL && gb_len > 0) {
Samuel Ortizd7f33452012-05-29 21:45:21 +02001806 cmd->next |= 4; /* We have some Gi */
1807 memcpy(data_ptr, gb, gb_len);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001808 } else {
1809 cmd->next = 0;
1810 }
1811
1812 memcpy(PN533_FRAME_CMD_PARAMS_PTR(dev->out_frame), cmd, cmd_len);
1813 dev->out_frame->datalen += cmd_len;
1814
1815 pn533_tx_frame_finish(dev->out_frame);
1816
1817 rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame,
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01001818 PN533_NORMAL_FRAME_MAX_LEN,
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +01001819 pn533_in_dep_link_up_complete, cmd);
Szymon Janc770f7502012-10-29 14:04:43 +01001820 if (rc < 0)
1821 kfree(cmd);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001822
1823 return rc;
1824}
1825
1826static int pn533_dep_link_down(struct nfc_dev *nfc_dev)
1827{
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02001828 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
1829
1830 pn533_poll_reset_mod_list(dev);
1831
Samuel Ortiz51ad3042012-05-31 20:01:32 +02001832 if (dev->tgt_mode || dev->tgt_active_prot) {
1833 pn533_send_ack(dev, GFP_KERNEL);
1834 usb_kill_urb(dev->in_urb);
1835 }
1836
1837 dev->tgt_active_prot = 0;
1838 dev->tgt_mode = 0;
1839
1840 skb_queue_purge(&dev->resp_q);
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01001841
1842 return 0;
1843}
1844
Samuel Ortizdadb06f2012-05-31 00:09:11 +02001845static int pn533_build_tx_frame(struct pn533 *dev, struct sk_buff *skb,
1846 bool target)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001847{
1848 int payload_len = skb->len;
1849 struct pn533_frame *out_frame;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001850 u8 tg;
1851
1852 nfc_dev_dbg(&dev->interface->dev, "%s - Sending %d bytes", __func__,
1853 payload_len);
1854
1855 if (payload_len > PN533_CMD_DATAEXCH_DATA_MAXLEN) {
1856 /* TODO: Implement support to multi-part data exchange */
1857 nfc_dev_err(&dev->interface->dev, "Data length greater than the"
1858 " max allowed: %d",
1859 PN533_CMD_DATAEXCH_DATA_MAXLEN);
1860 return -ENOSYS;
1861 }
1862
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01001863 skb_push(skb, PN533_FRAME_HEADER_LEN);
1864
Samuel Ortizdadb06f2012-05-31 00:09:11 +02001865 if (target == true) {
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02001866 switch (dev->device_type) {
Samuel Ortiza1fbbf12012-07-03 23:45:26 +02001867 case PN533_DEVICE_PASORI:
1868 if (dev->tgt_active_prot == NFC_PROTO_FELICA) {
Samuel Ortiza1fbbf12012-07-03 23:45:26 +02001869 out_frame = (struct pn533_frame *) skb->data;
1870 pn533_tx_frame_init(out_frame,
1871 PN533_CMD_IN_COMM_THRU);
1872
1873 break;
1874 }
1875
1876 default:
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02001877 skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN);
1878 out_frame = (struct pn533_frame *) skb->data;
1879 pn533_tx_frame_init(out_frame,
1880 PN533_CMD_IN_DATA_EXCHANGE);
1881 tg = 1;
1882 memcpy(PN533_FRAME_CMD_PARAMS_PTR(out_frame),
1883 &tg, sizeof(u8));
1884 out_frame->datalen += sizeof(u8);
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02001885
1886 break;
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02001887 }
1888
Samuel Ortizdadb06f2012-05-31 00:09:11 +02001889 } else {
1890 skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN - 1);
1891 out_frame = (struct pn533_frame *) skb->data;
1892 pn533_tx_frame_init(out_frame, PN533_CMD_TG_SET_DATA);
1893 }
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001894
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001895
1896 /* The data is already in the out_frame, just update the datalen */
1897 out_frame->datalen += payload_len;
1898
1899 pn533_tx_frame_finish(out_frame);
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01001900 skb_put(skb, PN533_FRAME_TAIL_LEN);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001901
1902 return 0;
1903}
1904
1905struct pn533_data_exchange_arg {
1906 struct sk_buff *skb_resp;
1907 struct sk_buff *skb_out;
1908 data_exchange_cb_t cb;
1909 void *cb_context;
1910};
1911
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02001912static struct sk_buff *pn533_build_response(struct pn533 *dev)
1913{
1914 struct sk_buff *skb, *tmp, *t;
1915 unsigned int skb_len = 0, tmp_len = 0;
1916
1917 nfc_dev_dbg(&dev->interface->dev, "%s\n", __func__);
1918
1919 if (skb_queue_empty(&dev->resp_q))
1920 return NULL;
1921
1922 if (skb_queue_len(&dev->resp_q) == 1) {
1923 skb = skb_dequeue(&dev->resp_q);
1924 goto out;
1925 }
1926
1927 skb_queue_walk_safe(&dev->resp_q, tmp, t)
1928 skb_len += tmp->len;
1929
1930 nfc_dev_dbg(&dev->interface->dev, "%s total length %d\n",
1931 __func__, skb_len);
1932
1933 skb = alloc_skb(skb_len, GFP_KERNEL);
1934 if (skb == NULL)
1935 goto out;
1936
1937 skb_put(skb, skb_len);
1938
1939 skb_queue_walk_safe(&dev->resp_q, tmp, t) {
1940 memcpy(skb->data + tmp_len, tmp->data, tmp->len);
1941 tmp_len += tmp->len;
1942 }
1943
1944out:
1945 skb_queue_purge(&dev->resp_q);
1946
1947 return skb;
1948}
1949
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001950static int pn533_data_exchange_complete(struct pn533 *dev, void *_arg,
1951 u8 *params, int params_len)
1952{
1953 struct pn533_data_exchange_arg *arg = _arg;
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02001954 struct sk_buff *skb = NULL, *skb_resp = arg->skb_resp;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001955 struct pn533_frame *in_frame = (struct pn533_frame *) skb_resp->data;
1956 int err = 0;
1957 u8 status;
1958 u8 cmd_ret;
1959
1960 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
1961
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02001962 dev_kfree_skb(arg->skb_out);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001963
1964 if (params_len < 0) { /* error */
1965 err = params_len;
1966 goto error;
1967 }
1968
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001969 status = params[0];
1970
1971 cmd_ret = status & PN533_CMD_RET_MASK;
1972 if (cmd_ret != PN533_CMD_RET_SUCCESS) {
1973 nfc_dev_err(&dev->interface->dev, "PN533 reported error %d when"
1974 " exchanging data", cmd_ret);
1975 err = -EIO;
1976 goto error;
1977 }
1978
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02001979 skb_put(skb_resp, PN533_FRAME_SIZE(in_frame));
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01001980 skb_pull(skb_resp, PN533_FRAME_HEADER_LEN);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001981 skb_pull(skb_resp, PN533_CMD_DATAEXCH_HEAD_LEN);
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01001982 skb_trim(skb_resp, skb_resp->len - PN533_FRAME_TAIL_LEN);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02001983 skb_queue_tail(&dev->resp_q, skb_resp);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001984
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02001985 if (status & PN533_CMD_MI_MASK) {
1986 queue_work(dev->wq, &dev->mi_work);
1987 return -EINPROGRESS;
1988 }
1989
1990 skb = pn533_build_response(dev);
1991 if (skb == NULL)
1992 goto error;
1993
1994 arg->cb(arg->cb_context, skb, 0);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03001995 kfree(arg);
1996 return 0;
1997
1998error:
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02001999 skb_queue_purge(&dev->resp_q);
2000 dev_kfree_skb(skb_resp);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002001 arg->cb(arg->cb_context, NULL, err);
2002 kfree(arg);
2003 return 0;
2004}
2005
Samuel Ortizbe9ae4c2012-05-16 15:55:48 +02002006static int pn533_transceive(struct nfc_dev *nfc_dev,
2007 struct nfc_target *target, struct sk_buff *skb,
2008 data_exchange_cb_t cb, void *cb_context)
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002009{
2010 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
2011 struct pn533_frame *out_frame, *in_frame;
2012 struct pn533_data_exchange_arg *arg;
2013 struct sk_buff *skb_resp;
2014 int skb_resp_len;
2015 int rc;
2016
2017 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2018
2019 if (!dev->tgt_active_prot) {
2020 nfc_dev_err(&dev->interface->dev, "Cannot exchange data if"
2021 " there is no active target");
2022 rc = -EINVAL;
2023 goto error;
2024 }
2025
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002026 rc = pn533_build_tx_frame(dev, skb, true);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002027 if (rc)
2028 goto error;
2029
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01002030 skb_resp_len = PN533_FRAME_HEADER_LEN +
2031 PN533_CMD_DATAEXCH_HEAD_LEN +
2032 PN533_CMD_DATAEXCH_DATA_MAXLEN +
2033 PN533_FRAME_TAIL_LEN;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002034
Samuel Ortiz7c7cd3b2011-12-14 16:43:06 +01002035 skb_resp = nfc_alloc_recv_skb(skb_resp_len, GFP_KERNEL);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002036 if (!skb_resp) {
2037 rc = -ENOMEM;
2038 goto error;
2039 }
2040
2041 in_frame = (struct pn533_frame *) skb_resp->data;
2042 out_frame = (struct pn533_frame *) skb->data;
2043
2044 arg = kmalloc(sizeof(struct pn533_data_exchange_arg), GFP_KERNEL);
2045 if (!arg) {
2046 rc = -ENOMEM;
2047 goto free_skb_resp;
2048 }
2049
2050 arg->skb_resp = skb_resp;
2051 arg->skb_out = skb;
2052 arg->cb = cb;
2053 arg->cb_context = cb_context;
2054
2055 rc = pn533_send_cmd_frame_async(dev, out_frame, in_frame, skb_resp_len,
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +01002056 pn533_data_exchange_complete, arg);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002057 if (rc) {
2058 nfc_dev_err(&dev->interface->dev, "Error %d when trying to"
2059 " perform data_exchange", rc);
2060 goto free_arg;
2061 }
2062
2063 return 0;
2064
2065free_arg:
2066 kfree(arg);
2067free_skb_resp:
2068 kfree_skb(skb_resp);
2069error:
2070 kfree_skb(skb);
2071 return rc;
2072}
2073
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002074static int pn533_tm_send_complete(struct pn533 *dev, void *arg,
2075 u8 *params, int params_len)
2076{
Thierry Escande5b412fd2012-11-15 18:24:28 +01002077 struct sk_buff *skb_out = arg;
2078
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002079 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2080
Thierry Escande5b412fd2012-11-15 18:24:28 +01002081 dev_kfree_skb(skb_out);
2082
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002083 if (params_len < 0) {
2084 nfc_dev_err(&dev->interface->dev,
2085 "Error %d when sending data",
2086 params_len);
2087
2088 return params_len;
2089 }
2090
2091 if (params_len > 0 && params[0] != 0) {
2092 nfc_tm_deactivated(dev->nfc_dev);
2093
Samuel Ortiz51ad3042012-05-31 20:01:32 +02002094 dev->tgt_mode = 0;
2095
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002096 return 0;
2097 }
2098
2099 queue_work(dev->wq, &dev->tg_work);
2100
2101 return 0;
2102}
2103
2104static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
2105{
2106 struct pn533 *dev = nfc_get_drvdata(nfc_dev);
2107 struct pn533_frame *out_frame;
2108 int rc;
2109
2110 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2111
2112 rc = pn533_build_tx_frame(dev, skb, false);
2113 if (rc)
2114 goto error;
2115
2116 out_frame = (struct pn533_frame *) skb->data;
2117
2118 rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame,
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01002119 PN533_NORMAL_FRAME_MAX_LEN,
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +01002120 pn533_tm_send_complete, skb);
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002121 if (rc) {
2122 nfc_dev_err(&dev->interface->dev,
2123 "Error %d when trying to send data", rc);
2124 goto error;
2125 }
2126
2127 return 0;
2128
2129error:
2130 kfree_skb(skb);
2131
2132 return rc;
2133}
2134
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002135static void pn533_wq_mi_recv(struct work_struct *work)
2136{
2137 struct pn533 *dev = container_of(work, struct pn533, mi_work);
2138 struct sk_buff *skb_cmd;
2139 struct pn533_data_exchange_arg *arg = dev->cmd_complete_arg;
2140 struct pn533_frame *out_frame, *in_frame;
2141 struct sk_buff *skb_resp;
2142 int skb_resp_len;
2143 int rc;
2144
2145 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2146
2147 /* This is a zero payload size skb */
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01002148 skb_cmd = alloc_skb(PN533_FRAME_HEADER_LEN +
2149 PN533_CMD_DATAEXCH_HEAD_LEN +
2150 PN533_FRAME_TAIL_LEN,
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002151 GFP_KERNEL);
2152 if (skb_cmd == NULL)
2153 goto error_cmd;
2154
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01002155 skb_reserve(skb_cmd,
2156 PN533_FRAME_HEADER_LEN + PN533_CMD_DATAEXCH_HEAD_LEN);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002157
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002158 rc = pn533_build_tx_frame(dev, skb_cmd, true);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002159 if (rc)
2160 goto error_frame;
2161
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01002162 skb_resp_len = PN533_FRAME_HEADER_LEN +
2163 PN533_CMD_DATAEXCH_HEAD_LEN +
2164 PN533_CMD_DATAEXCH_DATA_MAXLEN +
2165 PN533_FRAME_TAIL_LEN;
2166
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002167 skb_resp = alloc_skb(skb_resp_len, GFP_KERNEL);
2168 if (!skb_resp) {
2169 rc = -ENOMEM;
2170 goto error_frame;
2171 }
2172
2173 in_frame = (struct pn533_frame *) skb_resp->data;
2174 out_frame = (struct pn533_frame *) skb_cmd->data;
2175
2176 arg->skb_resp = skb_resp;
2177 arg->skb_out = skb_cmd;
2178
2179 rc = __pn533_send_cmd_frame_async(dev, out_frame, in_frame,
2180 skb_resp_len,
2181 pn533_data_exchange_complete,
Waldemar Rymarkiewiczd94ea4f2012-11-26 14:18:33 +01002182 dev->cmd_complete_arg);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002183 if (!rc)
2184 return;
2185
2186 nfc_dev_err(&dev->interface->dev, "Error %d when trying to"
2187 " perform data_exchange", rc);
2188
2189 kfree_skb(skb_resp);
2190
2191error_frame:
2192 kfree_skb(skb_cmd);
2193
2194error_cmd:
2195 pn533_send_ack(dev, GFP_KERNEL);
2196
2197 kfree(arg);
2198
Samuel Ortiz5d50b362012-08-17 23:47:54 +02002199 queue_work(dev->wq, &dev->cmd_work);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002200}
2201
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002202static int pn533_set_configuration(struct pn533 *dev, u8 cfgitem, u8 *cfgdata,
2203 u8 cfgdata_len)
2204{
2205 int rc;
2206 u8 *params;
2207
2208 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2209
2210 pn533_tx_frame_init(dev->out_frame, PN533_CMD_RF_CONFIGURATION);
2211
2212 params = PN533_FRAME_CMD_PARAMS_PTR(dev->out_frame);
2213 params[0] = cfgitem;
2214 memcpy(&params[1], cfgdata, cfgdata_len);
2215 dev->out_frame->datalen += (1 + cfgdata_len);
2216
2217 pn533_tx_frame_finish(dev->out_frame);
2218
2219 rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame,
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01002220 PN533_NORMAL_FRAME_MAX_LEN);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002221
2222 return rc;
2223}
2224
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002225static int pn533_fw_reset(struct pn533 *dev)
2226{
2227 int rc;
2228 u8 *params;
2229
2230 nfc_dev_dbg(&dev->interface->dev, "%s", __func__);
2231
2232 pn533_tx_frame_init(dev->out_frame, 0x18);
2233
2234 params = PN533_FRAME_CMD_PARAMS_PTR(dev->out_frame);
2235 params[0] = 0x1;
2236 dev->out_frame->datalen += 1;
2237
2238 pn533_tx_frame_finish(dev->out_frame);
2239
2240 rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame,
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01002241 PN533_NORMAL_FRAME_MAX_LEN);
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002242
2243 return rc;
2244}
2245
2246static struct nfc_ops pn533_nfc_ops = {
Ilan Elias8b3fe7b2011-09-18 11:19:33 +03002247 .dev_up = NULL,
2248 .dev_down = NULL,
Samuel Ortiz361f3cb2011-12-14 16:43:11 +01002249 .dep_link_up = pn533_dep_link_up,
2250 .dep_link_down = pn533_dep_link_down,
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002251 .start_poll = pn533_start_poll,
2252 .stop_poll = pn533_stop_poll,
2253 .activate_target = pn533_activate_target,
2254 .deactivate_target = pn533_deactivate_target,
Samuel Ortizbe9ae4c2012-05-16 15:55:48 +02002255 .im_transceive = pn533_transceive,
Samuel Ortizdadb06f2012-05-31 00:09:11 +02002256 .tm_send = pn533_tm_send,
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002257};
2258
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002259static int pn533_setup(struct pn533 *dev)
2260{
2261 struct pn533_config_max_retries max_retries;
2262 struct pn533_config_timing timing;
2263 u8 pasori_cfg[3] = {0x08, 0x01, 0x08};
2264 int rc;
2265
2266 switch (dev->device_type) {
2267 case PN533_DEVICE_STD:
2268 max_retries.mx_rty_atr = PN533_CONFIG_MAX_RETRIES_ENDLESS;
2269 max_retries.mx_rty_psl = 2;
2270 max_retries.mx_rty_passive_act =
2271 PN533_CONFIG_MAX_RETRIES_NO_RETRY;
2272
2273 timing.rfu = PN533_CONFIG_TIMING_102;
2274 timing.atr_res_timeout = PN533_CONFIG_TIMING_204;
2275 timing.dep_timeout = PN533_CONFIG_TIMING_409;
2276
2277 break;
2278
2279 case PN533_DEVICE_PASORI:
2280 max_retries.mx_rty_atr = 0x2;
2281 max_retries.mx_rty_psl = 0x1;
2282 max_retries.mx_rty_passive_act =
2283 PN533_CONFIG_MAX_RETRIES_NO_RETRY;
2284
2285 timing.rfu = PN533_CONFIG_TIMING_102;
2286 timing.atr_res_timeout = PN533_CONFIG_TIMING_102;
2287 timing.dep_timeout = PN533_CONFIG_TIMING_204;
2288
2289 break;
2290
2291 default:
2292 nfc_dev_err(&dev->interface->dev, "Unknown device type %d\n",
2293 dev->device_type);
2294 return -EINVAL;
2295 }
2296
2297 rc = pn533_set_configuration(dev, PN533_CFGITEM_MAX_RETRIES,
2298 (u8 *)&max_retries, sizeof(max_retries));
2299 if (rc) {
2300 nfc_dev_err(&dev->interface->dev,
2301 "Error on setting MAX_RETRIES config");
2302 return rc;
2303 }
2304
2305
2306 rc = pn533_set_configuration(dev, PN533_CFGITEM_TIMING,
2307 (u8 *)&timing, sizeof(timing));
2308 if (rc) {
2309 nfc_dev_err(&dev->interface->dev,
2310 "Error on setting RF timings");
2311 return rc;
2312 }
2313
2314 switch (dev->device_type) {
2315 case PN533_DEVICE_STD:
2316 break;
2317
2318 case PN533_DEVICE_PASORI:
2319 pn533_fw_reset(dev);
2320
2321 rc = pn533_set_configuration(dev, PN533_CFGITEM_PASORI,
2322 pasori_cfg, 3);
2323 if (rc) {
2324 nfc_dev_err(&dev->interface->dev,
2325 "Error while settings PASORI config");
2326 return rc;
2327 }
2328
2329 pn533_fw_reset(dev);
2330
2331 break;
2332 }
2333
2334 return 0;
2335}
2336
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002337static int pn533_probe(struct usb_interface *interface,
2338 const struct usb_device_id *id)
2339{
2340 struct pn533_fw_version *fw_ver;
2341 struct pn533 *dev;
2342 struct usb_host_interface *iface_desc;
2343 struct usb_endpoint_descriptor *endpoint;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002344 int in_endpoint = 0;
2345 int out_endpoint = 0;
2346 int rc = -ENOMEM;
2347 int i;
2348 u32 protocols;
2349
2350 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2351 if (!dev)
2352 return -ENOMEM;
2353
2354 dev->udev = usb_get_dev(interface_to_usbdev(interface));
2355 dev->interface = interface;
Samuel Ortiz0201ed02012-05-31 17:56:46 +02002356 mutex_init(&dev->cmd_lock);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002357
2358 iface_desc = interface->cur_altsetting;
2359 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
2360 endpoint = &iface_desc->endpoint[i].desc;
2361
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01002362 if (!in_endpoint && usb_endpoint_is_bulk_in(endpoint))
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002363 in_endpoint = endpoint->bEndpointAddress;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002364
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01002365 if (!out_endpoint && usb_endpoint_is_bulk_out(endpoint))
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002366 out_endpoint = endpoint->bEndpointAddress;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002367 }
2368
2369 if (!in_endpoint || !out_endpoint) {
2370 nfc_dev_err(&interface->dev, "Could not find bulk-in or"
2371 " bulk-out endpoint");
2372 rc = -ENODEV;
2373 goto error;
2374 }
2375
Waldemar Rymarkiewicz82dec342012-10-11 14:03:58 +02002376 dev->in_frame = kmalloc(PN533_NORMAL_FRAME_MAX_LEN, GFP_KERNEL);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002377 dev->in_urb = usb_alloc_urb(0, GFP_KERNEL);
Waldemar Rymarkiewicz82dec342012-10-11 14:03:58 +02002378 dev->out_frame = kmalloc(PN533_NORMAL_FRAME_MAX_LEN, GFP_KERNEL);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002379 dev->out_urb = usb_alloc_urb(0, GFP_KERNEL);
2380
2381 if (!dev->in_frame || !dev->out_frame ||
2382 !dev->in_urb || !dev->out_urb)
2383 goto error;
2384
2385 usb_fill_bulk_urb(dev->in_urb, dev->udev,
2386 usb_rcvbulkpipe(dev->udev, in_endpoint),
2387 NULL, 0, NULL, dev);
2388 usb_fill_bulk_urb(dev->out_urb, dev->udev,
2389 usb_sndbulkpipe(dev->udev, out_endpoint),
2390 NULL, 0,
2391 pn533_send_complete, dev);
2392
Samuel Ortiz5d50b362012-08-17 23:47:54 +02002393 INIT_WORK(&dev->cmd_work, pn533_wq_cmd);
2394 INIT_WORK(&dev->cmd_complete_work, pn533_wq_cmd_complete);
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002395 INIT_WORK(&dev->mi_work, pn533_wq_mi_recv);
Samuel Ortiz103b34c2012-05-31 00:07:51 +02002396 INIT_WORK(&dev->tg_work, pn533_wq_tg_get_data);
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02002397 INIT_WORK(&dev->poll_work, pn533_wq_poll);
Tejun Heo58637c92012-08-22 16:28:46 -07002398 dev->wq = alloc_ordered_workqueue("pn533", 0);
Samuel Ortiz4849f852012-04-10 19:43:17 +02002399 if (dev->wq == NULL)
2400 goto error;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002401
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02002402 init_timer(&dev->listen_timer);
2403 dev->listen_timer.data = (unsigned long) dev;
2404 dev->listen_timer.function = pn533_listen_mode_timer;
2405
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002406 skb_queue_head_init(&dev->resp_q);
2407
Samuel Ortiz5d50b362012-08-17 23:47:54 +02002408 INIT_LIST_HEAD(&dev->cmd_queue);
2409
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002410 usb_set_intfdata(interface, dev);
2411
2412 pn533_tx_frame_init(dev->out_frame, PN533_CMD_GET_FIRMWARE_VERSION);
2413 pn533_tx_frame_finish(dev->out_frame);
2414
2415 rc = pn533_send_cmd_frame_sync(dev, dev->out_frame, dev->in_frame,
Waldemar Rymarkiewicz8d25ca72012-11-26 14:18:30 +01002416 PN533_NORMAL_FRAME_MAX_LEN);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002417 if (rc)
Samuel Ortiz4849f852012-04-10 19:43:17 +02002418 goto destroy_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002419
2420 fw_ver = (struct pn533_fw_version *)
2421 PN533_FRAME_CMD_PARAMS_PTR(dev->in_frame);
2422 nfc_dev_info(&dev->interface->dev, "NXP PN533 firmware ver %d.%d now"
2423 " attached", fw_ver->ver, fw_ver->rev);
2424
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002425 dev->device_type = id->driver_info;
2426 switch (dev->device_type) {
2427 case PN533_DEVICE_STD:
2428 protocols = PN533_ALL_PROTOCOLS;
2429 break;
2430
2431 case PN533_DEVICE_PASORI:
2432 protocols = PN533_NO_TYPE_B_PROTOCOLS;
2433 break;
2434
2435 default:
2436 nfc_dev_err(&dev->interface->dev, "Unknown device type %d\n",
2437 dev->device_type);
2438 rc = -EINVAL;
2439 goto destroy_wq;
2440 }
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002441
Samuel Ortize8753042011-08-19 15:47:11 +02002442 dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols,
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01002443 PN533_FRAME_HEADER_LEN +
Samuel Ortize8753042011-08-19 15:47:11 +02002444 PN533_CMD_DATAEXCH_HEAD_LEN,
Waldemar Rymarkiewiczb1bb2902012-11-26 14:18:32 +01002445 PN533_FRAME_TAIL_LEN);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002446 if (!dev->nfc_dev)
Samuel Ortiz4849f852012-04-10 19:43:17 +02002447 goto destroy_wq;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002448
2449 nfc_set_parent_dev(dev->nfc_dev, &interface->dev);
2450 nfc_set_drvdata(dev->nfc_dev, dev);
2451
2452 rc = nfc_register_device(dev->nfc_dev);
2453 if (rc)
2454 goto free_nfc_dev;
2455
Samuel Ortiz5c7b0532012-07-02 20:04:01 +02002456 rc = pn533_setup(dev);
2457 if (rc)
Samuel Ortiz9f2f8ba2012-05-29 21:28:58 +02002458 goto unregister_nfc_dev;
Samuel Ortiz34a85bf2012-05-29 21:34:08 +02002459
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002460 return 0;
2461
Samuel Ortiz9f2f8ba2012-05-29 21:28:58 +02002462unregister_nfc_dev:
2463 nfc_unregister_device(dev->nfc_dev);
2464
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002465free_nfc_dev:
2466 nfc_free_device(dev->nfc_dev);
Samuel Ortiz9f2f8ba2012-05-29 21:28:58 +02002467
Samuel Ortiz4849f852012-04-10 19:43:17 +02002468destroy_wq:
2469 destroy_workqueue(dev->wq);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002470error:
2471 kfree(dev->in_frame);
2472 usb_free_urb(dev->in_urb);
2473 kfree(dev->out_frame);
2474 usb_free_urb(dev->out_urb);
2475 kfree(dev);
2476 return rc;
2477}
2478
2479static void pn533_disconnect(struct usb_interface *interface)
2480{
2481 struct pn533 *dev;
Samuel Ortiz5d50b362012-08-17 23:47:54 +02002482 struct pn533_cmd *cmd, *n;
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002483
2484 dev = usb_get_intfdata(interface);
2485 usb_set_intfdata(interface, NULL);
2486
2487 nfc_unregister_device(dev->nfc_dev);
2488 nfc_free_device(dev->nfc_dev);
2489
2490 usb_kill_urb(dev->in_urb);
2491 usb_kill_urb(dev->out_urb);
2492
Samuel Ortiz4849f852012-04-10 19:43:17 +02002493 destroy_workqueue(dev->wq);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002494
Samuel Ortiz6ff73fd2012-04-10 19:43:18 +02002495 skb_queue_purge(&dev->resp_q);
2496
Samuel Ortiz6fbbdc12012-05-30 17:20:25 +02002497 del_timer(&dev->listen_timer);
2498
Samuel Ortiz5d50b362012-08-17 23:47:54 +02002499 list_for_each_entry_safe(cmd, n, &dev->cmd_queue, queue) {
2500 list_del(&cmd->queue);
2501 kfree(cmd);
2502 }
2503
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002504 kfree(dev->in_frame);
2505 usb_free_urb(dev->in_urb);
2506 kfree(dev->out_frame);
2507 usb_free_urb(dev->out_urb);
2508 kfree(dev);
2509
Dan Carpenter276556d2011-07-08 10:21:15 +03002510 nfc_dev_info(&interface->dev, "NXP PN533 NFC device disconnected");
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002511}
2512
2513static struct usb_driver pn533_driver = {
2514 .name = "pn533",
2515 .probe = pn533_probe,
2516 .disconnect = pn533_disconnect,
2517 .id_table = pn533_table,
2518};
2519
Greg Kroah-Hartmanfe748482011-11-18 09:52:10 -08002520module_usb_driver(pn533_driver);
Aloisio Almeida Jrc46ee382011-07-01 19:31:37 -03002521
2522MODULE_AUTHOR("Lauro Ramos Venancio <lauro.venancio@openbossa.org>,"
2523 " Aloisio Almeida Jr <aloisio.almeida@openbossa.org>");
2524MODULE_DESCRIPTION("PN533 usb driver ver " VERSION);
2525MODULE_VERSION(VERSION);
2526MODULE_LICENSE("GPL");