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 return -EOPNOTSUPP; 78 79 if (info->mode != NXP_NCI_MODE_NCI) 80 return -EINVAL; 81 82 r = info->phy_ops->write(info->phy_id, skb); 83 if (r < 0) { 84 kfree_skb(skb); 85 return r; 86 } 87 88 consume_skb(skb); 89 return 0; 90 } 91 92 static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev, 93 struct sk_buff *skb) 94 { 95 nfc_err(&ndev->nfc_dev->dev, 96 "PLL didn't lock. Missing or unstable clock?\n"); 97 98 return 0; 99 } 100 101 static int nxp_nci_rf_txldo_error_ntf(struct nci_dev *ndev, 102 struct sk_buff *skb) 103 { 104 nfc_err(&ndev->nfc_dev->dev, 105 "RF transmitter couldn't start. Bad power and/or configuration?\n"); 106 107 return 0; 108 } 109 110 static const struct nci_driver_ops nxp_nci_core_ops[] = { 111 { 112 .opcode = NXP_NCI_RF_PLL_UNLOCKED_NTF, 113 .ntf = nxp_nci_rf_pll_unlocked_ntf, 114 }, 115 { 116 .opcode = NXP_NCI_RF_TXLDO_ERROR_NTF, 117 .ntf = nxp_nci_rf_txldo_error_ntf, 118 }, 119 }; 120 121 static const struct nci_ops nxp_nci_ops = { 122 .open = nxp_nci_open, 123 .close = nxp_nci_close, 124 .send = nxp_nci_send, 125 .fw_download = nxp_nci_fw_download, 126 .core_ops = nxp_nci_core_ops, 127 .n_core_ops = ARRAY_SIZE(nxp_nci_core_ops), 128 }; 129 130 int nxp_nci_probe(void *phy_id, struct device *pdev, 131 const struct nxp_nci_phy_ops *phy_ops, 132 unsigned int max_payload, 133 struct nci_dev **ndev) 134 { 135 struct nxp_nci_info *info; 136 int r; 137 138 info = devm_kzalloc(pdev, sizeof(struct nxp_nci_info), GFP_KERNEL); 139 if (!info) 140 return -ENOMEM; 141 142 info->phy_id = phy_id; 143 info->pdev = pdev; 144 info->phy_ops = phy_ops; 145 info->max_payload = max_payload; 146 INIT_WORK(&info->fw_info.work, nxp_nci_fw_work); 147 init_completion(&info->fw_info.cmd_completion); 148 mutex_init(&info->info_lock); 149 150 if (info->phy_ops->set_mode) { 151 r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD); 152 if (r < 0) 153 return r; 154 } 155 156 info->mode = NXP_NCI_MODE_COLD; 157 158 info->ndev = nci_allocate_device(&nxp_nci_ops, NXP_NCI_NFC_PROTOCOLS, 159 NXP_NCI_HDR_LEN, 0); 160 if (!info->ndev) 161 return -ENOMEM; 162 163 nci_set_parent_dev(info->ndev, pdev); 164 nci_set_drvdata(info->ndev, info); 165 r = nci_register_device(info->ndev); 166 if (r < 0) { 167 nci_free_device(info->ndev); 168 return r; 169 } 170 171 *ndev = info->ndev; 172 return r; 173 } 174 EXPORT_SYMBOL(nxp_nci_probe); 175 176 void nxp_nci_remove(struct nci_dev *ndev) 177 { 178 struct nxp_nci_info *info = nci_get_drvdata(ndev); 179 180 if (info->mode == NXP_NCI_MODE_FW) 181 nxp_nci_fw_work_complete(info, -ESHUTDOWN); 182 cancel_work_sync(&info->fw_info.work); 183 184 mutex_lock(&info->info_lock); 185 186 if (info->phy_ops->set_mode) 187 info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD); 188 189 nci_unregister_device(ndev); 190 nci_free_device(ndev); 191 192 mutex_unlock(&info->info_lock); 193 } 194 EXPORT_SYMBOL(nxp_nci_remove); 195 196 MODULE_LICENSE("GPL"); 197 MODULE_DESCRIPTION("NXP NCI NFC driver"); 198 MODULE_AUTHOR("Clément Perrochaud <clement.perrochaud@nxp.com>"); 199