Linux Audio

Check our new training course

Loading...
v6.13.7
  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 */
 12int 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}
 65EXPORT_SYMBOL_GPL(st95hf_spi_send);
 66
 67/* Function to Receive command Response */
 68int 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}
127EXPORT_SYMBOL_GPL(st95hf_spi_recv_response);
128
129int 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}
156EXPORT_SYMBOL_GPL(st95hf_spi_recv_echo_res);
v4.17
 
  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 */
 23int 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}
 76EXPORT_SYMBOL_GPL(st95hf_spi_send);
 77
 78/* Function to Receive command Response */
 79int 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}
138EXPORT_SYMBOL_GPL(st95hf_spi_recv_response);
139
140int 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}
167EXPORT_SYMBOL_GPL(st95hf_spi_recv_echo_res);