/* SPDX-License-Identifier: GPL-2.0-only */
#include <stdint.h>
#include <string.h>
#include <spi-generic.h>
#include <spi_sdcard.h>
#include <crc_byte.h>
#include <commonlib/helpers.h>
#include <console/console.h>

#define SPI_SDCARD_DEBUG 0

#define dprintk(fmt, args...) \
	do { if (SPI_SDCARD_DEBUG) { printk(BIOS_DEBUG, fmt, ##args); }} while (0)

#define SDCARD_TYPE_SDSC	1
#define SDCARD_TYPE_SDHC	2
#define SDCARD_TYPE_SDXC	3

/* CMD */
#define GO_IDLE_STATE           0
#define SEND_OP_COND            1
#define SWITCH_FUNC             6
#define SEND_IF_COND            8
#define SEND_CSD                9
#define SEND_CID                10
#define STOP_TRANSMISSION       12
#define SEND_STATUS             13
#define SET_BLOCKLEN            16
#define READ_SINGLE_BLOCK       17
#define READ_MULTIPLEBLOCK      18
#define WRITE_BLOCK             24
#define WRITE_MULTIPLEBLOCK     25
#define PROGRAM_CSD             27
#define SET_WRITE_PROT          28
#define CLR_WRITE_PROT          29
#define SEND_WRITE_PROT         30
#define ERASE_WR_BLK_START_ADDR 32
#define ERASE_WR_BLK_END_ADDR   33
#define ERASE                   38
#define LOCK_UNLOCK             42
#define APP_CMD                 55
#define GEN_CMD                 56
#define READ_OCR                58
#define CRC_ON_OFF              59

/* ACMD */
#define SD_STATUS               13
#define SEND_NUM_WR_BLOCKS      22
#define SET_WR_BLK_ERASE_COUNT  23
#define SD_SEND_OP_COND         41
#define SET_CLR_CARD_DETECT     42
#define SEND_SCR                51

/* control tokens */
#define CT_BLOCK_START                  0xfe
#define CT_MULTIPLE_BLOCK_START         0xfc
#define CT_MULTIPLE_BLOCK_STOP          0xfd
#define CT_RESPONSE_MASK                0x1f
#define  CT_RESPONSE_ACCEPTED           0x05
#define  CT_RESPONSE_REJECTED_CRC       0x0b
#define  CT_RESPONSE_REJECTED_WRITE_ERR 0x0d

/* response type */
#define RSP_R1  0
#define RSP_R1b 1
#define RSP_R2  2
#define RSP_R3  3
#define RSP_R4  4
#define RSP_R5  5
#define RSP_R7  7

#define RSP_ERR_CARD_IS_LOCKED	(1 << 0)
#define RSP_ERR_WP_ERASE_SKIP	(1 << 1)
#define RSP_ERR_GENERAL		(1 << 2)
#define RSP_ERR_CC		(1 << 3)
#define RSP_ERR_ECC		(1 << 4)
#define RSP_ERR_WP_VIOLATION	(1 << 5)
#define RSP_ERR_ERASE_PARAM	(1 << 6)
#define RSP_ERR_OUT_OF_RANGE	(1 << 7)
#define RSP_ERR_IN_IDLE		(1 << 8)
#define RSP_ERR_ERASE_RESET	(1 << 9)
#define RSP_ERR_ILLEGAL_COMMAND	(1 << 10)
#define RSP_ERR_COM_CRC		(1 << 11)
#define RSP_ERR_ERASE_SEQUENCE	(1 << 12)
#define RSP_ERR_ADDRESS		(1 << 13)
#define RSP_ERR_PARAMETER	(1 << 14)

#define BLOCK_SIZE	512

static unsigned long long extract_bits(uint8_t *buff,
	int width, int start, int end)
{
	unsigned long long r = 0;
	for (int i = end; i >= start; i--) {
		int bitpos = width - i - 1;
		int b = bitpos / 8;
		int shift = 7 - bitpos % 8;
		r = (r << 1) | ((buff[b] >> shift) & 1);
	}
	return r;
}

static void spi_sdcard_enable_cs(const struct spi_sdcard *card)
{
	spi_claim_bus(&card->slave);
}

static void spi_sdcard_disable_cs(const struct spi_sdcard *card)
{
	spi_release_bus(&card->slave);
}

static void spi_sdcard_sendbyte(const struct spi_sdcard *card, uint8_t b)
{
	dprintk("sdcard -> %#x\n", b);
	spi_xfer(&card->slave, &b, 1, NULL, 0);
}

static uint8_t spi_sdcard_recvbyte(const struct spi_sdcard *card)
{
	uint8_t b, t = 0xff;
	spi_xfer(&card->slave, &t, 1, &b, 1);
	dprintk("sdcard <- %#x\n", b);
	return b;
}

static uint8_t spi_sdcard_calculate_command_crc(uint8_t cmd, uint32_t argument)
{
	uint8_t crc = 0;
	crc = crc7_byte(crc, (cmd | 0x40) & 0x7f);
	crc = crc7_byte(crc, (argument >> (3 * 8)) & 0xff);
	crc = crc7_byte(crc, (argument >> (2 * 8)) & 0xff);
	crc = crc7_byte(crc, (argument >> (1 * 8)) & 0xff);
	crc = crc7_byte(crc, (argument >> (0 * 8)) & 0xff);
	return crc | 1;
}

static int lookup_cmd_response_type(uint8_t cmd)
{
	switch (cmd) {
	case GO_IDLE_STATE:
	case SEND_OP_COND:
	case SWITCH_FUNC:
	case SEND_CSD:
	case SEND_CID:
	case SET_BLOCKLEN:
	case READ_SINGLE_BLOCK:
	case READ_MULTIPLEBLOCK:
	case WRITE_BLOCK:
	case WRITE_MULTIPLEBLOCK:
	case PROGRAM_CSD:
	case SEND_WRITE_PROT:
	case ERASE_WR_BLK_START_ADDR:
	case ERASE_WR_BLK_END_ADDR:
	case LOCK_UNLOCK:
	case APP_CMD:
	case GEN_CMD:
	case CRC_ON_OFF:
		return RSP_R1;
	case STOP_TRANSMISSION:
	case SET_WRITE_PROT:
	case CLR_WRITE_PROT:
	case ERASE:
		return RSP_R1b;
	case SEND_STATUS:
		return RSP_R2;
	case READ_OCR:
		return RSP_R3;
	case SEND_IF_COND:
		return RSP_R7;
	}
	return -1;
}

static int lookup_acmd_response_type(uint8_t cmd)
{
	switch (cmd) {
	case SEND_NUM_WR_BLOCKS:
	case SET_WR_BLK_ERASE_COUNT:
	case SD_SEND_OP_COND:
	case SET_CLR_CARD_DETECT:
	case SEND_SCR:
		return RSP_R1;
	case SD_STATUS:
		return RSP_R2;
	}
	return -1;
}

static int lookup_response_length(int response_type)
{
	switch (response_type) {
	case RSP_R1:
	case RSP_R1b:
		return 1;
	case RSP_R2:
		return 2;
	case RSP_R3:
	case RSP_R7:
		return 5;
	}
	return -1;
}

static int response_resolve(int response_type, uint8_t *response,
	uint32_t *out_register)
{
	__maybe_unused static const char * const sd_err[] = {
		"Card is locked",
		"wp erase skip | lock/unlock cmd failed",
		"error",
		"CC error",
		"card err failed",
		"wp violation",
		"erase param",
		"out of range | csd overwrite",
		"in idle state",
		"erase reset",
		"illegal command",
		"com crc error",
		"erase sequence error",
		"address error",
		"parameter error"
	};
	uint8_t r1 = 0, r2 = 0;

	if ((response_type == RSP_R1)
		|| (response_type == RSP_R1b)
		|| (response_type == RSP_R2)
		|| (response_type == RSP_R3)
		|| (response_type == RSP_R7))
		r1 = response[0];

	if (response_type == RSP_R2)
		r2 = response[1];

	if (((response_type == RSP_R3) || (response_type == RSP_R7))
			&& (out_register != NULL)) {
		*out_register = 0;
		*out_register = (*out_register << 8) | response[1];
		*out_register = (*out_register << 8) | response[2];
		*out_register = (*out_register << 8) | response[3];
		*out_register = (*out_register << 8) | response[4];
	}

	if (r1 != 0 || r2 != 0) {
		int i = 0;
		uint16_t r = (r1 << 8) | r2;
		while (r) {
			if (r & 1)
				dprintk("SDCARD ERROR: %s\n", sd_err[i]);
			r = r >> 1;
			i++;
		}
		return (r1 << 8) | r2;
	}

	return 0;
}

static int spi_sdcard_do_command_help(const struct spi_sdcard *card,
		int is_acmd,
		uint8_t cmd,
		uint32_t argument,
		uint32_t *out_register)
{
	int ret, type, length, wait;
	uint8_t crc, c, response[5];

	/* calculate crc for command */
	crc = spi_sdcard_calculate_command_crc(cmd, argument);

	if (is_acmd)
		dprintk("\nsdcard execute acmd%d, argument = %#x, crc = %#x\n",
				cmd, argument, crc);
	else
		dprintk("\nsdcard execute  cmd%d, argument = %#x, crc = %#x\n",
				cmd, argument, crc);

	/* lookup response type of command */
	if (!is_acmd)
		type = lookup_cmd_response_type(cmd);
	else
		type = lookup_acmd_response_type(cmd);

	/* lookup response length of command */
	length = lookup_response_length(type);

	/* enable cs  */
	spi_sdcard_enable_cs(card);

	/* just delay 8 clocks */
	spi_sdcard_recvbyte(card);

	/* send command */
	spi_sdcard_sendbyte(card, (cmd | 0x40) & 0x7f);
	/* send argument */
	spi_sdcard_sendbyte(card, (argument >> (8 * 3)) & 0xff);
	spi_sdcard_sendbyte(card, (argument >> (8 * 2)) & 0xff);
	spi_sdcard_sendbyte(card, (argument >> (8 * 1)) & 0xff);
	spi_sdcard_sendbyte(card, (argument >> (8 * 0)) & 0xff);
	/* send crc */
	spi_sdcard_sendbyte(card, crc);

	/* waiting for response */
	wait = 0xffff;
	while (((c = spi_sdcard_recvbyte(card)) & 0x80) && --wait)
		;
	if (!wait) {
		spi_sdcard_disable_cs(card);
		return -1; /* timeout */
	}

	/* obtain response */
	for (int i = 0; i < length; i++) {
		response[i] = c;
		c = spi_sdcard_recvbyte(card);
	}

	if (type == RSP_R1b) {
		/* waiting done */
		wait = 0xffffff;
		while (c == 0 && --wait)
			c = spi_sdcard_recvbyte(card);
		if (!wait) {
			spi_sdcard_disable_cs(card);
			return -1; /* timeout */
		}
	}

	spi_sdcard_disable_cs(card);

	ret = response_resolve(type, response, out_register);

	return ret;
}

static int spi_sdcard_do_command(const struct spi_sdcard *card,
		uint8_t cmd,
		uint32_t argument,
		uint32_t *out_register)
{
	return spi_sdcard_do_command_help(card, 0, cmd, argument, out_register);
}

static int spi_sdcard_do_app_command(const struct spi_sdcard *card,
		uint8_t cmd,
		uint32_t argument,
		uint32_t *out_register)
{
	/* CMD55 */
	if (spi_sdcard_do_command(card, APP_CMD, 0, NULL))
		return -1;

	return spi_sdcard_do_command_help(card, 1, cmd, argument, out_register);
}

size_t spi_sdcard_size(const struct spi_sdcard *card)
{
	int wait;
	uint8_t csd[16];
	uint16_t c = 0;

	/* CMD9, send csd (128bits register) */
	if (spi_sdcard_do_command(card, SEND_CSD, 0, NULL))
		return -1;

	/* enable CS */
	spi_sdcard_enable_cs(card);

	/* waiting start block token */
	wait = 0xffff;
	while ((spi_sdcard_recvbyte(card) != CT_BLOCK_START) && --wait)
		;
	if (!wait) {
		spi_sdcard_disable_cs(card);
		return -1;
	}

	/* receive data */
	for (int i = 0; i < 16; i++) {
		csd[i] = spi_sdcard_recvbyte(card);
		c = crc16_byte(c, csd[i]);
	}

	/* receive crc and verify check sum */
	if (((c >> 8) & 0xff) != spi_sdcard_recvbyte(card)) {
		spi_sdcard_disable_cs(card);
		return -1;
	}
	if (((c >> 0) & 0xff) != spi_sdcard_recvbyte(card)) {
		spi_sdcard_disable_cs(card);
		return -1;
	}

	/* disable cs */
	spi_sdcard_disable_cs(card);

	if (extract_bits(csd, 128, 126, 127) == 0) {
		/* csd version 1.0 */
		size_t c_size = extract_bits(csd, 128, 62, 73);
		size_t mult = extract_bits(csd, 128, 47, 49);
		size_t read_bl_len = extract_bits(csd, 128, 80, 83);
		return (c_size + 1) * mult * (1 << read_bl_len);
	}

	if (extract_bits(csd, 128, 126, 127) == 1) {
		/* csd version 2.0 */
		size_t c_size = extract_bits(csd, 128, 48, 69);
		return (c_size + 1) * 512 * 1024;
	}

	return -1;
}

int spi_sdcard_init(struct spi_sdcard *card,
		const unsigned int bus, const unsigned int cs)
{
	int resolve, wait;
	uint32_t ocr;

	/* initialize spi controller */
	spi_setup_slave(bus, cs, &card->slave);

	/* must wait at least 74 clock ticks after reset
	 * disable cs pin to enter spi mode */
	spi_sdcard_disable_cs(card);
	for (int i = 0; i < 10; i++)
		spi_sdcard_sendbyte(card, 0xff);

	/* CMD0, reset sdcard */
	wait = 0xffff;
	while ((spi_sdcard_do_command(card, GO_IDLE_STATE, 0, NULL)
			!= RSP_ERR_IN_IDLE) && --wait)
		;
	if (!wait)
		return -1; /* timeout */

	/* CMD8 */
	resolve = spi_sdcard_do_command(card, SEND_IF_COND, 0x1aa, NULL);
	if (resolve & RSP_ERR_ILLEGAL_COMMAND) {
		/* ACMD41, initialize card */
		wait = 0xffff;
		while ((resolve = spi_sdcard_do_app_command(card,
			SD_SEND_OP_COND, 0, NULL)) && --wait)
			;
		if ((resolve & RSP_ERR_ILLEGAL_COMMAND) || !wait) {
			wait = 0xffff;
			/* CMD1, initialize card for 2.1mm SD Memory Card */
			while (spi_sdcard_do_app_command(card, SEND_OP_COND,
				0, NULL) && --wait)
				;
			if (!wait)
				return -1; /* unknown card */
		}
	} else {
		/* ACMD41, initialize card */
		wait = 0xffff;
		while (spi_sdcard_do_app_command(card, SD_SEND_OP_COND,
				0x40000000, NULL) && --wait)
			;
		if (!wait)
			return -1;
	}

	/* CMD58, read ocr register */
	if (spi_sdcard_do_command(card, READ_OCR, 0, &ocr))
		return -1;

	/* CMD16, set block length to 512 bytes */
	if (spi_sdcard_do_command(card, SET_BLOCKLEN, 512, NULL))
		return -1;

	/* CCS is bit30 of ocr register
	 * CCS = 0 -> SDSC
	 * CCS = 1 -> SDHC/SDXC
	 * */
	if ((ocr & 0x40000000) == 0)
		card->type = SDCARD_TYPE_SDSC;
	else {
		/* size > 32G -> SDXC */
		if (spi_sdcard_size(card) > 32LL * 1024 * 1024 * 1024)
			card->type = SDCARD_TYPE_SDXC;
		else
			card->type = SDCARD_TYPE_SDHC;
	}

	return 0;
}

int spi_sdcard_single_read(const struct spi_sdcard *card,
		size_t block_address,
		void *buff)
{
	int wait;
	uint16_t c = 0;

	if (card->type == SDCARD_TYPE_SDSC)
		block_address = block_address * 512;

	/* CMD17, start single block read */
	if (spi_sdcard_do_command(card, READ_SINGLE_BLOCK, block_address, NULL))
		return -1;

	/* enable cs */
	spi_sdcard_enable_cs(card);

	/* waiting start block token */
	wait = 0xffff;
	while ((spi_sdcard_recvbyte(card) != CT_BLOCK_START) && --wait)
		;
	if (!wait) { /* timeout */
		spi_sdcard_disable_cs(card);
		return -1;
	}

	/* receive data */
	for (int i = 0; i < 512; i++) {
		((uint8_t *)buff)[i] = spi_sdcard_recvbyte(card);
		c = crc16_byte(c, ((uint8_t *)buff)[i]);
	}

	/* receive crc and verify check sum */
	if (((c >> 8) & 0xff) != spi_sdcard_recvbyte(card)) {
		spi_sdcard_disable_cs(card);
		return -1;
	}
	if (((c >> 0) & 0xff) != spi_sdcard_recvbyte(card)) {
		spi_sdcard_disable_cs(card);
		return -1;
	}

	/* disable cs */
	spi_sdcard_disable_cs(card);

	return 0;
}

int spi_sdcard_multiple_read(const struct spi_sdcard *card,
		size_t start_block_address,
		size_t end_block_address,
		void *buff)
{
	int wait;
	int block_num = end_block_address - start_block_address + 1;
	if (card->type == SDCARD_TYPE_SDSC) {
		start_block_address = start_block_address * 512;
		end_block_address = end_block_address * 512;
	}
	/* CMD18, start multiple block read */
	if (spi_sdcard_do_command(card,
			READ_MULTIPLEBLOCK, start_block_address, NULL))
		return -1;

	/* enable cs */
	spi_sdcard_enable_cs(card);

	for (int i = 0; i < block_num; i++) {
		uint16_t c = 0;

		/* waiting start block token */
		wait = 0xffff;
		while ((spi_sdcard_recvbyte(card) != CT_BLOCK_START) && --wait)
			;
		if (!wait) { /* timeout */
			spi_sdcard_disable_cs(card);
			return -1;
		}

		/* receive data */
		for (int k = 0; k < 512; k++) {
			uint8_t tmp = spi_sdcard_recvbyte(card);
			((uint8_t *)buff)[512 * i + k] = tmp;
			c = crc16_byte(c, tmp);
		}

		/* receive crc and verify check sum */
		if (((c >> 8) & 0xff) != spi_sdcard_recvbyte(card)) {
			spi_sdcard_disable_cs(card);
			return -1;
		}
		if (((c >> 0) & 0xff) != spi_sdcard_recvbyte(card)) {
			spi_sdcard_disable_cs(card);
			return -1;
		}
	}

	/* disable cs */
	spi_sdcard_disable_cs(card);

	if (spi_sdcard_do_command(card, STOP_TRANSMISSION, 0, NULL))
		if (spi_sdcard_do_command(card, SEND_STATUS, 0, NULL))
			return -1;

	return 0;
}

int spi_sdcard_read(const struct spi_sdcard *card,
		void *dest,
		size_t offset,
		size_t count)
{
	size_t start_block_address = offset / BLOCK_SIZE;
	size_t end_block_address = (offset + count - 1) / BLOCK_SIZE;
	size_t has_begin = !!(offset % BLOCK_SIZE);
	size_t has_end = !!((offset + count) % BLOCK_SIZE);

	if (start_block_address == end_block_address) {
		uint8_t tmp[BLOCK_SIZE];
		size_t o = offset % BLOCK_SIZE;
		size_t l = count;
		if (spi_sdcard_single_read(card, start_block_address, tmp))
			return -1;
		memcpy(dest, tmp + o, l);
		return 0;
	}

	if (has_begin) {
		uint8_t tmp[BLOCK_SIZE];
		size_t o = offset % BLOCK_SIZE;
		size_t l = BLOCK_SIZE - o;
		if (spi_sdcard_single_read(card, start_block_address, tmp))
			return -1;
		memcpy(dest, tmp + o, l);
	}

	if (start_block_address + has_begin <= end_block_address - has_end) {
		size_t start_lba = start_block_address + has_begin;
		size_t end_lba = end_block_address - has_end;
		size_t o = has_begin ? BLOCK_SIZE - offset % BLOCK_SIZE : 0;
		if (start_lba < end_lba) {
			if (spi_sdcard_multiple_read(card, start_lba, end_lba,
					dest + o))
				return -1;
		} else {
			if (spi_sdcard_single_read(card, start_lba, dest + o))
				return -1;
		}
	}

	if (has_end) {
		uint8_t tmp[BLOCK_SIZE];
		size_t o = 0;
		size_t l = (offset + count) % BLOCK_SIZE;
		if (spi_sdcard_single_read(card, end_block_address, tmp))
			return -1;
		memcpy(dest + count - l, tmp + o, l);
	}

	return 0;
}

int spi_sdcard_single_write(const struct spi_sdcard *card,
		size_t block_address,
		void *buff)
{
	int wait;
	uint16_t c = 0;
	if (card->type == SDCARD_TYPE_SDSC)
		block_address = block_address * 512;

	if (spi_sdcard_do_command(card, WRITE_BLOCK, block_address, NULL))
		return -1;

	/* enable cs */
	spi_sdcard_enable_cs(card);

	/* send start block token */
	spi_sdcard_sendbyte(card, CT_BLOCK_START);

	/* send data */
	for (int i = 0; i < 512; i++) {
		spi_sdcard_sendbyte(card, ((uint8_t *)buff)[i]);
		c = crc16_byte(c, ((uint8_t *)buff)[i]);
	}

	/* send crc check sum */
	spi_sdcard_sendbyte(card, 0xff & (c >> 8));
	spi_sdcard_sendbyte(card, 0xff & (c >> 0));

	/* receive and verify data response token */
	c = spi_sdcard_recvbyte(card);
	if ((c & CT_RESPONSE_MASK) != CT_RESPONSE_ACCEPTED) {
		spi_sdcard_disable_cs(card);
		return -1;
	}

	wait = 0xffff;
	while ((spi_sdcard_recvbyte(card) == 0) && --wait)
		;/* wait for complete */
	if (!wait) {
		spi_sdcard_disable_cs(card);
		return -1;
	}

	/* disable cs */
	spi_sdcard_disable_cs(card);

	return 0;
}

int spi_sdcard_multiple_write(const struct spi_sdcard *card,
		size_t start_block_address,
		size_t end_block_address,
		void *buff)
{
	int wait, ret = 0;
	int block_num = end_block_address - start_block_address + 1;
	if (card->type == SDCARD_TYPE_SDSC) {
		start_block_address = start_block_address * 512;
		end_block_address = end_block_address * 512;
	}

	if (spi_sdcard_do_command(card, WRITE_MULTIPLEBLOCK,
		start_block_address, NULL))
		return -1;

	/* enable cs */
	spi_sdcard_enable_cs(card);

	for (int i = 0; i < block_num; i++) {
		uint16_t c = 0;

		ret = -1;

		/* send start block token */
		spi_sdcard_sendbyte(card, CT_MULTIPLE_BLOCK_START);

		/* send data */
		for (int k = 0; k < 512; k++) {
			uint8_t tmp = ((uint8_t *)buff)[512 * i + k];
			spi_sdcard_sendbyte(card, tmp);
			c = crc16_byte(c, tmp);
		}

		/* send crc check sum */
		spi_sdcard_sendbyte(card, 0xff & (c >> 8));
		spi_sdcard_sendbyte(card, 0xff & (c >> 0));

		/* receive and verify data response token */
		c = spi_sdcard_recvbyte(card);
		if ((c & CT_RESPONSE_MASK) != CT_RESPONSE_ACCEPTED)
			break;

		wait = 0xffff;
		while ((spi_sdcard_recvbyte(card) == 0) && --wait)
			;/* wait for complete */
		if (!wait)
			break;

		ret = 0;
	}

	/* send stop transmission token */
	spi_sdcard_sendbyte(card, CT_MULTIPLE_BLOCK_STOP);

	/* disable cs */
	spi_sdcard_disable_cs(card);

	if (spi_sdcard_do_command(card, STOP_TRANSMISSION, 0, NULL))
		if (spi_sdcard_do_command(card, SEND_STATUS, 0, NULL))
			return -1;

	return ret;
}

int spi_sdcard_erase(const struct spi_sdcard *card,
		size_t start_block_address,
		size_t end_block_address)
{
	if (card->type == SDCARD_TYPE_SDSC) {
		start_block_address = start_block_address * 512;
		end_block_address = end_block_address * 512;
	}

	/* CMD32, set erase start address */
	if (spi_sdcard_do_command(card, ERASE_WR_BLK_START_ADDR,
			start_block_address, NULL))
		return -1;

	/* CMD33, set erase end address */
	if (spi_sdcard_do_command(card, ERASE_WR_BLK_END_ADDR,
			end_block_address, NULL))
		return -1;

	/* CMD38, erase */
	if (spi_sdcard_do_command(card, ERASE, 0, NULL))
		return -1;

	return 0;
}

int spi_sdcard_erase_all(const struct spi_sdcard *card)
{
	return spi_sdcard_erase(card, 0, spi_sdcard_size(card) / BLOCK_SIZE);
}
