Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ----------------------------------------------------------------------------
0004  * drivers/nfc/st95hf/spi.c function definitions for SPI communication
0005  * ----------------------------------------------------------------------------
0006  * Copyright (C) 2015 STMicroelectronics Pvt. Ltd. All rights reserved.
0007  */
0008 
0009 #include "spi.h"
0010 
0011 /* Function to send user provided buffer to ST95HF through SPI */
0012 int st95hf_spi_send(struct st95hf_spi_context *spicontext,
0013             unsigned char *buffertx,
0014             int datalen,
0015             enum req_type reqtype)
0016 {
0017     struct spi_message m;
0018     int result = 0;
0019     struct spi_device *spidev = spicontext->spidev;
0020     struct spi_transfer tx_transfer = {
0021         .tx_buf = buffertx,
0022         .len = datalen,
0023     };
0024 
0025     mutex_lock(&spicontext->spi_lock);
0026 
0027     if (reqtype == SYNC) {
0028         spicontext->req_issync = true;
0029         reinit_completion(&spicontext->done);
0030     } else {
0031         spicontext->req_issync = false;
0032     }
0033 
0034     spi_message_init(&m);
0035     spi_message_add_tail(&tx_transfer, &m);
0036 
0037     result = spi_sync(spidev, &m);
0038     if (result) {
0039         dev_err(&spidev->dev, "error: sending cmd to st95hf using SPI = %d\n",
0040             result);
0041         mutex_unlock(&spicontext->spi_lock);
0042         return result;
0043     }
0044 
0045     /* return for asynchronous or no-wait case */
0046     if (reqtype == ASYNC) {
0047         mutex_unlock(&spicontext->spi_lock);
0048         return 0;
0049     }
0050 
0051     result = wait_for_completion_timeout(&spicontext->done,
0052                          msecs_to_jiffies(1000));
0053     /* check for timeout or success */
0054     if (!result) {
0055         dev_err(&spidev->dev, "error: response not ready timeout\n");
0056         result = -ETIMEDOUT;
0057     } else {
0058         result = 0;
0059     }
0060 
0061     mutex_unlock(&spicontext->spi_lock);
0062 
0063     return result;
0064 }
0065 EXPORT_SYMBOL_GPL(st95hf_spi_send);
0066 
0067 /* Function to Receive command Response */
0068 int st95hf_spi_recv_response(struct st95hf_spi_context *spicontext,
0069                  unsigned char *receivebuff)
0070 {
0071     int len = 0;
0072     struct spi_transfer tx_takedata;
0073     struct spi_message m;
0074     struct spi_device *spidev = spicontext->spidev;
0075     unsigned char readdata_cmd = ST95HF_COMMAND_RECEIVE;
0076     struct spi_transfer t[2] = {
0077         {.tx_buf = &readdata_cmd, .len = 1,},
0078         {.rx_buf = receivebuff, .len = 2, .cs_change = 1,},
0079     };
0080 
0081     int ret = 0;
0082 
0083     memset(&tx_takedata, 0x0, sizeof(struct spi_transfer));
0084 
0085     mutex_lock(&spicontext->spi_lock);
0086 
0087     /* First spi transfer to know the length of valid data */
0088     spi_message_init(&m);
0089     spi_message_add_tail(&t[0], &m);
0090     spi_message_add_tail(&t[1], &m);
0091 
0092     ret = spi_sync(spidev, &m);
0093     if (ret) {
0094         dev_err(&spidev->dev, "spi_recv_resp, data length error = %d\n",
0095             ret);
0096         mutex_unlock(&spicontext->spi_lock);
0097         return ret;
0098     }
0099 
0100     /* As 2 bytes are already read */
0101     len = 2;
0102 
0103     /* Support of long frame */
0104     if (receivebuff[0] & 0x60)
0105         len += (((receivebuff[0] & 0x60) >> 5) << 8) | receivebuff[1];
0106     else
0107         len += receivebuff[1];
0108 
0109     /* Now make a transfer to read only relevant bytes */
0110     tx_takedata.rx_buf = &receivebuff[2];
0111     tx_takedata.len = len - 2;
0112 
0113     spi_message_init(&m);
0114     spi_message_add_tail(&tx_takedata, &m);
0115 
0116     ret = spi_sync(spidev, &m);
0117 
0118     mutex_unlock(&spicontext->spi_lock);
0119     if (ret) {
0120         dev_err(&spidev->dev, "spi_recv_resp, data read error = %d\n",
0121             ret);
0122         return ret;
0123     }
0124 
0125     return len;
0126 }
0127 EXPORT_SYMBOL_GPL(st95hf_spi_recv_response);
0128 
0129 int st95hf_spi_recv_echo_res(struct st95hf_spi_context *spicontext,
0130                  unsigned char *receivebuff)
0131 {
0132     unsigned char readdata_cmd = ST95HF_COMMAND_RECEIVE;
0133     struct spi_transfer t[2] = {
0134         {.tx_buf = &readdata_cmd, .len = 1,},
0135         {.rx_buf = receivebuff, .len = 1,},
0136     };
0137     struct spi_message m;
0138     struct spi_device *spidev = spicontext->spidev;
0139     int ret = 0;
0140 
0141     mutex_lock(&spicontext->spi_lock);
0142 
0143     spi_message_init(&m);
0144     spi_message_add_tail(&t[0], &m);
0145     spi_message_add_tail(&t[1], &m);
0146     ret = spi_sync(spidev, &m);
0147 
0148     mutex_unlock(&spicontext->spi_lock);
0149 
0150     if (ret)
0151         dev_err(&spidev->dev, "recv_echo_res, data read error = %d\n",
0152             ret);
0153 
0154     return ret;
0155 }
0156 EXPORT_SYMBOL_GPL(st95hf_spi_recv_echo_res);