Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Christophe Ricard and committed by
Samuel Ortiz
79747280 a779b887

+72 -1
+72 -1
drivers/nfc/st21nfca/st21nfca.c
··· 33 33 #define ST21NFCA_RF_READER_CMD_PRESENCE_CHECK 0x30 34 34 35 35 #define ST21NFCA_RF_READER_ISO15693_GATE 0x12 36 + #define ST21NFCA_RF_READER_ISO15693_INVENTORY 0x01 36 37 37 38 /* 38 39 * Reader gate for communication with contact-less cards using Type A ··· 71 70 {ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_DEVICE_MGNT_PIPE}, 72 71 {ST21NFCA_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE}, 73 72 {ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE}, 73 + {ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE}, 74 74 }; 75 75 76 76 struct st21nfca_pipe_info { ··· 423 421 return r; 424 422 } 425 423 424 + static int st21nfca_get_iso15693_inventory(struct nfc_hci_dev *hdev, 425 + struct nfc_target *target) 426 + { 427 + int r; 428 + struct sk_buff *inventory_skb = NULL; 429 + 430 + r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_ISO15693_GATE, 431 + ST21NFCA_RF_READER_ISO15693_INVENTORY, 432 + &inventory_skb); 433 + if (r < 0) 434 + goto exit; 435 + 436 + skb_pull(inventory_skb, 2); 437 + 438 + if (inventory_skb->len == 0 || 439 + inventory_skb->len > NFC_ISO15693_UID_MAXSIZE) { 440 + r = -EPROTO; 441 + goto exit; 442 + } 443 + 444 + memcpy(target->iso15693_uid, inventory_skb->data, inventory_skb->len); 445 + target->iso15693_dsfid = inventory_skb->data[1]; 446 + target->is_iso15693 = 1; 447 + exit: 448 + kfree_skb(inventory_skb); 449 + return r; 450 + } 451 + 426 452 static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate, 427 453 struct nfc_target *target) 428 454 { ··· 492 462 } 493 463 494 464 break; 465 + case ST21NFCA_RF_READER_ISO15693_GATE: 466 + target->supported_protocols = NFC_PROTO_ISO15693_MASK; 467 + r = st21nfca_get_iso15693_inventory(hdev, target); 468 + if (r < 0) 469 + return r; 470 + break; 495 471 default: 496 472 return -EPROTO; 497 473 } 498 474 499 475 return 0; 476 + } 477 + 478 + #define ST21NFCA_CB_TYPE_READER_ISO15693 1 479 + static void st21nfca_hci_data_exchange_cb(void *context, struct sk_buff *skb, 480 + int err) 481 + { 482 + struct st21nfca_hci_info *info = context; 483 + 484 + switch (info->async_cb_type) { 485 + case ST21NFCA_CB_TYPE_READER_ISO15693: 486 + if (err == 0) 487 + skb_trim(skb, skb->len - 1); 488 + info->async_cb(info->async_cb_context, skb, err); 489 + break; 490 + default: 491 + if (err == 0) 492 + kfree_skb(skb); 493 + break; 494 + } 500 495 } 501 496 502 497 /* ··· 534 479 struct sk_buff *skb, 535 480 data_exchange_cb_t cb, void *cb_context) 536 481 { 482 + struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); 483 + 537 484 pr_info(DRIVER_DESC ": %s for gate=%d len=%d\n", __func__, 538 485 target->hci_reader_gate, skb->len); 539 486 ··· 551 494 return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, 552 495 ST21NFCA_WR_XCHG_DATA, skb->data, 553 496 skb->len, cb, cb_context); 497 + case ST21NFCA_RF_READER_ISO15693_GATE: 498 + info->async_cb_type = ST21NFCA_CB_TYPE_READER_ISO15693; 499 + info->async_cb = cb; 500 + info->async_cb_context = cb_context; 501 + 502 + *skb_push(skb, 1) = 0x17; 503 + 504 + return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate, 505 + ST21NFCA_WR_XCHG_DATA, skb->data, 506 + skb->len, 507 + st21nfca_hci_data_exchange_cb, 508 + info); 509 + break; 554 510 default: 555 511 return 1; 556 512 } ··· 647 577 NFC_PROTO_MIFARE_MASK | 648 578 NFC_PROTO_FELICA_MASK | 649 579 NFC_PROTO_ISO14443_MASK | 650 - NFC_PROTO_ISO14443_B_MASK; 580 + NFC_PROTO_ISO14443_B_MASK | 581 + NFC_PROTO_ISO15693_MASK; 651 582 652 583 set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks); 653 584