diff options
Diffstat (limited to 'drivers/nfc/pn544')
-rw-r--r-- | drivers/nfc/pn544/Kconfig | 23 | ||||
-rw-r--r-- | drivers/nfc/pn544/Makefile | 5 | ||||
-rw-r--r-- | drivers/nfc/pn544/i2c.c | 44 | ||||
-rw-r--r-- | drivers/nfc/pn544/pn544.c | 65 |
4 files changed, 75 insertions, 62 deletions
diff --git a/drivers/nfc/pn544/Kconfig b/drivers/nfc/pn544/Kconfig new file mode 100644 index 000000000000..c277790ac71c --- /dev/null +++ b/drivers/nfc/pn544/Kconfig | |||
@@ -0,0 +1,23 @@ | |||
1 | config NFC_PN544 | ||
2 | tristate "NXP PN544 NFC driver" | ||
3 | depends on NFC_HCI | ||
4 | select CRC_CCITT | ||
5 | default n | ||
6 | ---help--- | ||
7 | NXP PN544 core driver. | ||
8 | This is a driver based on the HCI NFC kernel layers and | ||
9 | will thus not work with NXP libnfc library. | ||
10 | |||
11 | To compile this driver as a module, choose m here. The module will | ||
12 | be called pn544. | ||
13 | Say N if unsure. | ||
14 | |||
15 | config NFC_PN544_I2C | ||
16 | tristate "NFC PN544 i2c support" | ||
17 | depends on NFC_PN544 && I2C && NFC_SHDLC | ||
18 | ---help--- | ||
19 | This module adds support for the NXP pn544 i2c interface. | ||
20 | Select this if your platform is using the i2c bus. | ||
21 | |||
22 | If you choose to build a module, it'll be called pn544_i2c. | ||
23 | Say N if unsure. \ No newline at end of file | ||
diff --git a/drivers/nfc/pn544/Makefile b/drivers/nfc/pn544/Makefile index 725733881eb3..ac076793687d 100644 --- a/drivers/nfc/pn544/Makefile +++ b/drivers/nfc/pn544/Makefile | |||
@@ -2,6 +2,7 @@ | |||
2 | # Makefile for PN544 HCI based NFC driver | 2 | # Makefile for PN544 HCI based NFC driver |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_PN544_HCI_NFC) += pn544_i2c.o | 5 | pn544_i2c-objs = i2c.o |
6 | 6 | ||
7 | pn544_i2c-y := pn544.o i2c.o | 7 | obj-$(CONFIG_NFC_PN544) += pn544.o |
8 | obj-$(CONFIG_NFC_PN544_I2C) += pn544_i2c.o | ||
diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c index 2a9c8d93d2e8..8cf64c19f022 100644 --- a/drivers/nfc/pn544/i2c.c +++ b/drivers/nfc/pn544/i2c.c | |||
@@ -376,12 +376,12 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, | |||
376 | return -ENODEV; | 376 | return -ENODEV; |
377 | } | 377 | } |
378 | 378 | ||
379 | phy = kzalloc(sizeof(struct pn544_i2c_phy), GFP_KERNEL); | 379 | phy = devm_kzalloc(&client->dev, sizeof(struct pn544_i2c_phy), |
380 | GFP_KERNEL); | ||
380 | if (!phy) { | 381 | if (!phy) { |
381 | dev_err(&client->dev, | 382 | dev_err(&client->dev, |
382 | "Cannot allocate memory for pn544 i2c phy.\n"); | 383 | "Cannot allocate memory for pn544 i2c phy.\n"); |
383 | r = -ENOMEM; | 384 | return -ENOMEM; |
384 | goto err_phy_alloc; | ||
385 | } | 385 | } |
386 | 386 | ||
387 | phy->i2c_dev = client; | 387 | phy->i2c_dev = client; |
@@ -390,20 +390,18 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, | |||
390 | pdata = client->dev.platform_data; | 390 | pdata = client->dev.platform_data; |
391 | if (pdata == NULL) { | 391 | if (pdata == NULL) { |
392 | dev_err(&client->dev, "No platform data\n"); | 392 | dev_err(&client->dev, "No platform data\n"); |
393 | r = -EINVAL; | 393 | return -EINVAL; |
394 | goto err_pdata; | ||
395 | } | 394 | } |
396 | 395 | ||
397 | if (pdata->request_resources == NULL) { | 396 | if (pdata->request_resources == NULL) { |
398 | dev_err(&client->dev, "request_resources() missing\n"); | 397 | dev_err(&client->dev, "request_resources() missing\n"); |
399 | r = -EINVAL; | 398 | return -EINVAL; |
400 | goto err_pdata; | ||
401 | } | 399 | } |
402 | 400 | ||
403 | r = pdata->request_resources(client); | 401 | r = pdata->request_resources(client); |
404 | if (r) { | 402 | if (r) { |
405 | dev_err(&client->dev, "Cannot get platform resources\n"); | 403 | dev_err(&client->dev, "Cannot get platform resources\n"); |
406 | goto err_pdata; | 404 | return r; |
407 | } | 405 | } |
408 | 406 | ||
409 | phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); | 407 | phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); |
@@ -435,10 +433,6 @@ err_rti: | |||
435 | if (pdata->free_resources != NULL) | 433 | if (pdata->free_resources != NULL) |
436 | pdata->free_resources(); | 434 | pdata->free_resources(); |
437 | 435 | ||
438 | err_pdata: | ||
439 | kfree(phy); | ||
440 | |||
441 | err_phy_alloc: | ||
442 | return r; | 436 | return r; |
443 | } | 437 | } |
444 | 438 | ||
@@ -458,8 +452,6 @@ static int pn544_hci_i2c_remove(struct i2c_client *client) | |||
458 | if (pdata->free_resources) | 452 | if (pdata->free_resources) |
459 | pdata->free_resources(); | 453 | pdata->free_resources(); |
460 | 454 | ||
461 | kfree(phy); | ||
462 | |||
463 | return 0; | 455 | return 0; |
464 | } | 456 | } |
465 | 457 | ||
@@ -472,29 +464,7 @@ static struct i2c_driver pn544_hci_i2c_driver = { | |||
472 | .remove = pn544_hci_i2c_remove, | 464 | .remove = pn544_hci_i2c_remove, |
473 | }; | 465 | }; |
474 | 466 | ||
475 | static int __init pn544_hci_i2c_init(void) | 467 | module_i2c_driver(pn544_hci_i2c_driver); |
476 | { | ||
477 | int r; | ||
478 | |||
479 | pr_debug(DRIVER_DESC ": %s\n", __func__); | ||
480 | |||
481 | r = i2c_add_driver(&pn544_hci_i2c_driver); | ||
482 | if (r) { | ||
483 | pr_err(PN544_HCI_I2C_DRIVER_NAME | ||
484 | ": driver registration failed\n"); | ||
485 | return r; | ||
486 | } | ||
487 | |||
488 | return 0; | ||
489 | } | ||
490 | |||
491 | static void __exit pn544_hci_i2c_exit(void) | ||
492 | { | ||
493 | i2c_del_driver(&pn544_hci_i2c_driver); | ||
494 | } | ||
495 | |||
496 | module_init(pn544_hci_i2c_init); | ||
497 | module_exit(pn544_hci_i2c_exit); | ||
498 | 468 | ||
499 | MODULE_LICENSE("GPL"); | 469 | MODULE_LICENSE("GPL"); |
500 | MODULE_DESCRIPTION(DRIVER_DESC); | 470 | MODULE_DESCRIPTION(DRIVER_DESC); |
diff --git a/drivers/nfc/pn544/pn544.c b/drivers/nfc/pn544/pn544.c index cc666de3b8e5..9c5f16e7baef 100644 --- a/drivers/nfc/pn544/pn544.c +++ b/drivers/nfc/pn544/pn544.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/module.h> | ||
23 | 24 | ||
24 | #include <linux/nfc.h> | 25 | #include <linux/nfc.h> |
25 | #include <net/nfc/hci.h> | 26 | #include <net/nfc/hci.h> |
@@ -675,11 +676,17 @@ static int pn544_hci_im_transceive(struct nfc_hci_dev *hdev, | |||
675 | 676 | ||
676 | static int pn544_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb) | 677 | static int pn544_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb) |
677 | { | 678 | { |
679 | int r; | ||
680 | |||
678 | /* Set default false for multiple information chaining */ | 681 | /* Set default false for multiple information chaining */ |
679 | *skb_push(skb, 1) = 0; | 682 | *skb_push(skb, 1) = 0; |
680 | 683 | ||
681 | return nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, | 684 | r = nfc_hci_send_event(hdev, PN544_RF_READER_NFCIP1_TARGET_GATE, |
682 | PN544_HCI_EVT_SND_DATA, skb->data, skb->len); | 685 | PN544_HCI_EVT_SND_DATA, skb->data, skb->len); |
686 | |||
687 | kfree_skb(skb); | ||
688 | |||
689 | return r; | ||
683 | } | 690 | } |
684 | 691 | ||
685 | static int pn544_hci_check_presence(struct nfc_hci_dev *hdev, | 692 | static int pn544_hci_check_presence(struct nfc_hci_dev *hdev, |
@@ -714,35 +721,40 @@ static int pn544_hci_check_presence(struct nfc_hci_dev *hdev, | |||
714 | return 0; | 721 | return 0; |
715 | } | 722 | } |
716 | 723 | ||
717 | static void pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, | 724 | /* |
718 | u8 event, struct sk_buff *skb) | 725 | * Returns: |
726 | * <= 0: driver handled the event, skb consumed | ||
727 | * 1: driver does not handle the event, please do standard processing | ||
728 | */ | ||
729 | static int pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event, | ||
730 | struct sk_buff *skb) | ||
719 | { | 731 | { |
720 | struct sk_buff *rgb_skb = NULL; | 732 | struct sk_buff *rgb_skb = NULL; |
721 | int r = 0; | 733 | int r; |
722 | 734 | ||
723 | pr_debug("hci event %d", event); | 735 | pr_debug("hci event %d", event); |
724 | switch (event) { | 736 | switch (event) { |
725 | case PN544_HCI_EVT_ACTIVATED: | 737 | case PN544_HCI_EVT_ACTIVATED: |
726 | if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) | 738 | if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) { |
727 | nfc_hci_target_discovered(hdev, gate); | 739 | r = nfc_hci_target_discovered(hdev, gate); |
728 | else if (gate == PN544_RF_READER_NFCIP1_TARGET_GATE) { | 740 | } else if (gate == PN544_RF_READER_NFCIP1_TARGET_GATE) { |
729 | r = nfc_hci_get_param(hdev, gate, PN544_DEP_ATR_REQ, | 741 | r = nfc_hci_get_param(hdev, gate, PN544_DEP_ATR_REQ, |
730 | &rgb_skb); | 742 | &rgb_skb); |
731 | |||
732 | if (r < 0) | 743 | if (r < 0) |
733 | goto exit; | 744 | goto exit; |
734 | 745 | ||
735 | nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK, | 746 | r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK, |
736 | NFC_COMM_PASSIVE, rgb_skb->data, | 747 | NFC_COMM_PASSIVE, rgb_skb->data, |
737 | rgb_skb->len); | 748 | rgb_skb->len); |
738 | 749 | ||
739 | kfree_skb(rgb_skb); | 750 | kfree_skb(rgb_skb); |
751 | } else { | ||
752 | r = -EINVAL; | ||
740 | } | 753 | } |
741 | |||
742 | break; | 754 | break; |
743 | case PN544_HCI_EVT_DEACTIVATED: | 755 | case PN544_HCI_EVT_DEACTIVATED: |
744 | nfc_hci_send_event(hdev, gate, | 756 | r = nfc_hci_send_event(hdev, gate, NFC_HCI_EVT_END_OPERATION, |
745 | NFC_HCI_EVT_END_OPERATION, NULL, 0); | 757 | NULL, 0); |
746 | break; | 758 | break; |
747 | case PN544_HCI_EVT_RCV_DATA: | 759 | case PN544_HCI_EVT_RCV_DATA: |
748 | if (skb->len < 2) { | 760 | if (skb->len < 2) { |
@@ -757,15 +769,15 @@ static void pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, | |||
757 | } | 769 | } |
758 | 770 | ||
759 | skb_pull(skb, 2); | 771 | skb_pull(skb, 2); |
760 | nfc_tm_data_received(hdev->ndev, skb); | 772 | return nfc_tm_data_received(hdev->ndev, skb); |
761 | |||
762 | return; | ||
763 | default: | 773 | default: |
764 | break; | 774 | return 1; |
765 | } | 775 | } |
766 | 776 | ||
767 | exit: | 777 | exit: |
768 | kfree_skb(skb); | 778 | kfree_skb(skb); |
779 | |||
780 | return r; | ||
769 | } | 781 | } |
770 | 782 | ||
771 | static struct nfc_hci_ops pn544_hci_ops = { | 783 | static struct nfc_hci_ops pn544_hci_ops = { |
@@ -789,7 +801,7 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, | |||
789 | struct nfc_hci_dev **hdev) | 801 | struct nfc_hci_dev **hdev) |
790 | { | 802 | { |
791 | struct pn544_hci_info *info; | 803 | struct pn544_hci_info *info; |
792 | u32 protocols; | 804 | u32 protocols, se; |
793 | struct nfc_hci_init_data init_data; | 805 | struct nfc_hci_init_data init_data; |
794 | int r; | 806 | int r; |
795 | 807 | ||
@@ -822,8 +834,10 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, | |||
822 | NFC_PROTO_ISO14443_B_MASK | | 834 | NFC_PROTO_ISO14443_B_MASK | |
823 | NFC_PROTO_NFC_DEP_MASK; | 835 | NFC_PROTO_NFC_DEP_MASK; |
824 | 836 | ||
825 | info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, | 837 | se = NFC_SE_UICC | NFC_SE_EMBEDDED; |
826 | protocols, llc_name, | 838 | |
839 | info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, 0, | ||
840 | protocols, se, llc_name, | ||
827 | phy_headroom + PN544_CMDS_HEADROOM, | 841 | phy_headroom + PN544_CMDS_HEADROOM, |
828 | phy_tailroom, phy_payload); | 842 | phy_tailroom, phy_payload); |
829 | if (!info->hdev) { | 843 | if (!info->hdev) { |
@@ -851,6 +865,7 @@ err_alloc_hdev: | |||
851 | err_info_alloc: | 865 | err_info_alloc: |
852 | return r; | 866 | return r; |
853 | } | 867 | } |
868 | EXPORT_SYMBOL(pn544_hci_probe); | ||
854 | 869 | ||
855 | void pn544_hci_remove(struct nfc_hci_dev *hdev) | 870 | void pn544_hci_remove(struct nfc_hci_dev *hdev) |
856 | { | 871 | { |
@@ -860,3 +875,7 @@ void pn544_hci_remove(struct nfc_hci_dev *hdev) | |||
860 | nfc_hci_free_device(hdev); | 875 | nfc_hci_free_device(hdev); |
861 | kfree(info); | 876 | kfree(info); |
862 | } | 877 | } |
878 | EXPORT_SYMBOL(pn544_hci_remove); | ||
879 | |||
880 | MODULE_LICENSE("GPL"); | ||
881 | MODULE_DESCRIPTION(DRIVER_DESC); | ||