root/drivers/nfc/st95hf/spi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. st95hf_spi_send
  2. st95hf_spi_recv_response
  3. st95hf_spi_recv_echo_res

   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 
   9 #include "spi.h"
  10 
  11 /* Function to send user provided buffer to ST95HF through SPI */
  12 int st95hf_spi_send(struct st95hf_spi_context *spicontext,
  13                     unsigned char *buffertx,
  14                     int datalen,
  15                     enum req_type reqtype)
  16 {
  17         struct spi_message m;
  18         int result = 0;
  19         struct spi_device *spidev = spicontext->spidev;
  20         struct spi_transfer tx_transfer = {
  21                 .tx_buf = buffertx,
  22                 .len = datalen,
  23         };
  24 
  25         mutex_lock(&spicontext->spi_lock);
  26 
  27         if (reqtype == SYNC) {
  28                 spicontext->req_issync = true;
  29                 reinit_completion(&spicontext->done);
  30         } else {
  31                 spicontext->req_issync = false;
  32         }
  33 
  34         spi_message_init(&m);
  35         spi_message_add_tail(&tx_transfer, &m);
  36 
  37         result = spi_sync(spidev, &m);
  38         if (result) {
  39                 dev_err(&spidev->dev, "error: sending cmd to st95hf using SPI = %d\n",
  40                         result);
  41                 mutex_unlock(&spicontext->spi_lock);
  42                 return result;
  43         }
  44 
  45         /* return for asynchronous or no-wait case */
  46         if (reqtype == ASYNC) {
  47                 mutex_unlock(&spicontext->spi_lock);
  48                 return 0;
  49         }
  50 
  51         result = wait_for_completion_timeout(&spicontext->done,
  52                                              msecs_to_jiffies(1000));
  53         /* check for timeout or success */
  54         if (!result) {
  55                 dev_err(&spidev->dev, "error: response not ready timeout\n");
  56                 result = -ETIMEDOUT;
  57         } else {
  58                 result = 0;
  59         }
  60 
  61         mutex_unlock(&spicontext->spi_lock);
  62 
  63         return result;
  64 }
  65 EXPORT_SYMBOL_GPL(st95hf_spi_send);
  66 
  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 
  81         int ret = 0;
  82 
  83         memset(&tx_takedata, 0x0, sizeof(struct spi_transfer));
  84 
  85         mutex_lock(&spicontext->spi_lock);
  86 
  87         /* First spi transfer to know the length of valid data */
  88         spi_message_init(&m);
  89         spi_message_add_tail(&t[0], &m);
  90         spi_message_add_tail(&t[1], &m);
  91 
  92         ret = spi_sync(spidev, &m);
  93         if (ret) {
  94                 dev_err(&spidev->dev, "spi_recv_resp, data length error = %d\n",
  95                         ret);
  96                 mutex_unlock(&spicontext->spi_lock);
  97                 return ret;
  98         }
  99 
 100         /* As 2 bytes are already read */
 101         len = 2;
 102 
 103         /* Support of long frame */
 104         if (receivebuff[0] & 0x60)
 105                 len += (((receivebuff[0] & 0x60) >> 5) << 8) | receivebuff[1];
 106         else
 107                 len += receivebuff[1];
 108 
 109         /* Now make a transfer to read only relevant bytes */
 110         tx_takedata.rx_buf = &receivebuff[2];
 111         tx_takedata.len = len - 2;
 112 
 113         spi_message_init(&m);
 114         spi_message_add_tail(&tx_takedata, &m);
 115 
 116         ret = spi_sync(spidev, &m);
 117 
 118         mutex_unlock(&spicontext->spi_lock);
 119         if (ret) {
 120                 dev_err(&spidev->dev, "spi_recv_resp, data read error = %d\n",
 121                         ret);
 122                 return ret;
 123         }
 124 
 125         return len;
 126 }
 127 EXPORT_SYMBOL_GPL(st95hf_spi_recv_response);
 128 
 129 int st95hf_spi_recv_echo_res(struct st95hf_spi_context *spicontext,
 130                              unsigned char *receivebuff)
 131 {
 132         unsigned char readdata_cmd = ST95HF_COMMAND_RECEIVE;
 133         struct spi_transfer t[2] = {
 134                 {.tx_buf = &readdata_cmd, .len = 1,},
 135                 {.rx_buf = receivebuff, .len = 1,},
 136         };
 137         struct spi_message m;
 138         struct spi_device *spidev = spicontext->spidev;
 139         int ret = 0;
 140 
 141         mutex_lock(&spicontext->spi_lock);
 142 
 143         spi_message_init(&m);
 144         spi_message_add_tail(&t[0], &m);
 145         spi_message_add_tail(&t[1], &m);
 146         ret = spi_sync(spidev, &m);
 147 
 148         mutex_unlock(&spicontext->spi_lock);
 149 
 150         if (ret)
 151                 dev_err(&spidev->dev, "recv_echo_res, data read error = %d\n",
 152                         ret);
 153 
 154         return ret;
 155 }
 156 EXPORT_SYMBOL_GPL(st95hf_spi_recv_echo_res);

/* [<][>][^][v][top][bottom][index][help] */