aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nfc
diff options
context:
space:
mode:
authorChristophe Ricard <christophe.ricard@gmail.com>2014-05-13 16:03:42 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2014-05-19 18:48:28 -0400
commit7974728094d35f38775417a26d8f30ea3602496a (patch)
tree706107db0e911312647d4b153a8df265fc5a8b09 /drivers/nfc
parenta779b8878c20a5cafff26d774eed4d36a903882a (diff)
NFC: st21nfca: Add ISO15693 Reader/Writer support
Add support for ISO/IEC 15693 RF technology and Type 5 tags. ISO15963 is using proprietary gate 12. Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc')
-rw-r--r--drivers/nfc/st21nfca/st21nfca.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/drivers/nfc/st21nfca/st21nfca.c b/drivers/nfc/st21nfca/st21nfca.c
index d9ee3d0c1a78..51e0f00b3a4f 100644
--- a/drivers/nfc/st21nfca/st21nfca.c
+++ b/drivers/nfc/st21nfca/st21nfca.c
@@ -33,6 +33,7 @@
33#define ST21NFCA_RF_READER_CMD_PRESENCE_CHECK 0x30 33#define ST21NFCA_RF_READER_CMD_PRESENCE_CHECK 0x30
34 34
35#define ST21NFCA_RF_READER_ISO15693_GATE 0x12 35#define ST21NFCA_RF_READER_ISO15693_GATE 0x12
36#define ST21NFCA_RF_READER_ISO15693_INVENTORY 0x01
36 37
37/* 38/*
38 * Reader gate for communication with contact-less cards using Type A 39 * Reader gate for communication with contact-less cards using Type A
@@ -70,6 +71,7 @@ static struct nfc_hci_gate st21nfca_gates[] = {
70 {ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_DEVICE_MGNT_PIPE}, 71 {ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_DEVICE_MGNT_PIPE},
71 {ST21NFCA_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE}, 72 {ST21NFCA_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE},
72 {ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE}, 73 {ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE},
74 {ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE},
73}; 75};
74 76
75struct st21nfca_pipe_info { 77struct st21nfca_pipe_info {
@@ -421,6 +423,34 @@ exit:
421 return r; 423 return r;
422} 424}
423 425
426static int st21nfca_get_iso15693_inventory(struct nfc_hci_dev *hdev,
427 struct nfc_target *target)
428{
429 int r;
430 struct sk_buff *inventory_skb = NULL;
431
432 r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_ISO15693_GATE,
433 ST21NFCA_RF_READER_ISO15693_INVENTORY,
434 &inventory_skb);
435 if (r < 0)
436 goto exit;
437
438 skb_pull(inventory_skb, 2);
439
440 if (inventory_skb->len == 0 ||
441 inventory_skb->len > NFC_ISO15693_UID_MAXSIZE) {
442 r = -EPROTO;
443 goto exit;
444 }
445
446 memcpy(target->iso15693_uid, inventory_skb->data, inventory_skb->len);
447 target->iso15693_dsfid = inventory_skb->data[1];
448 target->is_iso15693 = 1;
449exit:
450 kfree_skb(inventory_skb);
451 return r;
452}
453
424static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, 454static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
425 struct nfc_target *target) 455 struct nfc_target *target)
426{ 456{
@@ -462,6 +492,12 @@ static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
462 } 492 }
463 493
464 break; 494 break;
495 case ST21NFCA_RF_READER_ISO15693_GATE:
496 target->supported_protocols = NFC_PROTO_ISO15693_MASK;
497 r = st21nfca_get_iso15693_inventory(hdev, target);
498 if (r < 0)
499 return r;
500 break;
465 default: 501 default:
466 return -EPROTO; 502 return -EPROTO;
467 } 503 }
@@ -469,6 +505,25 @@ static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
469 return 0; 505 return 0;
470} 506}
471 507
508#define ST21NFCA_CB_TYPE_READER_ISO15693 1
509static void st21nfca_hci_data_exchange_cb(void *context, struct sk_buff *skb,
510 int err)
511{
512 struct st21nfca_hci_info *info = context;
513
514 switch (info->async_cb_type) {
515 case ST21NFCA_CB_TYPE_READER_ISO15693:
516 if (err == 0)
517 skb_trim(skb, skb->len - 1);
518 info->async_cb(info->async_cb_context, skb, err);
519 break;
520 default:
521 if (err == 0)
522 kfree_skb(skb);
523 break;
524 }
525}
526
472/* 527/*
473 * Returns: 528 * Returns:
474 * <= 0: driver handled the data exchange 529 * <= 0: driver handled the data exchange
@@ -479,6 +534,8 @@ static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev,
479 struct sk_buff *skb, 534 struct sk_buff *skb,
480 data_exchange_cb_t cb, void *cb_context) 535 data_exchange_cb_t cb, void *cb_context)
481{ 536{
537 struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
538
482 pr_info(DRIVER_DESC ": %s for gate=%d len=%d\n", __func__, 539 pr_info(DRIVER_DESC ": %s for gate=%d len=%d\n", __func__,
483 target->hci_reader_gate, skb->len); 540 target->hci_reader_gate, skb->len);
484 541
@@ -494,6 +551,19 @@ static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev,
494 return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, 551 return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
495 ST21NFCA_WR_XCHG_DATA, skb->data, 552 ST21NFCA_WR_XCHG_DATA, skb->data,
496 skb->len, cb, cb_context); 553 skb->len, cb, cb_context);
554 case ST21NFCA_RF_READER_ISO15693_GATE:
555 info->async_cb_type = ST21NFCA_CB_TYPE_READER_ISO15693;
556 info->async_cb = cb;
557 info->async_cb_context = cb_context;
558
559 *skb_push(skb, 1) = 0x17;
560
561 return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
562 ST21NFCA_WR_XCHG_DATA, skb->data,
563 skb->len,
564 st21nfca_hci_data_exchange_cb,
565 info);
566 break;
497 default: 567 default:
498 return 1; 568 return 1;
499 } 569 }
@@ -577,7 +647,8 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
577 NFC_PROTO_MIFARE_MASK | 647 NFC_PROTO_MIFARE_MASK |
578 NFC_PROTO_FELICA_MASK | 648 NFC_PROTO_FELICA_MASK |
579 NFC_PROTO_ISO14443_MASK | 649 NFC_PROTO_ISO14443_MASK |
580 NFC_PROTO_ISO14443_B_MASK; 650 NFC_PROTO_ISO14443_B_MASK |
651 NFC_PROTO_ISO15693_MASK;
581 652
582 set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks); 653 set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks);
583 654