drivers/nfc/st95hf/spi.c

Source file repositories/reference/linux-study-clean/drivers/nfc/st95hf/spi.c

File Facts

System
Linux kernel
Corpus path
drivers/nfc/st95hf/spi.c
Extension
.c
Size
3875 bytes
Lines
157
Domain
Driver Families
Bucket
drivers/nfc
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * ----------------------------------------------------------------------------
 * drivers/nfc/st95hf/spi.c function definitions for SPI communication
 * ----------------------------------------------------------------------------
 * Copyright (C) 2015 STMicroelectronics Pvt. Ltd. All rights reserved.
 */

#include "spi.h"

/* Function to send user provided buffer to ST95HF through SPI */
int st95hf_spi_send(struct st95hf_spi_context *spicontext,
		    unsigned char *buffertx,
		    int datalen,
		    enum req_type reqtype)
{
	struct spi_message m;
	int result = 0;
	struct spi_device *spidev = spicontext->spidev;
	struct spi_transfer tx_transfer = {
		.tx_buf = buffertx,
		.len = datalen,
	};

	mutex_lock(&spicontext->spi_lock);

	if (reqtype == SYNC) {
		spicontext->req_issync = true;
		reinit_completion(&spicontext->done);
	} else {
		spicontext->req_issync = false;
	}

	spi_message_init(&m);
	spi_message_add_tail(&tx_transfer, &m);

	result = spi_sync(spidev, &m);
	if (result) {
		dev_err(&spidev->dev, "error: sending cmd to st95hf using SPI = %d\n",
			result);
		mutex_unlock(&spicontext->spi_lock);
		return result;
	}

	/* return for asynchronous or no-wait case */
	if (reqtype == ASYNC) {
		mutex_unlock(&spicontext->spi_lock);
		return 0;
	}

	result = wait_for_completion_timeout(&spicontext->done,
					     msecs_to_jiffies(1000));
	/* check for timeout or success */
	if (!result) {
		dev_err(&spidev->dev, "error: response not ready timeout\n");
		result = -ETIMEDOUT;
	} else {
		result = 0;
	}

	mutex_unlock(&spicontext->spi_lock);

	return result;
}
EXPORT_SYMBOL_GPL(st95hf_spi_send);

/* Function to Receive command Response */
int st95hf_spi_recv_response(struct st95hf_spi_context *spicontext,
			     unsigned char *receivebuff)
{
	int len = 0;
	struct spi_transfer tx_takedata;
	struct spi_message m;
	struct spi_device *spidev = spicontext->spidev;
	unsigned char readdata_cmd = ST95HF_COMMAND_RECEIVE;
	struct spi_transfer t[2] = {
		{.tx_buf = &readdata_cmd, .len = 1,},
		{.rx_buf = receivebuff, .len = 2, .cs_change = 1,},
	};

	int ret = 0;

	memset(&tx_takedata, 0x0, sizeof(struct spi_transfer));

	mutex_lock(&spicontext->spi_lock);

	/* First spi transfer to know the length of valid data */
	spi_message_init(&m);
	spi_message_add_tail(&t[0], &m);
	spi_message_add_tail(&t[1], &m);

Annotation

Implementation Notes