/*
 * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>
#include <string.h>

#include <common/debug.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_storage.h>
#include <drivers/mmc.h>
#include <drivers/st/io_mmc.h>
#include <drivers/st/stm32_sdmmc2.h>

/* SDMMC device functions */
static int mmc_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info);
static int mmc_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
			  io_entity_t *entity);
static int mmc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params);
static int mmc_block_seek(io_entity_t *entity, int mode,
			  signed long long offset);
static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
			  size_t *length_read);
static int mmc_block_close(io_entity_t *entity);
static int mmc_dev_close(io_dev_info_t *dev_info);
static io_type_t device_type_mmc(void);

static signed long long seek_offset;
static size_t (*_read_blocks)(int lba, uintptr_t buf, size_t size);

static const io_dev_connector_t mmc_dev_connector = {
	.dev_open = mmc_dev_open
};

static const io_dev_funcs_t mmc_dev_funcs = {
	.type = device_type_mmc,
	.open = mmc_block_open,
	.seek = mmc_block_seek,
	.size = NULL,
	.read = mmc_block_read,
	.write = NULL,
	.close = mmc_block_close,
	.dev_init = mmc_dev_init,
	.dev_close = mmc_dev_close,
};

static const io_dev_info_t mmc_dev_info = {
	.funcs = &mmc_dev_funcs,
	.info = 0,
};

/* Identify the device type as mmc device */
static io_type_t device_type_mmc(void)
{
	return IO_TYPE_MMC;
}

/* Open a connection to the mmc device */
static int mmc_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info)
{
	struct io_mmc_dev_spec *device_spec =
		(struct io_mmc_dev_spec *)init_params;

	assert(dev_info != NULL);
	*dev_info = (io_dev_info_t *)&mmc_dev_info;

	_read_blocks = !device_spec->use_boot_part ?
		mmc_read_blocks : mmc_boot_part_read_blocks;

	return 0;
}

static int mmc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params)
{
	return 0;
}

/* Close a connection to the mmc device */
static int mmc_dev_close(io_dev_info_t *dev_info)
{
	return 0;
}

/* Open a file on the mmc device */
static int mmc_block_open(io_dev_info_t *dev_info, const  uintptr_t spec,
			  io_entity_t *entity)
{
	seek_offset = 0;
	return 0;
}

/* Seek to a particular file offset on the mmc device */
static int mmc_block_seek(io_entity_t *entity, int mode,
			  signed long long offset)
{
	seek_offset = offset;
	return 0;
}

/* Read data from a file on the mmc device */
static int mmc_block_read(io_entity_t *entity, uintptr_t buffer,
			  size_t length, size_t *length_read)
{
	uint8_t retries;

	for (retries = 0U; retries < 3U; retries++) {
		*length_read = _read_blocks(seek_offset / MMC_BLOCK_SIZE,
					    buffer, length);

		if (*length_read == length) {
			return 0;
		}
		WARN("%s: length_read = %lu (!= %lu), retry %u\n", __func__,
		     (unsigned long)*length_read, (unsigned long)length,
		     retries + 1U);
	}

	return -EIO;
}

/* Close a file on the mmc device */
static int mmc_block_close(io_entity_t *entity)
{
	return 0;
}

/* Register the mmc driver with the IO abstraction */
int register_io_dev_mmc(const io_dev_connector_t **dev_con)
{
	int result;

	assert(dev_con != NULL);

	result = io_register_device(&mmc_dev_info);
	if (result == 0) {
		*dev_con = &mmc_dev_connector;
	}

	return result;
}
