/*
 * Copyright 2022 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT zephyr_sdhc_spi_slot



#include <zephyr/drivers/sdhc.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/sys/crc.h>

LOG_MODULE_REGISTER(sdhc_spi, CONFIG_SDHC_LOG_LEVEL);

#define MAX_CMD_READ 21
#define SPI_R1B_TIMEOUT_MS 3000
#define SD_SPI_SKIP_RETRIES 1000000

/* The SD protocol requires sending ones while reading but Zephyr
 * defaults to writing zeros. This block of 512 bytes is used for writing
 * 0xff while we read data blocks. Should remain const so this buffer is
 * stored in flash.
 */
static const uint8_t sdhc_ones[] = {
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};

BUILD_ASSERT(sizeof(sdhc_ones) == 512, "0xFF array for SDHC must be 512 bytes");

struct sdhc_spi_config {
	const struct device *spi_dev;
	const struct gpio_dt_spec pwr_gpio;
	const uint32_t spi_max_freq;
};

struct sdhc_spi_data {
	enum sdhc_power power_mode;
	struct spi_config *spi_cfg;
	struct spi_config cfg_a;
	struct spi_config cfg_b;
	uint8_t scratch[MAX_CMD_READ];
};

/* Receives a block of bytes */
static int sdhc_spi_rx(const struct device *spi_dev, struct spi_config *spi_cfg,
	uint8_t *buf, int len)
{
	struct spi_buf tx_bufs[] = {
		{
			.buf = (uint8_t *)sdhc_ones,
			.len = len
		}
	};

	const struct spi_buf_set tx = {
		.buffers = tx_bufs,
		.count = 1,
	};

	struct spi_buf rx_bufs[] = {
		{
			.buf = buf,
			.len = len
		}
	};

	const struct spi_buf_set rx = {
		.buffers = rx_bufs,
		.count = 1,
	};

	return spi_transceive(spi_dev, spi_cfg, &tx, &rx);
}

static int sdhc_spi_init_card(const struct device *dev)
{
	/* SD spec requires at least 74 clocks be send to SD to start it.
	 * for SPI protocol, this will be performed by sending 10 0xff values
	 * to the card (this should result in 80 SCK cycles)
	 */
	const struct sdhc_spi_config *config = dev->config;
	struct sdhc_spi_data *data = dev->data;
	struct spi_config *spi_cfg = data->spi_cfg;
	int ret;

	if (spi_cfg->frequency == 0) {
		/* Use default 400KHZ frequency */
		spi_cfg->frequency = SDMMC_CLOCK_400KHZ;
	}
	/* the initial 74 clocks must be sent while CS is high */
	spi_cfg->operation |= SPI_CS_ACTIVE_HIGH;
	ret = sdhc_spi_rx(config->spi_dev, spi_cfg, data->scratch, 10);
	if (ret != 0) {
		spi_cfg->operation &= ~SPI_CS_ACTIVE_HIGH;
		return ret;
	}
	/* Release lock on SPI bus */
	ret = spi_release(config->spi_dev, spi_cfg);
	spi_cfg->operation &= ~SPI_CS_ACTIVE_HIGH;
	return ret;
}

/* Checks if SPI SD card is sending busy signal */
static int sdhc_spi_card_busy(const struct device *dev)
{
	const struct sdhc_spi_config *config = dev->config;
	struct sdhc_spi_data *data = dev->data;
	int ret;
	uint8_t response;


	ret = sdhc_spi_rx(config->spi_dev, data->spi_cfg, &response, 1);
	if (ret) {
		return -EIO;
	}

	if (response == 0xFF) {
		return 0;
	} else
		return 1;

}

/* Waits for SPI SD card to stop sending busy signal */
static int sdhc_spi_wait_unbusy(const struct device *dev,
	int timeout_ms,
	int interval_ticks)
{
	const struct sdhc_spi_config *config = dev->config;
	struct sdhc_spi_data *data = dev->data;
	int ret;
	uint8_t response;

	while (timeout_ms > 0) {
		ret = sdhc_spi_rx(config->spi_dev, data->spi_cfg, &response, 1);
		if (ret) {
			return ret;
		}
		if (response == 0xFF) {
			return 0;
		}
		k_msleep(k_ticks_to_ms_floor32(interval_ticks));
		timeout_ms -= k_ticks_to_ms_floor32(interval_ticks);
	}
	return -ETIMEDOUT;
}


/* Read SD command from SPI response */
static int sdhc_spi_response_get(const struct device *dev, struct sdhc_command *cmd,
	int rx_len)
{
	const struct sdhc_spi_config *config = dev->config;
	struct sdhc_spi_data *dev_data = dev->data;
	uint8_t *response = dev_data->scratch;
	uint8_t *end = response + rx_len;
	int ret;
	uint8_t value, i;

	/* First step is finding the first valid byte of the response.
	 * All SPI responses start with R1, which will have MSB of zero.
	 * we know we can ignore the first 7 bytes, which hold the command and
	 * initial "card ready" byte.
	 */
	response += 8;
	while (response < end && ((*response & SD_SPI_START) == SD_SPI_START)) {
		response++;
	}
	if (response == end) {
		/* Some cards are slow, and need more time to respond. Continue
		 * with single byte reads until the card responds.
		 */
		response = dev_data->scratch;
		end = response + 1;
		for (i = 0; i < 16; i++) {
			ret = sdhc_spi_rx(config->spi_dev, dev_data->spi_cfg,
				response, 1);
			if (ret < 0) {
				return ret;
			}
			if (*response != 0xff) {
				break;
			}
		}
		if (*response == 0xff) {
			return -ETIMEDOUT;
		}
	}
	/* Record R1 response */
	cmd->response[0] = *response++;
	/* Check response for error */
	if (cmd->response[0] != 0) {
		if (cmd->response[0] &	(SD_SPI_R1PARAMETER_ERR | SD_SPI_R1ADDRESS_ERR)) {
			return -EFAULT; /* Bad address */
		} else if (cmd->response[0] & (SD_SPI_R1ILLEGAL_CMD_ERR)) {
			return -EINVAL; /* Invalid command */
		} else if (cmd->response[0] & (SD_SPI_R1CMD_CRC_ERR)) {
			return -EILSEQ; /* Illegal byte sequence */
		} else if (cmd->response[0] & (SD_SPI_R1ERASE_SEQ_ERR | SD_SPI_R1ERASE_RESET)) {
			return -EIO;
		}
		/* else IDLE_STATE bit is set, which is not an error, card is just resetting */
	}
	switch ((cmd->response_type & SDHC_SPI_RESPONSE_TYPE_MASK)) {
	case SD_SPI_RSP_TYPE_R1:
		/* R1 response - one byte*/
		break;
	case SD_SPI_RSP_TYPE_R1b:
		/* R1b response - one byte plus busy signal */
		/* Read remaining bytes to see if card is still busy.
		 * card will be ready when it stops driving data out
		 * low.
		 */
		while (response < end && (*response == 0x0)) {
			response++;
		}
		if (response == end) {
			value = cmd->timeout_ms;
			response--;
			/* Periodically check busy line */
			ret = sdhc_spi_wait_unbusy(dev,
				SPI_R1B_TIMEOUT_MS, 1000);
		}
		break;
	case SD_SPI_RSP_TYPE_R2:
	case SD_SPI_RSP_TYPE_R5:
		/* R2/R5 response - R1 response + 1 byte*/
		if (response == end) {
			response = dev_data->scratch;
			end = response + 1;
			/* Read the next byte */
			ret = sdhc_spi_rx(config->spi_dev,
				dev_data->spi_cfg,
				response, 1);
			if (ret) {
				return ret;
			}
		}
		cmd->response[0] = (*response) << 8;
		break;
	case SD_SPI_RSP_TYPE_R3:
	case SD_SPI_RSP_TYPE_R4:
	case SD_SPI_RSP_TYPE_R7:
		/* R3/R4/R7 response - R1 response + 4 bytes */
		cmd->response[1] = 0;
		for (i = 0; i < 4; i++) {
			cmd->response[1] <<= 8;
			/* Read bytes of response */
			if (response == end) {
				response = dev_data->scratch;
				end = response + 1;
				/* Read the next byte */
				ret = sdhc_spi_rx(config->spi_dev,
					dev_data->spi_cfg,
					response, 1);
				if (ret) {
					return ret;
				}
			}
			cmd->response[1] |= *response++;
		}
		break;
	default:
		/* Other RSP types not supported */
		return -ENOTSUP;
	}
	return 0;
}

/* Send SD command using SPI */
static int sdhc_spi_send_cmd(const struct device *dev, struct sdhc_command *cmd,
	bool data_present)
{
	const struct sdhc_spi_config *config = dev->config;
	struct sdhc_spi_data *dev_data = dev->data;
	int err;
	uint8_t *cmd_buf;
	/* To reduce overhead, we will send entire command in one SPI
	 * transaction. The packet takes the following format:
	 * - all ones byte to ensure card is ready
	 * - opcode byte (which includes start and transmission bits)
	 * - 4 bytes for argument
	 * - crc7 byte (with end bit)
	 * The SD card can take up to 8 bytes worth of SCLK cycles to respond.
	 * therefore, we provide 8 bytes of all ones, to read data from the card.
	 * the maximum spi response length is 5 bytes, so we provide an
	 * additional 5 bytes of data, leaving us with 13 bytes of 0xff.
	 * Finally, we send a padding byte of all 0xff, to ensure that
	 * the card recives at least one 0xff byte before next command.
	 */

	/* Note: we can discard CMD data as we send it,
	 * so resuse the TX buf as RX
	 */
	struct spi_buf bufs[] = {
		{
			.buf = dev_data->scratch,
			.len = sizeof(dev_data->scratch),
		},
	};

	const struct spi_buf_set buf_set = {
		.buffers = bufs,
		.count = 1,
	};


	if (data_present) {
		/* We cannot send extra SCLK cycles with our command,
		 * since we'll miss the data the card responds with. We
		 * send one 0xff byte, six command bytes, two additional 0xff
		 * bytes, since the min value of NCR (see SD SPI timing
		 * diagrams) is one, and we know there will be an R1 response.
		 */
		bufs[0].len = SD_SPI_CMD_SIZE + 3;
	}
	memset(dev_data->scratch, 0xFF, sizeof(dev_data->scratch));
	cmd_buf = dev_data->scratch + 1;

	/* Command packet holds the following bits:
	 * [47]: start bit, 0b0
	 * [46]: transmission bit, 0b1
	 * [45-40]: command index
	 * [39-8]: argument
	 * [7-1]: CRC
	 * [0]: end bit, 0b1
	 * Note that packets are sent MSB first.
	 */
	/* Add start bit, tx bit, and cmd opcode */
	cmd_buf[0] = (cmd->opcode & SD_SPI_CMD);
	cmd_buf[0] = ((cmd_buf[0] | SD_SPI_TX) & ~SD_SPI_START);
	/* Add argument */
	sys_put_be32(cmd->arg, &cmd_buf[1]);
	/* Add CRC, and set LSB as the end bit */
	cmd_buf[SD_SPI_CMD_BODY_SIZE] = crc7_be(0, cmd_buf, SD_SPI_CMD_BODY_SIZE) | 0x1;
	LOG_DBG("cmd%d arg 0x%x", cmd->opcode, cmd->arg);
	/* Set data, will lock SPI bus */
	err = spi_transceive(config->spi_dev, dev_data->spi_cfg, &buf_set, &buf_set);
	if (err != 0) {
		return err;
	}
	/* Read command response */
	return sdhc_spi_response_get(dev, cmd, bufs[0].len);
}

/* Skips bytes in SDHC data stream. */
static int sdhc_skip(const struct device *dev, uint8_t skip_val)
{
	const struct sdhc_spi_config *config = dev->config;
	struct sdhc_spi_data *data = dev->data;
	uint8_t buf;
	int ret;
	uint32_t retries = SD_SPI_SKIP_RETRIES;

	do {
		ret = sdhc_spi_rx(config->spi_dev, data->spi_cfg,
			&buf, sizeof(buf));
		if (ret) {
			return ret;
		}
	} while (buf == skip_val && retries--);
	if (retries == 0) {
		return -ETIMEDOUT;
	}
	/* Return first non-skipped value */
	return buf;
}

/* Handles reading data from SD SPI device */
static int sdhc_spi_read_data(const struct device *dev, struct sdhc_data *data)
{
	const struct sdhc_spi_config *config = dev->config;
	struct sdhc_spi_data *dev_data = dev->data;
	uint8_t *read_location = data->data;
	uint32_t remaining = data->blocks;
	int ret;
	uint8_t crc[SD_SPI_CRC16_SIZE + 1];

	/* The SPI API defaults to sending 0x00 when no TX buffer is
	 * provided, so we are limited to 512 byte reads
	 * (unless we increase the size of SDHC buffer)
	 */
	const struct spi_buf tx_bufs[] = {
		{
			.buf = (uint8_t *)sdhc_ones,
			.len = data->block_size,
		},
	};

	const struct spi_buf_set tx = {
		.buffers = tx_bufs,
		.count = 1,
	};

	struct spi_buf rx_bufs[] = {
		{
			.buf = read_location,
			.len = data->block_size,
		}
	};

	const struct spi_buf_set rx = {
		.buffers = rx_bufs,
		.count = 1,
	};

	if (data->block_size > 512) {
		/* SPI max BLKLEN is 512 */
		return -ENOTSUP;
	}

	/* Read bytes until data stream starts. SD will send 0xff until
	 * data is available
	 */
	ret = sdhc_skip(dev, 0xff);
	if (ret < 0) {
		return ret;
	}
	/* Check token */
	if (ret != SD_SPI_TOKEN_SINGLE)	{
		return -EIO;
	}

	/* Read blocks until we are out of data */
	while (remaining--) {
		ret = spi_transceive(config->spi_dev,
			dev_data->spi_cfg, &tx, &rx);
		if (ret) {
			LOG_ERR("Data write failed");
			return ret;
		}
		/* Read CRC16 plus one end byte */
		ret = sdhc_spi_rx(config->spi_dev, dev_data->spi_cfg,
			crc, sizeof(crc));
		if (crc16_itu_t(0, read_location, data->block_size) !=
			sys_get_be16(crc)) {
			/* Bad CRC */
			LOG_ERR("Bad data CRC");
			return -EILSEQ;
		}
		/* Advance read location */
		read_location += data->block_size;
		rx_bufs[0].buf = read_location;
		if (remaining) {
			/* Check next data token */
			ret = sdhc_skip(dev, 0xff);
			if (ret != SD_SPI_TOKEN_SINGLE) {
				LOG_ERR("Bad token");
				return -EIO;
			}
		}
	}
	return ret;
}

/* Handles writing data to SD SPI device */
static int sdhc_spi_write_data(const struct device *dev, struct sdhc_data *data)
{
	const struct sdhc_spi_config *config = dev->config;
	struct sdhc_spi_data *dev_data = dev->data;
	int ret;
	uint8_t token, resp;
	uint8_t *write_location = data->data, crc[SD_SPI_CRC16_SIZE];
	uint32_t remaining = data->blocks;

	struct spi_buf tx_bufs[] = {
		{
			.buf = &token,
			.len = sizeof(uint8_t),
		},
		{
			.buf = write_location,
			.len = data->block_size,
		},
		{
			.buf = crc,
			.len = sizeof(crc),
		},
	};

	struct spi_buf_set tx = {
		.buffers = tx_bufs,
		.count = 3,
	};

	/* Set the token- single block reads use different token
	 * than multibock
	 */
	if (remaining > 1) {
		token = SD_SPI_TOKEN_MULTI_WRITE;
	} else {
		token = SD_SPI_TOKEN_SINGLE;
	}

	while (remaining--) {
		/* Build the CRC for this data block */
		sys_put_be16(crc16_itu_t(0, write_location, data->block_size),
			crc);
		ret = spi_write(config->spi_dev, dev_data->spi_cfg, &tx);
		if (ret) {
			return ret;
		}
		/* Read back the data response token from the card */
		ret = sdhc_spi_rx(config->spi_dev, dev_data->spi_cfg,
			&resp, sizeof(resp));
		if (ret) {
			return ret;
		}
		/* Check response token */
		if ((resp & 0xF) != SD_SPI_RESPONSE_ACCEPTED) {
			if ((resp & 0xF) == SD_SPI_RESPONSE_CRC_ERR) {
				return -EILSEQ;
			} else if ((resp & 0xF) == SD_SPI_RESPONSE_WRITE_ERR) {
				return -EIO;
			}
			LOG_DBG("Unknown write response token 0x%x", resp);
			return -EIO;
		}
		/* Advance write location */
		write_location += data->block_size;
		tx_bufs[1].buf = write_location;
		/* Wait for card to stop being busy */
		ret = sdhc_spi_wait_unbusy(dev, data->timeout_ms, 0);
		if (ret) {
			return ret;
		}
	}
	if (data->blocks > 1) {
		/* Write stop transfer token to card */
		token = SD_SPI_TOKEN_STOP_TRAN;
		tx.count = 1;
		ret = spi_write(config->spi_dev, dev_data->spi_cfg, &tx);
		if (ret) {
			return ret;
		}
		/* Wait for card to stop being busy */
		ret = sdhc_spi_wait_unbusy(dev, data->timeout_ms, 0);
		if (ret) {
			return ret;
		}
	}
	return 0;
}

static int sdhc_spi_request(const struct device *dev,
	struct sdhc_command *cmd,
	struct sdhc_data *data)
{
	const struct sdhc_spi_config *config = dev->config;
	struct sdhc_spi_data *dev_data = dev->data;
	int ret, retries = cmd->retries;
	const struct sdhc_command stop_cmd = {
		.opcode = SD_STOP_TRANSMISSION,
		.arg = 0,
		.response_type = SD_SPI_RSP_TYPE_R1b,
		.timeout_ms = 1000,
		.retries = 1,
	};
	if (data == NULL) {
		do {
			ret = sdhc_spi_send_cmd(dev, cmd, false);
		} while ((ret != 0) && (retries-- > 0));
	} else {
		do {
			ret = sdhc_spi_send_cmd(dev, cmd, true);
			if (ret) {
				continue;
			}
			if ((cmd->opcode == SD_WRITE_SINGLE_BLOCK) ||
				(cmd->opcode == SD_WRITE_MULTIPLE_BLOCK)) {
				ret = sdhc_spi_write_data(dev, data);
			} else {
				ret = sdhc_spi_read_data(dev, data);
			}
			if (ret || (cmd->opcode == SD_READ_MULTIPLE_BLOCK)) {
				/* CMD12 is required after multiple read, or
				 * to retry failed transfer
				 */
				sdhc_spi_send_cmd(dev,
					(struct sdhc_command *)&stop_cmd,
					false);
			}
		} while ((ret != 0) && (retries-- > 0));
	}
	if (ret) {
		return ret;
	}
	/* Release SPI bus */
	return spi_release(config->spi_dev, dev_data->spi_cfg);
}

static int sdhc_spi_set_io(const struct device *dev, struct sdhc_io *ios)
{
	const struct sdhc_spi_config *cfg = dev->config;
	struct sdhc_spi_data *data = dev->data;

	if (ios->clock != data->spi_cfg->frequency) {
		if (ios->clock > cfg->spi_max_freq) {
			return -ENOTSUP;
		}
		/* Because pointer comparision is used, we have to
		 * swap to a new configuration structure to reconfigure SPI.
		 */
		if (ios->clock != 0) {
			if (data->spi_cfg == &data->cfg_a) {
				data->cfg_a.frequency = ios->clock;
				memcpy(&data->cfg_b, &data->cfg_a,
					sizeof(struct spi_config));
				data->spi_cfg = &data->cfg_b;
			} else {
				data->cfg_b.frequency = ios->clock;
				memcpy(&data->cfg_a, &data->cfg_b,
					sizeof(struct spi_config));
				data->spi_cfg = &data->cfg_a;
			}
		}
	}
	if (ios->bus_mode != SDHC_BUSMODE_PUSHPULL) {
		/* SPI mode supports push pull */
		return -ENOTSUP;
	}
	if (data->power_mode != ios->power_mode) {
		if (ios->power_mode == SDHC_POWER_ON) {
			/* Send 74 clock cycles to start card */
			if (sdhc_spi_init_card(dev) != 0) {
				LOG_ERR("Card SCLK init sequence failed");
				return -EIO;
			}
		}
		if (cfg->pwr_gpio.port) {
			/* If power control GPIO is defined, toggle SD power */
			if (ios->power_mode == SDHC_POWER_ON) {
				if (gpio_pin_set_dt(&cfg->pwr_gpio, 1)) {
					return -EIO;
				}
			} else {
				if (gpio_pin_set_dt(&cfg->pwr_gpio, 0)) {
					return -EIO;
				}
			}
		}
		data->power_mode = ios->power_mode;
	}
	if (ios->bus_width != SDHC_BUS_WIDTH1BIT) {
		/* SPI mode supports 1 bit bus */
		return -ENOTSUP;
	}
	if (ios->signal_voltage != SD_VOL_3_3_V) {
		/* SPI mode does not support UHS voltages */
		return -ENOTSUP;
	}
	return 0;
}

static int sdhc_spi_get_card_present(const struct device *dev)
{
	/* SPI has no card presence method, assume card is in slot */
	return 1;
}

static int sdhc_spi_get_host_props(const struct device *dev,
	struct sdhc_host_props *props)
{
	const struct sdhc_spi_config *cfg = dev->config;

	memset(props, 0, sizeof(struct sdhc_host_props));

	props->f_min = SDMMC_CLOCK_400KHZ;
	props->f_max = cfg->spi_max_freq;
	props->power_delay = 1000; /* SPI always needs 1ms power delay */
	props->host_caps.vol_330_support = true;
	props->is_spi = true;
	return 0;
}

static int sdhc_spi_reset(const struct device *dev)
{
	struct sdhc_spi_data *data = dev->data;

	/* Reset host I/O */
	data->spi_cfg->frequency = SDMMC_CLOCK_400KHZ;
	return 0;
}

static int sdhc_spi_init(const struct device *dev)
{
	const struct sdhc_spi_config *cfg = dev->config;
	struct sdhc_spi_data *data = dev->data;

	if (!device_is_ready(cfg->spi_dev)) {
		return -ENODEV;
	}
	data->power_mode = SDHC_POWER_OFF;
	data->spi_cfg = &data->cfg_a;
	data->spi_cfg->frequency = 0;
	return 0;
}

static struct sdhc_driver_api sdhc_spi_api = {
	.request = sdhc_spi_request,
	.set_io = sdhc_spi_set_io,
	.get_host_props = sdhc_spi_get_host_props,
	.get_card_present = sdhc_spi_get_card_present,
	.reset = sdhc_spi_reset,
	.card_busy = sdhc_spi_card_busy,
};


#define SDHC_SPI_INIT(n)							\
	const struct sdhc_spi_config sdhc_spi_config_##n = {			\
		.spi_dev = DEVICE_DT_GET(DT_INST_PARENT(n)),			\
		.pwr_gpio = GPIO_DT_SPEC_INST_GET_OR(n, pwr_gpios, {0}),	\
		.spi_max_freq = DT_INST_PROP(n, spi_max_frequency),		\
	};									\
										\
	struct sdhc_spi_data sdhc_spi_data_##n = {				\
		.cfg_a = SPI_CONFIG_DT_INST(n,					\
				(SPI_LOCK_ON | SPI_HOLD_ON_CS | SPI_WORD_SET(8)),\
				0),						\
	};									\
										\
	DEVICE_DT_INST_DEFINE(n,						\
			&sdhc_spi_init,						\
			NULL,							\
			&sdhc_spi_data_##n,					\
			&sdhc_spi_config_##n,					\
			POST_KERNEL,						\
			CONFIG_SDHC_INIT_PRIORITY,				\
			&sdhc_spi_api);

DT_INST_FOREACH_STATUS_OKAY(SDHC_SPI_INIT)
