/*
 * Copyright (c) 2017 Google LLC.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT zephyr_mmc_spi_slot

#include <logging/log.h>

LOG_MODULE_REGISTER(sdmmc_spi, CONFIG_SDMMC_LOG_LEVEL);

#include <drivers/disk.h>
#include <drivers/gpio.h>
#include <sys/byteorder.h>
#include <drivers/spi.h>
#include <sys/crc.h>
#include "sdmmc_sdhc.h"

/* Clock speed used during initialisation */
#define SDHC_SPI_INIT_SPEED KHZ(400)
/* Maximum clock speed used after initialisation (actual speed set in DTS).
 * SD Specifications Part 1 Physical layer states 25MHz maximum.
 */
#define SDHC_SPI_MAX_OPER_SPEED MHZ(25)

#define SPI_SDHC_NODE DT_DRV_INST(0)

#if !DT_NODE_HAS_STATUS(SPI_SDHC_NODE, okay)
#warning NO SDHC slot specified on board
#else
struct sdhc_spi_data {
	const struct device *spi;
	const struct spi_config *spi_cfg;
	bool high_capacity;
	uint32_t sector_count;
	uint8_t status;
#if LOG_LEVEL >= LOG_LEVEL_DBG
	int trace_dir;
#endif
};

struct sdhc_spi_config {
	struct spi_config init_cfg;
	struct spi_config oper_cfg;
#if DT_SPI_DEV_HAS_CS_GPIOS(SPI_SDHC_NODE)
	struct spi_cs_control cs;
#endif
};

static void sdhc_spi_set_status(const struct device *dev, uint8_t status)
{
	struct sdhc_spi_data *data = dev->data;
	const struct sdhc_spi_config *cfg = dev->config;

	data->status = status;
	if (status == DISK_STATUS_UNINIT) {
		data->spi_cfg = &cfg->init_cfg;
	} else if (status == DISK_STATUS_OK) {
		data->spi_cfg = &cfg->oper_cfg;
	}
}

/* Traces card traffic for LOG_LEVEL_DBG */
static int sdhc_spi_trace(struct sdhc_spi_data *data, int dir, int err,
		      const uint8_t *buf, int len)
{
#if LOG_LEVEL >= LOG_LEVEL_DBG
	if (err != 0) {
		printk("(err=%d)", err);
		data->trace_dir = 0;
	}

	if (dir != data->trace_dir) {
		data->trace_dir = dir;

		printk("\n");

		if (dir == 1) {
			printk(">>");
		} else if (dir == -1) {
			printk("<<");
		}
	}

	for (; len != 0; len--) {
		printk(" %x", *buf++);
	}
#endif
	return err;
}

/* Receives a fixed number of bytes */
static int sdhc_spi_rx_bytes(struct sdhc_spi_data *data, 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 sdhc_spi_trace(data, -1,
			  spi_transceive(data->spi, data->spi_cfg, &tx, &rx),
			  buf, len);
}

/* Receives and returns a single byte */
static int sdhc_spi_rx_u8(struct sdhc_spi_data *data)
{
	uint8_t buf[1];
	int err = sdhc_spi_rx_bytes(data, buf, sizeof(buf));

	if (err != 0) {
		return err;
	}

	return buf[0];
}

/* Transmits a block of bytes */
static int sdhc_spi_tx(struct sdhc_spi_data *data, const uint8_t *buf, int len)
{
	struct spi_buf spi_bufs[] = {
		{
			.buf = (uint8_t *)buf,
			.len = len
		}
	};

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

	return sdhc_spi_trace(data, 1,
			spi_write(data->spi, data->spi_cfg, &tx), buf,
			len);
}

/* Transmits the command and payload */
static int sdhc_spi_tx_cmd(struct sdhc_spi_data *data, uint8_t cmd, uint32_t payload)
{
	uint8_t buf[SDHC_CMD_SIZE];

	LOG_DBG("cmd%d payload=%u", cmd, payload);
	sdhc_spi_trace(data, 0, 0, NULL, 0);

	/* Encode the command */
	buf[0] = SDHC_TX | (cmd & ~SDHC_START);
	sys_put_be32(payload, &buf[1]);

	/* Add CRC and set LSB as 'end bit' */
	buf[SDHC_CMD_BODY_SIZE] = crc7_be(0, buf, SDHC_CMD_BODY_SIZE) | 0x01;

	return sdhc_spi_tx(data, buf, sizeof(buf));
}

/* Reads until anything but `discard` is received */
static int sdhc_spi_skip(struct sdhc_spi_data *data, int discard)
{
	int err;
	struct sdhc_retry retry;

	sdhc_retry_init(&retry, SDHC_READY_TIMEOUT, 0);

	do {
		err = sdhc_spi_rx_u8(data);
		if (err != discard) {
			return err;
		}
	} while (sdhc_retry_ok(&retry));

	LOG_WRN("Timeout while waiting for !%d", discard);
	return -ETIMEDOUT;
}

/* Reads until the first byte in a response is received */
static int sdhc_spi_skip_until_start(struct sdhc_spi_data *data)
{
	struct sdhc_retry retry;
	int status;

	sdhc_retry_init(&retry, SDHC_READY_TIMEOUT, 0);

	do {
		status = sdhc_spi_rx_u8(data);
		if (status < 0) {
			return status;
		}

		if ((status & SDHC_START) == 0) {
			return status;
		}
	} while (sdhc_retry_ok(&retry));

	return -ETIMEDOUT;
}

/* Reads until the bus goes high */
static int sdhc_spi_skip_until_ready(struct sdhc_spi_data *data)
{
	struct sdhc_retry retry;
	int status;

	sdhc_retry_init(&retry, SDHC_READY_TIMEOUT, 0);

	do {
		status = sdhc_spi_rx_u8(data);
		if (status < 0) {
			return status;
		}

		if (status == 0) {
			/* Card is still busy */
			continue;
		}

		if (status == 0xFF) {
			return 0;
		}

		/* Got something else.	Some cards release MISO part
		 * way through the transfer.  Read another and see if
		 * MISO went high.
		 */
		status = sdhc_spi_rx_u8(data);
		if (status < 0) {
			return status;
		}

		if (status == 0xFF) {
			return 0;
		}

		return -EPROTO;
	} while (sdhc_retry_ok(&retry));

	return -ETIMEDOUT;
}

/* Sends a command and returns the received R1 status code */
static int sdhc_spi_cmd_r1_raw(struct sdhc_spi_data *data,
	uint8_t cmd, uint32_t payload)
{
	int err;

	err = sdhc_spi_tx_cmd(data, cmd, payload);
	if (err != 0) {
		return err;
	}

	err = sdhc_spi_skip_until_start(data);

	/* Ensure there's a idle byte between commands */
	if (cmd != SDHC_SEND_CSD && cmd != SDHC_SEND_CID &&
	    cmd != SDHC_READ_SINGLE_BLOCK && cmd != SDHC_READ_MULTIPLE_BLOCK &&
	    cmd != SDHC_WRITE_BLOCK && cmd != SDHC_WRITE_MULTIPLE_BLOCK) {
		sdhc_spi_rx_u8(data);
	}

	return err;
}

/* Sends a command and returns the mapped error code */
static int sdhc_spi_cmd_r1(struct sdhc_spi_data *data,
	uint8_t cmd, uint32_t payload)
{
	return sdhc_map_r1_status(sdhc_spi_cmd_r1_raw(data, cmd, payload));
}

/* Sends a command in idle mode returns the mapped error code */
static int sdhc_spi_cmd_r1_idle(struct sdhc_spi_data *data, uint8_t cmd,
			    uint32_t payload)
{
	return sdhc_map_r1_idle_status(sdhc_spi_cmd_r1_raw(data, cmd, payload));
}

/* Sends a command and returns the received multi-byte R2 status code */
static int sdhc_spi_cmd_r2(struct sdhc_spi_data *data,
	uint8_t cmd, uint32_t payload)
{
	int err;
	int r1;
	int r2;

	err = sdhc_spi_tx_cmd(data, cmd, payload);
	if (err != 0) {
		return err;
	}

	r1 = sdhc_map_r1_status(sdhc_spi_skip_until_start(data));
	/* Always read the rest of the reply */
	r2 = sdhc_spi_rx_u8(data);

	/* Ensure there's a idle byte between commands */
	sdhc_spi_rx_u8(data);

	if (r1 < 0) {
		return r1;
	}

	return r2;
}

/* Sends a command and returns the received multi-byte status code */
static int sdhc_spi_cmd_r37_raw(struct sdhc_spi_data *data,
	uint8_t cmd, uint32_t payload, uint32_t *reply)
{
	int err;
	int status;
	uint8_t buf[sizeof(*reply)];

	err = sdhc_spi_tx_cmd(data, cmd, payload);
	if (err != 0) {
		return err;
	}

	status = sdhc_spi_skip_until_start(data);

	/* Always read the rest of the reply */
	err = sdhc_spi_rx_bytes(data, buf, sizeof(buf));
	*reply = sys_get_be32(buf);

	/* Ensure there's a idle byte between commands */
	sdhc_spi_rx_u8(data);

	if (err != 0) {
		return err;
	}

	return status;
}

/* Sends a command in idle mode returns the mapped error code */
static int sdhc_spi_cmd_r7_idle(struct sdhc_spi_data *data,
	uint8_t cmd, uint32_t payload, uint32_t *reply)
{
	return sdhc_map_r1_idle_status(
		sdhc_spi_cmd_r37_raw(data, cmd, payload, reply));
}

/* Sends a command and returns the received multi-byte R3 error code */
static int sdhc_spi_cmd_r3(struct sdhc_spi_data *data,
	uint8_t cmd, uint32_t payload, uint32_t *reply)
{
	return sdhc_map_r1_status(
		sdhc_spi_cmd_r37_raw(data, cmd, payload, reply));
}

/* Receives a SDHC data block */
static int sdhc_spi_rx_block(struct sdhc_spi_data *data,
	uint8_t *buf, int len)
{
	int err;
	int token;
	int i;
	/* Note the one extra byte to ensure there's an idle byte
	 * between commands.
	 */
	uint8_t crc[SDHC_CRC16_SIZE + 1];

	token = sdhc_spi_skip(data, 0xFF);
	if (token < 0) {
		return token;
	}

	if (token != SDHC_TOKEN_SINGLE) {
		/* No start token */
		return -EIO;
	}

	/* Read the data in batches */
	for (i = 0; i < len; i += sizeof(sdhc_ones)) {
		int remain = MIN(sizeof(sdhc_ones), len - i);

		struct spi_buf tx_bufs[] = {
			{
				.buf = (uint8_t *)sdhc_ones,
				.len = remain
			}
		};

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

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

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

		err = sdhc_spi_trace(data, -1,
				spi_transceive(data->spi, data->spi_cfg,
				&tx, &rx),
				&buf[i], remain);
		if (err != 0) {
			return err;
		}
	}

	err = sdhc_spi_rx_bytes(data, crc, sizeof(crc));
	if (err != 0) {
		return err;
	}

	if (sys_get_be16(crc) != crc16_itu_t(0, buf, len)) {
		/* Bad CRC */
		return -EILSEQ;
	}

	return 0;
}

/* Transmits a SDHC data block */
static int sdhc_spi_tx_block(struct sdhc_spi_data *data,
	uint8_t *send, int len)
{
	uint8_t buf[SDHC_CRC16_SIZE];
	int err;

	/* Start the block */
	buf[0] = SDHC_TOKEN_SINGLE;
	err = sdhc_spi_tx(data, buf, 1);
	if (err != 0) {
		return err;
	}

	/* Write the payload */
	err = sdhc_spi_tx(data, send, len);
	if (err != 0) {
		return err;
	}

	/* Build and write the trailing CRC */
	sys_put_be16(crc16_itu_t(0, send, len), buf);

	err = sdhc_spi_tx(data, buf, sizeof(buf));
	if (err != 0) {
		return err;
	}

	return sdhc_map_data_status(sdhc_spi_rx_u8(data));
}

static int sdhc_spi_recover(struct sdhc_spi_data *data)
{
	/* TODO(nzmichaelh): implement */
	return sdhc_spi_cmd_r1(data, SDHC_SEND_STATUS, 0);
}

/* Attempts to return the card to idle mode */
static int sdhc_spi_go_idle(struct sdhc_spi_data *data)
{
	/* Write the initial >= 74 clocks */
	sdhc_spi_tx(data, sdhc_ones, 10);
	spi_release(data->spi, data->spi_cfg);

	return sdhc_spi_cmd_r1_idle(data, SDHC_GO_IDLE_STATE, 0);
}

/* Checks the supported host voltage and basic protocol of a SDHC card */
static int sdhc_spi_check_interface(struct sdhc_spi_data *data)
{
	uint32_t cond;
	int err;

	/* Check that the current voltage is supported */
	err = sdhc_spi_cmd_r7_idle(data, SDHC_SEND_IF_COND,
			       SDHC_VHS_3V3 | SDHC_CHECK, &cond);
	if (err != 0) {
		return err;
	}

	if ((cond & 0xFF) != SDHC_CHECK) {
		/* Card returned a different check pattern */
		return -ENOENT;
	}

	if ((cond & SDHC_VHS_MASK) != SDHC_VHS_3V3) {
		/* Card doesn't support this voltage */
		return -ENOTSUP;
	}

	return 0;
}

/* Detect and initialise the card */
static int sdhc_spi_detect(const struct device *dev)
{
	struct sdhc_spi_data *data = dev->data;

	int err;
	uint32_t ocr;
	struct sdhc_retry retry;
	uint8_t structure;
	uint8_t readbllen;
	uint32_t csize;
	uint8_t csizemult;
	uint8_t buf[SDHC_CSD_SIZE];
	bool is_v2;

	sdhc_spi_set_status(dev, DISK_STATUS_UNINIT);

	sdhc_retry_init(&retry, SDHC_INIT_TIMEOUT, SDHC_RETRY_DELAY);

	/* Synchronise with the card by sending it to idle */
	do {
		err = sdhc_spi_go_idle(data);
		if (err == 0) {
			err = sdhc_spi_check_interface(data);
			is_v2 = (err == 0) ? true : false;
			break;
		}

		if (!sdhc_retry_ok(&retry)) {
			return -ENOENT;
		}
	} while (true);

	/* Enable CRC mode */
	err = sdhc_spi_cmd_r1_idle(data, SDHC_CRC_ON_OFF, 1);
	if (err != 0) {
		return err;
	}

	/* Wait for the card to leave idle state */
	do {
		sdhc_spi_cmd_r1_raw(data, SDHC_APP_CMD, 0);

		/* Set HCS only if card conforms to specification v2.00 (cf. 4.2.3) */
		err = sdhc_spi_cmd_r1(data, SDHC_SEND_OP_COND, is_v2 ? SDHC_HCS : 0);
		if (err == 0) {
			break;
		}
	} while (sdhc_retry_ok(&retry));

	if (err != 0) {
		/* Card never exited idle */
		return -ETIMEDOUT;
	}

	ocr = 0;
	if (is_v2) {
		do {
			/* Read OCR to check if this is a SDSC or SDHC card.
			 * CCS bit is valid after BUSY bit is set.
			 */
			err = sdhc_spi_cmd_r3(data, SDHC_READ_OCR, 0, &ocr);
			if (err != 0) {
				return err;
			}
			if ((ocr & SDHC_BUSY) != 0U) {
				break;
			}
		} while (sdhc_retry_ok(&retry));
	}

	if ((ocr & SDHC_CCS) != 0U) {
		data->high_capacity = true;
	} else {
		/* A 'SDSC' card: Set block length to 512 bytes. */
		data->high_capacity = false;
		err = sdhc_spi_cmd_r1(data, SDHC_SET_BLOCK_SIZE, SDMMC_DEFAULT_BLOCK_SIZE);
		if (err != 0) {
			return err;
		}
	}

	/* Read the CSD */
	err = sdhc_spi_cmd_r1(data, SDHC_SEND_CSD, 0);
	if (err != 0) {
		return err;
	}

	err = sdhc_spi_rx_block(data, buf, sizeof(buf));
	if (err != 0) {
		return err;
	}

	/* Bits 126..127 are the structure version */
	structure = (buf[0] >> 6);
	switch (structure) {
	case SDHC_CSD_V1:
		/* The maximum read data block length is given by bits 80..83 raised
		 * to the power of 2. Possible values are 9, 10 and 11 for 512, 1024
		 * and 2048 bytes, respectively. This driver does not make use of block
		 * lengths greater than 512 bytes, but forces 512 byte block transfers
		 * instead.
		 */
		readbllen = buf[5] & ((1 << 4) - 1);
		if ((readbllen < 9) || (readbllen > 11)) {
			/* Invalid maximum read data block length (cf. section 5.3.2) */
			return -ENOTSUP;
		}
		/* The capacity of the card is given by bits 62..73 plus 1 multiplied
		 * by bits 47..49 plus 2 raised to the power of 2 in maximum read data
		 * blocks.
		 */
		csize = (sys_get_be32(&buf[6]) >> 14) & ((1 << 12) - 1);
		csizemult = (uint8_t) ((sys_get_be16(&buf[9]) >> 7) & ((1 << 3) - 1));
		data->sector_count = ((csize + 1) << (csizemult + 2 + readbllen - 9));
		break;
	case SDHC_CSD_V2:
		/* Bits 48..69 are the capacity of the card in 512 KiB units, minus 1.
		 */
		csize = sys_get_be32(&buf[6]) & ((1 << 22) - 1);
		if (csize < 4112) {
			/* Invalid capacity (cf. section 5.3.3) */
			return -ENOTSUP;
		}
		data->sector_count = (csize + 1) *
			(512 * 1024 / SDMMC_DEFAULT_BLOCK_SIZE);
		break;
	default:
		/* Unsupported CSD format */
		return -ENOTSUP;
	}

	LOG_INF("Found a ~%u MiB SDHC card.",
		data->sector_count / (1024 * 1024 / SDMMC_DEFAULT_BLOCK_SIZE));

	/* Read the CID */
	err = sdhc_spi_cmd_r1(data, SDHC_SEND_CID, 0);
	if (err != 0) {
		return err;
	}

	err = sdhc_spi_rx_block(data, buf, sizeof(buf));
	if (err != 0) {
		return err;
	}

	LOG_INF("Manufacturer ID=%d OEM='%c%c' Name='%c%c%c%c%c' "
		"Revision=0x%x Serial=0x%x",
		buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
		buf[7], buf[8], sys_get_be32(&buf[9]));

	/* Initilisation complete */
	sdhc_spi_set_status(dev, DISK_STATUS_OK);

	return 0;
}

static int sdhc_spi_read(struct sdhc_spi_data *data,
	uint8_t *buf, uint32_t sector, uint32_t count)
{
	int err;
	uint32_t addr;

	err = sdhc_map_disk_status(data->status);
	if (err != 0) {
		return err;
	}

	/* Translate sector number to data address.
	 * SDSC cards use byte addressing, SDHC cards use block addressing.
	 */
	if (data->high_capacity) {
		addr = sector;
	} else {
		addr = sector * SDMMC_DEFAULT_BLOCK_SIZE;
	}

	/* Send the start read command */
	err = sdhc_spi_cmd_r1(data, SDHC_READ_MULTIPLE_BLOCK, addr);
	if (err != 0) {
		goto error;
	}

	/* Read the sectors */
	for (; count != 0U; count--) {
		err = sdhc_spi_rx_block(data, buf, SDMMC_DEFAULT_BLOCK_SIZE);
		if (err != 0) {
			goto error;
		}

		buf += SDMMC_DEFAULT_BLOCK_SIZE;
	}

	/* Ignore the error as STOP_TRANSMISSION always returns 0x7F */
	sdhc_spi_cmd_r1(data, SDHC_STOP_TRANSMISSION, 0);

	/* Wait until the card becomes ready */
	err = sdhc_spi_skip_until_ready(data);

error:
	spi_release(data->spi, data->spi_cfg);

	return err;
}

static int sdhc_spi_write(struct sdhc_spi_data *data,
	const uint8_t *buf, uint32_t sector, uint32_t count)
{
	int err;
	uint32_t addr;

	err = sdhc_map_disk_status(data->status);
	if (err != 0) {
		return err;
	}

	/* Write the blocks one-by-one */
	for (; count != 0U; count--) {
		/* Translate sector number to data address.
		 * SDSC cards use byte addressing, SDHC cards use block addressing.
		 */
		if (data->high_capacity) {
			addr = sector;
		} else {
			addr = sector * SDMMC_DEFAULT_BLOCK_SIZE;
		}

		err = sdhc_spi_cmd_r1(data, SDHC_WRITE_BLOCK, addr);
		if (err < 0) {
			goto error;
		}

		err = sdhc_spi_tx_block(data, (uint8_t *)buf,
			SDMMC_DEFAULT_BLOCK_SIZE);
		if (err != 0) {
			goto error;
		}

		/* Wait for the card to finish programming */
		err = sdhc_spi_skip_until_ready(data);
		if (err != 0) {
			goto error;
		}

		err = sdhc_spi_cmd_r2(data, SDHC_SEND_STATUS, 0);
		if (err != 0) {
			goto error;
		}

		buf += SDMMC_DEFAULT_BLOCK_SIZE;
		sector++;
	}

	err = 0;
error:
	spi_release(data->spi, data->spi_cfg);

	return err;
}

/* this function is optimized to write multiple blocks */
static int sdhc_spi_write_multi(struct sdhc_spi_data *data,
	const uint8_t *buf, uint32_t sector, uint32_t count)
{
	int err;
	uint32_t addr;
	uint8_t block[SDHC_CRC16_SIZE];

	err = sdhc_map_disk_status(data->status);
	if (err != 0) {
		return err;
	}

	if (data->high_capacity) {
		addr = sector;
	} else {
		addr = sector * SDMMC_DEFAULT_BLOCK_SIZE;
	}

	err = sdhc_spi_cmd_r1(data, SDHC_WRITE_MULTIPLE_BLOCK, addr);
	if (err < 0) {
		goto exit;
	}

	/* Write the blocks */
	for (; count != 0U; count--) {
		/* Start the block */
		block[0] = SDHC_TOKEN_MULTI_WRITE;
		err = sdhc_spi_tx(data, block, 1);
		if (err != 0) {
			goto exit;
		}

		/* Write the payload */
		err = sdhc_spi_tx(data, buf, SDMMC_DEFAULT_BLOCK_SIZE);
		if (err != 0) {
			goto exit;
		}

		/* Build and write the trailing CRC */
		sys_put_be16(crc16_itu_t(0, buf, SDMMC_DEFAULT_BLOCK_SIZE),
			     block);

		err = sdhc_spi_tx(data, block, sizeof(block));
		if (err != 0) {
			goto exit;
		}

		err = sdhc_map_data_status(sdhc_spi_rx_u8(data));
		if (err != 0) {
			goto exit;
		}

		/* Wait for the card to finish programming */
		err = sdhc_spi_skip_until_ready(data);
		if (err != 0) {
			goto exit;
		}

		buf += SDMMC_DEFAULT_BLOCK_SIZE;
		sector++;
	}

	/* Stop the transmission */
	sdhc_spi_tx_cmd(data, SDHC_STOP_TRANSMISSION, 0);

	/* Wait for the card to finish operation */
	err = sdhc_spi_skip_until_ready(data);
	if (err != 0) {
		goto exit;
	}

	err = 0;
exit:
	spi_release(data->spi, data->spi_cfg);

	return err;
}

static int disk_spi_sdhc_init(const struct device *dev);

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

	data->spi = device_get_binding(DT_BUS_LABEL(SPI_SDHC_NODE));

	disk_spi_sdhc_init(dev);

	return 0;
}

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

	return data->status;
}

static int disk_spi_sdhc_access_read(struct disk_info *disk,
	uint8_t *buf, uint32_t sector, uint32_t count)
{
	const struct device *dev = disk->dev;
	struct sdhc_spi_data *data = dev->data;
	int err;

	LOG_DBG("sector=%u count=%u", sector, count);

	err = sdhc_spi_read(data, buf, sector, count);
	if (err != 0 && sdhc_is_retryable(err)) {
		sdhc_spi_recover(data);
		err = sdhc_spi_read(data, buf, sector, count);
	}

	return err;
}

static int disk_spi_sdhc_access_write(struct disk_info *disk,
	const uint8_t *buf, uint32_t sector, uint32_t count)
{
	const struct device *dev = disk->dev;
	struct sdhc_spi_data *data = dev->data;
	int err;

	/* for more than 2 blocks the multiple block is preferred */
	if (count > 2) {
		LOG_DBG("multi block sector=%u count=%u", sector, count);

		err = sdhc_spi_write_multi(data, buf, sector, count);
		if (err != 0 && sdhc_is_retryable(err)) {
			sdhc_spi_recover(data);
			err = sdhc_spi_write_multi(data, buf, sector, count);
		}
	} else {
		LOG_DBG("sector=%u count=%u", sector, count);

		err = sdhc_spi_write(data, buf, sector, count);
		if (err != 0 && sdhc_is_retryable(err)) {
			sdhc_spi_recover(data);
			err = sdhc_spi_write(data, buf, sector, count);
		}
	}
	return err;
}

static int disk_spi_sdhc_access_ioctl(struct disk_info *disk,
	uint8_t cmd, void *buf)
{
	const struct device *dev = disk->dev;
	struct sdhc_spi_data *data = dev->data;
	int err;

	err = sdhc_map_disk_status(data->status);
	if (err != 0) {
		return err;
	}

	switch (cmd) {
	case DISK_IOCTL_CTRL_SYNC:
		break;
	case DISK_IOCTL_GET_SECTOR_COUNT:
		*(uint32_t *)buf = data->sector_count;
		break;
	case DISK_IOCTL_GET_SECTOR_SIZE:
		*(uint32_t *)buf = SDMMC_DEFAULT_BLOCK_SIZE;
		break;
	case DISK_IOCTL_GET_ERASE_BLOCK_SZ:
		*(uint32_t *)buf = SDMMC_DEFAULT_BLOCK_SIZE;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int disk_spi_sdhc_access_init(struct disk_info *disk)
{
	const struct device *dev = disk->dev;
	struct sdhc_spi_data *data = dev->data;
	int err;

	err = sdhc_spi_detect(dev);
	spi_release(data->spi, data->spi_cfg);

	return err;
}

static const struct disk_operations spi_sdhc_disk_ops = {
	.init = disk_spi_sdhc_access_init,
	.status = disk_spi_sdhc_access_status,
	.read = disk_spi_sdhc_access_read,
	.write = disk_spi_sdhc_access_write,
	.ioctl = disk_spi_sdhc_access_ioctl,
};

static struct disk_info spi_sdhc_disk = {
	.name = CONFIG_SDMMC_VOLUME_NAME,
	.ops = &spi_sdhc_disk_ops,
};

static int disk_spi_sdhc_init(const struct device *dev)
{
	sdhc_spi_set_status(dev, DISK_STATUS_UNINIT);

	spi_sdhc_disk.dev = dev;

	return disk_access_register(&spi_sdhc_disk);
}

static struct sdhc_spi_data sdhc_spi_data_0;

static const struct sdhc_spi_config sdhc_spi_cfg_0 = {
	.init_cfg = {
		.frequency = SDHC_SPI_INIT_SPEED,
		.operation = SPI_WORD_SET(8) | SPI_HOLD_ON_CS,
		.slave = DT_REG_ADDR(SPI_SDHC_NODE),
#if DT_SPI_DEV_HAS_CS_GPIOS(SPI_SDHC_NODE)
		.cs = &sdhc_spi_cfg_0.cs,
#endif
	},
	.oper_cfg = {
		.frequency = MIN(SDHC_SPI_MAX_OPER_SPEED,
				 DT_INST_PROP(0, spi_max_frequency)),
		.operation = SPI_WORD_SET(8) | SPI_HOLD_ON_CS,
		.slave = DT_REG_ADDR(SPI_SDHC_NODE),
#if DT_SPI_DEV_HAS_CS_GPIOS(SPI_SDHC_NODE)
		.cs = &sdhc_spi_cfg_0.cs,
#endif
	},
#if DT_SPI_DEV_HAS_CS_GPIOS(SPI_SDHC_NODE)
	.cs = {
		.gpio_dev = DEVICE_DT_GET(DT_SPI_DEV_CS_GPIOS_CTLR(SPI_SDHC_NODE)),
		.gpio_pin = DT_SPI_DEV_CS_GPIOS_PIN(SPI_SDHC_NODE),
		.gpio_dt_flags = DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_SDHC_NODE),
	},
#endif
};

DEVICE_DT_INST_DEFINE(0, sdhc_spi_init, NULL,
	&sdhc_spi_data_0, &sdhc_spi_cfg_0,
	POST_KERNEL, CONFIG_SDMMC_INIT_PRIORITY, NULL);
#endif
