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