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);
v5.4
  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);