1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Generic driver for NXP NCI NFC chips 4 * 5 * Copyright (C) 2014 NXP Semiconductors All rights reserved. 6 * 7 * Authors: Clément Perrochaud <clement.perrochaud@nxp.com> 8 * 9 * Derived from PN544 device driver: 10 * Copyright (C) 2012 Intel Corporation. All rights reserved. 11 */ 12 13 #include <linux/delay.h> 14 #include <linux/module.h> 15 #include <linux/nfc.h> 16 17 #include <net/nfc/nci_core.h> 18 19 #include "nxp-nci.h" 20 21 #define NXP_NCI_HDR_LEN 4 22 23 #define NXP_NCI_NFC_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \ 24 NFC_PROTO_MIFARE_MASK | \ 25 NFC_PROTO_FELICA_MASK | \ 26 NFC_PROTO_ISO14443_MASK | \ 27 NFC_PROTO_ISO14443_B_MASK | \ 28 NFC_PROTO_NFC_DEP_MASK) 29 30 #define NXP_NCI_RF_PLL_UNLOCKED_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x21) 31 #define NXP_NCI_RF_TXLDO_ERROR_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x23) 32 33 static int nxp_nci_open(struct nci_dev *ndev) 34 { 35 struct nxp_nci_info *info = nci_get_drvdata(ndev); 36 int r = 0; 37 38 mutex_lock(&info->info_lock); 39 40 if (info->mode != NXP_NCI_MODE_COLD) { 41 r = -EBUSY; 42 goto open_exit; 43 } 44 45 if (info->phy_ops->set_mode) 46 r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_NCI); 47 48 info->mode = NXP_NCI_MODE_NCI; 49 50 open_exit: 51 mutex_unlock(&info->info_lock); 52 return r; 53 } 54 55 static int nxp_nci_close(struct nci_dev *ndev) 56 { 57 struct nxp_nci_info *info = nci_get_drvdata(ndev); 58 int r = 0; 59 60 mutex_lock(&info->info_lock); 61 62 if (info->phy_ops->set_mode) 63 r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD); 64 65 info->mode = NXP_NCI_MODE_COLD; 66 67 mutex_unlock(&info->info_lock); 68 return r; 69 } 70 71 static int nxp_nci_send(struct nci_dev *ndev, struct sk_buff *skb) 72 { 73 struct nxp_nci_info *info = nci_get_drvdata(ndev); 74 int r; 75 76 if (!info->phy_ops->write) { 77 kfree_skb(skb); 78 return -EOPNOTSUPP; 79 } 80 81 if (info->mode != NXP_NCI_MODE_NCI) { 82 kfree_skb(skb); 83 return -EINVAL; 84 } 85 86 r = info->phy_ops->write(info->phy_id, skb); 87 if (r < 0) { 88 kfree_skb(skb); 89 return r; 90 } 91 92 consume_skb(skb); 93 return 0; 94 } 95 96 static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev, 97 struct sk_buff *skb) 98 { 99 nfc_err(&ndev->nfc_dev->dev, 100 "PLL didn't lock. Missing or unstable clock?\n"); 101 102 return 0; 103 } 104 105 static int nxp_nci_rf_txldo_error_ntf(struct nci_dev *ndev, 106 struct sk_buff *skb) 107 { 108 nfc_err(&ndev->nfc_dev->dev, 109 "RF transmitter couldn't start. Bad power and/or configuration?\n"); 110 111 return 0; 112 } 113 114 static const struct nci_driver_ops nxp_nci_core_ops[] = { 115 { 116 .opcode = NXP_NCI_RF_PLL_UNLOCKED_NTF, 117 .ntf = nxp_nci_rf_pll_unlocked_ntf, 118 }, 119 { 120 .opcode = NXP_NCI_RF_TXLDO_ERROR_NTF, 121 .ntf = nxp_nci_rf_txldo_error_ntf, 122 }, 123 }; 124 125 static const struct nci_ops nxp_nci_ops = { 126 .open = nxp_nci_open, 127 .close = nxp_nci_close, 128 .send = nxp_nci_send, 129 .fw_download = nxp_nci_fw_download, 130 .core_ops = nxp_nci_core_ops, 131 .n_core_ops = ARRAY_SIZE(nxp_nci_core_ops), 132 }; 133 134 int nxp_nci_probe(void *phy_id, struct device *pdev, 135 const struct nxp_nci_phy_ops *phy_ops, 136 unsigned int max_payload, 137 struct nci_dev **ndev) 138 { 139 struct nxp_nci_info *info; 140 int r; 141 142 info = devm_kzalloc(pdev, sizeof(struct nxp_nci_info), GFP_KERNEL); 143 if (!info) 144 return -ENOMEM; 145 146 info->phy_id = phy_id; 147 info->pdev = pdev; 148 info->phy_ops = phy_ops; 149 info->max_payload = max_payload; 150 INIT_WORK(&info->fw_info.work, nxp_nci_fw_work); 151 init_completion(&info->fw_info.cmd_completion); 152 mutex_init(&info->info_lock); 153 154 if (info->phy_ops->set_mode) { 155 r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD); 156 if (r < 0) 157 return r; 158 } 159 160 info->mode = NXP_NCI_MODE_COLD; 161 162 info->ndev = nci_allocate_device(&nxp_nci_ops, NXP_NCI_NFC_PROTOCOLS, 163 NXP_NCI_HDR_LEN, 0); 164 if (!info->ndev) 165 return -ENOMEM; 166 167 nci_set_parent_dev(info->ndev, pdev); 168 nci_set_drvdata(info->ndev, info); 169 r = nci_register_device(info->ndev); 170 if (r < 0) { 171 nci_free_device(info->ndev); 172 return r; 173 } 174 175 *ndev = info->ndev; 176 return r; 177 } 178 EXPORT_SYMBOL(nxp_nci_probe); 179 180 void nxp_nci_remove(struct nci_dev *ndev) 181 { 182 struct nxp_nci_info *info = nci_get_drvdata(ndev); 183 184 if (info->mode == NXP_NCI_MODE_FW) 185 nxp_nci_fw_work_complete(info, -ESHUTDOWN); 186 cancel_work_sync(&info->fw_info.work); 187 188 mutex_lock(&info->info_lock); 189 190 if (info->phy_ops->set_mode) 191 info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD); 192 193 nci_unregister_device(ndev); 194 nci_free_device(ndev); 195 196 mutex_unlock(&info->info_lock); 197 } 198 EXPORT_SYMBOL(nxp_nci_remove); 199 200 MODULE_LICENSE("GPL"); 201 MODULE_DESCRIPTION("NXP NCI NFC driver"); 202 MODULE_AUTHOR("Clément Perrochaud <clement.perrochaud@nxp.com>"); 203