/*
 * Copyright (C) 2016 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <malloc.h>
#include <mmc.h>
#include "mmc_private.h"

static struct list_head mmc_devices;
static int cur_dev_num = -1;

#if !CONFIG_IS_ENABLED(MMC_TINY)
struct mmc *find_mmc_device(int dev_num)
{
	struct mmc *m;
	struct list_head *entry;

	list_for_each(entry, &mmc_devices) {
		m = list_entry(entry, struct mmc, link);

		if (m->block_dev.devnum == dev_num)
			return m;
	}

#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
	printf("MMC Device %d not found\n", dev_num);
#endif

	return NULL;
}

int mmc_get_next_devnum(void)
{
	return cur_dev_num++;
}

struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
{
	return &mmc->block_dev;
}

int get_mmc_num(void)
{
	return cur_dev_num;
}

void mmc_do_preinit(void)
{
	struct mmc *m;
	struct list_head *entry;

	list_for_each(entry, &mmc_devices) {
		m = list_entry(entry, struct mmc, link);

#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
		mmc_set_preinit(m, 1);
#endif
		if (m->preinit)
			mmc_start_init(m);
	}
}
#endif

void mmc_list_init(void)
{
	INIT_LIST_HEAD(&mmc_devices);
	cur_dev_num = 0;
}

void mmc_list_add(struct mmc *mmc)
{
	INIT_LIST_HEAD(&mmc->link);

	list_add_tail(&mmc->link, &mmc_devices);
}

#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
void print_mmc_devices(char separator)
{
	struct mmc *m;
	struct list_head *entry;
	char *mmc_type;

	list_for_each(entry, &mmc_devices) {
		m = list_entry(entry, struct mmc, link);

		if (m->has_init)
			mmc_type = IS_SD(m) ? "SD" : "eMMC";
		else
			mmc_type = NULL;

		printf("%s: %d", m->cfg->name, m->block_dev.devnum);
		if (mmc_type)
			printf(" (%s)", mmc_type);

		if (entry->next != &mmc_devices) {
			printf("%c", separator);
			if (separator != '\n')
				puts(" ");
		}
	}

	printf("\n");
}

#else
void print_mmc_devices(char separator) { }
#endif

#if CONFIG_IS_ENABLED(MMC_TINY)
static struct mmc mmc_static = {
	.dsr_imp		= 0,
	.dsr			= 0xffffffff,
	.block_dev = {
		.if_type	= IF_TYPE_MMC,
		.removable	= 1,
		.devnum		= 0,
		.block_read	= mmc_bread,
		.block_write	= mmc_bwrite,
		.block_erase	= mmc_berase,
		.part_type	= 0,
	},
};

struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
{
	struct mmc *mmc = &mmc_static;

	mmc->cfg = cfg;
	mmc->priv = priv;

	return mmc;
}

void mmc_destroy(struct mmc *mmc)
{
}
#else
struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
{
	struct blk_desc *bdesc;
	struct mmc *mmc;

	/* quick validation */
	if (cfg == NULL || cfg->f_min == 0 ||
	    cfg->f_max == 0 || cfg->b_max == 0)
		return NULL;

#ifndef CONFIG_DM_MMC_OPS
	if (cfg->ops == NULL || cfg->ops->send_cmd == NULL)
		return NULL;
#endif

	mmc = calloc(1, sizeof(*mmc));
	if (mmc == NULL)
		return NULL;

	mmc->cfg = cfg;
	mmc->priv = priv;

	/* the following chunk was mmc_register() */

	/* Setup dsr related values */
	mmc->dsr_imp = 0;
	mmc->dsr = 0xffffffff;
	/* Setup the universal parts of the block interface just once */
	bdesc = mmc_get_blk_desc(mmc);
	bdesc->if_type = IF_TYPE_MMC;
	bdesc->removable = 1;
	bdesc->devnum = mmc_get_next_devnum();
	bdesc->block_read = mmc_bread;
	bdesc->block_write = mmc_bwrite;
	bdesc->block_erase = mmc_berase;

	/* setup initial part type */
	bdesc->part_type = mmc->cfg->part_type;
	mmc_list_add(mmc);

	return mmc;
}

void mmc_destroy(struct mmc *mmc)
{
	/* only freeing memory for now */
	free(mmc);
}
#endif

static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
{
	struct mmc *mmc = find_mmc_device(desc->devnum);
	int ret;

	if (!mmc)
		return -ENODEV;

	if (mmc->block_dev.hwpart == hwpart)
		return 0;

	if (mmc->part_config == MMCPART_NOAVAILABLE)
		return -EMEDIUMTYPE;

	ret = mmc_switch_part(mmc, hwpart);
	if (ret)
		return ret;

	return 0;
}

static int mmc_get_dev(int dev, struct blk_desc **descp)
{
	struct mmc *mmc = find_mmc_device(dev);
	int ret;

	if (!mmc)
		return -ENODEV;
	ret = mmc_init(mmc);
	if (ret)
		return ret;

	*descp = &mmc->block_dev;

	return 0;
}

U_BOOT_LEGACY_BLK(mmc) = {
	.if_typename	= "mmc",
	.if_type	= IF_TYPE_MMC,
	.max_devs	= -1,
	.get_dev	= mmc_get_dev,
	.select_hwpart	= mmc_select_hwpartp,
};
