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

/* Define a simple and generic interface to access eMMC and SD-card devices. */

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

#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <drivers/mmc.h>
#include <lib/utils.h>
#include <plat/common/common_def.h>

#define MMC_DEFAULT_MAX_RETRIES		5
#define SEND_OP_COND_MAX_RETRIES	100

#define MULT_BY_512K_SHIFT		19

static const struct mmc_ops *ops;
static unsigned int mmc_ocr_value;
static struct mmc_csd_emmc mmc_csd;
static struct sd_switch_status sd_switch_func_status;
static unsigned char mmc_ext_csd[512] __aligned(16);
static unsigned int mmc_flags;
static struct mmc_device_info *mmc_dev_info;
static unsigned int rca;
static unsigned int scr[2]__aligned(16) = { 0 };

static const unsigned char tran_speed_base[16] = {
	0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80
};

static const unsigned char sd_tran_speed_base[16] = {
	0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
};

static bool is_cmd23_enabled(void)
{
	return ((mmc_flags & MMC_FLAG_CMD23) != 0U);
}

static bool is_sd_cmd6_enabled(void)
{
	return ((mmc_flags & MMC_FLAG_SD_CMD6) != 0U);
}

static int mmc_send_cmd(unsigned int idx, unsigned int arg,
			unsigned int r_type, unsigned int *r_data)
{
	struct mmc_cmd cmd;
	int ret;

	zeromem(&cmd, sizeof(struct mmc_cmd));

	cmd.cmd_idx = idx;
	cmd.cmd_arg = arg;
	cmd.resp_type = r_type;

	ret = ops->send_cmd(&cmd);

	if ((ret == 0) && (r_data != NULL)) {
		int i;

		for (i = 0; i < 4; i++) {
			r_data[i] = cmd.resp_data[i];
		}
	}

	if (ret != 0) {
		VERBOSE("Send command %u error: %d\n", idx, ret);
	}

	return ret;
}

static int mmc_device_state(void)
{
	int retries = MMC_DEFAULT_MAX_RETRIES;
	unsigned int resp_data[4];

	do {
		int ret;

		if (retries == 0) {
			ERROR("CMD13 failed after %d retries\n",
			      MMC_DEFAULT_MAX_RETRIES);
			return -EIO;
		}

		ret = mmc_send_cmd(MMC_CMD(13), rca << RCA_SHIFT_OFFSET,
				   MMC_RESPONSE_R1, &resp_data[0]);
		if (ret != 0) {
			retries--;
			continue;
		}

		if ((resp_data[0] & STATUS_SWITCH_ERROR) != 0U) {
			return -EIO;
		}

		retries--;
	} while ((resp_data[0] & STATUS_READY_FOR_DATA) == 0U);

	return MMC_GET_STATE(resp_data[0]);
}

static int mmc_send_part_switch_cmd(unsigned int part_config)
{
	int ret;
	unsigned int part_time = 0;

	ret = mmc_send_cmd(MMC_CMD(6),
			   EXTCSD_WRITE_BYTES |
			   EXTCSD_CMD(CMD_EXTCSD_PARTITION_CONFIG) |
			   EXTCSD_VALUE(part_config) |
			   EXTCSD_CMD_SET_NORMAL,
			   MMC_RESPONSE_R1B, NULL);
	if (ret != 0) {
		return ret;
	}

	/* Partition switch timing is in 10ms units */
	part_time = mmc_ext_csd[CMD_EXTCSD_PART_SWITCH_TIME] * 10;

	mdelay(part_time);

	do {
		ret = mmc_device_state();
		if (ret < 0) {
			return ret;
		}
	} while (ret == MMC_STATE_PRG);

	return 0;
}

static int mmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
{
	int ret;

	ret = mmc_send_cmd(MMC_CMD(6),
			   EXTCSD_WRITE_BYTES | EXTCSD_CMD(ext_cmd) |
			   EXTCSD_VALUE(value) | EXTCSD_CMD_SET_NORMAL,
			   MMC_RESPONSE_R1B, NULL);
	if (ret != 0) {
		return ret;
	}

	do {
		ret = mmc_device_state();
		if (ret < 0) {
			return ret;
		}
	} while (ret == MMC_STATE_PRG);

	return 0;
}

static int mmc_sd_switch(unsigned int bus_width)
{
	int ret;
	int retries = MMC_DEFAULT_MAX_RETRIES;
	unsigned int bus_width_arg = 0;

	ret = ops->prepare(0, (uintptr_t)&scr, sizeof(scr));
	if (ret != 0) {
		return ret;
	}

	/* CMD55: Application Specific Command */
	ret = mmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
			   MMC_RESPONSE_R5, NULL);
	if (ret != 0) {
		return ret;
	}

	/* ACMD51: SEND_SCR */
	do {
		ret = mmc_send_cmd(MMC_ACMD(51), 0, MMC_RESPONSE_R1, NULL);
		if ((ret != 0) && (retries == 0)) {
			ERROR("ACMD51 failed after %d retries (ret=%d)\n",
			      MMC_DEFAULT_MAX_RETRIES, ret);
			return ret;
		}

		retries--;
	} while (ret != 0);

	ret = ops->read(0, (uintptr_t)&scr, sizeof(scr));
	if (ret != 0) {
		return ret;
	}

	if (((scr[0] & SD_SCR_BUS_WIDTH_4) != 0U) &&
	    (bus_width == MMC_BUS_WIDTH_4)) {
		bus_width_arg = 2;
	}

	/* CMD55: Application Specific Command */
	ret = mmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
			   MMC_RESPONSE_R5, NULL);
	if (ret != 0) {
		return ret;
	}

	/* ACMD6: SET_BUS_WIDTH */
	ret = mmc_send_cmd(MMC_ACMD(6), bus_width_arg, MMC_RESPONSE_R1, NULL);
	if (ret != 0) {
		return ret;
	}

	do {
		ret = mmc_device_state();
		if (ret < 0) {
			return ret;
		}
	} while (ret == MMC_STATE_PRG);

	return 0;
}

static int mmc_set_ios(unsigned int clk, unsigned int bus_width)
{
	int ret;
	unsigned int width = bus_width;

	if (mmc_dev_info->mmc_dev_type != MMC_IS_EMMC) {
		if (width == MMC_BUS_WIDTH_8) {
			WARN("Wrong bus config for SD-card, force to 4\n");
			width = MMC_BUS_WIDTH_4;
		}
		ret = mmc_sd_switch(width);
		if (ret != 0) {
			return ret;
		}
	} else if (mmc_csd.spec_vers == 4U) {
		ret = mmc_set_ext_csd(CMD_EXTCSD_BUS_WIDTH,
				      (unsigned int)width);
		if (ret != 0) {
			return ret;
		}
	} else {
		VERBOSE("Wrong MMC type or spec version\n");
	}

	return ops->set_ios(clk, width);
}

static int mmc_fill_device_info(void)
{
	unsigned long long c_size;
	unsigned int speed_idx;
	unsigned int nb_blocks;
	unsigned int freq_unit;
	int ret = 0;
	struct mmc_csd_sd_v2 *csd_sd_v2;

	switch (mmc_dev_info->mmc_dev_type) {
	case MMC_IS_EMMC:
		mmc_dev_info->block_size = MMC_BLOCK_SIZE;

		ret = ops->prepare(0, (uintptr_t)&mmc_ext_csd,
				   sizeof(mmc_ext_csd));
		if (ret != 0) {
			return ret;
		}

		/* MMC CMD8: SEND_EXT_CSD */
		ret = mmc_send_cmd(MMC_CMD(8), 0, MMC_RESPONSE_R1, NULL);
		if (ret != 0) {
			return ret;
		}

		ret = ops->read(0, (uintptr_t)&mmc_ext_csd,
				sizeof(mmc_ext_csd));
		if (ret != 0) {
			return ret;
		}

		do {
			ret = mmc_device_state();
			if (ret < 0) {
				return ret;
			}
		} while (ret != MMC_STATE_TRAN);

		nb_blocks = (mmc_ext_csd[CMD_EXTCSD_SEC_CNT] << 0) |
			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 1] << 8) |
			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 2] << 16) |
			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 3] << 24);

		mmc_dev_info->device_size = (unsigned long long)nb_blocks *
			mmc_dev_info->block_size;

		break;

	case MMC_IS_SD:
		/*
		 * Use the same mmc_csd struct, as required fields here
		 * (READ_BL_LEN, C_SIZE, CSIZE_MULT) are common with eMMC.
		 */
		mmc_dev_info->block_size = BIT_32(mmc_csd.read_bl_len);

		c_size = ((unsigned long long)mmc_csd.c_size_high << 2U) |
			 (unsigned long long)mmc_csd.c_size_low;
		assert(c_size != 0xFFFU);

		mmc_dev_info->device_size = (c_size + 1U) *
					    BIT_64(mmc_csd.c_size_mult + 2U) *
					    mmc_dev_info->block_size;

		break;

	case MMC_IS_SD_HC:
		assert(mmc_csd.csd_structure == 1U);

		mmc_dev_info->block_size = MMC_BLOCK_SIZE;

		/* Need to use mmc_csd_sd_v2 struct */
		csd_sd_v2 = (struct mmc_csd_sd_v2 *)&mmc_csd;
		c_size = ((unsigned long long)csd_sd_v2->c_size_high << 16) |
			 (unsigned long long)csd_sd_v2->c_size_low;

		mmc_dev_info->device_size = (c_size + 1U) << MULT_BY_512K_SHIFT;

		break;

	default:
		ret = -EINVAL;
		break;
	}

	if (ret < 0) {
		return ret;
	}

	speed_idx = (mmc_csd.tran_speed & CSD_TRAN_SPEED_MULT_MASK) >>
			 CSD_TRAN_SPEED_MULT_SHIFT;

	assert(speed_idx > 0U);

	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
		mmc_dev_info->max_bus_freq = tran_speed_base[speed_idx];
	} else {
		mmc_dev_info->max_bus_freq = sd_tran_speed_base[speed_idx];
	}

	freq_unit = mmc_csd.tran_speed & CSD_TRAN_SPEED_UNIT_MASK;
	while (freq_unit != 0U) {
		mmc_dev_info->max_bus_freq *= 10U;
		--freq_unit;
	}

	mmc_dev_info->max_bus_freq *= 10000U;

	return 0;
}

static int sd_switch(unsigned int mode, unsigned char group,
		     unsigned char func)
{
	unsigned int group_shift = (group - 1U) * 4U;
	unsigned int group_mask = GENMASK(group_shift + 3U,  group_shift);
	unsigned int arg;
	int ret;

	ret = ops->prepare(0, (uintptr_t)&sd_switch_func_status,
			   sizeof(sd_switch_func_status));
	if (ret != 0) {
		return ret;
	}

	/* MMC CMD6: SWITCH_FUNC */
	arg = mode | SD_SWITCH_ALL_GROUPS_MASK;
	arg &= ~group_mask;
	arg |= func << group_shift;
	ret = mmc_send_cmd(MMC_CMD(6), arg, MMC_RESPONSE_R1, NULL);
	if (ret != 0) {
		return ret;
	}

	return ops->read(0, (uintptr_t)&sd_switch_func_status,
			 sizeof(sd_switch_func_status));
}

static int sd_send_op_cond(void)
{
	int n;
	unsigned int resp_data[4];

	for (n = 0; n < SEND_OP_COND_MAX_RETRIES; n++) {
		int ret;

		/* CMD55: Application Specific Command */
		ret = mmc_send_cmd(MMC_CMD(55), 0, MMC_RESPONSE_R1, NULL);
		if (ret != 0) {
			return ret;
		}

		/* ACMD41: SD_SEND_OP_COND */
		ret = mmc_send_cmd(MMC_ACMD(41), OCR_HCS |
			mmc_dev_info->ocr_voltage, MMC_RESPONSE_R3,
			&resp_data[0]);
		if (ret != 0) {
			return ret;
		}

		if ((resp_data[0] & OCR_POWERUP) != 0U) {
			mmc_ocr_value = resp_data[0];

			if ((mmc_ocr_value & OCR_HCS) != 0U) {
				mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
			} else {
				mmc_dev_info->mmc_dev_type = MMC_IS_SD;
			}

			return 0;
		}

		mdelay(10);
	}

	ERROR("ACMD41 failed after %d retries\n", SEND_OP_COND_MAX_RETRIES);

	return -EIO;
}

static int mmc_reset_to_idle(void)
{
	int ret;

	/* CMD0: reset to IDLE */
	ret = mmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
	if (ret != 0) {
		return ret;
	}

	mdelay(2);

	return 0;
}

static int mmc_send_op_cond(void)
{
	int ret, n;
	unsigned int resp_data[4];

	ret = mmc_reset_to_idle();
	if (ret != 0) {
		return ret;
	}

	for (n = 0; n < SEND_OP_COND_MAX_RETRIES; n++) {
		ret = mmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
				   OCR_VDD_MIN_2V7 | OCR_VDD_MIN_1V7,
				   MMC_RESPONSE_R3, &resp_data[0]);
		if (ret != 0) {
			return ret;
		}

		if ((resp_data[0] & OCR_POWERUP) != 0U) {
			mmc_ocr_value = resp_data[0];
			return 0;
		}

		mdelay(10);
	}

	ERROR("CMD1 failed after %d retries\n", SEND_OP_COND_MAX_RETRIES);

	return -EIO;
}

static int mmc_enumerate(unsigned int clk, unsigned int bus_width)
{
	int ret;
	unsigned int resp_data[4];

	ops->init();

	ret = mmc_reset_to_idle();
	if (ret != 0) {
		return ret;
	}

	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
		ret = mmc_send_op_cond();
	} else {
		/* CMD8: Send Interface Condition Command */
		ret = mmc_send_cmd(MMC_CMD(8), VHS_2_7_3_6_V | CMD8_CHECK_PATTERN,
				   MMC_RESPONSE_R5, &resp_data[0]);

		if ((ret == 0) && ((resp_data[0] & 0xffU) == CMD8_CHECK_PATTERN)) {
			ret = sd_send_op_cond();
		}
	}
	if (ret != 0) {
		return ret;
	}

	/* CMD2: Card Identification */
	ret = mmc_send_cmd(MMC_CMD(2), 0, MMC_RESPONSE_R2, NULL);
	if (ret != 0) {
		return ret;
	}

	/* CMD3: Set Relative Address */
	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
		rca = MMC_FIX_RCA;
		ret = mmc_send_cmd(MMC_CMD(3), rca << RCA_SHIFT_OFFSET,
				   MMC_RESPONSE_R1, NULL);
		if (ret != 0) {
			return ret;
		}
	} else {
		ret = mmc_send_cmd(MMC_CMD(3), 0,
				   MMC_RESPONSE_R6, &resp_data[0]);
		if (ret != 0) {
			return ret;
		}

		rca = (resp_data[0] & 0xFFFF0000U) >> 16;
	}

	/* CMD9: CSD Register */
	ret = mmc_send_cmd(MMC_CMD(9), rca << RCA_SHIFT_OFFSET,
			   MMC_RESPONSE_R2, &resp_data[0]);
	if (ret != 0) {
		return ret;
	}

	memcpy(&mmc_csd, &resp_data, sizeof(resp_data));

	/* CMD7: Select Card */
	ret = mmc_send_cmd(MMC_CMD(7), rca << RCA_SHIFT_OFFSET,
			   MMC_RESPONSE_R1, NULL);
	if (ret != 0) {
		return ret;
	}

	do {
		ret = mmc_device_state();
		if (ret < 0) {
			return ret;
		}
	} while (ret != MMC_STATE_TRAN);

	ret = mmc_set_ios(clk, bus_width);
	if (ret != 0) {
		return ret;
	}

	ret = mmc_fill_device_info();
	if (ret != 0) {
		return ret;
	}

	if (is_sd_cmd6_enabled() &&
	    (mmc_dev_info->mmc_dev_type == MMC_IS_SD_HC)) {
		/* Try to switch to High Speed Mode */
		ret = sd_switch(SD_SWITCH_FUNC_CHECK, 1U, 1U);
		if (ret != 0) {
			return ret;
		}

		if ((sd_switch_func_status.support_g1 & BIT(9)) == 0U) {
			/* High speed not supported, keep default speed */
			return 0;
		}

		ret = sd_switch(SD_SWITCH_FUNC_SWITCH, 1U, 1U);
		if (ret != 0) {
			return ret;
		}

		if ((sd_switch_func_status.sel_g2_g1 & 0x1U) == 0U) {
			/* Cannot switch to high speed, keep default speed */
			return 0;
		}

		mmc_dev_info->max_bus_freq = 50000000U;
		ret = ops->set_ios(clk, bus_width);
	}

	return ret;
}

size_t mmc_read_blocks(int lba, uintptr_t buf, size_t size)
{
	int ret;
	unsigned int cmd_idx, cmd_arg;

	assert((ops != NULL) &&
	       (ops->read != NULL) &&
	       (size != 0U) &&
	       ((size & MMC_BLOCK_MASK) == 0U));

	ret = ops->prepare(lba, buf, size);
	if (ret != 0) {
		return 0;
	}

	if (is_cmd23_enabled()) {
		/* Set block count */
		ret = mmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
				   MMC_RESPONSE_R1, NULL);
		if (ret != 0) {
			return 0;
		}

		cmd_idx = MMC_CMD(18);
	} else {
		if (size > MMC_BLOCK_SIZE) {
			cmd_idx = MMC_CMD(18);
		} else {
			cmd_idx = MMC_CMD(17);
		}
	}

	if (((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) &&
	    (mmc_dev_info->mmc_dev_type != MMC_IS_SD_HC)) {
		cmd_arg = lba * MMC_BLOCK_SIZE;
	} else {
		cmd_arg = lba;
	}

	ret = mmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R1, NULL);
	if (ret != 0) {
		return 0;
	}

	ret = ops->read(lba, buf, size);
	if (ret != 0) {
		return 0;
	}

	/* Wait buffer empty */
	do {
		ret = mmc_device_state();
		if (ret < 0) {
			return 0;
		}
	} while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_DATA));

	if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
		ret = mmc_send_cmd(MMC_CMD(12), 0, MMC_RESPONSE_R1B, NULL);
		if (ret != 0) {
			return 0;
		}
	}

	return size;
}

size_t mmc_write_blocks(int lba, const uintptr_t buf, size_t size)
{
	int ret;
	unsigned int cmd_idx, cmd_arg;

	assert((ops != NULL) &&
	       (ops->write != NULL) &&
	       (size != 0U) &&
	       ((buf & MMC_BLOCK_MASK) == 0U) &&
	       ((size & MMC_BLOCK_MASK) == 0U));

	ret = ops->prepare(lba, buf, size);
	if (ret != 0) {
		return 0;
	}

	if (is_cmd23_enabled()) {
		/* Set block count */
		ret = mmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
				   MMC_RESPONSE_R1, NULL);
		if (ret != 0) {
			return 0;
		}

		cmd_idx = MMC_CMD(25);
	} else {
		if (size > MMC_BLOCK_SIZE) {
			cmd_idx = MMC_CMD(25);
		} else {
			cmd_idx = MMC_CMD(24);
		}
	}

	if ((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) {
		cmd_arg = lba * MMC_BLOCK_SIZE;
	} else {
		cmd_arg = lba;
	}

	ret = mmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R1, NULL);
	if (ret != 0) {
		return 0;
	}

	ret = ops->write(lba, buf, size);
	if (ret != 0) {
		return 0;
	}

	/* Wait buffer empty */
	do {
		ret = mmc_device_state();
		if (ret < 0) {
			return 0;
		}
	} while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_RCV));

	if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
		ret = mmc_send_cmd(MMC_CMD(12), 0, MMC_RESPONSE_R1B, NULL);
		if (ret != 0) {
			return 0;
		}
	}

	return size;
}

size_t mmc_erase_blocks(int lba, size_t size)
{
	int ret;

	assert(ops != NULL);
	assert((size != 0U) && ((size & MMC_BLOCK_MASK) == 0U));

	ret = mmc_send_cmd(MMC_CMD(35), lba, MMC_RESPONSE_R1, NULL);
	if (ret != 0) {
		return 0;
	}

	ret = mmc_send_cmd(MMC_CMD(36), lba + (size / MMC_BLOCK_SIZE) - 1U,
			   MMC_RESPONSE_R1, NULL);
	if (ret != 0) {
		return 0;
	}

	ret = mmc_send_cmd(MMC_CMD(38), lba, MMC_RESPONSE_R1B, NULL);
	if (ret != 0) {
		return 0;
	}

	do {
		ret = mmc_device_state();
		if (ret < 0) {
			return 0;
		}
	} while (ret != MMC_STATE_TRAN);

	return size;
}

static int mmc_part_switch(unsigned int part_type)
{
	uint8_t part_config = mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG];

	part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
	part_config |= part_type;

	return mmc_send_part_switch_cmd(part_config);
}

static unsigned char mmc_current_boot_part(void)
{
	return PART_CFG_CURRENT_BOOT_PARTITION(mmc_ext_csd[CMD_EXTCSD_PARTITION_CONFIG]);
}

int mmc_part_switch_current_boot(void)
{
	unsigned char current_boot_part = mmc_current_boot_part();
	int ret;

	if ((current_boot_part != 1U) && (current_boot_part != 2U)) {
		ERROR("Got unexpected value for active boot partition, %u\n", current_boot_part);
		return -EIO;
	}

	ret = mmc_part_switch(current_boot_part);
	if (ret < 0) {
		ERROR("Failed to switch to boot partition, %d\n", ret);
	}

	return ret;
}

int mmc_part_switch_user(void)
{
	int ret;

	ret = mmc_part_switch(PART_CFG_BOOT_PARTITION_NO_ACCESS);
	if (ret < 0) {
		ERROR("Failed to switch to user partition, %d\n", ret);
	}

	return ret;
}

size_t mmc_boot_part_size(void)
{
	return mmc_ext_csd[CMD_EXTCSD_BOOT_SIZE_MULT] * SZ_128K;
}

size_t mmc_boot_part_read_blocks(int lba, uintptr_t buf, size_t size)
{
	size_t size_read;
	int ret;

	ret = mmc_part_switch_current_boot();
	if (ret < 0) {
		return 0;
	}

	size_read = mmc_read_blocks(lba, buf, size);

	ret = mmc_part_switch_user();
	if (ret < 0) {
		return 0;
	}

	return size_read;
}

int mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
	     unsigned int width, unsigned int flags,
	     struct mmc_device_info *device_info)
{
	assert((ops_ptr != NULL) &&
	       (ops_ptr->init != NULL) &&
	       (ops_ptr->send_cmd != NULL) &&
	       (ops_ptr->set_ios != NULL) &&
	       (ops_ptr->prepare != NULL) &&
	       (ops_ptr->read != NULL) &&
	       (ops_ptr->write != NULL) &&
	       (device_info != NULL) &&
	       (clk != 0) &&
	       ((width == MMC_BUS_WIDTH_1) ||
		(width == MMC_BUS_WIDTH_4) ||
		(width == MMC_BUS_WIDTH_8) ||
		(width == MMC_BUS_WIDTH_DDR_4) ||
		(width == MMC_BUS_WIDTH_DDR_8)));

	ops = ops_ptr;
	mmc_flags = flags;
	mmc_dev_info = device_info;

	return mmc_enumerate(clk, width);
}
