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