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

#include <logging/log.h>

LOG_MODULE_REGISTER(sdhc_spi, CONFIG_DISK_LOG_LEVEL);

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

/* Clock speed used during initialisation */
#define SDHC_SPI_INITIAL_SPEED 400000
/* Clock speed used after initialisation */
#define SDHC_SPI_SPEED 4000000

#if !DT_NODE_HAS_STATUS(DT_INST(0, zephyr_mmc_spi_slot), okay)
#warning NO SDHC slot specified on board
#else
struct sdhc_spi_data {
	struct device *spi;
	struct spi_config cfg;
	struct device *cs;
	u32_t pin;
	gpio_dt_flags_t flags;

	bool high_capacity;
	u32_t sector_count;
	u8_t status;
#if LOG_LEVEL >= LOG_LEVEL_DBG
	int trace_dir;
#endif
};

DEVICE_DECLARE(sdhc_spi_0);

/* Traces card traffic for LOG_LEVEL_DBG */
static int sdhc_spi_trace(struct sdhc_spi_data *data, int dir, int err,
		      const u8_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;
}

/* Asserts or deasserts chip select */
static void sdhc_spi_set_cs(struct sdhc_spi_data *data, int value)
{
	gpio_pin_set(data->cs, data->pin, value);
}

/* Receives a fixed number of bytes */
static int sdhc_spi_rx_bytes(struct sdhc_spi_data *data, u8_t *buf, int len)
{
	struct spi_buf tx_bufs[] = {
		{
			.buf = (u8_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->cfg, &tx, &rx),
			  buf, len);
}

/* Receives and returns a single byte */
static int sdhc_spi_rx_u8(struct sdhc_spi_data *data)
{
	u8_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 u8_t *buf, int len)
{
	struct spi_buf spi_bufs[] = {
		{
			.buf = (u8_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->cfg, &tx), buf,
			len);
}

/* Transmits the command and payload */
static int sdhc_spi_tx_cmd(struct sdhc_spi_data *data, u8_t cmd, u32_t payload)
{
	u8_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]);
	buf[SDHC_CMD_BODY_SIZE] = crc7_be(0, buf, SDHC_CMD_BODY_SIZE);

	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,
	u8_t cmd, u32_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,
	u8_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, u8_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,
	u8_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,
	u8_t cmd, u32_t payload, u32_t *reply)
{
	int err;
	int status;
	u8_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,
	u8_t cmd, u32_t payload, u32_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,
	u8_t cmd, uint32_t payload, u32_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,
	u8_t *buf, int len)
{
	int err;
	int token;
	int i;
	/* Note the one extra byte to ensure there's an idle byte
	 * between commands.
	 */
	u8_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 = (u8_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->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,
	u8_t *send, int len)
{
	u8_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)
{
	sdhc_spi_set_cs(data, 1);

	/* Write the initial >= 74 clocks */
	sdhc_spi_tx(data, sdhc_ones, 10);

	sdhc_spi_set_cs(data, 0);

	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)
{
	u32_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(struct sdhc_spi_data *data)
{
	int err;
	u32_t ocr;
	struct sdhc_retry retry;
	u8_t structure;
	u8_t readbllen;
	u32_t csize;
	u8_t csizemult;
	u8_t buf[SDHC_CSD_SIZE];
	bool is_v2;

	data->cfg.frequency = SDHC_SPI_INITIAL_SPEED;
	data->status = 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 = (u8_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 */
	data->cfg.frequency = SDHC_SPI_SPEED;
	data->status = DISK_STATUS_OK;

	return 0;
}

static int sdhc_spi_read(struct sdhc_spi_data *data,
	u8_t *buf, u32_t sector, u32_t count)
{
	int err;
	u32_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;
	}

	sdhc_spi_set_cs(data, 0);

	/* 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:
	sdhc_spi_set_cs(data, 1);

	return err;
}

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

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

	sdhc_spi_set_cs(data, 0);

	/* 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, (u8_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:
	sdhc_spi_set_cs(data, 1);

	return err;
}

static int disk_spi_sdhc_init(struct device *dev);

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

	data->spi = device_get_binding(DT_BUS_LABEL(DT_INST(0, zephyr_mmc_spi_slot)));

	data->cfg.frequency = SDHC_SPI_INITIAL_SPEED;
	data->cfg.operation = SPI_WORD_SET(8) | SPI_HOLD_ON_CS;
	data->cfg.slave = DT_REG_ADDR(DT_INST(0, zephyr_mmc_spi_slot));
	data->cs = device_get_binding(
		DT_SPI_DEV_CS_GPIOS_LABEL(DT_INST(0, zephyr_mmc_spi_slot)));
	__ASSERT_NO_MSG(data->cs != NULL);

	data->pin = DT_SPI_DEV_CS_GPIOS_PIN(DT_INST(0, zephyr_mmc_spi_slot));
	data->flags = DT_SPI_DEV_CS_GPIOS_FLAGS(DT_INST(0, zephyr_mmc_spi_slot));

	disk_spi_sdhc_init(dev);

	return gpio_pin_configure(data->cs, data->pin,
				  GPIO_OUTPUT_INACTIVE | data->flags);
}

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

	return data->status;
}

static int disk_spi_sdhc_access_read(struct disk_info *disk,
	u8_t *buf, u32_t sector, u32_t count)
{
	struct device *dev = disk->dev;
	struct sdhc_spi_data *data = dev->driver_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 u8_t *buf, u32_t sector, u32_t count)
{
	struct device *dev = disk->dev;
	struct sdhc_spi_data *data = dev->driver_data;
	int err;

	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,
	u8_t cmd, void *buf)
{
	struct device *dev = disk->dev;
	struct sdhc_spi_data *data = dev->driver_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:
		*(u32_t *)buf = data->sector_count;
		break;
	case DISK_IOCTL_GET_SECTOR_SIZE:
		*(u32_t *)buf = SDMMC_DEFAULT_BLOCK_SIZE;
		break;
	case DISK_IOCTL_GET_ERASE_BLOCK_SZ:
		*(u32_t *)buf = SDMMC_DEFAULT_BLOCK_SIZE;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

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

	err = sdhc_spi_detect(data);
	sdhc_spi_set_cs(data, 1);

	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_DISK_SDHC_VOLUME_NAME,
	.ops = &spi_sdhc_disk_ops,
};

static int disk_spi_sdhc_init(struct device *dev)
{
	struct sdhc_spi_data *data = dev->driver_data;

	data->status = DISK_STATUS_UNINIT;

	spi_sdhc_disk.dev = dev;

	return disk_access_register(&spi_sdhc_disk);
}

static struct sdhc_spi_data sdhc_spi_data_0;

DEVICE_AND_API_INIT(sdhc_spi_0,
	DT_LABEL(DT_INST(0, zephyr_mmc_spi_slot)),
	sdhc_spi_init, &sdhc_spi_data_0, NULL,
	APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
#endif
