diff options
| author | Clément Perrochaud <clement.perrochaud@nxp.com> | 2015-03-09 06:12:04 -0400 |
|---|---|---|
| committer | Samuel Ortiz <sameo@linux.intel.com> | 2015-03-26 06:07:50 -0400 |
| commit | dece45855a8b0d1dcf48eb01d0822070ded6a4c8 (patch) | |
| tree | ed467e14ac657acdc27ceddec268a4bacfe8e20f | |
| parent | 25af01ed18a282e7d324e5694fe67b85ac412994 (diff) | |
NFC: nxp-nci: Add support for NXP NCI chips
Add support for NXP NCI NFC controllers such as the NPC100 or PN7150
families.
Signed-off-by: Clément Perrochaud <clement.perrochaud@effinnov.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
| -rw-r--r-- | MAINTAINERS | 7 | ||||
| -rw-r--r-- | drivers/nfc/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/nfc/Makefile | 1 | ||||
| -rw-r--r-- | drivers/nfc/nxp-nci/Kconfig | 13 | ||||
| -rw-r--r-- | drivers/nfc/nxp-nci/Makefile | 9 | ||||
| -rw-r--r-- | drivers/nfc/nxp-nci/core.c | 186 | ||||
| -rw-r--r-- | drivers/nfc/nxp-nci/firmware.c | 324 | ||||
| -rw-r--r-- | drivers/nfc/nxp-nci/nxp-nci.h | 89 | ||||
| -rw-r--r-- | include/linux/platform_data/nxp-nci.h | 27 |
9 files changed, 657 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index c2016557b294..12fdf22a77b0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -6937,6 +6937,13 @@ S: Supported | |||
| 6937 | F: drivers/block/nvme* | 6937 | F: drivers/block/nvme* |
| 6938 | F: include/linux/nvme.h | 6938 | F: include/linux/nvme.h |
| 6939 | 6939 | ||
| 6940 | NXP-NCI NFC DRIVER | ||
| 6941 | M: Clément Perrochaud <clement.perrochaud@effinnov.com> | ||
| 6942 | R: Charles Gorand <charles.gorand@effinnov.com> | ||
| 6943 | L: linux-nfc@lists.01.org (moderated for non-subscribers) | ||
| 6944 | S: Supported | ||
| 6945 | F: drivers/nfc/nxp-nci | ||
| 6946 | |||
| 6940 | NXP TDA998X DRM DRIVER | 6947 | NXP TDA998X DRM DRIVER |
| 6941 | M: Russell King <rmk+kernel@arm.linux.org.uk> | 6948 | M: Russell King <rmk+kernel@arm.linux.org.uk> |
| 6942 | S: Supported | 6949 | S: Supported |
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig index 7929fac13e1c..107714e4405f 100644 --- a/drivers/nfc/Kconfig +++ b/drivers/nfc/Kconfig | |||
| @@ -73,4 +73,5 @@ source "drivers/nfc/microread/Kconfig" | |||
| 73 | source "drivers/nfc/nfcmrvl/Kconfig" | 73 | source "drivers/nfc/nfcmrvl/Kconfig" |
| 74 | source "drivers/nfc/st21nfca/Kconfig" | 74 | source "drivers/nfc/st21nfca/Kconfig" |
| 75 | source "drivers/nfc/st21nfcb/Kconfig" | 75 | source "drivers/nfc/st21nfcb/Kconfig" |
| 76 | source "drivers/nfc/nxp-nci/Kconfig" | ||
| 76 | endmenu | 77 | endmenu |
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile index 6b23a2c6e34a..a4292d790f9b 100644 --- a/drivers/nfc/Makefile +++ b/drivers/nfc/Makefile | |||
| @@ -13,5 +13,6 @@ obj-$(CONFIG_NFC_MRVL) += nfcmrvl/ | |||
| 13 | obj-$(CONFIG_NFC_TRF7970A) += trf7970a.o | 13 | obj-$(CONFIG_NFC_TRF7970A) += trf7970a.o |
| 14 | obj-$(CONFIG_NFC_ST21NFCA) += st21nfca/ | 14 | obj-$(CONFIG_NFC_ST21NFCA) += st21nfca/ |
| 15 | obj-$(CONFIG_NFC_ST21NFCB) += st21nfcb/ | 15 | obj-$(CONFIG_NFC_ST21NFCB) += st21nfcb/ |
| 16 | obj-$(CONFIG_NFC_NXP_NCI) += nxp-nci/ | ||
| 16 | 17 | ||
| 17 | ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG | 18 | ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG |
diff --git a/drivers/nfc/nxp-nci/Kconfig b/drivers/nfc/nxp-nci/Kconfig new file mode 100644 index 000000000000..5f60c7cf02e8 --- /dev/null +++ b/drivers/nfc/nxp-nci/Kconfig | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | config NFC_NXP_NCI | ||
| 2 | tristate "NXP-NCI NFC driver" | ||
| 3 | depends on NFC_NCI | ||
| 4 | default n | ||
| 5 | ---help--- | ||
| 6 | Generic core driver for NXP NCI chips such as the NPC100 | ||
| 7 | or PN7150 families. | ||
| 8 | This is a driver based on the NCI 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 nxp_nci. | ||
| 13 | Say N if unsure. | ||
diff --git a/drivers/nfc/nxp-nci/Makefile b/drivers/nfc/nxp-nci/Makefile new file mode 100644 index 000000000000..8f1e32826961 --- /dev/null +++ b/drivers/nfc/nxp-nci/Makefile | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | # | ||
| 2 | # Makefile for NXP-NCI NFC driver | ||
| 3 | # | ||
| 4 | |||
| 5 | nxp-nci-objs = core.o firmware.o | ||
| 6 | |||
| 7 | obj-$(CONFIG_NFC_NXP_NCI) += nxp-nci.o | ||
| 8 | |||
| 9 | ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG | ||
diff --git a/drivers/nfc/nxp-nci/core.c b/drivers/nfc/nxp-nci/core.c new file mode 100644 index 000000000000..8979636d48ea --- /dev/null +++ b/drivers/nfc/nxp-nci/core.c | |||
| @@ -0,0 +1,186 @@ | |||
| 1 | /* | ||
| 2 | * Generic driver for NXP NCI NFC chips | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 NXP Semiconductors All rights reserved. | ||
| 5 | * | ||
| 6 | * Authors: Clément Perrochaud <clement.perrochaud@nxp.com> | ||
| 7 | * | ||
| 8 | * Derived from PN544 device driver: | ||
| 9 | * Copyright (C) 2012 Intel Corporation. All rights reserved. | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify it | ||
| 12 | * under the terms and conditions of the GNU General Public License, | ||
| 13 | * version 2, as published by the Free Software Foundation. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/delay.h> | ||
| 25 | #include <linux/gpio.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/nfc.h> | ||
| 28 | #include <linux/platform_data/nxp-nci.h> | ||
| 29 | |||
| 30 | #include <net/nfc/nci_core.h> | ||
| 31 | |||
| 32 | #include "nxp-nci.h" | ||
| 33 | |||
| 34 | #define NXP_NCI_HDR_LEN 4 | ||
| 35 | |||
| 36 | #define NXP_NCI_NFC_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \ | ||
| 37 | NFC_PROTO_MIFARE_MASK | \ | ||
| 38 | NFC_PROTO_FELICA_MASK | \ | ||
| 39 | NFC_PROTO_ISO14443_MASK | \ | ||
| 40 | NFC_PROTO_ISO14443_B_MASK | \ | ||
| 41 | NFC_PROTO_NFC_DEP_MASK) | ||
| 42 | |||
| 43 | static int nxp_nci_open(struct nci_dev *ndev) | ||
| 44 | { | ||
| 45 | struct nxp_nci_info *info = nci_get_drvdata(ndev); | ||
| 46 | int r = 0; | ||
| 47 | |||
| 48 | mutex_lock(&info->info_lock); | ||
| 49 | |||
| 50 | if (info->mode != NXP_NCI_MODE_COLD) { | ||
| 51 | r = -EBUSY; | ||
| 52 | goto open_exit; | ||
| 53 | } | ||
| 54 | |||
| 55 | if (info->phy_ops->set_mode) | ||
| 56 | r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_NCI); | ||
| 57 | |||
| 58 | info->mode = NXP_NCI_MODE_NCI; | ||
| 59 | |||
| 60 | open_exit: | ||
| 61 | mutex_unlock(&info->info_lock); | ||
| 62 | return r; | ||
| 63 | } | ||
| 64 | |||
| 65 | static int nxp_nci_close(struct nci_dev *ndev) | ||
| 66 | { | ||
| 67 | struct nxp_nci_info *info = nci_get_drvdata(ndev); | ||
| 68 | int r = 0; | ||
| 69 | |||
| 70 | mutex_lock(&info->info_lock); | ||
| 71 | |||
| 72 | if (info->phy_ops->set_mode) | ||
| 73 | r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD); | ||
| 74 | |||
| 75 | info->mode = NXP_NCI_MODE_COLD; | ||
| 76 | |||
| 77 | mutex_unlock(&info->info_lock); | ||
| 78 | return r; | ||
| 79 | } | ||
| 80 | |||
| 81 | static int nxp_nci_send(struct nci_dev *ndev, struct sk_buff *skb) | ||
| 82 | { | ||
| 83 | struct nxp_nci_info *info = nci_get_drvdata(ndev); | ||
| 84 | int r; | ||
| 85 | |||
| 86 | if (!info->phy_ops->write) { | ||
| 87 | r = -ENOTSUPP; | ||
| 88 | goto send_exit; | ||
| 89 | } | ||
| 90 | |||
| 91 | if (info->mode != NXP_NCI_MODE_NCI) { | ||
| 92 | r = -EINVAL; | ||
| 93 | goto send_exit; | ||
| 94 | } | ||
| 95 | |||
| 96 | r = info->phy_ops->write(info->phy_id, skb); | ||
| 97 | if (r < 0) | ||
| 98 | kfree_skb(skb); | ||
| 99 | |||
| 100 | send_exit: | ||
| 101 | return r; | ||
| 102 | } | ||
| 103 | |||
| 104 | static struct nci_ops nxp_nci_ops = { | ||
| 105 | .open = nxp_nci_open, | ||
| 106 | .close = nxp_nci_close, | ||
| 107 | .send = nxp_nci_send, | ||
| 108 | .fw_download = nxp_nci_fw_download, | ||
| 109 | }; | ||
| 110 | |||
| 111 | int nxp_nci_probe(void *phy_id, struct device *pdev, | ||
| 112 | struct nxp_nci_phy_ops *phy_ops, unsigned int max_payload, | ||
| 113 | struct nci_dev **ndev) | ||
| 114 | { | ||
| 115 | struct nxp_nci_info *info; | ||
| 116 | int r; | ||
| 117 | |||
| 118 | info = devm_kzalloc(pdev, sizeof(struct nxp_nci_info), GFP_KERNEL); | ||
| 119 | if (!info) { | ||
| 120 | r = -ENOMEM; | ||
| 121 | goto probe_exit; | ||
| 122 | } | ||
| 123 | |||
