/*
 * Copyright 2022 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * MMC disk driver using zephyr SD subsystem
 */
#define DT_DRV_COMPAT zephyr_mmc_disk

#include <zephyr/sd/mmc.h>
#include <zephyr/drivers/disk.h>


enum sd_status {
	SD_UNINIT,
	SD_ERROR,
	SD_OK,
};

struct mmc_config {
	const struct device *host_controller;
	uint8_t bus_width;
};

struct mmc_data {
	struct sd_card card;
	enum sd_status status;
	char *name;
};


static int disk_mmc_access_init(struct disk_info *disk)
{
	const struct device *dev = disk->dev;
	const struct mmc_config *cfg = dev->config;
	struct mmc_data *data = dev->data;
	int ret;

	ret = sd_init(cfg->host_controller, &data->card);
	if (ret) {
		data->status = SD_ERROR;
		return ret;
	}
	data->status = SD_OK;
	return 0;
}

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

	if (data->status == SD_OK) {
		return DISK_STATUS_OK;
	} else {
		return DISK_STATUS_UNINIT;
	}
}

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

	return mmc_read_blocks(&data->card, buf, sector, count);
}

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

	return mmc_write_blocks(&data->card, buf, sector, count);
}

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

	switch (cmd) {
	case DISK_IOCTL_CTRL_INIT:
		return disk_mmc_access_init(disk);
	case DISK_IOCTL_CTRL_DEINIT:
		mmc_ioctl(&data->card, DISK_IOCTL_CTRL_SYNC, NULL);
		/* sd_init() will toggle power to MMC, so we can just mark
		 * disk as uninitialized
		 */
		data->status = SD_UNINIT;
		return 0;
	default:
		return mmc_ioctl(&data->card, cmd, buf);
	}

	return 0;
}

static const struct disk_operations mmc_disk_ops = {
	.init = disk_mmc_access_init,
	.status = disk_mmc_access_status,
	.read = disk_mmc_access_read,
	.write = disk_mmc_access_write,
	.ioctl = disk_mmc_access_ioctl,
};

static struct disk_info mmc_disk = {
	.ops = &mmc_disk_ops,
};

static int disk_mmc_init(const struct device *dev)
{
	struct mmc_data *data = dev->data;
	const struct mmc_config *config = dev->config;

	data->status = SD_UNINIT;
	data->card.bus_width = config->bus_width;
	mmc_disk.dev = dev;
	mmc_disk.name = data->name;

	return disk_access_register(&mmc_disk);
}

#define DISK_ACCESS_MMC_INIT(n)						\
	static const struct mmc_config mmc_config_##n = {			\
		.host_controller = DEVICE_DT_GET(DT_INST_PARENT(n)),		\
		.bus_width = DT_INST_PROP(n, bus_width),			\
	};									\
										\
	static struct mmc_data mmc_data_##n = {				\
		.name = CONFIG_MMC_VOLUME_NAME,				\
	};									\
										\
	DEVICE_DT_INST_DEFINE(n,						\
			&disk_mmc_init,					\
			NULL,							\
			&mmc_data_##n,					\
			&mmc_config_##n,					\
			POST_KERNEL,						\
			CONFIG_SD_INIT_PRIORITY,				\
			NULL);

DT_INST_FOREACH_STATUS_OKAY(DISK_ACCESS_MMC_INIT)
