spi.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * ----------------------------------------------------------------------------
  3. * drivers/nfc/st95hf/spi.c function definitions for SPI communication
  4. * ----------------------------------------------------------------------------
  5. * Copyright (C) 2015 STMicroelectronics Pvt. Ltd. All rights reserved.
  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 that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "spi.h"
  20. /* Function to send user provided buffer to ST95HF through SPI */
  21. int st95hf_spi_send(struct st95hf_spi_context *spicontext,
  22. unsigned char *buffertx,
  23. int datalen,
  24. enum req_type reqtype)
  25. {
  26. struct spi_message m;
  27. int result = 0;
  28. struct spi_device *spidev = spicontext->spidev;
  29. struct spi_transfer tx_transfer = {
  30. .tx_buf = buffertx,
  31. .len = datalen,
  32. };
  33. mutex_lock(&spicontext->spi_lock);
  34. if (reqtype == SYNC) {
  35. spicontext->req_issync = true;
  36. reinit_completion(&spicontext->done);
  37. } else {
  38. spicontext->req_issync = false;
  39. }
  40. spi_message_init(&m);
  41. spi_message_add_tail(&tx_transfer, &m);
  42. result = spi_sync(spidev, &m);
  43. if (result) {
  44. dev_err(&spidev->dev, "error: sending cmd to st95hf using SPI = %d\n",
  45. result);
  46. mutex_unlock(&spicontext->spi_lock);
  47. return result;
  48. }
  49. /* return for asynchronous or no-wait case */
  50. if (reqtype == ASYNC) {
  51. mutex_unlock(&spicontext->spi_lock);
  52. return 0;
  53. }
  54. result = wait_for_completion_timeout(&spicontext->done,
  55. msecs_to_jiffies(1000));
  56. /* check for timeout or success */
  57. if (!result) {
  58. dev_err(&spidev->dev, "error: response not ready timeout\n");
  59. result = -ETIMEDOUT;
  60. } else {
  61. result = 0;
  62. }
  63. mutex_unlock(&spicontext->spi_lock);
  64. return result;
  65. }
  66. EXPORT_SYMBOL_GPL(st95hf_spi_send);
  67. /* Function to Receive command Response */
  68. int st95hf_spi_recv_response(struct st95hf_spi_context *spicontext,
  69. unsigned char *receivebuff)
  70. {
  71. int len = 0;
  72. struct spi_transfer tx_takedata;
  73. struct spi_message m;
  74. struct spi_device *spidev = spicontext->spidev;
  75. unsigned char readdata_cmd = ST95HF_COMMAND_RECEIVE;
  76. struct spi_transfer t[2] = {
  77. {.tx_buf = &readdata_cmd, .len = 1,},
  78. {.rx_buf = receivebuff, .len = 2, .cs_change = 1,},
  79. };
  80. int ret = 0;
  81. memset(&tx_takedata, 0x0, sizeof(struct spi_transfer));
  82. mutex_lock(&spicontext->spi_lock);
  83. /* First spi transfer to know the length of valid data */
  84. spi_message_init(&m);
  85. spi_message_add_tail(&t[0], &m);
  86. spi_message_add_tail(&t[1], &m);
  87. ret = spi_sync(spidev, &m);
  88. if (ret) {
  89. dev_err(&spidev->dev, "spi_recv_resp, data length error = %d\n",
  90. ret);
  91. mutex_unlock(&spicontext->spi_lock);
  92. return ret;
  93. }
  94. /* As 2 bytes are already read */
  95. len = 2;
  96. /* Support of long frame */
  97. if (receivebuff[0] & 0x60)
  98. len += (((receivebuff[0] & 0x60) >> 5) << 8) | receivebuff[1];
  99. else
  100. len += receivebuff[1];
  101. /* Now make a transfer to read only relevant bytes */
  102. tx_takedata.rx_buf = &receivebuff[2];
  103. tx_takedata.len = len - 2;
  104. spi_message_init(&m);
  105. spi_message_add_tail(&tx_takedata, &m);
  106. ret = spi_sync(spidev, &m);
  107. mutex_unlock(&spicontext->spi_lock);
  108. if (ret) {
  109. dev_err(&spidev->dev, "spi_recv_resp, data read error = %d\n",
  110. ret);
  111. return ret;
  112. }
  113. return len;
  114. }
  115. EXPORT_SYMBOL_GPL(st95hf_spi_recv_response);
  116. int st95hf_spi_recv_echo_res(struct st95hf_spi_context *spicontext,
  117. unsigned char *receivebuff)
  118. {
  119. unsigned char readdata_cmd = ST95HF_COMMAND_RECEIVE;
  120. struct spi_transfer t[2] = {
  121. {.tx_buf = &readdata_cmd, .len = 1,},
  122. {.rx_buf = receivebuff, .len = 1,},
  123. };
  124. struct spi_message m;
  125. struct spi_device *spidev = spicontext->spidev;
  126. int ret = 0;
  127. mutex_lock(&spicontext->spi_lock);
  128. spi_message_init(&m);
  129. spi_message_add_tail(&t[0], &m);
  130. spi_message_add_tail(&t[1], &m);
  131. ret = spi_sync(spidev, &m);
  132. mutex_unlock(&spicontext->spi_lock);
  133. if (ret)
  134. dev_err(&spidev->dev, "recv_echo_res, data read error = %d\n",
  135. ret);
  136. return ret;
  137. }
  138. EXPORT_SYMBOL_GPL(st95hf_spi_recv_echo_res);