port100.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Sony NFC Port-100 Series driver
  3. * Copyright (c) 2013, Intel Corporation.
  4. *
  5. * Partly based/Inspired by Stephen Tiedemann's nfcpy
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms and conditions of the GNU General Public License,
  9. * version 2, as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14. * more details.
  15. *
  16. */
  17. #include <linux/module.h>
  18. #include <linux/usb.h>
  19. #include <net/nfc/digital.h>
  20. #define VERSION "0.1"
  21. #define SONY_VENDOR_ID 0x054c
  22. #define RCS380_PRODUCT_ID 0x06c1
  23. #define PORT100_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
  24. NFC_PROTO_MIFARE_MASK | \
  25. NFC_PROTO_FELICA_MASK | \
  26. NFC_PROTO_NFC_DEP_MASK)
  27. #define PORT100_CAPABILITIES (NFC_DIGITAL_DRV_CAPS_IN_CRC | \
  28. NFC_DIGITAL_DRV_CAPS_TG_CRC)
  29. struct port100 {
  30. struct nfc_digital_dev *nfc_digital_dev;
  31. int skb_headroom;
  32. int skb_tailroom;
  33. struct usb_device *udev;
  34. struct usb_interface *interface;
  35. };
  36. static void port100_abort_cmd(struct nfc_digital_dev *ddev)
  37. {
  38. }
  39. static int port100_switch_rf(struct nfc_digital_dev *ddev, bool on)
  40. {
  41. return -EOPNOTSUPP;
  42. }
  43. static int port100_in_configure_hw(struct nfc_digital_dev *ddev, int type,
  44. int param)
  45. {
  46. return -EOPNOTSUPP;
  47. }
  48. static int port100_in_send_cmd(struct nfc_digital_dev *ddev,
  49. struct sk_buff *skb, u16 _timeout,
  50. nfc_digital_cmd_complete_t cb, void *arg)
  51. {
  52. return -EOPNOTSUPP;
  53. }
  54. static int port100_tg_configure_hw(struct nfc_digital_dev *ddev, int type,
  55. int param)
  56. {
  57. return -EOPNOTSUPP;
  58. }
  59. static int port100_tg_send_cmd(struct nfc_digital_dev *ddev,
  60. struct sk_buff *skb, u16 timeout,
  61. nfc_digital_cmd_complete_t cb, void *arg)
  62. {
  63. return -EOPNOTSUPP;
  64. }
  65. static int port100_listen_mdaa(struct nfc_digital_dev *ddev,
  66. struct digital_tg_mdaa_params *params,
  67. u16 timeout,
  68. nfc_digital_cmd_complete_t cb, void *arg)
  69. {
  70. return -EOPNOTSUPP;
  71. }
  72. static int port100_listen(struct nfc_digital_dev *ddev, u16 timeout,
  73. nfc_digital_cmd_complete_t cb, void *arg)
  74. {
  75. return -EOPNOTSUPP;
  76. }
  77. static struct nfc_digital_ops port100_digital_ops = {
  78. .in_configure_hw = port100_in_configure_hw,
  79. .in_send_cmd = port100_in_send_cmd,
  80. .tg_listen_mdaa = port100_listen_mdaa,
  81. .tg_listen = port100_listen,
  82. .tg_configure_hw = port100_tg_configure_hw,
  83. .tg_send_cmd = port100_tg_send_cmd,
  84. .switch_rf = port100_switch_rf,
  85. .abort_cmd = port100_abort_cmd,
  86. };
  87. static const struct usb_device_id port100_table[] = {
  88. { .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
  89. .idVendor = SONY_VENDOR_ID,
  90. .idProduct = RCS380_PRODUCT_ID,
  91. },
  92. { }
  93. };
  94. MODULE_DEVICE_TABLE(usb, port100_table);
  95. static int port100_probe(struct usb_interface *interface,
  96. const struct usb_device_id *id)
  97. {
  98. struct port100 *dev;
  99. int rc;
  100. dev = devm_kzalloc(&interface->dev, sizeof(struct port100), GFP_KERNEL);
  101. if (!dev)
  102. return -ENOMEM;
  103. dev->udev = usb_get_dev(interface_to_usbdev(interface));
  104. dev->interface = interface;
  105. usb_set_intfdata(interface, dev);
  106. nfc_info(&interface->dev, "Sony NFC Port-100 Series attached\n");
  107. dev->nfc_digital_dev = nfc_digital_allocate_device(&port100_digital_ops,
  108. PORT100_PROTOCOLS,
  109. PORT100_CAPABILITIES,
  110. dev->skb_headroom,
  111. dev->skb_tailroom);
  112. if (!dev->nfc_digital_dev) {
  113. nfc_err(&interface->dev,
  114. "Could not allocate nfc_digital_dev.\n");
  115. rc = -ENOMEM;
  116. goto error;
  117. }
  118. nfc_digital_set_parent_dev(dev->nfc_digital_dev, &interface->dev);
  119. nfc_digital_set_drvdata(dev->nfc_digital_dev, dev);
  120. rc = nfc_digital_register_device(dev->nfc_digital_dev);
  121. if (rc) {
  122. nfc_err(&interface->dev,
  123. "Could not register digital device.\n");
  124. goto free_nfc_dev;
  125. }
  126. return 0;
  127. free_nfc_dev:
  128. nfc_digital_free_device(dev->nfc_digital_dev);
  129. error:
  130. return rc;
  131. }
  132. static void port100_disconnect(struct usb_interface *interface)
  133. {
  134. struct port100 *dev;
  135. dev = usb_get_intfdata(interface);
  136. usb_set_intfdata(interface, NULL);
  137. nfc_digital_unregister_device(dev->nfc_digital_dev);
  138. nfc_digital_free_device(dev->nfc_digital_dev);
  139. nfc_info(&interface->dev, "Sony Port-100 NFC device disconnected");
  140. }
  141. static struct usb_driver port100_driver = {
  142. .name = "port100",
  143. .probe = port100_probe,
  144. .disconnect = port100_disconnect,
  145. .id_table = port100_table,
  146. };
  147. module_usb_driver(port100_driver);
  148. MODULE_DESCRIPTION("NFC Port-100 series usb driver ver " VERSION);
  149. MODULE_VERSION(VERSION);
  150. MODULE_LICENSE("GPL");