/*
 * 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]));

	/* Initialisation 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
