1 // SPDX-License-Identifier: GPL-2.0-only
3 * ----------------------------------------------------------------------------
4 * drivers/nfc/st95hf/spi.c function definitions for SPI communication
5 * ----------------------------------------------------------------------------
6 * Copyright (C) 2015 STMicroelectronics Pvt. Ltd. All rights reserved.
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
,
15 enum req_type reqtype
)
19 struct spi_device
*spidev
= spicontext
->spidev
;
20 struct spi_transfer tx_transfer
= {
25 mutex_lock(&spicontext
->spi_lock
);
27 if (reqtype
== SYNC
) {
28 spicontext
->req_issync
= true;
29 reinit_completion(&spicontext
->done
);
31 spicontext
->req_issync
= false;
35 spi_message_add_tail(&tx_transfer
, &m
);
37 result
= spi_sync(spidev
, &m
);
39 dev_err(&spidev
->dev
, "error: sending cmd to st95hf using SPI = %d\n",
41 mutex_unlock(&spicontext
->spi_lock
);
45 /* return for asynchronous or no-wait case */
46 if (reqtype
== ASYNC
) {
47 mutex_unlock(&spicontext
->spi_lock
);
51 result
= wait_for_completion_timeout(&spicontext
->done
,
52 msecs_to_jiffies(1000));
53 /* check for timeout or success */
55 dev_err(&spidev
->dev
, "error: response not ready timeout\n");
61 mutex_unlock(&spicontext
->spi_lock
);
65 EXPORT_SYMBOL_GPL(st95hf_spi_send
);
67 /* Function to Receive command Response */
68 int st95hf_spi_recv_response(struct st95hf_spi_context
*spicontext
,
69 unsigned char *receivebuff
)
72 struct spi_transfer tx_takedata
;
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,},
83 memset(&tx_takedata
, 0x0, sizeof(struct spi_transfer
));
85 mutex_lock(&spicontext
->spi_lock
);
87 /* First spi transfer to know the length of valid data */
89 spi_message_add_tail(&t
[0], &m
);
90 spi_message_add_tail(&t
[1], &m
);
92 ret
= spi_sync(spidev
, &m
);
94 dev_err(&spidev
->dev
, "spi_recv_resp, data length error = %d\n",
96 mutex_unlock(&spicontext
->spi_lock
);
100 /* As 2 bytes are already read */
103 /* Support of long frame */
104 if (receivebuff
[0] & 0x60)
105 len
+= (((receivebuff
[0] & 0x60) >> 5) << 8) | receivebuff
[1];
107 len
+= receivebuff
[1];
109 /* Now make a transfer to read only relevant bytes */
110 tx_takedata
.rx_buf
= &receivebuff
[2];
111 tx_takedata
.len
= len
- 2;
113 spi_message_init(&m
);
114 spi_message_add_tail(&tx_takedata
, &m
);
116 ret
= spi_sync(spidev
, &m
);
118 mutex_unlock(&spicontext
->spi_lock
);
120 dev_err(&spidev
->dev
, "spi_recv_resp, data read error = %d\n",
127 EXPORT_SYMBOL_GPL(st95hf_spi_recv_response
);
129 int st95hf_spi_recv_echo_res(struct st95hf_spi_context
*spicontext
,
130 unsigned char *receivebuff
)
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,},
137 struct spi_message m
;
138 struct spi_device
*spidev
= spicontext
->spidev
;
141 mutex_lock(&spicontext
->spi_lock
);
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
);
148 mutex_unlock(&spicontext
->spi_lock
);
151 dev_err(&spidev
->dev
, "recv_echo_res, data read error = %d\n",
156 EXPORT_SYMBOL_GPL(st95hf_spi_recv_echo_res
);