core.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. #include <linux/delay.h>
  13. #include <linux/module.h>
  14. #include <linux/nfc.h>
  15. #include <net/nfc/nci_core.h>
  16. #include "nxp-nci.h"
  17. #define NXP_NCI_HDR_LEN 4
  18. #define NXP_NCI_NFC_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
  19. NFC_PROTO_MIFARE_MASK | \
  20. NFC_PROTO_FELICA_MASK | \
  21. NFC_PROTO_ISO14443_MASK | \
  22. NFC_PROTO_ISO14443_B_MASK | \
  23. NFC_PROTO_NFC_DEP_MASK)
  24. #define NXP_NCI_RF_PLL_UNLOCKED_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x21)
  25. #define NXP_NCI_RF_TXLDO_ERROR_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x23)
  26. static int nxp_nci_open(struct nci_dev *ndev)
  27. {
  28. struct nxp_nci_info *info = nci_get_drvdata(ndev);
  29. int r = 0;
  30. mutex_lock(&info->info_lock);
  31. if (info->mode != NXP_NCI_MODE_COLD) {
  32. r = -EBUSY;
  33. goto open_exit;
  34. }
  35. if (info->phy_ops->set_mode)
  36. r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_NCI);
  37. info->mode = NXP_NCI_MODE_NCI;
  38. open_exit:
  39. mutex_unlock(&info->info_lock);
  40. return r;
  41. }
  42. static int nxp_nci_close(struct nci_dev *ndev)
  43. {
  44. struct nxp_nci_info *info = nci_get_drvdata(ndev);
  45. int r = 0;
  46. mutex_lock(&info->info_lock);
  47. if (info->phy_ops->set_mode)
  48. r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD);
  49. info->mode = NXP_NCI_MODE_COLD;
  50. mutex_unlock(&info->info_lock);
  51. return r;
  52. }
  53. static int nxp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
  54. {
  55. struct nxp_nci_info *info = nci_get_drvdata(ndev);
  56. int r;
  57. if (!info->phy_ops->write) {
  58. kfree_skb(skb);
  59. return -EOPNOTSUPP;
  60. }
  61. if (info->mode != NXP_NCI_MODE_NCI) {
  62. kfree_skb(skb);
  63. return -EINVAL;
  64. }
  65. r = info->phy_ops->write(info->phy_id, skb);
  66. if (r < 0) {
  67. kfree_skb(skb);
  68. return r;
  69. }
  70. consume_skb(skb);
  71. return 0;
  72. }
  73. static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev,
  74. struct sk_buff *skb)
  75. {
  76. nfc_err(&ndev->nfc_dev->dev,
  77. "PLL didn't lock. Missing or unstable clock?\n");
  78. return 0;
  79. }
  80. static int nxp_nci_rf_txldo_error_ntf(struct nci_dev *ndev,
  81. struct sk_buff *skb)
  82. {
  83. nfc_err(&ndev->nfc_dev->dev,
  84. "RF transmitter couldn't start. Bad power and/or configuration?\n");
  85. return 0;
  86. }
  87. static const struct nci_driver_ops nxp_nci_core_ops[] = {
  88. {
  89. .opcode = NXP_NCI_RF_PLL_UNLOCKED_NTF,
  90. .ntf = nxp_nci_rf_pll_unlocked_ntf,
  91. },
  92. {
  93. .opcode = NXP_NCI_RF_TXLDO_ERROR_NTF,
  94. .ntf = nxp_nci_rf_txldo_error_ntf,
  95. },
  96. };
  97. static const struct nci_ops nxp_nci_ops = {
  98. .open = nxp_nci_open,
  99. .close = nxp_nci_close,
  100. .send = nxp_nci_send,
  101. .fw_download = nxp_nci_fw_download,
  102. .core_ops = nxp_nci_core_ops,
  103. .n_core_ops = ARRAY_SIZE(nxp_nci_core_ops),
  104. };
  105. int nxp_nci_probe(void *phy_id, struct device *pdev,
  106. const struct nxp_nci_phy_ops *phy_ops,
  107. unsigned int max_payload,
  108. struct nci_dev **ndev)
  109. {
  110. struct nxp_nci_info *info;
  111. int r;
  112. info = devm_kzalloc(pdev, sizeof(struct nxp_nci_info), GFP_KERNEL);
  113. if (!info)
  114. return -ENOMEM;
  115. info->phy_id = phy_id;
  116. info->pdev = pdev;
  117. info->phy_ops = phy_ops;
  118. info->max_payload = max_payload;
  119. INIT_WORK(&info->fw_info.work, nxp_nci_fw_work);
  120. init_completion(&info->fw_info.cmd_completion);
  121. mutex_init(&info->info_lock);
  122. if (info->phy_ops->set_mode) {
  123. r = info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD);
  124. if (r < 0)
  125. return r;
  126. }
  127. info->mode = NXP_NCI_MODE_COLD;
  128. info->ndev = nci_allocate_device(&nxp_nci_ops, NXP_NCI_NFC_PROTOCOLS,
  129. NXP_NCI_HDR_LEN, 0);
  130. if (!info->ndev)
  131. return -ENOMEM;
  132. nci_set_parent_dev(info->ndev, pdev);
  133. nci_set_drvdata(info->ndev, info);
  134. r = nci_register_device(info->ndev);
  135. if (r < 0) {
  136. nci_free_device(info->ndev);
  137. return r;
  138. }
  139. *ndev = info->ndev;
  140. return r;
  141. }
  142. EXPORT_SYMBOL(nxp_nci_probe);
  143. void nxp_nci_remove(struct nci_dev *ndev)
  144. {
  145. struct nxp_nci_info *info = nci_get_drvdata(ndev);
  146. if (info->mode == NXP_NCI_MODE_FW)
  147. nxp_nci_fw_work_complete(info, -ESHUTDOWN);
  148. cancel_work_sync(&info->fw_info.work);
  149. mutex_lock(&info->info_lock);
  150. if (info->phy_ops->set_mode)
  151. info->phy_ops->set_mode(info->phy_id, NXP_NCI_MODE_COLD);
  152. nci_unregister_device(ndev);
  153. nci_free_device(ndev);
  154. mutex_unlock(&info->info_lock);
  155. }
  156. EXPORT_SYMBOL(nxp_nci_remove);
  157. MODULE_LICENSE("GPL");
  158. MODULE_DESCRIPTION("NXP NCI NFC driver");
  159. MODULE_AUTHOR("Clément Perrochaud <clement.perrochaud@nxp.com>");