//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  Copyright (C) 2007 Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
#ifndef __SDMMC_H__
#define __SDMMC_H__

#if __cplusplus
extern "C" {
#endif

#include "bsp.h"
#pragma warning(push)
#pragma warning(disable: 4127)
#pragma warning(disable: 4201)
#pragma warning(disable: 4214)
#include "sdcard.h"
#include "sdcardddk.h"
#pragma warning(pop)
#include "fmd.h"


#define SDMMC									2		// Flash Type
#define SDHC_SECTOR_SIZE						512		// Sector Size
#define SDHC_BLOCK_CNT							65536	// Max Number of Blocks
#define SDHC_SECTOR_CNT							1		// Number of sectors to constitute a Block
#define SDHC_DELAY_TIMEOUT	                    60      // Timeout in Number of seconds

#define SDH_RESPONSE_FIFO_DEPTH					8 

#define MMC_CMD_ERASE_WR_BLK_START              35
#define MMC_CMD_ERASE_WR_BLK_END                36
#define MMC_OCR_VALUE							0x40FF8000
#define MMC_OCR_VALUE_MASK						0x00FF8000
#define MMC_OCR_HC_RES							0xC0FF8000
#define MMC_OCR_LC_RES							0x80FF8000
#define CARD_BUSY_BIT							0x80000000
#define SDHC_BLK_LEN							SDHC_SECTOR_SIZE
#define RCA_SHIFT								16
#define DEFAULT_BUS_REQUEST_RETRY_COUNT			3
#define SD_DEFAULT_BUSY_REQUEST_RETRY_COUNT		10

#define MMC_SPEC_VER_1_0_TO_1_2                 0
#define MMC_SPEC_VER_1_4                        1
#define MMC_SPEC_VER_2_0_TO_2_2                 2
#define MMC_SPEC_VER_3_1_TO_3_3                 3
#define MMC_SPEC_VER_4_0                        4

#define SDHC_STATUS_CLK_RUN_MSK               0x100
#define SDHC_STATUS_END_CMD_RESP_MSK          0x2000
#define SDHC_STATUS_TIME_OUT_RESP_MSK         0x2
#define SDHC_STATUS_RESP_CRC_ERR_MSK          0x20
#define SDHC_STATUS_BUF_READ_RDY_MSK          0x80
#define SDHC_STATUS_BUF_WRITE_RDY_MSK         0x40
#define SDHC_STATUS_WRITE_OP_DONE_MSK         0x1000
#define SDHC_STATUS_WR_CRC_ERR_CODE_MSK       0x600
#define SDHC_STATUS_WRITE_CRC_ERR_MSK         0x4
#define SDHC_STATUS_READ_OP_DONE_MSK          0x800
#define SDHC_STATUS_TIME_OUT_READ             0x1
#define SDHC_STATUS_READ_CRC_ERR_MSK          0x8

// hardware specific context
typedef struct _SDH_HARDWARE_CONTEXT {
    BOOL                SendInitClocks;                 // flag to indicate that we need to send the init clock
    BOOL                IsMMC;							// indicates if the card is MMC or SD
    BOOL                DevicePresent;                  // device is present in the slot
	DWORD 				BusWidthSetting; 				// 1 bit mode or 4 bit mode
	DWORD 				Units_in_fifo ;					// number of unit in FIFO buffer
	DWORD 				Bytes_in_fifo;					// FIFO size 
	BOOL 				fAppCommandSent;          		// Flag if CMD55 sent  
	DWORD				dwClockRate;					// Current card clock rate
	ULONG 				ulReadTimeout;					// ReadTimeout
	UINT32 				dwVddSettingMask ; 					// Slot Vdd voltage
	UINT32				dwVoltageWindowMask ; 			// Slot voltage window mask
	UINT32				dwOptVoltageMask ;					// Slot optimum voltage 
	UINT32				dwPowerUpDelay ; 				// Slot power up delay
	UINT32				dwBlockLen;						// Block Length

    DWORD               dwNumBytesToTransfer;           // Number of bytes (remaining) to transfer
    DWORD               dwNumWordsToTransfer;           // Number of words (remaining) to transfer
    DWORD               dwMisalignedBytesToTransfer;    // last few bytes which are less than a word
    PUCHAR              pBuffer;                        // Pointer to user data buffer
	SD_BUS_REQUEST		sdRequest;
}SDH_HARDWARE_CONTEXT, *PSDH_HARDWARE_CONTEXT;

typedef struct SDCARD_CARD_REGISTERS {
    UCHAR   OCR[SD_OCR_REGISTER_SIZE];          // SD OCR
    UCHAR   IO_OCR[SD_IO_OCR_REGISTER_SIZE];    // IO OCR
    UCHAR   CID[SD_CID_REGISTER_SIZE];          // CID
    UCHAR   CSD[SD_CSD_REGISTER_SIZE];          // CSD
    UCHAR   SCR[SD_SCR_REGISTER_SIZE];          // SCR
} SDCARD_CARD_REGISTERS;

enum sdhc_status
{
    SDHC_STATUS_PASS = 0,
    SDHC_STATUS_FAILURE = 1
};

BOOL SDMMC_Init(void);
BOOL SDMMC_Deinit (void);
UINT32 SDMMC_get_cid (void);
UINT32 SDMMC_get_csd (void);
UINT32 SDMMC_set_blocklen (UINT32 BlockLen);
UINT32 SDMMC_set_data_transfer_mode (void);
UINT32 SDMMC_card_software_reset(void);
UINT32 SDMMC_card_send_appcmd (void);
UINT32 SDMMC_send_rca (BOOL isMMC);
void SDCard_command_config (PSD_BUS_REQUEST pReq,UCHAR CommandCode, DWORD argument,
                            SD_TRANSFER_CLASS transfer,SD_RESPONSE_TYPE respType);
UINT32 SDMMC_R1b_busy_wait (PSD_COMMAND_RESPONSE pResp);
BOOL SDHC_IsCardPresent ();
BOOL SDMMC_GetInfo(PFlashInfo pFlashInfo);
BOOL SDMMC_EraseBlock(BLOCK_ID blockID, UINT32 num_blocks);
DWORD SDMMC_GetCardCapacity (void);

void SDConfigPins (void);
BOOL SDInterface_Init (void);
void SetRate(DWORD dwRate);
void SetBlockLen (UINT32 blkLen, UINT32 nob);
UINT32 SDHCSendCmdWaitResp (PSD_BUS_REQUEST pReq);
UINT32 SDHCReadResponse (PSD_COMMAND_RESPONSE pResp);
BOOL SDMMC_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff,
					  PSectorInfo pSectorInfoBuff, DWORD dwNumSectors);
BOOL SDMMC_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff,
					   PSectorInfo pSectorInfoBuff, DWORD dwNumSectors);

UINT32 SDHCDataRead (UINT32* dest_ptr, UINT32 blk_len);
UINT32 SDHCDataWrite (UINT32* dest_ptr, UINT32 blk_len);

UINT32 SD_Init(void);
UINT32 SD_VoltageValidation (void);

UINT32 MMC_Init(void);

#ifdef __cplusplus
}
#endif

#endif

