0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/delay.h>
0014 #include <linux/module.h>
0015 #include <linux/nfc.h>
0016
0017 #include <net/nfc/nci_core.h>
0018
0019 #include "nxp-nci.h"
0020
0021 #define NXP_NCI_HDR_LEN 4
0022
0023 #define NXP_NCI_NFC_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
0024 NFC_PROTO_MIFARE_MASK | \
0025 NFC_PROTO_FELICA_MASK | \
0026 NFC_PROTO_ISO14443_MASK | \
0027 NFC_PROTO_ISO14443_B_MASK | \
0028 NFC_PROTO_NFC_DEP_MASK)
0029
0030 #define NXP_NCI_RF_PLL_UNLOCKED_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x21)
0031 #define NXP_NCI_RF_TXLDO_ERROR_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x23)
0032
0033 static int nxp_nci_open(struct nci_dev *ndev)
0034 {
0035 struct nxp_nci_info *info = nci_get_drvdata(ndev);
0036 int r = 0;
0037
0038 mutex_lock(&info->info_lock);
0039
0040 if (info->mode != NXP_NCI_MODE_COLD) {
0041 r = -EBUSY;
0042 goto open_exit;
0043 }
0044
0045 if (info->phy_ops->set_mode)
0046 r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_NCI);
0047
0048 info->mode = NXP_NCI_MODE_NCI;
0049
0050 open_exit:
0051 mutex_unlock(&info->info_lock);
0052 return r;
0053 }
0054
0055 static int nxp_nci_close(struct nci_dev *ndev)
0056 {
0057 struct nxp_nci_info *info = nci_get_drvdata(ndev);
0058 int r = 0;
0059
0060 mutex_lock(&info->info_lock);
0061
0062 if (info->phy_ops->set_mode)
0063 r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD);
0064
0065 info->mode = NXP_NCI_MODE_COLD;
0066
0067 mutex_unlock(&info->info_lock);
0068 return r;
0069 }
0070
0071 static int nxp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
0072 {
0073 struct nxp_nci_info *info = nci_get_drvdata(ndev);
0074 int r;
0075
0076 if (!info->phy_ops->write)
0077 return -EOPNOTSUPP;
0078
0079 if (info->mode != NXP_NCI_MODE_NCI)
0080 return -EINVAL;
0081
0082 r = info->phy_ops->write(info->phy_id, skb);
0083 if (r < 0)
0084 kfree_skb(skb);
0085
0086 return r;
0087 }
0088
0089 static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev,
0090 struct sk_buff *skb)
0091 {
0092 nfc_err(&ndev->nfc_dev->dev,
0093 "PLL didn't lock. Missing or unstable clock?\n");
0094
0095 return 0;
0096 }
0097
0098 static int nxp_nci_rf_txldo_error_ntf(struct nci_dev *ndev,
0099 struct sk_buff *skb)
0100 {
0101 nfc_err(&ndev->nfc_dev->dev,
0102 "RF transmitter couldn't start. Bad power and/or configuration?\n");
0103
0104 return 0;
0105 }
0106
0107 static const struct nci_driver_ops nxp_nci_core_ops[] = {
0108 {
0109 .opcode = NXP_NCI_RF_PLL_UNLOCKED_NTF,
0110 .ntf = nxp_nci_rf_pll_unlocked_ntf,
0111 },
0112 {
0113 .opcode = NXP_NCI_RF_TXLDO_ERROR_NTF,
0114 .ntf = nxp_nci_rf_txldo_error_ntf,
0115 },
0116 };
0117
0118 static const struct nci_ops nxp_nci_ops = {
0119 .open = nxp_nci_open,
0120 .close = nxp_nci_close,
0121 .send = nxp_nci_send,
0122 .fw_download = nxp_nci_fw_download,
0123 .core_ops = nxp_nci_core_ops,
0124 .n_core_ops = ARRAY_SIZE(nxp_nci_core_ops),
0125 };
0126
0127 int nxp_nci_probe(void *phy_id, struct device *pdev,
0128 const struct nxp_nci_phy_ops *phy_ops,
0129 unsigned int max_payload,
0130 struct nci_dev **ndev)
0131 {
0132 struct nxp_nci_info *info;
0133 int r;
0134
0135 info = devm_kzalloc(pdev, sizeof(struct nxp_nci_info), GFP_KERNEL);
0136 if (!info)
0137 return -ENOMEM;
0138
0139 info->phy_id = phy_id;
0140 info->pdev = pdev;
0141 info->phy_ops = phy_ops;
0142 info->max_payload = max_payload;
0143 INIT_WORK(&info->fw_info.work, nxp_nci_fw_work);
0144 init_completion(&info->fw_info.cmd_completion);
0145 mutex_init(&info->info_lock);
0146
0147 if (info->phy_ops->set_mode) {
0148 r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD);
0149 if (r < 0)
0150 return r;
0151 }
0152
0153 info->mode = NXP_NCI_MODE_COLD;
0154
0155 info->ndev = nci_allocate_device(&nxp_nci_ops, NXP_NCI_NFC_PROTOCOLS,
0156 NXP_NCI_HDR_LEN, 0);
0157 if (!info->ndev)
0158 return -ENOMEM;
0159
0160 nci_set_parent_dev(info->ndev, pdev);
0161 nci_set_drvdata(info->ndev, info);
0162 r = nci_register_device(info->ndev);
0163 if (r < 0) {
0164 nci_free_device(info->ndev);
0165 return r;
0166 }
0167
0168 *ndev = info->ndev;
0169 return r;
0170 }
0171 EXPORT_SYMBOL(nxp_nci_probe);
0172
0173 void nxp_nci_remove(struct nci_dev *ndev)
0174 {
0175 struct nxp_nci_info *info = nci_get_drvdata(ndev);
0176
0177 if (info->mode == NXP_NCI_MODE_FW)
0178 nxp_nci_fw_work_complete(info, -ESHUTDOWN);
0179 cancel_work_sync(&info->fw_info.work);
0180
0181 mutex_lock(&info->info_lock);
0182
0183 if (info->phy_ops->set_mode)
0184 info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD);
0185
0186 nci_unregister_device(ndev);
0187 nci_free_device(ndev);
0188
0189 mutex_unlock(&info->info_lock);
0190 }
0191 EXPORT_SYMBOL(nxp_nci_remove);
0192
0193 MODULE_LICENSE("GPL");
0194 MODULE_DESCRIPTION("NXP NCI NFC driver");
0195 MODULE_AUTHOR("Clément Perrochaud <clement.perrochaud@nxp.com>");