spi.c 3.8 KB

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