/*
 * 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;
}

/* 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,
};


#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)
