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

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <mmc.h>
#include <asm/test.h>

DECLARE_GLOBAL_DATA_PTR;

struct sandbox_mmc_plat {
	struct mmc_config cfg;
	struct mmc mmc;
};

/**
 * sandbox_mmc_send_cmd() - Emulate SD commands
 *
 * This emulate an SD card version 2. Single-block reads result in zero data.
 * Multiple-block reads return a test string.
 */
static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
				struct mmc_data *data)
{
	switch (cmd->cmdidx) {
	case MMC_CMD_ALL_SEND_CID:
		break;
	case SD_CMD_SEND_RELATIVE_ADDR:
		cmd->response[0] = 0 << 16; /* mmc->rca */
	case MMC_CMD_GO_IDLE_STATE:
		break;
	case SD_CMD_SEND_IF_COND:
		cmd->response[0] = 0xaa;
		break;
	case MMC_CMD_SEND_STATUS:
		cmd->response[0] = MMC_STATUS_RDY_FOR_DATA;
		break;
	case MMC_CMD_SELECT_CARD:
		break;
	case MMC_CMD_SEND_CSD:
		cmd->response[0] = 0;
		cmd->response[1] = 10 << 16;	/* 1 << block_len */
		break;
	case SD_CMD_SWITCH_FUNC: {
		if (!data)
			break;
		u32 *resp = (u32 *)data->dest;
		resp[7] = cpu_to_be32(SD_HIGHSPEED_BUSY);
		if ((cmd->cmdarg & 0xF) == UHS_SDR12_BUS_SPEED)
			resp[4] = (cmd->cmdarg & 0xF) << 24;
		break;
	}
	case MMC_CMD_READ_SINGLE_BLOCK:
		memset(data->dest, '\0', data->blocksize);
		break;
	case MMC_CMD_READ_MULTIPLE_BLOCK:
		strcpy(data->dest, "this is a test");
		break;
	case MMC_CMD_STOP_TRANSMISSION:
		break;
	case SD_CMD_APP_SEND_OP_COND:
		cmd->response[0] = OCR_BUSY | OCR_HCS;
		cmd->response[1] = 0;
		cmd->response[2] = 0;
		break;
	case MMC_CMD_APP_CMD:
		break;
	case MMC_CMD_SET_BLOCKLEN:
		debug("block len %d\n", cmd->cmdarg);
		break;
	case SD_CMD_APP_SEND_SCR: {
		u32 *scr = (u32 *)data->dest;

		scr[0] = cpu_to_be32(2 << 24 | 1 << 15);  /* SD version 3 */
		break;
	}
	default:
		debug("%s: Unknown command %d\n", __func__, cmd->cmdidx);
		break;
	}

	return 0;
}

static int sandbox_mmc_set_ios(struct udevice *dev)
{
	return 0;
}

static int sandbox_mmc_get_cd(struct udevice *dev)
{
	return 1;
}

static const struct dm_mmc_ops sandbox_mmc_ops = {
	.send_cmd = sandbox_mmc_send_cmd,
	.set_ios = sandbox_mmc_set_ios,
	.get_cd = sandbox_mmc_get_cd,
};

int sandbox_mmc_probe(struct udevice *dev)
{
	struct sandbox_mmc_plat *plat = dev_get_platdata(dev);

	return mmc_init(&plat->mmc);
}

int sandbox_mmc_bind(struct udevice *dev)
{
	struct sandbox_mmc_plat *plat = dev_get_platdata(dev);
	struct mmc_config *cfg = &plat->cfg;

	cfg->name = dev->name;
	cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_8BIT;
	cfg->voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
	cfg->f_min = 1000000;
	cfg->f_max = 52000000;
	cfg->b_max = U32_MAX;

	return mmc_bind(dev, &plat->mmc, cfg);
}

int sandbox_mmc_unbind(struct udevice *dev)
{
	mmc_unbind(dev);

	return 0;
}

static const struct udevice_id sandbox_mmc_ids[] = {
	{ .compatible = "sandbox,mmc" },
	{ }
};

U_BOOT_DRIVER(mmc_sandbox) = {
	.name		= "mmc_sandbox",
	.id		= UCLASS_MMC,
	.of_match	= sandbox_mmc_ids,
	.ops		= &sandbox_mmc_ops,
	.bind		= sandbox_mmc_bind,
	.unbind		= sandbox_mmc_unbind,
	.probe		= sandbox_mmc_probe,
	.platdata_auto_alloc_size = sizeof(struct sandbox_mmc_plat),
};
