[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/driver/storage/mc/inc/msdc_def.h b/mcu/driver/storage/mc/inc/msdc_def.h
new file mode 100644
index 0000000..cd51b11
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/msdc_def.h
Binary files differ
diff --git a/mcu/driver/storage/mc/inc/msdc_reg_adap.h b/mcu/driver/storage/mc/inc/msdc_reg_adap.h
new file mode 100644
index 0000000..c4f9d0b
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/msdc_reg_adap.h
@@ -0,0 +1,160 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * msdc_reg_adap.h
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * This file is intends for memory card common definitions.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef MSDC_REG_ADAP_H
+#define MSDC_REG_ADAP_H
+
+#include "drv_comm.h"
+
+//#define __DRV_MSDC_REG_DBG__
+
+#if !defined(DRV_MSDC_OFF)
+#ifdef __DRV_MSDC_REG_DBG__
+
+#define MSDC_WriteReg(addr,data) DRV_DBG_WriteReg(addr,data)
+#define MSDC_Reg(addr) DRV_DBG_Reg(addr)
+#define MSDC_WriteReg32(addr,data) DRV_DBG_WriteReg32(addr,data)
+#define MSDC_Reg32(addr) DRV_DBG_Reg32(addr)
+#define MSDC_WriteReg8(addr,data) DRV_DBG_WriteReg8(addr,data)
+#define MSDC_Reg8(addr) DRV_DBG_Reg8(addr)
+
+#define MSDC_ClearBits(addr,data) DRV_DBG_ClearBits(addr,data)
+#define MSDC_SetBits(addr,data) DRV_DBG_SetBits(addr,data)
+#define MSDC_ClearBits32(addr,data) DRV_DBG_ClearBits32(addr,data)
+#define MSDC_SetBits32(addr,data) DRV_DBG_SetBits32(addr,data)
+#define MSDC_ClearBits8(addr,data) DRV_DBG_ClearBits8(addr,data)
+#define MSDC_SetBits8(addr,data) DRV_DBG_SetBits8(addr,data)
+
+#define MSDC_SetData(addr,bitmask,value) DRV_DBG_SetData(addr,bitmask,value)
+#define MSDC_SetData32(addr,bitmask,value) DRV_DBG_SetData32(addr,bitmask,value)
+#define MSDC_SetData8(addr,bitmask,value) DRV_DBG_SetData8(addr,bitmask,value)
+
+#else
+
+#define MSDC_WriteReg(addr,data) DRV_WriteReg(addr,data)
+#define MSDC_Reg(addr) DRV_Reg(addr)
+#define MSDC_WriteReg32(addr,data) DRV_WriteReg32(addr,data)
+#define MSDC_WriteReg32_NPW(addr,data) DRV_WriteReg32_NPW(addr,data)
+#define MSDC_Reg32(addr) DRV_Reg32(addr)
+#define MSDC_WriteReg8(addr,data) DRV_WriteReg8(addr,data)
+#define MSDC_Reg8(addr) DRV_Reg8(addr)
+
+#define MSDC_ClearBits(addr,data) DRV_ClearBits(addr,data)
+#define MSDC_SetBits(addr,data) DRV_SetBits(addr,data)
+#define MSDC_ClearBits32(addr,data) DRV_ClearBits32(addr,data)
+#define MSDC_SetBits32(addr,data) DRV_SetBits32(addr,data)
+#define MSDC_ClearBits8(addr,data) DRV_ClearBits8(addr,data)
+#define MSDC_SetBits8(addr,data) DRV_SetBits8(addr,data)
+
+#define MSDC_SetData(addr,bitmask,value) DRV_SetData(addr,bitmask,value)
+#define MSDC_SetData32(addr,bitmask,value) DRV_SetData32(addr,bitmask,value)
+#define MSDC_SetData8(addr,bitmask,value) DRV_SetData8(addr,bitmask,value)
+
+#define MSDC_SET_FIELD_NPW(addr,bitmask,value) \
+ do { \
+ volatile kal_uint32 tv = MSDC_Reg32(addr); \
+ tv &= ~(bitmask); \
+ tv |= ((value) << (uffs(bitmask) - 1)); \
+ DRV_WriteReg32_NPW(addr,tv); \
+ } while(0)
+
+#define MSDC_SET_FIELD(addr,bitmask,value) \
+ do { \
+ volatile kal_uint32 tv = MSDC_Reg32(addr); \
+ tv &= ~(bitmask); \
+ tv |= ((value) << (uffs(bitmask) - 1)); \
+ MSDC_WriteReg32(addr,tv); \
+ } while(0)
+
+#define MSDC_GET_FIELD(addr,bitmask,value) \
+ do { \
+ volatile kal_uint32 tv = MSDC_Reg32(addr); \
+ value = ((tv & (bitmask)) >> (uffs(bitmask) - 1)); \
+ } while(0)
+
+
+#endif//__DRV_MSDC_REG_DBG__
+
+#else //!defined(DRV_MSDC_OFF)
+
+#define MSDC_WriteReg(addr,data)
+#define MSDC_Reg(addr) drv_dummy_return()
+#define MSDC_WriteReg32(addr,data)
+#define MSDC_Reg32(addr) drv_dummy_return()
+#define MSDC_WriteReg8(addr,data)
+#define MSDC_Reg8(addr) drv_dummy_return()
+
+#define MSDC_ClearBits(addr,data)
+#define MSDC_SetBits(addr,data)
+#define MSDC_ClearBits32(addr,data)
+#define MSDC_SetBits32(addr,data)
+#define MSDC_ClearBits8(addr,data)
+#define MSDC_SetBits8(addr,data)
+
+#define MSDC_SetData(addr,bitmask,value)
+#define MSDC_SetData32(addr,bitmask,value)
+#define MSDC_SetData8(addr,bitmask,value)
+
+#endif //!defined(DRV_MSDC_OFF)
+
+#endif /* MSDC_REG_ADAP_H */
+
diff --git a/mcu/driver/storage/mc/inc/sd_def.h b/mcu/driver/storage/mc/inc/sd_def.h
new file mode 100644
index 0000000..ccabb4e
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/sd_def.h
@@ -0,0 +1,1051 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * Sd_def.h
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * Header file of SD/MMC driver
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef SD_DEF_H
+#define SD_DEF_H
+
+//RHR ADD
+#include "kal_general_types.h"
+#include "drv_trc.h"
+//RHR REMOVE
+/*
+//MSBB remove #include "kal_non_specific_general_types.h"
+*/
+//RHR
+#include "drv_features.h"
+#include "dcl.h"
+#include "dcl_msdc.h"
+#include "msdc_api.h"
+/*--------------------------------*/
+/*SDC register address */
+/*--------------------------------*/
+
+/*sdmmc register*/
+#define SDC_CFG (MSDC_ADRS + 0x30)
+#define SDC_CMD (MSDC_ADRS + 0x34)
+#define SDC_ARG (MSDC_ADRS + 0x38)
+#define SDC_STS (MSDC_ADRS + 0x3c)
+#define SDC_RESP0 (MSDC_ADRS + 0x40)
+#define SDC_RESP1 (MSDC_ADRS + 0x44)
+#define SDC_RESP2 (MSDC_ADRS + 0x48)
+#define SDC_RESP3 (MSDC_ADRS + 0x4c)
+#define SDC_BLK_NUM (MSDC_ADRS + 0x50)
+#define SDC_CSTS (MSDC_ADRS + 0x58)
+#define SDC_CSTS_EN (MSDC_ADRS + 0x5c)
+#define SDC_DCRC_STS (MSDC_ADRS + 0x60)
+/*emmc register*/
+#define EMMC_CFG0 (MSDC_ADRS + 0x70)
+#define EMMC_CFG1 (MSDC_ADRS + 0x74)
+#define EMMC_STS (MSDC_ADRS + 0x78)
+#define EMMC_IOCON (MSDC_ADRS + 0x7c)
+/*auto command register*/
+#define SDC_ACMD_RESP (MSDC_ADRS + 0x80)
+#define SDC_ACMD19_TRG (MSDC_ADRS + 0x84)
+#define SDC_ACMD19_STS (MSDC_ADRS + 0x88)
+
+
+
+/*SDC_CFG mask*/
+#define SDC_CFG_SDIOINTWKUP (0x1 << 0) /*RW*/
+#define SDC_CFG_INSWKUP (0x1 << 1) /*RW*/
+#define SDC_CFG_BUSWIDTH (0x3 << 16) /*RW*/
+#define SDC_CFG_SDIO (0x1 << 19) /*RW*/
+#define SDC_CFG_SDIOIDE (0x1 << 20) /*RW*/
+#define SDC_CFG_INTATGAP (0x1 << 21) /*RW*/
+#define SDC_CFG_DTOC (0xffUL << 24) /*RW*/
+
+
+/*SDC_CMD mask*/
+#define SDC_CMD_OPC (0x3f <<0) /*RW*/
+#define SDC_CMD_BRK (0x1 << 6) /*RW*/
+#define SDC_CMD_RSPTYP (0x7 << 7) /*RW*/
+#define SDC_CMD_DTYP (0x3 <<11) /*RW*/
+#define SDC_CMD_RW (0x1 << 13) /*RW*/
+#define SDC_CMD_STOP (0x1 << 14) /*RW*/
+#define SDC_CMD_GOIRQ (0x1 << 15) /*RW*/
+#define SDC_CMD_BLKLEN (0xfff << 16) /*RW*/
+#define SDC_CMD_AUTOCMD (0x3 << 28) /*RW*/
+#define SDC_CMD_VOLSWTH (0x1 << 30) /*RW*/
+
+/*SDC_STS mask */
+#define SDC_STS_SDCBUSY (0x1 << 0) /*RW*/
+#define SDC_STS_CMDBUSY (0x1 << 1) /*RW*/
+#define SDC_STS_SWR_COMPL (0x1 << 31) /*RW*/
+
+
+/*SDC_DCRC_STS mask*/
+#define SDC_DCRC_STS_NEG (0xf << 8) /*RO*/
+#define SDC_DCRC_STS_POS (0xff << 0) /*RO*/
+
+/*EMMC_CFG0 mask*/
+#define EMMC_CFG0_BOOTSTART (0x1 << 0) /*W*/
+#define EMMC_CFG0_BOOTSTOP (0x1 << 1) /*W*/
+#define EMMC_CFG0_BOOTMODE (0x1 << 2) /*RW*/
+#define EMMC_CFG0_BOOTWDLY (0x7 << 12) /*RW*/
+#define EMMC_CFG0_BOOTACKDIS (0x1 << 3) /*RW*/
+#define EMMC_CFG0_BOOTSUPP (0x1 << 15) /*RW*/
+
+/*EMMC_CFG1 mask*/
+#define EMMC_CFG1_BOOTDATTMC (0xfffff << 0) /*RW*/
+#define EMMC_CFG1_BOOTACKTMC (0xfffUL << 20) /*RW*/
+
+/*EMMC_STS mask*/
+#define EMMC_STS_BOOTCRCERR (0x1 << 0) /*W1C*/
+#define EMMC_STS_BOOTACKERR (0x1 << 1) /*W1C*/
+#define EMMC_STS_BOOTDATTMO (0x1 << 2) /*W1C*/
+#define EMMC_STS_BOOTACKTMO (0x1 << 3) /*W1C*/
+#define EMMC_STS_BOOTUPSTATE (0x1 << 4) /*R*/
+#define EMMC_STS_BOOTACKRCV (0x1 << 5) /*W1C*/
+#define EMMC_STS_BOOTDATRCV (0x1 << 6) /*R*/
+
+
+/*EMMC_IOCON mask*/
+#define EMMC_IOCON_BOOTRST (0x1 << 0) /*RW*/
+
+
+/*SDC_ACMD19_TRG mask*/
+#define MSDC_ACMD19_TRG_TUNESEL (0xf << 0) /*RW*/
+
+#define SDC_NO_ARG 0
+
+
+#define SDC_OCR_DEFAULT 0x00FF8000
+#define SDC_OCR_QUERY 0x0
+#define TRY_OCR 20
+#define SDC_OCR_BUSY 0x80000000
+#define SDC_RCA_DEFAULT 0x0000
+#define ARG_RCA_MASK 0xffff0000
+#define SDC_RCA_MMC 1
+#define SDC_DSR_DEFAULT 0x0404
+#define SDC_NO_ARG 0
+#define SDC_MAX_BKLENGTH 2048
+#define SDC_MAX_LOCKBK 34
+#define SDC_CMD8_ARG 0x000001AA // the argument of the CMD8
+#define SD_ACMD41_HCS 0x40000000 // indicate host support high capacity card.
+#define SD_ACMD41_XPC 0x10000000
+#define SD_ACMD41_S18R 0x01000000 // indicate host support 1.8v
+#define SD_CMD6_RESP_LEN 64 // lenght of the CMD6 response
+#define SD_CMD6_QUERY_SWITCH 0x00FF0000 //cmd6 query the function
+#define SD_CMD6_SELECT_SWITCH 0x80FF0000 //cmd6 select the function
+#define SD_CMD6_QUERY_SUPPORT_FUNCTION 0x00FFFFFF //use to get the functions supported by the card
+#define SD_CMD6_QUERY_HIGH_SPEED 0x00FFFFF1 // argument of CMD6 to query the high speed interface
+#define SD_CMD6_SELECT_HIGH_SPEED 0x80FFFFF1 // argument of CMD6 to query the high speed interface
+#define SD_FUNC_HIGH_SPEED 0x1
+#define SD_CSD_VER_20 0x01
+
+#define SD_FLAG_MMC_MRSW_FAIL (0x01) // some special MMC card will fail at multi-read follow a single wirte
+#define SD_FLAG_HCS_SUPPORT (0x02) // support block access mode
+#define SD_FLAG_CMD6_SUPPORT (0x04) // support CMD6 (SD1.1 higher)
+#define SD_FLAG_HS_SUPPORT (0x08) // support high speed interface (SD1.1 higher)
+#define SD_FLAG_HS_ENABLED (0x10) // enable high speed interface (SD1.1 higher)
+#define SD_FLAG_SD_TYPE_CARD (0x20) // to indicate SD or MMC type card
+#define SD_FLAG_USE_USB_CLK (0x40) // to indicate use USB clock
+#define SD_FLAG_UHS_ENABLED (0x80) //enable UHS interface
+#define SD_FLAG_UHS_SUPPORT (0x100) //support UHS interface
+
+
+#define SD_FLAG_LIMITED_HIGH_SPEED_CARD (0x8000) // to indicate special high speed card that we can only run with 26M
+
+
+
+#define MSDC_SD_BLOCK_SIZE 128 // * 4byte
+#define SECTOR_SIZE 512
+
+#define MSDC_TUNE_UHS_SCLK (100000000)
+
+typedef kal_uint32 SDC_CMD_STATUS;
+// ERROR definition of SDC_CMD_STATUS
+#define NO_ERROR 0
+#define ERR_CMD_TIMEOUT 1
+#define ERR_APP_CMD_NOT_ACCEPT 2
+#define ERR_R3_OCR_BUSY 3
+#define ERR_RCA_FAIL 4
+#define ERR_INVALID_CARD 5
+#define ERR_INVALID_BKLENGTH 6 // over 2048 or not multiple of 4
+#define ERR_DAT_CRCERR 7
+#define ERR_RW_CMDERR 8
+#define ERR_CMD_RSPCRCERR 9
+#define ERR_DAT_TIMEOUT 10
+#define ERR_STATUS 11
+#define ERR_LOCK_UNLOCK_FAILED 12
+#define ERR_APPCMD_FAILED 13
+#define ERR_NOT_SUPPORT_4BITS 14
+#define ERR_NORESP 15
+#define ERR_WRITE_PROTECT 16
+#define ERR_DATA_NOT_READY 17
+#define ERR_CARD_NOT_PRESENT 18
+#define ERR_OCR_NOT_SUPPORT 19
+#define ERR_DAT_ERROR 20
+#define SDIO_4MI_NOT_SUPPORT 21
+#define ERR_MMC_BUS_HS_ERROR 22
+#define ERR_SendEXTCSD 23
+#define ERR_CMD8_INVALID 24
+#define ERR_SD_HS_FAIL 25 // SD change high speed interface fail
+#define ERR_NOT_FOUND 26
+#define ERR_ACB_FAIL 27
+#define ERR_ACB_TIMEOUT 28
+#define ERR_ACB_STA_ENABLE_FAIL 29
+#define ERR_ERRORS 30 // general errors
+#define ERR_INVALID_BLOCK 31
+#define ERR_MMC_SWITCH_ERROR 32
+#define ERR_CARD_BUSY_TIMEOUT 33
+#define ERR_HIGH_SPEED_BUSY 34
+#define ERR_HIGH_SPEED_TIMEOUT 35
+#define ERR_HIGH_SPEED_COMMON_ERROR 36
+#define ERR_HIGH_SPEED_NOT_SUPPORT 37
+#define ERR_HIGH_SPEED_CONSUMPTION 38
+#define ERR_ARGUMENT 39
+
+#define CARD_IS_LOCKED 60
+#define CHECK_DATA_CMD_LOW_FAIL 61
+#define ERR_SWITCH_BUSY 62
+#define ERR_SWITCH_TIMEOUT 63
+#define ERR_SPEED_MODE_UNSUPPORT 64
+#define ERR_DRIVER_TYPE_UNSUPPORT 65
+#define ERR_CURRENT_LIMIT_UNSUPPORT 66
+
+
+/* MMC bus commands */
+#define CMD0_GO_IDLE_STATE 0x00 /* Resets the MMC */
+#define CMD1_SEND_OP_COND 0x01 /* Activates the card's initialization process */
+#define CMD2_ALL_SEND_CID 0x02 /* Asks all cards in ready state to send their CID */
+#define CMD3_SET_RELATIVE_ADDR 0x03 /* Assigns relative address to the card in identification state */
+#define CMD4_SET_DSR 0x04 /* Sets drive stage register DSR */
+#define CMD7_SELECT_CARD 0x07
+#define CMD9_SEND_CSD 0x09 /* Asks the selected card to send its CSD */
+#define CMD10_SEND_CID 0x0A /* Asks the selected card to send its CID */
+#define CMD11_READ_DAT_UNTIL_STOP_MMC 0x0B
+#define CMD12_STOP_TRANSMISSION 0x0C /* Stop data transmission */
+#define CMD13_SEND_STATUS 0x0D /* Asks the selected card to send its status register */
+#define CMD15_GO_INACTIVE_STATE 0x0F
+#define CMD16_SET_BLOCKLEN 0x10 /* Selects a block length for all following block commands */
+#define CMD17_READ_SINGLE_BLOCK 0x11 /* Reads a block of the size selected by the SET_BLOCKLEN command */
+#define CMD18_READ_MULTIPLE_BLOCK 0x12
+#define CMD20_WRITE_DAT_UNTIL_STOP_MMC 0x14
+#define CMD24_WRITE_SINGLE_BLOCK 0x18 /* Writes a block of the size selected by SET_BLOCKLEN command */
+#define CMD25_WRITE_MULTIPLE_BLOCK 0x19 /* Writes multiple block until CMD 12 */
+#define CMD26_PROGRAM_CID 0x1A
+#define CMD27_PROGRAM_CSD 0x1B /* Programming of the programmable bits of the CSD */
+#define CMD28_SET_WRITE_PROT 0x1C /* If the card has write protection features, sets the write protection bit */
+#define CMD29_CLR_WRITE_PROT 0x1D /* If with write protection features, clears the write protection bit */
+#define CMD30_SEND_WRITE_PROT 0x1E /* If with write protection features, asks the card to send status of write protection bit */
+#define CMD32_TAG_SECTOR_START 0x20 /* Sets the address of the first sector */
+#define CMD33_TAG_SECTOR_END 0x21 /* Sets the address of the last sectore */
+#define CMD34_UNTAG_SECTOR 0x22 /* Removes one previously selected sector */
+#define CMD35_TAG_ERASE_GROUP_START 0x23 /* Sets the address of the first erase group */
+#define CMD36_TAG_ERASE_GROUP_END 0x24 /* Sets the address of the last erase group */
+#define CMD37_UNTAG_ERASE_GROUP 0x25 /* Removes on previously selected erase group */
+#define CMD38_ERASE 0x26 /* Erases all previously selected sectors */
+#define CMD39_FAST_IO_MMC 0x27
+#define CMD40_GO_IRQ_STATE 0x28
+#define CMD42_LOCK_UNLOCK 0x2A /* Used to set/reset the password or lock/unlock the card */
+#define CMD55_APP 0x37 /* Indicates to the card the next cmd is an application specific command */
+#define CMD56_GEN 0x38 /* Used either to transfer a data block or to get a data block form the card for general purpse */
+
+// commnad value for MSDC controller SDC_CMD
+// not include the SDC_CMD LEN[27:16] !!
+#define SDC_CMD_CMD0 0x0000 /* response_none*/
+#define SDC_CMD_CMD1 0x0181 /* response_r3 */
+#define SDC_CMD_CMD2 0x0102 /* response_r2 */
+#define SDC_CMD_CMD3 0x0083 /* response_r6 */
+#define SDC_CMD_CMD3_MMC 0x0083 /* response_r1*/
+#define SDC_CMD_CMD4 0x0004 /* response_none*/
+#define SDC_CMD_CMD5 0x0185 /* response_r3*/
+#define SDC_CMD_CMD5_MMC 0x0385 /* response_r1b*/
+#define SDC_CMD_CMD6 0x0886 /* response_r1 +single_block + read*/
+#define SDC_CMD_CMD6_MMC 0x0386 /* response_r1b*/
+#define SDC_CMD_CMD7 0x0387 /* response_r1b*/
+#define SDC_CMD_CMD8 0x0088 /* response_r7*/
+#define SDC_CMD_CMD8_MMC40 0x0888 /* response_r1+single_blokc+read*/
+#define SDC_CMD_CMD9 0x0109 /* response_r2*/
+#define SDC_CMD_CMD10 0x010a /* response_r2 the response time delay is not NID(5 cycles)*/
+#define SDC_CMD_CMD11 0x4000008b /* response_r1+ switch vlot*/
+#define SDC_CMD_CMD11_MMC 0x188b /* response_r1*/
+#define SDC_CMD_CMD12 0x438c /* response_r1b+stop command*/
+#define SDC_CMD_CMD13 0x008d /* response_r1*/
+#define SDC_CMD_CMD15 0x000f /* response_none*/
+#define SDC_CMD_CMD16 0x0090 /* response_r1*/
+#define SDC_CMD_CMD17 0x0891 /* response_r1+single_block+read*/
+#define SDC_CMD_CMD18 0x1092 /* response_r1+mutli_block+read*/
+#define SDC_CMD_CMD19 0x0893 /* response_r1+single_block_read*/
+#define SDC_CMD_CMD19_MMC 0x0093 /* response_r1*/
+#define SDC_CMD_CMD20_MMC 0x3894 /* response_r1+stream_write*/
+#define SDC_CMD_CMD20 0x0394 /* response_r1b*/
+#define SDC_CMD_CMD23 0x0097 /* response_r1*/
+#define SDC_CMD_CMD24 0x2898 /* response_r1+single_block+write*/
+#define SDC_CMD_CMD25 0x3099 /* response_r1+mutli_block+write*/
+#define SDC_CMD_CMD26 0x009a /* response_r1*/
+#define SDC_CMD_CMD26_MMC 0x289a /* response_r1+single_block+write*/
+#define SDC_CMD_CMD27 0x289b /* response_r1+single_block_write*/
+#define SDC_CMD_CMD28 0x039c /* response_r1b*/
+#define SDC_CMD_CMD29 0x039d /* response_r1b*/
+#define SDC_CMD_CMD30 0x089e /* response_r1+single_block_read*/
+#define SDC_CMD_CMD31_MMC 0x039f /* response_r1b*/
+#define SDC_CMD_CMD32 0x00a0 /* response_r1*/
+#define SDC_CMD_CMD33 0x00a1 /* response_r1*/
+#define SDC_CMD_CMD35_MMC 0x00a3 /* response_r1*/
+#define SDC_CMD_CMD36_MMC 0x00a4 /* response_r1*/
+#define SDC_CMD_CMD38 0x03a6 /* response_r1b*/
+#define SDC_CMD_CMD39_MMC 0x0227 /* response_r4*/
+#define SDC_CMD_CMD40_MMC 0x80a8 /* response_r5*/
+#define SDC_CMD_CMD42 0x28aa /* response_r1+single_block+write*/
+#define SDC_CMD_CMD55 0x00b7 /* response_r1*/
+#define SDC_CMD_CMD56 0x08b8 /* response_r1+single_block*/
+#define SDC_CMD_ACMD6 0x0086 /* response_r1*/
+#define SDC_CMD_ACMD13 0x088d /* response_r1+single_block+read*/
+#define SDC_CMD_ACMD22 0x0896 /* response_r1+single_block+read*/
+#define SDC_CMD_ACMD23 0x0097 /* response_r1*/
+#define SDC_CMD_ACMD41 0x01a9 /* response_r3*/
+#define SDC_CMD_ACMD42 0x00aa /* response_r1*/
+#define SDC_CMD_ACMD51 0x08b3 /* response_r1+single_block+read*/
+
+#define SDC_CMD_CMD6_SD11 0x0886 // SWITCH
+
+/* SDIO command*/
+#define SDC_CMD_CMD52 0x00b4 /* response_r5 STOp field will be set while used to Stop data transfer*/
+#define SDC_CMD_CMD53 0x00b5 /* response_r5 the RWand DTYPE will be changed according request*/
+
+
+
+//masks for command error response(32) of SDC_CSTA
+#define SDC_OUT_OF_RANGE 0x80000000
+#define SDC_ADDRESS_ERROR 0x40000000
+#define SDC_BLOCK_LEN_ERROR 0X20000000
+#define SDC_ERASE_SEQ_ERROR 0X10000000
+#define SDC_ERASE_PARAM 0X08000000
+#define SDC_WP_VIOLATION 0X04000000
+#define SDC_CARD_IS_LOCKED 0x02000000
+#define SDC_LOCK_UNLOCK_FAILED 0X01000000
+#define SDC_COM_CRC_ERROR 0X00800000
+#define SDC_ILLEGAL_COMMAND 0X00400000
+#define SDC_CARD_ECC_FAILED 0X00200000
+#define SDC_CC_ERROR 0X00100000
+#define SDC_ERROR 0X00080000
+#define SDC_UNDERRUN 0X00040000
+#define SDC_OVERRUN 0X00020000
+#define SDC_CIDCSD_OVERWRITE 0X00010000
+#define MMC_SWITCH_ERROR 0x00000080
+#define SDC_AKE_SEQ_ERROR 0X00000008
+
+#define SDC_CSTA_MASK 0xffff0000
+
+//masks for card status contained in R1
+#define R1_AKE_SEQ_ERROR_3 0x00000004
+#define R1_APP_CMD_5 0x00000020
+#define R1_READY_FOR_DATA_8 0x00000100
+#define R1_CURRENT_STATE_9_12 0x00001e00
+#define R1_ERASE_RESET_13 0x00002000
+#define R1_CARD_ECC_DISABLE_14 0x00004000
+#define R1_WP_ERASE_SKIP_15 0x00008000
+#define R1_CID_CSD_OVERWRITE_16 0x00010000
+#define R1_OVERRUN_17 0x00020000
+#define R1_UNDERRUN_18 0x00040000
+#define R1_ERROR_19 0x00080000
+#define R1_CC_ERROR_20 0x00100000
+#define R1_CARD_ECC_FAILED_21 0x00200000
+#define R1_ILLEGAL_COMMAND_22 0x00400000
+#define R1_COM_CRC_ERROR_23 0x00800000
+#define R1_LOCK_UNLOCK_FAILED_24 0x01000000
+#define R1_CARD_IS_LOCKED_25 0x02000000
+#define R1_WP_VIOLATION_26 0x04000000
+#define R1_ERASE_PARAM_27 0x08000000
+#define R1_ERASE_SEQ_ERROR_28 0x10000000
+#define R1_BLOCK_LEN_ERROR_29 0x20000000
+#define R1_ADDRESS_ERROR_30 0x40000000
+#define R1_OUT_OF_RANGE_31 0x80000000
+#define R1_CUR_STATE 0x00001E00
+
+#define R1_CURRENT_STATE(a) (kal_uint32)(((a) & R1_CUR_STATE) >> 9)
+
+
+#define FUN1_SDR12_DS 0x1
+#define FUN1_SDR25_HS 0x2
+#define FUN1_SDR50 0x4
+#define FUN1_SDR104 0x8
+#define FUN1_DDR50 0x10
+#define FUN2_DEFAULT 0x1
+#define FUN2_FOR_EC 0x2
+#define FUN2_OTP 0x8
+#define FUN2_ASSD 0x10
+#define FUN3_TYPE_A 0x1
+#define FUN3_TYPE_B 0x2
+#define FUN3_TYPE_C 0x4
+#define FUN3_TYPE_D 0x8
+#define FUN4_200MA 0x1
+#define FUN4_400MA 0x2
+#define FUN4_600MA 0x4
+#define FUN4_800MA 0x8
+
+#define FUN1_SET_SDR12_DS (0x0)
+#define FUN1_SET_SDR25_HS (0x1)
+#define FUN1_SET_SDR50 (0x2)
+#define FUN1_SET_SDR104 (0x3)
+#define FUN1_SET_DDR50 (0x4)
+#define FUN2_SET_DEFAULT (0x0)
+#define FUN2_SET_FOR_EC (0x1)
+#define FUN2_SET_OTP (0x3)
+#define FUN2_SET_ASSD (0x4)
+#define FUN3_SET_TYPE_A (0x0)
+#define FUN3_SET_TYPE_B (0x1)
+#define FUN3_SET_TYPE_C (0x2)
+#define FUN3_SET_TYPE_D (0x3)
+#define FUN4_SET_200MA (0x0)
+#define FUN4_SET_400MA (0x1)
+#define FUN4_SET_600MA (0x2)
+#define FUN4_SET_800MA (0x3)
+
+/*Card Command Classes(CCC)*/
+#define CCC_BASIC (1<<0) //cmd0,1,2,3,4,7,9,10,12,13,15 and for SPI cdm58,59
+#define CCC_STREAM_READ (1<<1) //cmd11
+#define CCC_BLOCK_READ (1<<2) //cmd16,17,18
+#define CCC_STREAM_WRITE (1<<3) //CMD20
+#define CCC_BLOCK_WRITE (1<<4) //cmd16,24,25,26,27
+#define CCC_ERASE (1<<5) //cmd32,33,34,35,36,37,38,39
+#define CCC_WRITE_PROT (1<<6) //cmd28,29,30
+#define CCC_LOCK_CARD (1<<7) //cmd16,cmd42
+#define CCC_APP_SPEC (1<<8) //cmd55,56,57,ACMD
+#define CCC_IO_MODE (1<<9) //cmd5,39,40,52,53
+#define CCC_SWITCH (1<<10) //cmd6,34,35,36,37,50
+
+#define SCR_SPEC_VER_0 0 //system specification 1.0-1.01
+#define SCR_SEC_VER_1 1 //system specification 1.10
+#define SCR_SEC_VER_2 2 //system specification 2.00-3.0x
+
+typedef enum {
+ IDLE_STA,
+ READY_STA,
+ IDENT_STA,
+ STBY_STA,
+ TRAN_STA,
+ DATA_STA,
+ RCV_STA,
+ PRG_STA,
+ DIS_STA,
+ INV_STA
+}T_SDC_STATE;
+
+typedef enum{
+ SD_CMD8_RESP_NORESP, // before SD2.0 version or MMC
+ SD_CMD8_RESP_INVALID, // SD 2.0 or higher compliant but voltage condition is not allow
+ SD_CMD8_RESP_VALID // SD 2.0 or higher compliant
+}SD_CMD8_RESP;
+
+typedef enum{
+ eMMC_boot_partition1 = 1,
+ eMMC_boot_partition2,
+ eMMC_RPMB,
+ eMMC_GP_partition1,
+ eMMC_GP_partition2,
+ eMMC_GP_partition3,
+ eMMC_GP_partition4,
+ eMMC_user_Area
+} eMMC_partitions;
+
+
+
+
+
+typedef struct{
+ kal_bool isEmmcV44;
+ kal_bool supportPartition;
+ kal_bool supportEnhancedPart;
+ kal_uint32 bootPartitionSize; //size of boot partition, the uint is 512-byte
+ kal_uint32 gp1PartitionSize; //size of GP1 partition, the uint is 512-byte
+}t_emmc_info;
+
+#define MSDC_SD_BLOCK_SIZE 128 // x4 bytes
+#define EXT_CSD_BUS_WIDTH_INDEX 183
+#define EXT_CSD_HIGH_SPPED_INDEX 185
+#define EXT_CSD_POW_CLASS_INDEX 187
+#define EXT_CSD_PARTITION_CONFIG_INDEX 179
+#define EXT_CSD_BOOT_BUS_WIDTH_INDEX 177
+#define EXT_CSD_ERASE_GRP_DEF 175
+#define EXT_CSD_RT_FUNCTION_INDEX 162
+#define EXT_CSD_GP_SIZE_MULT_GP0_INDEX 143
+#define EXT_CSD_ENH_SIZE_MULT_INDEX 140
+#define EXT_CSD_ENABLE_HIGH_SPEED 1
+#define MMC_HIGH_DESITY_CHECK_BIT (0x40000000)
+#define MMC_HIGH_DESITY_CHECK_MSK (0x60000000)
+
+
+
+#define EMMC_MASK_PARTITION_SETTING 0x1
+#define EMMC_MASK_PARTITION_CONFIG 0x7
+
+
+typedef struct {
+#ifndef MSDC_MMC441_SUPPORT
+ kal_uint8 rev1[183];
+#else
+ kal_uint8 mmc44_rev0[136]; /*[135:0]*/
+ kal_uint32 enh_start_addr; /*[139:136]*/
+ kal_uint8 enh_size_mult[3]; /*[142:140]*/
+ kal_uint8 gp_size_mult[12]; /*[154:143]*/
+ kal_uint8 partition_settig; /*[155]*/
+ kal_uint8 partition_attr; /*[156]*/
+ kal_uint8 max_enh_size_mult[3]; /*[159:157]*/
+ kal_uint8 partition_support; /*[160]*/
+ kal_uint8 mmc44_rev1; /*[161]*/
+ kal_uint8 rst_function; /*[162]*/
+ kal_uint8 mmc44_rev2[5]; /*[167:163]*/
+ kal_uint8 rpmb_size_mul; /*[168]*/
+ kal_uint8 fw_config; /*[169]*/
+ kal_uint8 mmc44_rev3; /*[170]*/
+ kal_uint8 user_wp; /*[171]*/
+ kal_uint8 mmc44_rev4; /*[172]*/
+ kal_uint8 boot_wp; /*[173]*/
+ kal_uint8 mmc44_rev5; /*[174]*/
+ kal_uint8 erase_grp_def; /*[175]*/
+ kal_uint8 mmc44_rev6; /*[176]*/
+ kal_uint8 boot_bus_width; /*[177]*/
+ kal_uint8 boot_config_prot; /*[178]*/
+ kal_uint8 partition_config; /*[179]*/
+ kal_uint8 mmc44_rev7; /*[180]*/
+ kal_uint8 erased_mem_cont; /*[181]*/
+ kal_uint8 mmc44_rev8; /*[182]*/
+#endif
+ kal_uint8 bus_width;
+ kal_uint8 rev2;
+ kal_uint8 high_speed;
+ kal_uint8 rev3;
+ kal_uint8 power_class;
+ kal_uint8 rev4;
+ kal_uint8 cmd_set_rev;
+ kal_uint8 rev5;
+ kal_uint8 cmd_set;
+ kal_uint8 ext_csd_rev;
+ kal_uint8 rev7;
+ kal_uint8 ext_csd_ver;
+ kal_uint8 rev8;
+ kal_uint8 card_type;
+ kal_uint8 rev9;
+ kal_uint8 out_of_interrupt_time;
+ kal_uint8 partition_switch_time;
+ kal_uint8 pwr_52_195;
+ kal_uint8 pwr_26_195;
+ kal_uint8 pwr_52_360;
+ kal_uint8 pwr_26_360;
+ kal_uint8 rev10;
+ kal_uint8 min_perf_r_4_26;
+ kal_uint8 min_perf_w_4_26;
+ kal_uint8 min_perf_r_8_26_4_52;
+ kal_uint8 min_perf_w_8_26_4_52;
+ kal_uint8 min_perf_r_8_52;
+ kal_uint8 min_perf_w_8_52;
+ kal_uint8 resv11;
+ kal_uint32 sec_count; /*newly defined in MMC42*/
+#ifndef MSDC_MMC441_SUPPORT
+ kal_uint8 rev12[288];
+#else
+ kal_uint8 mmc44_rev9[5]; /*[220:216]*/
+ kal_uint8 hc_wp_grp_size; /*221*/
+ kal_uint8 rel_wr_sec_c; /*222*/
+ kal_uint8 erase_timeout_mult; /*223*/
+ kal_uint8 hc_erase_grp_size; /*224*/
+ kal_uint8 acc_size; /*225*/
+ kal_uint8 boot_size_mul; /*[226]*/
+ kal_uint8 mmc44_rev10; /*[227]*/
+ kal_uint8 boot_info; /*[228]*/
+ kal_uint8 mmc44_rev11[275]; /*[503:229]*/
+#endif
+ kal_uint8 s_cmd_set;
+ kal_uint8 rev13[7];
+}T_EXT_CSD_MMC40;
+
+typedef enum{
+ SD_SPEC_101,
+ SD_SPEC_110,
+ SD_SPEC_200,
+ SD_SPEC_30X
+}SD_SPEC;
+typedef enum{
+ CSD_VER_1_0 = 0,
+ CSD_VER_1_1 = 0,
+ CSD_VER_2_0 = 1,
+ CSD_VER_EXT
+ }CSD_VER_ENUM;
+
+/* Card Specific Data(CSD) register structure */
+typedef struct {
+ kal_uint8 tacc; /* read access time-1 */
+ kal_uint8 nsac; /* read access time-2 */
+ kal_uint8 tran_speed; /* max. data transfer rate */
+ kal_uint16 ccc; /* card command classes */
+ kal_uint32 w_blk_len; /* actual write block length in bytes */
+ kal_uint32 r_blk_len; /* actual read block length in bytes */
+ kal_uint32 max_w_blk_len; /* max write data block length */
+ kal_uint32 max_r_blk_len; /* max read data block length */
+ kal_uint8 w_blk_misali; /* write block misalighment */
+ kal_uint8 r_blk_misali; /* read block misalighment */
+ kal_uint8 w_blk_part; /* partial blocks for write allowed */
+ kal_uint8 r_blk_part; /* partial blocks for write allowed */
+ kal_uint32 erase_sec_size_mmc; /* erase sector size */
+ kal_uint32 erase_grp_size_mmc; /* erase group size */
+ kal_uint32 wp_grp_size_mmc; /* write protect group size */
+ kal_uint8 erase_blk_en_sd;
+ kal_uint32 erase_sec_size_sd;
+ kal_uint32 wp_prg_size_sd;
+ kal_uint8 wp_grp_enable; /* write protect group enable */
+ kal_uint64 capacity; /* capacity in bytes */
+ kal_uint16 cmd_class; /* card command classes */
+ kal_uint8 temp_wp; /* temporary write protection */
+ kal_uint8 perm_wp; /* permanent write protection */
+ kal_uint8 dsr_imp;
+ CSD_VER_ENUM csd_ver; /* the version of CSD structure */
+ kal_uint8 spec_ver; /* defne the MMC system spec. */
+ T_EXT_CSD_MMC40 *ext_csd; /* pointer to EXT_CSD */
+} T_CSD;
+
+typedef struct {
+ kal_uint8 mid;
+ kal_uint16 oid;
+ kal_uint8 pnm[6];
+ kal_uint8 prv;
+ kal_uint32 psn;
+ kal_uint16 year;
+ kal_uint8 month;
+}T_CID;
+
+typedef struct {
+ kal_uint8 dat_after_erase;
+ kal_uint8 security;
+ kal_uint8 bus_width;
+ kal_uint8 sd_spec3;
+ kal_uint8 cmd_support;
+ SD_SPEC spec_ver;
+}T_SCR;
+
+typedef struct {
+ unsigned char dat_bus_width:2,
+ secured_mode:1,
+ rsv1:5;
+ unsigned char rsv2:2,
+ rsv3:6;
+ unsigned short sd_card_type;
+ unsigned int size_of_prot_area;
+ unsigned char speed_class;
+ unsigned char perf_move;
+ unsigned char au_size:4,
+ rsv4:4;
+ unsigned short erase_size;
+ unsigned char erase_timeout:6,
+ erase_offset:2;
+ unsigned char uhs_speed_grade:4,
+ uhs_au_size:4;
+ unsigned char rsv5[49];
+}T_SD_STATUS;
+
+typedef struct {
+ kal_uint32 mSDC_ocr; // store the OCR
+ kal_uint32 mBKLength; // store the block length
+ kal_uint32 mBKNum; // store the block numbers
+ kal_uint32 flags; // for some special case handling
+ T_CSD mCSD; // card specific data
+ T_CID mCID; // card idendtification
+ T_SCR mSCR; // only for SD
+ T_SD_STATUS mSDSts;
+ kal_uint16 mRCA; // store relative card address
+ T_SDC_STATE mState; // indicate the current state
+ kal_bool mInactive; // indicate whether card in inactive state
+ kal_uint8 bus_width; // indicate 4-bits data line enable
+ kal_bool mWPEnabled; // indicate write protection is enabled(SD)
+ kal_bool mIsLocked; // indicate whether the card is locked by switch
+ kal_bool mCD_DAT3; // indicate the pull-up resistor of CD_DAT3 pin
+ kal_bool mIsBlkAddr;
+ SD_CMD8_RESP mCMD8Resp; // receive response after CMD8 (SD2.0 or higher)
+ MSDC_LOCK_TAG mSDdrv_lock; // lock for sd_drv adaption layer
+#if defined(MSDC_MMC441_SUPPORT)
+ t_emmc_info emmc_info;
+#endif
+ kal_uint32 sd_r;
+ kal_uint32 sd_w;
+ T_SWITCH_SUPPROT_FUNCTIONS card_support;
+ T_SWITCH_SUPPROT_FUNCTIONS function_set;
+}T_SDC_HANDLE;
+
+typedef struct{
+ kal_uint32 max_current : 16;
+ kal_uint32 group6_info : 16;
+ kal_uint32 group5_info : 16;
+ kal_uint32 group4_info : 16;
+ kal_uint32 group3_info : 16;
+ kal_uint32 group2_info : 16;
+ kal_uint32 group1_info : 16;
+ kal_uint32 group6_result: 4;
+ kal_uint32 group5_result: 4;
+ kal_uint32 group4_result: 4;
+ kal_uint32 group3_result: 4;
+ kal_uint32 group2_result: 4;
+ kal_uint32 group1_result: 4;
+ kal_uint32 ver : 8;
+ kal_uint32 group6_busy : 16;
+ kal_uint32 group5_busy : 16;
+ kal_uint32 group4_busy : 16;
+ kal_uint32 group3_busy : 16;
+ kal_uint32 group2_busy : 16;
+ kal_uint32 group1_busy : 16;
+ kal_uint8 rev[34];
+}T_SWITCH_STATUS;
+
+
+
+typedef enum{
+ SET_PWD,
+ CLR_PWD,
+ LOCK_CARD,
+ UNLOCK_CARD,
+ ERASE
+}SD_LOCK_OP;
+
+typedef enum{
+ BIT_1_MMC40,
+ BIT_4_MMC40,
+ BIT_8_MMC40
+}BUS_WIDHT_MMC40;
+typedef enum{
+ HS_26M = 1,
+ HS_52M = 2
+}EXT_CSD_CARD_TYPE_MMC40;
+
+
+
+
+
+// bit masks
+#define BIT_MASK_1 0x01
+#define BIT_MASK_2 0x03
+#define BIT_MASK_3 0x07
+#define BIT_MASK_4 0x0F
+#define BIT_MASK_5 0x1F
+#define BIT_MASK_6 0x3F
+#define BIT_MASK_7 0x7F
+#define BIT_MASK_8 0xFF
+#define GET_BIT(byte, bit_pos, bit_mask) (((byte) & ((bit_mask)<<(bit_pos)))>> (bit_pos))
+
+#ifndef __MSDC_BASIC_LOAD__
+#define SD_TRACE2(a,b,c,d) MD_TRC_##b(c, d)
+#else
+#define SD_TRACE2(a,b,c,d) dbg_print("SD error in file %d, line %d\n\r", c,d)
+#endif
+#define SD_INITIALIZE_STATUS_CHECK() \
+{\
+ if(NO_ERROR != status)\
+ {\
+ MSDC_ERR("[MSDC][%s %d]%x\r\n",__FUNCTION__,__LINE__,status);\
+ SD_TRACE2(TRACE_GROUP_5, MSDC_GENERAL_FAIL, MSDC_DRV_TRC_FILE_SD, __LINE__);\
+ goto err;\
+ }\
+}
+#define MSDC_ERROR 1
+#define MSDC_OK 0
+
+#define SD_IS_SDC_BUSY() (!!(MSDC_Reg32(SDC_STS)&SDC_STS_SDCBUSY))
+#define SD_IS_CMD_BUSY() (!!(MSDC_Reg32(SDC_STS)&SDC_STS_CMDBUSY))
+#define SD_IS_R1B_BUSY() (!(MSDC_Reg32(MSDC_PS)&(1<<16)))
+
+#define MSDC_BD_MAX 128
+extern msdc_gpd_t MSDC_gpd[SD_NUM];
+extern msdc_gpd_t MSDC_gpd_end[SD_NUM];
+
+extern msdc_bd_t MSDC_bd[SD_NUM][MSDC_BD_MAX];
+extern T_SDC_HANDLE * gSD;
+extern T_SDC_HANDLE gSD_blk[SD_NUM];
+SDC_CMD_STATUS SD_SendCmd(kal_uint32 cmd,kal_uint32 arg,kal_uint32 timeout_ms);
+void SD_Cmd8(void);
+
+SDC_CMD_STATUS SD_Reset(void);
+SDC_CMD_STATUS SD_Cmd55(kal_uint16 rca);
+SDC_CMD_STATUS SD_Cmd1_MMC(void);
+SDC_CMD_STATUS SD_Acmd41_SD(void);
+SDC_CMD_STATUS SD_GetCID(kal_uint32 Cid[4]);
+SDC_CMD_STATUS SD_ValidateRCA(kal_uint16* pRca);
+SDC_CMD_STATUS SD_SetDSR(void);
+SDC_CMD_STATUS SD_SelectCard(kal_uint16 rca);
+SDC_CMD_STATUS SD_GetCSD(kal_uint16 rca, kal_uint32 Csd[4]);
+SDC_CMD_STATUS SD_GetStatus(kal_uint16 rca, kal_uint32* resp);
+SDC_CMD_STATUS SD_SetBlength(kal_uint32 BKLength);
+SDC_CMD_STATUS SD_ReadSingleBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer);
+SDC_CMD_STATUS SD_ReadMultiBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer, kal_uint32 num);
+SDC_CMD_STATUS SD_WriteSingleBlock(kal_uint32 address, kal_uint32* txbuffer);
+SDC_CMD_STATUS SD_WriteMultiBlock(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num);
+SDC_CMD_STATUS SD_SetBusWidth(SD_BITWIDTH width);
+SDC_CMD_STATUS SD_ReadSCR(kal_uint32* scr);
+SDC_CMD_STATUS SD_ReadSDStatus(kal_uint32* sd_status);
+SDC_CMD_STATUS SD_SendEXTCSD_MMC40(kal_uint32* rxbuffer);
+SDC_CMD_STATUS SD_Initialize(void);
+SDC_CMD_STATUS SD_FlushSectors(kal_uint32 startSector, kal_uint32 sectorNum);
+SDC_CMD_STATUS SD_SetPreEraseBlk(kal_uint32 num);
+SDC_CMD_STATUS SD_CheckStatus(void);
+SDC_CMD_STATUS SD_Switch_MMC40(kal_uint8 access, kal_uint8 index, kal_uint8 value, kal_uint8 set);
+SDC_CMD_STATUS SD_SelectHighSpeed_SD11(void);
+SDC_CMD_STATUS SD_SwitchSpeedMode(void);
+
+SDC_CMD_STATUS SD_GpdWriteMultiBlock(kal_uint32 address ,kal_uint32 num_blk,void *gpd_data);
+SDC_CMD_STATUS SD_GpdReadMultiBlock(kal_uint32 address ,kal_uint32 num_blk,void *gpd_data );
+
+kal_bool SD_QMU_Init(void);
+
+void SD_closeFastFormat(void);
+void SD_startFastFormat(void);
+
+extern SDC_CMD_STATUS SD_StopTrans(void);
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*following 2 API is used to declare the beginning and ending of high level format*/
+void SD_startFastFormat(void);
+void SD_closeFastFormat(void);
+
+int MountDevice(void * DriveData, int DeviceNumber, int DeviceType, kal_uint32 Flags);
+int ReadSectors(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, void * Buffer);
+int WriteSectors(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, void * Buffer);
+
+
+
+
+
+#endif // end of SD_DEF_H
+
+
diff --git a/mcu/driver/storage/mc/inc/sdio_def.h b/mcu/driver/storage/mc/inc/sdio_def.h
new file mode 100644
index 0000000..71e7d08
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/sdio_def.h
@@ -0,0 +1,76 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * Sd_def.h
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * Header file of SDIO driver
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef SDIO_DEF_H
+#define SDIO_DEF_H
+/*HW part*/
+#define SDIO_CFG (MSDC_ADRS+0x54)
+#define SDIO_STA (MSDC_ADRS+0x58)
+//#define SDC_CFG_SDIO 0x00080000
+#define SDiO_CFG_INTEN 0x1 // enable interrupt
+#define SDiO_CFG_INTSEL 0x2 // interrupt signal selection 0: use DAT[1], 1: use DAT[5]
+#define SDiO_CFG_DSBSEL 0x4 // data block start bit selection
+
+#if defined(DRV_MSDC_MT6238_SERIES)
+#define SDIO_CFG2 (MSDC_ADRS2+0x54)
+#define SDIO_STA2 (MSDC_ADRS2+0x58)
+#endif
+
+#define SDIO_R4_CARD_READY 0x80
+#define IO_ARG_RW_FLAG 0x80000000
+#define IO_ARG_RAW_FLAG 0x08000000
+#define MSDC_WORK_OCR 0x8000
+
+#define R5_COM_CRC_ERROR (1<<7)
+#define R5_ILLEGAL_COMMAND (1<<6)
+#define R5_IO_CURRENT_STATE (3<<4)
+#define R5_ERROR (1<<3)
+#define R5_RFU (1<<2)
+#define R5_FUNCTION_NUMBER (1<<1)
+#define R5_OUT_OF_RANGE (1<<0)
+#define R5_ERROR_CHECK (R5_COM_CRC_ERROR|R5_ILLEGAL_COMMAND|R5_ERROR|R5_FUNCTION_NUMBER|R5_OUT_OF_RANGE)
+
+#define SDIO_STATUS_CHECK \
+{\
+ if(NO_ERROR != status)\
+ {\
+ SD_TRACE2(TRACE_GROUP_5, MSDC_GENERAL_FAIL, MSDC_DRV_TRC_FILE_SD, __LINE__);\
+ goto err;\
+ }\
+}
+
+#endif // end of SD_DEF_H
diff --git a/mcu/driver/storage/mc/inc/sdio_test.h b/mcu/driver/storage/mc/inc/sdio_test.h
new file mode 100644
index 0000000..d4d5639
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/sdio_test.h
@@ -0,0 +1,1238 @@
+
+#ifndef __PRECOMP_H
+#define __PRECOMP_H
+
+//#include "equates.h"
+//#include "i2128reg.h"
+/*I2128 register*/
+
+/************************************************************************
+* C O M P I L E R F L A G S
+*************************************************************************
+*/
+
+/************************************************************************
+* C O N S T A N T S
+*************************************************************************
+*/
+#define MCR_MEM_MAPPED_LENGTH 0x800 /* MCR memory-mapped length */
+
+/* IPN2128 MAC configuration register (MCR) offset definition */
+/* system control */
+#define MCR_SCR 0x0000 //
+#define MCR_QSR0 0x0008 //== 2128's MCR_MAISR
+#define MCR_MAISR MCR_QSR0
+/* non-used for SDIO */
+#define MCR_QSR1 0x000C
+#define MCR_TXQIER 0x0014
+/*--------------*/
+#define MCR_MRBS 0x0018 //
+
+/* used to R/W EEPROM */
+#define MCR_ECSR 0x0040 //
+#define MCR_ERWCR 0x0044 //
+#define MCR_EADR 0x0048 //
+
+/*queue*/
+#define MCR_QCR 0x0100 //== 2128's MCR_DPCR
+#define MCR_DPCR MCR_QCR
+#define MCR_ISAR 0x0104 //0x0004
+#define MCR_IER 0x0108 //0x0010
+
+/* used to query SDIO bus status */
+#define MCR_SDRDR 0x0110
+#define MCR_SDCR 0x0114
+#define MCR_SDSR 0x0118
+#define MCR_GPCR 0x0120 //GPIO
+#define MCR_PSCTL 0x012c
+
+/*----------*/
+#define MCR_DRNGR 0x0188
+#define MCR_AIFSR 0x018C
+//#define MCR_TQCWR 0x0190
+#define MCR_AC0CWR 0x0194
+/*
+#define MCR_AC1CWR 0x0198
+#define MCR_AC2CWR 0x019C
+#define MCR_AC3CWR 0x01A0
+*/
+/*security engine*/
+#define MCR_SKACR 0x0200
+#define MCR_SKADR0 0x0204
+#define MCR_SKADR1 0x0208
+#define MCR_SKADR2 0x020C
+#define MCR_SKADR3 0x0210
+#define MCR_SKADR4 0x0214
+#define MCR_SKADR5 0x0218
+#define MCR_SCPR0 0x021C
+#define MCR_SCPR1 0x0220 //non-used in both 2128 and 2128
+
+#ifdef SUPPORT_TKIP_ON_THE_FLY
+/* MIC key */
+#define MCR_MICKEY0 0x0224
+#define MCR_MICKEY1 0x0228
+#endif /* TKIP_ON_THE_FLY */
+
+/*phyical layer control interface*/
+#define MCR_PCICR 0x0240
+#define MCR_PCCR 0x0244
+#define MCR_PBAR 0x0248
+#define MCR_PPORCR0 0x0280
+#define MCR_PPORCR1 0x0284
+#define MCR_PPDRCR0 0x0288
+#define MCR_PPDRCR1 0x028C
+#define MCR_PPDRCR2 0x0290
+#define MCR_PPMCR 0x0294
+#define MCR_PSCR 0x02A0
+#define MCR_PSPR 0x02A4
+#define MCR_LCR 0X02A8
+/*transmitter control*/
+#define MCR_ACWLR 0x0300
+#define MCR_MPTCR 0x0304
+#define MCR_NPTCR 0x0308
+#define MCR_NTTCR 0x030C
+#define MCR_TXOPGBNTCR 0x0310
+#define MCR_NDTCR 0x0314
+#define MCR_NCSTCR 0x0318
+
+/*receiver control*/
+#define MCR_DRCR 0x0360
+#define MCR_RFECR 0x0364
+#define MCR_RFFCR 0x0368
+#define MCR_RPCR 0x036C
+#define MCR_CACR 0x0374
+#define MCR_RFBCR 0x0380
+#define MCR_OMAR0 0x03A0
+#define MCR_OMAR1 0x03A4
+#define MCR_CBR0 0x03A8
+#define MCR_CBR1 0x03AC
+#define MCR_AMAR0 0x03B0
+#define MCR_AMAR1 0x03B4
+#define MCR_AMAR2 0x03B8
+#define MCR_AMAR3 0x03BC
+#define MCR_AMAR4 0x03C0
+#define MCR_AMAR5 0x03C4
+#define MCR_AMAR6 0x03C8
+#define MCR_AMAR7 0x03CC
+#define MCR_AMAR8 0x03D0
+/*MAC protocol timing control*/
+#define MCR_MPDR 0x0400
+#define MCR_TNTDR 0x0404
+#define MCR_STDR 0x0408
+#define MCR_EPDDR 0x040C
+#define MCR_CRFCR0 0x0410
+//#define MCR_CRFCR1 0x0414--
+#define MCR_DTR 0x0418
+#define MCR_BCWR 0x041C
+#define MCR_RFTPCR 0x0420
+#define MCR_LTTR0 0x0440
+#define MCR_LTTR1 0x0444
+#define MCR_TTAR0 0x0448
+#define MCR_TTAR1 0x044C
+#define MCR_TTAR2 0x0450
+/*NVA control*/
+#define MCR_LNR 0x0470
+#define MCR_NRTR 0x0474
+#define MCR_NSUR 0x0478
+/*beacon generation*/
+#define MCR_BGCR0 0x0480
+#define MCR_BGCR1 0x0484
+#define MCR_SWBCCR 0x0488
+#define MCR_SWBCDR 0x048C
+#define MCR_ARRCR 0x0490
+#define MCR_AFRCR 0x0494
+#define MCR_ATFCR 0x0498
+#define MCR_ATBCR 0x049C
+
+/*miscellaneous and debug port*/
+/*
+#define MCR_GPIOCR 0x0050
+*/
+#define MCR_PRBCR 0x0080
+#define MCR_PRBSR 0x0084//--
+/*
+#define MCR_PFWDR 0x0088
+*/
+#define MCR_PRBDR 0x008C
+/*
+#define MCR_BPSR 0x0090
+*/
+#define MCR_CTPR1 0x0094 //--
+#define MCR_MPTR 0x03FC
+/*
+#define MCR_CTPR2 0x0098
+#define MCR_LNUIR0 0x0500
+#define MCR_LNUIR1 0x0504
+#define MCR_LNUIR2 0x0508
+*/
+/* Debug Register 0 (PRBDR) bit definitions */
+#define PRBDR_RN_FREEZE BIT(7)
+/* ----- System Control ----- */
+/* System Control Register (SCR) bit definitions */
+#define SCR_PCI_CLKRUN_ENABLE BIT(31)
+#define SCR_ASSERT_PCI_CLKRUN BIT(30)
+#define SCR_RADIO_PD_ACTIVE_EDGE BIT(26)
+#define SCR_RADIO_PD_REQ BIT(25)
+#define SCR_GPIO_PD_N BIT(24)
+/*
+#define SCR_SEC_CLK20M_ENABLE BIT(20)
+#define SCR_MAC_CLK20M_ENABLE BIT(19)
+#define SCR_MAC_CLK40M_ENABLE BIT(18)
+#define SCR_MAC_CLK33M_ENABLE BIT(17)
+#define SCR_PLL_ENABLE BIT(16)
+*/
+#define SCR_SEC_CLK_ENABLE BIT(20)
+#define SCR_MAC_CLK_ENABLE BIT(19)
+#define SCR_FIFO_CLK_ENABLE BIT(18)
+#define SCR_HST_CLK_ENABLE BIT(17)
+#define SCR_CLK_ALL_EN BITS(17,20)
+#define SCR_PAU_ENABLE BIT(7)
+#define SCR_MAC_REGRST BIT(3)
+#define SCR_MAC_RST BIT(2)
+#define SCR_BB_SIORST BIT(1)
+#define SCR_BB_MRST BIT(0)
+#define SCR_RST_ALL BITS(0,3)
+
+/* SDIO Read Done/Error Register (SDRDER) bit definitions */
+#define SDRDR_BLOCK_BYTE_COUNT BITS(6,16)
+#define SDRDR_BLOCK_BYTE_MODE BIT(5)
+#define SDRDR_CRC_ERROR BIT(4)
+#define SDRDR_MIC_RESULT_READ_DONE BIT(3)
+#define SDRDR_RX_DATA_READ_DONE BIT(2)
+#define SDRDR_RX_STATUS_READ_DONE BIT(1)
+#define SDRDR_TX_STATUS_READ_DONE BIT(0)
+
+/* SDIO Status Register (SDSR) bit definitions */
+#define SDSR_TX_STATUS_UNDER_RUN BIT(7)
+#define SDSR_RX_STATUS_UNDER_RUN BIT(6)
+#define SDSR_RX_DATA_UNDER_RUN BIT(5)
+#define SDSR_MIC_RESULT_UNDER_RUN BIT(4)
+#define SDSR_TX_DATA_LEN_OUT_OF_RANGE BIT(3)
+#define SDSR_TXD_BUF_EMPTY_STATUS BIT(2)
+#define SDSR_TXD_BUF_OVERFLOW BIT(1)
+
+/* IRQ Status and Acknowledge Register (ISAR) bit definitions */
+#define ISAR_EXTERNAL_INT BIT(22)
+#define ISAR_MAC_ABNORMAL_INT BIT(21) //
+#define ISAR_PHY_CCA_INDICATE_BUSY BIT(20)
+#define ISAR_RFIFO_OVERFLOW_INT BIT(19)
+#define ISAR_PRE_TBTT_INT BIT(18)
+#define ISAR_TBTT_INT BIT(17)
+#define ISAR_ATIM_W_TIMEUP_INT BIT(16)
+#define ISAR_SDIO_ABNORMAL_INT BIT(9) //
+#define ISAR_TX_BUFFER_EMPTY_INT BIT(8)
+#define ISAR_BEACON_TX_RX_OK_INT BIT(7)
+#define ISAR_SECURITY_Q_EMPTY_INT BIT(6)
+#define ISAR_AC0_Q_EMPTYINT BIT(5)
+#define ISAR_MIC_OK_INT BIT(4)
+#define ISAR_RX2_OK_INT BIT(3)
+#define ISAR_RX1_OK_INT BIT(2)
+#define ISAR_TX2_OK_INT BIT(1)
+#define ISAR_TX1_OK_INT BIT(0)
+
+#define ISAR_AC0_TX_DONE (ISAR_TX1_OK_INT | ISAR_TX2_OK_INT)
+#define ISAR_AC0_EVENT (ISAR_AC0_TX_DONE | ISAR_AC0_Q_EMPTYINT)
+#define ISAR_TX_Q_EVENT (ISAR_AC0_EVENT | ISAR_TX_BUFFER_EMPTY_INT)
+#define ISAR_RX_Q_EVENT BITS(2,3)
+#define ISAR_RX_DATA_Q_DONE_INT ISAR_RX_Q_EVENT
+
+/* Queue Status Register 0 (QSR0) bit definitions */
+#define QSR0_ABNORMAL_Q_NO BITS(12,15)
+#define QSR0_RFD_CHECK_SUM_ERR BIT(10)
+#define QSR0_TBD_CHECK_SUM_ERR BIT(9)
+#define QSR0_TFD_CHECK_SUM_ERR BIT(8)
+#define SDIOSR_RX_DATA_PORT_UNDER_RUN BIT(5)
+#define QSR0_RX_DATA_Q_OPERATING BIT(4)
+#define QSR0_SEC_ENGINE_OP_TX_Q_EMPTY BIT(3)
+#define QSR0_SEC_ENGINE_OP_TX_DONE BIT(2)
+#define QSR0_SEC_ENGINE_OP_TX_EVENT BITS(2,3)
+#define QSR0_SEC_ENGINE_OP_RX_Q_EMPTY BIT(1)
+#define QSR0_SEC_ENGINE_OP_RX_DONE BIT(0)
+#define QSR0_SEC_ENGINE_OP_RX_EVENT BITS(0,1)
+
+/* Queue Status Register 1 (QSR1) bit definitions */
+#define QSR1_AC0_QUEUE_EMPTY BIT(7)
+#define QSR1_AC0_TX_DONE BIT(6)
+#define QSR1_AC0_EVENT BITS(6.7)
+#define QSR1_AC0_OPERATING BIT(24)
+
+/* IRQ Enable Register (IER) bit definitions */
+#define IER_GLOBAL_ENABLE BIT(31)
+#define IER_EXTERNAL_INT BIT(22)
+#define IER_MAC_ABNORMAL_INT BIT(21) //
+#define IER_PHY_CCA_INDICATE_BUSY BIT(20)
+#define IER_RFIFO_OVERFLOW_INT BIT(19)
+#define IER_PRE_TBTT_INT BIT(18)
+#define IER_TBTT_INT BIT(17)
+#define IER_ATIM_W_TIMEUP_INT BIT(16)
+#define IER_SDIO_ABNORMAL_INT BIT(9) //
+#define IER_TX_BUFFER_EMPTY_INT BIT(8)
+#define IER_BEACON_TX_RX_OK_INT BIT(7)
+#define IER_SECURITY_Q_EMPTY_INT BIT(6)
+#define IER_AC0_Q_EMPTYINT BIT(5)
+#define IER_MIC_OK_INT BIT(4)
+#define IER_RX2_OK_INT BIT(3)
+#define IER_RX1_OK_INT BIT(2)
+#define IER_TX2_OK_INT BIT(1)
+#define IER_TX1_OK_INT BIT(0)
+
+#define IER_ENABLE_MAJOR BITS(0,8)
+//#define IER_ENABLE_ALL (IER_ENABLE_MAJOR | BIT(9) | BITS(16,22))
+#define IER_ENABLE_ALL (IER_ENABLE_MAJOR | BIT(9) | BITS(16,21))
+
+/* Tx Queue Interrupt Enable Register (TXQIER) bit definitions */
+#define TXQIER_TS3_QUEUE_EMPTY_EN BIT(21)
+#define TXQIER_TS3_TX_DONE_EN BIT(20)
+#define TXQIER_TS3_EVENT_EN BITS(20,21)
+#define TXQIER_TS2_QUEUE_EMPTY_EN BIT(19)
+#define TXQIER_TS2_TX_DONE_EN BIT(18)
+#define TXQIER_TS2_EVENT_EN BITS(18,19)
+#define TXQIER_TS1_QUEUE_EMPTY_EN BIT(17)
+#define TXQIER_TS1_TX_DONE_EN BIT(16)
+#define TXQIER_TS1_EVENT_EN BITS(16,17)
+#define TXQIER_TS0_QUEUE_EMPTY_EN BIT(15)
+#define TXQIER_TS0_TX_DONE_EN BIT(14)
+#define TXQIER_TS0_EVENT_EN BITS(14,15)
+#define TXQIER_AC3_QUEUE_EMPTY_EN BIT(13)
+#define TXQIER_AC3_TX_DONE_EN BIT(12)
+#define TXQIER_AC3_EVENT_EN BITS(12,13)
+#define TXQIER_AC2_QUEUE_EMPTY_EN BIT(11)
+#define TXQIER_AC2_TX_DONE_EN BIT(10)
+#define TXQIER_AC2_EVENT_EN BITS(10,11)
+#define TXQIER_AC1_QUEUE_EMPTY_EN BIT(9)
+#define TXQIER_AC1_TX_DONE_EN BIT(8)
+#define TXQIER_AC1_EVENT_EN BITS(8,9)
+#define TXQIER_AC0_QUEUE_EMPTY_EN BIT(7)
+#define TXQIER_AC0_TX_DONE_EN BIT(6)
+#define TXQIER_AC0_EVENT_EN BITS(6,7)
+#define TXQIER_ALL_ACQ_EVENT_EN BITS(6,13)
+#define TXQIER_TQ1_TIMEOUT_EN BIT(5)
+#define TXQIER_TQ1_QUEUE_EMPTY_EN BIT(4)
+#define TXQIER_TQ1_TX_DONE_EN BIT(3)
+#define TXQIER_TQ1_EVENT_EN BITS(3,5)
+#define TXQIER_TQ0_TIMEOUT_EN BIT(2)
+#define TXQIER_TQ0_QUEUE_EMPTY_EN BIT(1)
+#define TXQIER_TQ0_TX_DONE_EN BIT(0)
+#define TXQIER_TQ0_EVENT_EN BITS(0,2)
+#define TXQIER_ALL_TXQ_EVENT_EN BITS(0,5)
+
+/* Maximum Receive Buffer Size Register (MRBS) bit definitions */
+#define MRBSR_MAX_RECV_BUFFER_SIZE BITS(0,15)
+
+/* EEPROM Control and Status Register (ECSR) bit definitions */
+#define ECSR_EE_TYPE_NOT_PRESENT 0 /* EEPROM not present */
+#define ECSR_EE_CSERR BIT(3) /* EEPROM checksum error */
+#define ECSR_EE_RDY BIT(2) /* EEPROM access complete */
+#define ECSR_EE_RECALL BIT(1) /* recall operation from EEPROM */
+#define ECSR_EE_SERIAL BIT(0) /* EEPROM serial access mode enable */
+
+/* EEPROM Read/Write Control Register (ERWCR) bit definitions */
+#define ERWCR_EECS BIT(7) /* EEPROM Chip Select */
+#define ERWCR_EESK BIT(6) /* EEPROM Clock */
+#define ERWCR_EEDI BIT(5) /* EEPROM Data Input */
+#define ERWCR_EEDO BIT(4) /* EEPROM Data Output */
+#define ERWCR_EE_READ BIT(1) /* EEPROM read access */
+#define ERWCR_EE_WRITE BIT(0) /* EEPROM write access */
+
+/* EEPROM Address and Data Register (EADR) bit definitions */
+#define EADR_EE_ADDR BITS(16,23) /* EEPROM address */
+#define EADR_EE_DATA BITS(0,15) /* EEPROM data */
+
+
+/* ----- Queue ----- */
+/* Queue Command Register (QCR) bit definitions */
+#define QCR_RX_DATA_Q_STOP BIT(25)
+#define QCR_RX_DATA_Q_START BIT(24)
+#define QCR_SEC_ENGINE_OP_TX_STOP BIT(23)
+#define QCR_SEC_ENGINE_OP_TX_START BIT(22)
+#define QCR_SEC_ENGINE_OP_RX_STOP BIT(21)
+#define QCR_SEC_ENGINE_OP_RX_START BIT(20)
+#define QCR_TS3_STOP BIT(19)
+#define QCR_TS3_START BIT(18)
+#define QCR_TS2_STOP BIT(17)
+#define QCR_TS2_START BIT(16)
+#define QCR_TS1_STOP BIT(15)
+#define QCR_TS1_START BIT(14)
+#define QCR_TS0_STOP BIT(13)
+#define QCR_TS0_START BIT(12)
+#define QCR_AC3_STOP BIT(11)
+#define QCR_AC3_START BIT(10)
+#define QCR_AC2_STOP BIT(9)
+#define QCR_AC2_START BIT(8)
+#define QCR_AC1_STOP BIT(7)
+#define QCR_AC1_START BIT(6)
+#define QCR_AC0_STOP BIT(5)
+#define QCR_AC0_START BIT(4)
+#define QCR_TQ1_STOP BIT(3)
+#define QCR_TQ1_START BIT(2)
+#define QCR_TQ0_STOP BIT(1)
+#define QCR_TQ0_START BIT(0)
+
+/* Queue Resume Command Register (QRCR) bit definitions */
+
+#define QRCR_RXQ_RESUME BIT(12)
+#define QRCR_SEC_ENGINE_OP_TX_RESUME BIT(11)
+#define QRCR_SEC_ENGINE_OP_RX_RESUME BIT(10)
+#define QRCR_TS3_RESUME BIT(9)
+#define QRCR_TS2_RESUME BIT(8)
+#define QRCR_TS1_RESUME BIT(7)
+#define QRCR_TS0_RESUME BIT(6)
+#define QRCR_AC3_RESUME BIT(5)
+#define QRCR_AC2_RESUME BIT(4)
+#define QRCR_AC1_RESUME BIT(3)
+#define QRCR_AC0_RESUME BIT(2)
+#define QRCR_TQ1_RESUME BIT(1)
+#define QRCR_TQ0_RESUME BIT(0)
+
+/* TS Token Control Register (TSTCR) bit definitions */
+#define TSTCR_TS3_TIMER_ENABLE BIT(19)
+#define TSTCR_TS2_TIMER_ENABLE BIT(18)
+#define TSTCR_TS1_TIMER_ENABLE BIT(17)
+#define TSTCR_TS0_TIMER_ENABLE BIT(16)
+#define TSTCR_TOKEN_P_RENEW BIT(8)
+#define TSTCR_TOKEN_P_3 BITS(6,7)
+#define TSTCR_TOKEN_P_2 BITS(4,5)
+#define TSTCR_TOKEN_P_1 BITS(2,3)
+#define TSTCR_TOKEN_P_0 BITS(0,1)
+
+/* TS TX Limit Register (TSTXLR) bit definitions */
+#define TSTXLR_TS3_TX_LIMIT BITS(24,31)
+#define TSTXLR_TS2_TX_LIMIT BITS(16,23)
+#define TSTXLR_TS1_TX_LIMIT BITS(8,15)
+#define TSTXLR_TS0_TX_LIMIT BITS(0,7)
+
+/* Arbitration Inter Frame Spacing Register (AIFSR) bit definitions */
+#define AIFSR_TQ_RN_ADD_1_EN BIT(24)
+#define AIFSR_AC3_RN_ADD_1_EN BIT(23)
+#define AIFSR_AC2_RN_ADD_1_EN BIT(22)
+#define AIFSR_AC1_RN_ADD_1_EN BIT(21)
+#define AIFSR_AC0_RN_ADD_1_EN BIT(20)
+#define AIFSR_AIFS_TQ BITS(16,19)
+#define AIFSR_AIFS_3 BITS(12,15)
+#define AIFSR_AIFS_2 BITS(8,11)
+#define AIFSR_AIFS_1 BITS(4,7)
+#define AIFSR_AIFS_0 BITS(0,3)
+
+/* TQs Contention Window Register (TQCWR) bit definitions */
+#define TQCWR_TQ_CW_MAX BITS(16,31)
+#define TQCWR_TQ_CW_MIN BITS(0,7)
+
+/* AC0 Contention Window Register (AC0CWR) bit definitions */
+#define AC0CWR_AC0_CW_MAX BITS(16,31)
+#define AC0CWR_AC0_CW_MIN BITS(0,7)
+
+/* AC1 Contention Window Register (AC1CWR) bit definitions */
+#define AC1CWR_AC1_CW_MAX BITS(16,31)
+#define AC1CWR_AC1_CW_MIN BITS(0,7)
+
+/* AC2 Contention Window Register (AC2CWR) bit definitions */
+#define AC2CWR_AC2_CW_MAX BITS(16,31)
+#define AC2CWR_AC2_CW_MIN BITS(0,7)
+
+/* AC3 Contention Window Register (AC3CWR) bit definitions */
+#define AC3CWR_AC3_CW_MAX BITS(16,31)
+#define AC3CWR_AC3_CW_MIN BITS(0,7)
+
+
+/* ----- Security Engine ----- */
+/* Security Key Access Control Register (SKACR, offset 0x0200) */
+#define SKACR_ACCESS_START BIT(31)
+#define SKACR_READ_WRITE BIT(30)
+
+#ifdef SUPPORT_TKIP_ON_THE_FLY
+#define SKACR_MICKEY_ENABLE BIT(16)
+#endif /* TKIP_ON_THE_FLY */
+
+#define SKACR_TABLE_SIZE BITS(8,15)
+#define SKACR_KEY_INDEX BITS(0,7)
+
+/* Security Key Access Data Register 0 (SKADR0, offset 0x0204) */
+#define SKADR0_KEY_ID BITS(30,31)
+#define SKADR0_CHECK_ALL BITS(27,29)
+#define SKADR0_CHECK_A2 BIT(29)
+#define SKADR0_CHECK_A1 BIT(28)
+#define SKADR0_CHECK_KEY_ID BIT(27)
+#define SKADR0_CIPHER_SUITE BITS(24,26)
+#define SKADR0_KEY_MAPPING_ADDR BITS(0,23)
+
+/* Security Key Access Data Register 1 (SKADR0, offset 0x0208) */
+#define SKADR1_KEY_MAPPING_ADDR BITS(0,23)
+
+/* Security Key Access Data Register 2 (SKADR0, offset 0x020C) */
+#define SKADR2_KEY_VALUE BITS(0,31)
+
+/* Security Key Access Data Register 3 (SKADR0, offset 0x0210) */
+#define SKADR3_KEY_VALUE_8_31 BITS(8,31)
+#define SKADR3_KEY_VALUE_0_7 BITS(0,7)
+
+/* Security Key Access Data Register 4 (SKADR0, offset 0x0214) */
+#define SKADR4_KEY_VALUE BITS(0,31)
+
+/* Security Key Access Data Register 5 (SKADR0, offset 0x0218) */
+#define SKADR5_KEY_VALUE_8_31 BITS(8,31)
+#define SKADR5_KEY_VALUE_0_7 BITS(0,7)
+
+/* Security Control Parameter Register 0 (SCPR0, offset 0x021C) */
+#define SCPR0_FRAME_CONTROL_MASK BITS(16,31)
+#define SCPR0_SEQUENCE_CONTROL_MASK BITS(0,15)
+
+/* Security Control Parameter Register 1 (SCPR1, offset 0x0220) */
+#define SCPR1_TKIP_IV_ENDIAN BIT(31)
+#define SCPR1_TKIP_EIV_ENDIAN BIT(30)
+#define SCPR1_QOS_CONTROL_MASK BITS(0,15)
+
+/* ----- Physical Layer Control Interface ----- */
+/* PHY Control Interface Configuration Register (PCICR) bit definitions */
+#define PCICR_CHIP_ID_VERSION BITS(12,31) /* chip ID and version */
+#define PCICR_RF_SW_CTRL BIT(4) /* RF software control */
+#define PCICR_RF_CTRL_MODE BITS(0,2) /* RF control mode */
+
+/* PAU Control Configuration register (PCCR) */
+#define PCCR_BCIMODE BIT(0)
+
+/* PHY BCI Access Register (PBAR) bit definitions */
+#define PBAR_PHY_BCI_ACCESS_START BIT(25) /* PHY BCI access command/status */
+#define PBAR_PHY_BCI_RW_CTRL BIT(24) /* PHY BCI read/write control */
+#define PBAR_PHY_BCI_INDEX BITS(16,23) /* PHY BCI access CR register index */
+#define PBDR_PHY_BCI_WR_DATA BITS(8,15) /* PHY BCI write data */
+#define PBDR_PHY_BCI_RD_DATA BITS(0,7) /* PHY BCI read data */
+
+/* PHY Power Management Control Register (PPMCR) bit definitions */
+#define PPMCR_GPIO_CAL BIT(29) /* GPIO for RF power control */
+#define PPMCR_GPIO_RF_SHDN BIT(28) /* GPIO for RF power control */
+#define PPMCR_GPIO_PA2_EN BIT(22) /* GPIO for RF 2.4G PA enable */
+#define PPMCR_GPIO_PA5_EN BIT(21) /* GPIO for RF 5G PA enable */
+#define PPMCR_GPIO_RF_TX BIT(20) /* GPIO for RF Tx control */
+#define PPMCR_GPIO_RF_RX BIT(19) /* GPIO for RF Rx control */
+#define PPMCR_GPIO_TR_SW BIT(18) /* GPIO for BB TX */
+#define PPMCR_BB_TX_PE BIT(17) /* GPIO for RF Tx/Rx control */
+#define PPMCR_BB_RX_PE BIT(16) /* GPIO for RF Tx/Rx control */
+
+/* PHY Synthesizer Programming Register (PSPR) bit definitions */
+#define PSPR_SYNTH_PROG_START BIT(31) /* synthesizer programming command/status */
+#define PSPR_RW_CTL BIT(30) /* synthesizer RW control */
+#define PSPR_SYNTH_DATA BITS(0,23) /* synthesizer programming data */
+
+/* LED Configuration Register (LCR) bit definitions */
+#define LCR_LED_GPIO_OUTPUT BIT(19) /* LED GPIO Output control */
+#define LCR_LED_POLARITY BIT(18) /* LEDOn polarity */
+#define LCR_LED_MODE BITS(16,17) /* LED mode */
+#define LCR_LED_POLARITY_POSITIVE 0
+#define LCR_LED_POLARITY_NEGATIVE BIT(18)
+#define LCR_LED_MODE BITS(16,17) /* LED mode */
+#define LCR_LED_MODE_GPIO 0
+#define LCR_LED_MODE_TX BIT(16)
+#define LCR_LED_MODE_RX BIT(17)
+#define LCR_LED_MODE_TX_RX BITS(16,17)
+#define LCR_LED_ON_CNT BITS(8,15) /* LED On count */
+#define LCR_LED_OFF_CNT BITS(0,7) /* LED Off count */
+
+/* ----- Transmitter Control ----- */
+/* ATIM/CFP Window Length Register (ACWLR) bit definitions */
+#define ACWLR_CFP_MAX_DURATION BITS(16,31) /* CFP max duration */
+#define ACWLR_ATIM_WINDOW BITS(0,15) /* ATIM window */
+
+/* MAC Protocol Timing Control Register (MPTCR) bit definitions */
+#define MPTCR_OPERATION_MODE BITS(30,31) /* operation mode */
+#define MPTCR_OPERATION_MODE_ESS_STA 0 /* Infrastructure STA */
+#define MPTCR_OPERATION_MODE_IBSS BIT(30) /* ad hoc */
+#define MPTCR_OPERATION_MODE_ESS_AP BIT(31) /* Infrastructure AP */
+#define MPTCR_EN_COMP_NEXT_PRE_TBTT_TIME BIT(29)
+#define MPTCR_TBTT_ENABLE BIT(27) /* enable TBTT comparator */
+#define MPTCR_DTIM_ENABLE BIT(26) /* enable DTIM comparator */
+#define MPTCR_CFP_START_ENABLE BIT(25) /* enable CFPStart comparator */
+#define MPTCR_TXOP_GB_ENABLE BIT(24) /* enable TXOP Guard Band event comparator */
+#define MPTCR_EN_COMP_NEXT_TBTT_TIME BIT(23)
+#define MPTCR_EN_COMP_TXOP_GB_NEXT_TIME BIT(22)
+#define MPTCR_EN_COMP_NEXT_DTIM_TIME BIT(21)
+#define MPTCR_EN_COMP_NEXT_CFP_START_TIME BIT(20)
+#define MPTCR_EN_COMP_TS3_TIMER_NEXT_TIME BIT(19)
+#define MPTCR_EN_COMP_TS2_TIMER_NEXT_TIME BIT(18)
+#define MPTCR_EN_COMP_TS1_TIMER_NEXT_TIME BIT(17)
+#define MPTCR_EN_COMP_TS0_TIMER_NEXT_TIME BIT(16)
+#define MPTCR_PRE_TBTT_GEN_PERIOD BITS(0,15) /* pre-TBTT generation period */
+
+/* Next Pre-TBTT Time Control Register (NPTCR) bit definitions */
+#define NPTCR_NEXT_PRE_TBTT_TIME BITS(0,25) /* next pre-TBTT time */
+
+/* Next TBTT Time Control Register (NTTCR) bit definitions */
+#define NTTCR_TBTT_GEN_PERIOD BITS(16,31) /* TBTT generation period */
+#define NTTCR_NEXT_TBTT_TIME BITS(0,15) /* next TBTT time */
+
+/* TXOP Guard Band Next Time Control Register (TXOPGBNTCR) bit definitions */
+#define TXOPGBNTCR_TXOP_GB_NEXT_TIME BITS(0,18) /* next TXOP Guard Band time */
+
+/* Next DTIM Time Control Register (NDTCR) bit definitions */
+#define NDTCR_DTIM_GEN_PERIOD BITS(16,31) /* DTIM generation period */
+#define NDTCR_NEXT_DTIM_TIME BITS(0,15) /* next DTIM time */
+
+/* Next CFP Start Time Control Register (NCSTCR) bit definitions */
+#define NCSTCR_CFP_START_GEN_PERIOD BITS(16,31) /* CFPStart generation period */
+#define NCSTCR_NEXT_CFP_START_TIME BITS(0,15) /* next CFPStart time */
+
+/* AC TXOP Limit Register 0 (ACTXOPR0) bit definitions */
+#define ACTXOPR0_AC1_LIMIT BITS(16,31) /* TXOP limit of AC1 */
+#define ACTXOPR0_AC0_LIMIT BITS(0,15) /* TXOP limit of AC0 */
+
+/* AC TXOP Limit Register 1 (ACTXOPR1) bit definitions */
+#define ACTXOPR1_AC3_LIMIT BITS(16,31) /* TXOP limit of AC3 */
+#define ACTXOPR1_AC2_LIMIT BITS(0,15) /* TXOP limit of AC2 */
+
+/* TS Timer Generation Period Control Register (TSTGPCR) bit definitions */
+#define TSTGPCR_TS3_TIMER_GEN_PERIOD BITS(24,31) /* TS3 timer generation period */
+#define TSTGPCR_TS2_TIMER_GEN_PERIOD BITS(16,23) /* TS2 timer generation period */
+#define TSTGPCR_TS1_TIMER_GEN_PERIOD BITS(8,15) /* TS1 timer generation period */
+#define TSTGPCR_TS0_TIMER_GEN_PERIOD BITS(0,7) /* TS0 timer generation period */
+
+/* TS Timer Next Time Control Register 0 (TSTNTCR0) bit definitions */
+#define TSTNTCR0_TS1_TIMER_NEXT_TIME BITS(16,31) /* TS1 timer next time */
+#define TSTNTCR0_TS0_TIMER_NEXT_TIME BITS(0,15) /* TS0 timer next time */
+
+/* TS Timer Next Time Control Register 1 (TSTNTCR1) bit definitions */
+#define TSTNTCR1_TS3_TIMER_NEXT_TIME BITS(16,31) /* TS3 timer next time */
+#define TSTNTCR1_TS2_TIMER_NEXT_TIME BITS(0,15) /* TS2 timer next time */
+
+/* TXOP Release Control Register (TRCR) bit definitions */
+#define TRCR_TX_TIME BITS(16,24)
+#define TRCR_END_PACKET_TYPE BIT(6)
+#define TRCR_TX_RATE BITS(0,5)
+
+
+/* ----- Receiver Control ----- */
+/* Data Receiver Control Register (DRCR) bit definitions */
+#define DRCR_ADDR_1_VALIDATION BIT(16) /* Addr 1 validation for data */
+#define DRCR_MGT_BSSID_VALIDATION BIT(15) /* bc/mc mgt BSSID validation */
+#define DRCR_ADDR_3_OWN_SA_FILTERING BIT(14) /* Addr 3 own SA filtering for bc/mc data with ToDS=0, FromDS=1 */
+#define DRCR_ADDR_3_BSSID_VALIDATION BIT(13) /* Addr 3 BSSID validation for bc/mc data with ToDS=0, FromDS=0 */
+#define DRCR_ADDR_2_BSSID_VALIDATION BIT(12) /* Addr 2 BSSID validation for bc/mc data with ToDS=0, FromDS=1 */
+#define DRCR_RX_BROADCAST_ENABLE BIT(11) /* Rx bc MPDU enable bit */
+#define DRCR_RX_ALL_MULTICAST_ENABLE BIT(10) /* Rx all mc MPDUs enable bit */
+#define DRCR_RX_MULTICAST_ENABLE BIT(9) /* Rx multicast MPDU enable bit */
+#define DRCR_PROMISCUOUS_MODE BIT(8) /* promiscuous mode enable bit */
+#define DRCR_FCS_ERROR_FRAME_DISCARD BIT(0) /* Rx frame with FCS error discard control bit */
+
+/* Receive Frame Block Configuration Register (RFBCR) bit definitions */
+#define RFBCR_BB_CR_D_INDEX BITS(24,30) /* BB CR D index */
+#define RFBCR_BB_CR_C_INDEX BITS(16,22) /* BB CR C index */
+#define RFBCR_BB_CR_B_INDEX BITS(8,14) /* BB CR B index */
+#define RFBCR_BB_CR_A_INDEX BITS(0,6) /* BB CR A index */
+
+
+/* ----- MAC Protocol Timing Control ----- */
+/* MAC Processing Delay Registet (MPDR) bit definitions */
+#define MPDR_MAC_PRC_DELAY_2 BITS(16,23) /* MAC processing delay M2 */
+#define MPDR_MAC_PRC_DELAY_1 BITS(0,7) /* MAC processing delay M1 */
+
+/* Transmit to Next Transmit Delay Register (TNTDR) bit definitions */
+#define TNTDR_TX_PIFS_CCA BITS(16,31)
+#define TNTDR_TX_SIFS_TX BITS(0,15)
+#define TNTDR_RADIA_LONG_SLOT 0x01f40082
+#define TNTDR_RADIA_SHORT_SLOT 0x01180082
+#define TNTDR_MAXIM_LONG_SLOT 0x01f40082
+#define TNTDR_MAXIM_SHORT_SLOT 0x01180082
+#define TNTDR_RFMD_LONG_SLOT 0x01f40082
+#define TNTDR_RFMD_SHORT_SLOT 0x01180082
+
+/* Slot Time Duration Register (STDR) bit definitions */
+#define STDR_SLOT_TIME_2 BITS(16,31) /* slot time with M2 */
+#define STDR_SLOT_TIME_1 BITS(0,15) /* slot time with M1 */
+#define STDR_LONG_SLOT 0x01900190
+#define STDR_SHORT_SLOT 0x00b400b4
+
+/* EIFS and Probe Delay Duration Register (EPDDR) bit definitions */
+#define EPDDR_PROBE_DELAY BITS(16,31) /* ProbeDelay */
+#define EPDDR_EIFS_TIME BITS(0,15) /* EIFS */
+
+/* Control Response Frame Control Register 0 (CRFCR0) bit definitions */
+#define CRFCR0_RSP_SAME_PREAMBLE BIT(31)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_9M BITS(25,29)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_6M BITS(20,24)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_11M BITS(15,19)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_5_5M BITS(10,14)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_2M BITS(5,9)
+#define CRFCR0_CTRL_RSP_TX_RATE_FOR_1M BITS(0,4)
+
+/* Control Response Frame Control Register 1 (CRFCR1) bit definitions */
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_54M BITS(25,29)
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_48M BITS(20,24)
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_36M BITS(15,19)
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_24M BITS(10,14)
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_18M BITS(5,9)
+#define CRFCR1_CTRL_RSP_TX_RATE_FOR_12M BITS(0,4)
+
+#define CRFCR_CTRL_RSP_TX_RATE_1M RATE_CODE_1M
+#define CRFCR_CTRL_RSP_TX_RATE_2M RATE_CODE_2M
+#define CRFCR_CTRL_RSP_TX_RATE_5_5M RATE_CODE_5_5M
+#define CRFCR_CTRL_RSP_TX_RATE_11M RATE_CODE_11M
+#define CRFCR_CTRL_RSP_TX_RATE_6M (RATE_CODE_6M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_9M (RATE_CODE_9M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_12M (RATE_CODE_12M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_18M (RATE_CODE_18M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_24M (RATE_CODE_24M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_36M (RATE_CODE_36M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_48M (RATE_CODE_48M | 0x00000010)
+#define CRFCR_CTRL_RSP_TX_RATE_54M (RATE_CODE_54M | 0x00000010)
+
+/* DCF Timeout Register (DTR) bit definitions */
+
+/* Beacon Contention Window Register (BCWR) bit definitions */
+
+/* TSF Timer Adjustment Register 0 (TTAR0) bit definitions */
+#define TTAR0_TSF_TIMER_VALUE_CHANGE BIT(1) /* TSF timer value change command/status */
+#define TTAR0_TSF_TIMER_OFFSET_ADJUST BIT(0) /* TSF timer offset adjust command/status */
+
+
+/* ----- Network Allocation Vector (NAV) Control ----- */
+/* Local NAV Register (LNR) bit definitions */
+#define LNR_NAV BITS(0,25) /* local NAV value */
+
+/* NAV Reset Timeout Register (NRTR) bit definitions */
+#define NRTR_CAP_RECOVERY_TIME BITS(16,19) /* CAP recovery time for AP */
+#define NRTR_RTS_NAV_RESET_TIMEOUT BITS(0,8) /* RTS NAV reset timeout */
+
+/* NAV Software Update Register (NSUR) bit definitions */
+#define NSUR_NAV_UPDATE BIT(31) /* NAV update command and status */
+#define NSUR_NAV_UPDATE_VALUE BITS(0,25) /* NAV updated value */
+
+
+/* ----- Beacon Generation ----- */
+/* Beacon Generation Control Register 0 (BGCR0) bit definitions */
+#define BGCR0_TX_TIMESTAMP_OFFSET BITS(16,23)
+#define BGCR0_TRANSMISSION_POWER BITS(8,15)
+#define BGCR0_BEACON_TX_RATE BITS(0,5) /* beacon tx rate */
+
+/* Beacon Generation Control Register 1 (BGCR1) bit definitions */
+#define BGCR1_BC_OWN BIT(31) /* BC own bit */
+#define BGCR1_BEACON_SN BITS(16,27)
+#define BGCR1_BEACON_LENGTH BITS(8,15)
+#define BGCR1_BC_LENGTH BITS(0,7)
+
+/* SW Beacon Content Control Register (SWBCCR) bit definitions */
+#define SWBCCR_BC_ACCESS_START BIT(7)
+#define SWBCCR_BC_RW_CTRL BIT(6)
+#define SWBCCR_BC_READ 0
+#define SWBCCR_BC_WRITE BIT(6)
+#define SWBCCR_BC_INDEX BITS(0,5)
+
+
+/* ----- Transmit Frame Architecture ----- */
+/* Transmit Frame Control Block (TFCB) field definitions */
+/* TFD Control Flag field */
+#define TFCB_FLAG_EOL BIT(0) /* Last TFCB indication bit */
+#define TFCB_FLAG_NB BIT(1) /* Null TBB pointer indication bit */
+#define TFCB_FLAG_MORE BIT(2) /* More Frag bit */
+#define TFCB_FLAG_CFB BIT(3) /* Contention Free Burst bit */
+#define TFCB_FLAG_SEC BIT(4) /* Security Engine Operation */
+#define TFCB_FLAG_PAIRED BIT(5) /* Paired bit */
+/* Security Operation Mode field */
+#define TFCB_SEC_MODE BITS(0,3)
+#define TFCB_SEC_MODE_NORMAL 0
+#define TFCB_SEC_MODE_SEC_ENGINE BIT(3)
+#define TFCB_SEC_MODE_NONE 0x00
+#define TFCB_SEC_MODE_WEP_40 0x01
+#define TFCB_SEC_MODE_TKIP 0x02
+#define TFCB_SEC_MODE_WRAP 0x03
+#define TFCB_SEC_MODE_CCMP 0x04
+#define TFCB_SEC_MODE_WEP_104 0x05
+#define TFCB_SEC_MODE_2120_CCMP 0x07
+#define TFCB_SEC_MODE_TKIP_MIC 0x0A
+#define TFCB_SEC_MODE_ENCRYPT_AES_CHAIN 0x0C
+#define TFCB_SEC_MODE_ENCRYPT_AES_SEQ 0x0D
+#define TFCB_SEC_MODE_DECRYPT_AES_CHAIN 0x0E
+#define TFCB_SEC_MODE_DECRYPT_AES_SEQ 0x0F
+/* Initialiazation Vector (IV) field */
+#define TFCB_IV_WEP_KEY_ID BITS(30,31) /* Key ID subfield */
+#define TFCB_IV_WEP_PAD BITS(24,29) /* Pad subfield */
+#define TFCB_IV_WEP_IV BITS(0,23) /* Initialization vector subfield */
+#define TFCB_IV_TKIP_KEY_ID BITS(30,31)
+#define TFCB_IV_TKIP_EXT_IV BIT(29)
+#define TFCB_IV_TKIP_PAD BITS(24,28)
+#define TFCB_IV_TKIP_RC4_KEY_2 BITS(16,23)
+#define TFCB_IV_TKIP_RC4_KEY_1 BITS(8,15)
+#define TFCB_IV_TKIP_RC4_KEY_0 BITS(0,7)
+#define TFCB_IV_CCMP_KEY_ID BITS(30,31)
+#define TFCB_IV_CCMP_EXT_IV BIT(29)
+#define TFCB_IV_CCMP_PAD BITS(16,28)
+#define TFCB_IV_CCMP_IV_1 BITS(8,15)
+#define TFCB_IV_CCMP_IV_0 BITS(0,7)
+#define TFCB_IV_WRAP_KEY_ID BITS(30,31)
+#define TFCB_IV_WRAP_PAD BITS(28,29)
+#define TFCB_IV_WRAP_REPLAY_COUNTER BITS(0,27)
+/* Extended IV field */
+#define TFCB_EIV_TKIP_TSC_5 BITS(24,31)
+#define TFCB_EIV_TKIP_TSC_4 BITS(16,23)
+#define TFCB_EIV_TKIP_TSC_3 BITS(8,15)
+#define TFCB_EIV_TKIP_TSC_2 BITS(0,7)
+#define TFCB_EIV_CCMP_IV_5 BITS(24,31)
+#define TFCB_EIV_CCMP_IV_4 BITS(16,23)
+#define TFCB_EIV_CCMP_IV_3 BITS(8,15)
+#define TFCB_EIV_CCMP_IV_2 BITS(0,7)
+/* TCI Control Flag field */
+#define TFCB_CTRL_RTS BIT(7)
+#define TFCB_CTRL_CTS BIT(6)
+#define TFCB_CTRL_QOS_CF_POLL BIT(5)
+#define TFCB_CTRL_TSF BIT(4)
+#define TFCB_CTRL_NO_ACK BIT(3)
+#define TFCB_CTRL_DELAY BIT(2)
+#define TFCB_CTRL_CFB BIT(1)
+#define TFCB_CTRL_MORE BIT(0)
+/* TID & MAC Header Control Flag field */
+#define TFCB_TID BITS(0,3)
+#define TFCB_FRAG BIT(7)
+#define TFCB_TX_ANT BIT(6)
+#define TFCB_MAC_HEADER_EIV_PRESENT BIT(5)
+#define TFCB_MAC_HEADER_IV_PRESENT BIT(4)
+/* Multirate Switching Control field */
+#define TFCB_MULTIRATE_STEP_NUM BITS(14,15)
+#define TFCB_MULTIRATE_1_STEP_SWITCH 0
+#define TFCB_MULTIRATE_2_STEP_SWITCH BIT(14)
+#define TFCB_MULTIRATE_MPDU_RETRY_LIMIT_2 BITS(7,13)
+#define TFCB_MULTIRATE_MPDU_RETRY_LIMIT_1 BITS(0,6)
+/* Transmission Rates field */
+#define TFCB_TX_RATE_2 BITS(8,13)
+#define TFCB_TX_RATE_1 BITS(0,5)
+/* Transmit Status field */
+#define TFCB_STATUS_FRAG_SWSKIP BIT(15)
+#define TFCB_STATUS_TX_RATE BITS(8,15)
+#define TFCB_STATUS_TIMEUP_ERR BIT(4)
+#define TFCB_STATUS_FRAG_SKIP_ERR BIT(3)
+#define TFCB_STATUS_RTS_RETRY_ERR BIT(2)
+#define TFCB_STATUS_MPDU_RETRY_ERR BIT(1)
+#define TFCB_STATUS_OK BIT(0)
+#define TFCB_STATUS_MASK (TFCB_STATUS_OK | \
+ TFCB_STATUS_MPDU_RETRY_ERR | \
+ TFCB_STATUS_RTS_RETRY_ERR | \
+ TFCB_STATUS_FRAG_SKIP_ERR | \
+ TFCB_STATUS_TIMEUP_ERR | \
+ TFCB_STATUS_FRAG_SWSKIP)
+
+/* Transmit Frame Descriptor (TFD) Checksum size */
+#define TFCB_TFD_SIZE 0x0c //TFD legth for check sum calculation
+#define TFCB_TSI_SIZE 0x10 //Transmit Status Information
+
+
+
+/* Transmit Buffer Block (TBB) field definitions */
+/* TBB Flag field */
+#define TBB_FLAG_EOL BIT(0) /* Last TBB indication bit */
+
+/* Transmit Buffer Block (TBB) size definiton */
+#define TBB_REVBUFFER_SIZE 32
+#define TBB_TBD_SIZE 12
+
+
+/* ----- Receive Frame Architecture ----- */
+/* Receive Frame Block (RFB) field definitions */
+/* RFB Flag field */
+#define RFB_FLAG_EOL BIT(0) /* RFB EL Bit */
+/* Receive Status Bits */
+#define RFB_STATUS_FCS_ERR BIT(1)
+#define RFB_STATUS_OK BIT(0)
+#define RFB_STATUS_MASK (RFB_STATUS_OK | RFB_STATUS_FCS_ERR)
+/* Receive Security Status Bits */
+#define RFB_SECSTATUS_DATA_PRIVACY_MASK BITS(0,3)
+#define RFB_SECSTATUS_FORMAT_ERR BIT(11)
+#define RFB_SECSTATUS_RXICV_ERR BIT(10)
+#define RFB_SECSTATUS_RXKEYDIS_ERR BIT(9)
+#define RFB_SECSTATUS_RXKEY_NOT_FOUND_ERR BIT(8)
+#define RFB_SECSTATUS_RXDEC_ERR_MASK BITS(8,11)
+/* Receive Frame Descriptor (RFD) size */
+#define RFB_RFD_SIZE 0x08
+#define RFB_RX_BUFFER_MAC_HEADER_SIZE 32
+#define RFB_RSI_SIZE 48
+
+
+/* ----- Transmission rate codes ----- */
+#define RATE_CODE_RATE_MASK 0x0F
+#define RATE_CODE_1M 0x00
+#define RATE_CODE_2M 0x01
+#define RATE_CODE_5_5M 0x02
+#define RATE_CODE_11M 0x03
+#define RATE_CODE_6M 0x0B
+#define RATE_CODE_9M 0x0F
+#define RATE_CODE_12M 0x0A
+#define RATE_CODE_18M 0x0E
+#define RATE_CODE_24M 0x09
+#define RATE_CODE_36M 0x0D
+#define RATE_CODE_48M 0x08
+#define RATE_CODE_54M 0x0C
+
+#define RATE_CODE_PREAMBLE_MASK 0x10
+#define RATE_CODE_LONG_PREAMBLE 0x00
+#define RATE_CODE_SHORT_PREAMBLE 0x10
+
+#define RATE_CODE_OFDM_MASK 0x20
+#define RATE_CODE_CCK 0x00
+#define RATE_CODE_OFDM 0x20
+
+/* CCK mode, long preamble */
+#define TX_RATE_LONG_PREAMBLE_1M (RATE_CODE_1M | RATE_CODE_LONG_PREAMBLE)
+#define TX_RATE_LONG_PREAMBLE_2M (RATE_CODE_2M | RATE_CODE_LONG_PREAMBLE)
+#define TX_RATE_LONG_PREAMBLE_5_5M (RATE_CODE_5_5M | RATE_CODE_LONG_PREAMBLE)
+#define TX_RATE_LONG_PREAMBLE_11M (RATE_CODE_11M | RATE_CODE_LONG_PREAMBLE)
+
+/* CCK mode, short preamble */
+#define TX_RATE_SHORT_PREAMBLE_2M (RATE_CODE_2M | RATE_CODE_SHORT_PREAMBLE)
+#define TX_RATE_SHORT_PREAMBLE_5_5M (RATE_CODE_5_5M | RATE_CODE_SHORT_PREAMBLE)
+#define TX_RATE_SHORT_PREAMBLE_11M (RATE_CODE_11M | RATE_CODE_SHORT_PREAMBLE)
+
+/* OFDM mode */
+#define TX_RATE_OFDM_6M (RATE_CODE_6M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_9M (RATE_CODE_9M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_12M (RATE_CODE_12M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_18M (RATE_CODE_18M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_24M (RATE_CODE_24M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_36M (RATE_CODE_36M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_48M (RATE_CODE_48M | RATE_CODE_OFDM)
+#define TX_RATE_OFDM_54M (RATE_CODE_54M | RATE_CODE_OFDM)
+
+
+/* IPN2128 Baseband control register (BBCR) offset definition */
+#define BBCR_CR0 0
+#define BBCR_CR1 1
+#define BBCR_CR2 2
+#define BBCR_CR3 3
+#define BBCR_CR4 4
+#define BBCR_CR5 5
+#define BBCR_CR6 6
+#define BBCR_CR7 7
+#define BBCR_CR8 8
+#define BBCR_CR9 9
+#define BBCR_CR10 10
+#define BBCR_CR11 11
+#define BBCR_CR12 12
+#define BBCR_CR13 13
+#define BBCR_CR14 14
+#define BBCR_CR15 15
+#define BBCR_CR16 16
+#define BBCR_CR17 17
+#define BBCR_CR18 18
+#define BBCR_CR19 19
+#define BBCR_CR20 20
+#define BBCR_CR21 21
+#define BBCR_CR22 22
+#define BBCR_CR23 23
+#define BBCR_CR24 24
+#define BBCR_CR25 25
+#define BBCR_CR26 26
+#define BBCR_CR27 27
+#define BBCR_CR28 28
+#define BBCR_CR29 29
+#define BBCR_CR30 30
+#define BBCR_CR31 31
+#define BBCR_CR32 32
+#define BBCR_CR33 33
+#define BBCR_CR34 34
+#define BBCR_CR35 35
+#define BBCR_CR36 36
+#define BBCR_CR37 37
+#define BBCR_CR38 38
+#define BBCR_CR39 39
+#define BBCR_CR45 45
+#define BBCR_CR46 46
+#define BBCR_CR80 80
+#define BBCR_CR81 81
+#define BBCR_CR82 82
+#define BBCR_CR83 83
+#define BBCR_CR84 84
+#define BBCR_CR85 85
+#define BBCR_CR86 86
+#define BBCR_CR87 87
+#define BBCR_CR88 88
+#define BBCR_CR89 89
+#define BBCR_CR90 90
+#define BBCR_CR91 91
+#define BBCR_CR92 92
+#define BBCR_CR93 93
+#define BBCR_CR94 94
+#define BBCR_CR95 95
+#define BBCR_CR96 96
+#define BBCR_CR97 97
+#define BBCR_CR98 98
+#define BBCR_CR99 99
+#define BBCR_CR100 100
+#define BBCR_CR101 101
+#define BBCR_CR102 102
+#define BBCR_CR103 103
+#define BBCR_CR104 104
+#define BBCR_CR105 105
+#define BBCR_CR106 106
+#define BBCR_CR107 107
+#define BBCR_CR108 108
+#define BBCR_CR109 109
+#define BBCR_CR110 110
+#define BBCR_CR111 111
+#define BBCR_CR112 112
+#define BBCR_CR113 113
+#define BBCR_CR114 114
+#define BBCR_CR115 115
+#define BBCR_CR116 116
+#define BBCR_CR117 117
+#define BBCR_CR118 118
+#define BBCR_CR119 119
+#define BBCR_CR120 120
+#define BBCR_CR121 121
+#define BBCR_CR122 122
+#define BBCR_CR123 123
+#define BBCR_CR124 124
+#define BBCR_CR125 125
+#define BBCR_CR126 126
+#define BBCR_CR127 127
+#define BBCR_CR128 128
+#define BBCR_CR129 129
+
+/* IPN2128 Baseband control register (BBCR) definition */
+/* CR24 bit definitions */
+#define CR24_RX_MODULATION_TYPE BIT(7)
+#define CR24_RX_OFDM BIT(7)
+#define CR24_RX_CCK 0x00
+#define CR24_RX_PREAMBLE_TYPE BIT(6)
+#define CR24_RX_SHORT_PREAMBLE BIT(6)
+#define CR24_RX_LONG_PREAMBLE 0x00
+#define CR24_RX_RATE BITS(2,5)
+#define CR24_RX_RATE_1M (RATE_CODE_1M << 2)
+#define CR24_RX_RATE_2M (RATE_CODE_2M << 2)
+#define CR24_RX_RATE_5_5M (RATE_CODE_5_5M << 2)
+#define CR24_RX_RATE_11M (RATE_CODE_11M << 2)
+#define CR24_RX_RATE_6M (RATE_CODE_6M << 2)
+#define CR24_RX_RATE_9M (RATE_CODE_9M << 2)
+#define CR24_RX_RATE_12M (RATE_CODE_12M << 2)
+#define CR24_RX_RATE_18M (RATE_CODE_18M << 2)
+#define CR24_RX_RATE_24M (RATE_CODE_24M << 2)
+#define CR24_RX_RATE_36M (RATE_CODE_36M << 2)
+#define CR24_RX_RATE_48M (RATE_CODE_48M << 2)
+#define CR24_RX_RATE_54M (RATE_CODE_54M << 2)
+
+/* CR29 bit definitions */
+#define CR29_RX_ANTENNA BIT(7)
+#define CR29_LNA_STATUS BIT(5)
+#define CR29_VGA_GAIN BITS(0,4)
+
+/* LET Control */
+#define LED_BLINKING_ON_TIME_1 20 /* LED blinking on time: 80 ms */
+#define LED_BLINKING_OFF_TIME_1 6 /* LED blinking off time: 24 ms */
+#define LED_BLINKING_ON_TIME_2 20 /* LED blinking on time: 80 ms */
+#define LED_BLINKING_OFF_TIME_2 3 /* LED blinking off time: 12 ms */
+
+#define LCR_DEFAULT_VALUE (LCR_LED_MODE_TX_RX | \
+ LCR_LED_POLARITY_POSITIVE | \
+ ((LED_BLINKING_ON_TIME_1 << 8) & LCR_LED_ON_CNT) | \
+ (LED_BLINKING_OFF_TIME_1 & LCR_LED_OFF_CNT))
+
+
+/************************************************************************
+* D A T A T Y P E S
+*************************************************************************
+*/
+
+/* MCR structure for MCR init and RF init*/
+typedef struct _MCRLIST_STRUC {
+ unsigned short offset;
+ kal_uint32 initValue;
+} MCRLIST_STRUC, *PMCRLIST_STRUC;
+
+
+
+
+/************************************************************************
+* M A C R O S
+*************************************************************************
+*/
+
+/************************************************************************
+* D A T A D E C L A R A T I O N S
+*************************************************************************
+*/
+
+/************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+*************************************************************************
+*/
+
+/*equates.h*/
+/************************************************************************
+* C O M P I L E R F L A G S
+*************************************************************************
+*/
+
+/************************************************************************
+* C O N S T A N T S
+*************************************************************************
+*/
+
+#ifndef BIT
+//#define BIT(n) ( (ULONG)1 << (n) )
+#define BIT(n) ( (kal_uint32)1 << (n) )
+#define BITS2(m,n) ( BIT(m) | BIT (n) )
+#define BITS3(m,n,o) ( BIT(m) | BIT (n) | BIT (o) )
+#define BITS4(m,n,o,p) ( BIT(m) | BIT (n) | BIT (o) | BIT(p) )
+
+/* bits range: for example BITS(16,23) = 0xFF0000
+ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000
+ * ==> (BIT(n+1)-1) = 0x00FFFFFF
+ */
+#define BITS(m,n) ( ~(BIT(m)-1) & ((BIT(n)-1)|BIT(n)) )
+#endif
+
+
+/* MAC address */
+#define DEFAULT_MAC_ADDR {0x00, 0x08, 0x22, 0xFE, 0x00, 0x01}
+#define NULL_MAC_ADDR {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+#define BROADCAST_MAC_ADDR {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
+
+/* Chip ID and revision */
+#define IPN2128 0x21280000
+#define IPN2126 0x21260000
+
+#define CHIP_ID_VERSION_MASK BITS(8,31) /* mask for chip ID and version */
+#define CHIP_ID_MASK BITS(16,31) /* mask for chip ID */
+#define FPGA_VERSION_MASK BITS(0,15) /* mask for FPGA emulation platform version */
+
+#define IPN2128_FPGA 0x01 // FPGA version driver set 1
+#define IPN2128_BCI_P 0x00 // BCI parallel interface set 1
+
+/* Adapter Types Supported */
+#define IPN2128_MINI_PCI 0x00
+#define IPN2128_CARDBUS 0x01
+
+/* Supported RF chipsets */
+#define RF_RFMD 0x00000001 /* RF MicroDevice */
+#define RF_MAXIM 0x00000002 /* Maxim */
+#define RF_AIROHA 0x00000003 /* Airoha */
+
+
+#define MAC_ADDRESS_LENGTH 6
+#define MAC_ADDR_LEN MAC_ADDRESS_LENGTH
+
+/* Ethernet Frame Sizes */
+//#define ETHERNET_ADDRESS_LENGTH 6
+#define ETHERNET_HEADER_SIZE 14
+#define MINIMUM_ETHERNET_PACKET_SIZE 60
+#define MAXIMUM_ETHERNET_PACKET_SIZE 1514
+
+/* IEEE 802.11 WLAN Frame Sizes */
+#define WLAN_MAC_HEADER_SIZE 24 /* Address 4 excluded */
+#define MINIMUM_WLAN_PACKET_SIZE 16
+#define MAXIMUM_WLAN_PACKET_SIZE 4096 // including encryption needed
+
+/* PS-Poll frame MAC header size */
+#define WLAN_PSPOLL_MAC_HEADER_SIZE 16
+
+#define FRAME_BODY_MAX_LEN 2304 /* maximum length of MPDU */
+
+#define WLAN_MAC_FCS_LEN 4 /* length of FCS field in MAC frame */
+#define WLAN_MAC_IV_LEN 4 /* length of IV field in encrypted MAC frame */
+#define WLAN_MAC_ICV_LEN 4 /* length of ICV field in encrypted MAC frame */
+#define WLAN_MAC_EXT_IV_LEN 4 /* length of Extented ICV field in encrypted MAC frame */
+#define WLAN_MAC_MIC_LEN 8 /* length of MIC field in encrypted MAC frame */
+#define WLAN_MAC_REPLAY_CTR_LEN 4 /* length of Replay Counter field in encrypted MAC frame */
+#define WLAN_MAC_CKIP_MIC_LEN 4 /* length of CKIP MIC */
+#define WLAN_MAC_CKIP_SEQ_LEN 4 /* length of CKIP SEQ */
+
+#define CCM_IB_FLAGS 0x59
+#define CCM_CTR_FLAGS 0x01
+
+//#define TCB_BUFFER_SIZE 0XE0 // 224
+#define COALESCE_BUFFER_SIZE 2048 /* 4k bytes */
+//#define ETH_MAX_COPY_LENGTH 0x80 // 128
+
+// Make receive area 1536 for 16 bit alignment.
+//#define RCB_BUFFER_SIZE MAXIMUM_ETHERNET_PACKET_SIZE
+//#define RCB_BUFFER_SIZE 1520 // 0x5F0
+
+/* Wireless LAN packet buffer size (padding for 16-byte alignment) */
+#define WLAN_PACKET_BUFFER_SIZE (((MAXIMUM_WLAN_PACKET_SIZE + 15) >> 4) << 4)
+
+/* transmit buffer size (padding for 16-byte alignment) */
+#define TX_BUFFER_SIZE WLAN_PACKET_BUFFER_SIZE
+
+/* receive buffer size (padding for 16-byte alignment) */
+#define RX_BUFFER_SIZE WLAN_PACKET_BUFFER_SIZE
+
+//- Area reserved for all Non Transmit command blocks
+//#define MAX_NON_TX_CB_AREA 512
+
+/* IEEE 802.11 defined time constant */
+#define TU 1024 /* Time uint: 1024 microseconds */
+
+/* Ndis/Adapter driver constants */
+#define MAX_PHYS_DESC 16
+
+#define NUM_TX_QUEUES 4
+
+/* System wide Equates */
+//#define MAX_NUMBER_OF_EISA_SLOTS 15
+//#define MAX_NUMBER_OF_PCI_SLOTS 15
+
+#define MAX_ARRAY_SEND_PACKETS 8
+
+/* Number of RFBs - minimum, default, and maximum */
+#define NIC_MIN_NUM_RFBS 4
+#define NIC_DEF_NUM_RFBS 20
+#define NIC_MAX_NUM_RFBS 1024
+
+/* Maximum number of remote STA records */
+#define MAX_NUM_REMOTE_STA_RECORDS 16
+
+/* Maximum number of supported physical layer network subtypes */
+#define MAX_NUM_SUPPORTED_NETWORK_TYPE 3
+
+/* Maximum number of scan results */
+#define MAX_NUM_SCAN_RESULTS 32
+
+/* Miscellaneous Equates */
+//#define CR 0x0D // Carriage Return
+//#define LF 0x0A // Line Feed
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+#define DRIVER_NULL ((ULONG)0xffffffff) // reopen Jay 0613
+//#define DRIVER_ZERO 0
+
+// in order to make our custom oids hopefully somewhat unique
+// we will use 0xFF (indicating implementation specific OID)
+// A0 (first byte of non zero intel unique identifier)
+// C9 (second byte of non zero intel unique identifier)
+// XX (the custom OID number - providing 255 possible custom oids)
+
+
+
+/************************************************************************
+* M A C R O S
+*************************************************************************
+*/
+
+/************************************************************************
+* D A T A D E C L A R A T I O N S
+*************************************************************************
+*/
+
+/************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+*************************************************************************
+*/
+
+
+
+/* Chip ID and revision */
+#define IPN2128 0x21280000
+#define IPN2126 0x21260000
+#define CHIP_ID_REV IPN2128
+
+
+typedef struct i2126mgmt_ i2126mgmt_t;
+typedef i2126mgmt_t MP_ADAPTER, *PMP_ADAPTER;
+
+
+/* Macros to read and write MAC control registers (MCRs) */
+#define NIC_MCR_READ(_pAdapter, _register, _pValue) \
+ IPC_2126_MCR_Read(_register, (kal_uint32 *)(_pValue))
+
+#define NIC_MCR_WRITE(_pAdapter, _register, _value) \
+ IPC_2126_MCR_Write( _register, (kal_uint32)(_value))
+
+#endif /* __PRECOMP_H */
+
diff --git a/mcu/driver/storage/mc/inc/usbms_msdc.h b/mcu/driver/storage/mc/inc/usbms_msdc.h
new file mode 100644
index 0000000..0db32ac
--- /dev/null
+++ b/mcu/driver/storage/mc/inc/usbms_msdc.h
@@ -0,0 +1,89 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * usbms_msdc.h
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * Header file of memory card host driver
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+
+typedef enum {
+ MSDC_MEM_TYPE_EXT = 0,
+ MSDC_MEM_TYPE_SIMPLUS = 1,
+ MSDC_MEM_TYPE_TCARD2 = 2
+}MSDC_EXT_MEM_TYPE;
+
+typedef enum {
+ DEV_STATUS_OK = 0,
+ DEV_STATUS_MEDIA_CHANGE,
+ DEV_STATUS_NOMEDIA,
+ DEV_STATUS_WP,
+ DEV_STATUS_MAX
+} MSDC_DEV_STATUS;
+
+kal_bool usbms_read_all(void *data, kal_uint32 LBA, kal_uint16 sec_len, MSDC_EXT_MEM_TYPE type);
+kal_bool usbms_gpd_read_all(qbm_gpd *head,qbm_gpd *tail,kal_uint32 LBA,kal_uint16 sec_len,MSDC_EXT_MEM_TYPE type);
+kal_bool usbms_write_all(void *data, kal_uint32 LBA, kal_uint16 sec_len, MSDC_EXT_MEM_TYPE type);
+kal_bool usbms_gpd_write_all(qbm_gpd *head,qbm_gpd *tail,kal_uint32 LBA,kal_uint16 sec_len,MSDC_EXT_MEM_TYPE type);
+kal_int16 usbms_checkmedia_exist_all(MSDC_EXT_MEM_TYPE type);
+kal_bool usbms_format_all(MSDC_EXT_MEM_TYPE type);
+kal_bool usbms_prevmedia_removal_all(kal_bool enable);
+kal_bool usbms_query_max_bd_num(kal_uint16 * max_bd_num);
+kal_bool usbms_read_capacity_all(kal_uint32 *max_lba, kal_uint32 *sec_len, MSDC_EXT_MEM_TYPE type);
+
+
+
diff --git a/mcu/driver/storage/mc/src/dcl_memory_card.c b/mcu/driver/storage/mc/src/dcl_memory_card.c
new file mode 100644
index 0000000..679e351
--- /dev/null
+++ b/mcu/driver/storage/mc/src/dcl_memory_card.c
@@ -0,0 +1,3668 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * dcl_memory_card.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * This Module defines DCL (Driver Common Layer) of the memory card driver and SDIO driver.
+ * The memory card driver provide here include SD, MMC, MS/MSPro.
+ * In thie file, DclSD_xxx is the API for SD driver, Dcl_SDIO_xxx is the API for SDIO driver, and DclMS_xxx is the API for MS and MSPro driver.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include "drv_features.h"
+#include "drv_comm.h"
+#include "dcl.h"
+#include "msdc_def.h"
+
+#ifdef DCL_MSDC_INTERFACE
+#if !defined(DRV_MSDC_OFF)
+#include "msdc_reg_adap.h"
+#include "intrCtrl.h"
+#include "sd_def.h"
+#include "drv_trc.h"
+#include "cache_sw.h"
+#include "kal_public_api.h"
+#include "init.h"
+#include "qmu_bm.h"
+
+/**************************************************************************
+following defines options used in this file
+***************************************************************************/
+/*SD related handle*/
+#define DCL_SD_HANDLE_SD1 (MSDC_ADRS|SD_MSDC1)
+#if defined(__MSDC2_SD_MMC__)
+#define DCL_SD_HANDLE_SD2 (MSDC2_ADRS|SD_MSDC2)
+#endif
+
+
+#define DCL_SD_GET_SEL_FROM_HANDLE(a) ((sd_select_enum)(a & 0xF))
+
+/*SDIO related handle*/
+#define DCL_SDIO_HANDLE_SDIO1 (MSDC_ADRS|SD_MSDC1)
+#if defined(__MSDC2_SD_SDIO__)
+#define DCL_SDIO_HANDLE_SDIO2 (MSDC2_ADRS|SD_MSDC2)
+#endif
+#define DCL_SDIO_GET_SEL_FROM_HANDLE(a) ((sd_select_enum)(a & 0xF))
+
+/*MS related handle*/
+#define DCL_MS_HANDLE (MSDC_ADRS|0)
+#define DCL_MS_GET_SEL_FROM_HANDLE(a) ((sd_select_enum)(a & 0xF))
+
+/*following definition is to help easy search for incomplete part*/
+#define DCL_SD_IMPLEMENTATION_ASSERT ASSERT(0)
+
+/**************************************************************************
+following defines static global variables used in this file
+***************************************************************************/
+static kal_bool fgMSDCInit = KAL_FALSE;
+static kal_bool fgSDInit = KAL_FALSE;
+#if defined(__MSDC_SD_SDIO__)
+static kal_bool fgSDIOInit = KAL_FALSE;
+#endif
+
+#if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
+static kal_bool fgMSInit = KAL_FALSE;
+DCL_UINT32 u4ms16KBuffer[4*1024]; // 16K MS buffer
+#endif
+
+/*following variable is used to replace the compile option usage in the code*/
+static kal_uint32 u4MSDCSupport;//stand for wihch HW MSDC will be used
+
+
+
+//static kal_semid dclMsdcArb[3];
+static MSDC_LOCK_TAG dclMsdcLock[3];
+/**************************************************************************
+* following defines global variables and definitions used for resource contention
+* with uint16 stands for a resource, every resource is composed as following:
+* using[15:13] | occupied[12] | magic[11:4] | RFU[3:0]
+***************************************************************************/
+static kal_uint16 sdResource[3];
+//static kal_uint16 msdcResource[3];
+
+#define DCL_SD_RESOURCE_OCCUPIED 0x1000
+#define DCL_SD_RESOURCE_USING_MAX 0xE000
+#define DCL_SD_RESOURCE_USING_INCREMENT 0x2000
+#define DCL_SD_RESOURCE_MAGIC_MAX 0x0ff0
+#define DCL_SD_RESOURCE_MAGIC_UNIT 0x0010
+#define DCL_SD_GET_MAGIC_FROM_HANDLE(a) (a & DCL_SD_RESOURCE_MAGIC_MAX)
+#define DCL_SD_GET_DUMMY_HANDLE(a) (a & (~DCL_SD_RESOURCE_MAGIC_MAX))
+static sd_select_enum DCL_SD_USING_RESOURCE_START(DCL_HANDLE handle)
+{
+ sd_select_enum sel;
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ if(DCL_SD_RESOURCE_OCCUPIED != (sdResource[sel] & DCL_SD_RESOURCE_OCCUPIED))
+ {
+ ASSERT(0);
+ }
+ if((handle & DCL_SD_RESOURCE_MAGIC_MAX) != (sdResource[sel] & DCL_SD_RESOURCE_MAGIC_MAX))
+ {
+ ASSERT(0);
+ }
+ }
+
+ #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+
+ return sel;
+}
+
+static void DCL_SD_USING_RESOURCE_END(DCL_HANDLE handle,sd_select_enum sel)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+ return;
+}
+
+/*******************************************************************************
+* following defines global variables and definitions used for debuging on resource management
+********************************************************************************/
+typedef struct{
+ kal_uint32 callerRetAddr;
+ kal_uint32 ownerThdId;
+} DCL_SD_DBG_RESOURCE;
+
+
+/**************************************************************************
+* following defines function tables of SD layer and MSDC layer. These function tables should only be accessed by functions in this file
+* I should pay some time to remove hard coding of array exntries.
+***************************************************************************/
+static SDDriver_t *sdDriverTable[3];
+static MSDCDriver_t msdcDriverTable[3];
+#if defined(__MSDC_SD_SDIO__)
+static SDIODriver_t *sdioDriverTable[2];
+#endif
+
+/******************************************************************************************
+*following are extern variables from other file
+******************************************************************************************/
+extern SDDriver_t sd_driver_MTK1;
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+extern SDDriver_t sd_driver_MTK2;
+#endif
+
+#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
+#else
+extern void SD_SetRedDlt(kal_uint32 redDlt);
+#endif
+
+#if defined(__MSDC_MSPRO__)
+// global variables
+extern MSP_HANDLE gMSP;
+#endif
+/**************************************************************************
+followings are static functions that are only called by functions in this file
+***************************************************************************/
+
+/*************************************************************************
+* FUNCTION
+* DclMSDC_init
+*
+* DESCRIPTION
+* This function is to initialize MSDC related HW and SW.
+* This file is to be only called by DCL driver, so we set it statis.
+* Users should not remove "static" keyword unless you know MTK's memory card driver well.
+*
+* PARAMETERS
+* N/A
+*
+* RETURNS
+* None
+*
+*************************************************************************/
+static void DclMSDC_init(void)
+{
+ /*to get information about how many HW MSDC we will use*/
+#if (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__)|| defined(__MSDC_MSPRO__)) || defined(__MSDC_SD_SDIO__)
+ u4MSDCSupport |= DCL_MSDC_HW_MSDC1;
+#endif
+
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+ u4MSDCSupport |= DCL_MSDC_HW_MSDC2;
+#endif
+
+ if(u4MSDCSupport & DCL_MSDC_HW_MSDC1){
+ MSDC_Initialize();
+
+ #if defined(MSDC_QMU_ENABLE)
+ SD_QMU_Init();
+ #endif
+
+ //dclMsdcArb[0] = kal_create_sem("MSDC1_lock", 1);
+ init_MSDC_lock(&dclMsdcLock[0], "DCL_MSDC0_LOCK");
+ }
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+ /*if MSDC2 is not compiled, there will be no MSDC_Initialize2, should wrap here*/
+ if(u4MSDCSupport & DCL_MSDC_HW_MSDC2){
+ MSDC_Initialize2();
+ //dclMsdcArb[1] = kal_create_sem("MSDC2_lock", 1);
+ init_MSDC_lock(&dclMsdcLock[1], "DCL_MSDC1_LOCK");
+ }
+#endif
+
+ /*init MSDC driver tables, since the functions in every msdc drivers are few, we register then one by one*/
+ msdcDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SD1)].modulePDN = (DCL_MSDC_PDN)MSDC_PDNControl;
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ msdcDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SIMPLUS)].modulePDN = (DCL_MSDC_PDN)MSDC_PDNControl; //in the design, sel = 2 is preserved for SIM+ card, which uses 1st MSDC's code
+#endif
+
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+ msdcDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SD2)].modulePDN = (DCL_MSDC_PDN)MSDC_PDNControl2;
+#endif
+}
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+static DCL_STATUS ConfigGpdList(sd_select_enum sel ,qbm_gpd *head,qbm_gpd*tail,msdc_gpd_t * gpd,msdc_gpd_t * gpd_end)
+{
+#if 1
+ MSDC_Blk[sel].head = head;
+ MSDC_Blk[sel].tail = tail;
+ MSDC_Blk[sel].gpd = gpd;
+ MSDC_Blk[sel].gpd_end = gpd_end;
+
+#else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #ifdef MSDC_DMA_CHKSUM_EN
+/* under construction !*/
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #ifdef MSDC_DMA_CHKSUM_EN
+/* under construction !*/
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #if defined(MSDC_SCAT_BUF_FLUSH)/* || defined(ATEST_DRV_MSDC)*/
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #ifdef MSDC_DMA_CHKSUM_EN
+/* under construction !*/
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #ifdef MSDC_GPD_BD_BUF_CACHED
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+/* under construction !*/
+#endif
+
+ return STATUS_OK;
+}
+
+static DCL_BOOL DclSD_PollExistence(DCL_UINT8 irqMSDCCode, DCL_UINT32 addrReg_MSDC_PS, sd_select_enum sel)
+{
+ return MSDC_Blk[sel].mIsPresent;
+}
+
+//Sextern kal_bool DMA_Valid_Addr_Chk(const void *src, kal_uint32 length);
+static DCL_STATUS DclSD_CtrlCmdRead(sd_select_enum sel, SD_CTRL_READ_T *prRead)
+{
+#ifdef __MSDC_SD_MMC__
+// DCL_UINT32 addrs
+ DCL_UINT32 maxBlk;
+ DCL_SDC_CMD_STATUS status;
+ DCL_UINT32 u4Sector; //this specify the starting sector to read
+ DCL_UINT32 u4Sectors; //this specify the number of sectors to read
+ void *bufferAddr; //we will move move data from card to this address
+ SDDriver_t *sdDriver;
+
+ /*parameters in prRead should not be changed, take these as local variable*/
+ u4Sector = prRead->u4Sector;
+ u4Sectors = prRead->u4Sectors;
+ bufferAddr = prRead->bufferAddr;
+
+ /*requirement check here*/
+ if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+ //ASSERT(0);
+ status = STATUS_ERROR_WRONG_STATE;
+ return status;
+ }
+
+ maxBlk = gSD_blk[sel].mCSD.capacity/512;
+ /*sectors & sector check*/
+ if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector >= maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ /*check that ending block should be smaller than maximum block number*/
+ if((u4Sector + u4Sectors ) > maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+#if defined(MSDC_CACHED_SUPPORT)
+#if (defined(__UBL__) || defined(__FUE__)) && defined(__EMMC_BOOTING__)
+ MSDC_Blk[sel].isCachedBuf = KAL_TRUE;
+#else
+ /*tell buffer type each time this function called*/
+ if (INT_QueryIsCachedRAM(bufferAddr, u4Sectors * DCL_SECTOR_SIZE)){
+ MSDC_Blk[sel].isCachedBuf = KAL_TRUE;
+ }
+ else
+ MSDC_Blk[sel].isCachedBuf = KAL_FALSE;
+#endif
+#endif
+
+
+ /*power on MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_FALSE);
+
+ sdDriver = sdDriverTable[sel];
+ /*block address or byte address*/
+ if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+ u4Sector = u4Sector;
+ else
+ u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+ if(u4Sectors > 1)
+ {
+ status = sdDriver->mulBlkRd(u4Sector, bufferAddr, u4Sectors);
+ }
+ else{
+ status = sdDriver->singleBlkRd(u4Sector, bufferAddr);
+ }
+
+ /*power down MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_TRUE);
+ return status;
+#endif
+}
+
+static DCL_STATUS DclSD_CtrlCmdGpdRead(sd_select_enum sel, SD_CTRL_GPD_READ_T *prRead)
+{
+ #ifdef __MSDC_SD_MMC__
+// DCL_UINT32 addrs
+ DCL_UINT32 maxBlk;
+ DCL_SDC_CMD_STATUS status;
+ DCL_UINT32 u4Sector; //this specify the starting sector to read
+ DCL_UINT32 u4Sectors; //this specify the number of sectors to read
+ SDDriver_t *sdDriver;
+ /*parameters in prRead should not be changed, take these as local variable*/
+ u4Sector = prRead->u4Sector;
+ u4Sectors = prRead->u4Sectors;
+
+ /*requirement check here*/
+ if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+ //ASSERT(0);
+ status = STATUS_ERROR_WRONG_STATE;
+ return status;
+ }
+
+ maxBlk = gSD_blk[sel].mCSD.capacity/512;
+ /*sectors & sector check*/
+ if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector >= maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ /*check that ending block should be smaller than maximum block number*/
+ if((u4Sector + u4Sectors ) > maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ status=ConfigGpdList(sel,(qbm_gpd *)(prRead->bufferHead),(qbm_gpd*)(prRead->bufferTail),&MSDC_gpd[sel],&MSDC_gpd_end[sel]);
+
+ if(status !=NO_ERROR)
+ return status;
+ /*power on MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_FALSE);
+
+ sdDriver = sdDriverTable[sel];
+ /*block address or byte address*/
+ if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+ u4Sector = u4Sector;
+ else
+ u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+
+ status = sdDriver->GpdMulBlkRd(u4Sector, u4Sectors,&MSDC_gpd[sel]);
+
+ /*power down MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_TRUE);
+ return status;
+#endif
+}
+
+extern kal_bool INT_QueryIsROMSpace(kal_uint32 addr);
+
+static DCL_STATUS DclSD_CtrlCmdWrite(sd_select_enum sel, SD_CTRL_WRITE_T *prWrite)
+{
+#ifdef __MSDC_SD_MMC__
+ DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+ DCL_SDC_CMD_STATUS status=0;
+ DCL_UINT32 u4Sector; //this specify the starting sector to Write
+ DCL_UINT32 u4Sectors; //this specify the number of sectors to Write
+ void *bufferAddr; //we will move move data from this address to the card
+ SDDriver_t *sdDriver;
+
+ /*parameters in prRead should not be changed, take these as local variable*/
+ u4Sector = prWrite->u4Sector;
+ u4Sectors = prWrite->u4Sectors;
+ bufferAddr = prWrite->bufferAddr;
+
+ /*requirement check here*/
+ if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+ //ASSERT(0);
+ status = STATUS_ERROR_WRONG_STATE;
+ return status;
+ }
+
+ maxBlk = gSD_blk[sel].mCSD.capacity/512;
+ /*sectors & sector check*/
+ if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector >= maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ /*check that ending block should be smaller than maximum block number*/
+ if((u4Sector + u4Sectors ) > maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+#if defined(MSDC_CACHED_SUPPORT)
+#if (defined(__UBL__) || defined(__FUE__)) && defined(__EMMC_BOOTING__)
+ MSDC_Blk[sel].isCachedBuf = KAL_TRUE;
+#else
+ /*tell buffer type each time this function called*/
+ if (INT_QueryIsCachedRAM(bufferAddr, u4Sectors * DCL_SECTOR_SIZE)){
+ MSDC_Blk[sel].isCachedBuf = KAL_TRUE;
+ }
+ else
+ MSDC_Blk[sel].isCachedBuf = KAL_FALSE;
+#endif
+#endif
+
+
+ //
+ // To check if data is put on serial flash or nor flash.
+ //
+#ifdef MSDC_CACHED_SUPPORT
+ if (INT_QueryIsROMSpace((kal_uint32)bufferAddr) ||
+ INT_QueryIsROMSpace((kal_uint32)bufferAddr + u4Sectors*0x200)) {
+
+ //MSDC_Blk[sel].isCachedBuf = KAL_TRUE;
+ MSDC_Blk[sel].isRomSpace = KAL_TRUE;
+
+ }
+ else {
+ MSDC_Blk[sel].isRomSpace = KAL_FALSE;
+ }
+#endif
+ /*power on MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_FALSE);
+
+
+
+ sdDriver = sdDriverTable[sel];
+ /*block address or byte address*/
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+ u4Sector = u4Sector;
+ else
+ #endif//defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+ if(u4Sectors > 1)
+ {
+ if((SD20_HCS_CARD==MSDC_Blk[sel].mMSDC_type)
+ || (SD20_LCS_CARD==MSDC_Blk[sel].mMSDC_type)
+ || (SD_CARD == MSDC_Blk[sel].mMSDC_type))
+ sdDriver->setPreEraseCnt(u4Sectors);
+ status = sdDriver->mulBlkWr(u4Sector, bufferAddr, u4Sectors);
+ }
+ else{
+ status = sdDriver->singleBlkWr(u4Sector, bufferAddr);
+ }
+
+ /*power down MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_TRUE);
+
+ return status;
+#endif
+}
+
+
+static DCL_STATUS DclSD_CtrlCmdGpdWrite(sd_select_enum sel, SD_CTRL_GPD_WRITE_T *prWrite)
+{
+ #ifdef __MSDC_SD_MMC__
+ DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+ DCL_SDC_CMD_STATUS status=0;
+ DCL_UINT32 u4Sector; //this specify the starting sector to Write
+ DCL_UINT32 u4Sectors; //this specify the number of sectors to Write
+ SDDriver_t *sdDriver;
+
+ /*parameters in prRead should not be changed, take these as local variable*/
+ u4Sector = prWrite->u4Sector;
+ u4Sectors = prWrite->u4Sectors;
+
+ /*requirement check here*/
+ if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+ //ASSERT(0);
+ status = STATUS_ERROR_WRONG_STATE;
+ return status;
+ }
+
+ maxBlk = gSD_blk[sel].mCSD.capacity/512;
+ /*sectors & sector check*/
+ if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector >= maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ /*check that ending block should be smaller than maximum block number*/
+ if((u4Sector + u4Sectors ) > maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+ status=ConfigGpdList(sel,(qbm_gpd *)(prWrite->bufferHead),(qbm_gpd*)(prWrite->bufferTail),&MSDC_gpd[sel],&MSDC_gpd_end[sel]);
+ if(status !=NO_ERROR)
+ return status;
+ /*power on MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_FALSE);
+
+
+
+ sdDriver = sdDriverTable[sel];
+ /*block address or byte address*/
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+ u4Sector = u4Sector;
+ else
+ #endif//defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+
+ if((SD20_HCS_CARD==MSDC_Blk[sel].mMSDC_type)
+ || (SD20_LCS_CARD==MSDC_Blk[sel].mMSDC_type)
+ || (SD_CARD == MSDC_Blk[sel].mMSDC_type)
+ || (SD30_CARD == MSDC_Blk[sel].mMSDC_type))
+ sdDriver->setPreEraseCnt(u4Sectors);
+ status = sdDriver->GpdMulBlkWr(u4Sector, u4Sectors,&MSDC_gpd[sel]);
+ /*power down MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_TRUE);
+
+ return status;
+#endif
+}
+
+
+#if defined(MSDC_ODD_SUPPORT)
+static DCL_STATUS DclSD_CtrlCmdReadOdd(sd_select_enum sel, SD_CTRL_READ_ODD_T *prRead)
+{
+#ifdef __MSDC_SD_MMC__
+ DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+ DCL_SDC_CMD_STATUS status=0;
+ DCL_UINT32 u4Sector; //this specify the starting sector to read
+ DCL_UINT32 u4Size; //this specify the number of bytes to read
+ void *bufferAddr; //we will move move data from card to this address
+ SDDriver_t *sdDriver;
+
+ /*parameters in prRead should not be changed, take these as local variable*/
+ u4Sector = prRead->u4Sector;
+ u4Size = prRead->u4Size;
+ bufferAddr = prRead->bufferAddr;
+
+ /*requirement check here*/
+ if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+ //ASSERT(0);
+ status = STATUS_ERROR_WRONG_STATE;
+ return status;
+ }
+
+ maxBlk = gSD_blk[sel].mCSD.capacity/512;
+ /*sectors & sector check*/
+ if(0 == u4Size || u4Size > 512 || u4Sector >= maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ /*power on MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_FALSE);
+
+
+
+ sdDriver = sdDriverTable[sel];
+
+ /*set block length to u4Size*/
+ SD_SetBlength(u4Size);
+
+ /*block address or byte address*/
+ if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+ u4Sector = u4Sector;
+ else
+ u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+ if(u4Size > 1)
+ {
+ ASSERT(0);
+ }
+ else{
+ status = sdDriver->singleBlkRd(u4Sector, bufferAddr);
+ }
+
+ /*set the block length back to 512*/
+ SD_SetBlength(DCL_SECTOR_SIZE);
+
+ /*power down MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_TRUE);
+
+ return status;
+#endif
+}
+
+static DCL_STATUS DclSD_CtrlCmdWriteOdd(sd_select_enum sel, SD_CTRL_WRITE_ODD_T *prWrite)
+{
+#ifdef __MSDC_SD_MMC__
+ DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+ DCL_SDC_CMD_STATUS status=0;
+ DCL_UINT32 u4Sector; //this specify the starting sector to Write
+ DCL_UINT32 u4Size; //this specify the number of bytes to Write
+ void *bufferAddr; //we will move move data from this address to the card
+ SDDriver_t *sdDriver;
+
+ /*parameters in prRead should not be changed, take these as local variable*/
+ u4Sector = prWrite->u4Sector;
+ u4Size = prWrite->u4Size;
+ bufferAddr = prWrite->bufferAddr;
+
+ /*requirement check here*/
+ if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+ //ASSERT(0);
+ status = STATUS_ERROR_WRONG_STATE;
+ return status;
+ }
+
+ maxBlk = gSD_blk[sel].mCSD.capacity/512;
+ /*sectors & sector check*/
+ if(0 == u4Size || u4Size > 512 || u4Sector >= maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ /*power on MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_FALSE);
+
+
+
+ sdDriver = sdDriverTable[sel];
+ /*set block length to u4Size*/
+ SD_SetBlength(u4Size);
+
+ /*block address or byte address*/
+ if(gSD_blk[sel].flags & (SD_FLAG_HCS_SUPPORT|SD_FLAG_UHS_SUPPORT))
+ u4Sector = u4Sector;
+ else
+ u4Sector = u4Sector * DCL_SECTOR_SIZE;
+
+ if(u4Size > 512)
+ {
+ ASSERT(0);
+ }
+ else{
+ status = sdDriver->singleBlkWr(u4Sector, bufferAddr);
+ SD_WriteSingleBlock(u4Sector, bufferAddr);
+ }
+
+ /*set the block length back to 512*/
+ SD_SetBlength(DCL_SECTOR_SIZE);
+
+ /*power down MSDC module*/
+ msdcDriverTable[sel].modulePDN(KAL_TRUE);
+
+ return status;
+#endif
+}
+#endif
+/***************************************************************************************
+followings are DCL SD API exported
+*****************************************************************************************/
+/*************************************************************************
+* FUNCTION
+* DclSD_Initialize
+*
+* DESCRIPTION
+* This function is to initialize the SD driver related resource.
+* This function should be called in system initialization before tasks are scheduling.
+*
+* PARAMETERS
+* N/A
+*
+* RETURNS
+* STATUS_OK : this should be the only return value since MSDC_initialize returns nothing.
+*
+*************************************************************************/
+DCL_STATUS DclSD_Initialize(void)
+{
+ kal_uint32 maskedValue;
+
+ maskedValue = SaveAndSetIRQMask();
+ /*a sync mechanism to guarantee MSDC_Initialize is only called once*/
+ if(KAL_FALSE == fgMSDCInit){
+ fgMSDCInit = KAL_TRUE;
+ RestoreIRQMask(maskedValue);
+ DclMSDC_init();
+ }
+ else{
+ RestoreIRQMask(maskedValue);
+ }
+
+
+ maskedValue = SaveAndSetIRQMask();
+ if(KAL_FALSE == fgSDInit){
+ fgSDInit = KAL_TRUE;
+ RestoreIRQMask(maskedValue);
+ /*init SD driver tables, there are too many entries in SD driver, so we hook it by pointer*/
+#ifdef __MSDC_SD_MMC__
+ sdDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SD1)] = &sd_driver_MTK1;
+#endif
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sdDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SIMPLUS)] = &sd_driver_MTK1; //in the design, sel = 2 is preserved for SIM+ card, which uses 1st MSDC's code
+#endif
+
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+ sdDriverTable[DCL_SD_GET_SEL_FROM_HANDLE(DCL_SD_HANDLE_SD2)] = &sd_driver_MTK2;
+#endif
+ }
+ else{
+ RestoreIRQMask(maskedValue);
+ }
+
+ return STATUS_OK;
+}
+
+#if (defined(__UBL__) || defined(__FUE__)) && defined(__CARD_DOWNLOAD__)
+DCL_STATUS DclSD_DeInitialize(void)
+{
+ fgMSDCInit = KAL_FALSE;
+ fgSDInit = KAL_FALSE;
+ #if defined(__MSDC_SD_SDIO__)
+ fgSDIOInit = KAL_FALSE;
+ #endif
+ #if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
+ fgMSInit = KAL_FALSE;
+ #endif
+
+ MSDC_DeInit();
+
+ return STATUS_OK;
+}
+#endif
+
+/*************************************************************************
+* FUNCTION
+* DclSD_Initialize
+*
+* DESCRIPTION
+* This function is to get SD DCL handler.
+*
+* PARAMETERS
+* eDev - only valid for DCL_SD.
+* flags -following bit stand for specific meaning.
+* DCL_SD_FLAGS_CARD1: to get a handle for card 1
+* DCL_SD_FLAGS_CARD2: to get a handle for card 2
+* DCL_SD_FLAGS_SIMPLUS: to get a handle for sim plus
+* Other values are prohibited
+* RETURNS
+* DCL_HANDLE_INVALID - Open failed.
+* other value - a valid handle
+*
+*************************************************************************/
+DCL_HANDLE DclSD_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+ if (dev != DCL_SD)
+ {
+ ASSERT(0);
+ return DCL_HANDLE_INVALID;
+ }
+
+ /* Return Invalid handle directly if it is SYS_INIT phase */
+ if (KAL_TRUE == kal_query_systemInit())
+ return DCL_HANDLE_INVALID;
+
+ if(flags & DCL_SD_FLAGS_DEVICE_CARD1){
+ if(DCL_SD_FLAGS_DEVICE_CARD1 != (flags & DCL_SD_FLAGS_DEVICE_ALL)){
+ ASSERT(0);
+ }
+ if(flags & DCL_SD_FLAGS_USAGE_CMD){/*wanna get handle to control MSDC1, need contention for action handle*/
+ kal_uint16 magic;
+
+ //
+ // To prevent resource to be occupied twice, use semaphore to gate here.
+ //
+ get_MSDC_lock(&dclMsdcLock[0]);
+ /*
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_take_sem(dclMsdcArb[0], 1);
+
+ // from here, we are the only one gets CMD right to MSDC1, but check the maic first
+ if(sdResource[0] & DCL_SD_RESOURCE_OCCUPIED)
+ ASSERT(0);
+ }
+ */
+
+ /*process the magic of the resource as rolling counter*/
+ magic = (sdResource[0] & DCL_SD_RESOURCE_MAGIC_MAX);
+ if(DCL_SD_RESOURCE_MAGIC_MAX == magic) /*if means 0x0FF0 achieved*/
+ magic = DCL_SD_RESOURCE_MAGIC_UNIT;
+ else
+ magic += DCL_SD_RESOURCE_MAGIC_UNIT;
+
+ sdResource[0] = (DCL_SD_RESOURCE_OCCUPIED | magic);
+
+ return (DCL_SD_HANDLE_SD1 | magic);
+ }
+ else{/*just wanna get handle to get information of this device, return handle directly*/
+ return DCL_SD_HANDLE_SD1;
+ }
+ }
+ else if(flags & DCL_SD_FLAGS_DEVICE_CARD2){
+#if defined(__MSDC2_SD_MMC__)
+ if(DCL_SD_FLAGS_DEVICE_CARD2 != (flags & DCL_SD_FLAGS_DEVICE_ALL)){
+ ASSERT(0);
+ }
+ if(flags & DCL_SD_FLAGS_USAGE_CMD){/*wanna get handle to control MSDC2, need contention action handle*/
+ kal_uint16 magic;
+
+ //
+ // The same as MSDC1.
+ //
+ get_MSDC_lock(&dclMsdcLock[1]);
+ /*
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_take_sem(dclMsdcArb[1], 1);
+
+ // from here, we are the only one gets CMD right to MSDC2, but check the maic first
+ if(sdResource[1] & DCL_SD_RESOURCE_OCCUPIED)
+ ASSERT(0);
+ }
+ */
+
+ /*process the magic of the resource as rolling counter*/
+ magic = (sdResource[1] & DCL_SD_RESOURCE_MAGIC_MAX);
+ if(DCL_SD_RESOURCE_MAGIC_MAX == magic) /*if means 0x0FF0 achieved*/
+ magic = DCL_SD_RESOURCE_MAGIC_UNIT;
+ else
+ magic += DCL_SD_RESOURCE_MAGIC_UNIT;
+
+ sdResource[1] = (DCL_SD_RESOURCE_OCCUPIED | magic);
+
+ return (DCL_SD_HANDLE_SD2 | magic);
+ }
+ else{/*just wanna get handle to get information of this device, return handle directly*/
+ return DCL_SD_HANDLE_SD2;
+ }
+#else
+ ASSERT(0);
+ return 0;
+#endif
+ }
+
+ return 0;
+}
+
+DCL_STATUS DclSD_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+ ASSERT(0);
+ return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSD_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+ ASSERT(0);
+ return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSD_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+ DCL_SD_IMPLEMENTATION_ASSERT;
+ return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSD_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+ ASSERT(0);
+ return STATUS_UNSUPPORTED;
+}
+
+#define DCL_MSDC_FUNTION_TABLE
+#ifdef DCL_MSDC_FUNTION_TABLE
+
+#ifdef __MSDC_SD_MMC__
+typedef DCL_STATUS (*DCL_SD_CTRL_API) (DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data);
+
+
+DCL_STATUS DCL_SD_CTRL_API_READ(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status=0;
+ SD_CTRL_READ_T *prRead;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prRead = &(data->rSDRead);
+ status = DclSD_CtrlCmdRead(sel, prRead);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+
+ return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_WRITE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status=0;
+ SD_CTRL_WRITE_T *prWrite;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prWrite = &(data->rSDWrite);
+ status = DclSD_CtrlCmdWrite(sel, prWrite);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+
+ return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_READ_ODD_SIZE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status=0;
+#if defined(MSDC_ODD_SUPPORT)
+ SD_CTRL_READ_ODD_T *prRead;
+ sd_select_enum sel;
+
+ /*currently we only support on SD1, check it*/
+ if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+ ASSERT(0);
+ }
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prRead = &(data->rSDReadOdd);
+ status = DclSD_CtrlCmdReadOdd(sel, prRead);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+#else
+ ASSERT(0);
+#endif
+ return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_WRITE_ODD_SIZE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status=0;
+#if defined(MSDC_ODD_SUPPORT)
+ SD_CTRL_WRITE_ODD_T *prWrite;
+ sd_select_enum sel;
+
+ /*currently we only support on SD1, check it*/
+ if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+ ASSERT(0);
+ }
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prWrite = &(data->rSDWriteOdd);
+ status = DclSD_CtrlCmdWriteOdd(sel, prWrite);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+#else
+ ASSERT(0);
+#endif
+
+ return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_INIT(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status=0;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ if (DCL_SD_HANDLE_SD1 == DCL_SD_GET_DUMMY_HANDLE(handle)
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ || DCL_SD_HANDLE_SIMPLUS == DCL_SD_GET_DUMMY_HANDLE(handle)
+#endif
+#if defined(__MSDC2_SD_MMC__)
+ || DCL_SD_HANDLE_SD2 == DCL_SD_GET_DUMMY_HANDLE(handle)
+#endif
+ )
+ {
+ msdcDriverTable[sel].modulePDN(KAL_FALSE);
+ status = sdDriverTable[sel]->sdInititalize();
+ msdcDriverTable[sel].modulePDN(KAL_TRUE);
+ }
+ else{
+ ASSERT(0);
+ }
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+
+
+ return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_IS_INITED(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ SD_CTRL_INITED_T *prInited;
+ sd_select_enum sel;
+
+ prInited = &(data->rSDInited);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ prInited->fgInited = MSDC_Blk[sel].mIsInitialized;
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_ANALOG_SWITCH(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status;
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ SD_CTRL_ANALOG_SWITCH_T *prSwitch;
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prSwitch = &(data->rSDSwitch);
+ sel = prSwitch->u4TargetInterface;
+ MSDC_Switch_Card(sel);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+
+ status = NO_ERROR;
+#else
+ ASSERT(0);
+ status = STATUS_INVALID_CMD;
+#endif
+
+ return status;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_FAST_FORMAT_START(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ sd_select_enum sel;
+
+ /*currently we only support fast format on SD1, check it*/
+ if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+ ASSERT(0);
+ }
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+#ifdef __MSDC_SD_MMC__
+ SD_startFastFormat();
+#endif
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_FAST_FORMAT_STOP(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ sd_select_enum sel;
+
+ /*currently we only support fast format on SD1, check it*/
+ if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+ ASSERT(0);
+ }
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+#ifdef __MSDC_SD_MMC__
+ SD_closeFastFormat();
+#endif
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_IS_FAST_FORMAT_RUNNING(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ SD_CTRL_FAST_FORMAT_T *ff = &(data->rSDFastFormat);
+ sd_select_enum sel;
+
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+#ifdef __DRV_MSDC_FAST_FORMAT__
+ ff->enable = (DCL_BOOL)MSDC_Blk[sel].MSDC_fastFormat;
+#endif
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_GET_CAPACITY(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ SD_CTRL_GET_CAPACITY_T *prGetCapacity;
+ sd_select_enum sel;
+
+ prGetCapacity = &(data->rSDGetCapacity);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ prGetCapacity->pu8Capacity = gSD_blk[sel].mCSD.capacity;
+ prGetCapacity->gHighCapacityCard = SD_FLAG_HCS_SUPPORT ? KAL_TRUE:KAL_FALSE;
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_IS_EXISTENCE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ SD_CTRL_EXISTENCE_T *prExistence;
+ sd_select_enum sel;
+/*this function differs to SD_CTRL_CMD_POLL_EXISTENCE, we only get status from global variables*/
+ prExistence = &(data->rSDExistence);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ prExistence->fgPresent = MSDC_Blk[sel].mIsPresent;
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_POLL_EXISTENCE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+// DCL_SDC_CMD_STATUS status;
+ SD_CTRL_EXISTENCE_T *prPollExistence;
+ sd_select_enum sel;
+
+ /*this function differs to SD_CTRL_CMD_IS_EXISTENCE, we will get card's status again*/
+
+ /*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__
+ if (DCL_SD_HANDLE_SIMPLUS == handle){
+ ASSERT(0);
+ }
+#endif
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prPollExistence = &(data->rSDExistence);
+ if (SD_MSDC1 == sel
+#if defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ || SD_T_CARD_2 == sel
+#endif
+ )
+ {
+ prPollExistence->fgPresent = DclSD_PollExistence(MD_IRQID_MSDC0, MSDC_PS, sel);
+ }
+#if defined(__MSDC2_SD_MMC__)
+ if (SD_MSDC2 == sel){
+ prPollExistence->fgPresent = DclSD_PollExistence(MD_IRQID_MSDC1, MSDC_PS2, sel);
+ }
+#endif
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_SET_CLEAR_EXISTENCE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ SD_CTRL_EXISTENCE_T *prExistence;
+ sd_select_enum sel;
+
+ prExistence = &(data->rSDExistence);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ MSDC_Blk[sel].mIsPresent =(kal_bool)prExistence->fgPresent;
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_WRITE_PROTECTION(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ SD_CTRL_WRITE_PROTECTION_T *prWP;
+ sd_select_enum sel;
+
+ prWP = &(data->rSDWriteProrect);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ prWP->fgReadOnly = gSD_blk[sel].mWPEnabled;
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_QUERY_EVER_PLUGOUT(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ SD_CTRL_QUERY_EVER_PLUGOUT_T *prQueryPlugOut;
+ sd_select_enum sel;
+
+ /*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__
+ if(DCL_SD_HANDLE_SIMPLUS == handle){
+ ASSERT(0);
+ }
+#endif
+
+ prQueryPlugOut = &(data->rSDQueryEverPugOut);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ prQueryPlugOut->fgEverPLugOut = MSDC_Blk[sel].MSDC_everPlugOut;
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_RESET_EVER_PLUGOUT(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+// DCL_SDC_CMD_STATUS status;
+ sd_select_enum sel;
+
+ /*everPLugOut is set true in hot plug interrupt and DCL provide function to set false*/
+
+ /*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__
+ if(DCL_SD_HANDLE_SIMPLUS == handle){
+ ASSERT(0);
+ }
+#endif
+
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ MSDC_Blk[sel].MSDC_everPlugOut = KAL_FALSE;
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_FORCE_SINGLE_LINE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ SD_CTRL_FORCE_SINGLE_LINE_T *prForceSingleLine;
+ sd_select_enum sel;
+
+ /*SIM_PLUS only runs in single line*/
+#ifdef __SIM_PLUS__
+ if(DCL_SD_HANDLE_SIMPLUS != handle){
+ ASSERT(0);
+ }
+#endif
+
+ /*should add a assertion check for the MSDC that only support single line mode*/
+ prForceSingleLine = &(data->rSDForceSingleLine);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ MSDC_Blk[sel].trySingleLine = (kal_bool)prForceSingleLine->fgIsItTrue;
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_GO_IDLE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ sd_select_enum sel;
+
+ /*This function is to set global state mIsInitialized = false, it is only driver can set it to true*/
+
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ MSDC_Blk[sel].mIsInitialized = KAL_FALSE;
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_CACHEABLE_BUFFER(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+#ifdef MSDC_CACHED_SUPPORT
+ SD_CTRL_CACHEABLE_BUFFER_T *prCachedBuffer;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prCachedBuffer = &(data->rSDCacheableBuf);
+ MSDC_Blk[sel].isCachedBuf = prCachedBuffer->fgIsCACHEABLE;
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+#endif
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_SET_READ_FLAG(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status;
+ sd_select_enum sel;
+ SD_CTRL_SET_READ_TEST_FLAG_T *readFlag;
+
+ readFlag =&(data->rSDSetReadTestFlag);
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+ status = sdDriverTable[sel]->sdSetReadTestFlag(readFlag->readTestFlag);
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ return status;
+
+}
+DCL_STATUS DCL_SD_CTRL_API_SET_READ_TEST(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+
+ DCL_SDC_CMD_STATUS status;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+ msdcDriverTable[sel].modulePDN(KAL_FALSE);
+ status = sdDriverTable[sel]->sdSetReadTest();
+ msdcDriverTable[sel].modulePDN(KAL_TRUE);
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ return status;
+
+}
+DCL_STATUS DCL_SD_CTRL_API_SET_UPLL_CLOCK(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+
+ DCL_SDC_CMD_STATUS status;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+ //msdcDriverTable[sel].modulePDN(KAL_FALSE);
+ status = sdDriverTable[sel]->sdSetUpllClock();
+ //msdcDriverTable[sel].modulePDN(KAL_TRUE);
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ return status;
+
+}
+DCL_STATUS DCL_SD_CTRL_API_SET_CALLBACK(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status;
+ SD_CTRL_CALLBACK_T *callBack;
+ sd_select_enum sel;
+
+ callBack =&(data->rSDCallBackFunc);
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+ status = sdDriverTable[sel]->sdSetCallBack(callBack->callback1,callBack->callback2,callBack->callback3,callBack->callback4,callBack->callback5,callBack->callback6);
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ return status;
+}
+DCL_STATUS DCL_SD_CTRL_API_FLUSH_SECTORS(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status;
+ SD_CTRL_FLUSH_T *flush;
+ sd_select_enum sel;
+
+ flush =&(data->rSDFlush);
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+ status = sdDriverTable[sel]->eraseBlk(flush->startSector,flush->sectorNum);
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ return status;
+}
+DCL_STATUS DCL_SD_CTRL_API_GET_AND_CLEAR_MEDIA_CHANGED(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+// DCL_SDC_CMD_STATUS status;
+ SD_CTRL_MEDIA_CHANGED_T *changed;
+ sd_select_enum sel;
+
+ changed = &(data->rSDMediaChanged);
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+ changed->changed = MSDC_GetMediaChanged(sel);
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ return STATUS_OK;
+}
+
+DCL_STATUS DCL_SD_CTRL_API_GPD_READ(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status=0;
+ SD_CTRL_GPD_READ_T *prRead;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prRead = &(data->rSDReadGPD);
+ status = DclSD_CtrlCmdGpdRead(sel, prRead);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+
+ return status;
+}
+DCL_STATUS DCL_SD_CTRL_API_GPD_WRITE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status=0;
+ SD_CTRL_GPD_WRITE_T *prWrite;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prWrite = &(data->rSDWriteGPD);
+ status = DclSD_CtrlCmdGpdWrite(sel, prWrite);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+
+ return status;
+}
+DCL_STATUS DCL_SD_CTRL_API_GET_BD_STRUCT_NUM(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ SD_CTRL_MAX_BD_STRUCT_NUM_T *prNum;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prNum = &(data->rSDMaxBD);
+
+ prNum->max_bd_num=MSDC_BD_MAX;
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ return STATUS_OK;
+}
+DCL_SD_CTRL_API DclSD_APITbl[SD_CTRL_CMD_DUMMY_END - SD_CTRL_CMD_BASE] =
+{
+ DCL_SD_CTRL_API_READ,
+ DCL_SD_CTRL_API_WRITE,
+ DCL_SD_CTRL_API_READ_ODD_SIZE,
+ DCL_SD_CTRL_API_WRITE_ODD_SIZE,
+ DCL_SD_CTRL_API_INIT,
+ DCL_SD_CTRL_API_IS_INITED,
+ DCL_SD_CTRL_API_ANALOG_SWITCH,
+ DCL_SD_CTRL_API_FAST_FORMAT_START,
+ DCL_SD_CTRL_API_FAST_FORMAT_STOP,
+ DCL_SD_CTRL_API_IS_FAST_FORMAT_RUNNING,
+ DCL_SD_CTRL_API_GET_CAPACITY,
+ DCL_SD_CTRL_API_IS_EXISTENCE,
+ DCL_SD_CTRL_API_POLL_EXISTENCE,
+ DCL_SD_CTRL_API_SET_CLEAR_EXISTENCE,
+ DCL_SD_CTRL_API_WRITE_PROTECTION,
+ DCL_SD_CTRL_API_QUERY_EVER_PLUGOUT,
+ DCL_SD_CTRL_API_RESET_EVER_PLUGOUT,
+ DCL_SD_CTRL_API_FORCE_SINGLE_LINE,
+ DCL_SD_CTRL_API_GO_IDLE,
+ DCL_SD_CTRL_API_CACHEABLE_BUFFER,
+ DCL_SD_CTRL_API_SET_CALLBACK,
+ DCL_SD_CTRL_API_SET_READ_FLAG,
+ DCL_SD_CTRL_API_SET_READ_TEST,
+ DCL_SD_CTRL_API_SET_UPLL_CLOCK,
+ DCL_SD_CTRL_API_FLUSH_SECTORS,
+ DCL_SD_CTRL_API_GET_AND_CLEAR_MEDIA_CHANGED,
+ DCL_SD_CTRL_API_GPD_READ,
+ DCL_SD_CTRL_API_GPD_WRITE,
+ DCL_SD_CTRL_API_GET_BD_STRUCT_NUM,
+};
+#endif
+
+// for debugging
+DCL_CTRL_CMD_T dcl_sd_cmd_start = SD_CTRL_CMD_BASE;
+DCL_CTRL_CMD_T dcl_sd_cmd_end = SD_CTRL_CMD_DUMMY_END;
+DCL_STATUS DclSD_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+#ifdef __MSDC_SD_MMC__
+
+ DCL_SDC_CMD_STATUS status = 0;
+
+ // Mark here because we use dclsd_open to take semaphore.
+ /*
+ //dispatch
+ if (SD_CTRL_CMD_DUMMY_END > cmd && SD_CTRL_CMD_BASE <= cmd){
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ if (DCL_SD_HANDLE_SD1 == DCL_SD_GET_DUMMY_HANDLE(handle))
+ //kal_take_sem(dclMsdcArb[0], 1);
+ get_MSDC_lock(&dclMsdcLock[0]);
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+ else if (DCL_SD_HANDLE_SD2 == DCL_SD_GET_DUMMY_HANDLE(handle))
+ //kal_take_sem(dclMsdcArb[1], 1);
+ get_MSDC_lock(&dclMsdcLock[1]);
+#endif
+ }
+ */
+
+ #if 0
+/* under construction !*/
+ #else
+ status = DclSD_APITbl[cmd - SD_CTRL_CMD_BASE](handle, cmd, data);
+ #endif
+
+ // Remove give semaphore, we move it to dclsd_close.
+ /*
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ if (DCL_SD_HANDLE_SD1 == DCL_SD_GET_DUMMY_HANDLE(handle))
+ //kal_give_sem(dclMsdcArb[0]);
+ free_MSDC_lock(&dclMsdcLock[0]);
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+ else if (DCL_SD_HANDLE_SD2 == DCL_SD_GET_DUMMY_HANDLE(handle))
+ //kal_give_sem(dclMsdcArb[1]);
+ free_MSDC_lock(&dclMsdcLock[1]);
+#endif
+ }
+
+ }
+ else{
+ ASSERT(0);
+ status = STATUS_INVALID_CMD;
+ }
+ */
+
+ /*status central wrapper here, this is an inefficient but readable way*/
+ switch(status){
+ case NO_ERROR:
+ return STATUS_OK;
+ //break;
+ case ERR_CMD_TIMEOUT:/*fall through*/
+ return STATUS_ERROR_TIMEOUT;
+ //break;
+ case ERR_DAT_CRCERR:
+ case ERR_CMD_RSPCRCERR:
+ return STATUS_ERROR_CRCERROR;
+ // break;
+ case ERR_WRITE_PROTECT:
+ return STATUS_ERROR_READONLY;
+ // break;
+ default:
+ //ASSERT(0);
+ return status;
+ //return STATUS_ERROR_WRONG_STATE;
+ // break;
+ }
+
+ /*should not arrive here*/
+ ASSERT(0);
+ return STATUS_FAIL;
+
+#endif//__MSDC_SD_MMC__
+}
+
+#else//DCL_MSDC_FUNTION_TABLE
+
+/*************************************************************************
+* FUNCTION
+* DclSD_Control
+*
+* DESCRIPTION
+* This function is to send command to control the GPIO module.
+*
+* PARAMETERS
+* handle - a valid handle return by DclGPIO_Open()
+* cmd - a control command for GPIO module
+* 1. GPIO_CMD_READ: to read the input value of a GPIO port (high/low)
+* 2. GPIO_CMD_WRITE: to write to the output of a GPIO port (high/low)
+* 3. GPIO_CMD_SET_MODE: to set the mode of a GPIO port
+* 4. GPIO_CMD_SET_DIR: to set the direction of a GPIO port
+* 5. GPIO_CMD_RETURN_MODE: to get the mode of a GPIO port
+* 6. GPIO_CMD_RETURN_DIR: to get the direction of a GPIO port
+* 7. GPIO_CMD_RETURN_OUT: to return the output value of a GPIO port
+* 8. GPIO_CMD_ENABLE_PULL: to enable the pull resister for a GPIO port
+* 9. GPIO_CMD_SEL_PULL: to select the pull up or pull down for a GPIO port
+* 10. GPIO_CMD_SET_DINV: to set the inversion of a GPIO port
+* 11. GPIO_CMD_SET_DEBUG: to enable or disable debug mode
+* 12. GPIO_CMD_SET_CLK_OUT: to set the clock frequency for a clock output
+* 13. GPIO_CMD_SET_TM_DIR: to set TM direction
+* data - for 1. GPIO_CMD_READ: pointer to a HGPT_CTRL_CLK_T structure
+* 2. GPIO_CMD_WRITE: pointer to a HGPT_CTRL_RESET_T structure
+* 3. GPIO_CMD_SET_MODE: pointer to a GPIO_CTRL_SET_MODE_T structure
+* 4. GPIO_CMD_SET_DIR: pointer to a GPIO_CTRL_SET_DIR_T structure
+* 5. GPIO_CMD_RETURN_MODE: pointer to a GPIO_CTRL_RETURN_MODE_T structure
+* 6. GPIO_CMD_RETURN_DIR: pointer to a GPIO_CTRL_RETURN_DIR_T structure
+* 7. GPIO_CMD_RETURN_OUT: pointer to a GPIO_CTRL_RETURN_OUT_T structure
+* 8. GPIO_CMD_ENABLE_PULL: pointer to a GPIO_CTRL_ENABLE_PULL_T structure
+* 9. GPIO_CMD_SEL_PULL: pointer to a GPIO_CTRL_SEL_PULL_T structure
+* 10. GPIO_CMD_SET_DINV: pointer to a GPIO_CTRL_SET_DINV_T structure
+* 11. GPIO_CMD_SET_DEBUG: pointer to a GPIO_CTRL_SET_DEBUG_T structure
+* 12. GPIO_CMD_SET_CLK_OUT: pointer to a GPIO_CTRL_SET_CLK_OUT_T structure
+* 13. GPIO_CMD_SET_TM_DIR: pointer to a GPIO_CTRL_SET_TM_DIR_T structure
+*
+* RETURNS
+* STATUS_OK - command is executed successfully.
+* STATUS_FAIL - command is failed.
+* STATUS_INVALID_CMD - The command is invalid.
+* STATUS_INVALID_HANDLE - The handle is invalid.
+* STATUS_INVALID_CTRL_DATA - The ctrl data is not valid.
+*************************************************************************/
+DCL_STATUS DclSD_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_SDC_CMD_STATUS status;
+
+ switch(cmd){
+ case SD_CTRL_CMD_READ:
+ {
+ SD_CTRL_READ_T *prRead;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prRead = &(data->rSDRead);
+ status = DclSD_CtrlCmdGpdRead(sel, prRead);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ break;
+ }
+ case SD_CTRL_CMD_WRITE:
+ {
+ SD_CTRL_WRITE_T *prWrite;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prWrite = &(data->rSDWrite);
+ status = DclSD_CtrlCmdGpdWrite(sel, prWrite);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ break;
+ }
+ case SD_CTRL_CMD_READ_ODD_SIZE:
+ {
+ SD_CTRL_READ_ODD_T *prRead;
+ sd_select_enum sel;
+
+ /*currently we only support on SD1, check it*/
+ if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+ ASSERT(0);
+ }
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prRead = &(data->rSDReadOdd);
+ status = DclSD_CtrlCmdReadOdd(sel, prRead);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ break;
+ }
+ case SD_CTRL_CMD_WRITE_ODD_SIZE:
+ {
+ SD_CTRL_WRITE_ODD_T *prWrite;
+ sd_select_enum sel;
+
+ /*currently we only support on SD1, check it*/
+ if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+ ASSERT(0);
+ }
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prWrite = &(data->rSDWriteOdd);
+ status = DclSD_CtrlCmdWriteOdd(sel, prWrite);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ break;
+ }
+
+ case SD_CTRL_CMD_INIT:
+ {
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ if (DCL_SD_HANDLE_SD1 == DCL_SD_GET_DUMMY_HANDLE(handle)
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ || DCL_SD_HANDLE_SIMPLUS == DCL_SD_GET_DUMMY_HANDLE(handle)
+#endif
+#if defined(__MSDC2_SD_MMC__)
+ || DCL_SD_HANDLE_SD2 == DCL_SD_GET_DUMMY_HANDLE(handle)
+#endif
+ )
+ {
+ msdcDriverTable[sel].modulePDN(KAL_FALSE);
+ status = sdDriverTable[sel]->sdInititalize();
+ msdcDriverTable[sel].modulePDN(KAL_TRUE);
+ }
+ else{
+ ASSERT(0);
+ }
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ break;
+ }
+ case SD_CTRL_CMD_ANALOG_SWITCH:
+ {
+
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ SD_CTRL_ANALOG_SWITCH_T *prSwitch;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prSwitch = &(data->rSDSwitch);
+ sel = prSwitch->u4TargetInterface;
+ MSDC_Switch_Card(sel);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+
+ status = NO_ERROR;
+#else
+ ASSERT(0);
+ status = STATUS_INVALID_CMD;
+#endif
+ break;
+ }
+ case SD_CTRL_CMD_FAST_FORMAT_START:
+ {
+ sd_select_enum sel;
+
+ /*currently we only support fast format on SD1, check it*/
+ if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+ ASSERT(0);
+ }
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ SD_startFastFormat();
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ status = NO_ERROR;
+ break;
+ }
+ case SD_CTRL_CMD_FAST_FORMAT_STOP:
+ {
+ sd_select_enum sel;
+
+ /*currently we only support fast format on SD1, check it*/
+ if(DCL_SD_HANDLE_SD1 != DCL_SD_GET_DUMMY_HANDLE(handle)){
+ ASSERT(0);
+ }
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ SD_closeFastFormat();
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ status = NO_ERROR;
+ break;
+ }
+ case SD_CTRL_CMD_GET_CAPACITY:
+ {
+ SD_CTRL_GET_CAPACITY_T *prGetCapacity;
+ sd_select_enum sel;
+
+ prGetCapacity = &(data->rSDGetCapacity);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ prGetCapacity->pu8Capacity = gSD_blk[sel].mCSD.capacity;
+ prGetCapacity->gHighCapacityCard = SD_FLAG_HCS_SUPPORT ? KAL_TRUE:KAL_FALSE;
+ status = STATUS_OK;
+ break;
+ }
+ case SD_CTRL_CMD_IS_EXISTENCE: /*this function differs to SD_CTRL_CMD_POLL_EXISTENCE, we only get status from global variables*/
+ {
+ SD_CTRL_EXISTENCE_T *prExistence;
+ sd_select_enum sel;
+
+ prExistence = &(data->rSDExistence);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ prExistence->fgPresent = MSDC_Blk[sel].mIsPresent;
+ status = STATUS_OK;
+ break;
+ }
+ case SD_CTRL_CMD_POLL_EXISTENCE: /*this function differs to SD_CTRL_CMD_IS_EXISTENCE, we will get card's status again*/
+ {
+ SD_CTRL_EXISTENCE_T *prPollExistence;
+ sd_select_enum sel;
+
+ /*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__
+ if(DCL_SD_HANDLE_SIMPLUS == handle){
+ ASSERT(0);
+ }
+#endif
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+
+ prPollExistence = &(data->rSDExistence);
+ if(SD_MSDC1 == sel
+#if defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ || SD_T_CARD_2 == sel
+#endif
+ )
+ {
+ prPollExistence->fgPresent = DclSD_PollExistence(MD_IRQID_MSDC0, MSDC_PS, sel);
+ }
+#if defined(DRV_MSDC_MT6238_SERIES)
+ if(SD_MSDC2 == sel){
+ prPollExistence->fgPresent = DclSD_PollExistence(MD_IRQID_MSDC1, MSDC_PS2, sel);
+ }
+#endif
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ status = STATUS_OK;
+ break;
+ }
+ case SD_CTRL_CMD_SET_CLEAR_EXISTENCE:
+ {
+ SD_CTRL_EXISTENCE_T *prExistence;
+ sd_select_enum sel;
+
+ prExistence = &(data->rSDExistence);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ MSDC_Blk[sel].mIsPresent = prExistence->fgPresent;
+ status = STATUS_OK;
+ break;
+ }
+ case SD_CTRL_CMD_WRITE_PROTECTION:
+ {
+ SD_CTRL_WRITE_PROTECTION_T *prWP;
+ sd_select_enum sel;
+
+ prWP = &(data->rSDWriteProrect);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ *(prWP->fgReadOnly) = gSD_blk[sel].mWPEnabled;
+ status = STATUS_OK;
+ break;
+ }
+ case SD_CTRL_CMD_QUERY_EVER_PLUGOUT:
+ {
+ SD_CTRL_QUERY_EVER_PLUGOUT_T *prQueryPlugOut;
+ sd_select_enum sel;
+
+ /*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__
+ if(DCL_SD_HANDLE_SIMPLUS == handle){
+ ASSERT(0);
+ }
+#endif
+
+ prQueryPlugOut = &(data->rSDQueryEverPugOut);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ *(prQueryPlugOut->fgEverPLugOut) = gMSDC_Handle->MSDC_everPlugOut;
+ status = STATUS_OK;
+ break;
+ }
+ case SD_CTRL_CMD_RESET_EVER_PLUGOUT: /*everPLugOut is set true in hot plug interrupt and DCL provide function to set false*/
+ {
+ sd_select_enum sel;
+
+ /*we don't support hot plug of SIM+ , so hot plug related functions are prohibited*/
+#ifdef __SIM_PLUS__
+ if(DCL_SD_HANDLE_SIMPLUS == handle){
+ ASSERT(0);
+ }
+#endif
+
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ MSDC_Blk[sel].MSDC_everPlugOut = KAL_FALSE;
+ status = STATUS_OK;
+ break;
+ }
+ case SD_CTRL_CMD_FORCE_SINGLE_LINE: /*this function can be the last way to bring up a card with lower throughput*/
+ {
+ SD_CTRL_FORCE_SINGLE_LINE_T *prForceSingleLine;
+ sd_select_enum sel;
+
+ /*SIM_PLUS only runs in single line*/
+#ifdef __SIM_PLUS__
+ if(DCL_SD_HANDLE_SIMPLUS != handle){
+ ASSERT(0);
+ }
+#endif
+
+ /*should add a assertion check for the MSDC that only support single line mode*/
+ prForceSingleLine = &(data->rSDForceSingleLine);
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ MSDC_Blk[sel].trySingleLine = prForceSingleLine->fgIsItTrue;
+ status = STATUS_OK;
+ break;
+ }
+ case SD_CTRL_CMD_GO_IDLE: /*This function is to set global state mIsInitialized = false, it is only driver can set it to true*/
+ {
+ sd_select_enum sel;
+
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ MSDC_Blk[sel].mIsInitialized = KAL_FALSE;
+ status = STATUS_OK;
+ break;
+ }
+#ifdef MSDC_CACHED_SUPPORT
+ case SD_CTRL_CMD_CACHEABLE_BUFFER: /*This function is to notify that we will operate on a cacheable buffer*/
+ {
+ SD_CTRL_CACHEABLE_BUFFER_T *prCachedBuffer;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prCachedBuffer = &(data->rSDCacheableBuf);
+ MSDC_Blk[sel].isCachedBuf = prCachedBuffer->fgIsCACHEABLE;
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ status = STATUS_OK;
+ break;
+ }
+#endif
+ case SD_CTRL_CMD_FLUSH:
+ {
+ DCL_SDC_CMD_STATUS status;
+ SD_CTRL_FLUSH_T *flush;
+ sd_select_enum sel;
+
+ flush =&(data->rSDFlush);
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+ status = sdDriverTable[sel]->eraseBlk(flush->startSector,flush->sectorNum);
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ break;
+ }
+ case SD_CTRL_CMD_GPD_READ:
+ SD_CTRL_GPD_READ_T *prRead;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prRead = &(data->rSDRead);
+ status = DclSD_CtrlCmdGpdRead(sel, prRead);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ break;
+ case SD_CTRL_CMD_GPD_WRITE:
+ SD_CTRL_GPD_WRITE_T *prWrite;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prWrite = &(data->rSDWrite);
+ status = DclSD_CtrlCmdGpdWrite(sel, prWrite);
+
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ break;
+ case SD_CTRL_CMD_GET_BD_STRUCT_NUM:
+ SD_CTRL_MAX_BD_STRUCT_NUM_T *prNum;
+ sd_select_enum sel;
+
+ sel=DCL_SD_USING_RESOURCE_START(handle);
+
+ prNum = &(data->rSDMaxBD);
+
+ prNum->max_bd_num=MSDC_BD_MAX;
+ DCL_SD_USING_RESOURCE_END(handle,sel);
+ break;
+ default:
+ ASSERT(0);
+ status = STATUS_INVALID_CMD;
+ break;
+ }
+
+ /*status central wrapper here, this is an inefficient but readable way*/
+ switch(status){
+ case NO_ERROR:
+ return STATUS_OK;
+ break;
+ case ERR_CMD_TIMEOUT:/*fall through*/
+ case MSDC_GPT_TIMEOUT_ERR:
+ return STATUS_ERROR_TIMEOUT;
+ break;
+ case ERR_DAT_CRCERR:
+ return STATUS_ERROR_CRCERROR;
+ break;
+ case ERR_WRITE_PROTECT:
+ return STATUS_ERROR_READONLY;
+ break;
+ case STATUS_ERROR_WRONG_STATE: /*following status code are in the scope of DCL return value, return directly*/
+ case STATUS_INVALID_CTRL_DATA:
+ return status;
+ break;
+ default:
+ ASSERT(0);
+ return STATUS_FAIL;
+ break;
+ }
+
+ /*should not arrive here*/
+ ASSERT(0);
+ return STATUS_FAIL;
+}
+
+#endif//DCL_MSDC_FUNTION_TABLE
+
+DCL_STATUS DclSD_Close(DCL_HANDLE handle)
+{
+ sd_select_enum sel;
+
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ /*check whether it is action handle, if not, return directly*/
+ if(0 == DCL_SD_GET_MAGIC_FROM_HANDLE(handle)){
+ return STATUS_OK;
+ }
+ else{
+ kal_uint16 magic;
+ //jinxing remove this . since we never do free later.
+ //DCL_SD_USING_RESOURCE_START(handle);
+ /*after this point, we think that none should be able to use this action handle*/
+
+ /*process the magic of the resource*/
+ magic = (sdResource[sel] & DCL_SD_RESOURCE_MAGIC_MAX);
+ if(DCL_SD_RESOURCE_MAGIC_MAX == magic){ /*if means 0x0FF0 achieved*/
+ magic = DCL_SD_RESOURCE_MAGIC_UNIT;
+ }
+ else{
+ magic += DCL_SD_RESOURCE_MAGIC_UNIT;
+ }
+ sdResource[sel] = magic;
+
+ //
+ // To make a pair of taking and giving semaphore, add back the following action.
+ //
+ free_MSDC_lock(&dclMsdcLock[sel]);
+ /*
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ kal_give_sem(dclMsdcArb[sel]);
+ */
+
+ return STATUS_OK;
+ }
+}
+
+/***************************************************************************************
+followings are DCL SDIO API exported
+*****************************************************************************************/
+
+
+/**************************************************************************
+followings are DCL API exported
+***************************************************************************/
+/*************************************************************************
+* FUNCTION
+* DclSD_Initialize
+*
+* DESCRIPTION
+* This function is to initialize the SD driver related resource.
+* This function should be called in system initialization before tasks are scheduling.
+*
+* PARAMETERS
+* N/A
+*
+* RETURNS
+* STATUS_OK : this should be the only return value since MSDC_initialize returns nothing.
+*
+*************************************************************************/
+#if defined(__MSDC_SD_SDIO__)
+extern SDIODriver_t sdio_driver_MTK1;//guilin
+DCL_STATUS DclSDIO_Initialize(void)
+{
+ kal_uint32 maskedValue;
+
+ maskedValue = SaveAndSetIRQMask();
+ /*a sync mechanism to guarantee MSDC_Initialize is only called once*/
+ if(KAL_FALSE == fgMSDCInit){
+ fgMSDCInit = KAL_TRUE;
+ RestoreIRQMask(maskedValue);
+ DclMSDC_init();
+ }
+ else{
+ RestoreIRQMask(maskedValue);
+ }
+
+ maskedValue = SaveAndSetIRQMask();
+ if(KAL_FALSE == fgSDIOInit){
+ fgSDIOInit = KAL_TRUE;
+ RestoreIRQMask(maskedValue);
+ /*init SD driver tables, there are too many entries in SD driver, so we hook it by pointer*/
+#if defined(__MSDC_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
+ sdioDriverTable[DCL_SDIO_GET_SEL_FROM_HANDLE(DCL_SDIO_HANDLE_SDIO1)] = &sdio_driver_MTK1;
+#endif
+
+#if defined(__MSDC2_SD_SDIO__)
+ sdioDriverTable[DCL_SDIO_GET_SEL_FROM_HANDLE(DCL_SDIO_HANDLE_SDIO2)] = &sdio_driver_MTK2; //in the design, sel = 2 is preserved for SIM+ card, which uses 1st MSDC's code
+#endif
+ }
+ else{
+ RestoreIRQMask(maskedValue);
+ }
+
+ return STATUS_OK;
+}
+
+/*************************************************************************
+* FUNCTION
+* DclSD_Initialize
+*
+* DESCRIPTION
+* This function is to get SD DCL handler.
+*
+* PARAMETERS
+* N/A
+*
+* RETURNS
+* STATUS_OK : this should be the only return value since MSDC_initialize returns nothing.
+*
+*************************************************************************/
+DCL_HANDLE DclSDIO_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+ kal_uint32 retAddr = 0;
+ kal_uint32 thdId;
+
+ if (dev != DCL_SDIO)
+ {
+ ASSERT(0);
+ return DCL_HANDLE_INVALID;
+ }
+
+ GET_RETURN_ADDRESS(retAddr);
+
+ thdId = (kal_uint32)kal_get_current_thread_ID();
+
+ //drv_trace4(TRACE_GROUP_8, MSDC_DCL_SD_OPEN, flags, retAddr, thdId , drv_get_current_time());
+
+ if(flags & DCL_SDIO_FLAGS_SDIO1){
+ if(DCL_SDIO_FLAGS_SDIO1 != (flags & DCL_SDIO_FLAGS_ALL)){
+ ASSERT(0);
+ }
+ get_MSDC_lock(&dclMsdcLock[0]);
+ return DCL_SDIO_HANDLE_SDIO1;
+ }
+#if defined(__MSDC2_SD_SDIO__)
+ else if(flags & DCL_SDIO_FLAGS_SDIO2){
+ if(DCL_SDIO_FLAGS_SDIO2 != (flags & DCL_SDIO_FLAGS_ALL)){
+ ASSERT(0);
+ }
+ get_MSDC_lock(&dclMsdcLock[1]);
+ return DCL_SDIO_HANDLE_SDIO2;
+ }
+#endif
+}
+
+DCL_STATUS DclSDIO_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+ ASSERT(0);
+ return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSDIO_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+ ASSERT(0);
+ return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSDIO_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+ DCL_SD_IMPLEMENTATION_ASSERT;
+ return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSDIO_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+ //DCL_SD_IMPLEMENTATION_ASSERT;
+ //ASSERT(0);
+ //return STATUS_UNSUPPORTED;
+ // guilin
+ sd_select_enum sel;
+
+ sel = DCL_SDIO_GET_SEL_FROM_HANDLE(handle);
+ sdioDriverTable[sel]->hisr_callback(DCL_SDIO_FUCN_0, callback);
+ sdioDriverTable[sel]->hisr_callback(DCL_SDIO_FUCN_1, callback);
+
+ return STATUS_OK;
+}
+
+
+
+/*************************************************************************
+* FUNCTION
+* DclGPIO_Control
+*
+* DESCRIPTION
+* This function is to send command to control the GPIO module.
+*
+* PARAMETERS
+* handle - a valid handle return by DclGPIO_Open()
+* cmd - a control command for GPIO module
+* 1. GPIO_CMD_READ: to read the input value of a GPIO port (high/low)
+* 2. GPIO_CMD_WRITE: to write to the output of a GPIO port (high/low)
+* 3. GPIO_CMD_SET_MODE: to set the mode of a GPIO port
+* 4. GPIO_CMD_SET_DIR: to set the direction of a GPIO port
+* 5. GPIO_CMD_RETURN_MODE: to get the mode of a GPIO port
+* 6. GPIO_CMD_RETURN_DIR: to get the direction of a GPIO port
+* 7. GPIO_CMD_RETURN_OUT: to return the output value of a GPIO port
+* 8. GPIO_CMD_ENABLE_PULL: to enable the pull resister for a GPIO port
+* 9. GPIO_CMD_SEL_PULL: to select the pull up or pull down for a GPIO port
+* 10. GPIO_CMD_SET_DINV: to set the inversion of a GPIO port
+* 11. GPIO_CMD_SET_DEBUG: to enable or disable debug mode
+* 12. GPIO_CMD_SET_CLK_OUT: to set the clock frequency for a clock output
+* 13. GPIO_CMD_SET_TM_DIR: to set TM direction
+* data - for 1. GPIO_CMD_READ: pointer to a HGPT_CTRL_CLK_T structure
+* 2. GPIO_CMD_WRITE: pointer to a HGPT_CTRL_RESET_T structure
+* 3. GPIO_CMD_SET_MODE: pointer to a GPIO_CTRL_SET_MODE_T structure
+* 4. GPIO_CMD_SET_DIR: pointer to a GPIO_CTRL_SET_DIR_T structure
+* 5. GPIO_CMD_RETURN_MODE: pointer to a GPIO_CTRL_RETURN_MODE_T structure
+* 6. GPIO_CMD_RETURN_DIR: pointer to a GPIO_CTRL_RETURN_DIR_T structure
+* 7. GPIO_CMD_RETURN_OUT: pointer to a GPIO_CTRL_RETURN_OUT_T structure
+* 8. GPIO_CMD_ENABLE_PULL: pointer to a GPIO_CTRL_ENABLE_PULL_T structure
+* 9. GPIO_CMD_SEL_PULL: pointer to a GPIO_CTRL_SEL_PULL_T structure
+* 10. GPIO_CMD_SET_DINV: pointer to a GPIO_CTRL_SET_DINV_T structure
+* 11. GPIO_CMD_SET_DEBUG: pointer to a GPIO_CTRL_SET_DEBUG_T structure
+* 12. GPIO_CMD_SET_CLK_OUT: pointer to a GPIO_CTRL_SET_CLK_OUT_T structure
+* 13. GPIO_CMD_SET_TM_DIR: pointer to a GPIO_CTRL_SET_TM_DIR_T structure
+*
+* RETURNS
+* STATUS_OK - command is executed successfully.
+* STATUS_FAIL - command is failed.
+* STATUS_INVALID_CMD - The command is invalid.
+* STATUS_INVALID_HANDLE - The handle is invalid.
+* STATUS_INVALID_CTRL_DATA - The ctrl data is not valid.
+*************************************************************************/
+DCL_STATUS DclSDIO_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ DCL_BOOL status;/*in the world of SDIO driver, the return value is either trur or false*/
+ sd_select_enum sel;
+
+ sel = DCL_SDIO_GET_SEL_FROM_HANDLE(handle);
+ msdcDriverTable[sel].modulePDN(KAL_FALSE);
+
+ switch(cmd){
+ case SDIO_CTRL_CMD_REG_WR:
+ {
+ SDIO_CTRL_REG_RW_T *prRegWr;
+
+ prRegWr = &data->rSDIORegRw;
+ status = sdioDriverTable[sel]->regWr(prRegWr->function, prRegWr->addr, prRegWr->data, prRegWr->op);
+ break;
+ }
+ case SDIO_CTRL_CMD_REG_WR_ISR:
+ {
+ SDIO_CTRL_REG_RW_T *prRegWrIsr;
+
+ prRegWrIsr = &data->rSDIORegRw;
+ status = sdioDriverTable[sel]->regWrInIsr(prRegWrIsr->function, prRegWrIsr->addr, prRegWrIsr->data, prRegWrIsr->op);
+ break;
+ }
+ case SDIO_CTRL_CMD_DATA_WR:
+ {
+ SDIO_CTRL_DAT_RW_T *prDatWr;
+
+ prDatWr = &data->rSDIODatRw;
+ status = sdioDriverTable[sel]->dataWr(prDatWr->function, prDatWr->addr, (DCL_UINT8 *)prDatWr->buffer, prDatWr->op, prDatWr->count, prDatWr->block);
+ break;
+ }
+ case SDIO_CTRL_CMD_REG_RD:
+ {
+ SDIO_CTRL_REG_RW_T *prRegRd;
+
+ prRegRd = &data->rSDIORegRw;
+ status = sdioDriverTable[sel]->regRd(prRegRd->function, prRegRd->addr, &prRegRd->data, prRegRd->op);
+ break;
+ }
+ case SDIO_CTRL_CMD_DATA_RD:
+ {
+ SDIO_CTRL_DAT_RW_T *prDatRd;
+
+ prDatRd = &data->rSDIODatRw;
+ status = sdioDriverTable[sel]->dataRd(prDatRd->function, prDatRd->addr, (DCL_UINT8 *)prDatRd->buffer, prDatRd->op, prDatRd->count, prDatRd->block);
+ break;
+ }
+ case SDIO_CTRL_CMD_CHECK_INTR:
+ {
+ SDIO_CTRL_CHECK_INTR_T *prCheckIntr;
+
+ prCheckIntr = &data->rSDIOCheckIntr;
+ status = sdioDriverTable[sel]->checkIntr(prCheckIntr->function, prCheckIntr->pending);
+ break;
+ }
+ case SDIO_CTRL_CMD_ENABLE_INTR:
+ {
+ SDIO_CTRL_ENABLE_T *prEnableIntr;
+
+ prEnableIntr = &data->rSDIOEnable;
+ status = sdioDriverTable[sel]->enableIntr(prEnableIntr->function, prEnableIntr->enable);
+ break;
+ }
+ case SDIO_CTRL_CMD_INIT:
+ {
+ status = sdioDriverTable[sel]->sdioInititalize();
+ break;
+ }
+ case SDIO_CTRL_CMD_ABORT:
+ {
+ DCL_SDIO_function_id_enum function;
+
+ function = data->rSDIOFunction;
+ status = sdioDriverTable[sel]->abort(function);
+ break;
+ }
+ case SDIO_CTRL_CMD_SW_RST:
+ {
+ status = sdioDriverTable[sel]->swRst();
+ break;
+ }
+ case SDIO_CTRL_CMD_QUERY_BLK_SIZE:
+ {
+ DCL_SDIO_function_id_enum function;
+
+ function = data->rSDIOFunction;
+ status = sdioDriverTable[sel]->qryBlkSize(function);
+ break;
+ }
+ case SDIO_CTRL_CMD_SET_BLK_SIZE:
+ {
+ SDIO_CTRL_SET_BLK_SIZE_T *prSetBlkSize;
+
+ prSetBlkSize = &data->rSDIOSetBlkSize;
+ status = sdioDriverTable[sel]->setBlkSize(prSetBlkSize->function, prSetBlkSize->size);
+ break;
+ }
+ case SDIO_CTRL_CMD_ENABLE_IO:
+ {
+ SDIO_CTRL_ENABLE_T *prEnableIO;
+
+ prEnableIO = &data->rSDIOEnable;
+ status = sdioDriverTable[sel]->enableIO(prEnableIO->function, prEnableIO->enable);
+ break;
+ }
+ case SDIO_CTRL_CMD_SET_BUS_WIDTH:
+ {
+ DCL_SD_BITWIDTH busWidth;
+
+ busWidth = data->rSDIOBusWidth;
+ status = sdioDriverTable[sel]->setBusWidth(busWidth);
+ break;
+ }
+ //---------------------------------------------------------------------
+ case SDIO_CTRL_CMD_CMD52_READ:
+ {
+ SDIO_CTRL_CMD52_T *prCMD52;
+
+ prCMD52 = &data->rSDIOCMD52;
+ status = sdioDriverTable[sel]->cmd52_read(prCMD52->func, prCMD52->addr, &prCMD52->rdata, &prCMD52->r5_resp);
+ break;
+ }
+ case SDIO_CTRL_CMD_CMD52_WRITE:
+ {
+ SDIO_CTRL_CMD52_T *prCMD52;
+
+ prCMD52 = &data->rSDIOCMD52;
+ status = sdioDriverTable[sel]->cmd52_write(prCMD52->func, prCMD52->addr, prCMD52->wdata, &prCMD52->r5_resp);
+ break;
+ }
+ case SDIO_CTRL_CMD_CMD52_WRITE_READ:
+ {
+ SDIO_CTRL_CMD52_T *prCMD52;
+ sd_select_enum sel;
+
+ prCMD52 = &data->rSDIOCMD52;
+ sel = DCL_SDIO_GET_SEL_FROM_HANDLE(handle);
+ status = sdioDriverTable[sel]->cmd52_write_read(prCMD52->func, prCMD52->addr, prCMD52->wdata, &prCMD52->rdata, &prCMD52->r5_resp);
+ break;
+ }
+ case SDIO_CTRL_CMD_CMD53_READ:
+ {
+ SDIO_CTRL_CMD53_T *prCMD53;
+
+ prCMD53 = &data->rSDIOCMD53;
+ status = sdioDriverTable[sel]->cmd53_read(prCMD53->func, prCMD53->addr, prCMD53->buffer, prCMD53->op, prCMD53->count, prCMD53->block, &prCMD53->r5_resp);
+ break;
+ }
+ case SDIO_CTRL_CMD_CMD53_WRITE:
+ {
+ SDIO_CTRL_CMD53_T *prCMD53;
+
+ prCMD53 = &data->rSDIOCMD53;
+ status = sdioDriverTable[sel]->cmd53_write(prCMD53->func, prCMD53->addr, prCMD53->buffer, prCMD53->op, prCMD53->count, prCMD53->block, &prCMD53->r5_resp);
+ break;
+ }
+ case SDIO_CTRL_CMD_MCUDMA_READ:
+ {
+ SDIO_CTRL_CMD_REG_T *prCMDREG;
+
+ prCMDREG = &data->rSDIOCMDREG;
+ status = sdioDriverTable[sel]->mcudma_read(&prCMDREG->data);
+ break;
+ }
+ case SDIO_CTRL_CMD_MCUDMA_WRITE:
+ {
+ SDIO_CTRL_CMD_REG_T *prCMDREG;
+
+ prCMDREG = &data->rSDIOCMDREG;
+ status = sdioDriverTable[sel]->mcudma_write(prCMDREG->data);
+ break;
+ }
+ case SDIO_CTRL_CMD_CLKPADRED_READ:
+ {
+ SDIO_CTRL_CMD_REG_T *prCMDREG;
+
+ prCMDREG = &data->rSDIOCMDREG;
+ status = sdioDriverTable[sel]->clkpadred_read(&prCMDREG->data);
+ break;
+ }
+ case SDIO_CTRL_CMD_CLKPADRED_WRITE:
+ {
+ SDIO_CTRL_CMD_REG_T *prCMDREG;
+
+ prCMDREG = &data->rSDIOCMDREG;
+ status = sdioDriverTable[sel]->clkpadred_write(prCMDREG->data);
+ break;
+ }
+ case SDIO_CTRL_CMD_FORCEMCU_READ:
+ {
+ SDIO_CTRL_CMD_REG_T *prCMDREG;
+
+ prCMDREG = &data->rSDIOCMDREG;
+ status = sdioDriverTable[sel]->forcemcu_read(&prCMDREG->data);
+ break;
+ }
+ case SDIO_CTRL_CMD_FORCEMCU_WRITE:
+ {
+ SDIO_CTRL_CMD_REG_T *prCMDREG;
+
+ prCMDREG = &data->rSDIOCMDREG;
+ status = sdioDriverTable[sel]->forcemcu_write(prCMDREG->data);
+ break;
+ }
+ case SDIO_CTRL_CMD_GETCLK:
+ {
+ SDIO_CTRL_CMD_REG_T *prCMDREG;
+
+ prCMDREG = &data->rSDIOCMDREG;
+ status = sdioDriverTable[sel]->getclk(&prCMDREG->data);
+ break;
+ }
+ case SDIO_CTRL_CMD_SETCLK:
+ {
+ SDIO_CTRL_CMD_REG_T *prCMDREG;
+
+ prCMDREG = &data->rSDIOCMDREG;
+ status = sdioDriverTable[sel]->setclk(prCMDREG->data);
+ break;
+ }
+ case SDIO_CTRL_CMD_GET_BLK_SIZE:
+ {
+ SDIO_CTRL_SET_BLK_SIZE_T *prSetBlkSize;
+
+ prSetBlkSize = &data->rSDIOSetBlkSize;
+ status = sdioDriverTable[sel]->getBlkSize(prSetBlkSize->function, &prSetBlkSize->size);
+ break;
+ }
+ //---------------------------------------------------------------------
+ default:
+ ASSERT(0);
+ status = STATUS_INVALID_CMD;
+ break;
+ }
+ msdcDriverTable[sel].modulePDN(KAL_TRUE);
+ kal_prompt_trace(MOD_MSDC_HISR,"[%s %d]cmd=%d status=%d",__FUNCTION__,__LINE__,(cmd - SDIO_CTRL_CMD_REG_WR),status);//guilin
+ /*status central wrapper here, this is an inefficient but readable way*/
+ switch(status){
+ case NO_ERROR:
+ return STATUS_OK;
+ // break;
+ case ERR_CMD_TIMEOUT:/*fall through*/
+ case MSDC_GPT_TIMEOUT_ERR:
+ return STATUS_ERROR_TIMEOUT;
+ // break;
+ case ERR_DAT_CRCERR:
+ return STATUS_ERROR_CRCERROR;
+ // break;
+ case ERR_WRITE_PROTECT:
+ return STATUS_ERROR_READONLY;
+ // break;
+ case STATUS_ERROR_WRONG_STATE: /*following status code are in the scope of DCL return value, return directly*/
+ case STATUS_INVALID_CTRL_DATA:
+ return status;
+ // break;
+ default:
+ //ASSERT(0);
+ return STATUS_FAIL;
+ break;
+ }
+
+ /*should not arrive here*/
+ ASSERT(0);
+ return STATUS_FAIL;
+}
+
+DCL_STATUS DclSDIO_Close(DCL_HANDLE handle)
+{
+// DCL_SD_IMPLEMENTATION_ASSERT;
+// return STATUS_UNSUPPORTED;
+
+ sd_select_enum sel;
+
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ free_MSDC_lock(&dclMsdcLock[sel]);
+
+ return STATUS_OK;
+}
+#endif
+/****************************************************************************************************
+* followings are functions used by DCL MS API, these functions can only be called in this file.
+******************************************************************************************************/
+#if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
+static DCL_STATUS DclMS_CtrlCmdRead(sd_select_enum sel, SD_CTRL_READ_T *prRead)
+{
+#if defined(__MSDC_MSPRO__)
+ DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+ DCL_MSP_STATUS status;
+ DCL_UINT32 u4Sector; //this specify the starting sector to read
+ DCL_UINT32 u4Sectors; //this specify the number of sectors to read
+ void *bufferAddr; //we will move move data from card to this address
+ MSDriver_t *msDriver;
+
+
+ /*parameters in prRead should not be changed, take these as local variable*/
+ u4Sector = prRead->u4Sector;
+ u4Sectors = prRead->u4Sectors;
+ bufferAddr = prRead->bufferAddr;
+ msDriver = msDriverTable[sel];
+
+ /*requirement check here*/
+ if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+ ASSERT(0);
+ status = STATUS_ERROR_WRONG_STATE;
+ return status;
+ }
+
+
+ if(MSPRO_CARD == gMSDC_Handle->mMSDC_type){
+ kal_uint16 read;
+
+ maxBlk = gMSP.user_block*gMSP.block_size;
+
+ /*sectors & sector check*/
+ if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector > maxBlk){
+ ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ /*check that ending block should be smaller than maximum block number*/
+ if((u4Sector + u4Sectors - 1) > maxBlk){
+ ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ /*power on MSDC module*/
+ msdcDriverTable[sel]->modulePDN(KAL_FALSE);
+
+ status = msDriver->mspRdWrData(u4Sector, u4Sectors, bufferAddr, &read, MSP_READ);
+
+ /*power down MSDC module*/
+ msdcDriverTable[sel]->modulePDN(KAL_TRUE);
+ }
+ else if(MS_CARD == gMSDC_Handle->mMSDC_type){
+ /*followings are the local variables related to MS, since we have to calculate physical block in MS*/
+ kal_uint8 PagesPerBlk,page,readpage,len,*ptr, extra[4];
+ kal_uint32 lba,pba;
+
+ /*Capacity information is stored in MBR in MS so we don't do capacity check*/
+
+ gMS.is_write = KAL_FALSE;
+ PagesPerBlk = gMS.PagesPerBlk;
+ lba = u4Sector/PagesPerBlk; //calculate in which Blk does the starting sector locate
+ page = u4Sector%PagesPerBlk;//calculate with how many offset of page does the starting sector locate
+ ptr = (kal_uint8*) bufferAddr;
+
+ /*power on MSDC module*/
+ msdcDriverTable[sel]->modulePDN(KAL_FALSE);
+
+ while(1)
+ {
+ /*if all ofo the sectors wanna read reside in the same blk, we read them in ms readBlock; otherwise read them separately*/
+ if(PagesPerBlk - page < u4Sectors)
+ len = PagesPerBlk - page;
+ else
+ len = u4Sectors;
+
+ ASSERT(len >= 1 && len <= 32);
+
+ status = msDriver->msLogToPhy(gMS.pLPTbl, lba, &pba);
+ if(status != MS_NOERROR)
+ return status;//return FS_MSDC_READ_SECTOR_ERROR;
+ if(len == 1){
+ status = msDriver->msRdSinglePage(pba, page, (kal_uint32*)ptr, NULL);
+ }
+ else{
+ status = msDriver->msRdBlk(pba, (kal_uint32*)ptr, NULL, page, len, &readpage);
+ }
+ if(status != MS_NOERROR)
+ return status;//return FS_MSDC_READ_SECTOR_ERROR;
+
+ /*following part comes from M2 compliant test*/
+ //============ change the update status ====================//
+ status = msDriver->msRdExtraData(pba, 0, (kal_uint32*)extra);
+ if(MS_UPDATE_STATUS(extra[OVERWRITE_FLAG]) == 0)
+ {
+ kal_uint32 i;
+ kal_uint16 *FreeTable, *LPTable, spareblk;
+ kal_uint8 readpage;
+ // find a unused block from FreeTable, erase it and write updated info into it
+
+ LPTable = gMS.pLPTbl;
+ FreeTable = gMS.pFreeTbl;
+ i = 0;
+
+ /*find an i that satisfys FreeTable[i] != 0xFFFF*/
+ while((FreeTable[i++] == 0xFFFF) && (i < MS_FREETABLE_SIZE));
+
+ spareblk = FreeTable[i-1];
+ status = msDriver->msRdBlk(pba,(kal_uint32*)u4ms16KBuffer, (kal_uint32 *)extra, 0, PagesPerBlk, &readpage);
+ extra[0] |= MS_OVFLG_UDST;
+ status = msDriver->msWrExtraData(spareblk, 0, (kal_uint32 *)extra);
+ status = msDriver->msWrBlk(spareblk,(kal_uint32*)u4ms16KBuffer, (kal_uint32 *)extra, 0, PagesPerBlk, &readpage);
+ status = msDriver->msEraseBlk(pba);
+ // update the LPTable and FreeTable
+ LPTable[MS_GetLPIndex(lba)] = spareblk;
+ FreeTable[i-1] = pba;
+ }
+ //================================//
+
+ u4Sectors -= len;
+ if(u4Sectors == 0)
+ break;
+ page = 0;
+ ptr += MS_PAGE_SIZE*len;
+ lba++;
+ }
+
+ /*power down MSDC module*/
+ msdcDriverTable[sel]->modulePDN(KAL_TRUE);
+ }
+ else{/*neither MSPro nor MS*/
+ ASSERT(0);
+ }
+#else
+ /*if __MSDC_MSPRO__ is undefined, it is impossible to support read*/
+ ASSERT(0);
+ return STATUS_UNSUPPORTED;
+#endif
+}
+
+static DCL_STATUS DclMS_CtrlCmdWrite(sd_select_enum sel, SD_CTRL_READ_T *prWrite)
+{
+#if defined(__MSDC_MSPRO__)
+ DCL_UINT32 maxBlk;//DCL_UINT32 addrs, maxBlk;
+ SDC_CMD_STATUS status;
+ DCL_UINT32 u4Sector; //this specify the starting sector to Write
+ DCL_UINT32 u4Sectors; //this specify the number of sectors to Write
+ void *bufferAddr; //we will move move data from this address to the card
+ MSDriver_t *msDriver;
+
+ /*parameters in prRead should not be changed, take these as local variable*/
+ u4Sector = prWrite->u4Sector;
+ u4Sectors = prWrite->u4Sectors;
+ bufferAddr = prWrite->bufferAddr;
+ msDriver = msDriverTable[sel];
+
+ /*requirement check here*/
+ if(KAL_FALSE == MSDC_Blk[sel].mIsInitialized || KAL_FALSE == MSDC_Blk[sel].mIsPresent){
+ ASSERT(0);
+ status = STATUS_ERROR_WRONG_STATE;
+ return status;
+ }
+
+ if(MSPRO_CARD == gMSDC_Handle->mMSDC_type){
+ kal_uint16 write;
+
+ maxBlk = gMSP.user_block*gMSP.block_size;
+
+ /*sectors & sector check*/
+ if(0 == u4Sectors || u4Sectors > maxBlk || u4Sector > maxBlk){
+ ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ /*check that ending block should be smaller than maximum block number*/
+ if((u4Sector + u4Sectors - 1) > maxBlk){
+ ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ /*power on MSDC module*/
+ msdcDriverTable[sel]->modulePDN(KAL_FALSE);
+
+ status = msDriver->mspRdWrData(u4Sector, u4Sectors, bufferAddr, &write, MSP_WRITE);
+
+ /*power down MSDC module*/
+ msdcDriverTable[sel]->modulePDN(KAL_TRUE);
+ }
+ else if(MS_CARD == gMSDC_Handle->mMSDC_type){
+ /*followings are the local variables related to MS, since we have to calculate physical block in MS*/
+ kal_uint32 lba, pba, i, spareblk;
+ kal_uint8 *p = NULL, *ptr;
+ kal_uint8 PagesPerBlk, page, pages, extra[4], owflag, len;
+ kal_uint16 *LPTable, *FreeTable;
+
+
+ /*Capacity information is stored in MBR in MS so we don't do capacity check*/
+
+ gMS.is_write = KAL_TRUE;
+ LPTable = gMS.pLPTbl;
+ FreeTable = gMS.pFreeTbl;
+ PagesPerBlk = gMS.PagesPerBlk;
+ lba = u4Sector/PagesPerBlk; //calculate in which Blk does the starting sector locate
+ len = page = u4Sector%PagesPerBlk;//calculate with how many offset of page does the starting sector locate
+ ptr = (kal_uint8*) bufferAddr;
+ p = (kal_uint8 * )u4ms16KBuffer;
+
+
+ /*power on MSDC module*/
+ msdcDriverTable[sel]->modulePDN(KAL_FALSE);
+
+ while(1)
+ {
+ if(PagesPerBlk - page < u4Sectors){
+ len = PagesPerBlk - page;
+ }
+ else{
+ len = u4Sectors;
+ }
+ ASSERT(len >= 1 && len <= 32);
+ status = msDriver->msLogToPhy(LPTable, lba, &pba);
+ if(status != MS_NOERROR)
+ return status;
+
+ // set update status to 0
+ status = msDriver->msRdExtraData(pba, 0, (kal_uint32 *)extra);
+ owflag = extra[0];
+ extra[0] &= ~MS_OVFLG_UDST;
+ status = msDriver->msWrOverWriteFlag(pba, 0, extra[0]);
+
+ // read the entire block
+ status = msDriver->msRdBlk(pba, (kal_uint32*)p, (kal_uint32 *)extra, 0, PagesPerBlk, &pages);
+ if(status != MS_NOERROR)
+ {
+ return status;
+ }
+ if(gMS.uc_pages != 0)
+ {
+ status = msDriver->msLogToPhy(LPTable, lba, &pba);
+ status = msDriver->msRdExtraData(pba, 0, (kal_uint32 *)extra);
+ owflag = extra[0];
+ extra[0] &= ~MS_OVFLG_UDST;
+ status = msDriver->msWrExtraData(pba, 0, (kal_uint32 *)extra);
+ }
+ // update the page in the memory
+ kal_mem_cpy((kal_uint8*)(p+page*MS_PAGE_SIZE), (kal_uint8*)ptr, MS_PAGE_SIZE*len);
+ // find a unused block from FreeTable, erase it and write updated info into it
+ i = 0;
+ while((FreeTable[i++] == 0xFFFF) && (i < MS_FREETABLE_SIZE));
+ spareblk = FreeTable[i-1];
+ status = msDriver->msEraseBlk(spareblk);
+ if(status != MS_NOERROR)
+ return status;
+ extra[0] = (owflag|MS_OVFLG_UDST);
+ status = msDriver->msWrBlk(spareblk, (kal_uint32*)p, (kal_uint32*)extra, 0, PagesPerBlk, &pages);
+ if(status != MS_NOERROR)
+ return status;
+ // update the LPTable and FreeTable
+ LPTable[MS_GetLPIndex(lba)] = spareblk;
+ FreeTable[i-1] = pba;
+ // erase original block
+ status = msDriver->msEraseBlk(pba);
+ if(status != MS_NOERROR)
+ return status;
+ if(gMS.uc_pages || gMS.de_pages)
+ {
+ kal_uint32 pages;
+ if(gMS.uc_pages)
+ pages = gMS.uc_pages;
+ else
+ pages = gMS.de_pages;
+ for(i=0;i<32;i++)
+ {
+ if(pages & (1<<i))
+ {
+ status = msDriver->msRdExtraData(spareblk, i, (kal_uint32 *)extra);
+ extra[0] &= ~MS_OVFLG_PGST;
+ status = msDriver->msWrExtraData(spareblk, i, (kal_uint32 *)extra);
+ }
+ }
+ }
+ status = msDriver->msRdExtraData(spareblk, 0x18, (kal_uint32 *)extra);
+ u4Sectors -= len;
+ if(u4Sectors == 0) break;
+ ptr += MS_PAGE_SIZE*len;
+ page = 0;
+ lba++;
+ }
+ /*power down MSDC module*/
+ msdcDriverTable[sel]->modulePDN(KAL_TRUE);
+ }
+ else{/*neither MSPro nor MS*/
+ ASSERT(0);
+ }
+#else
+ /*if __MSDC_MSPRO__ is undefined, it is impossible to support write*/
+ ASSERT(0);
+ return STATUS_UNSUPPORTED;
+#endif
+}
+
+
+/***************************************************************************************
+followings are DCL MSPro API exported
+*****************************************************************************************/
+
+
+/***************************************************************************************
+followings are DCL SD API exported
+*****************************************************************************************/
+/*************************************************************************
+* FUNCTION
+* DclSD_Initialize
+*
+* DESCRIPTION
+* This function is to initialize the SD driver related resource.
+* This function should be called in system initialization before tasks are scheduling.
+*
+* PARAMETERS
+* N/A
+*
+* RETURNS
+* STATUS_OK : this should be the only return value since MSDC_initialize returns nothing.
+*
+*************************************************************************/
+DCL_STATUS DclMS_Initialize(void)
+{
+ DCL_UINT32 msdcSupport;
+ kal_uint32 maskedValue;
+
+ maskedValue = SaveAndSetIRQMask();
+ /*a sync mechanism to guarantee MSDC_Initialize is only called once*/
+ if(KAL_FALSE == fgMSDCInit){
+ fgMSDCInit = KAL_TRUE;
+ RestoreIRQMask(maskedValue);
+ DclMSDC_init();
+ }
+ else{
+ RestoreIRQMask(maskedValue);
+ }
+
+ maskedValue = SaveAndSetIRQMask();
+ if(KAL_FALSE == fgMSInit){
+ RestoreIRQMask(maskedValue);
+ fgMSInit = KAL_TRUE;
+ /*
+ Init MS driver tables, there are too many entries in MS driver, so we hook it by pointer.
+ Notes that we don't have MSPro 2 driver that can run synchronously with MSPro, both uses the same driver.
+ We use a global variable and compile option for this.
+ */
+#if defined(__MSDC_MSPRO__)
+ msDriverTable[DCL_MS_GET_SEL_FROM_HANDLE(DCL_MS_HANDLE)] = &ms_driver_MTK1;
+#endif
+ }
+ else{
+ RestoreIRQMask(maskedValue);
+ }
+
+ return STATUS_OK;
+}
+
+/*************************************************************************
+* FUNCTION
+* DclSD_Initialize
+*
+* DESCRIPTION
+* This function is to get MS DCL handler.
+*
+* PARAMETERS
+* N/A
+*
+* RETURNS
+* STATUS_OK : this should be the only return value since MSDC_initialize returns nothing.
+*
+*************************************************************************/
+DCL_HANDLE DclMS_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+ if (dev != DCL_MS)
+ {
+ ASSERT(0);
+ return DCL_HANDLE_INVALID;
+ }
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclMS_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+ ASSERT(0);
+ return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclMS_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+ ASSERT(0);
+ return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclMS_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+ DCL_SD_IMPLEMENTATION_ASSERT;
+ return STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclMS_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+ ASSERT(0);
+ return STATUS_UNSUPPORTED;
+}
+
+
+
+/*************************************************************************
+* FUNCTION
+* DclGPIO_Control
+*
+* DESCRIPTION
+* This function is to send command to control the GPIO module.
+*
+* PARAMETERS
+* handle - a valid handle return by DclGPIO_Open()
+* cmd - a control command for GPIO module
+* 1. GPIO_CMD_READ: to read the input value of a GPIO port (high/low)
+* 2. GPIO_CMD_WRITE: to write to the output of a GPIO port (high/low)
+* 3. GPIO_CMD_SET_MODE: to set the mode of a GPIO port
+* 4. GPIO_CMD_SET_DIR: to set the direction of a GPIO port
+* 5. GPIO_CMD_RETURN_MODE: to get the mode of a GPIO port
+* 6. GPIO_CMD_RETURN_DIR: to get the direction of a GPIO port
+* 7. GPIO_CMD_RETURN_OUT: to return the output value of a GPIO port
+* 8. GPIO_CMD_ENABLE_PULL: to enable the pull resister for a GPIO port
+* 9. GPIO_CMD_SEL_PULL: to select the pull up or pull down for a GPIO port
+* 10. GPIO_CMD_SET_DINV: to set the inversion of a GPIO port
+* 11. GPIO_CMD_SET_DEBUG: to enable or disable debug mode
+* 12. GPIO_CMD_SET_CLK_OUT: to set the clock frequency for a clock output
+* 13. GPIO_CMD_SET_TM_DIR: to set TM direction
+* data - for 1. GPIO_CMD_READ: pointer to a HGPT_CTRL_CLK_T structure
+* 2. GPIO_CMD_WRITE: pointer to a HGPT_CTRL_RESET_T structure
+* 3. GPIO_CMD_SET_MODE: pointer to a GPIO_CTRL_SET_MODE_T structure
+* 4. GPIO_CMD_SET_DIR: pointer to a GPIO_CTRL_SET_DIR_T structure
+* 5. GPIO_CMD_RETURN_MODE: pointer to a GPIO_CTRL_RETURN_MODE_T structure
+* 6. GPIO_CMD_RETURN_DIR: pointer to a GPIO_CTRL_RETURN_DIR_T structure
+* 7. GPIO_CMD_RETURN_OUT: pointer to a GPIO_CTRL_RETURN_OUT_T structure
+* 8. GPIO_CMD_ENABLE_PULL: pointer to a GPIO_CTRL_ENABLE_PULL_T structure
+* 9. GPIO_CMD_SEL_PULL: pointer to a GPIO_CTRL_SEL_PULL_T structure
+* 10. GPIO_CMD_SET_DINV: pointer to a GPIO_CTRL_SET_DINV_T structure
+* 11. GPIO_CMD_SET_DEBUG: pointer to a GPIO_CTRL_SET_DEBUG_T structure
+* 12. GPIO_CMD_SET_CLK_OUT: pointer to a GPIO_CTRL_SET_CLK_OUT_T structure
+* 13. GPIO_CMD_SET_TM_DIR: pointer to a GPIO_CTRL_SET_TM_DIR_T structure
+*
+* RETURNS
+* STATUS_OK - command is executed successfully.
+* STATUS_FAIL - command is failed.
+* STATUS_INVALID_CMD - The command is invalid.
+* STATUS_INVALID_HANDLE - The handle is invalid.
+* STATUS_INVALID_CTRL_DATA - The ctrl data is not valid.
+*************************************************************************/
+DCL_STATUS DclMS_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+#if defined(__MSDC_MSPRO__)
+ MSP_STATUS status;
+
+ switch(cmd){
+ case MS_CTRL_CMD_READ:
+ {
+ MS_CTRL_READ_T *prRead;
+ sd_select_enum sel;
+
+ prRead = &data->rSDRead;
+ sel = DCL_MS_GET_SEL_FROM_HANDLE(handle);
+
+ status = DclMS_CtrlCmdRead(sel, prRead);
+ break;
+ }
+ case MS_CTRL_CMD_WRITE:
+ {
+ MS_CTRL_WRITE_T *prWrite;
+ sd_select_enum sel;
+
+ prWrite = &data->rSDWrite;
+ sel = DCL_MS_GET_SEL_FROM_HANDLE(handle);
+
+ status = DclMS_CtrlCmdWrite(sd_select_enum sel, SD_CTRL_READ_T * prWrite);
+ break;
+ }
+ case MS_CTRL_CMD_INIT:
+ {
+ if(DCL_MS_HANDLE == handle){
+ status = msDriverTable[DCL_MS_GET_SEL_FROM_HANDLE(handle)].mspInit();
+ }
+ else{
+ ASSERT(0);
+ }
+ break;
+ }
+ case MS_CTRL_CMD_FORMAT:
+ {
+ if(DCL_MS_HANDLE != handle){
+ ASSERT(0);
+ }
+
+ if(MSPRO_CARD == gMSDC_Handle->mMSDC_type){
+ status = msDriverTable[DCL_MS_GET_SEL_FROM_HANDLE(handle)].mspFormat(MSP_FULL, NULL);
+ }
+ else if(MS_CARD == gMSDC_Handle->mMSDC_type){
+ status = msDriverTable[DCL_MS_GET_SEL_FROM_HANDLE(handle)].msFormat();
+ }
+ else{
+ ASSERT(0);
+ status = STATUS_ERROR_WRONG_STATE;
+ }
+
+ break;
+ }
+ case MS_CTRL_CMD_GET_CAPACITY:
+ {
+ MS_CTRL_GET_CAPACITY_T *prGetCapacity;
+ DCL_UINT32* pMBR;
+
+ prGetCapacity = &data->rMSGetCapacity;
+ if(MSPRO_CARD == gMSDC_Handle->mMSDC_type){
+ *(prGetCapacity->pu8Capacity) = gMSP.user_block * gMSP.block_size;
+ }
+ else if(MS_CARD == gMSDC_Handle->mMSDC_type){
+ int i = 0;
+ kal_uint8 c = gMS.Capacity;
+
+ // get index for MS_MBR
+ while((c >>= 1) != 2)
+ i++;
+ pMBR = MS_MBR[i];
+ /*byte 12~ byte 15 (start from byte 0) records device's capacity in MBR*/
+ *(prGetCapacity->pu8Capacity) = *(DCL_UINT32 *)(pMBR+3);
+ }
+ else{
+ ASSERT(0);
+ status = STATUS_ERROR_WRONG_STATE;
+ }
+
+ break;
+ }
+ case MS_CTRL_CMD_EXISTENCE: /*this function differs to MS_CTRL_CMD_EXISTENCE, we only get status from global variables*/
+ {
+ MS_CTRL_EXISTENCE_T *prExistence;
+ sd_select_enum sel;
+
+ prExistence = &data->rMSExist;
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ *(prExistence->fgPresent) = MSDC_Blk[sel].mIsPresent;
+ break;
+ }
+ case MS_CTRL_CMD_GO_IDLE: /*This function is to set global state mIsInitialized = false, it is only driver can set it to true*/
+ {
+ sd_select_enum sel;
+
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ MSDC_Blk[sel].mIsInitialized = KAL_FALSE;
+ break;
+ }
+ case MS_CTRL_CMD_CACHEABLE_BUFFER: /*This function is to notify that we will operate on a cacheable buffer*/
+ {
+ MS_CTRL_CACHEABLE_BUFFER_T *prCachedBuffer;
+ sd_select_enum sel;
+
+ prCachedBuffer = &data->rMSCacheableBuf;
+ sel = DCL_SD_GET_SEL_FROM_HANDLE(handle);
+ MSDC_Blk[sel].mIsInitializedmIsInitialized = prCachedBuffer->fgIsCACHEABLE;
+ break;
+ }
+ default:
+ ASSERT(0);
+ status = STATUS_INVALID_CMD;
+ break;
+ }
+
+ /*status central wrapper here, this is an inefficient but readable way*/
+ switch(status){
+ case NO_ERROR:
+ return STATUS_OK;
+ break;
+ case ERR_CMD_TIMEOUT:/*fall through*/
+ case MSDC_GPT_TIMEOUT_ERR:
+ return STATUS_ERROR_TIMEOUT;
+ break;
+ case ERR_DAT_CRCERR:
+ return STATUS_ERROR_CRCERROR;
+ break;
+ case ERR_WRITE_PROTECT:
+ return STATUS_ERROR_READONLY;
+ break;
+ case STATUS_ERROR_WRONG_STATE: /*following status code are in the scope of DCL return value, return directly*/
+ case STATUS_INVALID_CTRL_DATA:
+ return status;
+ break;
+ default:
+ ASSERT(0);
+ return STATUS_FAIL;
+ break;
+ }
+
+ /*should not arrive here*/
+ ASSERT(0);
+ return STATUS_FAIL;
+#else
+ /*if (__MSDC_MSPRO__) is not defined, it is impossible to support this command*/
+ ASSERT(0);
+ return STATUS_UNSUPPORTED;
+#endif
+}
+
+DCL_STATUS DclMS_Close(DCL_HANDLE handle)
+{
+ DCL_SD_IMPLEMENTATION_ASSERT;
+ return STATUS_UNSUPPORTED;
+}
+#endif
+
+#else /*!defined(DRV_MSDC_OFF)*/
+
+static kal_bool fgMSDCInit = KAL_FALSE;
+DCL_STATUS DclSD_Initialize(void)
+{
+ kal_uint32 maskedValue;
+
+ maskedValue = SaveAndSetIRQMask();
+ /*a sync mechanism to guarantee MSDC_Initialize is only called once*/
+ if(KAL_FALSE == fgMSDCInit){
+ fgMSDCInit = KAL_TRUE;
+ RestoreIRQMask(maskedValue);
+ MSDC_Initialize();
+ }
+ else{
+ RestoreIRQMask(maskedValue);
+ }
+
+ return STATUS_OK;
+}
+
+DCL_STATUS DclSD_DeInitialize(void)
+{
+ return STATUS_FAIL;
+}
+
+DCL_HANDLE DclSD_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+ return DCL_HANDLE_INVALID;
+}
+
+DCL_STATUS DclSD_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSD_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSD_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSD_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+ return STATUS_FAIL;
+}
+
+DCL_STATUS DclSD_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ return STATUS_FAIL;
+}
+
+DCL_STATUS DclSD_Close(DCL_HANDLE handle)
+{
+ return STATUS_FAIL;
+}
+
+
+DCL_STATUS DclSDIO_Initialize(void)
+{
+ return STATUS_FAIL;
+}
+
+DCL_HANDLE DclSDIO_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+ return DCL_HANDLE_INVALID;
+}
+
+DCL_STATUS DclSDIO_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSDIO_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSDIO_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSDIO_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+ return STATUS_FAIL;
+}
+
+DCL_STATUS DclSDIO_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ return STATUS_FAIL;
+}
+
+DCL_STATUS DclSDIO_Close(DCL_HANDLE handle)
+{
+ return STATUS_FAIL;
+}
+
+DCL_STATUS DclMS_Initialize(void)
+{
+ return STATUS_FAIL;
+}
+
+DCL_HANDLE DclMS_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+ return DCL_HANDLE_INVALID;
+}
+
+DCL_STATUS DclMS_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclMS_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclMS_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclMS_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+ return STATUS_FAIL;
+}
+
+DCL_STATUS DclMS_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ return STATUS_FAIL;
+}
+
+DCL_STATUS DclMS_Close(DCL_HANDLE handle)
+{
+ return STATUS_FAIL;
+}
+
+
+#endif /*!defined(DRV_MSDC_OFF)*/
+
+#endif //DCL_MSDC_INTERFACE
+
diff --git a/mcu/driver/storage/mc/src/msdc.c b/mcu/driver/storage/mc/src/msdc.c
new file mode 100644
index 0000000..28328cf
--- /dev/null
+++ b/mcu/driver/storage/mc/src/msdc.c
@@ -0,0 +1,3956 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * msdc.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * driver functons for MSDC controller
+ *
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include "drv_features.h"
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "md_drv_sap.h"
+#include "drv_msgid.h"
+#include "kal_general_types.h"
+#include "kal_public_defs.h"
+#include "kal_public_api.h"
+#include "kal_debug.h"
+#include "hisr_config.h"
+#include "config_hw.h"
+#include "init.h"
+
+#include "kal_trace.h"
+#include "dcl.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#include "kal_public_api.h"
+#include "kal_public_api.h" //MSBB change #include "app_ltlcom.h" /* Task message communiction */
+#include "intrCtrl.h"
+#include "reg_base.h"
+#include "drvpdn.h"
+#include "drv_features.h"
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#include "drv_hisr.h"
+#include "sleepdrv_interface.h"
+#include "eint.h"
+
+#if !defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+#include "msdc_api.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "../../../devdrv/iomux/inc/drv_iomux.h"
+
+//! EMB
+#include "FTL.h"
+
+#if defined(__MSDC_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
+#include "sdio_sw.h"
+#endif
+#if defined(__MSDC_MS__)
+#include "ms_def.h"
+#elif defined(__MSDC_MSPRO__)
+#include "mspro_def.h"
+#endif
+#include "upll_ctrl.h"
+//#include "gpio_sw.h"
+#include "drv_trc.h"
+#if defined(__AUDIO_DSP_LOWPOWER__)
+#include "audlp_exp.h"
+#endif
+
+#ifdef DRV_LSD
+#include "msdc_lsd.h"
+#endif
+
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON1
+#error "__CLKG_DEFINE__ & DRVPDN_CON1 are all defined"
+#else
+#define DRVPDN_CON1 CG_CON1
+#endif
+
+#ifdef DRVPDN_CON1_SIM
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SIM are all defined"
+#else
+#define DRVPDN_CON1_SIM CG_CON1_SIM
+#endif
+
+#ifndef MSDC_TEST_MSDC2_FROM_MSDC1_CODE
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC CG_CON1_MSDC
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR CG_CLR1
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET CG_SET1
+#endif
+
+#else /*when MSDC_TEST_MSDC2_FROM_MSDC1_CODE is defined, we direct CON1 related macro to CON0 related*/
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR CG_CLR0
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET CG_SET0
+#endif
+#endif//MSDC_TEST_MSDC2_FROM_MSDC1_CODE
+
+#endif
+
+
+
+
+/*
+#if !(defined __MSDC_NOT_SUPPORT_HOT_PLUG__)
+#if defined(MT6218B_FN) || defined(MT6219_EV) ||defined(MT6217)||defined(MT6227)||defined(MT6226)||defined(MT6226M)\
+ || defined(MT6225)
+#define USE_INT26_CARD_DETECTION
+#endif
+#endif
+*/
+
+
+#if defined (WISDOM35B_DEMO_BB)
+extern const char gpio_SD_det_pin;
+#endif
+
+// global variable
+MSDC_HANDLE MSDC_Blk[SD_NUM];
+
+#if (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__)|| defined(__MSDC_MSPRO__)) || defined(__MSDC_SD_SDIO__)
+MSDC_HANDLE *gMSDC_Handle = &(MSDC_Blk[0]);
+
+#if defined(__UBL__) && defined(__EMMC_BOOTING__)
+__attribute__ ((zero_init, section ("EXT_UN_INIT_ZI")))kal_uint32 MSDC_Sector[128];
+__attribute__ ((zero_init, section ("EXT_UN_INIT_ZI")))kal_uint32 MSDC_eCSD[128];
+#ifdef MSDC_CACHED_SUPPORT
+__attribute__ ((zero_init, section ("EXT_UN_INIT_ZI")))kal_uint32 msdc_uncachedBuf[MSDC_UNCACHED_BUF_SIZE / 4];
+#endif
+#else
+__attribute__ ((zero_init, section ("NONCACHEDZI")))kal_uint32 MSDC_Sector[128];
+__attribute__ ((zero_init, section ("NONCACHEDZI")))kal_uint32 MSDC_eCSD[128];
+#ifdef MSDC_CACHED_SUPPORT
+__attribute__ ((zero_init, section ("NONCACHEDZI")))kal_uint32 msdc_uncachedBuf[MSDC_UNCACHED_BUF_SIZE / 4];
+#endif
+#endif
+//Light 120907
+#define MSDC_DMA_BURSTLEN_LIMIT 0xFFFFFFFF//4294966784 //32bit
+//#define MSDC_DMA_BURSTLEN_LIMIT 65024
+kal_bool MSDC_useDMA4ByteBurst = KAL_FALSE;
+
+/* Debug log */
+kal_uint32 MSDC_DebugLevel;
+
+/* IO configurations */
+static struct msdc_cust msdc_cap = {
+ 0, /* host clock source */
+ 1, /* command latch edge */
+ 1, /* read data latch edge */
+ 1, /* write data latch edge */
+
+ {6, 6, 0, 0, 1, 0, 1},
+ {4, 4, 0, 0, 1, 0, 1},
+ {4, 4, 0, 0, 1, 0, 1},
+
+ 8, /* data pins */
+ 0, /* data address offset */
+
+ /* hardware capability flags */
+ 0,
+};
+
+#ifdef __TST_WRITE_TO_FILE__
+/*error recording: add this additional global variable to use when in error recording*/
+MSDC_HANDLE MSDC_ErrorRecordingBlk;
+#endif
+
+#if defined(DRV_MSDC_SHARE_BY_SWITCH)
+sd_select_enum current_card; // active card
+#if !defined(__CUST_NEW__)
+extern kal_char MSDC_GetLDO_GPIO(void);
+extern kal_char MSDC_GetSwitch_GPIO(void);
+extern kal_char MSDC_GetEXTLDO_GPIO(void);
+extern kal_char MSDC_GetSwitchDirection(void);
+kal_char gpio_simplug_ldo_switch;
+kal_char gpio_ext_sd_ldo_switch;
+kal_char gpio_sim_msdc_switch;
+#endif
+#endif
+
+#if !defined(DRV_LSD) && defined(__DRV_DBG_MEMORY_TRACE_SUPPORT__) && !defined(__UBL__)
+msdc_debugMessage msdc_msgArray[MSDC_DBG_ARRAY_SIZE];
+kal_uint32 msdc_msdIndex;
+#endif
+
+#define MSDC_EINT_NUM MSDC_EINT_NO
+
+
+// system control blocks
+
+// function predeclaration
+void MSDC_DMAInit(void);
+void MSDC_INT_Init(void);
+void MSDC_DMA_Callback(void);
+void MSDC_EINT_Handler(void);
+void MSDC_turnOnVMC(kal_bool turnOnLdo);
+#ifdef R1B_INTERRUPT_MODE
+static void MSDC_R1B_Init();
+#endif
+
+
+extern void GPIO_ModeSetup(kal_uint16 pin, kal_uint16 conf_dada);
+extern kal_bool INT_USBBoot(void);
+extern kal_int8 MSDC_GetDLTFromOPCLK(kal_uint32 opClk, kal_uint8 *setRED);
+extern void SD_Sleep4Wait(kal_int32 sleep_tick);
+extern void msdc_tune_init(void);
+
+#ifdef __CARD_DOWNLOAD__
+extern kal_bool MSDC_QueryIsPowerControllable(void);
+extern void MSDC_SetPower(kal_bool enable);
+#endif
+
+#if !defined(_MSDC_INTERNAL_CD_INT_PIN_)
+
+#if defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+#error "__MSDC_NOT_SUPPORT_HOT_PLUG__ shouldn't be defined."
+#endif
+extern const unsigned char MSDC_EINT_NO;
+static kal_uint32 MSDC_debounceTime;
+static kal_bool cardDetectionEINTPolarity;
+#endif
+
+#if defined(__UBL__) || defined(__FUE__)
+kal_bool MSDC_START_TIMER(kal_uint16 x)
+{
+ gMSDC_Handle->is_timeout = KAL_FALSE;
+}
+#else// defined(__UBL__) || defined(__FUE__)
+
+kal_bool MSDC_START_TIMER(kal_uint16 x)
+{
+ //DCL_HANDLE gpt_handle;
+ DCL_STATUS status;
+ SGPT_CTRL_START_T start;
+
+#if defined(MSDC_DEBUG_INFO)
+ strcpy(gMSDC_Handle->msdc_fname, __FILE__);
+ gMSDC_Handle->msdc_lines = __LINE__;
+#endif
+
+ gMSDC_Handle->is_timeout = KAL_FALSE;
+ start.u2Tick = x;
+ start.pfCallback = MSDC_TimeOutHandler;
+ start.vPara = NULL;
+ //gpt_handle= module |MSDC_GPT_CB_MAGIC_NUM;
+ status = DclSGPT_Control(MSDC_Blk[0].gpt_handle, SGPT_CMD_START, (DCL_CTRL_DATA_T*)&start);
+ //dbg_print("start timer++++++++%d+++++\r\n",drv_get_current_time());
+ if (STATUS_OK == status)
+ return KAL_TRUE;
+ else
+ return KAL_FALSE;
+}
+#endif// defined(__UBL__) || defined(__FUE__)
+
+#if defined(__UBL__) || defined(__FUE__)
+kal_bool MSDC_STOP_TIMER()
+{
+ return KAL_TRUE;
+}
+#else// defined(__UBL__) || defined(__FUE__)
+kal_bool MSDC_STOP_TIMER()
+{
+
+
+ //MSDC_GPTI_StopItem(gMSDC_Handle->gpt_handle);
+ DclSGPT_Control(MSDC_Blk[0].gpt_handle, SGPT_CMD_STOP, 0);
+ if (gMSDC_Handle->is_timeout ||!gMSDC_Handle->mIsPresent)
+ {
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+ }
+ //dbg_print("stop timer +++++++%d++++++++\r\n",drv_get_current_time());
+ return KAL_TRUE;
+}
+#endif// defined(__UBL__) || defined(__FUE__)
+
+#if !defined(__FUE__) && !defined(__UBL__)
+void MSDC_GPTI_BusyWait(kal_uint16 len)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+}
+
+kal_uint8 MSDC_GPTI_GetHandle(DCL_HANDLE *handle)
+{
+ //DCL_HANDLE gpt_handle;
+ *handle = DclSGPT_Open(DCL_GPT_CB, 0);
+
+ //*handle = 0xFF & gpt_handle;
+
+ return KAL_TRUE;
+}
+
+#endif//!defined(__FUE__) && !defined(__UBL__)
+
+/*************************************************************************
+* FUNCTION
+* MSDC_SetClock
+*
+* DESCRIPTION
+*
+* PARAMETERS
+* clock: the desired operating clock rate in the unit of kHz
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_uint32 MSDC_SetClock(kal_uint32 bus_clock,kal_bool ddr_mode)
+{
+ kal_uint32 msdc_clock,op_clock=0;
+ kal_uint32 div,mode;
+ if (!gMSDC_Handle->msdc_clock)
+ {
+ /*didn't set source clock*/
+ MSDC_ERR("[MSDC][%s %d]set clock before set source clock\r\n",__FUNCTION__,__LINE__);
+ return MSDC_ERROR;
+ }
+
+ msdc_clock=gMSDC_Handle->msdc_clock;
+
+ if (!(bus_clock))
+ {
+ MSDC_RESET();
+ MSDC_ENABLE_CARD_CLOCK(KAL_TRUE);
+ MSDC_ERR("[MSDC][%s %d]can't set bus clock to %d\r\n",__FUNCTION__,__LINE__,bus_clock);
+ return MSDC_ERROR;
+ }
+
+ /* Check the MAX bus clock which could be supportted by driver */
+ if (bus_clock > gMSDC_Handle->op_clock_max)
+ bus_clock = gMSDC_Handle->op_clock_max;
+
+ /*need disable irq*/
+
+ MSDC_ENABLE_CARD_CLOCK(KAL_FALSE);
+
+ if (ddr_mode){
+ mode=USE_DDR_MODE;
+ if (bus_clock>=(msdc_clock >> 2)){
+ div=0;
+ op_clock=msdc_clock >> 2;
+ }
+ else
+ {
+ bus_clock=bus_clock << 1;
+ div=(msdc_clock+((bus_clock << 2)-1))/(bus_clock << 2);
+ op_clock=(msdc_clock>>2)/div;
+ op_clock=op_clock>>1;
+ }
+ }
+ else
+ {
+ if (bus_clock >=msdc_clock)
+ {
+ //dbg_print("entry bus_clock==msdc_clock\r\n");
+ mode =USE_MSDC_SRC_CK;
+ div=0;
+ op_clock=msdc_clock;
+ }
+ else
+ {
+ mode =USE_CLOCK_DIV;
+ if (bus_clock >= (msdc_clock >> 1))
+ {
+
+ div=0;
+ op_clock=msdc_clock>>1;
+ //dbg_print("entry bus_clock >= (msdc_clock>>1),op_clock=%d\r\n",op_clock);
+ } else {
+
+ div=(msdc_clock+((bus_clock << 2)-1))/(bus_clock << 2);
+ op_clock=(msdc_clock >> 2)/div;
+ //dbg_print("entry bus_clock <(msdc_clock>>1),bus_clock=%d ,op_clock=%d,msdc_clock=%d\r\n",bus_clock,op_clock,msdc_clock);
+ }
+ }
+ }
+
+ gMSDC_Handle->op_clock=op_clock;
+ gMSDC_Handle->msdc_clock=msdc_clock;
+ //dbg_print("op_clock=%d ,msdc_clock=%d,div=%x\r\n",op_clock,msdc_clock,div);
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, mode, MSDC_CFG_CKMOD);
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG,div,MSDC_CFG_CKDIV);
+ if (MSDC_TIMEOUT_WAIT((MSDC_Reg32(MSDC_CFG)&MSDC_CFG_CKSTB),500))
+ {
+ MSDC_ERR("[MSDC][%s %d]wait clock stable 500ms,then timeout \r\n",__FUNCTION__,__LINE__);
+ return MSDC_ERROR;
+ }
+ //dbg_print("MSDC_CFG=%x\r\n",MSDC_Reg32(MSDC_CFG));
+
+ /*open irq*/
+ MSDC_CRIT("[MSDC][%s %d] SET_CLK(%dkHz): SCLK(%dkHz) MODE(%d) DDR(%d) DIV(%d)\r\n",
+ __FUNCTION__,__LINE__, bus_clock / 1000, op_clock / 1000, mode, ddr_mode, div);
+
+ MSDC_ENABLE_CARD_CLOCK(KAL_TRUE);
+ return MSDC_OK;
+
+}
+
+kal_uint32 uffs(kal_uint32 x)
+{
+ kal_uint32 r=1;
+ if (!x)
+ {
+ return 0 ;
+ }
+ if (!(x&0xffff))
+ {
+ x>>=16;
+ r+=16;
+ }
+ if (!(x&0xff))
+ {
+ x>>=8;
+ r+=8;
+ }
+ if (!(x&0xf))
+ {
+ x>>=4;
+ r+=4;
+ }
+ if (!(x&0x3))
+ {
+ x>>=2;
+ r+=2;
+ }
+ if (!(x&0x1))
+ {
+ x>>=1;
+ r+=1;
+ }
+ return r;
+}
+
+
+void msdc_sleep(kal_uint32 ticks)
+{
+ if ((kal_query_systemInit() == KAL_TRUE)
+ #ifdef __TST_WRITE_TO_FILE__ /*error recording: considering error recording additionally*/
+ || (KAL_TRUE == INT_QueryExceptionStatus())
+ #endif
+ #ifndef __MTK_TARGET__
+ || KAL_TRUE == FTL_isPollingMode()
+ #endif
+ )
+ {
+ MSDC_GPTI_BusyWait(ticks*5);
+ }
+ else
+ {
+ kal_sleep_task(ticks);
+ }
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_SetClockSource
+*
+* DESCRIPTION
+*
+* PARAMETERS
+* type: the desired operating clock source
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+#if (CHIP_VER == 0)
+void MSDC_SetClockSource(T_MSDC_CLK_TYPE type)
+{
+ kal_uint32 orig_val;
+ // 3'b000: 26MHz
+ // 3'b001: 40MHz
+ // 3'b010: 50MHz
+ // 3'b011: 60MHz
+ // 3'b100: 69MHz
+ // 3'b101: 80MHz
+ // 3'b110: 96MHz
+ // 3'b111: 100MHz
+ #define MSDC_SOURCE_SEL_ADDR (0xBF814004)
+ orig_val=MSDC_Reg32(MSDC_SOURCE_SEL_ADDR);
+ orig_val=orig_val&(~0x7);
+ switch (type)
+ {
+ case SRC_26M:
+ MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_26M);
+ gMSDC_Handle->msdc_clock=26000000;
+ gMSDC_Handle->op_clock_max = 13000000;
+ break;
+
+ case SRC_40M:
+ MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_40M);
+ gMSDC_Handle->msdc_clock=40000000;
+ gMSDC_Handle->op_clock_max = 20000000;
+ break;
+ case SRC_50M:
+ MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_50M);
+ gMSDC_Handle->msdc_clock=50000000;
+ gMSDC_Handle->msdc_clock=35000000;
+ gMSDC_Handle->op_clock_max = 17000000;
+ break;
+ case SRC_60M:
+ MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_60M);
+ gMSDC_Handle->msdc_clock=60000000;
+ gMSDC_Handle->op_clock_max = 30000000;
+ break;
+ case SRC_69M:
+ MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_69M);
+ gMSDC_Handle->msdc_clock=69000000;
+ gMSDC_Handle->op_clock_max = 35000000;
+ break;
+ case SRC_80M:
+ MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_80M);
+ gMSDC_Handle->msdc_clock=80000000;
+ gMSDC_Handle->op_clock_max = 40000000;
+ break;
+ case SRC_96M:
+ MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_96M);
+ gMSDC_Handle->msdc_clock=96000000;
+ gMSDC_Handle->op_clock_max = 48000000;
+ break;
+ case SRC_100M:
+ MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_100M);
+ gMSDC_Handle->msdc_clock=100000000;
+ gMSDC_Handle->op_clock_max = 50000000;
+ break;
+ default:
+ MSDC_WriteReg32(MSDC_SOURCE_SEL_ADDR,orig_val|SRC_26M);
+ gMSDC_Handle->msdc_clock=26000000;
+ MSDC_ERR("[MSDC][%s %d]unknow source CLK %d\r\n",__FUNCTION__,__LINE__,type);
+ break;
+ }
+}
+#elif (CHIP_VER == 1)
+
+#define MSDC_OP_SCLK (200000000)
+#define MSDC_MAX_SCLK (200000000)
+void MSDC_SetClockSource(T_MSDC_CLK_TYPE type)
+{
+ gMSDC_Handle->msdc_clock = MSDC_OP_SCLK;
+ gMSDC_Handle->op_clock_max = MSDC_MAX_SCLK;
+}
+
+#endif
+/*************************************************************************
+* FUNCTION
+* MSDC_Check_Card_Present
+*
+* DESCRIPTION
+* c
+*
+* PARAMETERS
+* ON: turn on power saving or not
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+kal_bool MSDC_Check_Card_Present(void)
+{
+#if !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ return gMSDC_Handle->mIsPresent;
+#else
+ return KAL_TRUE;
+#endif
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_PDNControl
+*
+* DESCRIPTION
+* Enable power saving or not.
+*
+* PARAMETERS
+* ON: turn on power saving or not
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+#define MSDC_PDN_EN
+void MSDC_PDNControl(kal_bool ON)
+{
+ if (ON) {
+ #if !defined(ATEST_DRV_ENABLE)
+
+ #if defined(MSDC_PDN_EN)
+ PDN_SET(PDN_MSDC0);
+ #endif
+
+ SleepDrv_SleepEnable(gMSDC_Handle->msdc_sm_hdl);
+ #endif
+ }
+ else {
+ #if !defined(ATEST_DRV_ENABLE)
+
+ #if defined(MSDC_PDN_EN)
+ PDN_CLR(PDN_MSDC0);
+ #endif
+
+ SleepDrv_SleepDisable(gMSDC_Handle->msdc_sm_hdl);
+ #endif
+ }
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_TimeOutHandler
+*
+* DESCRIPTION
+* Callback function of gpt timer, and launched while MSDC busy for a while
+
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_TimeOutHandler(void *parameter)
+{
+ gMSDC_Handle->is_timeout=KAL_TRUE;
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events,
+ EVENT_DMA_DONE|EVENT_XFER_DONE|EVENT_CMD_DONE,KAL_OR);
+ MSDC_ERR("[MSDC][%s %d] Enter timeout handler \r\n",__FUNCTION__,__LINE__);
+}
+
+/*************************************************************************
+* FUNCTION
+* MSDC_GetCardStatus
+*
+* DESCRIPTION
+* Check currently card is present or not.
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+* msdc_eint_state
+*
+*
+*************************************************************************/
+int MSDC_GetCardStatus(void * DriveData, int AckType)
+{
+ return 0;
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_SendCardInd
+*
+* DESCRIPTION
+* Send card indication to the specified module.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_SendCardInd(module_type dest_id, sd_select_enum sel, kal_uint32 msg_id)
+{
+
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_GetMediaChanged
+*
+* DESCRIPTION
+* Check if the media is changed, and clear the status after function call
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+kal_bool MSDC_GetMediaChanged(sd_select_enum sel)
+{
+ kal_bool ret;
+
+ ENTER_CRITICAL();
+ ret = (MSDC_Blk[sel].mIsChanged ) ? (KAL_TRUE) : (KAL_FALSE);
+ MSDC_Blk[sel].mIsChanged = KAL_FALSE;
+ EXIT_CRITICAL();
+
+ return ret;
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_InvertN
+*
+* DESCRIPTION
+* Invert the order of bytes eg,
+* src: 0x01 0x02, len: 2 => dest: 0x02 0x01
+*
+* PARAMETERS
+* 1. dest: used for store inverted result
+* 2. src: source for inverting
+* 3. len: bytes for inverting
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* 1. make sure dest has the same size with src.
+*************************************************************************/
+void MSDC_InvertN(kal_uint8 *dest, kal_uint8 *src, kal_uint8 len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ *(dest + len - 1 - i) = *(src + i);
+
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_Config_INS_WP
+*
+* DESCRIPTION
+* Configure the pull up or pull down status for INS and WP pin
+*
+* PARAMETERS
+* 1. ins: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
+* 2. wp: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* 1. MT6219 can not be configured to PULL up or down. They are all pulled up by IO.
+* 2. MT6218B and MT6217, WP is configured with data lines.
+*************************************************************************/
+void MSDC_Config_INS_WP(msdc_ioctrl_enum ins, msdc_ioctrl_enum wp)
+{
+
+}
+
+void MSDC_InitializeSwitchGpio()
+{
+
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ DCL_HANDLE handle;
+#if !defined(__CUST_NEW__)
+ GPIO_LDO_SWITCH = MSDC_GetLDO_GPIO();
+ GPIO_EXT_SD_LDO_SWITCH = MSDC_GetEXTLDO_GPIO();
+ GPIO_SIM_MSDC_SWITCH = MSDC_GetSwitch_GPIO();
+#endif
+ //GPIO_ModeSetup(GPIO_SIM_MSDC_SWITCH, 0); // gpio mode (replaced by DCL)
+ handle = DclGPIO_Open(DCL_GPIO, GPIO_SIM_MSDC_SWITCH);
+ DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+ DclGPIO_Close(handle);
+ //GPIO_InitIO(OUTPUT, GPIO_SIM_MSDC_SWITCH); // replaced by DCL
+ handle = DclGPIO_Open(DCL_GPIO, GPIO_SIM_MSDC_SWITCH);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+ DclGPIO_Close(handle);
+ /*bewlow comes after JRD SIM+ issue on 2007_03_08, use custom setting instead of fix value*/
+ //GPIO_WriteIO(MSDC_GetSwitchDirection(), GPIO_SIM_MSDC_SWITCH); // replaced by DCL
+ handle = DclGPIO_Open(DCL_GPIO, GPIO_SIM_MSDC_SWITCH);
+
+ if (0 == MSDC_GetSwitchDirection())
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+ else if (1 == MSDC_GetSwitchDirection())
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
+ else
+ {
+ DclGPIO_Close(handle);
+ ASSERT(0);
+ }
+
+ DclGPIO_Close(handle);
+ /*end of changes of JRD SIM+ issue on 2007_03_08*/
+#endif
+
+}
+
+#if !defined(_MSDC_INTERNAL_CD_INT_PIN_)
+#if defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
+kal_bool EINT_DefaultPolarity = KAL_FALSE;
+#else
+kal_bool EINT_DefaultPolarity = KAL_FALSE;
+#endif
+#endif
+
+void MSDC_ConfigPin(kal_uint32 pullmode)
+{
+ /*
+ * Note that the CLK signal is a output signal,
+ * and it should be kept to the default value.
+ * that is, PULL DOWN
+ */
+ switch (pullmode)
+ {
+ case MSDC_PIN_PULL_UP:
+
+ /* For CMD pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU_DUAL_IO, 1);
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD_DUAL_IO, 0);
+ /* For DATA pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU_DUAL_IO, 1);
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD_DUAL_IO, 0);
+ break;
+
+ case MSDC_PIN_PULL_DOWN:
+
+ /* For CMD pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU_DUAL_IO, 0);
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD_DUAL_IO, 1);
+ /* For DATA pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU_DUAL_IO, 0);
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD_DUAL_IO, 1);
+
+ break;
+ case MSDC_PIN_PULL_NONE:
+ default:
+
+ /* For CMD pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU_DUAL_IO, 0);
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD_DUAL_IO, 0);
+ /* For DATA pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU_DUAL_IO, 0);
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD_DUAL_IO, 0);
+
+ break;
+ }
+}
+
+/*************************************************************************
+* FUNCTION
+* MSDC_SetHostPower
+*
+* DESCRIPTION
+* enable or disable the power of host
+*
+* PARAMETERS*
+* on: KAL_TURE enable the power, KAL_FALSE disable the power
+*
+* RETURNS
+*
+* KAL_FALSE: fail to set the power
+* KAL_TURE: success to set the power
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+kal_bool MSDC_SetHostPower(kal_bool on)
+{
+ kal_bool ret = KAL_TRUE;
+
+ return ret;
+}
+
+#if (CHIP_VER == 0)
+/*************************************************************************
+* FUNCTION
+* MSDC_SetVddPower
+*
+* DESCRIPTION
+* enable or disable the power of host
+*
+* PARAMETERS*
+* on: KAL_TURE enable the power, KAL_FALSE disable the power
+* volt: the voltage of vdd 3300 mean 3.3v
+* RETURNS
+*
+* KAL_FALSE: fail to set the power
+* KAL_TURE: success to set the power
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+kal_bool MSDC_SetVddPower(kal_bool on,kal_uint32 volt)
+{
+ kal_bool ret =KAL_TRUE;
+ if (on)
+ {
+ if (volt == 3300)
+ {
+ MSDC_ConfigPin(MSDC_PIN_PULL_UP);
+ }
+ else
+ {
+ ret = KAL_FALSE;
+ }
+ }
+ else
+ {
+ MSDC_ConfigPin(MSDC_PIN_PULL_DOWN);
+ }
+ return ret;
+}
+
+/*************************************************************************
+* FUNCTION
+* MSDC_SetSignalPower
+*
+* DESCRIPTION
+* enable or disable the power of host
+*
+* PARAMETERS*
+* on: KAL_TURE enable the power, KAL_FALSE disable the power
+* volt: the voltage of signal , 3300 mean 3.3v ,1800 mean 1.8v
+* RETURNS
+*
+* KAL_FALSE: fail to set the power
+* KAL_TURE: success to set the power
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+/*
+ CARD_PWR 1 LEVEL_PWR33 0 1.8v
+ CARD_PWR 1 LEVEL_PWR33 1 3.3v
+ CARD_PWR0 0v
+*/
+#define MSDC_CARD_PWR 26
+#define MSDC_LEVEL_PWR33 27
+kal_bool MSDC_SetSignalPower(kal_bool on,kal_uint32 volt)
+{
+ DCL_HANDLE handle;
+ kal_bool ret =KAL_TRUE;
+ if (on)
+ {
+ handle = DclGPIO_Open(DCL_GPIO, MSDC_CARD_PWR);
+ DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
+ //DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+
+ DclGPIO_Close(handle);
+ if (volt == 3300)
+ {
+ handle = DclGPIO_Open(DCL_GPIO, MSDC_LEVEL_PWR33);
+ DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
+ //DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+
+ DclGPIO_Close(handle);
+ MSDC_CRIT("[MSDC][%s %d]set signal power to 3.3v\r\n",__FUNCTION__,__LINE__);
+ gMSDC_Handle->signal_volt=3300;
+ }
+ else if (volt ==1800)
+ {
+ handle = DclGPIO_Open(DCL_GPIO,MSDC_LEVEL_PWR33);
+ DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+ //DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+
+ DclGPIO_Close(handle);
+ MSDC_CRIT("[MSDC][%s %d]set signal power to 1.8v\r\n",__FUNCTION__,__LINE__);
+ gMSDC_Handle->signal_volt=1800;
+ }
+ else
+ {
+ MSDC_ERR("[MSDC][%s %d]unknow signal power %d v\r\n",__FUNCTION__,__LINE__,volt);
+ ret = KAL_FALSE;
+ }
+ }
+ else
+ {
+ /*set signal volt to 0v*/
+ handle = DclGPIO_Open(DCL_GPIO, MSDC_CARD_PWR);
+ DclGPIO_Control(handle, GPIO_CMD_SET_OWNERSHIP_TO_MD, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+ //DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+
+ DclGPIO_Close(handle);
+ MSDC_CRIT("[MSDC][%s %d]set signal power to 0v\r\n",__FUNCTION__,__LINE__);
+ gMSDC_Handle->signal_volt=0;
+ }
+
+ return ret;
+}
+
+#elif (CHIP_VER == 1)
+
+#define LDO_VMC 0
+#define LDO_VMCH 1
+#define LDO_VIO18_PMU 2
+
+static kal_uint32 g_msdc0_io = PMU_VOLT_03_300000_V;
+static kal_uint32 g_msdc0_card = PMU_VOLT_03_300000_V;
+
+static kal_uint32 hwPowerOn(kal_uint32 powerID, PMU_VOLTAGE_ENUM powerVolt)
+{
+ PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
+ PMU_CTRL_LDO_BUCK_SET_VOLTAGE pmu_volsel;
+ DCL_HANDLE handle;
+
+ /* Open PMU handle */
+ handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
+
+ switch(powerID) {
+ case LDO_VMC:
+ /* Set enable control */
+ pmu_en.mod = VMC;
+ pmu_en.enable = 1;
+
+ /* Set voltage */
+ pmu_volsel.mod = VMC;
+ pmu_volsel.voltage = powerVolt;
+
+ DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
+ DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+
+ break;
+
+ case LDO_VMCH:
+ /* Set enable control */
+ pmu_en.mod = VMCH;
+ pmu_en.enable = 1;
+
+ /* Set voltage */
+ pmu_volsel.mod = VMCH;
+ pmu_volsel.voltage = powerVolt;
+
+ DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
+ DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+
+ break;
+
+ default:
+ break;
+ }
+
+ /* Close PMU handle */
+ DclPMU_Close(handle);
+
+ return 1;
+}
+
+static kal_uint32 hwPowerDown(kal_uint32 powerID)
+{
+ PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
+ DCL_HANDLE handle;
+
+ /* Open PMU handle */
+ handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
+
+ switch(powerID) {
+ case LDO_VMC:
+ /* Set enable control */
+ pmu_en.mod = VMC;
+ pmu_en.enable = 0;
+
+ DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+ break;
+
+ case LDO_VMCH:
+ /* Set enable control */
+ pmu_en.mod = VMCH;
+ pmu_en.enable = 0;
+
+ DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+
+ break;
+
+ default:
+ break;
+ }
+
+ /* Close PMU handle */
+ DclPMU_Close(handle);
+
+ return 1;
+}
+
+static kal_uint32 msdc_ldo_power(kal_uint32 on, kal_uint8 powerId,
+ PMU_VOLTAGE_ENUM powerVolt, kal_uint32 *status)
+{
+ if (on) { // want to power on
+ if (*status == 0) { // can power on
+ MSDC_CRIT("msdc LDO<%s> power on<%d>\r\n",
+ powerId ? "VMCH" : "VMC", powerVolt);
+
+ hwPowerOn(powerId, powerVolt);
+
+ *status = powerVolt;
+ } else if (*status == powerVolt) {
+ MSDC_CRIT("msdc LDO<%s><%d> power on again!\r\n",
+ powerId ? "VMCH" : "VMC", powerVolt);
+ } else { // for sd3.0 later
+ MSDC_CRIT("msdc LDO<%s> change<%d> to <%d>\r\n",
+ powerId ? "VMCH" : "VMC", *status, powerVolt);
+
+ hwPowerDown(powerId);
+ hwPowerOn(powerId, powerVolt);
+
+ *status = powerVolt;
+ }
+ } else { // want to power off
+ if (*status != 0) { // has been powerred on
+ MSDC_CRIT("msdc LDO<%s> power off\r\n", powerId ? "VMCH" : "VMC");
+
+ hwPowerDown(powerId);
+
+ *status = 0;
+ } else {
+ MSDC_CRIT("LDO<%s> not power on\r\n", powerId ? "VMCH" : "VMC");
+ }
+ }
+
+ return 0;
+}
+
+void msdc_set_smt(kal_bool clk, kal_bool cmd, kal_bool dat)
+{
+ clk &= 0xF;
+ cmd &= 0xF;
+ dat &= 0xF;
+
+ /* For CLK pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSMT, clk);
+ /* For CMD pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSMT, cmd);
+ /* For DATA pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSMT, dat);
+}
+
+void msdc_set_slew_rate(int clk,int cmd, int dat)
+{
+ clk &= 0x1;
+ cmd &= 0x1;
+ dat &= 0x1;
+
+ /* For CLK pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSR, clk);
+ /* For CMD pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSR, cmd);
+ /* For DATA pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSR, dat);
+}
+
+void msdc_set_rdsel(kal_bool clk, kal_bool cmd, kal_bool dat)
+{
+ clk &= 0xF;
+ cmd &= 0xF;
+ dat &= 0xF;
+
+ /* For CLK pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKRDSEL, clk);
+ /* For CMD pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDRDSEL, cmd);
+ /* For DATA pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATRDSEL, dat);
+}
+
+void msdc_set_tdsel(kal_bool clk, kal_bool cmd, kal_bool dat)
+{
+ clk &= 0xF;
+ cmd &= 0xF;
+ dat &= 0xF;
+
+ /* For CLK pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKTDSEL, clk);
+ /* For CMD pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDTDSEL, cmd);
+ /* For DATA pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATTDSEL, dat);
+}
+
+void msdc_set_driving(struct msdc_cust *hw, kal_bool sd_18)
+{
+ if (sd_18) {
+ /* For CLK pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRV, hw->io_clk.io_drv_18);
+ /* For CMD pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRV, hw->io_cmd.io_drv_18);
+ /* For DATA pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRV, hw->io_dat.io_drv_18);
+ } else {
+ /* For CLK pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRV, hw->io_clk.io_drv_33);
+ /* For CMD pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRV, hw->io_cmd.io_drv_33);
+ /* For DATA pin */
+ MSDC_SET_FIELD(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRV, hw->io_dat.io_drv_33);
+ }
+
+}
+
+int msdc_io_init()
+{
+ struct msdc_cust *pmsdc_cust = NULL;
+
+ pmsdc_cust = &msdc_cap;
+
+ if (!pmsdc_cust) {
+ MSDC_ERR("<%s> : Invalid host ID!\r\n", __FUNCTION__);
+ goto exit;
+ }
+
+ /* RDSEL Init */
+ msdc_set_rdsel(pmsdc_cust->io_clk.rdsel, pmsdc_cust->io_cmd.rdsel,
+ pmsdc_cust->io_dat.rdsel);
+
+ /* TDSEL Init */
+ msdc_set_tdsel(pmsdc_cust->io_clk.tdsel, pmsdc_cust->io_cmd.tdsel,
+ pmsdc_cust->io_dat.tdsel);
+
+ /* SMTen Init */
+ msdc_set_smt(pmsdc_cust->io_clk.smten, pmsdc_cust->io_cmd.smten,
+ pmsdc_cust->io_dat.smten);
+
+ /* Slew Rate Init */
+ msdc_set_slew_rate(pmsdc_cust->io_clk.slew, pmsdc_cust->io_cmd.slew,
+ pmsdc_cust->io_dat.slew);
+
+ /* IO driving Init */
+ msdc_set_driving(pmsdc_cust, 0);
+
+exit:
+
+ return 1;
+}
+
+void msdc_pin_init()
+{
+ /* Pin config for MSDC0 */
+#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
+ /* Set to MSDC function(INS and WP) */
+ IOMUX_set_module_func(0, sel_msdc0p_0);
+#else
+ /* Set GPIO/EINT function, both for INS and WP */
+ IOMUX_set_module_func(4, sel_msdc0p_0);
+
+ #ifdef ATEST_DRV_MSDC
+ GPIO_init();
+ EINT_Setting_Init();
+ #endif
+
+#endif
+
+ IOMUX_set_module_func(0, sel_msdc0p_1);
+ IOMUX_set_module_func(0, sel_msdc0p_2);
+
+ return;
+}
+
+kal_bool MSDC_SetVddPower(kal_bool on, kal_uint32 volt)
+{
+ kal_bool ret =KAL_TRUE;
+
+ if (on)
+ MSDC_ConfigPin(MSDC_PIN_PULL_UP);
+
+ if (volt == 3300)
+ {
+ msdc_ldo_power(on, LDO_VMCH, PMU_VOLT_03_300000_V, &g_msdc0_card);
+ }
+ else
+ {
+ MSDC_ERR("[MSDC][%s %d]unknow signal power %d v\r\n",
+ __FUNCTION__, __LINE__, volt);
+
+ ret = KAL_FALSE;
+ }
+
+ if (!on)
+ MSDC_ConfigPin(MSDC_PIN_PULL_UP);
+
+ return ret;
+}
+
+kal_bool MSDC_SetSignalPower(kal_bool on,kal_uint32 volt)
+{
+ kal_bool ret =KAL_TRUE;
+ if (volt == 3300)
+ {
+ msdc_ldo_power(on, LDO_VMC, PMU_VOLT_03_300000_V, &g_msdc0_io);
+ msdc_set_driving(&msdc_cap, 0);
+ }
+ else if (volt ==1800)
+ {
+ msdc_ldo_power(on, LDO_VMC, PMU_VOLT_01_800000_V, &g_msdc0_io);
+ msdc_set_driving(&msdc_cap, 1);
+ }
+ else
+ {
+ MSDC_ERR("[MSDC][%s %d]unknow signal power %d v\r\n",
+ __FUNCTION__, __LINE__, volt);
+
+ ret = KAL_FALSE;
+ }
+
+ return ret;
+}
+#endif
+
+/*************************************************************************
+* FUNCTION
+* MSDC_SetAllPower
+*
+* DESCRIPTION
+* enable or disable the power of host\Vdd\signal
+*
+* PARAMETERS*
+*
+* RETURNS
+*
+* KAL_FALSE: fail to set the power
+* KAL_TURE: success to set the power
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+kal_bool MSDC_SetAllPower(kal_bool on)
+{
+ kal_bool ret=KAL_TRUE;
+
+ if (on)
+ {
+ MSDC_SetHostPower(on);
+ MSDC_SetVddPower(on,gMSDC_Handle->vdd_volt);
+ MSDC_SetSignalPower(on,gMSDC_Handle->signal_volt);
+ }
+ else
+ {
+ MSDC_SetSignalPower(on,gMSDC_Handle->signal_volt);
+ MSDC_SetVddPower(on,gMSDC_Handle->vdd_volt);
+ MSDC_SetHostPower(on);
+
+ }
+ return ret;
+
+}
+
+void power_cycle(kal_uint32 interval_ticks)
+{
+ MSDC_SetVddPower(0,gMSDC_Handle->vdd_volt);
+ msdc_sleep(interval_ticks);
+ MSDC_SetVddPower(1,gMSDC_Handle->vdd_volt);
+}
+
+/*************************************************************************
+* FUNCTION
+* MSDC_SetBusWidth
+*
+* DESCRIPTION
+* set the bus width to 1 ,4 8
+*
+* PARAMETERS*
+* bus_width : set to 1 ,4 ,8
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+void MSDC_SetBusWidth(SD_BITWIDTH bus_width)
+{
+ kal_uint32 val;
+ val=MSDC_Reg32(SDC_CFG)&(~SDC_CFG_BUSWIDTH);
+ switch(bus_width)
+ {
+ default:
+ case BIT_1W:
+ val |=(MSDC_BUS_1BITS << 16);
+ gMSDC_Handle->bus_width=1;
+ break;
+ case BIT_4W:
+ val |=(MSDC_BUS_4BITS <<16);
+ gMSDC_Handle->bus_width=4;
+ break;
+ case BIT_8W:
+ val |=(MSDC_BUS_8BITS<<16);
+ gMSDC_Handle->bus_width=8;
+ break;
+ }
+ MSDC_WriteReg32(SDC_CFG,val);
+
+ MSDC_CRIT("[MSDC][%s %d]Set to %d-bit bus width\r\n", __FUNCTION__,
+ __LINE__, gMSDC_Handle->bus_width);
+}
+
+void MSDC_FatalErrorHandle()
+{
+ /*reset msdc*/
+ MSDC_RESET();
+ /*stop dma*/
+ MSDC_STOP_DMA();
+ /*clear fifo*/
+ MSDC_CLR_FIFO_EX();
+ /*clear ints*/
+ MSDC_CLR_INT();
+ /**/
+}
+
+ kal_uint32 MSDC_PollInts(kal_uint32 int_mask,kal_uint32 timeout_ms)
+{
+ kal_uint32 intsts;
+ if (!MSDC_TIMEOUT_WAIT((MSDC_Reg32(MSDC_INT)&int_mask),timeout_ms))
+ {
+ intsts=MSDC_Reg32(MSDC_INT);
+ MSDC_WriteReg32(MSDC_INT,intsts&int_mask);
+ return intsts&int_mask;
+ }
+
+ MSDC_ERR("[MSDC][%s %d]poll INT %d, SW timeout\r\n",__FUNCTION__,__LINE__,timeout_ms);
+ return 0;
+}
+/*************************************************************************
+* FUNCTION
+
+* MSDC_Initialize
+*
+* DESCRIPTION
+* Initialize the MS/SD host controller, called only once at drv_init
+*
+* PARAMETERS*
+*
+* RETURNS
+* 1: initailized failed
+* 0: successful
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+extern kal_semid dualMsdcArb;
+
+void MSDC_Probe (void)
+{
+ if (gMSDC_Handle->mIsProbeMSDC)
+ return;
+
+ /* PDN disable first */
+ MSDC_PDNControl(KAL_FALSE);
+
+ #if (CHIP_VER == 1)
+ msdc_io_init();
+ #endif
+
+ /*check card present or not*/
+#if defined(MSDC_HOTPLUG_EN)
+#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
+ if (MSDC_Reg32(MSDC_PS)&MSDC_PS_CDSTS)
+ gMSDC_Handle->mIsPresent=KAL_FALSE;
+ else
+ gMSDC_Handle->mIsPresent=KAL_TRUE;
+#else /* _MSDC_INTERNAL_CD_INT_PIN_ */
+ {
+ DCL_HANDLE handle;
+
+ GPIO_CTRL_READ_T data;
+
+ /* when use EINT for card detect,get the status */
+ handle = DclGPIO_Open(DCL_GPIO, MSDC_INS_GPIO);
+ DclGPIO_Control(handle, GPIO_CMD_READ, (DCL_CTRL_DATA_T *)&data);
+
+ if (data.u1IOData)
+ gMSDC_Handle->mIsPresent = KAL_FALSE;
+ else
+ gMSDC_Handle->mIsPresent = KAL_TRUE;
+
+ DclGPIO_Close(handle);
+ }
+#endif
+#else /* MSDC_HOTPLUG_EN */
+ gMSDC_Handle->mIsPresent = KAL_TRUE;
+#endif
+ MSDC_CRIT("[MSDC][%s %d]Card is %s\r\n",__FUNCTION__,__LINE__,
+ gMSDC_Handle->mIsPresent ? "Present" : "Not Present");
+
+ /* If card is not exist, step over the INIT flow */
+ if (gMSDC_Handle->mIsPresent)
+ gMSDC_Handle->mIsProbeMSDC = KAL_TRUE;
+ else {
+ gMSDC_Handle->mIsProbeMSDC = KAL_FALSE;
+ goto exit;
+ }
+
+ /*set MSDC as the controller of SD*/
+ MSDC_SET_FIELD(MSDC_CFG, MSDC_CFG_MODE, 1);
+
+ /*reset MSDC ,clear FIFO*/
+ MSDC_RESET();
+ MSDC_CLR_FIFO_EX();
+ MSDC_DEBUG("[MSDC][%s %d]reset MSDC,clear FIFO\r\n",__FUNCTION__,__LINE__);
+
+ /*write crc timeout detection*/
+ MSDC_SetData32(MSDC_PATCH_BIT0,1<<30,(1<<30));
+ /*Configure To Default Data Timeout */
+ MSDC_SetData32(SDC_CFG,SDC_CFG_DTOC,(DEFAULT_DTOC<<24));
+ /*set bus width to 1 */
+ MSDC_SetBusWidth(BIT_1W);
+
+ /* Tuning parameters INIT */
+ msdc_tune_init();
+
+exit:
+ MSDC_PDNControl(KAL_TRUE);
+
+ /* Shut card power */
+ MSDC_SetVddPower(KAL_FALSE, gMSDC_Handle->vdd_volt);
+
+ /* Defaultly turn VMC to 1.8V to save power */
+ MSDC_SetSignalPower(KAL_TRUE, gMSDC_Handle->signal_volt);
+}
+
+void MSDC_Initialize(void)
+{
+ /* INIT MSDC debug flag */
+ MSDC_SetDebugLevel(K_NOTICE);
+
+ MSDC_CRIT("[MSDC][%s %d]Start init MSDC...\r\n",__FUNCTION__,__LINE__);
+
+ /*check MSDC is initalized or not */
+ if (gMSDC_Handle->mIsInitMSDC)
+ return;
+
+ gMSDC_Handle->mIsProbeMSDC = 0;
+
+ /*init gSD*/
+ kal_mem_set(gSD,0,sizeof(T_SDC_HANDLE));
+
+ /* Set voltage of single and card power */
+ gMSDC_Handle->signal_volt = 1800;
+ gMSDC_Handle->vdd_volt = 3300;
+
+ #if !defined(ATEST_DRV_ENABLE)
+ /* Get Sleep handler */
+ gMSDC_Handle->msdc_sm_hdl = SleepDrv_GetHandle(SMP);
+ MSDC_CRIT("[MSDC][%s %d]MSDC Slp Handler: %d\r\n",
+ __FUNCTION__, __LINE__, gMSDC_Handle->msdc_sm_hdl);
+ #endif
+
+ /*set clock source */
+ MSDC_SetClockSource(SRC_80M);
+
+ #if (CHIP_VER == 1)
+ /* Pin MUX setting and IO settings */
+ msdc_pin_init();
+ #endif
+
+ /*get gpt handle*/
+ if (gMSDC_Handle->gpt_handle==0)
+ MSDC_GPTI_GetHandle(&gMSDC_Handle->gpt_handle);
+
+ /*clear and disable all interrupt*/
+ MSDC_ClearBits32(MSDC_INTEN,MSDC_Reg32(MSDC_INTEN));
+ MSDC_WriteReg32(MSDC_INT,MSDC_Reg32(MSDC_INT));
+
+ /* INIT the MSDC related registers */
+ MSDC_Probe();
+
+ /*init INT handle*/
+ MSDC_INT_Init();
+
+ /*set the function support by host*/
+ gMSDC_Handle->host_support.function1=FUN1_SDR12_DS|FUN1_SDR25_HS|FUN1_SDR50|FUN1_SDR104|FUN1_DDR50;
+ gMSDC_Handle->host_support.function2=FUN2_DEFAULT;
+ gMSDC_Handle->host_support.function3=FUN3_TYPE_B;
+ gMSDC_Handle->host_support.function4=FUN4_200MA|FUN4_400MA|FUN4_600MA|FUN4_800MA;
+
+ gMSDC_Handle->mIsInitMSDC = KAL_TRUE;
+
+ MSDC_DEBUG("[MSDC][%s %d]finish init MSDC\r\n",__FUNCTION__,__LINE__);
+}
+
+/*************************************************************************
+* FUNCTION
+* MSDC_DeInit
+*
+* DESCRIPTION
+* De-initialize the MS/SD host controller, called only once at drv_init
+*
+* PARAMETERS*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void MSDC_DeInit(void)
+{
+ /* Shutdown Card power Only */
+ MSDC_SetVddPower(KAL_FALSE, gMSDC_Handle->vdd_volt);
+
+ gMSDC_Handle->mIsProbeMSDC = KAL_FALSE;
+ gMSDC_Handle->mIsInitialized = KAL_FALSE;
+
+ return;
+}
+
+
+#ifdef __TST_WRITE_TO_FILE__
+/*error recording: add this function to do MSDC reset when error recording*/
+void MSDC_ErrorRecordingReset()
+{
+
+
+}
+#endif
+
+#ifndef DRV_LSD
+/*************************************************************************
+* FUNCTION
+* BitFieldWrite32
+*
+* DESCRIPTION
+* Write src to dest at mask position
+*
+* PARAMETERS
+* dest: destination to be update
+* src: value to be written
+* mask: bit mask
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+// Note: mask must be a continuous area during 32bits. eg,
+// dest : 00A30000 , src : BF, mask : 0000BF00.
+// after BitFieldCpy, dest : 00A3BF00, copy src to dest at mask position.
+void BitFieldWrite32(kal_uint32 * dest, kal_uint32 src, kal_uint32 mask)
+{
+ kal_uint8 bit_pos;
+ kal_uint32 tmp;
+
+ bit_pos = 0;
+ tmp = MSDC_Reg32(dest);
+
+ // get bit positoin
+ while (!((mask >> bit_pos++) & 1));
+
+ //use mask clear the corresponding area
+ tmp &= ~mask;
+ //shift src to the corresponding positiion
+ src <<= (bit_pos - 1);
+ //copy src into destination
+ tmp |= src;
+ MSDC_WriteReg32(dest, tmp);
+}
+#endif
+
+#ifdef MSDC_USED_STUFF
+/*************************************************************************
+* FUNCTION
+* BitFieldRead32
+*
+* DESCRIPTION
+* read src to dest at mask position
+*
+* PARAMETERS
+* dest: destination to store
+* src: value to be written
+* mask: bit mask
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+
+// Note: mask must ve continuous area during 32 bits.eg,
+// src : 00A3BF00, mask : 00FF0000
+// after BitFieldRead, dest : A3
+void BitFieldRead32(kal_uint32 * dest, kal_uint32 src, kal_uint32 mask)
+{
+ kal_uint8 bit_pos = 0;
+
+ while (!((mask >> bit_pos++) & 1));
+
+ src &= mask;
+ *(kal_uint32 *)dest = src >> (bit_pos - 1);
+}
+#endif//MSDC_USED_STUFF
+
+// get the bit field value of start_bit with width bits
+// note 1) start_bit start from bit 0
+// 2) prepare dest with initialized with zeros
+// 3) width must less than 32 if using the retrun value as a result
+// eg,
+// src:00110110, start_bit:2,width:3 => dest:101
+void GetBitFieldN(kal_uint8* dest, kal_uint8* src, kal_uint16 start_bit, kal_uint16 width)
+{
+ int i;
+ kal_uint16 bytes, bits;
+
+ //kal_mem_set(dest,0,width/8+1);
+ kal_mem_set(dest, 0, (width / 8) + (0 == (width % 8) ? 0 : 1));
+
+ for ( i = 0; i < width; i++)
+ {
+ bytes = (start_bit + i) / 8;
+ bits = (start_bit + i) % 8;
+ *(dest + i / 8) |= (kal_uint8)(((*(src + bytes) >> bits) & 1) << (i % 8));
+ }
+
+ /*in MT6238, address of kal_uint32 is checked strictly, and we don't need the return value of this function*/
+ /*change it's return type to void*/
+ return ;
+}
+
+#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
+void MSDC_SetLatchTuning(void)
+{
+
+}
+#else
+void MSDC_SetIOCONRegDLT(void)
+{
+
+}
+#endif//#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+void msdc_dump_reg(void)
+{
+ int idx;
+
+ MSDC_CRIT("****** [00]MSDC_CFG : %x\r\n", MSDC_Reg32(MSDC_CFG));
+ MSDC_CRIT("****** [04]MSDC_IOCON : %x\r\n", MSDC_Reg32(MSDC_IOCON));
+ MSDC_CRIT("****** [08]MSDC_PS : %x\r\n", MSDC_Reg32(MSDC_PS));
+ MSDC_CRIT("****** [0C]MSDC_INT : %x\r\n", MSDC_Reg32(MSDC_INT));
+ MSDC_CRIT("****** [10]MSDC_INTEN : %x\r\n", MSDC_Reg32(MSDC_INTEN));
+ MSDC_CRIT("****** [14]MSDC_FIFOCS : %x\r\n", MSDC_Reg32(MSDC_FIFOCS));
+ MSDC_CRIT("****** [18]MSDC_TXDATA : %x\r\n", MSDC_Reg32(MSDC_TXDATA));
+ MSDC_CRIT("****** [1C]MSDC_RXDATA : --------\r\n");
+ MSDC_CRIT("****** [30]SDC_CFG : %x\r\n", MSDC_Reg32(SDC_CFG));
+ MSDC_CRIT("****** [34]SDC_CMD : %x\r\n", MSDC_Reg32(SDC_CMD));
+ MSDC_CRIT("****** [38]SDC_ARG : %x\r\n", MSDC_Reg32(SDC_ARG));
+ MSDC_CRIT("****** [3C]SDC_STS : %x\r\n", MSDC_Reg32(SDC_STS));
+ MSDC_CRIT("****** [40]SDC_RESP0 : %x\r\n", MSDC_Reg32(SDC_RESP0));
+ MSDC_CRIT("****** [44]SDC_RESP1 : %x\r\n", MSDC_Reg32(SDC_RESP1));
+ MSDC_CRIT("****** [48]SDC_RESP2 : %x\r\n", MSDC_Reg32(SDC_RESP2));
+ MSDC_CRIT("****** [4C]SDC_RESP3 : %x\r\n", MSDC_Reg32(SDC_RESP3));
+ MSDC_CRIT("****** [50]SDC_BLK_NUM : %x\r\n", MSDC_Reg32(SDC_BLK_NUM));
+ MSDC_CRIT("****** [58]SDC_CSTS : %x\r\n", MSDC_Reg32(SDC_CSTS));
+ MSDC_CRIT("****** [5C]SDC_CSTS_EN : %x\r\n", MSDC_Reg32(SDC_CSTS_EN));
+ MSDC_CRIT("****** [60]SDC_DATCRC_STS : %x\r\n", MSDC_Reg32(SDC_DCRC_STS));
+ MSDC_CRIT("****** [70]EMMC_CFG0 : %x\r\n", MSDC_Reg32(EMMC_CFG0));
+ MSDC_CRIT("****** [74]EMMC_CFG1 : %x\r\n", MSDC_Reg32(EMMC_CFG1));
+ MSDC_CRIT("****** [78]EMMC_STS : %x\r\n", MSDC_Reg32(EMMC_STS));
+ MSDC_CRIT("****** [7C]EMMC_IOCON : %x\r\n", MSDC_Reg32(EMMC_IOCON));
+ MSDC_CRIT("****** [80]SD_ACMD_RESP : %x\r\n", MSDC_Reg32(SDC_ACMD_RESP));
+ MSDC_CRIT("****** [84]SD_ACMD19_TRG : %x\r\n", MSDC_Reg32(SDC_ACMD19_TRG));
+ MSDC_CRIT("****** [88]SD_ACMD19_STS : %x\r\n", MSDC_Reg32(SDC_ACMD19_STS));
+ MSDC_CRIT("****** [90]DMA_SA : %x\r\n", MSDC_Reg32(MSDC_DMA_SA));
+ MSDC_CRIT("****** [94]DMA_CA : %x\r\n", MSDC_Reg32(MSDC_DMA_CA));
+ MSDC_CRIT("****** [98]DMA_CTRL : %x\r\n", MSDC_Reg32(MSDC_DMA_CTL));
+ MSDC_CRIT("****** [9C]DMA_CFG : %x\r\n", MSDC_Reg32(MSDC_DMA_CFG));
+ MSDC_CRIT("****** [A8]DMA_LENGTH : %x\r\n", MSDC_Reg32(MSDC_DMA_LENGTH));
+ MSDC_CRIT("****** [B0]PATCH_BIT0 : %x\r\n", MSDC_Reg32(MSDC_PATCH_BIT0));
+ MSDC_CRIT("****** [B4]PATCH_BIT1 : %x\r\n", MSDC_Reg32(MSDC_PATCH_BIT1));
+ MSDC_CRIT("****** [E0]SD30_PAD_CTL0 : %x\r\n", MSDC_Reg32(MSDC_PAD_CTL0));
+ MSDC_CRIT("****** [E4]SD30_PAD_CTL1 : %x\r\n", MSDC_Reg32(MSDC_PAD_CTL1));
+ MSDC_CRIT("****** [E8]SD30_PAD_CTL2 : %x\r\n", MSDC_Reg32(MSDC_PAD_CTL2));
+ MSDC_CRIT("****** [EC]PAD_TUNE : %x\r\n", MSDC_Reg32(MSDC_PAD_TUNE));
+ MSDC_CRIT("****** [F0]DAT_RD_DLY0 : %x\r\n", MSDC_Reg32(MSDC_DAT_RDDLY0));
+ MSDC_CRIT("****** [F4]DAT_RD_DLY1 : %x\r\n", MSDC_Reg32(MSDC_DAT_RDDLY1));
+ MSDC_CRIT("****** [100]MAIN_VERSION : %x\r\n", MSDC_Reg32(MSDC_VERSION));
+ MSDC_CRIT("****** [104]ECO_VERSION : %x\r\n", MSDC_Reg32(MSDC_ECO_VER));
+
+ for (idx = 0; idx < 26; idx++) {
+ MSDC_WriteReg32(MSDC_DBG_SEL, idx);
+ MSDC_CRIT("=*=*=* MSDC_DBG_SEL:%d => MSDC_DBG_OUT:%x\r\n",
+ idx, MSDC_Reg32(MSDC_DBG_OUT));
+ }
+
+ MSDC_CRIT("====== MSDC Register and Debug Register Dump End ======\r\n");
+}
+
+#ifdef _MSDC_DMA_
+/*************************************************************************
+* FUNCTION
+* MSDC_DMAInit
+*
+* DESCRIPTION
+* Initialize MSDC's DMA
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_DMAInit(void)
+{
+
+}
+void MSDC_StartDMA(void)
+{
+ kal_uint32 ints=MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
+ MSDC_INTEN_DATCRCERR |MSDC_INTEN_DXFER_DONE |
+ MSDC_INTEN_BD_CS_ERR | MSDC_INTEN_GPD_CS_ERR;
+ //kal_uint32 ints=MSDC_DAT_INTS;
+ kal_uint32 abnormal_ints;
+ abnormal_ints=MSDC_Reg32(MSDC_INT)&ints;
+ if(0 != abnormal_ints)
+ {
+ /*error, have irq before we enable it*/
+ MSDC_ERR("[MSDC][%s %d]abnormal irq %x\r\n",__FUNCTION__,__LINE__,abnormal_ints);
+ MSDC_WriteReg32(MSDC_INT,abnormal_ints);
+ }
+ MSDC_SetBits32(MSDC_INTEN, ints);
+ MSDC_SET_FIELD(MSDC_DMA_CTL, MSDC_DMA_CTL_START, 1);
+ gMSDC_Handle->is_timeout=KAL_FALSE;
+ MSDC_START_TIMER(MSDC_DMA_DAT_TMO);
+}
+SDC_CMD_STATUS MSDC_ConfigDMA(kal_uint32 * buffer,kal_uint32 num,msdc_gpd_t * gpd_ptr,kal_bool isLastBuf)
+{
+ kal_uint32 dma_ctl_arg;
+ #define BURST_8Byte 3
+ #define BURST_16Byte 4
+ #define BURST_32Byte 5
+ #define BURST_64Byte 6
+ /*if (gpd_ptr==NULL)
+ {
+ gMSDC_Handle->error=ERR_ARGUMENT;
+ #ifdef MSDC_DEBUG_PRINT
+ dbg_print("[MSDC][ERROR][%s %d]gpd_ptr point to zero\r\n",__FUNCTION__,__LINE__);
+ #endif
+ return ERR_ARGUMENT;
+ }*/
+ //set to DMA mode
+ //BitFieldWrite32((kal_uint32 *)MSDC_CFG, 0, MSDC_CFG_PIO);
+ MSDC_ClearBits32(MSDC_CFG,MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=1;
+ if ((buffer==NULL) && (gpd_ptr != NULL))
+ {
+ /*use link list based DMA */
+
+ #ifdef MSDC_DMA_CHKSUM_EN
+ /*Enable descriptor 's checksum*/
+ MSDC_SET_FIELD(MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1);
+ #else
+ /*Disable descriptor 's checksum*/
+ MSDC_SET_FIELD(MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 0);
+ #endif
+
+ /*descriptor mode and burst size=64Bytes*/
+ dma_ctl_arg=(BURST_64Byte<<12)|MSDC_DMA_CTL_MODE;
+ MSDC_WriteReg32(MSDC_DMA_CTL,dma_ctl_arg);
+ /*write DMA start address to GPD's physical address*/
+ MSDC_WriteReg32(MSDC_DMA_SA,gpd_ptr);
+ }
+ else if((buffer != NULL)&& (gpd_ptr == NULL))
+ {
+
+ /*use basic DMA*/
+ /*burst size\last buffer*/
+ dma_ctl_arg = (isLastBuf==KAL_TRUE)? ((BURST_64Byte<<12)|MSDC_DMA_CTL_LASTBUF) : (BURST_64Byte<<12);
+ MSDC_WriteReg32(MSDC_DMA_CTL,dma_ctl_arg);
+ /*set xfer size*/
+ MSDC_WriteReg32(MSDC_DMA_LENGTH,num);
+ /*set address*/
+ MSDC_WriteReg32(MSDC_DMA_SA,buffer);
+ }
+ else
+ {
+ //wrong argument
+ }
+ return NO_ERROR;
+}
+SDC_CMD_STATUS MSDC_WaitDMADone()
+{
+ kal_uint32 status;
+ kal_uint32 ints= MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
+ MSDC_INTEN_DATCRCERR |MSDC_INTEN_DXFER_DONE |
+ MSDC_INTEN_BD_CS_ERR | MSDC_INTEN_GPD_CS_ERR;
+
+ /*wait DMA done*/
+ kal_retrieve_eg_events(gMSDC_Handle->MSDC_Events,EVENT_XFER_DONE|EVENT_DMA_DONE,KAL_OR_CONSUME,&status,KAL_SUSPEND);
+ MSDC_STOP_TIMER();
+ MSDC_DEBUG("[MSDC][%s]msdc_int=%x\r\n",__FUNCTION__,gMSDC_Handle->msdc_int);
+ if (gMSDC_Handle->is_timeout)
+ {
+ MSDC_ERR("[MSDC][%s %d]wait DMA done GPT timeout\r\n",__FUNCTION__,__LINE__);
+ msdc_dump_reg();
+ gMSDC_Handle->error=MSDC_GPT_TIMEOUT_ERR;
+ }
+ /*Disable interrupt*/
+ MSDC_ClearBits32(MSDC_INTEN,ints);
+ /*stop dma*/
+ MSDC_STOP_DMA();
+ return gMSDC_Handle->error;
+}
+kal_uint32 MSDC_CheckCardBusy(kal_bool send_stop,kal_uint32 timeout_ms)
+{
+ kal_uint32 start_time,status;
+ kal_uint32 err,count=0;
+ start_time = drv_get_current_time();
+
+ do{
+ err=SD_GetStatus(gSD->mRCA, &status);
+ if(err)
+ {
+ break;
+ }
+ count++;
+ if(count%5000==0)
+ {
+ if(send_stop)
+ {
+ SD_StopTrans();
+ }
+ }
+ }while((!(status&R1_READY_FOR_DATA_8)||(R1_CURRENT_STATE(status)==7))&&(drv_get_duration_ms(start_time) <=timeout_ms));
+ if (!(drv_get_duration_ms(start_time) <=timeout_ms))
+ {
+ MSDC_ERR("[MSDC][%s %d]card busy timeout\r\n",__FUNCTION__,__LINE__);
+ gMSDC_Handle->error=err=ERR_CARD_BUSY_TIMEOUT;
+ }
+ return err;
+}
+/************************************************************************
+* FUNCTION
+* MSDC_DMATransferFinal_In_Callback
+*
+* DESCRIPTION
+* Initialize MSDC's DMA
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+#if defined(MSDC_START_DMA_IN_CALLBACK)
+
+void MSDC_DMATransferFinal_In_Callback(void)
+{
+
+}
+
+kal_uint32 MSDC_DMATransferFinal(void)
+{
+
+}
+#endif
+/*************************************************************************
+* FUNCTION
+* MSDC_DMATransfer
+*
+* DESCRIPTION
+* MSDC using DAM for data transfer
+*
+* PARAMETERS
+* adrs: data buffer
+* count: bytes to be transfered
+* isTx: ture for move data from MSDC to data buffer and vise versa
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+extern kal_bool FTL_isPollingMode();
+void MSDC_DMATransferFirst( kal_bool isWrite,kal_bool isLinkListBuf)
+{
+ kal_uint32 * adrs;
+
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events,0,KAL_AND);
+ if (isLinkListBuf)
+ {
+ /*configure DMA*/
+ MSDC_ConfigDMA(NULL,gMSDC_Handle->total_count,(msdc_gpd_t *)gMSDC_Handle->buf_addr,1);
+ }
+ else
+ {
+ adrs=gMSDC_Handle->buf_addr;
+ #ifdef MSDC_CACHED_SUPPORT
+ if (gMSDC_Handle->isRomSpace)
+ {
+ gMSDC_Handle->trans_count=(gMSDC_Handle->total_count > MSDC_UNCACHED_TRANSFER_SIZE) ? (MSDC_UNCACHED_TRANSFER_SIZE) : gMSDC_Handle->total_count;
+ /*copy from upper application buffer*/
+ if (isWrite)
+ {
+ kal_mem_cpy((void *)msdc_uncachedBuf,(void*)gMSDC_Handle->buf_addr,gMSDC_Handle->trans_count);
+ }
+ adrs=(kal_uint32 *)msdc_uncachedBuf;
+ }
+ else if (gMSDC_Handle->isCachedBuf)
+ {
+ //clear cache
+ gMSDC_Handle->trans_count=(gMSDC_Handle->total_count > MSDC_DMA_BURSTLEN_LIMIT) ? (MSDC_DMA_BURSTLEN_LIMIT) : gMSDC_Handle->total_count;
+ clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)gMSDC_Handle->buf_addr),CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)gMSDC_Handle->buf_addr,gMSDC_Handle->trans_count));
+ Data_Mem_Barrier();
+ }
+ else
+ #endif
+ {
+ gMSDC_Handle->trans_count=(gMSDC_Handle->total_count > MSDC_DMA_BURSTLEN_LIMIT) ? (MSDC_DMA_BURSTLEN_LIMIT) : gMSDC_Handle->total_count;
+ }
+ /*configure DMA*/
+ MSDC_ConfigDMA(adrs,gMSDC_Handle->trans_count,NULL,(gMSDC_Handle->total_count==gMSDC_Handle->trans_count));
+ }
+
+}
+#if !defined(MSDC_START_DMA_IN_CALLBACK)
+kal_uint32 MSDC_DMATransferFinal(kal_bool isWrite,kal_bool isLinkListBuf)
+{
+ kal_uint32 status;
+ while(1)
+ {
+ /*start DMA*/
+ MSDC_StartDMA();
+ /*wait DMA finish*/
+ status=MSDC_WaitDMADone();
+ if (status!=NO_ERROR)
+ {
+ MSDC_ERR("[MSDC][%s %d]INTS<%x>\r\n",__FUNCTION__,__LINE__,gMSDC_Handle->msdc_int);
+ goto done;
+ }
+ if (isLinkListBuf)
+ {
+ MSDC_DEBUG("[MSDC]link list DMA finish\r\n");
+ break;
+ }
+ else
+ {
+ /*copy RX data when use cached buffer*/
+ #ifdef MSDC_CACHED_SUPPORT
+ if (gMSDC_Handle->isCachedBuf)
+ {
+ /*if (!isWrite)
+ {
+ kal_mem_cpy((void *)gMSDC_Handle->buf_addr,(void *)msdc_uncachedBuf,gMSDC_Handle->trans_count);
+ }*/
+ //invalidate_dcache((gMSDC_Handle->buf_addr&~CPU_CACHE_LINE_SIZE_MASK),(gMSDC_Handle->trans_count+CPU_CACHE_LINE_SIZE_MASK)&~CPU_CACHE_LINE_SIZE_MASK);
+ }
+ #endif
+ /*check need do further transfer or not */
+ gMSDC_Handle->total_count-=gMSDC_Handle->trans_count;
+ if (gMSDC_Handle->total_count==0)
+ {
+ gMSDC_Handle->error=NO_ERROR;
+ goto done;
+ }
+ gMSDC_Handle->buf_addr+=gMSDC_Handle->trans_count;
+ MSDC_DMATransferFirst( isWrite,isLinkListBuf);
+ }
+ }
+done:
+
+ return status;
+}
+#endif //!defined(MSDC_START_DMA_IN_CALLBACK)
+
+#endif // DMA
+
+void* GetMsdcHandle(kal_uint8 id)
+{
+ return (void*)&MSDC_Blk[id];
+}
+
+#ifdef R1B_INTERRUPT_MODE
+static void MSDC_R1B_Init()
+{
+
+}
+#endif
+
+// ===========================================================
+// MSDC common lock
+// ===========================================================
+
+#if !defined(__FUE__) && !defined(__UBL__)
+
+void init_MSDC_lock(PMSDC_LOCK_TAG lock, const kal_char *str)
+{
+ if (lock->mtd_mutex == NULL)
+ {
+ strcpy((char *)lock->name, str);
+ lock->mtd_mutex = kal_create_mutex((kal_char *)lock->name);
+ lock->lock_count = 0;
+ lock->owner_id = NULL;
+ }
+}
+
+static kal_uint8 msdc_lock_user = 0;
+
+void get_MSDC_lock(PMSDC_LOCK_TAG lock)
+{
+ if (msdc_lock_user > 0)
+ ;//ASSERT(0); // init debugging purpose
+ else
+ msdc_lock_user ++;
+
+ if ( kal_query_systemInit() || INT_QueryExceptionStatus() )
+ return;
+
+ if (kal_if_hisr() == KAL_TRUE || kal_if_lisr() == KAL_TRUE)
+ {
+ kal_uint32 retaddr0 = 0;
+ GET_RETURN_ADDRESS(retaddr0);
+ EXT_ASSERT(0, retaddr0, 0, 0);
+ }
+
+ if ( kal_get_current_task() == lock->owner_id )
+ {
+ force_ASSERT(0 != lock->lock_count, lock->lock_count, (kal_uint32)lock->owner_id, (kal_uint32)lock->mtd_mutex);
+ lock->lock_count++;
+ }
+ else
+ {
+ if (lock->mtd_mutex == NULL)
+ {
+ init_MSDC_lock(lock, (const kal_char *)lock->name);
+ }
+
+ kal_take_mutex(lock->mtd_mutex);
+ // lock->owner_id = kal_get_task_self_id();
+ lock->owner_id = kal_get_current_task();
+ lock->lock_count++;
+ }
+}
+
+void free_MSDC_lock(PMSDC_LOCK_TAG lock)
+{
+ if (msdc_lock_user != 1)
+ ;//ASSERT(0); // init debugging purpose
+ else
+ msdc_lock_user --;
+
+ if ( kal_query_systemInit() || INT_QueryExceptionStatus() )
+ return;
+
+ if ( kal_get_current_task() == lock->owner_id )
+ {
+ force_ASSERT(lock->lock_count > 0, lock->lock_count, (kal_uint32)lock->owner_id, (kal_uint32)lock->mtd_mutex);
+ lock->lock_count--;
+
+ if (0 == lock->lock_count)
+ {
+ lock->owner_id = NULL;
+
+ if (lock->mtd_mutex != NULL)
+ kal_give_mutex(lock->mtd_mutex);
+ }
+ }
+ else
+ {
+ force_ASSERT(0, (kal_uint32)lock->owner_id, (kal_uint32)kal_get_current_task(), (kal_uint32)lock->mtd_mutex);
+ }
+}
+
+#else /* __FUE__, __UBL__ */
+
+//#define init_MSDC_lock(x)
+
+//#define get_MSDC_lock(x)
+
+//#define free_MSDC_lock(x)
+
+#endif /* !defined(__FUE__) && !defined(__UBL__) */
+
+#ifdef _MSDC_INT_
+
+#ifdef USE_INT26_CARD_DETECTION
+void MSDC_CardDetect_LISR(void)
+{
+
+}
+#endif //USE_INT26_CARD_DETECTION
+
+
+#ifdef DRV_LSD
+kal_uint32 MSDC_CARD_INSERT_COUNTER, MSDC_CARD_REMOVE_COUNTER;
+kal_uint32 notifiedFMT;//this variable is to sync the state, since we only allow FMT get disk infor to be the first operation that access SD
+
+
+void MSDC_LSD_HISR(void)
+{
+
+
+}
+
+void MSDC_unsealMountOperation(void)
+{
+ /*notifiedFMT may be modified by FMT and MMI tasks, but it is no need to protect this, any task that preempt FMT just get mount fail*/
+ if (1 == notifiedFMT) /*FMT may call this function no matter card exits or not*/
+ {
+ notifiedFMT = 2;
+ }
+
+}
+#endif
+
+#if !defined(_MSDC_INTERNAL_CD_INT_PIN_)
+void MSDC_CD_Entry()
+{
+ /* Reverse the polarity */
+ cardDetectionEINTPolarity = !cardDetectionEINTPolarity;
+ EINT_Set_Polarity(MSDC_EINT_NUM, cardDetectionEINTPolarity);
+
+ gMSDC_Handle->mIsChanged=KAL_TRUE;
+
+ /*memory card insertion\removal */
+ if (!cardDetectionEINTPolarity)
+ {
+ gMSDC_Handle->mIsPresent=KAL_FALSE;
+ gMSDC_Handle->mIsInitialized=KAL_FALSE;
+ #ifdef MSDC_MUST_RECORD_PLUGOUT
+ if (KAL_FALSE == gMSDC_Handle->mIsPresent)
+ gMSDC_Handle->MSDC_everPlugOut = KAL_TRUE;
+ #endif//MSDC_MUST_RECORD_PLUGOUT
+
+ MSDC_CRIT("[MSDC]Card Remove(EINT)\r\n");
+ MSDC_DeInit();
+ }
+ else
+ {
+ gMSDC_Handle->mIsPresent=KAL_TRUE;
+ gMSDC_Handle->mIsInitialized=KAL_FALSE;
+
+ MSDC_CRIT("[MSDC]Card Insert(EINT)\r\n");
+ MSDC_Probe();
+ }
+}
+#endif
+
+/*************************************************************************
+* FUNCTION
+* MSDC_INT_Init
+*
+* DESCRIPTION
+* Initialize MSDC's interrupt
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_INT_Init(void)
+{
+ /*create events group*/
+ gMSDC_Handle->MSDC_Events=kal_create_event_group("MSDC Event");
+ /*register HISR*/
+ DRV_Register_HISR(DRV_MSDC_HISR_ID,MSDC_HISR_Entry);
+ /*register LISR*/
+ IRQ_Register_LISR(MD_IRQID_MSDC0,MSDC_LISR,"MSDC ISR");
+ IRQSensitivity(MD_IRQID_MSDC0,LEVEL_SENSITIVE);
+ IRQUnmask(MD_IRQID_MSDC0);
+ /*clear IRQ */
+ MSDC_WriteReg32(MSDC_INT,MSDC_Reg32(MSDC_INT));
+
+ /*register IRQ for card detect*/
+ /*enable card detect interrupt*/
+#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
+ /*enable card detect*/
+ MSDC_SET_FIELD(MSDC_PS, MSDC_PS_CDEN, 1);
+ MSDC_SET_FIELD(MSDC_INTEN, MSDC_INTEN_CDSC, 1);
+#else
+
+ /* Polarity setting, default triggered by low level */
+ cardDetectionEINTPolarity = EINT_DefaultPolarity;
+
+ /* SW debounce time is 300ms */
+ MSDC_debounceTime=30;
+
+ EINT_Mask(MSDC_EINT_NUM); //need check the MSDC_EINT_NO ,unused current time
+
+ /* Level trigger */
+ EINT_Set_Sensitivity(MSDC_EINT_NUM, KAL_FALSE);
+
+ EINT_Registration(MSDC_EINT_NUM,KAL_TRUE,cardDetectionEINTPolarity,MSDC_CD_Entry,KAL_TRUE);
+ EINT_SW_Debounce_Modify(MSDC_EINT_NUM,MSDC_debounceTime);
+ EINT_UnMask(MSDC_EINT_NUM);
+
+#endif
+}
+void MSDC_LISR(void)
+{
+ /*Mask IRQ*/
+ IRQMask(MD_IRQID_MSDC0);
+ /*save IRQ information*/
+ gMSDC_Handle->msdc_int=MSDC_Reg32(MSDC_INT);
+ /*call hisr*/
+ drv_active_hisr(DRV_MSDC_HISR_ID);
+
+}
+
+void MSDC_DatIrqHandle(kal_uint32 intsts)
+{
+ if (intsts & MSDC_INT_XFER_COMPL){
+ gMSDC_Handle->error=NO_ERROR;
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_XFER_DONE,KAL_OR);
+ }
+ else if (intsts & MSDC_INT_DXFER_DONE)
+ {
+
+ gMSDC_Handle->error=NO_ERROR;
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_DMA_DONE,KAL_OR);
+ }
+ else
+ {
+
+ /*mean some error */
+ if (intsts & MSDC_INT_DATCRCERR)
+ {
+ gMSDC_Handle->error=ERR_DAT_CRCERR;
+ MSDC_ERR("[MSDC][%s %d]CMD%d DMA DAT CRCERR!\r\n",__FUNCTION__,
+ __LINE__, gMSDC_Handle->cmd & 0x3F);
+ }
+ else if (intsts & MSDC_INT_DATTMO)
+ {
+ gMSDC_Handle->error=ERR_DAT_TIMEOUT;
+ MSDC_ERR("[MSDC][%s %d]CMD%d DMA DAT TMO!\r\n",__FUNCTION__,
+ __LINE__, gMSDC_Handle->cmd & 0x3F);
+ } else if (intsts & MSDC_INT_BD_CS_ERR) {
+
+ gMSDC_Handle->error = ERR_DAT_TIMEOUT;
+ MSDC_ERR("[MSDC][%s %d]CMD%d DMA BD checksum ERR!\r\n",__FUNCTION__,
+ __LINE__, gMSDC_Handle->cmd & 0x3F);
+ } else if (intsts & MSDC_INT_GPD_CS_ERR) {
+
+ gMSDC_Handle->error = ERR_DAT_TIMEOUT;
+ MSDC_ERR("[MSDC][%s %d]CMD%d DMA GPD checksum ERR!\r\n",__FUNCTION__,
+ __LINE__, gMSDC_Handle->cmd & 0x3F);
+ }
+
+ /*for poll mode exit*/
+ gMSDC_Handle->abort=1;
+
+ if (gMSDC_Handle->dma_xfer)
+ {
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_XFER_DONE,KAL_OR);
+ }
+ }
+}
+void MSDC_CmdIrqHandle(kal_uint32 intsts)
+{
+ if ((intsts&MSDC_INT_CMDRDY)||(intsts&MSDC_INT_ACMDRDY)||(intsts&MSDC_INT_ACMD19_DONE))
+ {
+ gMSDC_Handle->error=NO_ERROR;
+ }
+ else if ((intsts&MSDC_INT_RSPCRCERR)||(intsts&MSDC_INT_ACMDCRCERR))
+ {
+ gMSDC_Handle->error=ERR_CMD_RSPCRCERR;
+ }
+ else if ((intsts&MSDC_INT_ACMDTMO)||(intsts&MSDC_INT_CMDTMO))
+ {
+ gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+ }
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_CMD_DONE,KAL_OR);
+}
+
+void MSDC_CardDetectHandle(kal_uint32 intsts)
+{
+#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
+
+
+ gMSDC_Handle->mIsChanged=KAL_TRUE;
+
+ /*memory card insertion\removal */
+ if (MSDC_Reg32(MSDC_PS)&MSDC_PS_CDSTS)
+ {
+ /*Card detection pin is logic high*/
+ gMSDC_Handle->mIsPresent=KAL_FALSE;
+ gMSDC_Handle->mIsInitialized=KAL_FALSE;
+ #ifdef MSDC_MUST_RECORD_PLUGOUT
+ if (KAL_FALSE == gMSDC_Handle->mIsPresent)
+ gMSDC_Handle->MSDC_everPlugOut = KAL_TRUE;
+ #endif//MSDC_MUST_RECORD_PLUGOUT
+
+ MSDC_CRIT("[MSDC]Card Remove\r\n");
+ MSDC_DeInit();
+
+ }
+ else
+ {
+ /*Card detection pin is logic low*/
+ gMSDC_Handle->mIsPresent=KAL_TRUE;
+ gMSDC_Handle->mIsInitialized=KAL_FALSE;
+
+ MSDC_CRIT("[MSDC]Card Insert\r\n");
+ MSDC_Probe();
+ }
+
+#endif
+}
+
+/*************************************************************************
+* FUNCTION
+* MSDC_HISR_Entry
+*
+* DESCRIPTION
+* Set corresponding enevt and wake up waiting task.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_HISR_Entry(void)
+{
+ kal_uint32 cmdsts =MSDC_INT_CMDRDY|MSDC_INT_CMDTMO|MSDC_INT_RSPCRCERR;
+ kal_uint32 acmdsts =MSDC_INT_ACMDRDY|MSDC_INT_ACMDTMO|MSDC_INT_ACMDCRCERR|MSDC_INT_ACMD19_DONE;
+ kal_uint32 datsts =MSDC_INT_XFER_COMPL | MSDC_INT_DXFER_DONE |
+ MSDC_INT_DATCRCERR | MSDC_INT_DATTMO |
+ MSDC_INT_BD_CS_ERR | MSDC_INT_GPD_CS_ERR;
+
+ kal_uint32 intsts_pure;
+ kal_uint32 inten, intsts;
+
+ /*Mask IRQ*/
+ IRQMask(MD_IRQID_MSDC0);
+ /*save IRQ information*/
+ gMSDC_Handle->msdc_int=MSDC_Reg32(MSDC_INT);
+
+ intsts_pure=gMSDC_Handle->msdc_int;
+ inten=MSDC_Reg32(MSDC_INTEN);
+
+ intsts=intsts_pure&inten;
+ /*clear all interrupt*/
+ MSDC_WriteReg32(MSDC_INT,intsts);
+ /*data transfer interrupt*/
+ if (intsts&datsts)
+ {
+ MSDC_DatIrqHandle(intsts);
+ }
+ /*command interrupt*/
+ if (intsts&(cmdsts|acmdsts))
+ {
+ MSDC_CmdIrqHandle(intsts);
+ }
+ /*card detect interrupt*/
+ if(intsts & MSDC_INT_CDSC)
+ {
+ MSDC_CardDetectHandle(intsts);
+ }
+ /*mmc interrupt*/
+
+ /*unmask irq*/
+ IRQUnmask(MD_IRQID_MSDC0);
+}
+
+/*************************************************************************
+* FUNCTION
+* MSDC_DMA_Callback
+*
+* DESCRIPTION
+* Call back while DMA has done the data transfer.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_DMA_Callback(void)
+{
+
+}
+
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+void MSDC_changeSwContext(sd_select_enum sel)
+{
+ gMSDC_Handle = &MSDC_Blk[sel];
+ gSD = &gSD_blk[sel];
+}
+
+/*
+ this function do not consider race condition issue, caller should make sure this function is called without risk
+ currently, this function is called in sdio_drv.c and sd_drv.c
+*/
+void MSDC_backupHwSetting()
+{
+ /*backup MSDC_CFG, MSDC_IOCON, SDC_CFG*/
+ gMSDC_Handle->setting_MSDC_CFG = MSDC_Reg32(MSDC_CFG);
+ gMSDC_Handle->setting_MSDC_IOCON = MSDC_Reg32(MSDC_IOCON);
+ gMSDC_Handle->setting_SDC_CFG = MSDC_Reg32(SDC_CFG);
+}
+
+void MSDC_retreiveHwSetting()
+{
+ MSDC_WriteReg32(MSDC_CFG, gMSDC_Handle->setting_MSDC_CFG);
+ MSDC_WriteReg32(MSDC_IOCON, gMSDC_Handle->setting_MSDC_IOCON);
+ MSDC_WriteReg32(SDC_CFG, gMSDC_Handle->setting_SDC_CFG);
+}
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+void MSDC_Switch_Card(sd_select_enum sel)
+{
+
+}
+#endif
+
+#endif //end of MSDC_INT
+
+
+void MSDC_turnOnVMC(kal_bool turnOnLdo)
+{
+
+}
+
+#if defined(MSDC_TRACE_LEVEL3)
+void MSDC_add_dbg_msg( msdc_dbg_Event event, kal_uint32 data1, kal_uint32 data2)
+{
+
+}
+#endif
+
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+void MSDC_Switch_SDIO(sd_select_enum sel)
+{
+
+
+}
+#endif
+
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+
+/*following should be the value defined in custom files*/
+#define MSDC_SWITCH_2_SD 1
+#define MSDC_SWITCH_2_SDIO 0
+#define MSDC_SWITCH_GPIO 20
+typedef enum
+{
+ MSDC_SWITCH_DIRECTION_SD,
+ MSDC_SWITCH_DIRECTION_SDIO
+} MSDC_SWITCH_DIRECTION;
+
+
+void MSDC_Switch_init()
+{
+
+}
+
+/*
+ direction:
+ 0 : cmmb
+ 1 : sd card
+*/
+
+void MSDC_Switch(sd_select_enum direction)
+{
+
+}
+#endif
+
+
+#else
+#ifdef DRV_LSD
+void MSDC_LSD_HISR(void)
+{
+}
+#endif
+#endif // end of (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__))
+#endif//!defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+
+#else //DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "msdc_def.h"
+
+/*
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//RHR REMOVE
+#include "syscomp_config.h"
+#include "task_config.h"
+#include "stacklib.h"
+#include "eint.h"
+#include "fat_fs.h"
+*/
+//RHR
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "kal_public_api.h" //MSBB change #include "app_ltlcom.h"
+#include "intrCtrl.h"
+#include "reg_base.h"
+#include "drvpdn.h"
+//#include "gpt_sw.h"
+#include "drv_comm.h"
+#include "drv_hisr.h"
+#include "msdc_def.h"
+#include "dcl.h"
+
+/* Debug log */
+kal_uint32 MSDC_DebugLevel;
+
+#define LDO_VMC 0
+#define LDO_VMCH 1
+#define LDO_VIO18_PMU 2
+
+static kal_uint32 g_msdc0_io = PMU_VOLT_03_300000_V;
+static kal_uint32 g_msdc0_card = PMU_VOLT_03_300000_V;
+
+static kal_uint32 hwPowerOn(kal_uint32 powerID, PMU_VOLTAGE_ENUM powerVolt)
+{
+ PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
+ PMU_CTRL_LDO_BUCK_SET_VOLTAGE pmu_volsel;
+ DCL_HANDLE handle;
+
+ /* Open PMU handle */
+ handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
+
+ switch(powerID) {
+ case LDO_VMC:
+ /* Set enable control */
+ pmu_en.mod = VMC;
+ pmu_en.enable = 1;
+
+ /* Set voltage */
+ pmu_volsel.mod = VMC;
+ pmu_volsel.voltage = powerVolt;
+
+ DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
+ DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+
+ break;
+
+ case LDO_VMCH:
+ /* Set enable control */
+ pmu_en.mod = VMCH;
+ pmu_en.enable = 1;
+
+ /* Set voltage */
+ pmu_volsel.mod = VMCH;
+ pmu_volsel.voltage = powerVolt;
+
+ DclPMU_Control(handle, LDO_BUCK_SET_VOLTAGE, (DCL_CTRL_DATA_T *)&pmu_volsel);
+ DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+
+ break;
+
+ default:
+ break;
+ }
+
+ /* Close PMU handle */
+ DclPMU_Close(handle);
+
+ return 1;
+}
+
+static kal_uint32 hwPowerDown(kal_uint32 powerID)
+{
+ PMU_CTRL_LDO_BUCK_SET_EN pmu_en;
+ DCL_HANDLE handle;
+
+ /* Open PMU handle */
+ handle = DclPMU_Open(DCL_PMU, FLAGS_NONE);
+
+ switch(powerID) {
+ case LDO_VMC:
+ /* Set enable control */
+ pmu_en.mod = VMC;
+ pmu_en.enable = 0;
+
+ DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+ break;
+
+ case LDO_VMCH:
+ /* Set enable control */
+ pmu_en.mod = VMCH;
+ pmu_en.enable = 0;
+
+ DclPMU_Control(handle, LDO_BUCK_SET_EN, (DCL_CTRL_DATA_T *)&pmu_en);
+
+ break;
+
+ default:
+ break;
+ }
+
+ /* Close PMU handle */
+ DclPMU_Close(handle);
+
+ return 1;
+}
+
+static kal_uint32 msdc_ldo_power(kal_uint32 on, kal_uint8 powerId,
+ PMU_VOLTAGE_ENUM powerVolt, kal_uint32 *status)
+{
+ if (on) { // want to power on
+ if (*status == 0) { // can power on
+ hwPowerOn(powerId, powerVolt);
+
+ *status = powerVolt;
+ } else if (*status == powerVolt) {
+ } else { // for sd3.0 later
+
+ hwPowerDown(powerId);
+ hwPowerOn(powerId, powerVolt);
+
+ *status = powerVolt;
+ }
+ } else { // want to power off
+ if (*status != 0) { // has been powerred on
+
+ hwPowerDown(powerId);
+
+ *status = 0;
+ } else {
+ }
+ }
+
+ return 0;
+}
+
+kal_bool MSDC_SetVddPower(kal_bool on, kal_uint32 volt)
+{
+ kal_bool ret =KAL_TRUE;
+
+ if (volt == 3300)
+ {
+ msdc_ldo_power(on, LDO_VMCH, PMU_VOLT_03_300000_V, &g_msdc0_card);
+ }
+ else
+ {
+ ret = KAL_FALSE;
+ }
+
+ return ret;
+}
+
+kal_bool MSDC_SetSignalPower(kal_bool on,kal_uint32 volt)
+{
+ kal_bool ret =KAL_TRUE;
+ if (volt == 3300)
+ {
+ msdc_ldo_power(on, LDO_VMC, PMU_VOLT_03_300000_V, &g_msdc0_io);
+ }
+ else if (volt ==1800)
+ {
+ msdc_ldo_power(on, LDO_VMC, PMU_VOLT_01_800000_V, &g_msdc0_io);
+ }
+ else
+ {
+ ret = KAL_FALSE;
+ }
+
+ return ret;
+}
+
+/*here are dummy API*/
+void MSDC_Initialize(void)
+{
+ /* INIT MSDC debug flag */
+ MSDC_SetDebugLevel(K_WARNIN);
+
+ /* Shut card power and signal power */
+ MSDC_SetVddPower(KAL_FALSE, 3300);
+ MSDC_SetSignalPower(KAL_FALSE, 3300);
+}
+
+void MSDC_PDNControl(kal_bool ON) {}
+int MSDC_GetCardStatus(void * DriveData, int AckType) {return 0;}
+//kal_bool MSDC_GetMediaChanged(void * id) {}
+kal_bool MSDC_GetMediaChanged(sd_select_enum id) {return 0;}
+MSDC_HANDLE MSDC_Blk[SD_NUM];
+MSDC_HANDLE *gMSDC_Handle = &(MSDC_Blk[0]);
+//kal_bool MSDC_everPlugOut;
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/msdc2.c b/mcu/driver/storage/mc/src/msdc2.c
new file mode 100644
index 0000000..d96043f
--- /dev/null
+++ b/mcu/driver/storage/mc/src/msdc2.c
@@ -0,0 +1,1049 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * msdc2.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * driver functons for MSDC controller
+ *
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_msgs.h"
+#include "kal_public_api.h" //MSBB change #include "app_ltlcom.h" /* Task message communiction */
+#include "syscomp_config.h"
+#include "task_config.h"
+#include "stacklib.h"
+#include "intrCtrl.h"
+#include "reg_base.h"
+#include "drvpdn.h"
+#include "eint.h"
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#include "fat_fs.h"
+#include "dma_hw.h"
+#include "dma_sw.h"
+#include "drv_hisr.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#if defined(__MSDC2_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
+#include "sdio_sw.h"
+#endif
+#if defined(__MSDC_MS__)
+#include "ms_def.h"
+#elif defined(__MSDC_MSPRO__)
+#include "mspro_def.h"
+#endif
+#include "upll_ctrl.h"
+//#include "gpio_hw.h"
+//#include "gpio_sw.h"
+//#include "sim_hw.h"
+#ifdef __MULTI_BOOT__
+#include "syscomp_config.h"
+#include "multiboot_config.h"
+#endif /*__MULTI_BOOT__*/
+//#include "sim_hw.h"
+
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+
+
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON0
+#error "__CLKG_DEFINE__ & DRVPDN_CON0 are all defined"
+#else
+#define DRVPDN_CON0 CG_CON0
+#endif
+
+#ifdef DRVPDN_CON1_SIM
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SIM are all defined"
+#else
+#define DRVPDN_CON1_SIM CG_CON1_SIM
+#endif
+
+#ifdef DRVPDN_CON0_MSDC2
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_MSDC2 are all defined"
+#else
+#define DRVPDN_CON0_MSDC2 CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON0_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_CLR are all defined"
+#else
+#define DRVPDN_CON0_CLR CG_CLR0
+#endif
+
+#ifdef DRVPDN_CON0_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_SET are all defined"
+#else
+#define DRVPDN_CON0_SET CG_SET0
+#endif
+#endif
+
+
+
+
+#pragma arm section zidata = "NONCACHEDZI", rwdata = "NONCACHEDRW"
+kal_uint32 MSDC_Sector2[128] = {0};
+MSDC_HANDLE *msdc2_handle = &MSDC_Blk[SD_MSDC2];
+
+#ifdef MSDC_CACHED_SUPPORT
+kal_uint32 msdc_uncachedBuf2[MSDC_UNCACHED_BUF_SIZE/4];
+#endif
+#pragma arm section zidata, rwdata
+
+// function predeclaration
+void MSDC_DMAInit2(void);
+void MSDC_INT_Init2(void);
+void MSDC_DMA_Callback2(void);
+extern void GPIO_ModeSetup(kal_uint16 pin, kal_uint16 conf_dada);
+extern boot_mode_type stack_query_boot_mode(void);
+extern kal_bool INT_USBBoot(void);
+extern kal_uint32 MSDC_GetCustom(void);
+/*************************************************************************
+* FUNCTION
+* MSDC_SetClock
+*
+* DESCRIPTION
+*
+* PARAMETERS
+* clock: the desired operating clock rate in the unit of kHz
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void MSDC_SetClock2(kal_uint32 clock)
+{
+ kal_uint32 cfg;
+
+ if(clock == 0)
+ return;
+ MSDC_LSD_ClearBits32(SDC_CFG2,SDC_CFG_SIEN);
+ cfg = ((msdc2_handle->msdc_clock+clock-1)/clock);
+ if(cfg <=2 )
+ {
+ cfg = 0;
+ msdc2_handle->op_clock = msdc2_handle->msdc_clock/2;
+ }
+ else
+ {
+ cfg = (cfg >> 2) + (cfg&3 != 0);
+ msdc2_handle->op_clock = msdc2_handle->msdc_clock/(4*cfg);
+ }
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)cfg,MSDC_CFG_SCLKF);
+ MSDC_LSD_SetBits32(SDC_CFG2,SDC_CFG_SIEN);
+
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_Check_Card_Present2
+*
+* DESCRIPTION
+* c
+*
+* PARAMETERS
+* ON: turn on power saving or not
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+kal_bool MSDC_Check_Card_Present2(void)
+{
+#if !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ return msdc2_handle->mIsPresent;
+#else
+ return KAL_TRUE;
+#endif
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_PDNControl
+*
+* DESCRIPTION
+* Enable power saving or not.
+*
+* PARAMETERS
+* ON: turn on power saving or not
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_PDNControl2(kal_bool ON)
+{
+ msdc2_handle->mIsPWDown = ON;
+ if(ON)
+ { // OFF
+ MSDC_CLR_INT2();
+ MSDC_CLR_INT2();
+ #if defined(MSDC_USE_USB_CLK) && defined(__MSDC2_SD_MMC__)
+ if(gSD_blk[SD_MSDC2].flags & SD_FLAG_USE_USB_CLK)
+ UPLL_Disable(UPLL_OWNER_MSDC2);
+ #endif
+ DRVPDN_Enable(DRVPDN_CON0,DRVPDN_CON0_MSDC2,PDN_MSDC2);
+ }
+ else
+ { // ON
+ DRVPDN_Disable(DRVPDN_CON0,DRVPDN_CON0_MSDC2,PDN_MSDC2);
+ #if defined(MSDC_USE_USB_CLK) && defined(__MSDC2_SD_MMC__)
+ if(gSD_blk[SD_MSDC2].flags & SD_FLAG_USE_USB_CLK)
+ UPLL_Enable(UPLL_OWNER_MSDC2);
+ #endif
+ }
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_TimeOutHandler2
+*
+* DESCRIPTION
+* Callback function of gpt timer, and launched while MSDC busy for a while
+
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_TimeOutHandler2(void *parameter)
+{
+ tst_sys_trace("MSDC_TimeOutHandler2");
+ msdc2_handle->is_timeout = KAL_TRUE;
+ #if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
+ kal_set_eg_events(msdc2_handle->MSDC_Events,
+ (EVENT_MSIFIRQ|EVENT_DMAIRQ|EVENT_MSRDYIRQ),
+ KAL_OR);
+ #else
+ kal_set_eg_events(msdc2_handle->MSDC_Events,
+ (EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ),
+ KAL_OR);
+ #endif
+}
+
+
+/*************************************************************************
+* FUNCTION
+* MSDC_GetCardStatus
+*
+* DESCRIPTION
+* Check currently card is present or not.
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+* msdc_eint_state
+*
+*
+*************************************************************************/
+int MSDC_GetCardStatus2(void * DriveData, int AckType)
+{
+ MSDC_HANDLE *msdc = (MSDC_HANDLE *)DriveData;;
+
+ // a debounce mechanism
+ if(kal_query_systemInit() == KAL_FALSE)
+ {
+ kal_sleep_task(100);
+ }
+ ENTER_CRITICAL();
+ msdc->send_ilm = KAL_TRUE;
+ EXIT_CRITICAL();
+
+
+ if(!msdc->mIsPresent)
+ MSDC_PDNControl2(KAL_TRUE);
+ return 0;
+}
+
+
+/*************************************************************************
+* FUNCTION
+* MSDC_Config_INS_WP
+*
+* DESCRIPTION
+* Configure the pull up or pull down status for INS and WP pin
+*
+* PARAMETERS
+* 1. ins: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
+* 2. wp: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* 1. MT6219 can not be configured to PULL up or down. They are all pulled up by IO.
+* 2. MT6218B and MT6217, WP is configured with data lines.
+*************************************************************************/
+void MSDC_Config_INS_WP2(msdc_ioctrl_enum ins, msdc_ioctrl_enum wp)
+{
+ kal_uint32 msdc_cfg,iocon;
+
+ msdc2_handle->ins_level = ins;
+ //#if defined(MT6218B) || defined(MT6217)
+ // INS use PRCFG3, WP use PRCFG0
+ MSDC_SetData32(MSDC_CFG2, MSDC_CFG_PRCFG0, (wp << 22));
+ MSDC_SetData32(MSDC_IOCON2, MSDC_IOCON_PRCFG3, (ins << 8));
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_Initialize
+*
+* DESCRIPTION
+* Initialize the MS/SD host controller, called only once at drv_init
+*
+* PARAMETERS*
+*
+* RETURNS
+* 1: initailized failed
+* 0: successful
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+void MSDC_Initialize2(void)
+{
+
+ // turn on the power of controler
+ DRVPDN_Disable(DRVPDN_CON0,DRVPDN_CON0_MSDC2,PDN_MSDC2);
+#if defined(__MSDC_MS__)
+ MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_MSDC);
+ msdc2_handle->mMSDC_type = MS_CARD;
+#elif defined(__MSDC_MSPRO__)
+ MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_MSDC);
+ msdc2_handle->mMSDC_type = MSPRO_CARD;
+ FS_MspDrvAll = FS_MspDrv;
+#elif (defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__))
+ MSDC_LSD_SetBits32(MSDC_CFG2, MSDC_CFG_MSDC) ;
+ msdc2_handle->mMSDC_type = SD_CARD;
+#endif
+ msdc2_handle->msdc_clock = MSDC_CLOCK;
+
+ if(msdc2_handle->gpt_handle == 0)
+ MSDC_GPTI_GetHandle(&msdc2_handle->gpt_handle);
+ #if !defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
+ MSDC_Config_INS_WP2(MSDC_IOCTRL_PULL_UP,MSDC_IOCTRL_PULL_UP);
+ #else
+ MSDC_Config_INS_WP2(MSDC_IOCTRL_PULL_DOWN,MSDC_IOCTRL_PULL_UP);
+ // first time if card is present, no card insertion interrupt generated
+ msdc2_handle->mIsPresent = KAL_TRUE;
+ #endif
+ // turn on the power of memory card
+ MSDC_LSD_SetBits32(MSDC_CFG2,MSDC_CFG_VDDPD);
+ MSDC_SET_FIFO2(1);
+
+ if(MSDC_GetCustom() & MSDC2_HOT_PLUG)
+ {
+ // enable card detection
+ MSDC_WriteReg32(MSDC_PS2, MSDC_PS_CDEN|MSDC_PS_PIEN0|MSDC_PS_POEN0);
+ if(MSDC_Reg(MSDC_PS2) & MSDC_PS_PIN0)
+ {
+ if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+ msdc2_handle->mIsPresent = KAL_FALSE;
+ else
+ msdc2_handle->mIsPresent = KAL_TRUE;
+ }
+ else
+ {
+ if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+ msdc2_handle->mIsPresent = KAL_TRUE;
+ else
+ msdc2_handle->mIsPresent = KAL_FALSE;
+ }
+ MSDC_LSD_SetBits32(MSDC_CFG2, MSDC_CFG_PINEN);
+ }
+ else
+ {
+ msdc2_handle->mIsPresent = KAL_TRUE;
+ }
+
+ #ifdef MSDC_INT
+ MSDC_INT_Init2();
+ #endif // end of MSDC_INT
+ #ifdef MSDC_DMA
+ MSDC_DMAInit2();
+ #endif
+ #ifdef __MULTI_BOOT__
+ if(stack_query_boot_mode() != NORMAL_BOOT)
+ msdc2_handle->send_ilm = KAL_FALSE;
+ else
+ msdc2_handle->send_ilm = KAL_TRUE;
+ #else
+ msdc2_handle->send_ilm = KAL_FALSE;
+ #endif
+
+ DRVPDN_Enable(DRVPDN_CON0,DRVPDN_CON0_MSDC2,PDN_MSDC2);
+}
+
+void MSDC_SetIOCONRegDLT2(void)
+{
+ kal_uint32 factor;
+
+ /*set DLT field according to SCLKF seeting*/
+ factor = msdc2_handle->msdc_clock/msdc2_handle->op_clock;
+ BitFieldWrite32((kal_uint32*)MSDC_IOCON2,(kal_uint32)(factor/2),MSDC_IOCON_DLT);
+}
+
+/*************************************************************************
+* FUNCTION
+* MSDC_GetMediaChanged
+*
+* DESCRIPTION
+* Check if the media is changed, and clear the status after function call
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+/*! combined to MSDC_GetMediaChanged(), and removed in HAL [20101203 Samuel]
+kal_bool MSDC_GetMediaChanged2(void* id)
+{
+ kal_bool ret;
+
+ ENTER_CRITICAL();
+ msdc2_handle = (MSDC_HANDLE *)id;
+ ret = (msdc2_handle->mIsChanged )?(KAL_TRUE):(KAL_FALSE);
+ msdc2_handle->mIsChanged = KAL_FALSE;
+ EXIT_CRITICAL();
+
+ return ret;
+}
+*/
+
+#ifdef MSDC_DMA
+extern kal_uint8 DMA_GetChannel(DMA_Master DMA_CODE);
+/*************************************************************************
+* FUNCTION
+* MSDC_DMAInit
+*
+* DESCRIPTION
+* Initialize MSDC's DMA
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_DMAInit2(void)
+{
+ msdc2_handle->msdc_dmaport = DMA_GetChannel(DMA_MSDC2);
+ msdc2_handle->msdc_menu.TMOD.burst_mode = KAL_TRUE;
+ msdc2_handle->msdc_menu.TMOD.cycle = 0x4;
+ msdc2_handle->msdc_menu.master = DMA_MSDC2;
+ msdc2_handle->msdc_menu.addr = NULL;
+ msdc2_handle->msdc_input.type = DMA_HWRX;
+ msdc2_handle->msdc_input.size = DMA_LONG;
+ msdc2_handle->msdc_input.count = 0;
+ msdc2_handle->msdc_input.menu = &msdc2_handle->msdc_menu;
+}
+
+/*************************************************************************
+* FUNCTION
+* MSDC_DMATransfer
+*
+* DESCRIPTION
+* MSDC using DAM for data transfer
+*
+* PARAMETERS
+* adrs: data buffer
+* count: bytes to be transfered
+* isTx: ture for move data from MSDC to data buffer and vise versa
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_DMATransferFirst2(kal_uint32 adrs,kal_uint32 count, kal_bool isTx)
+{
+ kal_uint32 total_count;
+ kal_bool is_aligned, is_poll;
+
+ DMA_Stop(msdc2_handle->msdc_dmaport);
+
+#ifdef MSDC_CACHED_SUPPORT
+ if (KAL_TRUE == msdc2_handle->isCachedBuf){
+ msdc2_handle->msdc_menu.addr = (kal_uint32)msdc_uncachedBuf2;
+ msdc2_handle->cachedBufCopyPtr = adrs;
+ }
+ else
+#endif
+ msdc2_handle->msdc_menu.addr = adrs;
+
+
+ if(isTx)
+ {
+ msdc2_handle->timeout_period = (50 + (count>>5));
+ msdc2_handle->msdc_input.type = DMA_HWTX;
+ if(count <= MSDC_WRITE_THD_POLL)
+ {
+ msdc2_handle->msdc_input.callback = NULL;
+ is_poll = KAL_TRUE;
+ }
+ else
+ {
+ msdc2_handle->msdc_input.callback = MSDC_DMA_Callback2;
+ is_poll = KAL_FALSE;
+ }
+ }
+ else
+ {
+ msdc2_handle->timeout_period = (50 + (count>>7));
+ msdc2_handle->msdc_input.type = DMA_HWRX;
+ if(count <= MSDC_READ_THD_POLL)
+ {
+ msdc2_handle->msdc_input.callback = NULL;
+ is_poll = KAL_TRUE;
+ }
+ else
+ {
+ msdc2_handle->msdc_input.callback = MSDC_DMA_Callback2;
+ is_poll = KAL_FALSE;
+ }
+ }
+
+ if(kal_query_systemInit() == KAL_TRUE
+#ifdef __TST_WRITE_TO_FILE_ONLY__ /*error recording: considering error recording additionally*/
+ || (KAL_TRUE == INT_QueryExceptionStatus())
+#endif
+ )
+ {
+ msdc2_handle->msdc_input.callback = NULL;
+ is_poll = KAL_TRUE;
+ }
+
+#ifndef MSDC_CACHED_SUPPORT
+ if(adrs%4 == 0)
+ {
+ is_aligned = KAL_TRUE;
+ total_count = count;
+ }
+ else
+ {
+ is_aligned = KAL_FALSE;
+ total_count = count<<2;
+ }
+#else
+ if(adrs%4 == 0 || KAL_TRUE == msdc2_handle->isCachedBuf)
+ {
+ is_aligned = KAL_TRUE;
+ total_count = count;
+ }
+ else
+ {
+ is_aligned = KAL_FALSE;
+ total_count = count<<2;
+ }
+#endif
+ msdc2_handle->total_count = total_count;
+ msdc2_handle->is_poll = is_poll;
+ msdc2_handle->is_aligned = is_aligned;
+ {
+ if(is_aligned)
+ {
+ #if defined(USE_DMA_BURST)
+ MSDC_SET_FIFO2(4);
+ #else
+ msdc2_handle->msdc_menu.TMOD.burst_mode = KAL_FALSE;
+ #endif
+#ifdef MSDC_CACHED_SUPPORT
+ if(KAL_TRUE == msdc2_handle->isCachedBuf)
+ msdc2_handle->msdc_input.count = (total_count > MSDC_UNCACHED_TRASNFER_SIZE)?(MSDC_UNCACHED_TRASNFER_SIZE):(total_count);
+ else
+#endif
+ msdc2_handle->msdc_input.count = (total_count > 65024)?(65024):(total_count);
+#ifdef MSDC_CACHED_SUPPORT
+ if(KAL_TRUE == msdc2_handle->isCachedBuf){
+ /*have do memory copy stuff here*/
+ if(DMA_HWTX == msdc2_handle->msdc_input.type){
+ /*copy from upper application buffer*/
+ kal_mem_cpy(msdc_uncachedBuf2, (void *)msdc2_handle->cachedBufCopyPtr, 4 * msdc2_handle->msdc_input.count);
+ msdc2_handle->cachedBufCopyPtr += msdc2_handle->msdc_input.count * 4;
+ }
+ }
+#endif
+ msdc2_handle->msdc_input.size = DMA_LONG;
+ DMA_Config_B2W(msdc2_handle->msdc_dmaport,&msdc2_handle->msdc_input,KAL_TRUE,KAL_FALSE);
+ msdc2_handle->msdc_menu.addr += msdc2_handle->msdc_input.count*4;
+ }
+ else
+ {
+#ifdef MSDC_CACHED_SUPPORT
+ if(KAL_TRUE == msdc2_handle->isCachedBuf)
+ ASSERT(0);
+#endif
+ #if defined(USE_DMA_BURST)
+ MSDC_SET_FIFO2(1);
+ #else
+
+ msdc2_handle->msdc_menu.TMOD.burst_mode = KAL_TRUE;
+ #endif
+ msdc2_handle->msdc_input.count = (total_count > 65024)?(65024):(total_count);
+ msdc2_handle->msdc_input.size = DMA_BYTE;
+ DMA_Config_B2W(msdc2_handle->msdc_dmaport,&msdc2_handle->msdc_input,KAL_TRUE,KAL_TRUE);
+ msdc2_handle->msdc_menu.addr += msdc2_handle->msdc_input.count;
+ }
+
+ }
+}
+kal_uint32 MSDC_DMATransferFinal2(void)
+{
+ kal_uint32 total_count = msdc2_handle->total_count, t1;
+ kal_bool is_poll = msdc2_handle->is_poll;
+ kal_bool is_aligned = msdc2_handle->is_aligned;
+
+ t1 = drv_get_current_time();
+ if(msdc2_handle->timeout_period > MSDC_TIMEOUT_PERIOD_DAT)
+ msdc2_handle->timeout_period = MSDC_TIMEOUT_PERIOD_DAT;
+ MSDC_START_TIMER2(msdc2_handle->timeout_period);
+ if(is_poll)
+ {
+ while(IS_MSDC_DMA_RUN(msdc2_handle->msdc_dmaport) && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ }
+ }
+ else
+ {
+ kal_uint32 flags;
+ kal_retrieve_eg_events(msdc2_handle->MSDC_Events,(EVENT_DMAIRQ),KAL_OR_CONSUME,&flags,KAL_SUSPEND);
+ }
+ MSDC_STOP_TIMER2();
+ if(IS_MSDC_DMA_RUN(msdc2_handle->msdc_dmaport) && msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+
+ total_count -= msdc2_handle->msdc_input.count;
+ if(total_count == 0){
+#ifdef MSDC_CACHED_SUPPORT
+ if(KAL_TRUE == msdc2_handle->isCachedBuf){
+ if(DMA_HWRX == msdc2_handle->msdc_input.type){
+ /*copy to upper application's buffer*/
+ kal_mem_cpy((void *)msdc2_handle->cachedBufCopyPtr, msdc_uncachedBuf2, 4 * msdc2_handle->msdc_input.count);
+ }
+ }
+#endif
+ return MSDC_NOERROR;
+ }
+
+#ifdef MSDC_CACHED_SUPPORT
+ if(KAL_TRUE == msdc2_handle->isCachedBuf){
+ /*have do memory copy stuff here*/
+ if(DMA_HWTX == msdc2_handle->msdc_input.type){
+ /*copy from upper application buffer*/
+ kal_mem_cpy(msdc_uncachedBuf2, (void *)msdc2_handle->cachedBufCopyPtr, 4 * msdc2_handle->msdc_input.count);
+ }
+ else{
+ /*copy to upper application's buffer*/
+ kal_mem_cpy((void *)msdc2_handle->cachedBufCopyPtr, msdc_uncachedBuf2, 4 * msdc2_handle->msdc_input.count);
+ }
+ msdc2_handle->cachedBufCopyPtr += msdc2_handle->msdc_input.count * 4;
+ }
+#endif
+ while(1)
+ {
+ if(is_aligned)
+ {
+ #if defined(USE_DMA_BURST)
+ MSDC_SET_FIFO(4);
+ #else
+ msdc2_handle->msdc_menu.TMOD.burst_mode = KAL_FALSE;
+ #endif
+#ifdef MSDC_CACHED_SUPPORT
+ if(KAL_TRUE == msdc2_handle->isCachedBuf)
+ msdc2_handle->msdc_input.count = (total_count > MSDC_UNCACHED_TRASNFER_SIZE)?(MSDC_UNCACHED_TRASNFER_SIZE):(total_count);
+ else
+#endif
+ msdc2_handle->msdc_input.count = (total_count > 65024)?(65024):(total_count);
+ msdc2_handle->msdc_input.size = DMA_LONG;
+ DMA_Config_B2W(msdc2_handle->msdc_dmaport,&msdc2_handle->msdc_input,KAL_TRUE,KAL_FALSE);
+#ifdef MSDC_CACHED_SUPPORT
+ /*we don't need to increase the addr when encounter cached buffer, since we only have a fix size uncached buffer to use*/
+ if(KAL_FALSE == msdc2_handle->isCachedBuf)
+#endif
+ {
+ msdc2_handle->msdc_menu.addr += msdc2_handle->msdc_input.count*4;
+ }
+ msdc2_handle->timeout_period = 1 + (msdc2_handle->msdc_input.count>>7);
+ }
+ else
+ {
+#ifdef MSDC_CACHED_SUPPORT
+ if(KAL_TRUE == msdc2_handle->isCachedBuf)
+ ASSERT(0);
+#endif
+ #if defined(USE_DMA_BURST)
+ MSDC_SET_FIFO(1);
+ #else
+ msdc2_handle->msdc_menu.TMOD.burst_mode = KAL_TRUE;
+ #endif
+ msdc2_handle->msdc_input.count = (total_count > 65024)?(65024):(total_count);
+ msdc2_handle->msdc_input.size = DMA_BYTE;
+ DMA_Config_B2W(msdc2_handle->msdc_dmaport,&msdc2_handle->msdc_input,KAL_TRUE,KAL_TRUE);
+ msdc2_handle->msdc_menu.addr += msdc2_handle->msdc_input.count;
+ msdc2_handle->timeout_period = 1 + (msdc2_handle->msdc_input.count>>9);
+ }
+
+ // wait until running bit clr
+ if(msdc2_handle->msdc_input.type == DMA_HWTX)
+ msdc2_handle->timeout_period <<= 2 ;
+ if(msdc2_handle->mMSDC_type == MMC_CARD)
+ msdc2_handle->timeout_period <<= 1;
+
+ t1 = drv_get_current_time();
+ MSDC_START_TIMER2(msdc2_handle->timeout_period);
+ if(is_poll)
+ {
+ while(IS_MSDC_DMA_RUN(msdc2_handle->msdc_dmaport) && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > msdc2_handle->timeout_period*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ }
+ }
+ else
+ {
+ kal_uint32 flags;
+ kal_retrieve_eg_events(msdc2_handle->MSDC_Events,(EVENT_DMAIRQ),KAL_OR_CONSUME,&flags,KAL_SUSPEND);
+ }
+ MSDC_STOP_TIMER2();
+ if(IS_MSDC_DMA_RUN(msdc2_handle->msdc_dmaport) && msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+ total_count -= msdc2_handle->msdc_input.count;
+ if(total_count == 0)
+ break;
+#ifdef MSDC_CACHED_SUPPORT
+ if(KAL_TRUE == msdc2_handle->isCachedBuf){
+ /*have do memory copy stuff here*/
+ if(DMA_HWTX == msdc2_handle->msdc_input.type){
+ /*copy from upper application buffer*/
+ kal_mem_cpy(msdc_uncachedBuf2, (void *)msdc2_handle->cachedBufCopyPtr, 4 * msdc2_handle->msdc_input.count);
+ }
+ else{
+ /*copy to upper application's buffer*/
+ kal_mem_cpy((void *)msdc2_handle->cachedBufCopyPtr, msdc_uncachedBuf2, 4 * msdc2_handle->msdc_input.count);
+ }
+ msdc2_handle->cachedBufCopyPtr += msdc2_handle->msdc_input.count * 4;
+ }
+#endif
+ }
+
+#ifdef MSDC_CACHED_SUPPORT
+ if(KAL_TRUE == msdc2_handle->isCachedBuf){
+ if(DMA_HWRX == msdc2_handle->msdc_input.type){
+ /*copy to upper application's buffer*/
+ kal_mem_cpy((void *)msdc2_handle->cachedBufCopyPtr, msdc_uncachedBuf2, 4 * msdc2_handle->msdc_input.count);
+ }
+ }
+#endif
+ return MSDC_NOERROR;
+}
+
+
+#endif // DMA
+
+#ifdef MSDC_INT
+/*************************************************************************
+* FUNCTION
+* MSDC_INT_Init
+*
+* DESCRIPTION
+* Initialize MSDC's interrupt
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_INT_Init2(void)
+{
+
+ msdc2_handle->MSDC_Events = kal_create_event_group("MSDC2");
+ DRV_Register_HISR(DRV_MSDC2_HISR_ID, MSDC_HISR_Entry2);
+ IRQ_Register_LISR(IRQ_MSDC2_CODE, MSDC_LISR2,"MSDC_LISR2");
+ IRQSensitivity(IRQ_MSDC2_CODE,LEVEL_SENSITIVE);
+ IRQUnmask(IRQ_MSDC2_CODE);
+
+ // enable MSDC interrupt
+ MSDC_CLR_INT();
+ #if !defined(MSDC_USE_INT)
+ MSDC_DISABLE_INT2();// (active)turn off other interrupt event except pin interrupt
+ #else
+ MSDC_ENABLE_INT2();// (deactive)
+ #endif
+
+}
+void MSDC_LISR2(void)
+{
+ IRQMask(IRQ_MSDC2_CODE);
+ drv_active_hisr(DRV_MSDC2_HISR_ID);
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_HISR_Entry
+*
+* DESCRIPTION
+* Set corresponding enevt and wake up waiting task.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_HISR_Entry2(void)
+{
+ kal_uint16 msdc_int = 0;
+
+#if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
+ kal_uint16 msc_sta;
+
+ FS_MspDrvAll = FS_MspDrv;
+ TurnOnMSDC2();
+ msc_sta = MSDC_Reg(MSC_STA2);
+ if(msc_sta & MSC_STA_SIF)
+ kal_set_eg_events(msdc2_handle->MSDC_Events,EVENT_MSIFIRQ,KAL_OR);
+ else
+ kal_set_eg_events(msdc2_handle->MSDC_Events,EVENT_MSRDYIRQ,KAL_OR);
+
+ msdc_int = MSDC_Reg(MSDC_INTR);
+ if(msdc_int & MSDC_INT_PINIRQ)
+ {
+ msdc2_handle->mIsInitialized = KAL_FALSE;
+ msdc2_handle->mIsChanged = KAL_TRUE;
+ kal_set_eg_events(msdc2_handle->MSDC_Events,
+ (EVENT_MSIFIRQ|EVENT_DMAIRQ|EVENT_MSRDYIRQ),
+ KAL_OR);
+ if(MSDC_Reg(MSDC_PS2) & MSDC_PS_PIN0)
+ {
+ if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+ msdc2_handle->mIsPresent = KAL_FALSE;
+ else
+ msdc2_handle->mIsPresent = KAL_TRUE;
+ }
+ else
+ {
+ if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+ msdc2_handle->mIsPresent = KAL_TRUE;
+ else
+ msdc2_handle->mIsPresent = KAL_FALSE;
+ }
+ if(msdc2_handle->mIsPresent == KAL_FALSE)
+ {
+ MSDC_CLR_FIFO2();
+ MSDC_CLR_INT2();
+ MSDC_CLR_INT2();
+ DMA_Stop(msdc2_handle->msdc_dmaport);
+ }
+ #if !defined(FMT_NOT_PRESENT)
+ MSDC_SendCardInd(MOD_FMT, SD_MSDC2);
+ #endif
+ }
+#else // sd/mmc start here
+ TurnOnMSDC2();
+ msdc_int = MSDC_Reg(MSDC_INTR2);
+ #if defined(__MSDC2_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
+ /*SDIO*/
+ if(msdc_int & MSDC_INT_SDIOIRQ)
+ {
+ SDIO_HISR_Entry();
+ }
+ #endif
+
+ if(msdc_int & MSDC_INT_PINIRQ)
+ {
+ msdc2_handle->mIsInitialized = KAL_FALSE;
+ msdc2_handle->mIsChanged = KAL_TRUE;
+ if(MSDC_Reg(MSDC_PS2) & MSDC_PS_PIN0)
+ {
+ if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+ msdc2_handle->mIsPresent = KAL_FALSE;
+ else
+ msdc2_handle->mIsPresent = KAL_TRUE;
+ }
+ else
+ {
+ if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+ msdc2_handle->mIsPresent = KAL_TRUE;
+ else
+ msdc2_handle->mIsPresent = KAL_FALSE;
+ }
+ if(msdc2_handle->mIsPresent == KAL_FALSE)
+ {
+ MSDC_CLR_FIFO2();
+ MSDC_CLR_INT2();
+ MSDC_CLR_INT2();
+ DMA_Stop(msdc2_handle->msdc_dmaport);
+ }
+ #if !defined(FMT_NOT_PRESENT)
+ MSDC_SendCardInd(MOD_FMT, SD_MSDC2);
+ #endif
+ }
+ #endif // MSDC_MS
+ IRQUnmask(IRQ_MSDC2_CODE);
+}
+/*************************************************************************
+* FUNCTION
+* MSDC_DMA_Callback
+*
+* DESCRIPTION
+* Call back while DMA has done the data transfer.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+void MSDC_DMA_Callback2(void)
+{
+ kal_set_eg_events(msdc2_handle->MSDC_Events,EVENT_DMAIRQ,KAL_OR);
+}
+
+#endif //end of MSDC_INT
+#endif // end of (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__)) && defined(__MSDC2_SD_MMC__)
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/msdc_fake_kal.c b/mcu/driver/storage/mc/src/msdc_fake_kal.c
new file mode 100644
index 0000000..ddebaea
--- /dev/null
+++ b/mcu/driver/storage/mc/src/msdc_fake_kal.c
@@ -0,0 +1,203 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2007
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * msdc_fake_kal.c
+ *
+ * Project:
+ * --------
+ * Maui
+ *
+ * Description:
+ * ------------
+ * Resource Manager fake kal code body for multiplatform using
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#include "drv_comm.h"
+
+#if (defined(__UBL__) || defined(__FUE__)) && (defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__))
+
+#include "msdc_def.h"
+#include "msdc_fake_kal.h"
+
+kal_bool kal_if_hisr(void)
+{
+ return KAL_FALSE;
+}
+
+kal_semid kal_create_sem(kal_char *name, kal_uint32 initial_count)
+{
+ return NULL;
+}
+
+kal_status kal_take_sem(kal_semid ext_sem_id_ptr, kal_wait_mode wait_mode)
+{
+ return 0;
+}
+
+void kal_give_sem(kal_semid ext_sem_id_ptr)
+{
+}
+
+void* kal_get_current_thread_ID(void)
+{
+ return NULL;
+}
+
+ilm_struct* allocate_ilm(module_type module_id)
+{
+ return NULL;
+}
+
+kal_bool msg_send_ext_queue(ilm_struct *ilm_ptr)
+{
+ return KAL_TRUE;
+}
+
+void* construct_int_local_para(kal_uint16 local_para_size, kal_uint32 auto_reset,
+ kal_char* file_ptr, kal_uint32 line)
+{
+ ASSERT(0);
+ return NULL;
+}
+
+#if 0 // [Carlos] move to dummy
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+#endif//defined(__UBL__) && (defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__))
+
diff --git a/mcu/driver/storage/mc/src/msdc_test.c b/mcu/driver/storage/mc/src/msdc_test.c
new file mode 100644
index 0000000..917628b
--- /dev/null
+++ b/mcu/driver/storage/mc/src/msdc_test.c
@@ -0,0 +1,8529 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * msdc_test.c
+ *
+ * Project:
+ * --------
+ * MT6268ADVT
+ *
+ * Description:
+ * ------------
+ * This file is used when doing msdc dvt, when enable __MSDC_BASIC_LOAD__, functions here will replace ssdbg1_main.
+ * The target of this file is to merge as many DVT loads into single test load as possible.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#include "kal_public_api.h"
+#include "drv_features.h"
+#if (defined( __MSDC_BASIC_LOAD__) || defined(DRV_MSDC_BT)) //this should be defined as global option, without this option, this file won't be compiled
+#include "stack_common.h"
+#include "stack_msgs.h"
+#include "app_ltlcom.h" /* Task message communiction */
+#include "kal_public_api.h"
+//guilin #include "tst_ltlcom.h"
+#include "kal_debug.h"
+#include "syscomp_config.h"
+#include "task_config.h" /* Task creation */
+#include "cache_sw.h"
+#include "stacklib.h" /* Basic type for dll, evshed, stacktimer */
+
+#include "event_shed.h" /* Event scheduler */
+
+#include "stack_timer.h" /* Stack timer */
+
+#include "string.h"
+#include "uart_sw.h"
+
+#include "stack_timer.h" /* Stack timer */
+
+#include <stdlib.h>
+
+#include "stdio.h"
+#include "uart_sw.h"
+#include "fat_fs.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+
+
+#include "fs_gprot.h"
+#include "config_hw.h"
+#include "intrCtrl.h"
+
+#include "dma_hw.h"
+#include "dma_sw.h"
+
+#include "pwic.h"
+
+#include "dcl.h"
+#include "dcl_msdc.h"
+#include "eint.h"
+
+//extern void srand(unsigned int seed);
+//extern int rand(void);
+
+
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON1
+#error "__CLKG_DEFINE__ & DRVPDN_CON1 are all defined"
+#else
+#define DRVPDN_CON1 CG_CON1
+#endif
+
+#ifdef DRVPDN_CON0
+#error "__CLKG_DEFINE__ & DRVPDN_CON0 are all defined"
+#else
+#define DRVPDN_CON0 CG_CON0
+#endif
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC CG_CON1_MSDC
+#endif
+
+#ifdef DRVPDN_CON0_MSDC2
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_MSDC2 are all defined"
+#else
+#define DRVPDN_CON0_MSDC2 CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR CG_CLR1
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET CG_SET1
+#endif
+#endif
+
+
+#define MSDC_DVT
+#ifdef MSDC_DVT
+
+#ifdef __MSDC_BASIC_LOAD__
+typedef struct ssdbg1_context_struct_t
+{
+ stack_timer_struct ssdbg1_timer0;
+ stack_timer_struct ssdbg1_base_timer;
+ event_scheduler *ssdbg1_event_scheduler_ptr;
+ eventid ssdbg1_event_id;
+} ssdbg1_context_struct_t;
+
+extern ssdbg1_context_struct_t ssdbg1_context;
+
+typedef struct ssdbg2_context_struct_t
+{
+ stack_timer_struct ssdbg2_timer0;
+
+ stack_timer_struct ssdbg2_base_timer;
+ event_scheduler *ssdbg2_event_scheduler_ptr;
+ eventid ssdbg2_event_id;
+} ssdbg2_context_struct_t;
+
+extern ssdbg2_context_struct_t ssdbg2_context;
+
+
+typedef struct
+{
+ LOCAL_PARA_HDR
+ kal_uint32 id;
+} ssdbg1_localpara_struct;
+
+
+#endif
+
+#define LEN 32*1024
+//#define LEN 512*1024
+#define TIMES 100
+//static kal_uint8 MyTxbuf[LEN];
+//static kal_uint8 MyRxbuf[LEN];
+//static kal_uint8 buffer[1024*8];
+//static kal_uint32 fcount = 0;
+#define BYTES_PER_ACCESS 17839
+//#define WRITE_TEST
+//#define CACHED_TEST
+
+//#define NOT_4BYTES_ALIGN
+
+__align(4) kal_uint8 r[LEN + 3], w[LEN + 3], w1[LEN + 3], r2[LEN + 3], w2[LEN + 3];
+
+volatile kal_bool check_read_content = KAL_TRUE;
+double bestReadThroughput, worstReadThroughput, bestWriteThroughput, worstWriteThroughput;
+
+#ifdef CACHED_TEST
+kal_bool cachedTest;
+double cachedBestReadThroughput, cachedWorstReadThroughput, cachedBestWriteThroughput, cachedWorstWriteThroughput;
+#pragma arm section zidata = "CACHEDZI"
+__align(4) kal_uint8 cached_r[LEN + 3], cached_w[LEN + 3];
+#pragma arm section zidata
+#endif
+
+#ifdef __MSDC_BASIC_LOAD__
+#define TESTBLNUMMAX 1024
+
+
+kal_int32 testblnum = 32;
+#define TESTLOOP 1
+#define ADDREND 100
+#define ADDREND2 (ADDREND*10)
+
+
+//
+// For each project, config gpio setting at first.
+//
+
+#define CLKSRCNUM 4 // 0~3
+#define SCLKFNUM 4 // 0~3,255
+
+#pragma arm section zidata = "NONCACHEDZI", rwdata = "NONCACHEDRW"
+kal_uint32 msdc_sector_buf1[128] = {0};
+kal_uint32 msdc_sector_buf2[128] = {0};
+kal_uint32 msdc_sector_buf3[128] = {0};
+kal_uint8 MSDC_Sector_guilin81[129 * 4] = {0};
+kal_uint8 MSDC_Sector_guilin82[129 * 4] = {0};
+
+kal_uint32 msdc_uncachedBuf1[TESTBLNUMMAX * 512 / 4];
+kal_uint32 msdc_uncachedBuf2[TESTBLNUMMAX * 512 / 4];
+#pragma arm section zidata, rwdata
+
+kal_uint32 cachemsdc_sector_buf1[128] = {0};
+kal_uint32 cachemsdc_sector_buf2[128] = {0};
+kal_uint32 cachemsdc_uncachedBuf1[TESTBLNUMMAX * 512 / 4];
+kal_uint32 cachemsdc_uncachedBuf2[TESTBLNUMMAX * 512 / 4];
+
+extern kal_bool MSDC_useDMA4ByteBurst;
+kal_uint32 test_clksrc;
+kal_uint32 test_sclkf;
+kal_uint32 testsectors;
+kal_uint32 gspeed = 0;
+
+typedef struct
+{
+ kal_int32 bit14;
+ kal_int32 isread1;
+ kal_int32 clksrc;
+ kal_int32 sclkf;
+ kal_int32 clock;
+ kal_int32 addr;
+ kal_int32 blnum;
+ kal_int32 speed;
+} CLKTEST;
+
+CLKTEST test_statistic[1000];
+
+
+#define ESCKEY (0x1b)
+
+void msdc_dbg_print(char *fmt, ...);
+void msdc_dbg_input(kal_uint32 *value);
+void guilin_sleep(kal_uint32 x);
+#endif
+
+void dummyFunction(void) {}
+
+#if defined(MSDC_SDIO_DVT) || defined(MSDC2_SDIO_DVT)
+kal_bool waitingSDIOTest = KAL_TRUE;/*if SDIO test is doing, we have to make both task wait for SDIO test done*/
+#else
+kal_bool waitingSDIOTest = KAL_FALSE;
+#endif
+
+#ifdef MSDC2_SDIO_DVT
+extern MSDC_HANDLE *msdc2_handle ;
+#endif
+
+#ifdef __MSDC_BASIC_LOAD__
+/*
+#if 1
+void MSDC_DVT_readWrite(void)
+{
+ kal_int32 status;
+
+ dbg_print("[%s %d]\r\n",__FUNCTION__,__LINE__);
+ gMSDC_Handle->mIsInitMSDC = KAL_FALSE;
+ gMSDC_Handle->mIsInitialized = KAL_FALSE;
+ //MSDC_Initialize();
+ //status=SD_Initialize();
+ status = DclSD_Initialize();
+ dbg_print("[%s %d]SD_Initialize=%d \r\n",__FUNCTION__,__LINE__,status);
+ //status = MountDevice_NEW(&MSDC_Blk[0], 0, 0, 0);
+ //dbg_print("[%s %d]MountDevice_NEW=%d \r\n",__FUNCTION__,__LINE__,status);
+ status = SD_Initialize();
+ //MSDC_PDNControl(0);
+
+
+}
+#else
+void MSDC_DVT_readWrite(void)
+{
+
+
+
+#ifdef MULTIPLE_WRITE_TEST
+ gMSDC_Handle->mIsPresent = KAL_TRUE;
+ simple_multi_write_test();
+ return;
+#endif
+
+
+
+
+ kal_int32 i,j, result = 0, count = 0;
+ kal_uint32 access = 17893;
+ FS_HANDLE hFile=0, wFile = 0;
+ kal_wchar full_name[100];
+ kal_uint32 file_size,len,total_len;
+ kal_uint32 time_1,time_2;
+ double rate;
+ volatile kal_bool format = 0;
+ kal_uint8 offset1 = 0,offset2 = 0;
+ kal_uint32 timeUsedinFS;
+ int card;
+ kal_uint8 path[10];
+ FS_DiskInfo info;
+
+ kal_uint32 testTimes = 0;
+
+
+
+ result = FS_TestMSDC(gMSDC_Handle);
+ if(result < FS_NO_ERROR){
+ dbg_print("memory card card not present %d !!\r\n", result);
+ return;
+ while(1)
+ kal_sleep_task(1000);
+ }
+
+ card = FS_GetDrive(FS_DRIVE_V_REMOVABLE, 1, FS_NO_ALT_DRIVE);
+
+ if (card >= FS_NO_ERROR)
+ {
+ kal_wsprintf((WCHAR*) path, "%c:\\", card);
+
+ result = FS_GetDiskInfo((WCHAR*) path, &info, FS_DI_BASIC_INFO | FS_DI_FREE_SPACE);
+ if (result < RTF_NO_ERROR)
+ {
+ ASSERT(0);
+ }
+
+
+ }
+ else{
+ dbg_print("memory card card not present!!\r\n");
+ return;
+ while(1)
+ kal_sleep_task(1000);
+ }
+
+#ifdef HW_FAST_FORMAT_TEST
+ while(1){
+ time_1 = drv_get_current_time();
+ result = FS_GeneralFormat((WCHAR*) path, FS_FORMAT_HIGH, NULL);
+ if(FS_NO_ERROR == result){
+ time_2 = drv_get_current_time();
+ dbg_print("format done %d, %f\n\r", time_2 - time_1, (double)(0.0005 * writeSectorsCount * 32000)/(double)(writeTimeCount));
+ writeSectorsCount = writeTimeCount = 0;
+ kal_sleep_task(1500);
+ }
+ else{
+ dbg_print("format failed: %d \n\r", result);
+ while(1)
+ kal_sleep_task(1000);
+
+ }
+ }
+#endif
+ //DumpDiskInfo("d:\\");
+ kal_wsprintf(full_name, "%c:\\Write.bin", card);
+ for(i=0;i<LEN+3;i++)
+ {
+ w[i+offset1] = i%256;
+ r[i+offset2] = 0;
+
+#ifdef CACHED_TEST
+ cached_w[i+offset1] = i%256;
+ cached_r[i+offset2] = 0;
+#endif
+
+ }
+
+#if defined(NOT_4BYTES_ALIGN)
+ // test W to B or B to W(DMA)
+ offset1 = (kal_uint32)w % 4;
+ if(offset1 == 0)
+ offset1 = 1;
+ else
+ offset1 = 0;
+
+ offset2 = (kal_uint32)r % 4;
+ if(offset2 == 0)
+ offset2 = 1;
+ else
+ offset2 = 0;
+ for(i=0;i<LEN+3;i++)
+ {
+ w[i+offset1] = i%256;
+ r[i+offset2] = 0;
+ }
+#endif
+
+
+ while(1){
+
+
+#if 1//write
+
+ count++;
+ //Search_Dir(L"C:\\");
+ FS_Delete(full_name);
+#ifdef CACHED_TEST
+ if(KAL_TRUE == cachedTest)
+ cachedTest = KAL_FALSE;
+ else
+ cachedTest = KAL_TRUE;
+
+ if(KAL_TRUE == cachedTest)
+ dbg_print("\r\n===========Cached Write Test Start(%d) ====================\r\n",count);
+ else
+#endif
+ dbg_print("\r\n==================Write Test Start(%d) ====================\r\n",count);
+
+ hFile = FS_Open(full_name, FS_CREATE|FS_READ_WRITE);
+ if(hFile <= 0){
+ dbg_print("open file failed \r\n");
+ return ;
+ }
+ //ASSERT(hFile>0);
+
+#if defined(NOT_4BYTES_ALIGN)
+ // test W to B or B to W(DMA)
+ offset1 = (kal_uint32)w % 4;
+ if(offset1 == 0)
+ offset1 = 1;
+ else
+ offset1 = 0;
+
+ offset2 = (kal_uint32)r % 4;
+ if(offset2 == 0)
+ offset2 = 1;
+ else
+ offset2 = 0;
+ for(i=0;i<LEN+3;i++)
+ {
+ w[i+offset1] = i%256;
+ r[i+offset2] = 0;
+ }
+#endif
+ i = 0;
+ total_len = 0;
+
+ kal_get_time(&time_1);
+ //readSectorCount = writeSectorCount = readTime = writeTime = writeSectorCount2 = writeTime2 = 0;
+ //writeTime3 = writeTime4 = writeTime5 = writeTime6 = 0;
+ while(1)
+ {
+
+#ifdef CACHED_TEST
+ if(KAL_TRUE == cachedTest)
+ result = FS_Write(hFile,cached_w+offset1,LEN,&len);
+ else
+#endif
+ result = FS_Write(hFile,w+offset1,LEN,&len);
+ total_len += len;
+ i++;
+ if(result < 0 ){
+ if(result == RTF_DISK_FULL){
+ dbg_print("Disk Full %d\r\n", total_len);
+ FS_Close(hFile);
+ return;
+ }
+ else{
+ dbg_print("write fail %d at: %d \r\n",result, total_len);
+ FS_Close(hFile);
+ return;
+
+ break;
+ }
+ }
+ if(len != LEN){
+ dbg_print("write length not correct \r\n");
+ FS_Close(hFile);
+ return;
+ }
+ if(i%TIMES == 0)
+ {
+ kal_get_time(&time_2);
+ rate = (double)(LEN*TIMES)/(double)(time_2-time_1);
+ dbg_print("write[%d], total: %d, rate %f \r\n", i, total_len,rate/0.004615);
+ //dbg_print("%d, %d, %d , %d\r\n", writeTime3 , writeTime4 , writeTime5,writeTime6);
+ //readSectorCount = writeSectorCount = readTime = writeTime = writeSectorCount2 = writeTime2= 0;
+ //writeTime3 = writeTime4 = writeTime5 = writeTime6 = 0;
+#ifdef CACHED_TEST
+ if(KAL_TRUE == cachedTest){
+ if((rate/0.004615) > cachedBestWriteThroughput || 0 == cachedBestWriteThroughput)
+ cachedBestWriteThroughput = (rate/0.004615);
+ if((rate/0.004615) < cachedWorstWriteThroughput || 0 == cachedWorstWriteThroughput)
+ cachedWorstWriteThroughput = (rate/0.004615);
+ }
+ else
+#endif
+ {
+ if((rate/0.004615) > bestWriteThroughput || 0 == bestWriteThroughput)
+ bestWriteThroughput = (rate/0.004615);
+ if((rate/0.004615) < worstWriteThroughput || 0 == worstWriteThroughput)
+ worstWriteThroughput = (rate/0.004615);
+ }
+
+ kal_get_time(&time_1);
+
+
+ if(i == TIMES*5) break;
+ }
+ }
+ FS_Close(hFile);
+
+#ifdef CACHED_TEST
+ if(KAL_TRUE == cachedTest)
+ dbg_print("\r\nbest: %f, worst:%f\r\n", cachedBestWriteThroughput, cachedWorstWriteThroughput);
+ else
+#endif
+ dbg_print("\r\nbest: %f, worst:%f\r\n", bestWriteThroughput, worstWriteThroughput);
+
+ dbg_print("\r\n==================Write Test End(%d) ====================\r\n",count);
+#endif //write
+
+#if 1 // read test
+
+#ifdef CACHED_TEST
+ if(KAL_TRUE == cachedTest)
+ dbg_print("\r\n==========Cached Read Test Start(%d) ====================\r\n",count);
+ else
+#endif
+ dbg_print("\r\n==================Read Test Start(%d) ====================\r\n",count);
+
+ timeUsedinFS = 0;
+ i = 0;
+ total_len = 0;
+ hFile = FS_Open(full_name, FS_READ_WRITE);
+ if(hFile <= 0){
+ dbg_print("FS open failed\r\n");
+ return;
+ }
+
+ ASSERT(hFile>0);
+
+ while(1){
+ kal_get_time(&time_1);
+
+#ifdef CACHED_TEST
+ if(KAL_TRUE == cachedTest)
+ result = FS_Read(hFile,cached_r +offset1,LEN,&len);
+ else
+#endif
+ result = FS_Read(hFile,r+offset2,LEN,&len);
+
+ kal_get_time(&time_2);
+ timeUsedinFS += (time_2 - time_1);
+ i++;
+ total_len += len;
+
+ if(check_read_content)
+ {
+#ifdef CACHED_TEST
+ if(KAL_TRUE == cachedTest){
+ for(j=0;j<len;j++){
+ if(cached_r[j+offset2] != cached_w[j+offset1])
+ {
+ dbg_print("read not the same , at: %d, %d, %d, %d \r\n", total_len, j, offset2, offset1);
+ while(1);
+ }
+
+ }
+ }
+ else
+#endif
+ {
+ for(j=0;j<len;j++){
+ if(r[j+offset2] != w[j+offset1])
+ {
+ dbg_print("read not the same , at: %d, %d, %d, %d \r\n", total_len, j, offset2, offset1);
+ FS_Close(hFile);
+ return;
+ }
+
+ }
+ }
+ dbg_print(".");
+#ifdef CACHED_TEST
+ if(KAL_TRUE == cachedTest)
+ memset(cached_r,0,sizeof(cached_r));
+ else
+#endif
+ memset(r,0,sizeof(r));
+ }
+ if(result < 0){
+ if(result != RTF_DISK_FULL){
+ dbg_print("read fail %d, at: %d \r\n", result, total_len);
+ FS_Close(hFile);
+ return;
+ }
+ else{
+ dbg_print("Disk Full \r\n");
+ FS_Close(hFile);
+ return;
+ }
+ }
+ if(len != LEN){
+ dbg_print("length not correct \r\n");
+ FS_Close(hFile);
+ return;
+ }
+ if(i%TIMES == 0){
+
+ rate = (double)(LEN*TIMES)/(double)timeUsedinFS;
+ dbg_print("read[%d], total: %d, rate: %f \r\n", i, total_len,rate/0.004615);
+
+#ifdef CACHED_TEST
+ if(KAL_TRUE == cachedTest){
+ if((rate/0.004615) > cachedBestReadThroughput || 0 == cachedBestReadThroughput)
+ cachedBestReadThroughput = (rate/0.004615);
+ if((rate/0.004615) < cachedWorstReadThroughput || 0 == cachedWorstReadThroughput)
+ cachedWorstReadThroughput = (rate/0.004615);
+ }
+ else
+#endif
+ {
+ if((rate/0.004615) > bestReadThroughput || 0 == bestReadThroughput)
+ bestReadThroughput = (rate/0.004615);
+ if((rate/0.004615) < worstReadThroughput || 0 == worstReadThroughput)
+ worstReadThroughput = (rate/0.004615);
+ }
+
+ timeUsedinFS = 0;
+ if(i == TIMES*5) break;
+ }
+ }
+ FS_Close(hFile);
+
+#ifdef CACHED_TEST
+ if(KAL_TRUE == cachedTest)
+ dbg_print("\r\nbest: %f, worst:%f\r\n", cachedBestReadThroughput, cachedWorstReadThroughput);
+ else
+#endif
+ dbg_print("\r\nbest: %f, worst:%f\r\n", bestReadThroughput, worstReadThroughput);
+
+ dbg_print("\r\n==================Read Test End(%d) ====================\r\n",count);
+ FS_Delete(full_name);
+#endif // read test
+
+ testTimes ++;
+ if(5 == testTimes)
+ return;
+ }
+ //=======================================//
+}
+#endif
+*/
+
+typedef struct
+{
+ kal_char name[16];
+ kal_uint32 addr;
+ kal_uint32 defval;
+} REGTEST;
+
+REGTEST regbuf[] =
+{
+ {"MSDC_CFG ", MSDC_CFG, 0x04000020},
+ {"MSDC_STA ", MSDC_STA, 2},
+ {"MSDC_INT ", MSDC_INTR, 0},
+ {"MSDC_PS ", MSDC_PS, 0x01ff0008},
+
+ {"MSDC_DAT ", MSDC_DAT, 0xffffffff},
+ {"MSDC_IOCON0 ", MSDC_IOCON, 0x010000c3},
+ {"MSDC_IOCON1 ", MSDC_IOCON1, 0x00022022},
+
+ {"SDC_CFG ", SDC_CFG, 0x8000},
+ {"SDC_CMD ", SDC_CMD, 0},
+ {"SDC_ARG ", SDC_ARG, 0xffffffff},
+ {"SDC_STA ", SDC_STA, 0x8000},
+
+ {"SDC_RESP0 ", SDC_RESP0, 0xffffffff},
+ {"SDC_RESP1 ", SDC_RESP1, 0xffffffff},
+ {"SDC_RESP2 ", SDC_RESP2, 0xffffffff},
+ {"SDC_RESP3 ", SDC_RESP3, 0xffffffff},
+
+ {"SDC_CMDSTA ", SDC_CMDSTA, 0},
+ {"SDC_DATSTA ", SDC_DATSTA, 0},
+ {"SDC_CSTA ", SDC_CSTA, 0},
+ {"SDC_IRQMASK0 ", SDC_IRQMASK0, 0},
+ {"SDC_IRQMASK1 ", SDC_IRQMASK1, 0},
+
+#if defined(__MSDC_SD_SDIO__)
+ //{"SDIO_CFG ",SDIO_CFG,0},
+ //{"SDIO_STA ",SDIO_STA,0},
+#endif
+
+ {"BOOT_CFG ", MSDC_BOOT_CFG, 0},
+ {"BOOT_STA ", MSDC_BOOT_STA, 0},
+
+ {"CLKACB_CFG ", MSDC_CLKACB_CFG, 0x00020000},
+};
+
+kal_int32 sdtestgpio(void)
+{
+ DCL_HANDLE handle;
+ int x;
+ handle = DclGPIO_Open(DCL_GPIO, 10); // GPIO10
+ DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+
+ for (x = 100; x; x--)
+ {
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+ }
+
+ DclGPIO_Close(handle);
+
+}
+
+kal_int32 sdtestgpio2(void)
+{
+ kal_uint8 buf[30], input, offset;
+ kal_int32 value, x;
+ DCL_HANDLE handle;
+
+ memset(buf, 0, sizeof(buf));
+ msdc_dbg_print("input(GPIO)(ESC:exit):");
+ offset = 0;
+
+ while (1)
+ {
+ input = U_GetUARTByte(uart_port1);
+
+ if (input >= '0' && input <= '9')
+ {
+ //input -= '0';
+ }
+ else if (input == 0x0d || input == 0x0a)
+ {
+ break;
+ }
+ else if (input == ESCKEY) //esc
+ {
+ return;
+ }
+ else
+ {
+ continue;
+ }
+
+ buf[offset++] = input;
+ dbg_print("%c", input);
+ }
+
+ buf[30 - 1] = 0;
+ value = -1;
+ dbg_print("\r\n");
+ sscanf(buf, "%d", &value);
+
+ if (value >= 0)
+ {
+ handle = DclGPIO_Open(DCL_GPIO, value); // GPIO10
+ DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_OUT, 0);
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+ msdc_dbg_print("[%s %d]gpio=%d \r\n", __FUNCTION__, __LINE__, value);
+
+ for (x = 1000000; x; x--)
+ {
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_HIGH, 0);
+ DclGPIO_Control(handle, GPIO_CMD_WRITE_LOW, 0);
+ }
+
+ DclGPIO_Close(handle);
+ }
+
+
+}
+
+
+
+SDC_CMD_STATUS SD_ReadSingleBlock_MCU(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+ kal_uint32 count, whileIndex;
+ SDC_CMD_STATUS status;
+ kal_uint32 value;
+
+ count = MSDC_SD_BLOCK_SIZE;
+
+#ifdef DRV_LSD
+ LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+#endif
+
+ RESET_MSDC();
+
+ if ((status = SD_Send_Cmd(SDC_CMD_CMD17, data_adrs)) != NO_ERROR)
+ goto ERR_Exit;
+
+ whileIndex = 0;
+
+ while (1)
+ {
+ if (!MSDC_IS_FIFO_EMPTY)
+ {
+ value = MSDC_Reg32(MSDC_DAT);
+
+ if ((kal_uint32)rxbuffer % 4)
+ kal_mem_cpy(rxbuffer + whileIndex, (const void*)&value, 4);
+ else
+ *(rxbuffer + whileIndex) = value;
+
+ whileIndex++;
+
+ if (whileIndex >= count)
+ break;
+ }
+ }
+
+ if ((status = SD_WaitDatRdyOrTo()) != NO_ERROR)
+ goto ERR_Exit;
+
+ MSDC_CLR_FIFO();
+
+#ifdef SD_STOP_SLOW
+ {
+ kal_uint32 cardStatus;
+ whileIndex = 0x40000;
+
+ while (SD_IS_R1B_BUSY && whileIndex)
+ whileIndex--;
+
+ whileIndex = 0x100;
+
+ do
+ {
+ status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&cardStatus);
+
+ if (NO_ERROR != status)
+ {
+ dbg_print("[MSDC]CMD13 fail when singleBlockRead!");
+ msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+ goto ERR_Exit;
+ }
+
+ whileIndex--;
+ }
+ while (((cardStatus & R1_CUR_STATE) >> 9 != TRAN_STA) && (0 != whileIndex));
+ }
+#endif
+ MSDC_CLR_FIFO();
+ RESET_MSDC();
+ return NO_ERROR;
+ERR_Exit:
+ {
+ kal_uint32 tmp;
+
+#ifdef MSDC_USE_INT
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+#endif
+ DisableMSDC_DMA();
+ RESET_MSDC();
+
+ // SD_StopTrans(KAL_FALSE);
+ SD_GetStatus(gSD->mRCA, (kal_uint32*)&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA, &tmp);
+ MSDC_CLR_FIFO();
+ msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+ return status;
+ }
+
+}
+
+SDC_CMD_STATUS SD_ReadSingleBlock_MCU_datto(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+ kal_uint32 count, whileIndex;
+ SDC_CMD_STATUS status;
+ kal_uint16 sdc_datsta;
+ // msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x",__FUNCTION__,__LINE__,data_adrs,rxbuffer);
+ count = MSDC_SD_BLOCK_SIZE;
+#ifdef DRV_LSD
+ LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+#endif
+ {
+ DCL_HANDLE handle;
+ handle = DclGPIO_Open(DCL_GPIO, DATGPIO);
+ DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+ DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+ DclGPIO_Close(handle);
+ guilin_sleep(10);
+ }
+
+ if ((status = SD_Send_Cmd(SDC_CMD_CMD17, data_adrs)) != NO_ERROR)
+ goto ERR_Exit;
+
+ whileIndex = 0;
+
+ while (1) //for(whileIndex=0;whileIndex<count;whileIndex++)
+ {
+ sdc_datsta = MSDC_Reg(SDC_DATSTA);
+ gMSDC_Handle->dat_sta = sdc_datsta;
+
+ if (sdc_datsta & SDC_DATSTA_DATTO)
+ {
+ msdc_dbg_print("[%s %d]ERROR,sdc_datsta=0x%x", __FUNCTION__, __LINE__, sdc_datsta);
+ status = ERR_DAT_TIMEOUT;
+ goto ERR_Exit;
+ }
+ else if (sdc_datsta & SDC_DATSTA_DATCRCERR)
+ {
+ status = ERR_DAT_CRCERR;
+ goto ERR_Exit;
+ }
+
+ if (!MSDC_IS_FIFO_EMPTY )
+ {
+ *(rxbuffer + whileIndex) = MSDC_Reg32(MSDC_DAT);
+ whileIndex++;
+
+ if (whileIndex >= count)
+ break;
+ }
+ }
+
+ //if ((status = SD_WaitDatRdyOrTo())!=NO_ERROR)
+ // goto ERR_Exit;
+
+ MSDC_CLR_FIFO();
+
+#ifdef SD_STOP_SLOW
+ {
+ kal_uint32 cardStatus;
+ whileIndex = 0x40000;
+
+ while (SD_IS_R1B_BUSY && whileIndex)
+ whileIndex--;
+
+ whileIndex = 0x100;
+
+ do
+ {
+ status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&cardStatus);
+
+ if (NO_ERROR != status)
+ {
+ dbg_print("[MSDC]CMD13 fail when singleBlockRead!");
+ msdc_dbg_print("[%s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+ goto ERR_Exit;
+ }
+
+ whileIndex--;
+ }
+ while (((cardStatus & R1_CUR_STATE) >> 9 != TRAN_STA) && (0 != whileIndex));
+ }
+#endif
+ MSDC_CLR_FIFO();
+ RESET_MSDC();
+ return NO_ERROR;
+ERR_Exit:
+ {
+ kal_uint32 tmp;
+
+#ifdef MSDC_USE_INT
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+#endif
+ DisableMSDC_DMA();
+ RESET_MSDC();
+
+ // SD_StopTrans(KAL_FALSE);
+ SD_GetStatus(gSD->mRCA, (kal_uint32*)&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA, &tmp);
+ MSDC_CLR_FIFO();
+ msdc_dbg_print("[%s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+ return status;
+ }
+
+}
+SDC_CMD_STATUS SD_ReadSingleBlock_MCU_datcrc(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+ kal_uint32 count, whileIndex;
+ SDC_CMD_STATUS status;
+ kal_uint16 sdc_datsta;
+ // msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x",__FUNCTION__,__LINE__,data_adrs,rxbuffer);
+ count = MSDC_SD_BLOCK_SIZE;
+#ifdef DRV_LSD
+ LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+#endif
+
+ if ((status = SD_Send_Cmd(SDC_CMD_CMD17, data_adrs)) != NO_ERROR)
+ goto ERR_Exit;
+
+ whileIndex = 0;
+
+ while (1) //for(whileIndex=0;whileIndex<count;whileIndex++)
+ {
+ sdc_datsta = MSDC_Reg(SDC_DATSTA);
+ gMSDC_Handle->dat_sta = sdc_datsta;
+
+ if (sdc_datsta & SDC_DATSTA_DATCRCERR)
+ {
+ msdc_dbg_print("[%s %d]ERROR,sdc_datsta=0x%x", __FUNCTION__, __LINE__, sdc_datsta);
+ status = ERR_DAT_CRCERR;
+ goto ERR_Exit;
+ }
+ else if (sdc_datsta & SDC_DATSTA_DATTO)
+ {
+ status = ERR_DAT_TIMEOUT;
+ goto ERR_Exit;
+ }
+
+ if (!MSDC_IS_FIFO_EMPTY)
+ {
+ *(rxbuffer + whileIndex) = MSDC_Reg32(MSDC_DAT);
+ whileIndex++;
+
+ if (whileIndex >= count)
+ break;
+ }
+
+ if (whileIndex == 100 )
+ {
+ DCL_HANDLE handle;
+ handle = DclGPIO_Open(DCL_GPIO, DATGPIO);
+ DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+ DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+ DclGPIO_Close(handle);
+ guilin_sleep(10);
+ }
+ else if (whileIndex == 110 )
+ {
+ DCL_HANDLE handle;
+ handle = DclGPIO_Open(DCL_GPIO, DATGPIO);
+ DclGPIO_Control(handle, GPIO_CMD_SET_MODE_1, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+ DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+ DclGPIO_Close(handle);
+ guilin_sleep(10);
+ }
+
+ }
+
+ // if ((status = SD_WaitDatRdyOrTo())!=NO_ERROR)
+ // goto ERR_Exit;
+
+ MSDC_CLR_FIFO();
+
+#ifdef SD_STOP_SLOW
+ {
+ kal_uint32 cardStatus;
+ whileIndex = 0x40000;
+
+ while (SD_IS_R1B_BUSY && whileIndex)
+ whileIndex--;
+
+ whileIndex = 0x100;
+
+ do
+ {
+ status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&cardStatus);
+
+ if (NO_ERROR != status)
+ {
+ dbg_print("[MSDC]CMD13 fail when singleBlockRead!");
+ msdc_dbg_print("[%s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+ goto ERR_Exit;
+ }
+
+ whileIndex--;
+ }
+ while (((cardStatus & R1_CUR_STATE) >> 9 != TRAN_STA) && (0 != whileIndex));
+ }
+#endif
+ MSDC_CLR_FIFO();
+ RESET_MSDC();
+ return NO_ERROR;
+ERR_Exit:
+ {
+ kal_uint32 tmp;
+
+#ifdef MSDC_USE_INT
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+#endif
+ DisableMSDC_DMA();
+ RESET_MSDC();
+
+ // SD_StopTrans(KAL_FALSE);
+ SD_GetStatus(gSD->mRCA, (kal_uint32*)&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA, &tmp);
+ MSDC_CLR_FIFO();
+ msdc_dbg_print("[%s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+ return status;
+ }
+
+}
+SDC_CMD_STATUS SD_ReadSingleBlock_MCU_cmdto(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+ kal_uint32 count, whileIndex;
+ SDC_CMD_STATUS status;
+ kal_uint16 sdc_datsta;
+ // msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x",__FUNCTION__,__LINE__,data_adrs,rxbuffer);
+ count = MSDC_SD_BLOCK_SIZE;
+#ifdef DRV_LSD
+ LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+#endif
+ {
+ DCL_HANDLE handle;
+ handle = DclGPIO_Open(DCL_GPIO, CMDGPIO);
+ DclGPIO_Control(handle, GPIO_CMD_SET_MODE_0, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+ DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+ DclGPIO_Close(handle);
+ guilin_sleep(10);
+ }
+
+ if ((status = SD_Send_Cmd(SDC_CMD_CMD17, data_adrs)) != NO_ERROR)
+ goto ERR_Exit;
+
+ whileIndex = 0;
+
+ while (1) //for(whileIndex=0;whileIndex<count;whileIndex++)
+ {
+ if (!MSDC_IS_FIFO_EMPTY )
+ {
+ *(rxbuffer + whileIndex) = MSDC_Reg32(MSDC_DAT);
+ whileIndex++;
+
+ if (whileIndex >= count)
+ break;
+ }
+
+ sdc_datsta = MSDC_Reg(SDC_DATSTA);
+ gMSDC_Handle->dat_sta = sdc_datsta;
+
+ if (sdc_datsta >> 1)
+ {
+ msdc_dbg_print("[guilin %s %d]ERROR,sdc_datsta=0x%x", __FUNCTION__, __LINE__, sdc_datsta);
+ break;
+ }
+
+ }
+
+ // if((status = SD_WaitDatRdyOrTo())!=NO_ERROR)
+ // goto ERR_Exit;
+
+ MSDC_CLR_FIFO();
+
+#ifdef SD_STOP_SLOW
+ {
+ kal_uint32 cardStatus;
+ whileIndex = 0x40000;
+
+ while (SD_IS_R1B_BUSY && whileIndex)
+ whileIndex--;
+
+ whileIndex = 0x100;
+
+ do
+ {
+ status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&cardStatus);
+
+ if (NO_ERROR != status)
+ {
+ dbg_print("[MSDC]CMD13 fail when singleBlockRead!");
+ msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+ goto ERR_Exit;
+ }
+
+ whileIndex--;
+ }
+ while (((cardStatus & R1_CUR_STATE) >> 9 != TRAN_STA) && (0 != whileIndex));
+ }
+#endif
+ MSDC_CLR_FIFO();
+ RESET_MSDC();
+ return NO_ERROR;
+ERR_Exit:
+ {
+ kal_uint32 tmp;
+
+#ifdef MSDC_USE_INT
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+#endif
+ DisableMSDC_DMA();
+ RESET_MSDC();
+
+ // SD_StopTrans(KAL_FALSE);
+ SD_GetStatus(gSD->mRCA, (kal_uint32*)&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA, &tmp);
+ MSDC_CLR_FIFO();
+ msdc_dbg_print("[guilin %s %d]data_adrs=0x%x rxbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, data_adrs, rxbuffer, status);
+ return status;
+ }
+
+}
+
+SDC_CMD_STATUS SD_WriteSingleBlock_MCU(kal_uint32 address, kal_uint32* txbuffer)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 count, whileIndex, value;
+#ifdef DRV_MSDC_FORCE_WAIT_FOR_PROG_R1B_MALFUNCTION
+ kal_uint32 cardStatus = 0;
+ kal_uint32 t1 = 0;
+#endif
+ kal_uint32 *ptr;
+#if defined(MT6225)
+ kal_bool is_aligned;
+ ECO_VERSION eco;
+ eco = INT_ecoVersion();
+#endif
+
+#ifdef DRV_MSDC_2_DLT_FOR_RD_WR
+ kal_uint32 triedDLTTimes = 0;
+
+retryDLT:
+#endif
+
+ RESET_MSDC();
+ MSDC_CLR_FIFO();
+
+ if (gSD->mWPEnabled)
+ return ERR_WRITE_PROTECT;
+
+ count = MSDC_SD_BLOCK_SIZE;
+
+#if defined(MT6225)
+
+ if (eco <= ECO_E3)
+ {
+ is_aligned = ((kal_uint32)txbuffer % 4 == 0);
+
+ if (is_aligned)
+ {
+ ptr = txbuffer;
+ }
+ else
+ {
+ kal_mem_cpy(MSDC_Sector, txbuffer, 512);
+ ptr = MSDC_Sector;
+ }
+ }
+ else
+ {
+ ptr = txbuffer;
+ }
+
+#else
+ ptr = txbuffer;
+#endif
+
+#ifdef DRV_LSD
+ LSD_HostSetBuffer((kal_uint8 *)txbuffer);
+#endif
+
+ if ((status = SD_Send_Cmd(SDC_CMD_CMD24, address)) != NO_ERROR)
+ goto ERR_Exit;
+
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ goto ERR_Exit;
+
+ whileIndex = 0;
+
+ while (1)
+ {
+ if (!MSDC_IS_FIFO_FULL)
+ {
+ if ((kal_uint32)txbuffer % 4)
+ kal_mem_cpy(&value, (txbuffer + whileIndex), 4);
+ else
+ value = *(txbuffer + whileIndex);
+
+ MSDC_WriteReg32(MSDC_DAT, value);
+
+ whileIndex++;
+
+ if (whileIndex >= count)
+ break;
+ }
+ }
+
+ if ((status = SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT)) != NO_ERROR)
+ goto ERR_Exit;
+
+ if ((status = SD_WaitDatRdyOrTo()) != NO_ERROR)
+ goto ERR_Exit;
+
+#ifdef SD_STOP_SLOW
+ {
+ kal_uint32 cardStatus;
+ whileIndex = 0x40000;
+
+ while (SD_IS_R1B_BUSY && whileIndex)
+ whileIndex--;
+
+ whileIndex = 0x100;
+
+ do
+ {
+ status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&cardStatus);
+
+ if (NO_ERROR != status)
+ {
+ dbg_print("[MSDC]CMD13 fail when singleBlockWrite!");
+ msdc_dbg_print("[guilin %s %d]ERROR address=0x%x txbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, address, txbuffer, status);
+ goto ERR_Exit;
+ }
+
+ whileIndex--;
+ }
+ while (((cardStatus & R1_CUR_STATE) >> 9 != TRAN_STA) && (0 != whileIndex));
+
+ if ((cardStatus & R1_CUR_STATE) >> 9 != TRAN_STA) //guilin
+ {
+ msdc_dbg_print("[guilin %s %d]ERROR cardStatus=0x%x", __FUNCTION__, __LINE__, cardStatus);
+ return ERR_CMD_TIMEOUT; //guilin
+ }
+ }
+#endif
+
+ MSDC_CLR_FIFO();
+ RESET_MSDC();
+
+ return NO_ERROR;
+
+ERR_Exit:
+ {
+ kal_uint32 tmp;
+
+#ifdef MSDC_USE_INT
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+#endif
+ RESET_MSDC();
+ //SD_StopTrans(KAL_TRUE);
+ SD_GetStatus(gSD->mRCA, (kal_uint32*)&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA, &tmp);
+ msdc_dbg_print("[guilin %s %d]address=0x%x txbuffer=0x%x error=0x%x", __FUNCTION__, __LINE__, address, txbuffer, status);
+ return status;
+ }
+
+}
+
+// ==================================================================================
+//
+// Test Case 1. Mount
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase1(void)
+{
+ kal_int32 status;
+
+ msdc_dbg_print("\r\n[%s %d]mount test...\r\n", __FUNCTION__, __LINE__);
+
+
+
+ gMSDC_Handle->mIsInitMSDC = KAL_FALSE;
+ gMSDC_Handle->mIsInitialized = KAL_FALSE;
+ gMSDC_Handle->msdc_clkTuneUpperBund = MSDC_CLOCK / 2;
+
+ DclSD_Initialize();
+
+ //status = MountDevice_NEW(&MSDC_Blk[0], 0, 0, 0);
+ status = SD_Initialize();
+
+ testsectors = gSD->mCSD.capacity / 512;
+
+ msdc_dbg_print("[%s %d]size(sectors) = %d ,%d MB\r\n", __FUNCTION__, __LINE__, testsectors, gSD->mCSD.capacity / (1024 * 1024));
+
+ if (status != NO_ERROR)
+ msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ else
+ msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+ return status;
+}
+
+kal_int32 sdtestcase2(void)
+{
+ kal_int32 size, i;
+ msdc_dbg_print("\r\n[%s %d]reg default test...", __FUNCTION__, __LINE__);
+ size = sizeof(regbuf) / sizeof(REGTEST);
+
+ for (i = 0; i < size; i++)
+ {
+ msdc_dbg_print("[%s,0x%08x,0x%08x]=0x%08x", regbuf[i].name, regbuf[i].addr, regbuf[i].defval, MSDC_Reg32(regbuf[i].addr));
+ }
+}
+
+
+// ==================================================================================
+//
+// Test Case 3. Single block read test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase3(kal_int32 addr , kal_uint32 *pbufr)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 time1, time2;
+
+ sdtestgpio();
+
+ do
+ {
+
+ time1 = drv_get_current_time();
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock(addr, pbufr);
+ else
+ status = SD_ReadSingleBlock(addr * 512, pbufr);
+
+ time2 = drv_get_current_time();
+
+ if (status != NO_ERROR)
+ {
+ msdc_dbg_print("[%s %d]ERROR, SD_ReadSingleBlock, %d", __FUNCTION__, __LINE__, status);
+ break;
+ }
+
+ if (time2 != time1)
+ msdc_dbg_print("[%s %d]OK, SD_ReadSingleBlock, %5d KB/S,time=%d,addr=%d", __FUNCTION__, __LINE__, (1 * 32768 * 5) / ((time2 - time1) * 10), (time2 - time1), addr);
+ else
+ msdc_dbg_print("[%s %d]OK, SD_ReadSingleBlock, time=0,addr=%d", __FUNCTION__, __LINE__, addr);
+
+
+ }
+ while (0);
+
+ if (status != NO_ERROR)
+ msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ else
+ msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+
+ return status;
+}
+
+
+
+// ==================================================================================
+//
+// Test Case 4. Single block write test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase4(kal_int32 addr , kal_uint32 *pbufw , kal_uint32 *pbufr)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 time1, time2;
+ kal_int32 i, compare_error;
+
+ for (i = 0; i < 512; i++)
+ //pbufw[i]=((i+10)<<0)|((i+11)<<8)|((i+12)<<16)|((i+13)<<24);
+ *((kal_uint8 *)pbufw + i) = rand() % 256;
+
+ sdtestgpio();
+
+ do
+ {
+
+ time1 = drv_get_current_time();
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_WriteSingleBlock(addr, pbufw);
+ else
+ status = SD_WriteSingleBlock(addr * 512, pbufw);
+
+ time2 = drv_get_current_time();
+
+ if (status != NO_ERROR)
+ {
+ msdc_dbg_print("[%s %d]ERROR, SD_WriteSingleBlock, %d", __FUNCTION__, __LINE__, status);
+ break;
+ }
+
+ // readback compare
+ compare_error = 0;
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock(addr, pbufr);
+ else
+ status = SD_ReadSingleBlock(addr * 512, pbufr);
+
+ if (status != NO_ERROR)
+ {
+ msdc_dbg_print("[%s %d]ERROR, SD_ReadSingleBlock, %d", __FUNCTION__, __LINE__, status);
+ break;
+ }
+
+ for (i = 0; i < 512; i++)
+ {
+ if (((kal_uint8 *)pbufw)[i] != ((kal_uint8 *)pbufr)[i])
+ {
+ msdc_dbg_print("[%s %d]ERROR, compare error:0x%x , 0x%x ,i=%d", __FUNCTION__, __LINE__, pbufw[i], pbufr[i], i);
+ compare_error = 1;
+ status = ERR_STATUS;
+ break;
+ }
+ }
+
+ if (compare_error == 0)
+ {
+ if (time2 != time1)
+ msdc_dbg_print("[%s %d]OK,SD_WriteSingleBlock,readback compare ok,write= %5d KB/S , time=%d ,addr=%d", __FUNCTION__, __LINE__, (1 * 32768 * 5) / ((time2 - time1) * 10) , time2 - time1 , addr);
+ else
+ msdc_dbg_print("[%s %d]OK,SD_WriteSingleBlock,readback compare ok,time=0,addr=%d", __FUNCTION__, __LINE__, addr);
+ }
+
+
+
+ }
+ while (0);
+
+ if (status != NO_ERROR)
+ msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ else
+ msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+ return status;
+}
+
+
+// ==================================================================================
+//
+// Test Case 5. Multiple block read test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase5(kal_int32 addr , kal_uint32 *pbufr)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 time1, time2;
+
+ sdtestgpio();
+
+ do
+ {
+
+ time1 = drv_get_current_time();
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadMultiBlock(addr, pbufr, testblnum);
+ else
+ status = SD_ReadMultiBlock(addr * 512, pbufr, testblnum);
+
+ time2 = drv_get_current_time();
+
+ if (status != NO_ERROR)
+ {
+ msdc_dbg_print("[%s %d]ERROR, SD_ReadMultiBlock, %d", __FUNCTION__, __LINE__, status);
+ break;
+ }
+
+ if (time2 != time1)
+ msdc_dbg_print("[%s %d]OK,SD_ReadMultiBlock, %5d KB/S,addr=%d , blnum=%d", __FUNCTION__, __LINE__, (testblnum * 32768 * 5) / ((time2 - time1) * 10), addr, testblnum);
+ else
+ msdc_dbg_print("[%s %d]OK,SD_ReadMultiBlock, time=0,addr=%d , blnum=%d", __FUNCTION__, __LINE__, addr, testblnum);
+
+ gspeed = (testblnum * 32768 * 5) / ((time2 - time1) * 10);
+
+
+ }
+ while (0);
+
+ if (status != NO_ERROR)
+ msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ else
+ msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+ return status;
+}
+
+kal_int32 sdtestcase6(kal_int32 addr , kal_uint32 *pbufw , kal_uint32 *pbufr)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 time1, time2;
+
+ kal_int32 i, compare_error;
+
+ //srand(drv_get_current_tick());
+
+ for (i = 0; i < 512 * testblnum; i++)
+ //pbufw[i]=((i+20)<<0)|((i+21)<<8)|((i+22)<<16)|((i+23)<<24);
+ //*((kal_uint8 *)pbufw + i) = i;
+ *((kal_uint8 *)pbufw + i) = rand() % 256;
+
+ sdtestgpio();
+
+ do
+ {
+
+ time1 = drv_get_current_time();
+
+ if (SD_CARD == gMSDC_Handle->mMSDC_type)
+ {
+
+ status = SD_SetPreEraseBlk(testblnum);
+
+ if (status != NO_ERROR)
+ {
+ msdc_dbg_print("[%s %d]ERROR, pre erase fail!!, %d", __FUNCTION__, __LINE__, status);
+ break;
+ }
+ }
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_WriteMultiBlock(addr, pbufw, testblnum);
+ else
+ status = SD_WriteMultiBlock(addr * 512, pbufw, testblnum);
+
+ time2 = drv_get_current_time();
+
+ if (status != NO_ERROR)
+ {
+ msdc_dbg_print("[%s %d]ERROR,SD_WriteMultiBlock,%d", __FUNCTION__, __LINE__, status);
+ break;
+ }
+
+ // readback compare
+ compare_error = 0;
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadMultiBlock(addr, pbufr, testblnum);
+ else
+ status = SD_ReadMultiBlock(addr * 512, pbufr, testblnum);
+
+ if (status != NO_ERROR)
+ {
+ msdc_dbg_print("[%s %d]ERROR,SD_ReadMultiBlock,%d", __FUNCTION__, __LINE__, status);
+ break;
+ }
+
+ for (i = 0; i < 128 * testblnum; i++)
+ {
+ if (pbufw[i] != pbufr[i])
+ {
+ msdc_dbg_print("[%s %d]ERROR, readback compare error:0x%x , 0x%x ,i=%d", __FUNCTION__, __LINE__, pbufw[i], pbufr[i], i);
+ compare_error = 1;
+ status = ERR_STATUS;
+ break;
+ }
+ }
+
+ if (compare_error == 0)
+ {
+ if (time2 != time1)
+ msdc_dbg_print("[%s %d]OK,SD_WriteMultiBlock,readback compare ok,write= %5d KB/S , time=%d ,addr=%d , blnum=%d", __FUNCTION__, __LINE__, (testblnum * 32768 * 5) / ((time2 - time1) * 10) , time2 - time1 , addr, testblnum);
+ else
+ msdc_dbg_print("[%s %d]OK,SD_WriteMultiBlock,readback compare ok,time=0,addr=%d , blnum=%d", __FUNCTION__, __LINE__, addr, testblnum);
+ }
+
+ gspeed = (testblnum * 32768 * 5) / ((time2 - time1) * 10);
+
+
+
+ }
+ while (0);
+
+ if (status != NO_ERROR)
+ msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ else
+ msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+ return status;
+}
+
+kal_int32 SD_setclk(kal_int32 wdata)//KHZ
+{
+ msdc_clk_setting cs, cs2;
+ kal_int32 temp1, temp2;
+
+ temp1 = 0;
+ temp2 = 0x0fffffff;
+ cs2.cardClk = 0;
+
+ for (cs.sclkf = 0; cs.sclkf < 250; cs.sclkf ++)
+ {
+ for (cs.clksrc = 0; cs.clksrc < CLKSRCNUM; cs.clksrc ++)
+ {
+ cs.cardClk = gMsdcClksrcRate[cs.clksrc] / DIV_SCLKF(cs.sclkf);
+
+ if (wdata >= cs.cardClk)
+ {
+ temp1 = wdata - cs.cardClk;
+
+ if (temp1 <= temp2)
+ {
+ temp2 = temp1;
+ cs2.cardClk = cs.cardClk;
+ cs2.clksrc = cs.clksrc;
+ cs2.sclkf = cs.sclkf;
+
+ if (temp1 == 0)
+ goto SD_setclk_return;
+ }
+ }
+ }
+ }
+
+SD_setclk_return:
+
+ if (cs2.cardClk)
+ {
+ MSDC_LSD_ClearBits32(SDC_CFG, SDC_CFG_SIEN);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG, (kal_uint32)cs2.sclkf, MSDC_CFG_SCLKF);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG, (kal_uint32)cs2.clksrc, MSDC_CFG_CLKSRC);
+ MSDC_LSD_SetBits32(SDC_CFG, SDC_CFG_SIEN);
+ gMSDC_Handle->op_clock = cs2.cardClk;
+ gMSDC_Handle->msdc_clock = gMsdcClksrcRate[cs2.clksrc];
+ msdc_dbg_print("[%s %d]CLK=%d,CLKSRC=%d,SCLKF=%d,op_clock=%d,msdc_clock=%d", __FUNCTION__, __LINE__, cs2.cardClk, cs2.clksrc, cs2.sclkf, gMSDC_Handle->op_clock, gMSDC_Handle->msdc_clock);
+
+ if (gMSDC_Handle->op_clock >= 25000)
+ {
+ MSDC_LSD_SetBits32(MSDC_IOCON, (1 << 10));
+ msdc_dbg_print("[%s %d]HIGH SPEED", __FUNCTION__, __LINE__);
+ }
+ else
+ {
+ MSDC_LSD_ClearBits32(MSDC_IOCON, (1 << 10));
+ }
+ }
+
+ return 0;
+}
+
+
+// ==================================================================================
+//
+// Test Case 7. Set clock/ODC
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase7(void)
+{
+ kal_uint8 buf[30], input, offset = 0;
+ kal_uint32 value = 0xFFFFFFFF, odc;
+
+ dbg_print("1. Set clock.\r\n");
+ dbg_print("2. Set ODC. \r\n");
+ dbg_print("3. Set MPLL/26M.\r\n");
+
+ dbg_print("input:");
+ input = U_GetUARTByte(uart_port1);
+ dbg_print("%c\r\n", input);
+
+ switch (input)
+ {
+
+ case '1':
+ {
+
+ memset(buf, 0, sizeof(buf));
+ msdc_dbg_print("\r\n[%s %d]clock test...", __FUNCTION__, __LINE__);
+ msdc_dbg_print("[%s %d]msdc_clock=%d,op_clock=%d,MSDC_CFG=0x%x(CLKSRC=%d,SCLKF=%d)", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_clock, gMSDC_Handle->op_clock, MSDC_Reg32(MSDC_CFG), 0x3 & (MSDC_Reg32(MSDC_CFG) >> 3), 0x0ff & (MSDC_Reg32(MSDC_CFG) >> 8));
+ msdc_dbg_print("input(KHz)(ESC:exit):");
+
+ msdc_dbg_input(&value);
+
+ if (value != 0xFFFFFFFF)
+ {
+ SD_setclk(value);
+ msdc_dbg_print("\r\n set clock=%d(%d) KHz , press any key to exit...\r\n", value, gMSDC_Handle->op_clock);
+ // enable 74 SD clk by s/w
+ MSDC_SetBits32(MSDC_CFG, 0x80);
+
+ //kal_sleep_task(2000);
+ U_GetUARTByte(uart_port1);
+
+ // stop SD clk by s/w
+ MSDC_ClearBits32(MSDC_CFG, 0x80);
+ }
+
+ }
+ break;
+
+ case '2':
+ {
+
+ msdc_dbg_print("[%s %d]MSDC_IOCON=0x%x \r\n", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_IOCON));
+ dbg_print("Choose ODC(4,8,12,16):");
+
+ msdc_dbg_input(&value);
+
+ if (value == 4)
+ odc = MSDC_ODC_4MA;
+ else if (value == 8)
+ odc = MSDC_ODC_8MA;
+ else if (value == 12)
+ odc = MSDC_ODC_12MA;
+ else if (value == 16)
+ odc = MSDC_ODC_16MA;
+ else
+ {
+ dbg_print("wrong argument\r\n");
+ return -1;
+ }
+
+ MSDC_SetData32(
+ MSDC_IOCON,
+ MSDC_IOCON_ODCCFG0 | MSDC_IOCON_ODCCFG1,
+ (odc << 3 | odc)
+ );
+
+ }
+ break;
+
+ case '3':
+ {
+
+ dbg_print("Not support\r\n");
+
+ }
+ break;
+
+ default:
+ break;
+ }
+
+
+}
+
+
+
+
+
+kal_int32 sdtestcase8(void)
+{
+ kal_uint32 input;
+
+ msdc_dbg_print("\r\n[%s %d]1-4 bit BUS test...", __FUNCTION__, __LINE__);
+ msdc_dbg_print("[%d BIT]input(1:1bit ; 4:4bit ; ESC:exit):", (SDC_CFG_MDLEN & MSDC_Reg32(SDC_CFG)) ? 4 : 1 );
+
+ msdc_dbg_input(&input);
+
+ if (input == 1)
+ gMSDC_Handle->trySingleLine = KAL_TRUE;
+ else if (input == 4)
+ gMSDC_Handle->trySingleLine = KAL_FALSE;
+
+
+ msdc_dbg_print("\r\n re-mount...\r\n");
+
+ kal_sleep_task(200);
+ sdtestcase1();
+
+
+}
+
+
+
+// ==================================================================================
+//
+// Test Case 9. Stress test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase9(void)
+{
+ SDC_CMD_STATUS status = 0;
+ kal_int32 loopIndex = 0, addr = 0, addrend = 10;
+ kal_uint32 time1, time2;
+ kal_int32 result = 0;
+ kal_uint32 oknum = 0, errornum = 0;
+ kal_uint8 str[30], input, offset;
+ kal_uint32 value;
+
+ memset(str, 0, sizeof(str));
+
+
+ msdc_dbg_print("\r\n[%s %d]stress test...", __FUNCTION__, __LINE__);
+
+ msdc_dbg_print("\r\n Input test loop: ");
+
+ msdc_dbg_input(&value);
+
+ //-------------------------------------------------------------------------
+ addrend = value;
+
+ for (addr = 0; addr < addrend; addr++)
+ {
+
+ //
+ // Single read test.
+ //
+ status = sdtestcase3(addr, msdc_sector_buf1);
+
+ if (status == NO_ERROR)
+ oknum++;
+ else if (status != NO_ERROR)
+ {
+ errornum++;
+ break;
+ }
+
+ }
+
+ msdc_dbg_print("[%s %d]ok=%d , error=%d\r\n", __FUNCTION__, __LINE__, oknum, errornum);
+
+ oknum = 0;
+ errornum = 0;
+
+ //-------------------------------------------------------------------------
+
+ for (addr = 0; addr < addrend; addr++)
+ {
+
+ //
+ // Single write with compare test.
+ //
+ status = sdtestcase4(addr, msdc_sector_buf1, msdc_sector_buf2);
+
+ if (status == NO_ERROR)
+ oknum++;
+ else if (status != NO_ERROR)
+ {
+ errornum++;
+ break;
+ }
+
+ }
+
+ msdc_dbg_print("[%s %d]ok=%d , error=%d\r\n", __FUNCTION__, __LINE__, oknum, errornum);
+
+ oknum = 0;
+ errornum = 0;
+
+
+
+ //-------------------------------------------------------------------------
+ for (addr = 0; addr < addrend * testblnum; addr += testblnum)
+ {
+ //
+ // Multi read test.
+ //
+ status = sdtestcase5(addr, msdc_uncachedBuf1);
+
+ if (status == NO_ERROR)
+ oknum++;
+ else if (status != NO_ERROR)
+ {
+ errornum++;
+ break;
+ }
+
+ }
+
+ msdc_dbg_print("[%s %d]ok=%d , error=%d\r\n", __FUNCTION__, __LINE__, oknum, errornum);
+
+ oknum = 0;
+ errornum = 0;
+
+
+
+ //-------------------------------------------------------------------------
+ for (addr = 0; addr < addrend * testblnum; addr += testblnum)
+ {
+ //
+ // Multi write with compare test.
+ //
+ status = sdtestcase6(addr, msdc_uncachedBuf1, msdc_uncachedBuf2);
+
+ if (status == NO_ERROR)
+ oknum++;
+ else if (status != NO_ERROR)
+ {
+ errornum++;
+ break;
+ }
+ }
+
+ msdc_dbg_print("[%s %d]ok=%d , error=%d\r\n", __FUNCTION__, __LINE__, oknum, errornum);
+
+ //-------------------------------------------------------------------------
+
+
+ if (status != NO_ERROR)
+ msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ else
+ msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+ return 0;
+}
+
+
+
+// ==================================================================================
+//
+// Test Case 0. Non-4N align test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase10(void)
+{
+ kal_int32 loopIndex, addr;
+ SDC_CMD_STATUS status;
+ kal_uint32 time1, time2, result = KAL_TRUE;
+
+ msdc_dbg_print("\r\n[%s %d]non-4N read single test...", __FUNCTION__, __LINE__);
+
+ for (loopIndex = 0; loopIndex < 4; loopIndex++)
+ {
+ msdc_dbg_print("[%s %d]DMA test, addr = %x", __FUNCTION__, __LINE__, (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+ status = sdtestcase3(0 , (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+
+ if (status != NO_ERROR)
+ result = 0;
+
+ guilin_sleep(200);
+
+ msdc_dbg_print("[%s %d]MCU test, addr = %x", __FUNCTION__, __LINE__, (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+ status = SD_ReadSingleBlock_MCU(0 , (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+
+ if (status != NO_ERROR)
+ result = 0;
+
+ guilin_sleep(200);
+ }
+
+ //---------------------------------------------------------------------------
+ msdc_dbg_print("\r\n[%s %d]non-4N write single test...", __FUNCTION__, __LINE__);
+
+ for (loopIndex = 0; loopIndex < 4; loopIndex++)
+ {
+ msdc_dbg_print("[%s %d]DMA test, addr = %x", __FUNCTION__, __LINE__, (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+ status = sdtestcase4(0 , (kal_uint32 *)&msdc_sector_buf1[loopIndex], (kal_uint32 *)&msdc_sector_buf2[loopIndex]);
+
+ if (status != NO_ERROR)
+ result = 0;
+
+ guilin_sleep(200);
+
+ msdc_dbg_print("[%s %d]MCU test, addr = %x", __FUNCTION__, __LINE__, (kal_uint32 *)&msdc_sector_buf2[loopIndex]);
+ status = SD_WriteSingleBlock_MCU(0 , (kal_uint32 *)&msdc_sector_buf1[loopIndex]);
+
+ if (status != NO_ERROR)
+ result = 0;
+
+ guilin_sleep(200);
+ }
+
+ if (result == 0)
+ msdc_dbg_print("\r\n[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ else
+ msdc_dbg_print("\r\n[%s]Result: PASS... ", __FUNCTION__);
+
+}
+
+// ==================================================================================
+//
+// Test Case 11. cache test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase11(void)
+{
+ kal_int32 loopIndex, addr, addrend;
+ SDC_CMD_STATUS status;
+ kal_uint32 time1, time2;
+ kal_uint32 value = 0;
+ kal_uint32 oknum = 0, errornum = 0;
+
+ msdc_dbg_print("\r\n[%s %d]cache stress test...", __FUNCTION__, __LINE__);
+
+ gMSDC_Handle->isCachedBuf = KAL_TRUE;
+
+ msdc_dbg_input(&value);
+
+ //-------------------------------------------------------------------------
+ addrend = value;
+
+ for (addr = 0; addr < addrend; addr++)
+ {
+ status = sdtestcase3(addr, cachemsdc_sector_buf1);
+
+ if (status == NO_ERROR)
+ oknum++;
+ else if (status != NO_ERROR)
+ {
+ errornum++;
+ break;
+ }
+
+ }
+
+ msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+
+ oknum = 0;
+ errornum = 0;
+
+
+
+ //-------------------------------------------------------------------------
+ //addrend = testsectors;
+ //addrend = ADDREND;
+
+ for (addr = 0; addr < addrend; addr++)
+ {
+ status = sdtestcase4(addr, cachemsdc_sector_buf1, cachemsdc_sector_buf2);
+
+ if (status == NO_ERROR)
+ oknum++;
+ else if (status != NO_ERROR)
+ {
+ errornum++;
+ break;
+ }
+
+ }
+
+ msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+
+ oknum = 0;
+ errornum = 0;
+
+ //-------------------------------------------------------------------------
+ //addrend = testsectors - testblnum;
+ //addrend = ADDREND2;
+
+ for (addr = 0; addr < addrend * testblnum; addr += testblnum)
+ {
+ status = sdtestcase5(addr, cachemsdc_uncachedBuf1);
+
+ if (status == NO_ERROR)
+ oknum++;
+ else if (status != NO_ERROR)
+ {
+ errornum++;
+ break;
+ }
+
+ }
+
+ msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+
+ oknum = 0;
+ errornum = 0;
+
+ //-------------------------------------------------------------------------
+
+ for (addr = 0; addr < addrend * testblnum; addr += testblnum)
+ {
+ status = sdtestcase6(addr, cachemsdc_uncachedBuf1, cachemsdc_uncachedBuf2);
+
+ if (status == NO_ERROR)
+ oknum++;
+ else if (status != NO_ERROR)
+ {
+ errornum++;
+ break;
+ }
+
+ }
+
+ msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+ oknum = 0;
+ errornum = 0;
+
+ //-------------------------------------------------------------------------
+ gMSDC_Handle->isCachedBuf = KAL_FALSE;
+
+ if (status != NO_ERROR)
+ msdc_dbg_print("\r\n[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ else
+ msdc_dbg_print("\r\n[%s]Result: PASS... ", __FUNCTION__);
+
+ return 0;
+
+}
+
+
+kal_int32 sdtestcase12(void)
+{
+ kal_int32 loopIndex;
+ SDC_CMD_STATUS status;
+ kal_uint32 oknum = 0, errornum = 0;
+
+ msdc_dbg_print("\r\n[%s %d]mount stress test...", __FUNCTION__, __LINE__);
+
+ for (loopIndex = 0; loopIndex < TESTLOOP; loopIndex++)
+ {
+ if (U_GetUARTByte_guilin(uart_port1) == ESCKEY)
+ {
+ msdc_dbg_print("[%s %d]ESC,mount stress test...END,OK=%d,ERROR=%d", __FUNCTION__, __LINE__, oknum, errornum);
+ break;
+ }
+
+ if (sdtestcase1() == NO_ERROR)
+ {
+ oknum++;
+ msdc_dbg_print("[%s %d]OK=%d,ERROR=%d,clksrc=%d,sclkf=%d,CLK=%d \r\n", __FUNCTION__, __LINE__, oknum, errornum, test_clksrc, test_sclkf, gMsdcClksrcRate[test_clksrc] / DIV_SCLKF(test_sclkf));
+ }
+ else
+ {
+ errornum++;
+ msdc_dbg_print("[%s %d]OK=%d,ERROR=%d,clksrc=%d,sclkf=%d,CLK=%d \r\n", __FUNCTION__, __LINE__, oknum, errornum, test_clksrc, test_sclkf, gMsdcClksrcRate[test_clksrc] / DIV_SCLKF(test_sclkf));
+ }
+ }
+
+ msdc_dbg_print("[%s %d]mount stress test...END,OK=%d,ERROR=%d", __FUNCTION__, __LINE__, oknum, errornum);
+
+}
+
+
+// ==================================================================================
+//
+// Test Case 13. Clock test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase13(kal_uint32 count)
+{
+ SDC_CMD_STATUS status;
+ kal_int32 result = 0, oknum = 0, errornum = 0, errloop = 0, round;
+
+ msdc_dbg_print("\r\n[%s %d]clock stress test...", __FUNCTION__, __LINE__);
+ memset(test_statistic, 0, sizeof(test_statistic));
+
+ for (test_clksrc = 0; test_clksrc < CLKSRCNUM; test_clksrc++)
+ {
+
+ for (test_sclkf = 0; test_sclkf < SCLKFNUM; test_sclkf++)
+ {
+ MSDC_LSD_ClearBits32(SDC_CFG, SDC_CFG_SIEN);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG, (kal_uint32)test_sclkf, MSDC_CFG_SCLKF);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG, (kal_uint32)test_clksrc, MSDC_CFG_CLKSRC);
+ MSDC_LSD_SetBits32(SDC_CFG, SDC_CFG_SIEN);
+ gMSDC_Handle->op_clock = gMsdcClksrcRate[test_clksrc] / DIV_SCLKF(test_sclkf);
+ gMSDC_Handle->msdc_clock = gMsdcClksrcRate[test_clksrc];
+ msdc_dbg_print("[%s %d]CLKSRC=%d,SCLKF=%d,op_clock=%d,msdc_clock=%d", __FUNCTION__, __LINE__, test_clksrc, test_sclkf, gMSDC_Handle->op_clock, gMSDC_Handle->msdc_clock);
+
+ errloop = 0;
+
+ status = sdtestcase21(count);
+
+ if (status == NO_ERROR)
+ {
+ oknum++;
+ msdc_dbg_print("[%s %d]OK=%d,CLKSRC=%d,SCLKF=%d,op_clock=%d,msdc_clock=%d", __FUNCTION__, __LINE__, oknum, test_clksrc, test_sclkf, gMSDC_Handle->op_clock, gMSDC_Handle->msdc_clock);
+ }
+ else
+ {
+ errornum++;
+ msdc_dbg_print("[%s %d]ERROR=%d,CLKSRC=%d,SCLKF=%d,op_clock=%d,msdc_clock=%d\r\n", __FUNCTION__, __LINE__, errornum, test_clksrc, test_sclkf, gMSDC_Handle->op_clock, gMSDC_Handle->msdc_clock);
+ goto END_TEST;
+ }
+
+ }
+ }
+
+
+ msdc_dbg_print("\r\n[%s %d]clock stress test...END\r\n", __FUNCTION__, __LINE__);
+
+END_TEST:
+
+ if (status != NO_ERROR)
+ msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ else
+ msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+ return status;
+
+}
+
+
+kal_int32 sdtestcase14(void)
+{
+ kal_uint8 input;
+ kal_uint32 value;
+
+ msdc_dbg_print("[%s %d]CLKPAD_RED test...\r\n", __FUNCTION__, __LINE__);
+ msdc_dbg_print("[%s %d]CLKPAD_RED=%d\r\n", __FUNCTION__, __LINE__, ((MSDC_Reg32(MSDC_CLKACB_CFG) & 0x80) >> 7));
+ msdc_dbg_print("input(0:rising edge ; 1:falling edge)(ESC:exit):\r\n");
+
+ msdc_dbg_input(&value);
+ dbg_print("%c\r\n", value);
+
+ if (value == 1)
+ {
+ MSDC_SetBits32(MSDC_CLKACB_CFG, 1 << 7);
+ }
+ else
+ {
+ MSDC_ClearBits32(MSDC_CLKACB_CFG, 1 << 7);
+ }
+
+ return 0;
+}
+
+
+// ==================================================================================
+//
+// Test Case 15. Format test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase15(void)
+{
+ kal_uint32 status;
+ kal_uint32 boot_sector_offset, total_sectors;
+
+ FS_MasterBootRecord *mbr;
+ FS_BootRecord *bs;
+
+ msdc_dbg_print("\r\n[%s %d]FAT fastformat test...", __FUNCTION__, __LINE__);
+
+ do
+ {
+
+ mbr = (FS_MasterBootRecord *)msdc_sector_buf1;
+ bs = (FS_BootRecord *)msdc_sector_buf2;
+
+ total_sectors = gSD->mCSD.capacity / 512;
+
+ //
+ // 1. Create MBR.
+ //
+ boot_sector_offset = SDCreateMasterBootRecord(mbr, total_sectors);
+
+ if (boot_sector_offset > 0)
+ {
+
+ //
+ // 2. Write MBR.
+ //
+ status = WriteSectors(&MSDC_Blk[0], 0, 1, (void *)mbr);
+
+ if (status != STATUS_OK)
+ {
+ msdc_dbg_print("[%s %d]FAT fastformat test...write MBR fail,%d", __FUNCTION__, __LINE__, status);
+ break;
+ }
+
+ //
+ // 3. Create boot sector.
+ //
+ if (SDCreateBootSector(bs, total_sectors, &mbr->PTable[0]) > 0)
+ {
+
+ //
+ // 4. Write boot sector to boot_sector_offset
+ //
+ status = WriteSectors(&MSDC_Blk[0], boot_sector_offset, 1, bs);
+
+ if (status != STATUS_OK)
+ {
+ msdc_dbg_print("[%s %d]FAT fastformat test...write BS fail,%d", __FUNCTION__, __LINE__, status);
+ break;
+ }
+
+ }
+ else
+ {
+ msdc_dbg_print("[%s %d]FAT fastformat test...boot sector fail!!!", __FUNCTION__, __LINE__);
+ }
+ }
+ else
+ {
+ msdc_dbg_print("[%s %d]FAT fastformat test...boot sector offset is wrong!!!", __FUNCTION__, __LINE__);
+ }
+
+ //
+ // 5. Finally, perform high level format.
+ // According to SD spec, 2G~32G card's start address is 0x2000
+ //
+ status = highlevelformat(&MSDC_Blk[0], boot_sector_offset);
+
+ if (status != STATUS_OK)
+ msdc_dbg_print("[%s %d]FAT fastformat test...highlevelformat error,%d", __FUNCTION__, __LINE__, status);
+ else
+ msdc_dbg_print("[%s %d]FAT fastformat test...END,%d", __FUNCTION__, __LINE__, status);
+
+ }
+ while (0);
+
+ if (status != STATUS_OK)
+ msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ else
+ msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+}
+
+
+kal_int32 sdtestcase16(void)
+{
+ kal_int32 status;
+ msdc_dbg_print("\r\n[%s %d]DMA.fix test...", __FUNCTION__, __LINE__);
+ gMSDC_Handle->MSDC_fastFormat = KAL_TRUE;
+ {
+ kal_int32 loopIndex, addr, addrend;
+ SDC_CMD_STATUS status;
+ kal_uint32 time1, time2;
+
+ msdc_dbg_print("[%s %d]write multi test...", __FUNCTION__, __LINE__);
+ addrend = testsectors - testblnum;
+ addr = 0;
+ addrend = ADDREND2;
+ //for(loopIndex = TESTLOOP; loopIndex; loopIndex--)
+ //for(addr=0;addr<addrend;addr++)
+ {
+ kal_int32 i, compare_error;
+
+ for (i = 0; i < 128 * 1; i++)
+ msdc_sector_buf1[i] = ((i + 20 + addr) << 0) | ((i + 21 + addr) << 8) | ((i + 22 + addr) << 16) | ((i + 23 + addr) << 24);
+
+ memset(msdc_uncachedBuf1, 0, sizeof(msdc_uncachedBuf1));
+ time1 = drv_get_current_time();
+
+ //status = SD_SetPreEraseBlk(testblnum);
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_WriteMultiBlock(addr, msdc_sector_buf1, testblnum);
+ else
+ status = SD_WriteMultiBlock(addr * 512, msdc_sector_buf1, testblnum);
+
+ time2 = drv_get_current_time();
+ msdc_dbg_print("[guilin %s %d]SD_WriteMultiBlock=%d,%d KB/S,addr=%d", __FUNCTION__, __LINE__, status, (testblnum * 32768 * 5) / ((time2 - time1) * 10), addr);
+
+ if (status != NO_ERROR)
+ {
+ msdc_dbg_print("[%s %d]ERROR,SD_WriteMultiBlock,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+
+ //guilin_sleep(400);
+ // readback compare
+ compare_error = 0;
+ time1 = drv_get_current_time();
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadMultiBlock(addr, msdc_uncachedBuf2, testblnum);
+ else
+ status = SD_ReadMultiBlock(addr * 512, msdc_uncachedBuf2, testblnum);
+
+ time2 = drv_get_current_time();
+ msdc_dbg_print("[guilin %s %d]SD_ReadMultiBlock=%d,%d KB/S,addr=%d", __FUNCTION__, __LINE__, status, (testblnum * 32768 * 5) / ((time2 - time1) * 10), addr);
+
+ if (status != NO_ERROR)
+ {
+ msdc_dbg_print("[%s %d]ERROR,SD_ReadMultiBlock,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+
+ for (i = 0; i < 128 * testblnum; i++)
+ {
+ if (msdc_sector_buf1[0] != msdc_uncachedBuf2[i])
+ {
+ msdc_dbg_print("[%s %d]SD_WriteMultiBlock,readback compare error:write=0x%x , read=0x%x ,i=%d", __FUNCTION__, __LINE__, msdc_uncachedBuf1[i], msdc_uncachedBuf2[i], i);
+ compare_error = 1;
+ break;
+ }
+ }
+
+ if (compare_error == 0)
+ {
+ msdc_dbg_print("[%s %d]SD_WriteMultiBlock,readback compare ok", __FUNCTION__, __LINE__);
+ }
+ }
+
+ }
+
+
+ gMSDC_Handle->MSDC_fastFormat = KAL_FALSE;
+ msdc_dbg_print("[%s %d]DMA.fix test...END,%d", __FUNCTION__, __LINE__, status);
+
+
+}
+
+kal_int32 sdtestcase17(void)
+{
+ kal_int32 status, addr, cnt = 0;
+
+ do
+ {
+
+ //--------------------------------------------------------------------
+ msdc_dbg_print("\r\n[%s %d]DAT CRC test...", __FUNCTION__, __LINE__);
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock_MCU_datcrc(0, msdc_sector_buf1 );
+ else
+ status = SD_ReadSingleBlock_MCU_datcrc(0 * 512, msdc_sector_buf1 );
+
+ msdc_dbg_print("[%s %d]sdc_datsta=0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->dat_sta);
+
+ if (status != ERR_DAT_CRCERR)
+ break;
+
+ cnt++;
+
+ {
+ DCL_HANDLE handle;
+ handle = DclGPIO_Open(DCL_GPIO, DATGPIO); // GPIO31-DAT0
+ DclGPIO_Control(handle, GPIO_CMD_SET_MODE_1, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+ DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+ DclGPIO_Close(handle);
+ guilin_sleep(100);
+ }
+
+
+ //--------------------------------------------------------------------
+ msdc_dbg_print("\r\n[%s %d]DATTO test...", __FUNCTION__, __LINE__);
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock_MCU_datto(0, msdc_sector_buf1 );
+ else
+ status = SD_ReadSingleBlock_MCU_datto(0 * 512, msdc_sector_buf1 );
+
+ msdc_dbg_print("[%s %d]sdc_datsta=0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->dat_sta);
+
+ if (status != ERR_DAT_TIMEOUT)
+ break;
+
+ cnt++;
+
+ {
+ DCL_HANDLE handle;
+ handle = DclGPIO_Open(DCL_GPIO, DATGPIO); // GPIO31-DAT0
+ DclGPIO_Control(handle, GPIO_CMD_SET_MODE_1, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+ DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+ DclGPIO_Close(handle);
+ guilin_sleep(100);
+ }
+
+
+
+ //--------------------------------------------------------------------
+ msdc_dbg_print("\r\n[%s %d]CMDTO test...", __FUNCTION__, __LINE__);
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock_MCU_cmdto(0, msdc_sector_buf1 );
+ else
+ status = SD_ReadSingleBlock_MCU_cmdto(0 * 512, msdc_sector_buf1 );
+
+ msdc_dbg_print("[%s %d]sdc_cmdsta=0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->cmd_sta);
+
+ if (status != ERR_CMD_TIMEOUT)
+ break;
+
+ cnt++;
+
+ {
+ DCL_HANDLE handle;
+ handle = DclGPIO_Open(DCL_GPIO, CMDGPIO); // GPIO32-CMD
+ DclGPIO_Control(handle, GPIO_CMD_SET_MODE_1, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_DIR_IN, 0);
+ DclGPIO_Control(handle, GPIO_CMD_SET_PULL_HIGH, 0);
+ DclGPIO_Control(handle, GPIO_CMD_ENABLE_PULL, 0);
+ DclGPIO_Close(handle);
+ guilin_sleep(100);
+ }
+
+
+
+ //--------------------------------------------------------------------
+
+ msdc_dbg_print("[%s %d]CRC,CMDTO,DATTO test...END,%d", __FUNCTION__, __LINE__, status);
+
+ }
+ while (0);
+
+ if (cnt == 3)
+ msdc_dbg_print("\r\n[%s]Result: PASS... ", __FUNCTION__);
+ else
+ msdc_dbg_print("\r\n[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+
+}
+kal_int32 sdtestcase18(void)
+{
+ kal_int32 status, addr, loopIndex;
+ kal_uint8 *p81, *p82;
+ //-------------------------------------------------------------------------
+ msdc_dbg_print("\r\n[%s %d]odd-size test...read_mcu", __FUNCTION__, __LINE__);
+ addr = gSD->mBKNum - 1;
+
+ if (addr < 0)addr = 0;
+
+ loopIndex = 1;
+ memset(msdc_sector_buf1, 0, sizeof(msdc_sector_buf1));
+ memset(msdc_sector_buf2, 0xff, sizeof(msdc_sector_buf2));
+ status = SD_SetBlength(512);
+ msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock_MCU(0, msdc_sector_buf1);
+ else
+ status = SD_ReadSingleBlock_MCU(0 * 512, msdc_sector_buf1);
+
+ status = SD_SetBlength(511);
+ msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock_MCU(0, msdc_sector_buf2);
+ else
+ status = SD_ReadSingleBlock_MCU(0 * 512, msdc_sector_buf2);
+
+ p81 = (kal_uint8 *)&msdc_sector_buf1[0];
+ p82 = (kal_uint8 *)&msdc_sector_buf2[0];
+
+ for (loopIndex = 0; loopIndex < 511; loopIndex++)
+ {
+ if (p81[loopIndex] != p82[loopIndex])
+ {
+ msdc_dbg_print("[%s %d]compare error: 0x%x , 0x%x ,i=%d ", __FUNCTION__, __LINE__, p81[loopIndex], p82[loopIndex], loopIndex);
+ break;
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ msdc_dbg_print("\r\n[%s %d]odd-size test...write_mcu", __FUNCTION__, __LINE__);
+ memset(msdc_sector_buf1, 0, sizeof(msdc_sector_buf1));
+ memset(msdc_sector_buf2, 0xff, sizeof(msdc_sector_buf2));
+ memset(msdc_sector_buf3, 0, sizeof(msdc_sector_buf3));
+ status = SD_SetBlength(512);
+ msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock_MCU(0, msdc_sector_buf1 );
+ else
+ status = SD_ReadSingleBlock_MCU(0 * 512, msdc_sector_buf1);
+
+ for (loopIndex = 0; loopIndex < 512 / 4; loopIndex++)
+ msdc_sector_buf2[loopIndex] = msdc_sector_buf1[loopIndex] + 0x01010101;
+
+ status = SD_SetBlength(511);
+ msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_WriteSingleBlock_MCU(0, msdc_sector_buf2);
+ else
+ status = SD_WriteSingleBlock_MCU(0 * 512, msdc_sector_buf2);
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock_MCU(0, msdc_sector_buf3);
+ else
+ status = SD_ReadSingleBlock_MCU(0 * 512, msdc_sector_buf3);
+
+ p81 = (kal_uint8 *)&msdc_sector_buf3[0];
+ p82 = (kal_uint8 *)&msdc_sector_buf2[0];
+
+ for (loopIndex = 0; loopIndex < 511; loopIndex++)
+ {
+ if (p81[loopIndex] != p82[loopIndex])
+ {
+ msdc_dbg_print("[%s %d]compare error: 0x%x , 0x%x ,i=%d ", __FUNCTION__, __LINE__, p81[loopIndex], p82[loopIndex], loopIndex);
+ break;
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
+ msdc_dbg_print("\r\n[%s %d]odd-size test...read_dma", __FUNCTION__, __LINE__);
+ memset(msdc_sector_buf1, 0, sizeof(msdc_sector_buf1));
+ memset(msdc_sector_buf2, 0xff, sizeof(msdc_sector_buf2));
+ status = SD_SetBlength(512);
+ msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock(0, msdc_sector_buf1);
+ else
+ status = SD_ReadSingleBlock(0 * 512, msdc_sector_buf1);
+
+ status = SD_SetBlength(511);
+ msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock(0, msdc_sector_buf2);
+ else
+ status = SD_ReadSingleBlock(0 * 512, msdc_sector_buf2);
+
+ p81 = (kal_uint8 *)&msdc_sector_buf1[0];
+ p82 = (kal_uint8 *)&msdc_sector_buf2[0];
+
+ for (loopIndex = 0; loopIndex < 511; loopIndex++)
+ {
+ if (p81[loopIndex] != p82[loopIndex])
+ {
+ msdc_dbg_print("[%s %d]compare error: 0x%x , 0x%x ,i=%d ", __FUNCTION__, __LINE__, p81[loopIndex], p82[loopIndex], loopIndex);
+ break;
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ msdc_dbg_print("\r\n[%s %d]odd-size test...write_dma", __FUNCTION__, __LINE__);
+ memset(msdc_sector_buf1, 0, sizeof(msdc_sector_buf1));
+ memset(msdc_sector_buf2, 0xff, sizeof(msdc_sector_buf2));
+ memset(msdc_sector_buf3, 0, sizeof(msdc_sector_buf3));
+ status = SD_SetBlength(512);
+ msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock(0, msdc_sector_buf1 );
+ else
+ status = SD_ReadSingleBlock(0 * 512, msdc_sector_buf1);
+
+ for (loopIndex = 0; loopIndex < 512 / 4; loopIndex++)
+ msdc_sector_buf2[loopIndex] = msdc_sector_buf1[loopIndex] + 0x01010101;
+
+ status = SD_SetBlength(511);
+ msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+ loopIndex = 1;
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_WriteSingleBlock(0, msdc_sector_buf2);
+ else
+ status = SD_WriteSingleBlock(0 * 512, msdc_sector_buf2);
+
+ loopIndex = 1;
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ status = SD_ReadSingleBlock(0, msdc_sector_buf3);
+ else
+ status = SD_ReadSingleBlock(0 * 512, msdc_sector_buf3);
+
+ p81 = (kal_uint8 *)&msdc_sector_buf3[0];
+ p82 = (kal_uint8 *)&msdc_sector_buf2[0];
+
+ for (loopIndex = 0; loopIndex < 511; loopIndex++)
+ {
+ if (p81[loopIndex] != p82[loopIndex])
+ {
+ msdc_dbg_print("[%s %d]compare error: 0x%x , 0x%x ,i=%d ", __FUNCTION__, __LINE__, p81[loopIndex], p82[loopIndex], loopIndex);
+ break;
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ status = SD_SetBlength(512);
+ msdc_dbg_print("[%s %d]SD_SetBlength=%d", __FUNCTION__, __LINE__, status);
+ //-------------------------------------------------------------------------
+ msdc_dbg_print("[%s %d]odd-size test...END,%d", __FUNCTION__, __LINE__, status);
+
+}
+kal_int32 sdtestcase19(void)
+{
+ kal_uint8 input;
+
+ msdc_dbg_print("\r\n[%s %d]MSDC_useDMA4ByteBurst test...%d byte", __FUNCTION__, __LINE__, (MSDC_useDMA4ByteBurst == KAL_TRUE ? 4 : 1));
+ msdc_dbg_print("input(1:1byte ; 4:4byte ; ESC:exit):");
+
+ while (1)
+ {
+ input = U_GetUARTByte(uart_port1);
+
+ if (input == '1')
+ {
+ MSDC_useDMA4ByteBurst = KAL_FALSE;
+ }
+ else if (input == '4')
+ {
+ MSDC_useDMA4ByteBurst = KAL_TRUE;
+ }
+ else if (input == 0x0d || input == 0x0a)
+ {
+ break;
+ }
+ else if (input == ESCKEY) //esc
+ {
+ return;
+ }
+ else
+ {
+ continue;
+ }
+
+ dbg_print("%c", input);
+ }
+}
+
+
+
+// ==================================================================================
+//
+// Test Case 20. Erase test
+//
+//
+//
+// ==================================================================================
+kal_int32 sdtestcase20(kal_uint32 startSector, kal_uint32 sectorNum)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 i;
+ kal_uint32 time1, time2;
+
+ msdc_dbg_print("[%s %d]SD_FlushSectors %d, %d", __FUNCTION__, __LINE__, startSector, sectorNum);
+
+ time1 = drv_get_current_time();
+ status = SD_FlushSectors(startSector, sectorNum);
+ time2 = drv_get_current_time();
+
+ if (status == NO_ERROR)
+ {
+ msdc_dbg_print("[%s %d]OK=%d , time=%d \r\n", __FUNCTION__, __LINE__, status, time2 - time1);
+ msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+ }
+ else
+ {
+ msdc_dbg_print("[%s %d]ERROR=%d , time=%d \r\n", __FUNCTION__, __LINE__, status, time2 - time1);
+ msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ }
+
+
+ MSDC_PDNControl(KAL_FALSE);
+}
+
+
+
+kal_int32 sdtestcase21(kal_uint32 test_round)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 i, addr, addrend, loopIndex, oknum, errornum, result, offset;
+ msdc_dbg_print("[%s %d]start", __FUNCTION__, __LINE__);
+
+ memset(test_statistic, 0, sizeof(test_statistic));
+
+ oknum = 0;
+ errornum = 0;
+ offset = 0;
+
+ //-------------------------------------------------------------------------
+ for (testblnum = 1; testblnum < 1024; testblnum *= 2)
+ {
+ addrend = testblnum * test_round;
+
+ for (addr = 0; addr < addrend; addr += testblnum)
+ {
+ status = sdtestcase5(addr, msdc_uncachedBuf1);
+
+ if (status == NO_ERROR)
+ {
+ oknum++;
+ test_statistic[offset].bit14 = (SDC_CFG_MDLEN & MSDC_Reg32(SDC_CFG)) ? 4 : 1;
+ test_statistic[offset].isread1 = 1;
+ test_statistic[offset].clksrc = 0x3 & (MSDC_Reg32(MSDC_CFG) >> 3);
+ test_statistic[offset].sclkf = 0x0ff & (MSDC_Reg32(MSDC_CFG) >> 8);
+ test_statistic[offset].clock = gMsdcClksrcRate[test_statistic[offset].clksrc] / DIV_SCLKF(test_statistic[offset].sclkf);
+ test_statistic[offset].addr = addr;
+ test_statistic[offset].blnum = testblnum;
+ test_statistic[offset].speed = gspeed;
+ gspeed = 0;
+ offset++;
+ }
+ else
+ {
+ errornum++;
+ msdc_dbg_print("[%s %d]ERROR, ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+ return status;
+ }
+ }
+ }
+
+ msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+ //-------------------------------------------------------------------------
+ msdc_dbg_print("\r\n:index bit RW \t clksrc sclkf clock \t addr \t blnum \t speed ");
+
+ for (offset = 0; offset < test_round * 10; offset++)
+ {
+ msdc_dbg_print("[%3d] %3d \t %c \t %3d \t %3d \t %6d \t %6d \t %6d \t %6d ",
+ offset,
+ test_statistic[offset].bit14,
+ test_statistic[offset].isread1 == 1 ? 'R' : 'W',
+ test_statistic[offset].clksrc,
+ test_statistic[offset].sclkf,
+ test_statistic[offset].clock,
+ test_statistic[offset].addr,
+ test_statistic[offset].blnum,
+ test_statistic[offset].speed );
+ }
+
+ //-------------------------------------------------------------------------
+ memset(test_statistic, 0, sizeof(test_statistic));
+
+ oknum = 0;
+ errornum = 0;
+ offset = 0;
+
+WRITE_TEST:
+
+ for (testblnum = 1; testblnum < 1024; testblnum *= 2)
+ {
+ addrend = testblnum * test_round;
+
+ for (addr = 0; addr < addrend; addr += testblnum)
+ {
+ status = sdtestcase6(addr, msdc_uncachedBuf1, msdc_uncachedBuf2);
+
+ if (status == NO_ERROR)
+ {
+ oknum++;
+ test_statistic[offset].bit14 = (SDC_CFG_MDLEN & MSDC_Reg32(SDC_CFG)) ? 4 : 1;
+ test_statistic[offset].isread1 = 2;
+ test_statistic[offset].clksrc = 0x3 & (MSDC_Reg32(MSDC_CFG) >> 3);
+ test_statistic[offset].sclkf = 0x0ff & (MSDC_Reg32(MSDC_CFG) >> 8);
+ test_statistic[offset].clock = gMsdcClksrcRate[test_statistic[offset].clksrc] / DIV_SCLKF(test_statistic[offset].sclkf);
+ test_statistic[offset].addr = addr;
+ test_statistic[offset].blnum = testblnum;
+ test_statistic[offset].speed = gspeed;
+ gspeed = 0;
+ offset++;
+ }
+ else
+ {
+ errornum++;
+ msdc_dbg_print("[%s %d]ERROR, ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+ return status;
+ }
+
+ }
+ }
+
+ msdc_dbg_print("[%s %d]ok=%d , error=%d", __FUNCTION__, __LINE__, oknum, errornum);
+ oknum = 0;
+ errornum = 0;
+
+ //-------------------------------------------------------------------------
+ msdc_dbg_print("\r\n:index bit RW \t clksrc sclkf clock \t addr \t blnum \t speed ");
+
+ for (offset = 0; offset < test_round * 10; offset++)
+ {
+ msdc_dbg_print("[%3d] %3d \t %c \t %3d \t %3d \t %6d \t %6d \t %6d \t %6d ",
+
+ offset,
+ test_statistic[offset].bit14,
+ test_statistic[offset].isread1 == 1 ? 'R' : 'W',
+ test_statistic[offset].clksrc,
+ test_statistic[offset].sclkf,
+ test_statistic[offset].clock,
+ test_statistic[offset].addr,
+ test_statistic[offset].blnum,
+ test_statistic[offset].speed );
+ }
+
+END_TEST:
+
+ testblnum = 32;
+
+ return status;
+}
+
+kal_int32 sdtestcase22(void)
+{
+ SDC_CMD_STATUS status;
+ kal_uint8 buf[30], input, offset;
+ kal_uint32 value, cmdvalue = 0, cmdarg = 0x55;
+
+ memset(buf, 0, sizeof(buf));
+ msdc_dbg_print("\r\n[%s %d]SD CMD test...", __FUNCTION__, __LINE__);
+ msdc_dbg_print("[%s %d]SDC_CMD=0x%x SDC_ARG=0x%x SDC_CMDSTA=0x%x SDC_RESP0=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_CMD), MSDC_Reg32(SDC_ARG), MSDC_Reg(SDC_CMDSTA), MSDC_Reg32(SDC_RESP0));
+ msdc_dbg_print("input CMD(ESC:exit):");
+
+ msdc_dbg_input(&value);
+
+ if (value >= 0)
+ {
+ switch (value)
+ {
+ case 0 :
+ cmdvalue = SDC_CMD_CMD0;
+ cmdarg = 0;
+ break;
+
+ case 1 :
+ cmdvalue = SDC_CMD_CMD1;
+ cmdarg = 0;
+ break;
+
+ case 2 :
+ cmdvalue = SDC_CMD_CMD2;
+ cmdarg = 0;
+ break;
+
+ case 3 :
+ cmdvalue = SDC_CMD_CMD3_SD;
+ cmdarg = 0;
+ break;
+
+ case 7 :
+ cmdvalue = SDC_CMD_CMD7;
+ cmdarg = gSD->mRCA;
+ break;
+
+ case 8 :
+ cmdvalue = SDC_CMD_CMD8;
+ cmdarg = 0x1aa;
+ break;
+
+ case 9 :
+ cmdvalue = SDC_CMD_CMD9;
+ cmdarg = 0;
+ break;
+
+ case 13:
+ cmdvalue = SDC_CMD_CMD13;
+ cmdarg = gSD->mRCA;
+ break;
+
+ case 16:
+ cmdvalue = SDC_CMD_CMD16;
+ cmdarg = 0;
+ break;
+
+ case 17:
+ cmdvalue = SDC_CMD_CMD17;
+ cmdarg = 0;
+ break;
+
+ case 18:
+ cmdvalue = SDC_CMD_CMD18;
+ cmdarg = 0;
+ break;
+
+ case 41:
+ cmdvalue = SDC_CMD_CMD41_SD;
+ cmdarg = 0x40ff8000;
+ break;
+
+ case 42:
+ cmdvalue = SDC_CMD_CMD42;
+ cmdarg = 0;
+ break;
+
+ case 51:
+ cmdvalue = SDC_CMD_ACMD51;
+ cmdarg = 0x40FF8000;
+ break;
+
+ case 55:
+ cmdvalue = SDC_CMD_CMD55;
+ cmdarg = 0;
+ break;
+
+ default:
+ cmdvalue = SDC_CMD_CMD0;
+ cmdarg = 0;
+ break;
+ }
+
+ status = SD_Send_Cmd(cmdvalue, cmdarg);
+ msdc_dbg_print("SD_Send_Cmd=%d cmd=0x%x cmdarg=0x%x", status, cmdvalue, cmdarg);
+ msdc_dbg_print("[%s %d]SDC_CMD=0x%x SDC_ARG=0x%x SDC_CMDSTA=0x%x SDC_RESP0=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_CMD), MSDC_Reg32(SDC_ARG), gMSDC_Handle->cmd_sta, MSDC_Reg32(SDC_RESP0));
+ }
+
+
+}
+
+
+
+
+SDC_CMD_STATUS vSDIOInitialisation_Test(void)
+{
+ static DCL_STATUS fgControl;
+ static SDIO_CTRL_SET_BLK_SIZE_T fgblksize;
+ static DCL_SDIO_function_id_enum fgfunctionid;
+ static kal_uint32 u4BlockSize;
+ static kal_char u4PrintBuff[30];
+ static SDIO_CTRL_REG_RW_T regReadWrite;
+ kal_uint32 j;
+ int tbttCount = 0;
+ kal_uint32 mcrValue;
+ SDIO_CTRL_DAT_RW_T datReadWrite;
+ SDIO_CTRL_ENABLE_T enableInterrupt;
+ kal_uint32 checkChipIdRevision;
+ SDC_CMD_STATUS status;
+
+ //fgControl = DclSDIO_Open(DCL_SDIO, DCL_SDIO_FLAGS_DEVICE_CARD1|DCL_SDIO_FLAGS_USAGE_CMD);
+
+ //fgControl = DclSDIO_Control(handle_sdio, SDIO_CTRL_CMD_INIT, (DCL_CTRL_DATA_T *)NULL);
+
+ //MSDC_Initialize();
+
+ MSDC_turnOnVMC(KAL_FALSE);
+ guilin_sleep(1000);
+ MSDC_turnOnVMC(KAL_TRUE);
+
+ status = SDIO_Initialize();
+
+ if (status != NO_ERROR)
+ {
+ msdc_dbg_print("[%s %d]sdio initialize fail!!%d\r\n", __FUNCTION__, __LINE__, status);
+ return;
+ }
+
+ msdc_dbg_print("[%s %d]sdio initialize OK. %d\r\n", __FUNCTION__, __LINE__, status);
+
+ /*
+ fgblksize.function= SDIO_FUCN_1;
+ fgblksize.size = 128;
+ fgControl = DclSDIO_Control(handle_sdio,SDIO_CTRL_CMD_SET_BLK_SIZE,(DCL_CTRL_DATA_T *)&fgblksize);
+
+ if (fgControl != ((DCL_STATUS)STATUS_OK)) {
+
+ dbg_print("Error !!! SDIO Setting bulk size for function 1 Failed!\n");
+ }
+ else {
+ dbg_print("SDIO Setting bulk size for function 1 passed!\n");
+
+ }
+ */
+}
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+#if 1
+char str_buf[256] = {0};
+kal_int32 str_num = 0;
+kal_semid msdc_dbg_print_semid = NULL;
+
+void msdc_dbg_print(char *fmt, ...)
+{
+ static kal_uint32 num = 0;
+
+ va_list argp;
+
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()) && (KAL_FALSE == kal_if_lisr()) && (KAL_FALSE == kal_if_hisr()))
+ if (msdc_dbg_print_semid == NULL)
+ msdc_dbg_print_semid = kal_create_sem("msdc_dbg_print_semid_lock", 1);
+
+
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()) && (KAL_FALSE == kal_if_lisr()) && (KAL_FALSE == kal_if_hisr()))
+ {
+ if (msdc_dbg_print_semid)
+ kal_take_sem(msdc_dbg_print_semid, 1);
+ }
+
+
+ snprintf(str_buf, 5, "%04d", str_num++);
+ va_start(argp, fmt);
+ _vsnprintf(&str_buf[4], (256 - 4), fmt, argp);
+ va_end(argp);
+
+ kal_prompt_trace(MOD_MSDC_HISR, "%s", str_buf);
+ dbg_print("%s \r\n", str_buf);
+
+ // kal_bootup_trace
+
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()) && (KAL_FALSE == kal_if_lisr()) && (KAL_FALSE == kal_if_hisr()))
+ {
+ if (msdc_dbg_print_semid)
+ kal_give_sem(msdc_dbg_print_semid);
+ }
+
+
+}
+
+kal_uint8 U_GetUARTByte(UART_PORT port)
+{
+
+ kal_uint8 data;
+ kal_uint8 U_GetUARTByteWithTimeOut(UART_PORT port, kal_uint8* ch, kal_uint32 timeout_value);//liming add statement
+ while(!U_GetUARTByteWithTimeOut(port,&data,0xffffffff));// for descrease code size (U_GetUARTByte &U_GetUARTByteTimeout)
+ return data;
+}
+
+void msdc_dbg_input(kal_uint32 *value)
+{
+ kal_uint32 result = 0;
+ kal_uint8 str[30], input, offset;
+
+ offset = 0;
+
+ while (1)
+ {
+ input = U_GetUARTByte(DBG_PRINT_PORT);
+
+ /*
+ if (input >='0' && input <= '9') {
+
+ //input -= '0';
+ }
+ else {
+
+ if(input == 0x0d || input == 0x0a) {
+
+ break;
+ }
+ else {
+
+ if(input == ESCKEY)//esc
+ return;
+ else
+ continue;
+
+ }
+ }
+ */
+ if (input == 0x0d || input == 0x0a)
+ break;
+
+ if (input == ESCKEY)
+ return;
+
+ str[offset++] = input;
+ dbg_print("%c", input);
+ }
+
+ str[offset] = 0;
+
+ dbg_print("\r\n");
+ sscanf(str, "%d", value);
+}
+
+
+kal_uint32 msdc_get_uart_input()
+{
+ kal_uint8 buf[30], input, offset;
+ kal_int32 value = 0;
+
+ while (1)
+ {
+
+ input = U_GetUARTByte(uart_port1);
+
+ //if(input >='0' && input <= '9')
+ //{
+ //input -= '0';
+ //}
+ //else if(input == 0x0d || input == 0x0a)
+ if (input == 0x0d || input == 0x0a)
+ {
+ break;
+ }
+ else if (input == ESCKEY) //esc
+ {
+ return;
+ }
+
+ //else
+ //{
+ // continue;
+ //}
+
+ buf[offset++] = input;
+ dbg_print("%c", input);
+ }
+
+ buf[30 - 1] = 0;
+
+ dbg_print("\r\n");
+ sscanf(buf, "%x", &value);
+
+ return value;
+}
+
+
+void guilin_sleep(kal_uint32 x)
+{
+ if ((kal_query_systemInit() == KAL_TRUE)
+#ifdef __TST_WRITE_TO_FILE__
+ || (KAL_TRUE == INT_QueryExceptionStatus())
+#endif
+ || KAL_TRUE == FTL_isPollingMode()
+ )
+ {
+ MSDC_GPTI_BusyWait(x * 5);
+ }
+ else
+ {
+ kal_sleep_task(x);
+ }
+}
+void guilintest(void)
+{
+ msdc_dbg_print("[guilin %s %d]start", __FUNCTION__, __LINE__);
+
+ msdc_dbg_print("[guilin %s %d]gSD->mSDC_ocr =0x%x", __FUNCTION__, __LINE__, gSD->mSDC_ocr ); // gSD->mSDC_ocr =0x80FF8000
+ msdc_dbg_print("[guilin %s %d]gSD->mBKLength =0x%x", __FUNCTION__, __LINE__, gSD->mBKLength ); // gSD->mBKLength =0x200
+ msdc_dbg_print("[guilin %s %d]gSD->mBKNum =0x%x", __FUNCTION__, __LINE__, gSD->mBKNum ); // gSD->mBKNum =0xF3400
+ msdc_dbg_print("[guilin %s %d]gSD->flags =0x%x", __FUNCTION__, __LINE__, gSD->flags ); // gSD->flags =0x3C
+ msdc_dbg_print("[guilin %s %d]gSD->mRCA =0x%x", __FUNCTION__, __LINE__, gSD->mRCA ); // gSD->mRCA =0xB368
+ msdc_dbg_print("[guilin %s %d]gSD->mState =0x%x", __FUNCTION__, __LINE__, gSD->mState ); // gSD->mState =0x3
+ msdc_dbg_print("[guilin %s %d]gSD->mInactive =0x%x", __FUNCTION__, __LINE__, gSD->mInactive ); // gSD->mInactive =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->bus_width =0x%x", __FUNCTION__, __LINE__, gSD->bus_width ); // gSD->bus_width =0x4
+ msdc_dbg_print("[guilin %s %d]gSD->mWPEnabled=0x%x", __FUNCTION__, __LINE__, gSD->mWPEnabled ); // gSD->mWPEnabled=0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mIsLocked =0x%x", __FUNCTION__, __LINE__, gSD->mIsLocked ); // gSD->mIsLocked =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCD_DAT3 =0x%x", __FUNCTION__, __LINE__, gSD->mCD_DAT3 ); // gSD->mCD_DAT3 =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCMD8Resp =0x%x", __FUNCTION__, __LINE__, gSD->mCMD8Resp ); // gSD->mCMD8Resp =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->sd_r =0x%x", __FUNCTION__, __LINE__, gSD->sd_r ); // gSD->sd_r =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->sd_w =0x%x", __FUNCTION__, __LINE__, gSD->sd_w ); // gSD->sd_w =0x0
+
+ msdc_dbg_print("[guilin %s %d]CSD", __FUNCTION__, __LINE__);
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.tacc =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.tacc ); // gSD->mCSD.tacc =0x5E
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.nsac =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.nsac ); // gSD->mCSD.nsac =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.tran_speed =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.tran_speed ); // gSD->mCSD.tran_speed =0x32
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ccc =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ccc ); // gSD->mCSD.ccc =0x5F5
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.w_blk_len =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.w_blk_len ); // gSD->mCSD.w_blk_len =0x200
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.r_blk_len =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.r_blk_len ); // gSD->mCSD.r_blk_len =0x200
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.max_w_blk_len =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.max_w_blk_len ); // gSD->mCSD.max_w_blk_len =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.max_r_blk_len =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.max_r_blk_len ); // gSD->mCSD.max_r_blk_len =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.w_blk_misali =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.w_blk_misali ); // gSD->mCSD.w_blk_misali =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.r_blk_misali =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.r_blk_misali ); // gSD->mCSD.r_blk_misali =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.w_blk_part =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.w_blk_part ); // gSD->mCSD.w_blk_part =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.r_blk_part =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.r_blk_part ); // gSD->mCSD.r_blk_part =0x1
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.erase_sec_size_mmc=0x%x", __FUNCTION__, __LINE__, gSD->mCSD.erase_sec_size_mmc ); // gSD->mCSD.erase_sec_size_mmc=0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.erase_grp_size_mmc=0x%x", __FUNCTION__, __LINE__, gSD->mCSD.erase_grp_size_mmc ); // gSD->mCSD.erase_grp_size_mmc=0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.wp_grp_size_mmc =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.wp_grp_size_mmc ); // gSD->mCSD.wp_grp_size_mmc =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.erase_blk_en_sd =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.erase_blk_en_sd ); // gSD->mCSD.erase_blk_en_sd =0x1
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.erase_sec_size_sd =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.erase_sec_size_sd ); // gSD->mCSD.erase_sec_size_sd =0x80
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.wp_prg_size_sd =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.wp_prg_size_sd ); // gSD->mCSD.wp_prg_size_sd =0x800
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.wp_grp_enable =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.wp_grp_enable ); // gSD->mCSD.wp_grp_enable =0x1
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.capacity =%d MB", __FUNCTION__, __LINE__, gSD->mCSD.capacity / (1024 * 1024)); // gSD->mCSD.capacity =0x1E680000
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.cmd_class =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.cmd_class ); // gSD->mCSD.cmd_class =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.temp_wp =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.temp_wp ); // gSD->mCSD.temp_wp =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.perm_wp =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.perm_wp ); // gSD->mCSD.perm_wp =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.dsr_imp =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.dsr_imp ); // gSD->mCSD.dsr_imp =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.csd_ver =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.csd_ver ); // gSD->mCSD.csd_ver =0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.spec_ver =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.spec_ver ); // gSD->mCSD.spec_ver =0x0
+ {
+ guilin_sleep(30);
+ msdc_dbg_print("[guilin %s %d]EXTCSD", __FUNCTION__, __LINE__);
+#ifndef MSDC_MMC441_SUPPORT
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev1[183] =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev1[183 - 1] );
+#else
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev0[136] =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev0[136 - 1] );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->enh_start_addr =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->enh_start_addr );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->enh_size_mult[3] =0x%x 0x%x 0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->enh_size_mult[2], gSD->mCSD.ext_csd->enh_size_mult[1], gSD->mCSD.ext_csd->enh_size_mult[0] );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->gp_size_mult[4] =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->gp_size_mult[11], gSD->mCSD.ext_csd->gp_size_mult[10], gSD->mCSD.ext_csd->gp_size_mult[9] );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->gp_size_mult[3] =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->gp_size_mult[8], gSD->mCSD.ext_csd->gp_size_mult[7], gSD->mCSD.ext_csd->gp_size_mult[6] );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->gp_size_mult[2] =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->gp_size_mult[5], gSD->mCSD.ext_csd->gp_size_mult[4], gSD->mCSD.ext_csd->gp_size_mult[3] );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->gp_size_mult[1] =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->gp_size_mult[2], gSD->mCSD.ext_csd->gp_size_mult[1], gSD->mCSD.ext_csd->gp_size_mult[0] );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->partition_settig =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->partition_settig );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->partition_attr =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->partition_attr );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->max_enh_size_mult[3] =0x%x 0x%x 0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->max_enh_size_mult[2], gSD->mCSD.ext_csd->max_enh_size_mult[1], gSD->mCSD.ext_csd->max_enh_size_mult[0]);
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->partition_support =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->partition_support );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev1 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev1 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rst_function =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rst_function );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev2[5] =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev2[5 - 1] );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rpmb_size_mul =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rpmb_size_mul );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->fw_config =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->fw_config );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev3 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev3 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->user_wp =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->user_wp );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev4 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev4 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->boot_wp =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->boot_wp );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev5 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev5 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->erase_grp_def =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->erase_grp_def );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev6 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev6 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->boot_bus_width =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->boot_bus_width );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->boot_config_prot =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->boot_config_prot );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->partition_config =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->partition_config );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev7 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev7 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->erased_mem_cont =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->erased_mem_cont );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev8 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev8 );
+#endif
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->bus_width =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->bus_width );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev2 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev2 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->high_speed =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->high_speed );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev3 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev3 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->power_class =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->power_class );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev4 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev4 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->cmd_set_rev =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->cmd_set_rev );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev5 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev5 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->cmd_set =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->cmd_set );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->ext_csd_rev =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->ext_csd_rev );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev7 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev7 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->ext_csd_ver =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->ext_csd_ver );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev8 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev8 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->card_type =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->card_type );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev9 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev9 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->out_of_interrupt_time=0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->out_of_interrupt_time);
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->partition_switch_time=0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->partition_switch_time);
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->pwr_52_195 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->pwr_52_195 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->pwr_26_195 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->pwr_26_195 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->pwr_52_360 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->pwr_52_360 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->pwr_26_360 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->pwr_26_360 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev10 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev10 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_r_4_26 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_r_4_26 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_w_4_26 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_w_4_26 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_r_8_26_4_52 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_r_8_26_4_52 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_w_8_26_4_52 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_w_8_26_4_52 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_r_8_52 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_r_8_52 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->min_perf_w_8_52 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->min_perf_w_8_52 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->resv11 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->resv11 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->sec_count =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->sec_count );
+
+ guilin_sleep(30);
+#ifndef MSDC_MMC441_SUPPORT
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev12[288] =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev12[288 - 1] );
+#else
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev9[5] =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev9[5 - 1] );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->hc_wp_grp_size =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->hc_wp_grp_size );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rel_wr_sec_c =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rel_wr_sec_c );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->erase_timeout_mult =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->erase_timeout_mult);
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->hc_erase_grp_size =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->hc_erase_grp_size );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->acc_size =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->acc_size );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->boot_size_mul =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->boot_size_mul );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev10 =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev10 );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->boot_info =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->boot_info );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->mmc44_rev11[275] =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->mmc44_rev11[275 - 1] );
+#endif
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->s_cmd_set =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->s_cmd_set );
+ msdc_dbg_print("[guilin %s %d]gSD->mCSD.ext_csd->rev13[7] =0x%x", __FUNCTION__, __LINE__, gSD->mCSD.ext_csd->rev13[7 - 1] );
+ }
+
+ msdc_dbg_print("[guilin %s %d]CID", __FUNCTION__, __LINE__);
+ msdc_dbg_print("[guilin %s %d]gSD->mCID.mid =0x%x", __FUNCTION__, __LINE__, gSD->mCID.mid ); // gSD->mCID.mid =0x1B
+ msdc_dbg_print("[guilin %s %d]gSD->mCID.oid =0x%x", __FUNCTION__, __LINE__, gSD->mCID.oid ); // gSD->mCID.oid =0x534D
+ msdc_dbg_print("[guilin %s %d]gSD->mCID.pnm =%c%c%c%c%c%c", __FUNCTION__, __LINE__, gSD->mCID.pnm[0], gSD->mCID.pnm[1], gSD->mCID.pnm[2], gSD->mCID.pnm[3], gSD->mCID.pnm[4], gSD->mCID.pnm[5]);
+ msdc_dbg_print("[guilin %s %d]gSD->mCID.prv =0x%x", __FUNCTION__, __LINE__, gSD->mCID.prv ); // gSD->mCID.prv =0x10
+ msdc_dbg_print("[guilin %s %d]gSD->mCID.psn =0x%x", __FUNCTION__, __LINE__, gSD->mCID.psn ); // gSD->mCID.psn =0x7940C2
+ msdc_dbg_print("[guilin %s %d]gSD->mCID.year =0x%x", __FUNCTION__, __LINE__, gSD->mCID.year ); // gSD->mCID.year =0x7D8
+ msdc_dbg_print("[guilin %s %d]gSD->mCID.month=0x%x", __FUNCTION__, __LINE__, gSD->mCID.month ); // gSD->mCID.month=0x8
+
+ msdc_dbg_print("[guilin %s %d]SCR", __FUNCTION__, __LINE__);
+ msdc_dbg_print("[guilin %s %d]gSD->mSCR.dat_after_erase=0x%x", __FUNCTION__, __LINE__, gSD->mSCR.dat_after_erase ); // gSD->mSCR.dat_after_erase=0x0
+ msdc_dbg_print("[guilin %s %d]gSD->mSCR.security =0x%x", __FUNCTION__, __LINE__, gSD->mSCR.security ); // gSD->mSCR.security =0x2
+ msdc_dbg_print("[guilin %s %d]gSD->mSCR.bus_width =0x%x", __FUNCTION__, __LINE__, gSD->mSCR.bus_width ); // gSD->mSCR.bus_width =0x5
+ msdc_dbg_print("[guilin %s %d]gSD->mSCR.spec_ver =0x%x", __FUNCTION__, __LINE__, gSD->mSCR.spec_ver ); // gSD->mSCR.spec_ver =0x1
+
+ guilin_sleep(30);
+
+ msdc_dbg_print("[guilin %s %d]Reg", __FUNCTION__, __LINE__);
+ msdc_dbg_print("[guilin %s %d]MSDC_CFG=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_CFG)); // MSDC_CFG=0x1210031
+ msdc_dbg_print("[guilin %s %d]MSDC_STA=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_STA)); // MSDC_STA=0x2
+ msdc_dbg_print("[guilin %s %d]MSDC_PS=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_PS)); // MSDC_PS=0x1FF0008
+ msdc_dbg_print("[guilin %s %d]MSDC_IOCON=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_IOCON)); // MSDC_IOCON=0x1280036
+ msdc_dbg_print("[guilin %s %d]MSDC_IOCON1=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_IOCON1)); // MSDC_IOCON1=0x22222
+
+ msdc_dbg_print("[guilin %s %d]SDC_CFG=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_CFG)); // SDC_CFG=0x50038200
+ msdc_dbg_print("[guilin %s %d]SDC_CMD=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_CMD)); // SDC_CMD=0x97
+ msdc_dbg_print("[guilin %s %d]SDC_ARG=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_ARG)); // SDC_ARG=0x20
+ msdc_dbg_print("[guilin %s %d]SDC_IRQMASK0=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_IRQMASK0)); // SDC_IRQMASK0=0x7000F
+ msdc_dbg_print("[guilin %s %d]SDC_IRQMASK1=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_IRQMASK1)); // SDC_IRQMASK1=0x0
+
+ msdc_dbg_print("[guilin %s %d]SDIO_CFG=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(SDC_IRQMASK1 + 4)); // SDIO_CFG=0x0
+
+ // msdc_dbg_print("[guilin %s %d]MSDC_BOOT_CFG=0x%x",__FUNCTION__,__LINE__,MSDC_Reg32(MSDC_BOOT_CFG)); // MSDC_BOOT_CFG=0x0
+ // msdc_dbg_print("[guilin %s %d]MSDC_BOOT_IOCON=0x%x",__FUNCTION__,__LINE__,MSDC_Reg32(MSDC_BOOT_IOCON));// MSDC_BOOT_IOCON=0x0
+
+ msdc_dbg_print("[guilin %s %d]MSDC_CLKACB_CFG=0x%x", __FUNCTION__, __LINE__, MSDC_Reg32(MSDC_CLKACB_CFG)); // MSDC_CLKACB_CFG=0x20000
+
+ guilin_sleep(30);
+
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_clock =%d", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_clock );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->op_clock =%d", __FUNCTION__, __LINE__, gMSDC_Handle->op_clock );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->total_count =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->total_count );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->timeout_period =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->timeout_period );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_input.type =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_input.type );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_input.size =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_input.size );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_input.count =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_input.count );
+#if defined(__DMA_API_V2__)
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_input.fixed_pattern =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_input.fixed_pattern );
+#endif
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_menu.TMOD.burst_mode=0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_menu.TMOD.burst_mode );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_menu.TMOD.cycle =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_menu.TMOD.cycle );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_menu.master =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_menu.master );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mMSDC_type =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mMSDC_type );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mIsPresent =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mIsPresent );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mIsInitialized =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mIsInitialized );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mIsChanged =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mIsChanged );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->is_timeout =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->is_timeout );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mIsPWDown =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mIsPWDown );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->cmd_sta =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->cmd_sta );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->dat_sta =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->dat_sta );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->ins_level =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->ins_level );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->timeout_count =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->timeout_count );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->is_poll =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->is_poll );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->is_aligned =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->is_aligned );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->is_init_timeout =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->is_init_timeout );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->send_ilm =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->send_ilm );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_dmaport =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_dmaport );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->dataCrcError_count =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->dataCrcError_count );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->trySingleLine =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->trySingleLine );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->isCachedBuf =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->isCachedBuf );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->cachedBufCopyPtr =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->cachedBufCopyPtr );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->tuningTopology =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->tuningTopology );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->MSDC_everPlugOut =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->MSDC_everPlugOut );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->MSDC_fastFormat =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->MSDC_fastFormat );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdcTimeoutDuration =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdcTimeoutDuration );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_clkTuneUpperBund =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_clkTuneUpperBund );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->mIsInitMSDC =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->mIsInitMSDC );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->msdc_int =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->msdc_int );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->LISR_Entry_Count =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->LISR_Entry_Count );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDCMDIRQ_Entry_Count =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDCMDIRQ_Entry_Count );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDMCIRQ_Entry_Count =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDMCIRQ_Entry_Count );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDDATIRQ_Entry_Count =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDDATIRQ_Entry_Count );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDR1bIRQ_Entry_count =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDR1bIRQ_Entry_count );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDIOIRQ_Entry_Count =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDIOIRQ_Entry_Count );
+ msdc_dbg_print("[guilin %s %d]gMSDC_Handle->SDPINIRQ_Entry_Count =0x%x", __FUNCTION__, __LINE__, gMSDC_Handle->SDPINIRQ_Entry_Count );
+
+ msdc_dbg_print("[guilin %s %d]end", __FUNCTION__, __LINE__);
+ guilin_sleep(30);
+
+}
+
+
+#endif
+
+
+#endif //#ifdef __MSDC_BASIC_LOAD__
+
+#ifdef __MSDC_SD_SDIO__
+
+
+DCL_HANDLE handle_sdio;
+
+#define TEST_PACKET_MIN_LENGTH (140)
+#define TEST_PACKET_MAX_LENGTH (1500)
+#define MAX_TX_QUEUE_NUM 16
+
+#pragma arm section rwdata="DYNAMICCACHEABLERW_C", zidata="DYNAMICCACHEABLEZI_C"
+static unsigned char ucDmaBuf[1500]; /*__HOTSPOT_SUPPORT__*/
+#pragma arm section
+
+typedef struct _NIC_HIF_TX_HEADER_T
+{
+ kal_uint16 u2TxByteCount;
+ kal_uint8 ucEtherTypeOffset;
+ kal_uint8 ucCSUMFlags;
+ kal_uint32 dummy[3];
+} NIC_HIF_TX_HEADER_T, *P_NIC_HIF_TX_HEADER_T;
+
+typedef enum
+{
+ RANDOM = 0,
+ DATA_FF,
+ DATA_00,
+ DATA_F0,
+ DATA_0F,
+ DATA_55,
+ DATA_99,
+ DATA_AA,
+ DATA_66,
+} Data_Pattern;
+
+// MT5931
+#define WCIR (0x0000)
+#define WHLPCR (0x0004)
+#define WSDIOCSR (0x0008)
+#define WHCR (0x000c)
+#define WHISR (0x0010)
+#define WHIER (0x0014)
+#define WASR (0x0018)
+#define WSICR (0x001c)
+#define WTSR0 (0x0020)
+#define WTSR1 (0x0024)
+#define WTDR0 (0x0028)
+#define WTDR1 (0x002c)
+#define WRDR0 (0x0030)
+#define WRDR1 (0x0034)
+#define H2DSM0R (0x0038)
+#define H2DSM1R (0x003c)
+#define D2HRM0R (0x0040)
+#define D2HRM1R (0x0044)
+#define D2HRM2R (0x0048)
+#define WRPLR (0x0050)
+#define WEHTCR (0x0054)
+
+#define FWDLDR (0x0080)
+#define FWDLDSAR (0x0084)
+#define FWDLSR (0x0088)
+#define FWDLCMR0 (0x008c)
+#define FWDLCMR1 (0x0090)
+
+//4 CHIP ID Register
+#define MCR_WCIR 0x0000
+
+//4 HIF Low Power Control Register
+#define MCR_WHLPCR 0x0004
+
+//4 Control Status Register
+#define MCR_WSDIOCSR 0x0008
+#define MCR_WSPICSR 0x0008
+
+//4 HIF Control Register
+#define MCR_WHCR 0x000C
+
+//4 HIF Interrupt Status Register
+#define MCR_WHISR 0x0010
+
+//4 HIF Interrupt Enable Register
+#define MCR_WHIER 0x0014
+
+//4 Abnormal Status Register
+#define MCR_WASR 0x0018
+
+//4 WLAN Software Interrupt Control Register
+#define MCR_WSICR 0x001C
+
+//4 WLAN TX Status Register
+#define MCR_WTSR0 0x0020
+
+//4 WLAN TX Status Register
+#define MCR_WTSR1 0x0024
+
+//4 WLAN TX Data Register 0
+#define MCR_WTDR0 0x0028
+
+//4 WLAN TX Data Register 1
+#define MCR_WTDR1 0x002C
+
+//4 WLAN RX Data Register 0
+#define MCR_WRDR0 0x0030
+
+//4 WLAN RX Data Register 1
+#define MCR_WRDR1 0x0034
+
+//4 Host to Device Send Mailbox 0 Register
+#define MCR_H2DSM0R 0x0038
+
+//4 Host to Device Send Mailbox 1 Register
+#define MCR_H2DSM1R 0x003c
+
+//4 Device to Host Receive Mailbox 0 Register
+#define MCR_D2HRM0R 0x0040
+
+//4 Device to Host Receive Mailbox 1 Register
+#define MCR_D2HRM1R 0x0044
+
+//4 Device to Host Receive Mailbox 2 Register
+#define MCR_D2HRM2R 0x0048
+
+//4 WLAN RX Packet Length Register
+#define MCR_WRPLR 0x0050
+
+//4 EHPI Transaction Count Register
+#define MCR_EHTCR 0x0054
+
+//4 Firmware Download Data Register
+#define MCR_FWDLDR 0x0080
+
+//4 Firmware Download Destination Starting Address Register
+#define MCR_FWDLDSAR 0x0084
+
+//4 Firmware Download Status Register
+#define MCR_FWDLSR 0x0088
+
+//4 WLAN MCU Control & Status Register
+#define MCR_WMCSR 0x008c
+
+//4 WLAN Firmware Download Configuration
+#define MCR_FWCFG 0x0090
+
+#define BIT(x) (1 << (x))
+
+//2 Definition in each register
+//3 WCIR 0x0000
+#define WCIR_WLAN_READY BIT(21)
+#define WCIR_POR_INDICATOR BIT(20)
+#define WCIR_REVISION_ID BITS(16,19)
+#define WCIR_CHIP_ID BITS(0,15)
+
+#define MTK_CHIP_REV 0x00005931
+#define MTK_CHIP_MP_REVERSION_ID 0x0
+
+//3 WHLPCR 0x0004
+#define WHLPCR_FW_OWN_REQ_CLR BIT(9)
+#define WHLPCR_FW_OWN_REQ_SET BIT(8)
+#define WHLPCR_IS_DRIVER_OWN BIT(8)
+#define WHLPCR_INT_EN_CLR BIT(1)
+#define WHLPCR_INT_EN_SET BIT(0)
+
+//3 WSDIOCSR 0x0008
+#define WSDIOCSR_SDIO_RE_INIT_EN BIT(0)
+
+//3 WSPICSR 0x0008
+#define WCSR_SPI_MODE_SEL BITS(3,4)
+#define WCSR_SPI_ENDIAN_BIG BIT(2)
+#define WCSR_SPI_INT_OUT_MODE BIT(1)
+#define WCSR_SPI_DATA_OUT_MODE BIT(0)
+
+//3 WHCR 0x000C
+#define WHCR_RX_ENHANCE_MODE_EN BIT(16)
+#define WHCR_MAX_HIF_RX_LEN_NUM BITS(4,7)
+#define WHCR_W_MAILBOX_RD_CLR_EN BIT(2)
+#define WHCR_W_INT_CLR_CTRL BIT(1)
+#define WHCR_MCU_DBG_EN BIT(0)
+#define WHCR_OFFSET_MAX_HIF_RX_LEN_NUM 4
+
+//3 WHISR 0x0010
+#define WHISR_D2H_SW_INT BITS(8,31)
+#define WHISR_D2H_SW_ASSERT_INFO_INT BIT(31)
+#define WHISR_FW_OWN_BACK_INT BIT(4)
+#define WHISR_ABNORMAL_INT BIT(3)
+#define WHISR_RX1_DONE_INT BIT(2)
+#define WHISR_RX0_DONE_INT BIT(1)
+#define WHISR_TX_DONE_INT BIT(0)
+
+
+//3 WHIER 0x0014
+#define WHIER_D2H_SW_INT BITS(8,31)
+#define WHIER_FW_OWN_BACK_INT_EN BIT(4)
+#define WHIER_ABNORMAL_INT_EN BIT(3)
+#define WHIER_RX1_DONE_INT_EN BIT(2)
+#define WHIER_RX0_DONE_INT_EN BIT(1)
+#define WHIER_TX_DONE_INT_EN BIT(0)
+#define WHIER_DEFAULT (WHIER_RX0_DONE_INT_EN | \
+ WHIER_RX1_DONE_INT_EN | \
+ WHIER_TX_DONE_INT_EN | \
+ WHIER_ABNORMAL_INT_EN | \
+ WHIER_D2H_SW_INT \
+ )
+
+
+//3 WASR 0x0018
+#define WASR_FW_OWN_INVALID_ACCESS BIT(4)
+#define WASR_RX1_UNDER_FLOW BIT(3)
+#define WASR_RX0_UNDER_FLOW BIT(2)
+#define WASR_TX1_OVER_FLOW BIT(1)
+#define WASR_TX0_OVER_FLOW BIT(0)
+
+
+//3 WSICR 0x001C
+#define WSICR_H2D_SW_INT_SET BITS(16,31)
+
+
+//3 WRPLR 0x0050
+#define WRPLR_RX1_PACKET_LENGTH BITS(16,31)
+#define WRPLR_RX0_PACKET_LENGTH BITS(0,15)
+
+
+//3 FWDLSR 0x0088
+#define FWDLSR_FWDL_RDY BIT(8)
+#define FWDLSR_FWDL_MODE BIT(0)
+
+
+//3 WMCSR 0x008c
+#define WMCSR_CHIP_RST BIT(15) /* write */
+#define WMCSR_DL_OK BIT(15) /* read */
+#define WMCSR_DL_FAIL BIT(14)
+#define WMCSR_PLLRDY BIT(13)
+#define WMCSR_WF_ON BIT(12)
+#define WMCSR_INI_RDY BIT(11)
+#define WMCSR_WF_EN BIT(6)
+#define WMCSR_SW_EN BIT(5)
+#define WMCSR_SPLLEN BIT(4)
+#define WMCSR_SPWREN BIT(3)
+#define WMCSR_HSTOPIL BIT(2)
+#define WMCSR_FWDLRST BIT(1)
+#define WMCSR_FWDLEN BIT(0)
+
+
+//3 FWCFG 0x0090
+#define FWCFG_KSEL BITS(14,15)
+#define FWCFG_FLEN BITS(0,13)
+
+#define CFG_RESPONSE_POLLING_TIMEOUT 512
+/* Type definition for WLAN STATUS */
+typedef kal_uint32 WLAN_STATUS, *P_WLAN_STATUS;
+
+#define WLAN_STATUS_SUCCESS ((WLAN_STATUS) 0x00000000L)
+#define WLAN_STATUS_FAILURE ((WLAN_STATUS) 0xC0000001L)
+
+#define CFG_FW_LOAD_ADDRESS 0xFF900000
+#define CFG_FW_START_ADDRESS 0x00000000
+#define CMD_PKT_SIZE_FOR_IMAGE 2048 /* !< 2048 Bytes CMD payload buffer */
+
+typedef struct _HIF_HW_TX_HEADER_T
+{
+ kal_uint16 u2TxByteCount;
+ kal_uint8 ucEtherTypeOffset;
+ kal_uint8 ucCSflags;
+ kal_uint8 aucBuffer[4];
+} HIF_HW_TX_HEADER_T, *P_HIF_HW_TX_HEADER_T;
+
+#pragma arm section rwdata="DYNAMICCACHEABLERW_C", zidata="DYNAMICCACHEABLEZI_C"
+__align(32) kal_uint8 wndrv_cmd_temp_buf[CMD_PKT_SIZE_FOR_IMAGE + 512];
+#pragma arm section
+
+#define HIF_HW_TX_HDR_SIZE OFFSET_OF(HIF_HW_TX_HEADER_T, aucBuffer[0])
+#define OFFSET_OF(_type, _field) ((kal_uint32)&(((_type *)0)->_field))
+#define ALIGN_4(_value) (((_value) + 3) & ~3u)
+#define ALIGN_32(_value) (((_value) + 31) & ~31u)
+#define FUNC1_SDIO_BLK_SIZE (512)
+#define DMA_THRESHOLD 128
+#define SWITCH_TO_NONCACHEABLE 0
+#define SWITCH_TO_CACHEABLE 1
+kal_uint8 payload[1500];
+kal_uint8 pucTXBuf[1500];
+kal_uint8 pucRXBuf[1500];
+
+kal_uint8 const mt5931_E3_Beta_loopback_firmware_hex[] =
+{
+ 0x74, 0xDB, 0x7D, 0xB4, 0x6E, 0xA7, 0x12, 0xCE, 0x3C, 0x69, 0xFF, 0xD6, 0xF3, 0x13, 0x47, 0x60
+ , 0xC7, 0x6E, 0x5C, 0xA1, 0x74, 0x29, 0x70, 0x0C, 0x6A, 0xA3, 0x42, 0x02, 0x6D, 0x1B, 0xCE, 0x6F
+ , 0x2F, 0x07, 0x8A, 0x75, 0x63, 0xF8, 0xCD, 0x46, 0x3C, 0x43, 0x7E, 0x62, 0x24, 0x58, 0x19, 0x11
+ , 0x10, 0x30, 0x84, 0x36, 0x0F, 0x06, 0x52, 0x71, 0x86, 0x5F, 0x09, 0x0F, 0x01, 0x8A, 0x51, 0x32
+ , 0x84, 0xEE, 0xA8, 0x7F, 0xF8, 0xEF, 0xD8, 0xE7, 0x1E, 0xF1, 0xE5, 0x0D, 0x43, 0x69, 0x1F, 0xF7
+ , 0x91, 0xC3, 0xFE, 0xA1, 0xA7, 0x30, 0x50, 0x9B, 0xED, 0xBC, 0xE6, 0x21, 0xFB, 0x58, 0xCD, 0xAD
+ , 0x08, 0x34, 0xB4, 0x7E, 0x4B, 0xB1, 0x18, 0x21, 0xD6, 0x98, 0xE9, 0x16, 0x94, 0xFE, 0x11, 0x2E
+ , 0xEC, 0xE6, 0x61, 0x25, 0xD2, 0x3C, 0x14, 0xDC, 0x36, 0xF3, 0x22, 0x35, 0xDF, 0xA7, 0xE7, 0x59
+ , 0xA7, 0xDD, 0x1E, 0xF2, 0x4D, 0x1D, 0x93, 0xA2, 0x22, 0xDE, 0xE5, 0x05, 0x50, 0xA5, 0xE6, 0xCA
+ , 0xC0, 0xEC, 0x76, 0x7E, 0x13, 0x8B, 0xBA, 0x3D, 0x4C, 0xC9, 0xCE, 0x6D, 0x50, 0x0F, 0x86, 0x3D
+ , 0x51, 0x52, 0xB2, 0xB5, 0xE9, 0xA2, 0x32, 0x2B, 0x9E, 0xB4, 0x65, 0x8F, 0x60, 0x18, 0xF3, 0xEB
+ , 0xE9, 0xEA, 0xD2, 0xEE, 0x81, 0xD0, 0x53, 0x44, 0x06, 0xBC, 0x43, 0x51, 0x2C, 0xA8, 0x9B, 0xEF
+ , 0xB5, 0x4C, 0x87, 0x80, 0x02, 0x94, 0xFD, 0x25, 0x6F, 0x28, 0x9E, 0x84, 0xA0, 0xDA, 0x6F, 0xA3
+ , 0x30, 0x9B, 0x68, 0xA3, 0x9E, 0x51, 0xBE, 0x1B, 0x49, 0x68, 0xBA, 0x09, 0x6E, 0xEF, 0xF9, 0x52
+ , 0x8F, 0x97, 0x31, 0x3D, 0x77, 0xFF, 0x0C, 0xF1, 0x5A, 0xE4, 0x24, 0x3A, 0xCC, 0x44, 0x9E, 0xF6
+ , 0x34, 0x69, 0x3B, 0x6E, 0xDE, 0xE1, 0x12, 0xA1, 0x1A, 0x3C, 0x18, 0xA3, 0x62, 0xB9, 0x8D, 0x3D
+ , 0xAA, 0x9F, 0x38, 0x52, 0x9A, 0x76, 0x36, 0x39, 0xF3, 0x51, 0x01, 0xEE, 0xBC, 0xCF, 0x59, 0x26
+ , 0x58, 0x2A, 0x25, 0xD5, 0x4E, 0x25, 0xF8, 0xBC, 0xC2, 0x94, 0x91, 0x17, 0x1B, 0x0B, 0x0F, 0xDF
+ , 0x7B, 0x6A, 0x61, 0x39, 0xE0, 0x49, 0x0F, 0x31, 0x97, 0x1C, 0xC4, 0x20, 0xD6, 0x0B, 0xA6, 0xF4
+ , 0xA5, 0x7A, 0xCC, 0xC4, 0x1D, 0x38, 0xEC, 0x32, 0x0A, 0x83, 0xE1, 0xB2, 0x64, 0x4F, 0x9F, 0x4C
+ , 0x9A, 0x07, 0xC1, 0xC5, 0xEA, 0x1B, 0xAC, 0x14, 0x41, 0xB9, 0xEA, 0x0C, 0x3F, 0x6F, 0x27, 0xAF
+ , 0x1B, 0x87, 0x56, 0x5E, 0xAE, 0xB6, 0xB6, 0x53, 0xA9, 0xC8, 0xA4, 0xC4, 0x98, 0x97, 0xA4, 0x0F
+ , 0xAD, 0xB6, 0x89, 0x10, 0xAA, 0x99, 0xF5, 0x3C, 0xF7, 0x92, 0x09, 0x62, 0x95, 0xEC, 0x14, 0xE5
+ , 0x81, 0x20, 0xC2, 0x8F, 0xCD, 0xD0, 0x68, 0x9F, 0x9A, 0xF5, 0x7E, 0x3B, 0x13, 0x8D, 0xC9, 0x81
+ , 0x01, 0xC3, 0x39, 0xD9, 0xB5, 0x4C, 0xA4, 0x06, 0x7A, 0x76, 0xDE, 0x55, 0x53, 0x03, 0x3C, 0xA4
+ , 0xBF, 0x24, 0x19, 0x96, 0xBE, 0xD5, 0x15, 0xB5, 0xAF, 0x76, 0x9F, 0x4D, 0x75, 0x4D, 0xE3, 0xA8
+ , 0x03, 0xB0, 0x12, 0xE9, 0x45, 0x8D, 0xB3, 0x67, 0x50, 0xE5, 0xD3, 0x1C, 0xB5, 0x19, 0x32, 0x27
+ , 0x63, 0x38, 0x11, 0x64, 0x19, 0xC7, 0x4E, 0xF4, 0xEE, 0x01, 0xAF, 0xB5, 0x03, 0x97, 0x69, 0x14
+ , 0x97, 0x9E, 0x40, 0xEB, 0x04, 0xDD, 0x7C, 0xFD, 0xD0, 0xA6, 0x02, 0xD2, 0x30, 0x1B, 0x07, 0xBD
+ , 0x72, 0xC7, 0xED, 0xB5, 0x59, 0x53, 0x9B, 0x97, 0x66, 0x3B, 0x07, 0x06, 0x78, 0x51, 0xE6, 0x06
+ , 0xD2, 0xFE, 0x33, 0x1E, 0x73, 0xCC, 0x7C, 0x91, 0x66, 0x9A, 0xBA, 0x8E, 0x6E, 0x2B, 0x4D, 0x5E
+ , 0x2D, 0x2C, 0x91, 0x3C, 0x8F, 0x23, 0xF6, 0x5D, 0x6F, 0xBF, 0x84, 0x9F, 0x0B, 0xF5, 0x81, 0x02
+ , 0x0A, 0x4B, 0xDE, 0x16, 0x7A, 0x80, 0x18, 0x08, 0x5B, 0x2A, 0xFA, 0x3A, 0x6B, 0x36, 0x07, 0xCF
+ , 0x84, 0xEE, 0xA8, 0x7F, 0xF8, 0xEF, 0xD8, 0xE7, 0x1E, 0xF1, 0xE5, 0x0D, 0x43, 0x69, 0x1F, 0xF7
+ , 0x91, 0xC3, 0xFE, 0xA1, 0xA7, 0x30, 0x50, 0x9B, 0xED, 0xBC, 0xE6, 0x21, 0xFB, 0x58, 0xCD, 0xAD
+ , 0x08, 0x34, 0xB4, 0x7E, 0x4B, 0xB1, 0x18, 0x21, 0xD6, 0x98, 0xE9, 0x16, 0x94, 0xFE, 0x11, 0x2E
+ , 0x7A, 0xB7, 0xD9, 0x69, 0x2E, 0xC4, 0x19, 0xE7, 0x9B, 0x85, 0x9F, 0x3F, 0x31, 0x43, 0xA7, 0xCC
+ , 0x84, 0xEE, 0xA8, 0x7F, 0xF8, 0xEF, 0xD8, 0xE7, 0x1E, 0xF1, 0xE5, 0x0D, 0x43, 0x69, 0x1F, 0xF7
+ , 0x91, 0xC3, 0xFE, 0xA1, 0xA7, 0x30, 0x50, 0x9B, 0xED, 0xBC, 0xE6, 0x21, 0xFB, 0x58, 0xCD, 0xAD
+ , 0x08, 0x34, 0xB4, 0x7E, 0x4B, 0xB1, 0x18, 0x21, 0xD6, 0x98, 0xE9, 0x16, 0x94, 0xFE, 0x11, 0x2E
+ , 0x22, 0xEE, 0x34, 0x46, 0x5A, 0x19, 0xE1, 0x1A, 0x67, 0x74, 0x7A, 0xD2, 0xA2, 0xCB, 0x69, 0x5C
+ , 0xA7, 0xDD, 0x1E, 0xF2, 0x4D, 0x1D, 0x93, 0xA2, 0x22, 0xDE, 0xE5, 0x05, 0x50, 0xA5, 0xE6, 0xCA
+ , 0xC0, 0xEC, 0x76, 0x7E, 0x13, 0x8B, 0xBA, 0x3D, 0x4C, 0xC9, 0xCE, 0x6D, 0x50, 0x0F, 0x86, 0x3D
+ , 0x83, 0x95, 0xFF, 0xA2, 0xA4, 0x31, 0xF5, 0x88, 0x38, 0x00, 0xB9, 0x27, 0xA3, 0x7B, 0xEF, 0x8A
+ , 0x5C, 0x79, 0xF1, 0x26, 0x42, 0x2C, 0x68, 0x27, 0x40, 0x02, 0x52, 0x97, 0xD6, 0x51, 0x4D, 0x3F
+ , 0xB5, 0x4C, 0x87, 0x80, 0x02, 0x94, 0xFD, 0x25, 0x6F, 0x28, 0x9E, 0x84, 0xA0, 0xDA, 0x6F, 0xA3
+ , 0x30, 0x9B, 0x68, 0xA3, 0x9E, 0x51, 0xBE, 0x1B, 0x49, 0x68, 0xBA, 0x09, 0x6E, 0xEF, 0xF9, 0x52
+ , 0x25, 0x15, 0x38, 0x2C, 0x07, 0xDB, 0x76, 0xC9, 0x7C, 0x2F, 0xC6, 0x60, 0x4F, 0xA2, 0xE3, 0xC4
+ , 0x34, 0x69, 0x3B, 0x6E, 0xDE, 0xE1, 0x12, 0xA1, 0x1A, 0x3C, 0x18, 0xA3, 0x62, 0xB9, 0x8D, 0x3D
+ , 0xAA, 0x9F, 0x38, 0x52, 0x9A, 0x76, 0x36, 0x39, 0xF3, 0x51, 0x01, 0xEE, 0xBC, 0xCF, 0x59, 0x26
+ , 0x58, 0x2A, 0x25, 0xD5, 0x4E, 0x25, 0xF8, 0xBC, 0xC2, 0x94, 0x91, 0x17, 0x1B, 0x0B, 0x0F, 0xDF
+ , 0x0B, 0x7D, 0x19, 0x57, 0xB6, 0xF2, 0x8C, 0x9B, 0xCA, 0x0B, 0xDC, 0x56, 0x1C, 0x63, 0x8D, 0x1D
+ , 0xD2, 0xFE, 0x33, 0x1E, 0x73, 0xCC, 0x7C, 0x91, 0x66, 0x9A, 0xBA, 0x8E, 0x6E, 0x2B, 0x4D, 0x5E
+ , 0x2D, 0x2C, 0x91, 0x3C, 0x8F, 0x23, 0xF6, 0x5D, 0x6F, 0xBF, 0x84, 0x9F, 0x0B, 0xF5, 0x81, 0x02
+ , 0x2F, 0x27, 0x25, 0x17, 0x1D, 0x25, 0x03, 0x43, 0x4B, 0x34, 0x42, 0x74, 0x45, 0x67, 0xCE, 0x68
+ , 0x34, 0x69, 0x3B, 0x6E, 0xDE, 0xE1, 0x12, 0xA1, 0x1A, 0x3C, 0x18, 0xA3, 0x62, 0xB9, 0x8D, 0x3D
+ , 0xAA, 0x9F, 0x38, 0x52, 0x9A, 0x76, 0x36, 0x39, 0xF3, 0x51, 0x01, 0xEE, 0xBC, 0xCF, 0x59, 0x26
+ , 0x58, 0x2A, 0x25, 0xD5, 0x4E, 0x25, 0xF8, 0xBC, 0xC2, 0x94, 0x91, 0x17, 0x1B, 0x0B, 0x0F, 0xDF
+ , 0x3A, 0x95, 0xC8, 0x83, 0xF3, 0x0B, 0x46, 0x50, 0x95, 0xA5, 0x06, 0x15, 0xFB, 0x2B, 0x67, 0xE5
+ , 0xD2, 0xFE, 0x33, 0x1E, 0x73, 0xCC, 0x7C, 0x91, 0x66, 0x9A, 0xBA, 0x8E, 0x6E, 0x2B, 0x4D, 0x5E
+ , 0x2D, 0x2C, 0x91, 0x3C, 0x8F, 0x23, 0xF6, 0x5D, 0x6F, 0xBF, 0x84, 0x9F, 0x0B, 0xF5, 0x81, 0x02
+ , 0xD3, 0xC1, 0x82, 0x91, 0x78, 0xA3, 0x12, 0x9F, 0xDD, 0xB1, 0xDE, 0x2E, 0xB5, 0x47, 0xD5, 0x51
+ , 0x01, 0xDD, 0x20, 0x23, 0x97, 0x00, 0xE9, 0x45, 0x75, 0x69, 0xE2, 0xD1, 0xD7, 0xC5, 0x43, 0x36
+ , 0x81, 0xA0, 0x4C, 0x6B, 0x02, 0x42, 0xC5, 0xEC, 0xCB, 0x94, 0x06, 0x3E, 0x13, 0xB1, 0x8F, 0x44
+ , 0x81, 0xA0, 0x4C, 0x6B, 0x02, 0x42, 0xC5, 0xEC, 0xCB, 0x94, 0x06, 0x3E, 0x13, 0xB1, 0x8F, 0x44
+ , 0xAC, 0xFB, 0x1F, 0x99, 0xF7, 0x6D, 0xAB, 0x37, 0x68, 0x2F, 0x95, 0x73, 0xE0, 0x84, 0x6E, 0x02
+ , 0x81, 0xA0, 0x4C, 0x6B, 0x02, 0x42, 0xC5, 0xEC, 0xCB, 0x94, 0x06, 0x3E, 0x13, 0xB1, 0x8F, 0x44
+ , 0xAD, 0x20, 0xFD, 0x61, 0x97, 0xF7, 0xBD, 0x96, 0xDD, 0xB9, 0x23, 0x12, 0xF9, 0xBE, 0x41, 0x58
+ , 0x55, 0x42, 0x8E, 0x49, 0x16, 0xEF, 0xCB, 0xF5, 0x8C, 0x4E, 0x1D, 0x7C, 0x3C, 0x12, 0xF8, 0xA4
+ , 0xA0, 0x08, 0xC3, 0x5F, 0x04, 0xF5, 0xAC, 0x42, 0x4F, 0x3D, 0x1D, 0x74, 0x80, 0x35, 0x6F, 0xFC
+ , 0x99, 0x53, 0x85, 0xC0, 0x07, 0x4F, 0xD3, 0xE5, 0xF9, 0x04, 0xCE, 0xE7, 0xF9, 0x76, 0x61, 0xE0
+ , 0x13, 0x6C, 0xC2, 0x84, 0x09, 0x87, 0x16, 0x13, 0x27, 0xFB, 0x15, 0x23, 0x47, 0x14, 0x82, 0x9D
+ , 0x98, 0xE3, 0x5A, 0x96, 0x9D, 0xBF, 0xB5, 0x8B, 0x58, 0x71, 0x32, 0xC2, 0xDF, 0x43, 0x79, 0x1B
+ , 0x25, 0x8B, 0x60, 0xBC, 0x49, 0x99, 0x03, 0x47, 0x37, 0xA1, 0x50, 0x44, 0x45, 0xF2, 0x2E, 0x33
+ , 0x7D, 0x7E, 0x71, 0x29, 0xDA, 0x73, 0x58, 0xF3, 0x8A, 0x9B, 0xD7, 0xF1, 0x95, 0x92, 0x24, 0xE0
+ , 0xE0, 0xA7, 0xC8, 0x5A, 0x78, 0x5C, 0xA0, 0x48, 0x8B, 0x97, 0xA0, 0x1A, 0xA1, 0xE9, 0xED, 0x5D
+ , 0x82, 0xED, 0x1B, 0x5A, 0xDA, 0x1A, 0x64, 0x0F, 0x47, 0x55, 0x21, 0x65, 0xE7, 0x80, 0x8A, 0x20
+ , 0x13, 0xA9, 0x1C, 0xE3, 0x64, 0xA4, 0xBA, 0x42, 0x06, 0x91, 0x0E, 0x57, 0x10, 0xF7, 0x04, 0x50
+ , 0x08, 0xBF, 0xEA, 0xAC, 0xDA, 0xA4, 0x1F, 0x3D, 0xFC, 0xBF, 0xD4, 0x48, 0xE5, 0x02, 0x5F, 0xFA
+ , 0x79, 0xD0, 0x2B, 0xAA, 0x45, 0xC4, 0x15, 0xB0, 0x4B, 0x2D, 0x81, 0xD0, 0xDA, 0x50, 0xDE, 0xB2
+ , 0x4F, 0xB2, 0xCB, 0x50, 0x37, 0x9E, 0xFA, 0x43, 0xEC, 0x8D, 0xE0, 0xDF, 0x5E, 0x96, 0x4E, 0xDE
+ , 0x45, 0x17, 0x77, 0xBE, 0x2C, 0x0E, 0xF1, 0x89, 0x92, 0x44, 0xDC, 0x3E, 0xC9, 0xBC, 0x9C, 0x8F
+ , 0x33, 0x36, 0xD6, 0x51, 0xE0, 0xB9, 0xE0, 0x2E, 0xB9, 0x06, 0xC6, 0xF1, 0xE5, 0xCD, 0x86, 0xDB
+ , 0x24, 0x2C, 0xFE, 0x98, 0x59, 0x63, 0x35, 0x73, 0x45, 0x54, 0xD4, 0x3C, 0x7B, 0x0E, 0x23, 0xFC
+ , 0x5D, 0x94, 0xC9, 0x02, 0xB4, 0xC6, 0xAB, 0x0C, 0xF7, 0xC7, 0x7E, 0x7D, 0x69, 0x95, 0x47, 0xF0
+ , 0x87, 0xD6, 0x7D, 0x7C, 0x2C, 0x18, 0x38, 0x0A, 0x61, 0x50, 0xD5, 0xA3, 0xEE, 0xEB, 0xBC, 0x14
+ , 0x38, 0xA0, 0x4B, 0xAE, 0xC3, 0x65, 0x24, 0x9B, 0x54, 0x23, 0x1F, 0xE1, 0xCB, 0xA9, 0xCE, 0xB5
+ , 0x8A, 0x42, 0x35, 0x7F, 0x1F, 0xED, 0xC1, 0x24, 0x9F, 0x7B, 0xB2, 0xB4, 0x8E, 0xA7, 0x44, 0x2B
+ , 0xCE, 0x92, 0x9C, 0x00, 0xA1, 0x16, 0x35, 0x00, 0x62, 0x29, 0xCF, 0xB7, 0x45, 0x27, 0x49, 0x60
+ , 0x9B, 0x61, 0x76, 0xE1, 0x2E, 0xBD, 0xE1, 0x7B, 0x12, 0x52, 0x10, 0xB9, 0xB6, 0xEB, 0x4B, 0xC1
+ , 0x35, 0x95, 0x08, 0x7B, 0xD6, 0xD3, 0x8E, 0xBF, 0xB5, 0xCF, 0xD5, 0x34, 0x62, 0xFE, 0x0C, 0x08
+ , 0xFA, 0x94, 0x18, 0x6E, 0x86, 0xB4, 0xA4, 0x2F, 0x97, 0xEB, 0xC4, 0xB3, 0x32, 0xEE, 0xEB, 0xB5
+ , 0x13, 0x86, 0xD3, 0x68, 0x8C, 0xDE, 0x8C, 0xD4, 0x8D, 0xE7, 0xEF, 0x79, 0x00, 0x7C, 0xAE, 0x36
+ , 0x79, 0xBF, 0x2E, 0x13, 0xF6, 0x58, 0x43, 0xB2, 0x3F, 0xD6, 0x2F, 0xCF, 0x51, 0x96, 0x19, 0x44
+ , 0x29, 0xF8, 0x9A, 0xEE, 0x17, 0xFD, 0xCE, 0x42, 0xD4, 0x5C, 0x8B, 0xA4, 0x2B, 0x17, 0x5E, 0x51
+ , 0xEE, 0x05, 0xC7, 0x54, 0xC9, 0xCE, 0x6E, 0x9D, 0x95, 0x8C, 0x96, 0x11, 0x9A, 0x29, 0x46, 0x21
+ , 0x85, 0x96, 0xF8, 0xBA, 0xEC, 0x6F, 0x63, 0x00, 0x3D, 0x92, 0xD9, 0x92, 0xD3, 0x38, 0xDF, 0x95
+ , 0x25, 0xBE, 0xAC, 0x59, 0x17, 0x0A, 0x9B, 0x0A, 0x5D, 0xDC, 0x4B, 0x8C, 0xF8, 0x67, 0x21, 0x5F
+ , 0xD2, 0x20, 0xF7, 0xCF, 0x50, 0x84, 0x29, 0x51, 0xE3, 0xCD, 0xFF, 0x85, 0x40, 0x5C, 0x38, 0x93
+ , 0x39, 0x6A, 0x44, 0x72, 0x32, 0x1C, 0xF9, 0xEC, 0xBB, 0x4E, 0x26, 0xF2, 0x05, 0x48, 0x79, 0x8C
+ , 0x2E, 0xAA, 0x72, 0x6B, 0xCB, 0x24, 0x9E, 0x09, 0x27, 0x43, 0xE7, 0xEA, 0x1E, 0x3A, 0xB9, 0xBE
+ , 0xA6, 0x3A, 0xBD, 0x3B, 0xD7, 0x16, 0x8A, 0x00, 0x8D, 0xF5, 0x6D, 0x91, 0x7D, 0x68, 0x91, 0x32
+ , 0x88, 0xE5, 0x82, 0xAE, 0x24, 0xAC, 0x38, 0x07, 0x9F, 0x3F, 0x47, 0x93, 0xB2, 0x41, 0x1D, 0xBF
+ , 0xD7, 0xFC, 0xF0, 0x12, 0x3F, 0xA1, 0xB5, 0xF1, 0xB4, 0x7B, 0x58, 0x94, 0x2A, 0x2F, 0xAE, 0xC2
+ , 0x4D, 0xF3, 0xA6, 0x5A, 0x4D, 0xB9, 0x3F, 0x0E, 0xA1, 0x67, 0xE9, 0xAF, 0x03, 0xA5, 0xF3, 0x7F
+ , 0x45, 0x85, 0x64, 0x3C, 0xE3, 0x2E, 0xA3, 0x31, 0x03, 0xD4, 0x3A, 0xF0, 0xB5, 0x94, 0xF9, 0x46
+ , 0xCE, 0xA4, 0x72, 0xDC, 0x65, 0xD1, 0x59, 0xBE, 0x0B, 0xAD, 0xE5, 0x5D, 0xBA, 0x55, 0xE0, 0xC1
+ , 0x82, 0x6E, 0x4A, 0x14, 0xC9, 0x55, 0xC6, 0xC0, 0x22, 0xF6, 0x57, 0x80, 0xF0, 0x02, 0xD9, 0xBD
+ , 0x4C, 0x9D, 0x3C, 0xDC, 0xC7, 0x5F, 0xCA, 0xF0, 0x3E, 0xDA, 0xFF, 0xFE, 0x69, 0xAF, 0xDA, 0x38
+ , 0x20, 0x0B, 0x14, 0x4F, 0xBB, 0x9B, 0xD0, 0xA4, 0x01, 0x63, 0x1F, 0x61, 0x24, 0x7F, 0x87, 0xB6
+ , 0x47, 0xEA, 0x7E, 0xEA, 0x74, 0xA4, 0x00, 0xDC, 0x49, 0xE3, 0x3A, 0x3C, 0xEF, 0x67, 0xF6, 0xB7
+ , 0x21, 0x09, 0x25, 0x96, 0x6F, 0xE8, 0x76, 0xEF, 0xF2, 0x6C, 0x6E, 0xF5, 0xCF, 0x06, 0x37, 0x24
+ , 0x00, 0xF2, 0xA7, 0x27, 0x4B, 0xE3, 0xC3, 0x9C, 0x9E, 0x93, 0xB5, 0xA4, 0x11, 0x65, 0x06, 0x4C
+ , 0x03, 0x97, 0x1D, 0x88, 0x3B, 0x14, 0x72, 0x5B, 0x52, 0xA5, 0xB8, 0x03, 0x68, 0xE5, 0xF1, 0x98
+ , 0x06, 0x48, 0xF7, 0x3E, 0x33, 0x29, 0xE3, 0x04, 0xEB, 0xD7, 0xCD, 0x69, 0xD9, 0x8E, 0x84, 0x15
+ , 0xBE, 0x21, 0xFC, 0x31, 0x99, 0x41, 0x58, 0x3C, 0x72, 0x6F, 0x73, 0x11, 0x43, 0x78, 0x5A, 0xF8
+ , 0x71, 0xDC, 0x02, 0x10, 0x59, 0xC8, 0xB9, 0x03, 0xB8, 0x25, 0x60, 0xDF, 0x22, 0x45, 0x4F, 0xF0
+ , 0x7E, 0x50, 0xDE, 0x54, 0x1F, 0x58, 0x8A, 0x5C, 0x93, 0xA9, 0x12, 0x2C, 0x95, 0x4C, 0x80, 0x5B
+ , 0x32, 0x8A, 0x78, 0x2C, 0x9D, 0x58, 0x2C, 0xB9, 0x40, 0xCB, 0x64, 0xFB, 0x59, 0x1E, 0xE8, 0xBD
+ , 0xBF, 0x64, 0x3F, 0x58, 0x76, 0xAE, 0xC2, 0xDF, 0x9A, 0x57, 0x69, 0xBB, 0x6C, 0xA0, 0x54, 0x0B
+ , 0xCA, 0xCA, 0x6A, 0xB6, 0xA3, 0x79, 0x54, 0x48, 0x71, 0x67, 0x40, 0x3B, 0x8E, 0x59, 0x94, 0xFB
+ , 0x31, 0xA6, 0xEE, 0xAF, 0x53, 0xC9, 0x24, 0xD6, 0x77, 0x4C, 0xE5, 0x34, 0xAD, 0x93, 0xD5, 0xCA
+ , 0x24, 0x61, 0x09, 0x66, 0x42, 0x65, 0x27, 0x7B, 0x1D, 0x3C, 0x35, 0x06, 0xB9, 0xA9, 0x13, 0xE0
+ , 0x9C, 0x08, 0xEC, 0x53, 0xB7, 0xAC, 0x71, 0x89, 0x2D, 0xEE, 0x34, 0xAE, 0x3E, 0x1D, 0x47, 0xDE
+ , 0x42, 0x17, 0xBA, 0xB8, 0x83, 0x96, 0xE5, 0x91, 0x39, 0x7D, 0xBA, 0x6E, 0x51, 0x6A, 0x48, 0xC3
+ , 0x4A, 0x9B, 0x12, 0x48, 0xA4, 0x5D, 0xD4, 0x29, 0xCA, 0x42, 0xC3, 0x75, 0xFE, 0xD9, 0xA1, 0x95
+ , 0xD6, 0xE3, 0xB9, 0x24, 0xC2, 0xD5, 0x5F, 0xF7, 0xBF, 0xB8, 0x93, 0x68, 0xCA, 0xCD, 0xF3, 0x4D
+ , 0xBA, 0x07, 0x63, 0xA6, 0x9D, 0xB1, 0x4D, 0x10, 0xF9, 0x61, 0xFB, 0x8C, 0x10, 0x27, 0x93, 0xEA
+ , 0x4A, 0x8A, 0x61, 0x87, 0x6E, 0x16, 0x46, 0xD3, 0x14, 0xD3, 0x39, 0x9E, 0x0B, 0xB4, 0xE4, 0x10
+ , 0xDE, 0x07, 0xE4, 0x69, 0x4F, 0xC2, 0x20, 0x09, 0x2B, 0x68, 0x4F, 0x9E, 0xF6, 0xD8, 0xCA, 0x9E
+ , 0x8A, 0xBD, 0x1B, 0x4B, 0xC1, 0x3C, 0x0B, 0x4D, 0xB9, 0x3A, 0x48, 0x03, 0xBA, 0xB3, 0xD4, 0xDF
+ , 0x7A, 0x93, 0x5D, 0x4D, 0x8A, 0xE7, 0x42, 0xF6, 0x73, 0x45, 0x1F, 0x36, 0xB6, 0xE0, 0xCB, 0xF6
+ , 0x22, 0xE5, 0x5B, 0x64, 0x8B, 0x51, 0xB1, 0x55, 0xC6, 0x2A, 0xD0, 0xB6, 0xAB, 0x48, 0xDA, 0x66
+ , 0xDF, 0xFD, 0xAF, 0x76, 0x47, 0x49, 0x03, 0x69, 0xB8, 0xF6, 0x05, 0x08, 0x40, 0x00, 0xFB, 0xF5
+ , 0xB7, 0x65, 0x15, 0xD1, 0xCB, 0xD0, 0x0E, 0xFB, 0x9A, 0x38, 0xAF, 0x76, 0x23, 0x2D, 0x51, 0x3A
+ , 0xFF, 0x5E, 0x56, 0xB9, 0x25, 0xD1, 0xCB, 0x94, 0xD0, 0x05, 0x92, 0x1D, 0xED, 0xCB, 0x70, 0xA6
+ , 0x6B, 0x0F, 0x41, 0x41, 0x8B, 0x3F, 0x3E, 0xA7, 0x5B, 0x73, 0xD1, 0xE8, 0x62, 0x56, 0x73, 0x64
+ , 0xB4, 0x4D, 0xF8, 0x99, 0x79, 0x39, 0xC1, 0xCD, 0xA0, 0xCA, 0x06, 0xF3, 0xF4, 0xCD, 0x66, 0x56
+ , 0x75, 0xE8, 0x21, 0xF6, 0x9A, 0xE3, 0xB1, 0x2B, 0x5B, 0x0F, 0x9F, 0xDE, 0x7A, 0xA5, 0xD1, 0x3C
+ , 0xE1, 0x11, 0x41, 0x8C, 0xCB, 0x9D, 0x25, 0x09, 0x4F, 0x2E, 0x83, 0x62, 0x9E, 0xCD, 0x77, 0x79
+ , 0x82, 0x4C, 0xB0, 0xEA, 0x02, 0xE3, 0x66, 0x9D, 0x10, 0x13, 0x75, 0x8E, 0xEF, 0x82, 0x6F, 0xDA
+ , 0xB4, 0xD6, 0x37, 0xD7, 0x6A, 0x26, 0x72, 0x62, 0x8F, 0x2D, 0xBD, 0xED, 0x23, 0xFE, 0xC4, 0xCE
+ , 0x5E, 0x1E, 0x5B, 0xDF, 0xF1, 0xFD, 0x50, 0x71, 0xD9, 0xAF, 0xE9, 0xCB, 0x07, 0xAA, 0x7C, 0xC6
+ , 0x34, 0x1A, 0x8A, 0x85, 0x25, 0x16, 0x1D, 0x55, 0x96, 0x5C, 0x8B, 0xA0, 0x6B, 0x54, 0xC5, 0x98
+ , 0x80, 0x98, 0x4D, 0x45, 0x6A, 0x96, 0x3C, 0x1A, 0x1C, 0x8D, 0x8B, 0xB8, 0x6D, 0x91, 0x6B, 0x30
+ , 0xEF, 0x11, 0x6D, 0x25, 0x84, 0x82, 0x9C, 0xD7, 0x6A, 0x18, 0x89, 0xCA, 0x88, 0xEA, 0x6F, 0x56
+ , 0xBE, 0x82, 0x03, 0xC0, 0xA3, 0xBB, 0x22, 0xAA, 0x9E, 0x99, 0x7D, 0x9D, 0x1C, 0x06, 0x8E, 0x0C
+ , 0x14, 0x0A, 0xC9, 0x18, 0x2D, 0x18, 0x8A, 0x3B, 0xC3, 0x88, 0x07, 0x19, 0x54, 0xD3, 0x2D, 0xC2
+ , 0x64, 0x2B, 0x97, 0xB5, 0xED, 0x71, 0x19, 0xAA, 0xED, 0x34, 0xEC, 0xF9, 0xEE, 0x89, 0x33, 0x19
+ , 0x2C, 0x33, 0x9D, 0xA7, 0x85, 0x98, 0x94, 0x3B, 0xE1, 0x5C, 0x5E, 0x53, 0x7F, 0x4A, 0x6B, 0xC4
+ , 0x48, 0xF4, 0xBC, 0x44, 0x93, 0x78, 0xC8, 0xC0, 0xE3, 0xD9, 0x48, 0x59, 0xDE, 0xB5, 0xE8, 0x8F
+ , 0xB1, 0x61, 0x4B, 0x67, 0xE6, 0x99, 0x47, 0x3E, 0x9A, 0xB7, 0x4D, 0x5C, 0x46, 0x0B, 0x4D, 0x5E
+ , 0xDF, 0xE8, 0xB9, 0x2B, 0xC9, 0xF8, 0xD3, 0x87, 0x4F, 0xA2, 0x3D, 0x2E, 0x2A, 0x22, 0x2B, 0x4B
+ , 0x23, 0x55, 0x7F, 0x0D, 0x0C, 0x20, 0xF4, 0x43, 0xCB, 0xF2, 0x31, 0x18, 0xD8, 0xC3, 0x0F, 0x0D
+ , 0xF5, 0xEB, 0x70, 0xCD, 0xB0, 0xD0, 0xBA, 0x2A, 0x37, 0xFD, 0x24, 0x5A, 0xF6, 0x69, 0x1A, 0x38
+ , 0x22, 0x49, 0xBC, 0xCE, 0x00, 0xCB, 0x6A, 0x2F, 0x6E, 0x98, 0x20, 0xDB, 0xE5, 0x8C, 0x0A, 0x0B
+ , 0x5E, 0x99, 0x8D, 0xAB, 0x9B, 0xD3, 0x4B, 0x12, 0xBE, 0x35, 0x75, 0x95, 0xE7, 0xA4, 0xAA, 0xC5
+ , 0x79, 0xB7, 0x9A, 0xB8, 0x3B, 0x86, 0x29, 0x15, 0xE5, 0x40, 0xE4, 0xC2, 0x85, 0xC2, 0x1B, 0xB5
+ , 0x06, 0xAF, 0x05, 0x49, 0xAD, 0x8B, 0xCE, 0xAD, 0xCD, 0x91, 0xE5, 0xA8, 0x0F, 0x97, 0x7F, 0x1C
+ , 0x42, 0x73, 0xAB, 0x1E, 0x5A, 0xEC, 0xA1, 0x31, 0x06, 0x6C, 0x80, 0x06, 0xE8, 0x03, 0x73, 0x4B
+ , 0x45, 0x48, 0x46, 0x09, 0xE0, 0x7D, 0x6F, 0xD9, 0xCD, 0x66, 0xF6, 0x0F, 0xEC, 0x01, 0xE7, 0x84
+ , 0xD9, 0xF0, 0x86, 0xF0, 0x5A, 0xE9, 0x10, 0xE4, 0xDC, 0x49, 0x03, 0xF4, 0x6C, 0x3B, 0xE4, 0xC3
+ , 0x3B, 0xAE, 0x39, 0x77, 0xB1, 0x3E, 0x9F, 0x03, 0x4A, 0x09, 0xDA, 0xD8, 0xE0, 0x60, 0x2D, 0x3C
+ , 0x77, 0x98, 0xC6, 0x36, 0xFB, 0x63, 0xD6, 0x4B, 0x99, 0xDB, 0x1F, 0x5B, 0xD2, 0x75, 0x21, 0xA2
+ , 0x8E, 0xDD, 0x8F, 0x25, 0x38, 0x1E, 0xDE, 0xBA, 0x89, 0xB9, 0x58, 0x77, 0x7F, 0x6E, 0x7C, 0xA4
+ , 0xD9, 0xA1, 0x4E, 0xF2, 0x9F, 0x77, 0x84, 0x09, 0x19, 0xEE, 0xBA, 0xB1, 0x73, 0x66, 0x35, 0xBD
+ , 0x4B, 0x2A, 0x0F, 0x21, 0x08, 0x5B, 0xF2, 0xBA, 0x7C, 0xC3, 0xE6, 0xAF, 0xF0, 0x44, 0xDF, 0x10
+ , 0x0D, 0x60, 0x16, 0x2F, 0xE6, 0x8D, 0x9D, 0x15, 0xB6, 0x05, 0x6C, 0x63, 0x6B, 0xBE, 0x9D, 0x5E
+ , 0x7F, 0xBC, 0xFF, 0x38, 0xE4, 0x9E, 0xBA, 0x7A, 0xDB, 0x36, 0x87, 0x0C, 0x7D, 0x69, 0x45, 0xD6
+ , 0xFA, 0x1B, 0xA0, 0x8D, 0xFD, 0xC4, 0xC8, 0xD6, 0x01, 0xE6, 0xB3, 0x87, 0xAC, 0xD3, 0xE5, 0xDC
+ , 0x88, 0x43, 0x81, 0x89, 0x04, 0x2B, 0x43, 0x54, 0x77, 0x5D, 0x7E, 0x27, 0xF2, 0x3E, 0x02, 0xA4
+ , 0xAC, 0x9B, 0x0F, 0xCB, 0x54, 0xD7, 0xA9, 0xE4, 0x2E, 0x08, 0x9A, 0x69, 0x28, 0x89, 0x4B, 0xF4
+ , 0x19, 0x97, 0x5A, 0xB3, 0x56, 0xCD, 0xB7, 0x2C, 0x4A, 0xD5, 0xA1, 0x52, 0xF3, 0x7A, 0xB0, 0x71
+ , 0x3A, 0xA2, 0x09, 0x01, 0x80, 0x54, 0x58, 0x61, 0x4C, 0xE5, 0x0F, 0x08, 0x1E, 0x47, 0xB6, 0x43
+ , 0xC0, 0x88, 0x4A, 0xBD, 0xAB, 0x65, 0xCB, 0x32, 0x5C, 0xAA, 0x69, 0x9A, 0x42, 0x8E, 0x46, 0xB9
+ , 0x64, 0x5C, 0x9A, 0x1F, 0xF8, 0xD6, 0x47, 0xC5, 0x49, 0x17, 0x17, 0x95, 0xAE, 0x8F, 0x9C, 0xC3
+ , 0xC6, 0x9F, 0xAE, 0x3F, 0x72, 0x13, 0x72, 0xED, 0xD9, 0x35, 0x20, 0x6E, 0xAA, 0x8E, 0xAA, 0x58
+ , 0x0A, 0xB2, 0x5C, 0x97, 0xA5, 0x44, 0xF9, 0x73, 0x43, 0x59, 0x8E, 0xD6, 0x05, 0x8A, 0x13, 0x79
+ , 0xBC, 0xAA, 0x37, 0x60, 0x7B, 0xFA, 0xA1, 0x36, 0x14, 0x5D, 0xC9, 0xB3, 0x88, 0x92, 0x80, 0x59
+ , 0xD7, 0x19, 0x6C, 0xC4, 0x4B, 0x4F, 0xC2, 0x6E, 0x1D, 0x8D, 0x8B, 0x04, 0x28, 0x28, 0x85, 0x15
+ , 0x86, 0xEB, 0xD5, 0x3E, 0x39, 0x48, 0xDE, 0xF7, 0x1D, 0x59, 0xF9, 0x06, 0x77, 0xFD, 0x57, 0x5D
+ , 0x66, 0x26, 0x10, 0x6D, 0x6B, 0xF7, 0xD5, 0x47, 0xBD, 0xCA, 0xF4, 0x3E, 0xBF, 0x01, 0x49, 0xBC
+ , 0xE7, 0xF1, 0x24, 0xAE, 0x00, 0x55, 0x9B, 0xF1, 0x49, 0xAB, 0x4C, 0x50, 0x25, 0x11, 0x0E, 0x56
+ , 0x51, 0x22, 0xD4, 0x52, 0xE2, 0x9E, 0x7F, 0x08, 0xB0, 0xD0, 0x33, 0xC1, 0x22, 0xD1, 0x54, 0xCA
+ , 0x90, 0x7A, 0x22, 0x66, 0x8C, 0x28, 0xAF, 0x2D, 0x47, 0x7B, 0x8A, 0x11, 0xC5, 0x5D, 0x96, 0x66
+ , 0x3A, 0x7B, 0x4B, 0x67, 0xA8, 0x30, 0x09, 0x5A, 0x06, 0xE0, 0xA8, 0xB3, 0xDB, 0x02, 0x21, 0x46
+ , 0xCF, 0x60, 0x27, 0x19, 0x76, 0x58, 0x35, 0xBB, 0x8E, 0x0C, 0x09, 0x63, 0xD4, 0x40, 0x49, 0xF9
+ , 0xC6, 0xA0, 0xA1, 0xFF, 0xAE, 0x36, 0xC8, 0x71, 0x7E, 0x82, 0xF9, 0xDC, 0x52, 0x10, 0x26, 0xF3
+ , 0xF7, 0x1C, 0x66, 0xAC, 0x21, 0x2C, 0x5F, 0x9E, 0x69, 0xAF, 0xEA, 0x90, 0x34, 0x44, 0x01, 0x42
+ , 0xBB, 0x7B, 0x57, 0x53, 0x2D, 0x26, 0x58, 0x60, 0x0A, 0x9E, 0xF5, 0x30, 0xF9, 0x8D, 0x08, 0x86
+ , 0x32, 0x43, 0x4D, 0x85, 0xE0, 0x07, 0x54, 0x78, 0x49, 0x00, 0x40, 0x2B, 0x60, 0x18, 0x3A, 0x2A
+ , 0xD6, 0xBE, 0x1B, 0x9E, 0x8F, 0x01, 0x92, 0x43, 0x1A, 0x1D, 0xDB, 0xB0, 0x06, 0xC4, 0x8A, 0x06
+ , 0x49, 0x10, 0x9F, 0x85, 0x42, 0x12, 0x41, 0xE8, 0xDA, 0xF5, 0x73, 0x47, 0x58, 0xCF, 0x6D, 0x14
+ , 0x0C, 0x1E, 0x9A, 0x20, 0x8B, 0x81, 0x36, 0xFD, 0x0D, 0xAC, 0x6A, 0x00, 0xAD, 0x52, 0xB7, 0x7A
+ , 0x91, 0x64, 0x78, 0xD7, 0xDB, 0x7F, 0x9B, 0x31, 0xE1, 0xCB, 0x22, 0xD1, 0xD3, 0x41, 0xF5, 0xCE
+ , 0x06, 0xCD, 0x13, 0x1E, 0x52, 0x39, 0x3B, 0xFD, 0x9F, 0x16, 0x1F, 0x7D, 0x60, 0x21, 0x28, 0x29
+ , 0x10, 0x62, 0xB0, 0xE5, 0x9F, 0x43, 0x76, 0x92, 0x38, 0x5C, 0xE9, 0x31, 0x62, 0xD2, 0x24, 0x52
+ , 0x70, 0xD4, 0xBA, 0x05, 0x6F, 0x17, 0x7A, 0x43, 0x09, 0xD9, 0x57, 0x67, 0x3C, 0x8F, 0x88, 0xE8
+ , 0x22, 0x23, 0xAD, 0x68, 0x61, 0xCC, 0x8C, 0xF3, 0x94, 0x6F, 0x1C, 0x40, 0x38, 0xA9, 0x5A, 0xA5
+ , 0xD5, 0x79, 0x2C, 0xDB, 0x21, 0x32, 0x5F, 0x11, 0xC4, 0x8F, 0xC2, 0x70, 0x41, 0x93, 0xF4, 0x91
+ , 0xF8, 0xF5, 0xC5, 0x92, 0x05, 0xAA, 0xF7, 0x82, 0xB9, 0xD9, 0x7C, 0x5F, 0xE9, 0x62, 0xAB, 0x52
+ , 0xDD, 0x98, 0xF1, 0xAE, 0x0B, 0x1C, 0x8F, 0x81, 0x22, 0xDF, 0x69, 0xBA, 0xFA, 0x51, 0xB5, 0xFC
+ , 0x46, 0x1C, 0xCC, 0xA2, 0xDD, 0xD9, 0x12, 0xC5, 0xCC, 0xB6, 0xC7, 0x03, 0x57, 0x57, 0xEE, 0x5D
+ , 0x66, 0x4A, 0xB6, 0x7B, 0x07, 0x9E, 0x2A, 0x1F, 0x06, 0x00, 0x9E, 0xC5, 0x9C, 0xC2, 0x70, 0x24
+ , 0xE0, 0x8C, 0xF7, 0x13, 0x69, 0x93, 0x91, 0x39, 0x69, 0xFC, 0x47, 0xD6, 0xA0, 0xCE, 0xAA, 0xA6
+ , 0xC9, 0x04, 0xDF, 0xA9, 0x60, 0x5A, 0x96, 0xA1, 0x2C, 0xC6, 0x2A, 0xA7, 0xE5, 0x65, 0x4D, 0xA9
+ , 0x76, 0x0C, 0x6B, 0xBB, 0xAE, 0xB9, 0x58, 0x4F, 0x48, 0xE6, 0xD5, 0xDB, 0x04, 0x02, 0x2C, 0x50
+ , 0xF6, 0xE3, 0x95, 0xCC, 0xDB, 0x4D, 0x67, 0xCB, 0xED, 0x1D, 0xEC, 0x81, 0x68, 0x69, 0x2E, 0xCD
+ , 0x9A, 0x1F, 0xF6, 0x72, 0x53, 0x86, 0xBE, 0x73, 0x5F, 0xBE, 0x0E, 0x8E, 0x51, 0x06, 0xD4, 0xA5
+ , 0x27, 0x3E, 0xEE, 0x6B, 0x3B, 0x07, 0xE6, 0xF2, 0x29, 0xA2, 0x83, 0x28, 0xA9, 0x81, 0x0C, 0xE5
+ , 0x5F, 0xB6, 0x18, 0x35, 0x70, 0x45, 0x82, 0xC2, 0xEC, 0x65, 0x88, 0xD7, 0x05, 0xEE, 0x30, 0xA8
+ , 0x3D, 0x3D, 0xAB, 0x3E, 0x7A, 0x3A, 0x1B, 0x5A, 0xC4, 0xD1, 0xF8, 0x3B, 0xB8, 0x8F, 0xB2, 0x20
+ , 0xF9, 0xB4, 0x0F, 0xED, 0xB4, 0x83, 0x62, 0x85, 0x33, 0xBF, 0xE6, 0x21, 0xE3, 0x32, 0x1B, 0x24
+ , 0xD8, 0x48, 0x62, 0x1B, 0x9C, 0xDD, 0x77, 0xFC, 0x6B, 0x4C, 0x76, 0x2A, 0x74, 0xB8, 0x9C, 0x57
+ , 0x72, 0x64, 0x47, 0xF5, 0x14, 0x45, 0xC1, 0x62, 0xD5, 0x21, 0xC4, 0x91, 0x85, 0xCC, 0x61, 0xE4
+ , 0x69, 0x92, 0x7D, 0x20, 0x9A, 0x60, 0x76, 0xEC, 0x07, 0x58, 0xD6, 0xB9, 0x0A, 0xCF, 0x64, 0x33
+ , 0x28, 0x99, 0x93, 0xDE, 0x5A, 0x94, 0x6B, 0x25, 0x82, 0x77, 0x04, 0x4F, 0xFD, 0x02, 0x87, 0xD1
+ , 0x41, 0x60, 0x3B, 0xDA, 0xF6, 0x30, 0x65, 0xE9, 0x53, 0xA8, 0xB8, 0xBB, 0xBE, 0x54, 0x97, 0x74
+ , 0x15, 0x3D, 0xAD, 0x21, 0x01, 0xA0, 0xC5, 0x1C, 0x05, 0x6B, 0x55, 0x35, 0x81, 0x25, 0xFA, 0x81
+ , 0x64, 0x94, 0xBD, 0xA5, 0xE9, 0x0F, 0xFC, 0xF2, 0x40, 0xA9, 0x20, 0xE1, 0x2C, 0xCC, 0x7A, 0xC7
+ , 0xA4, 0x18, 0x6E, 0xCD, 0xDE, 0xFD, 0x17, 0xEE, 0xF9, 0x39, 0x10, 0x04, 0x9D, 0xDF, 0xBB, 0x72
+ , 0x37, 0x5D, 0xBC, 0xF8, 0xE3, 0x59, 0x73, 0x40, 0x00, 0xC2, 0x28, 0x96, 0x41, 0x10, 0x34, 0x4D
+ , 0x9C, 0x2C, 0x75, 0x5A, 0xF8, 0x24, 0x8E, 0x75, 0x0B, 0xD3, 0x72, 0x88, 0x91, 0x70, 0x7A, 0xCA
+ , 0x74, 0x0F, 0x7F, 0xAD, 0x38, 0xE7, 0x27, 0xB9, 0x42, 0xA3, 0xA4, 0xDA, 0x7A, 0xFA, 0xE9, 0x15
+ , 0xC6, 0xA2, 0x6E, 0xFE, 0x8F, 0xD6, 0x99, 0xBC, 0x29, 0x77, 0xC5, 0x16, 0x25, 0x00, 0x2A, 0x94
+ , 0xB1, 0x6C, 0x3B, 0x59, 0xEC, 0xE9, 0x14, 0x0D, 0xD3, 0xFA, 0x50, 0xF8, 0x7C, 0x2C, 0x43, 0xA1
+ , 0x9D, 0x16, 0xCF, 0x00, 0x7E, 0xD4, 0x6E, 0xB4, 0x8E, 0xEA, 0x88, 0x37, 0x13, 0xC5, 0x84, 0xD9
+ , 0x5D, 0x77, 0xC8, 0x3C, 0x2B, 0x43, 0x04, 0x83, 0x61, 0xE8, 0x8A, 0x76, 0xAC, 0x68, 0xC4, 0xF8
+ , 0x7B, 0xB5, 0xF8, 0x02, 0x2A, 0x8A, 0xD7, 0xD2, 0x60, 0x22, 0x64, 0x5A, 0xDC, 0x0B, 0xA7, 0x49
+ , 0x18, 0x8F, 0xF5, 0x7C, 0xF5, 0x82, 0x3B, 0x6C, 0xC7, 0x2D, 0xD1, 0x4D, 0x48, 0x1B, 0x22, 0x88
+ , 0x31, 0x8A, 0x42, 0x66, 0x25, 0x67, 0x9A, 0xAF, 0xAE, 0x9C, 0x61, 0x10, 0x29, 0x9B, 0xE6, 0xB9
+ , 0xBD, 0xED, 0xD3, 0x80, 0x92, 0x2C, 0xAF, 0x19, 0x59, 0xDF, 0x54, 0x30, 0x87, 0x1A, 0x83, 0x73
+ , 0xEF, 0x86, 0x1D, 0xAC, 0xAB, 0x5A, 0x46, 0x66, 0x8B, 0xF9, 0x55, 0x79, 0xA7, 0x1F, 0x9E, 0x03
+ , 0x93, 0xF1, 0x55, 0xD0, 0x90, 0x7F, 0x46, 0x2A, 0x26, 0xD7, 0x72, 0xFF, 0x1C, 0x76, 0x45, 0x67
+ , 0x96, 0xAB, 0x75, 0xED, 0x83, 0x63, 0x17, 0x27, 0xA3, 0xB4, 0x01, 0x98, 0xE0, 0x70, 0x07, 0x4E
+ , 0xC2, 0x16, 0x0B, 0x20, 0x5B, 0xAD, 0x42, 0x31, 0xA2, 0x8A, 0x04, 0x58, 0xD5, 0x75, 0xF2, 0x2C
+ , 0x51, 0x87, 0xF3, 0xA3, 0x81, 0xD9, 0x06, 0x91, 0x7E, 0xE5, 0x13, 0x71, 0xAD, 0x61, 0x6D, 0x29
+ , 0xCB, 0xA5, 0x8A, 0x64, 0x3E, 0x92, 0xB0, 0x8C, 0x03, 0xCA, 0x2A, 0xDE, 0x36, 0x76, 0x2C, 0xB7
+ , 0x44, 0xCB, 0x8B, 0xFF, 0xCF, 0x23, 0xF3, 0xD9, 0x4F, 0xE2, 0x94, 0x2A, 0xE5, 0x69, 0x97, 0xD7
+ , 0xF2, 0xAC, 0x2D, 0x3B, 0x4C, 0xD6, 0x97, 0x72, 0xF7, 0x64, 0x13, 0x69, 0x47, 0x98, 0xE1, 0xCF
+ , 0x7A, 0xAB, 0xDF, 0x45, 0xBC, 0x0C, 0x1F, 0x56, 0x07, 0xA9, 0xD0, 0x5E, 0xF2, 0xC7, 0xDB, 0x9D
+ , 0x96, 0x16, 0x89, 0x24, 0x7D, 0xD1, 0x0A, 0x4F, 0x9D, 0x52, 0xFD, 0x87, 0x2B, 0xD9, 0x19, 0x74
+ , 0x05, 0x33, 0x53, 0xCB, 0x6F, 0x89, 0x6D, 0x41, 0x19, 0x4D, 0x24, 0xEF, 0x0A, 0xB4, 0x72, 0x6E
+ , 0xE3, 0x66, 0xE2, 0x15, 0x15, 0xDF, 0x02, 0x48, 0xCA, 0x1A, 0x0A, 0xCD, 0x1A, 0xE2, 0x3A, 0x94
+ , 0x86, 0x62, 0xBC, 0x15, 0xC1, 0xD5, 0x29, 0xC8, 0x05, 0xA5, 0x81, 0x35, 0xFA, 0x07, 0x10, 0x7B
+ , 0x13, 0xBA, 0x88, 0xD0, 0xF6, 0xDD, 0xC9, 0x0F, 0xFC, 0x0D, 0xA8, 0xB4, 0x1F, 0x45, 0x4B, 0x42
+ , 0xE8, 0x0D, 0x33, 0x3D, 0x83, 0x7E, 0x1E, 0x80, 0x3D, 0x68, 0xF9, 0xB3, 0x09, 0x08, 0x14, 0x0D
+ , 0x49, 0xBA, 0xC3, 0xEF, 0xA5, 0x8A, 0x0B, 0xF2, 0xB7, 0x4F, 0xFD, 0xB6, 0xDB, 0xB6, 0xE7, 0xC6
+ , 0xB8, 0xF1, 0x00, 0x83, 0x8A, 0xF5, 0x06, 0xB8, 0x29, 0x51, 0xAF, 0x23, 0x43, 0xA7, 0xD9, 0x71
+ , 0x13, 0x94, 0x2D, 0x90, 0xF0, 0xD4, 0xDC, 0x27, 0x89, 0xF6, 0xB0, 0x61, 0x5D, 0x0B, 0x84, 0xF8
+ , 0x53, 0x28, 0x67, 0x52, 0x3E, 0x00, 0xBB, 0x8F, 0x03, 0x8D, 0x48, 0x0F, 0xFD, 0x15, 0xEA, 0x70
+ , 0x69, 0x8A, 0xA2, 0x6B, 0xC8, 0xA3, 0xD5, 0x3A, 0xF7, 0x78, 0x60, 0x88, 0x96, 0x46, 0x1B, 0xAA
+ , 0x83, 0x92, 0x8E, 0xE6, 0xA0, 0x66, 0x83, 0x1B, 0xD5, 0x1C, 0xD4, 0xE9, 0x25, 0xA0, 0xF4, 0xE1
+ , 0x5C, 0x22, 0x7E, 0xDF, 0xFC, 0xB0, 0x9A, 0xBC, 0x25, 0x42, 0x31, 0xCE, 0xDC, 0xB7, 0xDD, 0x90
+ , 0xFE, 0x30, 0x75, 0x02, 0xBF, 0xA0, 0x24, 0x3F, 0xFB, 0xF0, 0xDA, 0x95, 0x7C, 0xCF, 0x9E, 0x0B
+ , 0xEA, 0x56, 0xD3, 0x55, 0xF8, 0x0D, 0x82, 0xCE, 0x73, 0x29, 0x0C, 0x36, 0xBF, 0xD0, 0x72, 0x0B
+ , 0x44, 0x00, 0x6C, 0x05, 0xA9, 0x31, 0xE7, 0x0C, 0xF0, 0x2E, 0x8F, 0x93, 0xAB, 0x5B, 0xCE, 0x13
+ , 0xAC, 0x4F, 0xBD, 0x14, 0x5D, 0x8B, 0x05, 0x78, 0x7E, 0x22, 0xF5, 0x22, 0xE2, 0xA8, 0x1E, 0x97
+ , 0x3D, 0xFB, 0x52, 0xB8, 0x76, 0x78, 0x8D, 0xA1, 0xFB, 0x48, 0x2D, 0xED, 0x5E, 0x08, 0xBA, 0xB7
+ , 0x83, 0x94, 0xF6, 0xC4, 0x18, 0x07, 0xD3, 0x57, 0xC8, 0xBB, 0x45, 0x28, 0xDC, 0xB4, 0x2F, 0xF8
+ , 0xC8, 0x7D, 0x48, 0xC3, 0xA0, 0x11, 0x60, 0x2F, 0x34, 0x06, 0xB0, 0xFA, 0xBC, 0xCA, 0x2C, 0x71
+ , 0x0F, 0x35, 0xF6, 0x73, 0xBF, 0x2D, 0xAF, 0x49, 0xB4, 0x45, 0x9A, 0x64, 0x32, 0xAA, 0x44, 0xA0
+ , 0x66, 0x37, 0x52, 0x0A, 0xE0, 0xB2, 0xA4, 0x1D, 0x10, 0x90, 0x08, 0x85, 0x24, 0x79, 0x3B, 0x3A
+ , 0xDD, 0x8F, 0x0C, 0x9F, 0x1E, 0xBD, 0x7F, 0xDF, 0x5E, 0xE7, 0x41, 0x73, 0x2D, 0xE5, 0xC7, 0xDC
+ , 0xD3, 0xC5, 0x8B, 0x2A, 0x76, 0x2E, 0x8F, 0x42, 0x80, 0x9E, 0xC8, 0xBA, 0x19, 0x5D, 0xC7, 0xD6
+ , 0x9E, 0x76, 0x55, 0xA0, 0x4B, 0xE3, 0x37, 0xBF, 0xE7, 0x36, 0xFC, 0xD8, 0xB4, 0xB5, 0x14, 0xA9
+ , 0xD5, 0x0D, 0xB2, 0xD6, 0x6A, 0x95, 0xD3, 0xD0, 0x35, 0x8C, 0xCA, 0x70, 0x02, 0xE4, 0x15, 0xD9
+ , 0x5C, 0x92, 0xE2, 0x6B, 0xAC, 0xED, 0xD4, 0x9E, 0x1A, 0x32, 0x59, 0x40, 0x09, 0xC4, 0xA5, 0xBF
+ , 0x04, 0xD5, 0x53, 0x56, 0x70, 0x7C, 0xAC, 0x13, 0xF4, 0xB6, 0xFB, 0xF8, 0xFE, 0x3F, 0x18, 0x69
+ , 0x2C, 0x02, 0x5E, 0xF8, 0x35, 0x94, 0xF7, 0xAE, 0x87, 0x9E, 0xB9, 0xAC, 0xE4, 0xF2, 0xFA, 0xEE
+ , 0x3E, 0x23, 0x73, 0xE1, 0x55, 0x1E, 0xBA, 0x98, 0xE9, 0xB2, 0x7D, 0x75, 0x92, 0x24, 0xAD, 0xB2
+ , 0xEB, 0x2D, 0x68, 0xDB, 0x0D, 0x5F, 0xE0, 0x3F, 0x71, 0x42, 0xFB, 0x0D, 0xD7, 0xA6, 0x2C, 0x47
+ , 0xAA, 0x5F, 0xE0, 0x32, 0x89, 0x7C, 0x59, 0xEC, 0x27, 0x45, 0xF6, 0x94, 0x84, 0x85, 0xDF, 0xE3
+ , 0x86, 0xDA, 0x08, 0x3C, 0xB9, 0x57, 0xEB, 0x62, 0x5F, 0x23, 0xC7, 0x85, 0x85, 0x5C, 0x0B, 0x34
+ , 0x60, 0x2A, 0x9B, 0x01, 0x6C, 0xD6, 0xFD, 0x61, 0x81, 0xD7, 0xB8, 0xCC, 0x61, 0xFB, 0x38, 0x9E
+ , 0xFD, 0x51, 0xA1, 0x80, 0xB8, 0xA0, 0x27, 0x9D, 0x92, 0xC2, 0xCC, 0xFC, 0x76, 0x1C, 0xF3, 0x7F
+ , 0x5A, 0xEF, 0xFA, 0x26, 0x90, 0x2A, 0xB2, 0x92, 0x48, 0xB1, 0xE5, 0x3A, 0x68, 0xF9, 0x26, 0x72
+ , 0x38, 0x2D, 0xA4, 0x23, 0xAE, 0xF7, 0x3B, 0xCC, 0x8C, 0xD3, 0xB0, 0x2E, 0xFF, 0x2C, 0xE0, 0xA1
+ , 0xF5, 0xD1, 0x37, 0x98, 0x63, 0x83, 0xF2, 0x63, 0xBA, 0x3A, 0xF8, 0x98, 0xEF, 0xF7, 0x56, 0x04
+ , 0x42, 0xB9, 0x3F, 0x06, 0xF9, 0xB7, 0x42, 0xA9, 0xB6, 0xFC, 0x1A, 0x01, 0x13, 0x12, 0x42, 0x60
+ , 0xF1, 0xE1, 0xBB, 0xBF, 0x2A, 0x29, 0x6D, 0xFA, 0x2B, 0x58, 0x7E, 0xA6, 0x36, 0x8F, 0x8E, 0xD0
+ , 0x7F, 0x56, 0xEE, 0xDF, 0x49, 0x3E, 0xD6, 0xA2, 0xF3, 0x54, 0x68, 0x7E, 0xB7, 0xD6, 0xDE, 0x90
+ , 0xA8, 0xD9, 0xB6, 0x76, 0xF9, 0x77, 0x05, 0x73, 0x80, 0x4B, 0xD0, 0xB4, 0x64, 0xE7, 0xE4, 0x6C
+ , 0x13, 0x4E, 0x21, 0x2D, 0x71, 0x5A, 0x8C, 0xDE, 0xC6, 0x3F, 0xD6, 0xDC, 0xB5, 0x41, 0x96, 0x92
+ , 0x0D, 0x99, 0x5C, 0x09, 0x92, 0x73, 0x90, 0x9F, 0xC3, 0x13, 0xD9, 0x74, 0x94, 0xF9, 0xB5, 0x92
+ , 0xFA, 0x1C, 0x8D, 0x4A, 0x69, 0x23, 0xA7, 0x16, 0x64, 0xA8, 0x11, 0x7E, 0x8B, 0x88, 0xD8, 0xD5
+ , 0xE3, 0x21, 0xDB, 0xCB, 0xE8, 0x23, 0x1A, 0xB7, 0x4C, 0x35, 0x60, 0xAF, 0xBF, 0x08, 0x82, 0x72
+ , 0x46, 0x95, 0xA7, 0x98, 0x5A, 0x3E, 0xC5, 0x69, 0x28, 0x1A, 0xD0, 0xA8, 0x77, 0x9C, 0x77, 0xC5
+ , 0xDF, 0x17, 0x76, 0x13, 0x67, 0x69, 0x9E, 0x88, 0x95, 0x28, 0x74, 0xCC, 0xEE, 0x79, 0xAF, 0x70
+ , 0x99, 0x01, 0xDC, 0xCF, 0xDB, 0xF2, 0x8B, 0xF0, 0x9F, 0x02, 0xE0, 0x3D, 0xCC, 0x19, 0x9B, 0x2A
+ , 0x20, 0x01, 0x4A, 0xAC, 0x0F, 0x77, 0xB8, 0x23, 0x00, 0x0E, 0x65, 0xCF, 0xA5, 0xCF, 0x8B, 0x27
+ , 0xDD, 0x18, 0x0A, 0x41, 0x78, 0xDE, 0x9D, 0x75, 0x21, 0xE9, 0xCF, 0x37, 0xC7, 0x53, 0x97, 0x3C
+ , 0x89, 0x09, 0x47, 0x21, 0xF1, 0x50, 0xB4, 0x2D, 0x83, 0xE7, 0xE2, 0xBB, 0x36, 0x0B, 0x2B, 0xAE
+ , 0x8C, 0xC0, 0xF9, 0x7A, 0x7D, 0x83, 0x7C, 0x9C, 0x1A, 0xB5, 0x23, 0xED, 0xC0, 0x1A, 0x51, 0x16
+ , 0xDD, 0xB3, 0xB2, 0x42, 0x11, 0x87, 0x2E, 0x2D, 0x66, 0x57, 0x6A, 0x3B, 0x96, 0x2D, 0x1C, 0x7E
+ , 0x0A, 0x73, 0x93, 0xCE, 0x9D, 0xD5, 0xB5, 0xEC, 0xC0, 0x29, 0x95, 0xD5, 0xF3, 0x36, 0x5B, 0x3A
+ , 0xA3, 0xF2, 0x3F, 0xF4, 0x22, 0x25, 0x81, 0xD5, 0x15, 0xBD, 0x04, 0xF5, 0x3B, 0x44, 0x2B, 0xFE
+ , 0x53, 0x84, 0xC6, 0xE3, 0xA1, 0x82, 0xFC, 0xC8, 0x61, 0x8C, 0x5F, 0xCC, 0x36, 0xDB, 0x90, 0x5A
+ , 0x50, 0x8A, 0x03, 0xAB, 0xBB, 0xFF, 0x27, 0x5E, 0xE9, 0x54, 0x12, 0x6F, 0x96, 0x72, 0xF8, 0xCE
+ , 0x21, 0xC5, 0xE6, 0x58, 0xA5, 0x23, 0xF8, 0x0D, 0x5E, 0x85, 0xC0, 0x6F, 0x61, 0x88, 0x3D, 0x23
+ , 0x0D, 0xAE, 0xAE, 0xCB, 0x41, 0x8F, 0x8F, 0xA1, 0xFC, 0xE6, 0x38, 0x70, 0xE6, 0xF7, 0x6E, 0x9E
+ , 0x50, 0x8A, 0x03, 0xAB, 0xBB, 0xFF, 0x27, 0x5E, 0xE9, 0x54, 0x12, 0x6F, 0x96, 0x72, 0xF8, 0xCE
+ , 0xF5, 0xD1, 0x91, 0xDF, 0x5A, 0x77, 0x10, 0xC1, 0x8C, 0xC7, 0xCB, 0x16, 0x95, 0x85, 0x26, 0x98
+ , 0x8C, 0x79, 0xD9, 0x1D, 0xB8, 0x29, 0xD4, 0xC9, 0x9C, 0x86, 0x9D, 0x5C, 0xE7, 0x72, 0x1D, 0xA0
+ , 0x9D, 0xC8, 0x25, 0x48, 0x2A, 0x19, 0x6B, 0xCD, 0xC6, 0x6A, 0xE3, 0xD4, 0x9B, 0xB3, 0x99, 0x9A
+ , 0x5E, 0xE9, 0x8E, 0x6B, 0xDD, 0x9B, 0xF1, 0x92, 0xDF, 0x39, 0x74, 0x4F, 0xDF, 0xFA, 0xA8, 0x98
+ , 0xBD, 0xA6, 0x1A, 0x4C, 0x44, 0x71, 0x39, 0x26, 0x40, 0xE0, 0xCD, 0xAA, 0xD1, 0x93, 0x36, 0x11
+ , 0xE8, 0xD8, 0x39, 0x7D, 0xF5, 0x96, 0xB6, 0x31, 0x8F, 0x0D, 0x2C, 0xD4, 0x35, 0xDA, 0x23, 0xE6
+ , 0x7A, 0x92, 0x00, 0x4B, 0xB5, 0x36, 0x1B, 0xA2, 0x4F, 0xFB, 0x41, 0xD4, 0x5E, 0x94, 0x93, 0x2F
+ , 0x6A, 0xE5, 0x36, 0xC8, 0xB0, 0x6C, 0x3E, 0xEC, 0x10, 0xA1, 0xD9, 0x0A, 0xD0, 0x1D, 0xD7, 0xAA
+ , 0x31, 0xE5, 0x00, 0xBD, 0x74, 0xBB, 0x12, 0x2D, 0x74, 0xA6, 0xAC, 0xC1, 0x2C, 0xCC, 0x7C, 0xF2
+ , 0x88, 0xAA, 0x4D, 0x3F, 0x0A, 0x22, 0xBA, 0x2E, 0x2B, 0x3B, 0x74, 0xBF, 0x53, 0xEF, 0xAE, 0x20
+ , 0xDD, 0x09, 0x5A, 0xB5, 0xDA, 0xB2, 0x1B, 0x04, 0x29, 0x5D, 0x75, 0xF4, 0x4A, 0x89, 0x70, 0xC2
+ , 0xB8, 0xF6, 0x64, 0x7A, 0x8A, 0x51, 0x5F, 0x05, 0x85, 0x52, 0x57, 0x0D, 0x7D, 0x9A, 0x0F, 0x3A
+ , 0x20, 0xD1, 0x83, 0x54, 0x38, 0x5B, 0xB5, 0x2B, 0x3B, 0x71, 0x24, 0xCE, 0x08, 0x9B, 0x4F, 0x38
+ , 0xCF, 0x92, 0x42, 0x66, 0x0C, 0x1C, 0x02, 0x29, 0x4C, 0x03, 0xF3, 0x87, 0x77, 0xB0, 0x88, 0xF7
+ , 0x2C, 0x51, 0x36, 0x3C, 0x1C, 0x2D, 0xE5, 0x6C, 0x90, 0x24, 0x2E, 0x69, 0x90, 0x6F, 0x96, 0x81
+ , 0x5B, 0x0D, 0x91, 0xBF, 0xC0, 0xFC, 0x2B, 0xBD, 0xF3, 0x77, 0x87, 0x45, 0x20, 0xB2, 0xEB, 0x56
+ , 0x87, 0x64, 0x6B, 0xA3, 0xDA, 0x7F, 0x6F, 0x2B, 0x8F, 0x72, 0xE5, 0xA2, 0xB5, 0x1B, 0xC8, 0x06
+ , 0xE1, 0xD9, 0x6C, 0xB3, 0x83, 0x2E, 0xB6, 0x25, 0xD7, 0x42, 0x7C, 0x57, 0x84, 0xA6, 0xDE, 0x3E
+ , 0xE5, 0x97, 0xCF, 0xA3, 0x60, 0x66, 0x3A, 0xB7, 0xD9, 0x0E, 0xCC, 0xB0, 0xBF, 0x56, 0x81, 0x4A
+ , 0xA4, 0x87, 0x50, 0x63, 0x1B, 0x94, 0xBE, 0x59, 0x86, 0x76, 0x20, 0xE5, 0xE4, 0x72, 0xF8, 0xCA
+ , 0xEC, 0xBD, 0x5F, 0x18, 0x4D, 0x9E, 0x25, 0xBB, 0xF0, 0xC9, 0xAA, 0x1A, 0xAF, 0xAF, 0x17, 0xAA
+ , 0x45, 0x46, 0x2F, 0xD6, 0xF2, 0xB8, 0xF5, 0x83, 0x17, 0xC6, 0xAC, 0xC6, 0x6B, 0x48, 0x49, 0xBA
+ , 0x2A, 0xB5, 0xDE, 0x4F, 0x07, 0x41, 0xD3, 0xE7, 0x03, 0x79, 0xA0, 0xCF, 0x4C, 0x6C, 0xB7, 0x4F
+ , 0x41, 0xDF, 0xEC, 0x14, 0xD0, 0x97, 0xF8, 0x93, 0x55, 0xA6, 0x2C, 0x13, 0x70, 0x5C, 0xE1, 0xDC
+ , 0x78, 0x39, 0x3C, 0x68, 0x53, 0xE6, 0x67, 0x5A, 0x57, 0xC6, 0xDE, 0x3F, 0x2D, 0x73, 0x25, 0x58
+ , 0xA8, 0x0B, 0xCA, 0xA0, 0xC9, 0xCF, 0xA2, 0x96, 0x02, 0xE4, 0x15, 0x66, 0xD1, 0x6A, 0x7C, 0x52
+ , 0xA9, 0x60, 0xAE, 0xBF, 0x06, 0xB3, 0x3E, 0xB2, 0x3E, 0x07, 0x33, 0xCC, 0xD5, 0xB3, 0xDA, 0xF1
+ , 0xB9, 0x1A, 0xD0, 0xB3, 0x1C, 0x3C, 0x28, 0xE2, 0x9B, 0x99, 0x83, 0xFF, 0xF2, 0xC3, 0xBC, 0xD1
+ , 0xB8, 0x44, 0x8E, 0xA7, 0xDC, 0x8E, 0x9D, 0x64, 0x1B, 0x15, 0x00, 0x01, 0xC2, 0x0B, 0x7A, 0x72
+ , 0x6F, 0xC5, 0xC7, 0xD1, 0x37, 0x3C, 0x23, 0x6E, 0x1F, 0x0D, 0xF2, 0xAF, 0x63, 0xBA, 0x6D, 0x3A
+ , 0x53, 0x29, 0x35, 0x3D, 0x9F, 0x76, 0x02, 0x20, 0x45, 0x73, 0x4C, 0xAA, 0x7E, 0x06, 0xD5, 0xE6
+ , 0xFC, 0x35, 0xFB, 0xC4, 0x2D, 0xEE, 0xDC, 0xD2, 0xE9, 0xAB, 0x8B, 0x73, 0x9C, 0xE1, 0xB0, 0x6D
+ , 0xD5, 0x59, 0xF2, 0xEE, 0x70, 0x3C, 0x4B, 0x93, 0x76, 0x4B, 0x64, 0x4E, 0xAA, 0x9E, 0xE4, 0x5C
+ , 0x87, 0xAC, 0x88, 0x68, 0x2A, 0x96, 0x8A, 0x18, 0xB2, 0x57, 0x31, 0x30, 0x87, 0x2F, 0x91, 0x29
+ , 0xDF, 0xA8, 0x41, 0x94, 0x3B, 0x22, 0xE8, 0x90, 0xAC, 0xC4, 0x58, 0x59, 0x9A, 0x0B, 0x51, 0x8D
+ , 0x14, 0xBE, 0xC4, 0x88, 0xD2, 0xA0, 0x6E, 0x5E, 0xDA, 0x74, 0xD7, 0x9D, 0xE5, 0xD9, 0x3B, 0x83
+ , 0x2E, 0x06, 0xB7, 0xB7, 0x98, 0x59, 0x28, 0x94, 0x1D, 0x75, 0x2A, 0x9A, 0x07, 0x07, 0xFD, 0xC1
+ , 0x2D, 0xB5, 0x29, 0x85, 0x87, 0x45, 0x06, 0xCF, 0xEE, 0x5C, 0x17, 0x65, 0x54, 0x21, 0xCE, 0x87
+ , 0x1A, 0xBF, 0x70, 0x2C, 0xFB, 0xC8, 0x9F, 0x44, 0xF3, 0xA2, 0x1D, 0xF2, 0x74, 0x85, 0x2E, 0x23
+ , 0xB8, 0x44, 0x8E, 0xA7, 0xDC, 0x8E, 0x9D, 0x64, 0x1B, 0x15, 0x00, 0x01, 0xC2, 0x0B, 0x7A, 0x72
+ , 0x20, 0xA3, 0x54, 0x5C, 0x23, 0x4D, 0xA3, 0x22, 0x82, 0x83, 0xFA, 0x09, 0xE2, 0xFD, 0x54, 0xE1
+ , 0x56, 0x74, 0xD6, 0x36, 0x45, 0xDB, 0x33, 0x2B, 0xFF, 0x5C, 0xBE, 0x4A, 0x44, 0x96, 0x9E, 0x4E
+ , 0x05, 0x8B, 0xAC, 0x07, 0x29, 0xFC, 0xBB, 0x48, 0x03, 0x2C, 0xC9, 0x95, 0x9C, 0x18, 0x10, 0x02
+ , 0x66, 0xC8, 0x8B, 0x2F, 0xA1, 0xCA, 0xB2, 0xAA, 0x3F, 0x89, 0x3A, 0xE5, 0x79, 0x7E, 0x94, 0x22
+ , 0x1E, 0xBF, 0x51, 0xBF, 0x84, 0x5D, 0x44, 0xB8, 0xFC, 0xB1, 0x8F, 0xC8, 0x2B, 0x42, 0x8F, 0xCF
+ , 0xFC, 0x35, 0xFB, 0xC4, 0x2D, 0xEE, 0xDC, 0xD2, 0xE9, 0xAB, 0x8B, 0x73, 0x9C, 0xE1, 0xB0, 0x6D
+ , 0xD9, 0x33, 0xA4, 0x6D, 0xC6, 0xF5, 0xB3, 0xA5, 0xE2, 0xD3, 0x52, 0xB6, 0x80, 0x83, 0xBF, 0xA7
+ , 0x87, 0x6A, 0xAB, 0xF9, 0xF8, 0x19, 0xB5, 0x54, 0x7B, 0xA5, 0x37, 0x80, 0xF5, 0x2C, 0x78, 0xF2
+ , 0xEA, 0x7E, 0x85, 0x88, 0x6B, 0x2C, 0x5D, 0x9F, 0xBC, 0x8E, 0xE2, 0x4B, 0x2D, 0x78, 0xC9, 0x60
+ , 0xA2, 0x84, 0x3B, 0x38, 0x8B, 0xEF, 0x34, 0x34, 0xBC, 0x62, 0x80, 0x38, 0x0B, 0xA6, 0x8C, 0x26
+ , 0x87, 0xAC, 0x88, 0x68, 0x2A, 0x96, 0x8A, 0x18, 0xB2, 0x57, 0x31, 0x30, 0x87, 0x2F, 0x91, 0x29
+ , 0xDF, 0xA8, 0x41, 0x94, 0x3B, 0x22, 0xE8, 0x90, 0xAC, 0xC4, 0x58, 0x59, 0x9A, 0x0B, 0x51, 0x8D
+ , 0x2E, 0x4F, 0x10, 0x15, 0x2C, 0xF3, 0xE7, 0x07, 0xF5, 0xA7, 0x21, 0xC5, 0xFC, 0x7D, 0x20, 0x76
+ , 0x73, 0x97, 0xB8, 0x79, 0x93, 0xA8, 0x89, 0xF0, 0xAD, 0x2B, 0x97, 0xD2, 0x2A, 0xA4, 0x2A, 0xCE
+ , 0xCE, 0xB8, 0x2C, 0x87, 0x3C, 0x37, 0x6A, 0xDB, 0xB0, 0x38, 0x2D, 0x67, 0xC2, 0x3C, 0x42, 0x7F
+ , 0xA3, 0x30, 0x9C, 0x98, 0x0D, 0xD8, 0x79, 0xF7, 0x34, 0x53, 0x9D, 0x97, 0xE3, 0x87, 0x62, 0x12
+ , 0xF5, 0x4E, 0xC4, 0xDF, 0xA5, 0x64, 0xFB, 0xC2, 0xDA, 0xAE, 0xEA, 0x26, 0x44, 0xC4, 0xCE, 0x39
+ , 0x36, 0x6C, 0x44, 0xD6, 0xE5, 0x73, 0x9D, 0x34, 0x48, 0xEB, 0x76, 0x0A, 0x19, 0x84, 0xD2, 0xD7
+ , 0x33, 0xC1, 0x17, 0x3E, 0xC7, 0xCB, 0xDF, 0x55, 0xEC, 0x41, 0x2E, 0x92, 0xC2, 0xE9, 0x20, 0xD8
+ , 0x63, 0xED, 0x96, 0xD8, 0x43, 0x7A, 0x9A, 0xE3, 0xFC, 0x4E, 0xD3, 0x5F, 0xD7, 0xBF, 0x46, 0x59
+ , 0x1F, 0x9E, 0xEB, 0xF7, 0x49, 0x9F, 0x50, 0x8B, 0xF1, 0x4E, 0x83, 0x30, 0x0F, 0x3D, 0x63, 0x5B
+ , 0x74, 0x8E, 0xCE, 0x94, 0xFB, 0x06, 0x54, 0x1B, 0x0B, 0x68, 0x7D, 0x13, 0xC8, 0x74, 0x89, 0xF7
+ , 0x68, 0xB8, 0x39, 0x73, 0x7F, 0xC1, 0x78, 0xA0, 0xB5, 0xC8, 0x4D, 0x65, 0xE1, 0x87, 0x3D, 0xF4
+ , 0x53, 0x3E, 0xA2, 0x35, 0xC7, 0x55, 0x99, 0x5A, 0xAB, 0xA2, 0x5E, 0xA8, 0x13, 0xE2, 0x9F, 0x12
+ , 0x4F, 0x76, 0xCE, 0xF4, 0x85, 0x10, 0xC7, 0xB8, 0xEB, 0xF9, 0xDD, 0x66, 0x31, 0x33, 0x38, 0x1C
+ , 0xE6, 0x87, 0x00, 0x44, 0x7E, 0x22, 0xF1, 0x8F, 0xF8, 0x8C, 0x73, 0xAF, 0x0C, 0x14, 0x3C, 0x54
+ , 0xB2, 0x97, 0x10, 0xEA, 0xBC, 0xD0, 0x7B, 0x1C, 0x33, 0x6B, 0x64, 0x56, 0x1C, 0xE5, 0x6D, 0xBE
+ , 0x3D, 0xA8, 0x8E, 0xA3, 0xCB, 0x20, 0xF0, 0xDA, 0xFB, 0xEE, 0xB8, 0x28, 0xDF, 0xB8, 0x35, 0xB7
+ , 0x62, 0x4F, 0xF1, 0xFE, 0xB6, 0xE2, 0x4D, 0xFD, 0x43, 0x32, 0xCC, 0x11, 0x8B, 0x9A, 0x21, 0x2C
+ , 0x8D, 0xBC, 0x6D, 0x91, 0xDB, 0x1B, 0x2E, 0x03, 0x41, 0xE6, 0xBA, 0x0B, 0x46, 0xD1, 0xE9, 0x9B
+ , 0xF6, 0x73, 0x0B, 0x2A, 0x6A, 0xA4, 0xAC, 0x90, 0x97, 0xEA, 0x7D, 0x35, 0xD8, 0x21, 0x9C, 0xCD
+ , 0x17, 0x2E, 0x17, 0x58, 0x97, 0x1B, 0x2C, 0xB4, 0x7E, 0x83, 0xB1, 0xDA, 0x49, 0x4D, 0x07, 0x6D
+ , 0x1E, 0x48, 0xC2, 0xDA, 0xF2, 0x06, 0x2A, 0x76, 0xE8, 0xD9, 0x37, 0x69, 0x17, 0x65, 0x74, 0x83
+ , 0xB8, 0xEA, 0x25, 0x53, 0xE1, 0xD2, 0x74, 0x81, 0x35, 0xD4, 0x71, 0x33, 0x2A, 0x6D, 0x57, 0x7E
+ , 0xF6, 0xE4, 0x13, 0xA2, 0x03, 0xF8, 0x97, 0x76, 0xE6, 0xBF, 0xB0, 0x97, 0xD3, 0xF6, 0x33, 0x34
+ , 0x8B, 0xB6, 0xD5, 0x29, 0xA4, 0x4E, 0xA5, 0xF9, 0xA6, 0x19, 0x42, 0x31, 0x56, 0x6E, 0x30, 0xC3
+ , 0xF7, 0x66, 0x70, 0x44, 0x0A, 0xC1, 0xF5, 0xF7, 0x18, 0xA9, 0xB6, 0xAB, 0x7A, 0x01, 0x6D, 0x3D
+ , 0xCF, 0xC1, 0x20, 0xD4, 0x50, 0x3D, 0xFB, 0xCB, 0x87, 0x53, 0x9D, 0x82, 0x38, 0x57, 0xE2, 0x8D
+ , 0x68, 0xDF, 0x78, 0xE5, 0x62, 0x58, 0x62, 0x92, 0x3E, 0xFD, 0x5E, 0xA8, 0x35, 0x80, 0x93, 0xC6
+ , 0x35, 0xF0, 0xA2, 0xA4, 0xBA, 0xAD, 0x7B, 0x72, 0x65, 0x75, 0xDA, 0x6F, 0x48, 0x91, 0x07, 0x70
+ , 0x0C, 0x19, 0x5E, 0xA5, 0x8B, 0x0C, 0x9C, 0x84, 0xB5, 0xBA, 0x2D, 0x22, 0x2D, 0xAD, 0xB7, 0x0D
+ , 0x56, 0xF0, 0x78, 0xA9, 0x75, 0x8E, 0x80, 0x96, 0x38, 0x9B, 0x30, 0xB8, 0xF0, 0xAE, 0xB2, 0xFD
+ , 0xA6, 0x82, 0x47, 0x13, 0x4C, 0xB5, 0xC5, 0x99, 0xFF, 0xF9, 0x49, 0xB2, 0x09, 0x92, 0xCC, 0xA1
+ , 0x3E, 0x3A, 0x17, 0x93, 0x4A, 0x45, 0x9A, 0xC0, 0x02, 0x52, 0x6A, 0x02, 0x19, 0x45, 0x94, 0x1C
+ , 0x73, 0xD6, 0x1E, 0x52, 0xFF, 0x66, 0x12, 0x56, 0x05, 0xA9, 0xBC, 0xC5, 0x10, 0x14, 0x8F, 0x95
+ , 0x08, 0x2D, 0x58, 0xC1, 0x34, 0x13, 0xDD, 0x93, 0x49, 0xC5, 0x73, 0x9D, 0x62, 0xC1, 0x4F, 0x24
+ , 0x20, 0x34, 0x7A, 0x6E, 0x82, 0xE9, 0xAA, 0x96, 0x6E, 0x90, 0xA1, 0x8E, 0xB8, 0x03, 0x8D, 0x68
+ , 0xFF, 0xA7, 0x47, 0xAB, 0xD0, 0x8D, 0x0C, 0xBF, 0xE0, 0x99, 0x40, 0xB8, 0x0C, 0xE7, 0x36, 0x94
+ , 0xA1, 0x55, 0x0C, 0x97, 0xBD, 0xCD, 0x28, 0x99, 0xB6, 0x99, 0xD4, 0x69, 0x2E, 0x62, 0x4B, 0x41
+ , 0x78, 0x57, 0x86, 0x16, 0xC4, 0xBC, 0x32, 0x8B, 0x02, 0xB1, 0x80, 0x7B, 0x27, 0x4A, 0x05, 0x43
+ , 0xC7, 0x94, 0x1F, 0xED, 0x07, 0xB0, 0x1C, 0x9E, 0x64, 0xEF, 0xED, 0x16, 0x1C, 0xC8, 0xB3, 0x55
+ , 0xF6, 0x78, 0x34, 0x9E, 0x6F, 0x37, 0x14, 0x1B, 0x4F, 0xE2, 0xDC, 0x1B, 0x77, 0xCE, 0x74, 0x1A
+ , 0x2E, 0x3C, 0x0F, 0xCF, 0x0A, 0xDC, 0x31, 0x92, 0x23, 0x5C, 0x4E, 0x46, 0xFC, 0x42, 0xF1, 0xA7
+ , 0x05, 0xFD, 0xB0, 0xFF, 0x32, 0xF6, 0xFB, 0xA6, 0x1F, 0x3D, 0x8C, 0x18, 0x38, 0x0F, 0x83, 0xFC
+ , 0xEB, 0xFD, 0x51, 0xB8, 0x73, 0x39, 0x7A, 0x88, 0x0F, 0x2E, 0xFA, 0xF7, 0x78, 0xA3, 0x1B, 0x39
+ , 0x49, 0xF6, 0xFB, 0xC4, 0xA6, 0x0C, 0x90, 0x31, 0x95, 0x06, 0x6F, 0x4F, 0x32, 0x0B, 0x85, 0xB2
+ , 0xF6, 0x40, 0x15, 0x1D, 0x96, 0xB6, 0x10, 0x93, 0x10, 0xFC, 0x84, 0x5D, 0xB1, 0xBA, 0xEE, 0x4A
+ , 0xBC, 0x25, 0x0B, 0xC7, 0x49, 0x42, 0x00, 0xF2, 0x74, 0xD6, 0x55, 0x82, 0x13, 0xF5, 0x3B, 0x03
+ , 0x0D, 0x7C, 0x51, 0xBF, 0xEA, 0xB7, 0x32, 0x4C, 0x46, 0xA3, 0x33, 0xE6, 0x5F, 0x12, 0x74, 0x78
+ , 0xBE, 0x61, 0xFE, 0x0E, 0x17, 0x00, 0x86, 0xDE, 0x57, 0x48, 0x29, 0xBB, 0xEF, 0xEE, 0x13, 0x0F
+ , 0xEE, 0xA0, 0x19, 0xB1, 0xD1, 0x22, 0xBB, 0x36, 0x5E, 0x49, 0x2A, 0x58, 0x4D, 0x05, 0x2B, 0x27
+ , 0xE0, 0x92, 0xE3, 0xDC, 0x58, 0x00, 0x29, 0x93, 0x78, 0xD8, 0xC6, 0xD3, 0xC7, 0x1B, 0x91, 0xFE
+ , 0x43, 0xC5, 0x61, 0x19, 0x94, 0x6A, 0xD2, 0x37, 0xF9, 0xFF, 0xF8, 0x5D, 0x6E, 0x94, 0x03, 0x2F
+ , 0x2F, 0xF9, 0xF8, 0xCA, 0xE5, 0x1C, 0xE8, 0xA8, 0x22, 0x33, 0xE7, 0xE1, 0x7F, 0xF0, 0x88, 0x34
+ , 0x45, 0x0C, 0x72, 0x27, 0xB4, 0x6F, 0x7B, 0x7D, 0x7E, 0xC6, 0xC2, 0x05, 0xD6, 0xBB, 0x81, 0xB6
+ , 0x8F, 0xFF, 0x25, 0xA5, 0x75, 0x13, 0x28, 0x2C, 0x13, 0x3C, 0x49, 0x59, 0x57, 0xF9, 0x04, 0x3A
+ , 0x65, 0x04, 0x28, 0x16, 0xF1, 0x19, 0x32, 0x08, 0x32, 0xDA, 0x35, 0x2C, 0xEC, 0x52, 0x31, 0x6F
+ , 0x67, 0xCD, 0xAF, 0xDB, 0x2E, 0xB1, 0xEA, 0x9A, 0x18, 0x59, 0x12, 0x0B, 0x46, 0xB6, 0x06, 0xDA
+ , 0x85, 0x89, 0xE6, 0xE9, 0x7A, 0xA7, 0x14, 0xBE, 0x0D, 0x0D, 0xA8, 0xAF, 0x21, 0x86, 0x64, 0x09
+ , 0xD4, 0xCE, 0x84, 0x93, 0xB8, 0x93, 0x55, 0x62, 0xB3, 0xA3, 0xA2, 0x0A, 0xCE, 0x23, 0x5F, 0xE4
+ , 0x45, 0xF7, 0xDA, 0x0F, 0x8A, 0x7A, 0x8D, 0x28, 0x02, 0xDB, 0xED, 0x5C, 0x1C, 0x49, 0xF9, 0x72
+ , 0x2A, 0xE3, 0x16, 0x61, 0xFF, 0xF4, 0xD7, 0x54, 0x50, 0x19, 0x50, 0xA8, 0x61, 0xFF, 0x59, 0xA9
+ , 0x96, 0x93, 0x75, 0x89, 0xA4, 0x0E, 0x8E, 0x67, 0x08, 0xC6, 0x98, 0x4C, 0xF9, 0xFF, 0x84, 0x7D
+ , 0x21, 0xD6, 0x48, 0xFA, 0x33, 0xF1, 0x52, 0x0C, 0x62, 0xEA, 0x80, 0xCB, 0xE1, 0xA0, 0x78, 0x04
+ , 0x2D, 0xF0, 0xEB, 0x20, 0xC9, 0x65, 0xDD, 0xB3, 0xAC, 0x8A, 0x14, 0x0F, 0xCB, 0x37, 0xF0, 0x4A
+ , 0xED, 0xCD, 0xA0, 0xA9, 0x9D, 0x28, 0x8C, 0xB8, 0xC7, 0x4A, 0xA5, 0x79, 0xE7, 0x3B, 0xC9, 0xBF
+ , 0x59, 0xA2, 0xFE, 0xD7, 0x71, 0x37, 0x71, 0x20, 0x90, 0xB6, 0xC2, 0x19, 0x1C, 0x9C, 0x5F, 0x69
+ , 0xF1, 0xF0, 0xE8, 0x64, 0x0F, 0x61, 0x53, 0x67, 0x49, 0x95, 0xEA, 0x76, 0x89, 0xED, 0x3D, 0x4F
+ , 0xC1, 0xE1, 0x77, 0x77, 0xEB, 0xAF, 0x7A, 0xFA, 0xBB, 0x15, 0xFB, 0xFA, 0xE5, 0x0B, 0xD6, 0xC4
+ , 0xB4, 0x7B, 0xC3, 0xA9, 0xE4, 0xDB, 0xEA, 0x40, 0xAC, 0x77, 0x08, 0xBB, 0xBD, 0xAC, 0x3D, 0x4C
+ , 0x3A, 0x92, 0x39, 0x27, 0xD1, 0xF0, 0xB0, 0x4A, 0xF3, 0xAC, 0x34, 0x4E, 0x4E, 0x45, 0xD8, 0x58
+ , 0x52, 0x7F, 0x1E, 0xFF, 0xAC, 0x36, 0xD3, 0x9C, 0xD0, 0xB3, 0x69, 0x89, 0x7E, 0x09, 0x72, 0xF6
+ , 0x67, 0xB4, 0x2C, 0xB6, 0xD3, 0xD5, 0x9A, 0xCF, 0x02, 0xBB, 0x7C, 0xFE, 0x31, 0xCF, 0xF6, 0x16
+ , 0x1B, 0xEC, 0xC7, 0x21, 0x0B, 0xA9, 0x2C, 0x09, 0xD6, 0x55, 0xEE, 0xF7, 0x0C, 0x57, 0x34, 0x04
+ , 0xE3, 0x7C, 0x5B, 0x0D, 0x09, 0x61, 0xEE, 0x5B, 0x71, 0xFB, 0xC9, 0x07, 0xB0, 0x02, 0xB0, 0xF7
+ , 0xA8, 0xD5, 0x23, 0x27, 0x5B, 0xB0, 0xC1, 0x14, 0x95, 0xA6, 0xB3, 0x9B, 0xDB, 0x20, 0xCD, 0xDE
+ , 0x21, 0x36, 0x22, 0xAE, 0xE5, 0x4F, 0x49, 0x02, 0xD2, 0x4E, 0xDC, 0x90, 0x7A, 0x5E, 0xF4, 0xAD
+ , 0xB6, 0xE7, 0xB3, 0x67, 0xDB, 0x26, 0x8C, 0xFF, 0x2F, 0x21, 0x59, 0xBF, 0x79, 0xDC, 0xAD, 0xD1
+ , 0xEE, 0xD6, 0xB2, 0x5F, 0x6C, 0x17, 0x48, 0x06, 0xFC, 0xC2, 0x0B, 0x0C, 0x26, 0x0A, 0x82, 0x1B
+ , 0xD3, 0xCC, 0x41, 0xAA, 0xA2, 0x8B, 0xCB, 0xB9, 0x91, 0x55, 0x3F, 0x5D, 0xA9, 0x69, 0xD0, 0xEC
+ , 0x50, 0xE7, 0x97, 0x71, 0x00, 0xD7, 0xC3, 0xF3, 0xBF, 0x24, 0x71, 0xEB, 0x53, 0x4E, 0x5F, 0xD1
+ , 0x66, 0x65, 0x0A, 0x61, 0xD5, 0x05, 0x91, 0xF8, 0x42, 0xC6, 0x90, 0x7F, 0xD9, 0xC2, 0xC3, 0x3E
+ , 0xEC, 0x9F, 0x27, 0xB9, 0xB2, 0xE3, 0xBD, 0xC9, 0x8A, 0x7A, 0x5D, 0x10, 0x7D, 0x98, 0xF5, 0x3D
+ , 0xAC, 0x69, 0x9E, 0x67, 0x79, 0xDA, 0xA9, 0x53, 0x8B, 0xDD, 0x18, 0xCD, 0xC5, 0x0F, 0x47, 0x71
+ , 0x22, 0x26, 0xFB, 0xB1, 0xB7, 0xB9, 0x87, 0x78, 0x00, 0x09, 0x90, 0x7C, 0x6A, 0x64, 0xD2, 0x2D
+ , 0x3D, 0x10, 0x4C, 0xA4, 0xF8, 0x8F, 0x61, 0x8F, 0xC8, 0x5F, 0x2E, 0xF8, 0x07, 0x17, 0x36, 0xC4
+ , 0xB2, 0x5D, 0xEE, 0x93, 0x54, 0x53, 0x52, 0x31, 0xC0, 0x7E, 0xDA, 0xFA, 0x79, 0x95, 0x49, 0xED
+ , 0x66, 0x6D, 0x31, 0xD5, 0x2C, 0xE9, 0xA1, 0x26, 0x0C, 0x47, 0x23, 0x42, 0x91, 0x3F, 0x14, 0x49
+ , 0x1A, 0xC5, 0xEF, 0x7D, 0x9E, 0x8D, 0x37, 0x53, 0x06, 0xA7, 0xF2, 0x88, 0x5B, 0x64, 0xD5, 0xD7
+ , 0xBD, 0x6A, 0x54, 0x2F, 0xA4, 0x56, 0x58, 0x0B, 0xCF, 0x65, 0x40, 0xBA, 0x37, 0x99, 0xCE, 0x88
+ , 0x64, 0x91, 0xCC, 0x8A, 0x7E, 0x4C, 0x8C, 0x47, 0xA2, 0xBD, 0x04, 0x05, 0xB8, 0xCC, 0x62, 0xCD
+ , 0x86, 0x15, 0x54, 0x83, 0x45, 0xC8, 0x07, 0xED, 0x69, 0xD3, 0xB4, 0x90, 0x6A, 0xCE, 0x1C, 0xAC
+ , 0x1C, 0x82, 0x93, 0xDF, 0xEC, 0xCB, 0x61, 0xBC, 0x83, 0xA5, 0x54, 0xB9, 0x35, 0xC3, 0x88, 0xE4
+ , 0x9F, 0xA8, 0x9F, 0xF1, 0x3C, 0x4F, 0x01, 0xED, 0xC9, 0x71, 0xF6, 0x7F, 0xD6, 0x8C, 0x4B, 0xBC
+ , 0x2A, 0x9F, 0x28, 0xF7, 0x9A, 0x16, 0x8A, 0x00, 0xD1, 0x8F, 0x2A, 0x22, 0x3D, 0xD6, 0x7B, 0xB8
+ , 0x3B, 0xA3, 0xAD, 0x71, 0x35, 0x1D, 0x72, 0xD3, 0xB7, 0xF1, 0x9A, 0x67, 0x19, 0x23, 0x1E, 0x1B
+ , 0x2C, 0x27, 0xEE, 0x34, 0xF9, 0x45, 0x67, 0xB5, 0x1D, 0x2A, 0x9C, 0xA6, 0x5E, 0x66, 0x8D, 0x62
+ , 0xB1, 0xEF, 0xB1, 0xD6, 0x5E, 0x2B, 0x91, 0x42, 0xB2, 0x8A, 0x74, 0x7B, 0x8B, 0xEF, 0xE2, 0x02
+ , 0x38, 0x82, 0x34, 0x5B, 0xBF, 0x95, 0x4F, 0xBB, 0x70, 0xDC, 0x49, 0x17, 0xAC, 0x73, 0xD0, 0x65
+ , 0x45, 0xA6, 0x22, 0xAF, 0x99, 0x76, 0x7A, 0xA8, 0x62, 0x40, 0x2F, 0xCF, 0x31, 0xCE, 0xDD, 0x74
+ , 0x4F, 0x8A, 0x36, 0x6F, 0xB3, 0x9B, 0xBA, 0x51, 0x41, 0x2F, 0x85, 0x50, 0x74, 0xD5, 0x66, 0x01
+ , 0x90, 0xED, 0x78, 0x4C, 0xC2, 0x03, 0x99, 0x59, 0x4B, 0x08, 0x26, 0x20, 0xC1, 0x6E, 0xF8, 0x41
+ , 0x94, 0x73, 0x22, 0xEF, 0xD6, 0xB6, 0x1F, 0x64, 0x72, 0xB4, 0xEA, 0x7A, 0xFE, 0xEB, 0xB8, 0x21
+ , 0xE5, 0x16, 0x43, 0xD8, 0x4B, 0xF9, 0x58, 0x8A, 0x50, 0x6E, 0x66, 0xF5, 0x60, 0x42, 0x4E, 0x74
+ , 0x49, 0xC3, 0xE5, 0xBB, 0xF8, 0x82, 0x35, 0xAE, 0x61, 0x03, 0xAF, 0x5A, 0xA3, 0x06, 0xDE, 0x60
+ , 0x66, 0xB3, 0xBC, 0x87, 0x98, 0xD3, 0xCF, 0x98, 0xF9, 0x34, 0x38, 0xC5, 0xF0, 0x52, 0xED, 0xA5
+ , 0x01, 0x66, 0xFF, 0x80, 0x40, 0x88, 0xE9, 0x10, 0x38, 0x5F, 0xDF, 0xB3, 0x95, 0x38, 0xFF, 0x40
+ , 0x22, 0xE5, 0x9B, 0xD8, 0xEA, 0xB5, 0x0B, 0x7C, 0x28, 0x18, 0xA1, 0x6B, 0xF7, 0x32, 0x7E, 0x20
+ , 0xDD, 0xFB, 0xA3, 0xCA, 0xE4, 0x2F, 0xB0, 0x3D, 0x7F, 0x7A, 0x46, 0xBF, 0x5D, 0x93, 0x54, 0xCD
+ , 0xC3, 0xFA, 0x1C, 0x3B, 0x19, 0xFC, 0xE9, 0xD8, 0xFB, 0xB2, 0xB4, 0x0C, 0xF6, 0x4F, 0xB6, 0x42
+ , 0x61, 0xD5, 0x99, 0xEC, 0x56, 0xCF, 0xF3, 0x74, 0xD6, 0xC5, 0x10, 0x65, 0x27, 0x81, 0xD0, 0x42
+ , 0x9D, 0xFC, 0x87, 0x07, 0xEA, 0x0C, 0x55, 0x8D, 0xBA, 0xE1, 0x72, 0x13, 0xBF, 0x4B, 0x4B, 0x26
+ , 0xE0, 0xE7, 0xEC, 0xD1, 0xDA, 0x7F, 0xFC, 0xF1, 0x06, 0x6A, 0x56, 0xC4, 0xDC, 0xB2, 0x63, 0xB5
+ , 0x75, 0xEE, 0xEC, 0xAC, 0x8C, 0xDC, 0x35, 0xE6, 0x73, 0x91, 0x36, 0x30, 0x76, 0x9C, 0x50, 0x30
+ , 0xF7, 0x63, 0xE1, 0xFC, 0xE1, 0x15, 0x85, 0x42, 0xDD, 0x19, 0xA2, 0x1B, 0x3D, 0xF7, 0x8A, 0xB9
+ , 0x93, 0x9F, 0x88, 0x07, 0x00, 0x09, 0x6B, 0xD9, 0x9B, 0xC1, 0x9C, 0x09, 0x45, 0xA9, 0x3C, 0x3E
+ , 0x4C, 0xC4, 0x4D, 0x24, 0x79, 0x1A, 0xE1, 0xAA, 0x9E, 0x46, 0x46, 0xF4, 0xA5, 0xF0, 0x74, 0xFE
+ , 0xB3, 0x3D, 0xF7, 0x3B, 0x02, 0xBA, 0x7C, 0x1C, 0x4D, 0xFB, 0x02, 0x0E, 0xFF, 0x89, 0xF9, 0xD9
+ , 0xEB, 0x4D, 0x53, 0x19, 0x32, 0x37, 0xBD, 0x75, 0x2E, 0xBC, 0x4A, 0x4C, 0x03, 0xB4, 0xE6, 0xE3
+ , 0x9A, 0xBE, 0xBD, 0x89, 0xEC, 0x0D, 0x38, 0xDA, 0x51, 0xC0, 0xC3, 0x5F, 0xFA, 0xEE, 0x2B, 0x35
+ , 0x49, 0xF2, 0x15, 0x2D, 0x93, 0x14, 0x59, 0xB6, 0x8E, 0x23, 0x80, 0xD7, 0xBF, 0x4B, 0xF2, 0xDD
+ , 0x44, 0x6A, 0x5F, 0x48, 0xA5, 0xC1, 0x6D, 0x4C, 0x2C, 0xB4, 0xF5, 0x02, 0x5C, 0x98, 0xE5, 0xD0
+ , 0x11, 0xF8, 0xEA, 0xB5, 0xC3, 0x47, 0x39, 0xAC, 0x68, 0xC0, 0x98, 0x3F, 0x1E, 0x51, 0xCB, 0xE1
+ , 0x88, 0x32, 0x45, 0x83, 0xD1, 0x62, 0x4D, 0xA3, 0x3F, 0x4A, 0xC7, 0xD6, 0x93, 0x6F, 0xE6, 0x47
+ , 0x4A, 0x82, 0x34, 0x6D, 0xE4, 0x67, 0x9E, 0xB0, 0x83, 0x36, 0x84, 0x4A, 0xE2, 0x7C, 0xD2, 0x6A
+ , 0x93, 0x9F, 0x88, 0x07, 0x00, 0x09, 0x6B, 0xD9, 0x9B, 0xC1, 0x9C, 0x09, 0x45, 0xA9, 0x3C, 0x3E
+ , 0x98, 0x67, 0xCC, 0x9D, 0xD4, 0x01, 0x40, 0x25, 0x02, 0x17, 0xC0, 0xCF, 0x51, 0xD1, 0x24, 0x31
+ , 0xAD, 0xAC, 0x92, 0x10, 0x75, 0xCB, 0x97, 0x05, 0x6C, 0xFE, 0x45, 0x4A, 0x03, 0xEA, 0xC6, 0x3C
+ , 0xB1, 0xBA, 0x46, 0x61, 0xB4, 0x59, 0x5D, 0x12, 0x89, 0xA6, 0x43, 0x2C, 0xEE, 0x2A, 0x15, 0x63
+ , 0x32, 0xC3, 0xEF, 0xBC, 0xAA, 0x12, 0x41, 0xC0, 0xD9, 0x3E, 0x18, 0x6D, 0x9B, 0x47, 0xE3, 0xEA
+ , 0x4F, 0x12, 0x6F, 0xCB, 0x7F, 0x03, 0x5B, 0x48, 0x19, 0x52, 0x7A, 0xE6, 0xAD, 0x16, 0xFD, 0xCA
+ , 0x79, 0x29, 0x4F, 0xC1, 0x3B, 0x78, 0x16, 0x66, 0x1A, 0x22, 0x92, 0x06, 0x23, 0xEC, 0x27, 0xDC
+ , 0x60, 0x61, 0x42, 0x6E, 0x9C, 0x63, 0x75, 0x17, 0x9A, 0x97, 0xC3, 0x09, 0x60, 0x59, 0xFC, 0x81
+ , 0x83, 0x96, 0xAA, 0x21, 0xD2, 0xF7, 0x26, 0x2E, 0xAF, 0xF4, 0xAA, 0x27, 0x82, 0x65, 0xD6, 0x44
+ , 0xD8, 0x73, 0x04, 0x9C, 0xF1, 0xFD, 0x5C, 0xD0, 0x38, 0xB5, 0xB0, 0xAF, 0xA7, 0x54, 0xD6, 0xC3
+ , 0xD0, 0xF8, 0xB8, 0x67, 0x19, 0xD3, 0x75, 0x91, 0x7B, 0x38, 0x3A, 0xD5, 0xF4, 0x38, 0x27, 0xBA
+ , 0x09, 0xEA, 0x44, 0xF6, 0x4E, 0xB0, 0xA1, 0xD0, 0x2D, 0x5D, 0x65, 0x80, 0x92, 0x86, 0x2F, 0x30
+ , 0x2B, 0x05, 0xC7, 0xDF, 0xB8, 0x13, 0x8C, 0xC2, 0x29, 0xF9, 0x18, 0x9B, 0x85, 0x1D, 0x29, 0xD3
+ , 0x4B, 0xF5, 0x05, 0xAA, 0x17, 0x72, 0x13, 0xEE, 0x32, 0x80, 0x1C, 0xF3, 0x07, 0x5A, 0x39, 0x9F
+ , 0xF4, 0xC6, 0x6A, 0xB6, 0x1F, 0xB4, 0x85, 0xF4, 0x7B, 0xE6, 0x18, 0xF5, 0x45, 0x10, 0x1B, 0x52
+ , 0xF3, 0xD2, 0x35, 0xD8, 0xFF, 0xE4, 0x48, 0x50, 0xA1, 0xA0, 0x4E, 0x06, 0xEA, 0x84, 0xCF, 0xF4
+ , 0xC7, 0x48, 0x64, 0xFF, 0x61, 0xFA, 0xDD, 0xA4, 0xAB, 0x25, 0xED, 0xCE, 0xF2, 0x0A, 0xE8, 0xAC
+ , 0xF7, 0xCE, 0x2B, 0x09, 0x1F, 0xF3, 0xF6, 0xE2, 0xA2, 0xB7, 0x9E, 0xED, 0xDF, 0x93, 0x0D, 0x23
+ , 0xEF, 0xCB, 0xA4, 0x16, 0x80, 0x22, 0x9B, 0x09, 0xAC, 0xDE, 0xE2, 0xD7, 0x93, 0x3E, 0x2D, 0x2F
+ , 0x2D, 0x3B, 0xA6, 0x9D, 0x37, 0x51, 0xAB, 0x90, 0x07, 0xF1, 0x1B, 0xD9, 0x5F, 0xDD, 0x16, 0x47
+ , 0x15, 0xFA, 0x3D, 0x2F, 0x05, 0x90, 0x07, 0xDD, 0x9C, 0xC2, 0x5D, 0x52, 0x60, 0xA4, 0x52, 0x21
+ , 0x6E, 0x16, 0xBF, 0x26, 0x9F, 0x37, 0xE0, 0x3E, 0xF9, 0x98, 0x45, 0x00, 0x44, 0x37, 0x3E, 0xB7
+ , 0x41, 0xED, 0x1A, 0xDF, 0xEF, 0x15, 0xDB, 0x54, 0xB4, 0x26, 0x61, 0x87, 0x48, 0x9F, 0x8B, 0xD3
+ , 0x5E, 0x26, 0x59, 0xF4, 0x75, 0xCC, 0x47, 0xD0, 0xDA, 0xB8, 0x29, 0xDD, 0x15, 0xBE, 0x31, 0x34
+ , 0x8A, 0x7F, 0xDC, 0x29, 0x76, 0x94, 0x8C, 0x65, 0xC8, 0xD8, 0x4A, 0x28, 0x4E, 0x90, 0xFA, 0xB4
+ , 0x3E, 0x48, 0xD5, 0xA6, 0xCB, 0x36, 0x02, 0x30, 0xBB, 0xCA, 0xD2, 0xD0, 0x98, 0x2D, 0x6F, 0xD3
+ , 0x3F, 0xE6, 0x2B, 0x40, 0x08, 0xE3, 0x28, 0x02, 0xA3, 0x3D, 0x3F, 0xDE, 0xCB, 0xE6, 0xF9, 0xC1
+ , 0xA4, 0x7F, 0x75, 0x63, 0x48, 0x1C, 0xCA, 0xF0, 0x2D, 0x4A, 0xEF, 0x6E, 0xCE, 0x45, 0x40, 0xD2
+ , 0xC5, 0x6A, 0x0C, 0x47, 0x11, 0x02, 0x8B, 0xBC, 0xD8, 0x34, 0x80, 0x23, 0xA9, 0xD3, 0x23, 0x9B
+ , 0x72, 0xAA, 0x17, 0xAA, 0xB1, 0x56, 0x22, 0x21, 0xA3, 0xDD, 0xBB, 0x37, 0x81, 0x84, 0x39, 0xC7
+ , 0x3F, 0xEC, 0x7D, 0xB0, 0xB2, 0x79, 0x70, 0x14, 0x9A, 0xF4, 0xD2, 0x9F, 0x10, 0x01, 0xF3, 0x25
+ , 0xD5, 0x70, 0x3B, 0xD5, 0x38, 0x0C, 0x96, 0x57, 0xB4, 0x05, 0xB1, 0xD8, 0x04, 0xD7, 0x16, 0xB7
+ , 0xFA, 0x69, 0xE8, 0x44, 0x1C, 0xF5, 0xE2, 0x6C, 0x97, 0xE4, 0x51, 0xD5, 0x3D, 0x51, 0xC3, 0x07
+ , 0xF8, 0x4B, 0xD7, 0x7A, 0x4B, 0xC1, 0x27, 0x61, 0xBB, 0x46, 0xDE, 0xCE, 0x23, 0x37, 0xE7, 0x5E
+ , 0xFF, 0xEE, 0x5F, 0x35, 0x52, 0x2C, 0x43, 0xDE, 0x83, 0xC9, 0x15, 0xC2, 0x11, 0x86, 0xA9, 0x67
+ , 0x28, 0xBC, 0xB4, 0x29, 0xF9, 0x9F, 0x8D, 0x2D, 0x0B, 0xF5, 0x2A, 0x60, 0xBB, 0x48, 0x80, 0x54
+ , 0x5F, 0x95, 0xE4, 0xFC, 0x5E, 0xFA, 0x24, 0xB3, 0xCC, 0xCF, 0x1D, 0xBF, 0x2F, 0x1C, 0x47, 0x13
+ , 0x2F, 0xDE, 0xB2, 0x41, 0x1F, 0xB4, 0x40, 0xAB, 0x4B, 0xCB, 0x13, 0x13, 0x7F, 0xB2, 0x4A, 0xF3
+ , 0x77, 0x9C, 0xF4, 0x07, 0xE1, 0x1D, 0x65, 0x1D, 0xB0, 0xCE, 0x48, 0xB0, 0x38, 0xEE, 0x20, 0x95
+ , 0x2F, 0xCB, 0xFE, 0xAA, 0x88, 0xCF, 0xAF, 0x80, 0x85, 0x4F, 0xC9, 0xAD, 0x59, 0xBA, 0x0E, 0x94
+ , 0xBF, 0x64, 0xEF, 0x2D, 0x10, 0xFF, 0x9F, 0x4C, 0x82, 0x00, 0x92, 0xB9, 0x96, 0xDE, 0x1E, 0x1A
+ , 0xD0, 0x6E, 0x70, 0x07, 0x27, 0x76, 0x98, 0x11, 0xAA, 0x7E, 0x5F, 0xAC, 0x2C, 0x24, 0xA7, 0x89
+ , 0xF0, 0xF6, 0xFA, 0xE4, 0x19, 0xA3, 0xB9, 0x34, 0x8C, 0xD1, 0xA5, 0x5A, 0xFE, 0x40, 0xE5, 0xBE
+ , 0xE9, 0x21, 0x5A, 0x0F, 0x96, 0x87, 0x10, 0x73, 0xBC, 0x76, 0x92, 0x4B, 0xBB, 0xEB, 0x82, 0x3C
+ , 0xBF, 0x8B, 0xF1, 0xE9, 0xB3, 0x87, 0xDC, 0x46, 0xD5, 0x06, 0x93, 0xF9, 0xA9, 0x5C, 0xDE, 0x39
+ , 0x85, 0xA3, 0x02, 0x7C, 0x9D, 0x89, 0xC9, 0x83, 0xDB, 0x4C, 0x8F, 0x40, 0xA4, 0x2C, 0x9B, 0xE2
+ , 0xD0, 0xFD, 0x4E, 0x0B, 0xE3, 0x58, 0x40, 0x3F, 0x97, 0x0D, 0x25, 0x8F, 0x3F, 0xF6, 0x64, 0xBB
+ , 0x19, 0xBF, 0xE3, 0xF0, 0x29, 0x2F, 0xC3, 0x16, 0x75, 0x0E, 0x98, 0x8F, 0x30, 0x11, 0xF8, 0x92
+ , 0xA2, 0x2A, 0x41, 0xD5, 0x16, 0xBC, 0x3C, 0x24, 0x16, 0x8D, 0x47, 0xC9, 0x06, 0xC6, 0x70, 0x16
+ , 0x39, 0x37, 0xE2, 0x25, 0xF8, 0x98, 0xA1, 0xFB, 0x86, 0xB9, 0xD1, 0x86, 0x17, 0x49, 0xFD, 0x6F
+ , 0x8A, 0x83, 0x92, 0xB2, 0xF3, 0xDE, 0xBC, 0x44, 0x0F, 0x9F, 0x08, 0xE9, 0x88, 0x40, 0x4E, 0xD2
+ , 0x58, 0x68, 0x77, 0x89, 0xA9, 0x78, 0xBB, 0xEC, 0xA9, 0x07, 0x23, 0x3C, 0xA3, 0x12, 0x28, 0x71
+ , 0x87, 0x05, 0x86, 0x8B, 0xC7, 0x6B, 0x7E, 0x9A, 0x2D, 0xE0, 0x6D, 0x95, 0x2F, 0xDA, 0x2E, 0x33
+ , 0x42, 0x47, 0xFF, 0x41, 0x51, 0x1E, 0xB2, 0xB0, 0x07, 0xD9, 0x4D, 0x5D, 0x4F, 0xDC, 0x2F, 0xEB
+ , 0xFA, 0x56, 0xB9, 0xDA, 0x53, 0x7D, 0x75, 0x40, 0xD6, 0xA7, 0x32, 0x66, 0xFF, 0x7A, 0xB8, 0xBF
+ , 0x16, 0xB2, 0x51, 0x3D, 0x4D, 0x80, 0xFD, 0x1D, 0x11, 0x32, 0x57, 0xC9, 0x95, 0x4E, 0xAF, 0xC6
+ , 0xB0, 0x19, 0xF8, 0xC0, 0x0B, 0x1F, 0xD3, 0x92, 0xAA, 0xF0, 0xA3, 0xEE, 0x7D, 0x2D, 0xA7, 0xA4
+ , 0xB5, 0xC9, 0x45, 0x2E, 0x95, 0xF2, 0x38, 0x36, 0x49, 0x80, 0x9D, 0x9E, 0x95, 0x1D, 0x94, 0x57
+ , 0x97, 0x55, 0x0B, 0xDC, 0x03, 0xC5, 0x57, 0xB2, 0x13, 0x39, 0xB2, 0x98, 0x5B, 0xAD, 0xF6, 0xF5
+ , 0x51, 0xCD, 0xCB, 0x44, 0x54, 0xE8, 0xF7, 0xB5, 0xA4, 0xD6, 0x0F, 0xA1, 0x55, 0xB3, 0x40, 0x93
+ , 0xC6, 0xF8, 0xE1, 0x45, 0x74, 0xDA, 0x65, 0xF3, 0x8A, 0xE9, 0x57, 0xEE, 0x9E, 0x82, 0xEE, 0xEA
+ , 0x9B, 0x27, 0xE8, 0x34, 0x4E, 0x40, 0xE9, 0x99, 0x29, 0x22, 0x74, 0x92, 0x7E, 0x03, 0x8D, 0x08
+ , 0x41, 0x8E, 0x7B, 0xA4, 0xBE, 0x17, 0x2F, 0x7F, 0xC1, 0xD4, 0xED, 0x45, 0x5A, 0xB3, 0x31, 0x67
+ , 0x6D, 0x51, 0x39, 0xF4, 0x30, 0xD9, 0xFB, 0xB7, 0x87, 0xD8, 0x21, 0xB6, 0x2B, 0xAE, 0xBB, 0x76
+ , 0xBD, 0xC3, 0x4F, 0x31, 0x65, 0x63, 0x89, 0x5C, 0xFD, 0xDE, 0x36, 0xB7, 0xD3, 0xD6, 0x65, 0xC5
+ , 0xE7, 0x16, 0x1B, 0xEC, 0xF0, 0x3D, 0x47, 0x54, 0x66, 0x5E, 0xF0, 0x61, 0xB4, 0x00, 0x66, 0x13
+ , 0xD6, 0x5E, 0xBD, 0xC7, 0xC8, 0x11, 0xE1, 0x80, 0x82, 0x7C, 0x3D, 0x00, 0x23, 0xC2, 0x34, 0xA9
+ , 0x71, 0x66, 0xD7, 0x7E, 0x52, 0x45, 0x8E, 0xF2, 0xE7, 0x4B, 0x2C, 0x4A, 0x00, 0x8C, 0x28, 0xFD
+ , 0xA2, 0xFC, 0xC8, 0x72, 0xAC, 0x55, 0x25, 0xAD, 0xE6, 0x85, 0x86, 0x78, 0x8D, 0xA2, 0x47, 0xF7
+ , 0xA0, 0xCC, 0x03, 0xC0, 0xA3, 0x38, 0x7B, 0xD4, 0x7F, 0xD7, 0xE5, 0x58, 0xB4, 0x4D, 0x7B, 0xB8
+ , 0x10, 0x53, 0x0D, 0x5F, 0x15, 0x14, 0xAC, 0x4E, 0x3D, 0x80, 0x45, 0x92, 0x34, 0xDF, 0x82, 0xF2
+ , 0xCE, 0x2A, 0x25, 0x7B, 0xB7, 0x48, 0x36, 0xCF, 0xCE, 0x14, 0xCF, 0xB1, 0x82, 0xDE, 0x85, 0xAD
+ , 0x51, 0x5E, 0x0C, 0x3F, 0xE6, 0xD2, 0x4C, 0x6E, 0x40, 0x35, 0xB9, 0x07, 0x45, 0x3F, 0x23, 0x44
+ , 0x60, 0xD7, 0x78, 0x51, 0x44, 0x08, 0x43, 0x74, 0x17, 0xDD, 0x21, 0x7E, 0x04, 0xE9, 0x58, 0xF2
+ , 0x0F, 0xBB, 0x1D, 0xDB, 0xA6, 0xE6, 0x3C, 0x72, 0xF1, 0x02, 0x1A, 0x66, 0x63, 0xAF, 0x4A, 0x0A
+ , 0x7F, 0x46, 0x7C, 0x2C, 0x5B, 0xA9, 0x3A, 0x3A, 0xB3, 0x7A, 0x5F, 0xDF, 0x60, 0x49, 0xE8, 0xC0
+ , 0xC2, 0x4B, 0x81, 0xAE, 0xD6, 0xDD, 0x4A, 0x46, 0x8C, 0xEB, 0xF3, 0x10, 0x5C, 0x90, 0x9B, 0x6F
+ , 0x23, 0x1C, 0xD7, 0xAB, 0xB2, 0x70, 0x87, 0xA8, 0x80, 0xAB, 0xFF, 0xB0, 0x04, 0xAD, 0x40, 0xFE
+ , 0x41, 0x29, 0xAE, 0xE6, 0xDD, 0xF1, 0xA8, 0x69, 0xA6, 0xA4, 0xF1, 0x67, 0x65, 0x8F, 0x7F, 0xC1
+ , 0x41, 0x7E, 0xA2, 0xA0, 0xB1, 0x5D, 0x28, 0xC6, 0x04, 0x3B, 0x90, 0x0A, 0x22, 0x53, 0x16, 0x17
+ , 0x0A, 0xEF, 0xDB, 0x63, 0xEA, 0xDB, 0x40, 0x1B, 0xF9, 0x14, 0xBC, 0xCB, 0x84, 0x98, 0x3E, 0xF7
+ , 0x33, 0xEA, 0x14, 0x67, 0x52, 0x32, 0x6B, 0xAD, 0x6D, 0xE4, 0x0F, 0x62, 0x58, 0x6D, 0x8A, 0x3D
+ , 0x6C, 0x55, 0xCB, 0x30, 0xD9, 0x36, 0xE9, 0x96, 0x18, 0x4E, 0x37, 0x69, 0xC9, 0x5A, 0xCD, 0xCB
+ , 0x83, 0x22, 0x9D, 0xD5, 0xFA, 0xDC, 0xA7, 0xB7, 0x4D, 0xFC, 0x4D, 0x56, 0x70, 0xF6, 0x0F, 0xE9
+ , 0x29, 0x4C, 0xC8, 0x19, 0xA1, 0x48, 0x8A, 0x03, 0x84, 0xA4, 0x08, 0xE9, 0xA8, 0x2C, 0x48, 0xAA
+ , 0x04, 0x66, 0xCF, 0x46, 0x54, 0xC0, 0x20, 0xEA, 0x49, 0x70, 0x35, 0x7D, 0xDF, 0xA5, 0x55, 0x66
+ , 0x76, 0xE9, 0x5A, 0xE1, 0xBA, 0x24, 0xF8, 0x99, 0x46, 0x51, 0x13, 0xD9, 0x28, 0xCD, 0xC8, 0x7D
+ , 0xC5, 0x01, 0x33, 0x02, 0x9F, 0xA4, 0xFA, 0xAC, 0xB3, 0xCA, 0x79, 0xFE, 0x72, 0x40, 0x95, 0xA3
+ , 0x7D, 0x03, 0x07, 0xC9, 0x0D, 0xE2, 0x5C, 0xB1, 0xCA, 0x18, 0x12, 0x33, 0x0B, 0x95, 0x98, 0x27
+ , 0x1E, 0x55, 0x9B, 0x73, 0x8C, 0x21, 0xF1, 0x7B, 0xF5, 0x58, 0x3F, 0x9C, 0x16, 0xCB, 0xB6, 0x9D
+ , 0x60, 0xC7, 0x06, 0x78, 0x07, 0x98, 0xBF, 0xE0, 0x1D, 0x05, 0x83, 0x0D, 0xFC, 0xDA, 0xA8, 0x1A
+ , 0xAA, 0x20, 0x83, 0x65, 0xD7, 0x4E, 0x06, 0x21, 0x5B, 0x85, 0x31, 0xE1, 0x52, 0x60, 0xF9, 0xD9
+ , 0xD9, 0x25, 0x9E, 0xFE, 0xE4, 0x90, 0x89, 0x2A, 0x2B, 0x7F, 0xB8, 0xAE, 0x23, 0xB7, 0xE1, 0x7A
+ , 0x92, 0x70, 0x93, 0xC1, 0xDE, 0xF1, 0x87, 0x5B, 0x41, 0x18, 0xEA, 0xCF, 0x78, 0x2F, 0xDC, 0x3D
+ , 0xD4, 0x59, 0xFA, 0xA6, 0xD9, 0xC3, 0x58, 0x5B, 0xF0, 0x45, 0xC2, 0x18, 0xD8, 0x98, 0x83, 0x47
+ , 0x99, 0xDF, 0x12, 0x0F, 0x93, 0x4E, 0x95, 0x8B, 0x13, 0xDD, 0x16, 0x0E, 0xD4, 0x83, 0x1A, 0x14
+ , 0x07, 0x3C, 0xC9, 0x93, 0x29, 0xF2, 0xA6, 0x58, 0x87, 0xE5, 0x31, 0x78, 0x8F, 0x8A, 0x4A, 0xFF
+ , 0xF6, 0xA4, 0x4E, 0x9D, 0xA6, 0x6D, 0xC0, 0xAA, 0x54, 0xE1, 0x11, 0x73, 0x8F, 0xB0, 0x6B, 0xEF
+ , 0x39, 0xD9, 0x14, 0xA2, 0xFD, 0xBE, 0x40, 0x29, 0x00, 0x39, 0x3B, 0xEF, 0xA7, 0xA3, 0x92, 0x64
+ , 0xF4, 0x67, 0xF2, 0xA3, 0xF5, 0x8C, 0x36, 0x21, 0x8E, 0x3F, 0xA6, 0x29, 0xE8, 0x92, 0xC5, 0x55
+ , 0xFF, 0x36, 0x7D, 0x05, 0x6E, 0x4A, 0x0C, 0x51, 0x30, 0x94, 0x2C, 0x74, 0xE9, 0xB9, 0xD2, 0x34
+ , 0x36, 0xAC, 0x88, 0xF3, 0x4B, 0xBD, 0x31, 0xCF, 0xB1, 0x9D, 0x0F, 0x85, 0xC6, 0x5A, 0xAD, 0xB1
+ , 0xD2, 0xCB, 0x87, 0x6C, 0x52, 0x87, 0x77, 0x17, 0x1E, 0xEE, 0x6E, 0x11, 0xE9, 0xA6, 0x24, 0x36
+ , 0xD4, 0x60, 0x14, 0xD7, 0xCD, 0xAE, 0x07, 0xAA, 0xAE, 0xB0, 0x0C, 0xF0, 0x6C, 0x83, 0xEF, 0xEB
+ , 0xA2, 0xD1, 0xF1, 0x19, 0x4C, 0x21, 0xA3, 0x17, 0x10, 0xCB, 0x59, 0x49, 0x91, 0x0F, 0x30, 0x09
+ , 0x4F, 0xC5, 0x5C, 0x11, 0x53, 0x87, 0x69, 0xC4, 0x06, 0x5D, 0xA8, 0x06, 0x55, 0xD0, 0x84, 0xA3
+ , 0x19, 0xBC, 0x86, 0x4B, 0xE5, 0xF2, 0x81, 0xF0, 0x74, 0x2B, 0x79, 0xB2, 0xCD, 0x1B, 0xA3, 0xBF
+ , 0x5D, 0xDC, 0x71, 0xFC, 0xF3, 0xEC, 0x8B, 0x11, 0x94, 0xD3, 0x93, 0x6D, 0xE3, 0x27, 0xF8, 0x31
+ , 0xCE, 0x1A, 0xBE, 0x2E, 0xE6, 0x2D, 0x8A, 0xFC, 0x85, 0x82, 0xE9, 0xEC, 0xF5, 0xD8, 0xE4, 0x7F
+ , 0x3C, 0x87, 0x51, 0x97, 0x9F, 0x29, 0xD2, 0xE3, 0x24, 0x14, 0x87, 0x3B, 0x7F, 0x4D, 0x24, 0xB7
+ , 0x44, 0xEC, 0x1E, 0x2D, 0xAD, 0x87, 0x0D, 0x73, 0xB2, 0x68, 0x20, 0x09, 0xAF, 0x02, 0xF1, 0x58
+ , 0x49, 0x77, 0x23, 0xBA, 0xD4, 0xB3, 0x72, 0xA9, 0xED, 0x95, 0x36, 0xEC, 0x32, 0x79, 0xA8, 0x70
+ , 0x27, 0x8A, 0x3B, 0x1C, 0x68, 0x07, 0x8E, 0xA5, 0xB8, 0xE3, 0x81, 0x57, 0xA4, 0x0A, 0x07, 0xEA
+ , 0x4E, 0x44, 0x5F, 0x5E, 0x9D, 0xDF, 0x20, 0xA8, 0x5D, 0xD5, 0xBE, 0xED, 0xEA, 0xF9, 0x23, 0x31
+ , 0x93, 0xF6, 0x34, 0xC8, 0x5B, 0xA5, 0x46, 0x25, 0xCD, 0xDD, 0x31, 0xCB, 0x9A, 0xAA, 0x0C, 0xD1
+ , 0x6D, 0x5A, 0xB3, 0x65, 0x3C, 0xE0, 0x80, 0x67, 0xE8, 0x5C, 0x76, 0xCF, 0x36, 0x7F, 0xF0, 0x3B
+ , 0xB9, 0x0F, 0xE8, 0x56, 0xCA, 0xDA, 0xDE, 0x47, 0xD2, 0x88, 0x90, 0xAC, 0xE8, 0x92, 0x22, 0x8A
+ , 0x61, 0x1A, 0xFE, 0x21, 0x41, 0x6C, 0x25, 0x69, 0xDE, 0xD8, 0x33, 0xDF, 0x2A, 0xC4, 0xB4, 0xFC
+ , 0x50, 0x56, 0x78, 0xCE, 0xE9, 0x6C, 0xEA, 0xBF, 0xEE, 0x50, 0xED, 0xC7, 0x96, 0xD9, 0x88, 0xD4
+ , 0x83, 0xCB, 0x93, 0xFB, 0x7D, 0x3B, 0x04, 0xAC, 0x96, 0x7A, 0xAB, 0xFC, 0x2F, 0xCE, 0xD1, 0x68
+ , 0xF0, 0x91, 0x87, 0xE0, 0x15, 0x93, 0xF7, 0x3A, 0x8D, 0xAB, 0xAD, 0xD8, 0x7F, 0x42, 0x76, 0xA4
+ , 0x12, 0xD2, 0x54, 0x31, 0xB5, 0x79, 0xC1, 0xA1, 0xED, 0x6A, 0x38, 0x65, 0x8B, 0xDF, 0x6D, 0xD7
+ , 0x48, 0x2C, 0xA4, 0x62, 0x9E, 0x1F, 0x0A, 0x3F, 0xB2, 0xB4, 0x1F, 0x92, 0xB7, 0xF9, 0x5A, 0x93
+ , 0xF0, 0x1B, 0x67, 0x04, 0x60, 0x3A, 0x79, 0x01, 0x76, 0x40, 0xEE, 0x80, 0xF5, 0x19, 0x52, 0x2D
+ , 0xA3, 0xE4, 0xCA, 0xEC, 0x4F, 0x4B, 0x09, 0x2C, 0xE2, 0x86, 0xD7, 0x6F, 0x35, 0x07, 0xC9, 0x77
+ , 0xE6, 0x94, 0x65, 0xA4, 0x3A, 0xC1, 0xDD, 0xAF, 0x14, 0x80, 0x2D, 0xAD, 0x6B, 0xBC, 0x33, 0x5E
+ , 0xE9, 0x80, 0x3B, 0xF3, 0xCA, 0x89, 0xCD, 0x39, 0xA9, 0xC4, 0xA7, 0x50, 0xE9, 0x40, 0x10, 0x12
+ , 0x63, 0x17, 0xD0, 0xD0, 0x17, 0x9E, 0x7B, 0x7C, 0x50, 0x56, 0x27, 0x7B, 0x87, 0xEC, 0x90, 0x67
+ , 0xF2, 0xF2, 0x67, 0x5F, 0x49, 0x5A, 0xAB, 0x2E, 0x80, 0xC1, 0xC9, 0x32, 0x19, 0xA4, 0xFC, 0x19
+ , 0x59, 0x32, 0xFA, 0xE9, 0xA8, 0x99, 0xD7, 0x8C, 0x7A, 0x4E, 0x07, 0xCE, 0x7F, 0x16, 0x59, 0x47
+ , 0x90, 0x4E, 0xEE, 0x8B, 0xFF, 0xBA, 0xE3, 0xB8, 0x3F, 0x02, 0xE8, 0xC4, 0x4A, 0x50, 0xBC, 0x2F
+ , 0xC0, 0x95, 0x8D, 0xFE, 0xAF, 0xEB, 0x74, 0xF1, 0x42, 0x59, 0x20, 0x51, 0xA6, 0xAC, 0x49, 0xFF
+ , 0x68, 0x47, 0x00, 0x04, 0x55, 0x93, 0xCD, 0x85, 0x7B, 0xE5, 0xD6, 0x8C, 0x3B, 0xEB, 0x66, 0x62
+ , 0xB4, 0xD8, 0x67, 0x20, 0xCA, 0x11, 0x60, 0xE7, 0x71, 0xFC, 0xB4, 0x4E, 0x84, 0x94, 0x49, 0xE8
+ , 0x4E, 0xE5, 0x84, 0x9F, 0x2A, 0x70, 0x1D, 0xF1, 0xD1, 0x4A, 0x9C, 0x5E, 0xDF, 0xF3, 0xA7, 0x50
+ , 0x0B, 0x35, 0xF2, 0xC4, 0x1E, 0x8A, 0x9F, 0xD5, 0x7B, 0x16, 0xFA, 0x98, 0x71, 0x55, 0x6C, 0xC4
+ , 0x4C, 0x17, 0x5E, 0xD4, 0x73, 0x2C, 0xA0, 0x4C, 0x14, 0xB8, 0x48, 0x51, 0x3F, 0xBF, 0x57, 0x30
+ , 0x9D, 0x96, 0x11, 0x80, 0x40, 0x71, 0x3D, 0x17, 0x7D, 0x7E, 0xF3, 0xE6, 0xF3, 0x1D, 0x00, 0x73
+ , 0x70, 0x35, 0x5B, 0x98, 0x02, 0xF0, 0x90, 0x9A, 0x20, 0x2D, 0x15, 0xE9, 0x14, 0x0E, 0x5A, 0x12
+ , 0x00, 0x08, 0x27, 0xDF, 0x4D, 0x10, 0x52, 0xF2, 0x08, 0xF5, 0x94, 0x28, 0xED, 0x2E, 0x97, 0x07
+ , 0x0D, 0xAE, 0xED, 0x83, 0xBC, 0x58, 0x6A, 0xFA, 0x54, 0xEA, 0x48, 0xDB, 0x97, 0xB8, 0xAA, 0x22
+ , 0xA2, 0x07, 0xC6, 0x01, 0x7D, 0x55, 0x76, 0x1F, 0x9D, 0x21, 0x20, 0xF4, 0xF8, 0xF0, 0xA5, 0xF0
+ , 0x5F, 0xB9, 0xAF, 0x7A, 0x79, 0xEB, 0x3E, 0x28, 0xCC, 0xD2, 0x20, 0x04, 0x2E, 0x1D, 0xF4, 0xD4
+ , 0x1F, 0xFB, 0xC0, 0x93, 0xF9, 0x53, 0x32, 0xD0, 0x2F, 0x91, 0x78, 0x37, 0x59, 0x2E, 0x52, 0x2F
+ , 0x50, 0x9B, 0xAE, 0x03, 0xC3, 0xEE, 0x80, 0xEE, 0xB2, 0x09, 0x86, 0x3D, 0x9C, 0xCF, 0xC4, 0xC3
+ , 0xC9, 0x22, 0x41, 0x39, 0xC8, 0x8E, 0xA6, 0x48, 0x1E, 0x68, 0xD1, 0xC7, 0xB3, 0xA4, 0xCE, 0x3E
+ , 0xC4, 0xEB, 0xAF, 0x09, 0xDD, 0x5B, 0xD0, 0xAC, 0x89, 0xE8, 0x8C, 0x66, 0x8C, 0x98, 0x23, 0xF6
+ , 0x68, 0x36, 0xDB, 0x19, 0x86, 0x01, 0x70, 0x25, 0x7E, 0x70, 0x99, 0xF1, 0x62, 0x2D, 0x95, 0x4D
+ , 0x36, 0x5E, 0x06, 0x2F, 0xBE, 0x3F, 0xAC, 0xC7, 0x35, 0x0A, 0xBE, 0x1A, 0x59, 0x6C, 0x81, 0x5F
+ , 0xE5, 0x4D, 0xAA, 0x28, 0xC8, 0x69, 0x1F, 0x87, 0x52, 0xF3, 0x38, 0x99, 0x3D, 0x58, 0xCE, 0xD8
+ , 0xF2, 0x19, 0xA8, 0xE0, 0x8B, 0xD4, 0xF5, 0xD3, 0x67, 0x6B, 0xF4, 0x3A, 0x19, 0x24, 0xB4, 0xAD
+ , 0x0C, 0x1D, 0xC2, 0x89, 0x33, 0xC7, 0x6E, 0x6F, 0x07, 0x06, 0xAB, 0xB5, 0x28, 0x36, 0xDA, 0xE0
+ , 0x02, 0x7B, 0xCE, 0x66, 0x1D, 0xB8, 0x83, 0xBD, 0x80, 0x9B, 0xEA, 0x11, 0x7E, 0x68, 0x2A, 0x51
+ , 0xA8, 0x1F, 0x14, 0x2D, 0x04, 0xE1, 0x77, 0x2A, 0xB6, 0x98, 0xF0, 0x8C, 0xD0, 0x5F, 0x9C, 0x00
+ , 0x80, 0x8E, 0x46, 0x85, 0x17, 0x27, 0x89, 0x63, 0xB2, 0x1E, 0xB2, 0xEB, 0x01, 0x5A, 0x75, 0xDE
+ , 0x9F, 0x3F, 0xEC, 0x77, 0x70, 0x71, 0xA1, 0xE5, 0xC4, 0xC1, 0xFB, 0x89, 0x2E, 0x92, 0x29, 0xF2
+ , 0x2A, 0x6D, 0x48, 0x8B, 0x17, 0x4B, 0xAA, 0x4D, 0x23, 0x1D, 0x38, 0x3A, 0xD5, 0x41, 0x62, 0xBF
+ , 0xA9, 0x7B, 0x3E, 0x73, 0x08, 0xC2, 0x87, 0x00, 0xD5, 0x0F, 0x2A, 0x34, 0xCA, 0xA3, 0x59, 0x9B
+ , 0x7C, 0x46, 0x1D, 0x59, 0xFB, 0xAC, 0x86, 0x2D, 0x6A, 0x77, 0x05, 0x9A, 0xD7, 0x28, 0xB6, 0xD5
+ , 0xC3, 0xFA, 0x0E, 0x46, 0x91, 0xE7, 0xEF, 0xD6, 0xCC, 0x1B, 0x72, 0x94, 0x05, 0x00, 0xB9, 0x8D
+ , 0xE6, 0x85, 0x22, 0x99, 0xB5, 0x94, 0x0C, 0x05, 0x6A, 0xEC, 0x82, 0x02, 0x0B, 0xE4, 0x44, 0xB9
+ , 0xDF, 0x10, 0x95, 0xC7, 0x5C, 0xF9, 0x8B, 0x35, 0xF1, 0x87, 0xF6, 0xDA, 0x3E, 0xD6, 0x83, 0x64
+ , 0xDE, 0x57, 0x7C, 0xF3, 0xDB, 0xF1, 0xE5, 0xE8, 0xD6, 0x43, 0xF3, 0x6E, 0xED, 0x3F, 0xC0, 0x13
+ , 0x9F, 0x1D, 0x8E, 0x71, 0x20, 0xD1, 0x22, 0x99, 0x0B, 0x3E, 0x6A, 0x69, 0x1B, 0xFF, 0x3F, 0xD3
+ , 0x31, 0xA9, 0x24, 0xBA, 0xAA, 0xA1, 0x0B, 0x68, 0xE1, 0x42, 0x04, 0xED, 0x9B, 0x6B, 0x0D, 0xD1
+ , 0xCF, 0xC0, 0x79, 0x99, 0xCE, 0x8C, 0x42, 0x9E, 0x22, 0x32, 0xAF, 0x72, 0x65, 0x76, 0xDC, 0xA5
+ , 0x3F, 0xE1, 0xC7, 0x39, 0xCB, 0xAF, 0xE2, 0xC8, 0x14, 0x3C, 0x41, 0xFE, 0x6F, 0x47, 0xE7, 0x0E
+ , 0x85, 0xD9, 0x3A, 0x09, 0x7E, 0x6B, 0x53, 0x6A, 0xD7, 0xB2, 0xDF, 0x5D, 0xE2, 0x81, 0x29, 0x1A
+ , 0xCF, 0x10, 0x86, 0xE2, 0x53, 0x3C, 0x7A, 0x69, 0xE5, 0x62, 0x38, 0x2B, 0x0F, 0x9E, 0x79, 0x40
+ , 0x99, 0x3A, 0x16, 0x8E, 0xE6, 0x68, 0xF0, 0x61, 0xAC, 0x11, 0x45, 0xC2, 0x1D, 0x9E, 0x53, 0x79
+ , 0x07, 0xD9, 0xCD, 0x58, 0xDF, 0x76, 0xAD, 0xA5, 0xF4, 0xB7, 0xEE, 0x3E, 0x7A, 0xB2, 0xC2, 0x32
+ , 0x76, 0xDB, 0x15, 0xD6, 0x6B, 0x20, 0xF1, 0xA2, 0xDB, 0x00, 0x0C, 0xC8, 0xA7, 0xA5, 0xD9, 0x9A
+ , 0x68, 0xF5, 0xF7, 0x7F, 0x47, 0xB4, 0x73, 0x0D, 0x37, 0x05, 0xA5, 0x77, 0xE3, 0x69, 0x5F, 0x0A
+ , 0xFA, 0x94, 0x3D, 0xCD, 0x33, 0xBF, 0x55, 0xDE, 0xAD, 0x03, 0x6E, 0x3E, 0x13, 0x8E, 0x95, 0x71
+ , 0xD4, 0xCC, 0xC2, 0x30, 0x85, 0x64, 0xED, 0x96, 0xFC, 0xF0, 0x4E, 0x11, 0x3E, 0x74, 0xA9, 0xD8
+ , 0x2C, 0xBB, 0x5D, 0xAD, 0x49, 0xE1, 0x10, 0x31, 0xD1, 0x95, 0xFC, 0x77, 0x27, 0x8A, 0x4F, 0x51
+ , 0x5F, 0x61, 0x5D, 0x45, 0x2D, 0xE3, 0x98, 0x64, 0x43, 0xA3, 0x51, 0xBB, 0x48, 0x1F, 0x42, 0xFF
+ , 0xFB, 0x3A, 0x6A, 0x52, 0xE5, 0x90, 0xD0, 0x32, 0xC8, 0x56, 0x5B, 0x50, 0xC5, 0x94, 0x9E, 0xF4
+ , 0x80, 0xAA, 0x5B, 0x6D, 0x52, 0x79, 0x65, 0x87, 0x42, 0x69, 0x22, 0xE2, 0x13, 0x44, 0x6C, 0x07
+ , 0xC0, 0x13, 0xC7, 0xE2, 0xC9, 0xD6, 0x7C, 0x68, 0xB2, 0xCC, 0x12, 0x7D, 0x19, 0xC6, 0x69, 0xCC
+ , 0x8C, 0x96, 0xF7, 0x49, 0x4C, 0x34, 0x9F, 0xBA, 0x46, 0x5D, 0xDF, 0x17, 0xA5, 0x6A, 0x42, 0xA2
+ , 0xD1, 0x17, 0x04, 0xD6, 0x66, 0x39, 0xAD, 0x0D, 0x64, 0xD9, 0x21, 0xDD, 0x3B, 0x0E, 0xEA, 0x43
+ , 0xA9, 0x02, 0x29, 0x15, 0x7E, 0xC3, 0x11, 0xA9, 0xC4, 0x0A, 0x55, 0x8E, 0x0B, 0xEF, 0xAE, 0x1E
+ , 0x54, 0x56, 0x82, 0x3D, 0x88, 0xFB, 0x60, 0x1A, 0x6C, 0xF4, 0x98, 0x82, 0xD6, 0xAF, 0xBB, 0x39
+ , 0x65, 0xDC, 0x9D, 0xD6, 0x4B, 0xA1, 0xE3, 0xFB, 0x49, 0x58, 0x41, 0x33, 0x25, 0x52, 0x9F, 0x84
+ , 0xA1, 0x43, 0x1C, 0x48, 0x87, 0x09, 0xFF, 0x7E, 0x89, 0x25, 0x54, 0x9E, 0x30, 0x68, 0x26, 0x4C
+ , 0xC7, 0xCE, 0x5F, 0xB5, 0xFB, 0x7F, 0x9B, 0xEB, 0xB0, 0xCF, 0x25, 0x78, 0x97, 0x96, 0x9D, 0xB9
+ , 0x00, 0xD4, 0x29, 0x6E, 0x92, 0x3D, 0x18, 0xE5, 0x56, 0xE9, 0x55, 0x14, 0x6B, 0xFA, 0xD8, 0xF2
+ , 0xE8, 0x4A, 0x8D, 0x5C, 0xBD, 0x27, 0x1D, 0x02, 0x78, 0x64, 0xE7, 0x85, 0x4A, 0x10, 0x0C, 0x27
+ , 0xC0, 0xCE, 0xF6, 0xF3, 0x74, 0x57, 0x5C, 0x83, 0xA3, 0x27, 0x46, 0xE6, 0xB3, 0x00, 0x04, 0xCF
+ , 0xBE, 0x64, 0x0A, 0xDE, 0xD0, 0xFB, 0xB6, 0x11, 0x71, 0x54, 0xCB, 0x7D, 0x30, 0x2F, 0x25, 0xBD
+ , 0xD9, 0x7B, 0x00, 0xB4, 0x75, 0x5D, 0xEC, 0xA9, 0x81, 0xC3, 0x75, 0x16, 0x6C, 0xC6, 0xDD, 0xA2
+ , 0x30, 0xF6, 0xD7, 0x64, 0xB4, 0x87, 0x09, 0x0E, 0x7C, 0xEF, 0x9C, 0xB9, 0xF4, 0xCE, 0x35, 0xF5
+ , 0xB8, 0x4D, 0x06, 0x18, 0x5D, 0x2A, 0xBB, 0x67, 0xC2, 0xCB, 0xA6, 0x40, 0xD3, 0xFE, 0x7B, 0xCD
+ , 0x19, 0x33, 0x08, 0x75, 0x38, 0xE5, 0x77, 0x09, 0x36, 0xAF, 0x85, 0x4D, 0xAC, 0xB7, 0xE0, 0xFC
+ , 0x04, 0x16, 0xE6, 0x86, 0x2E, 0x49, 0x3E, 0x9F, 0x70, 0xC0, 0x35, 0xF8, 0x86, 0x88, 0x7F, 0xA8
+ , 0x10, 0x36, 0x7D, 0xB0, 0xA2, 0xC7, 0x61, 0x81, 0xAA, 0x28, 0x48, 0x1D, 0xBF, 0xD3, 0x13, 0x29
+ , 0x73, 0x8F, 0x5B, 0x4E, 0x5D, 0x71, 0x62, 0xAC, 0xD3, 0x8D, 0x41, 0xE5, 0x90, 0x7A, 0xFE, 0x83
+ , 0x06, 0x6C, 0x38, 0x51, 0xEE, 0x5E, 0xBE, 0x9B, 0x97, 0xF2, 0x0A, 0xCC, 0xAD, 0xBD, 0x37, 0x53
+ , 0x1C, 0x9F, 0x28, 0x87, 0xF8, 0x89, 0x5C, 0xB0, 0x23, 0x41, 0xA8, 0x59, 0x97, 0xC9, 0x01, 0x88
+ , 0x5B, 0xA4, 0x7B, 0xBA, 0xAC, 0x33, 0xFC, 0x55, 0xC7, 0x24, 0x12, 0xB8, 0xFC, 0x5C, 0x9F, 0xE3
+ , 0xFD, 0x14, 0x41, 0x6B, 0x9F, 0x49, 0x3C, 0x5D, 0xE5, 0x8E, 0xBD, 0x8D, 0x9E, 0x38, 0x1F, 0x34
+ , 0xEA, 0xAB, 0x88, 0x13, 0xA0, 0x53, 0x4B, 0xB1, 0x91, 0xE7, 0x12, 0x9C, 0x56, 0x1E, 0xD9, 0x47
+ , 0x92, 0x9C, 0x44, 0xE9, 0xC6, 0x82, 0xDC, 0x77, 0xB7, 0xC9, 0x7E, 0xF7, 0xF1, 0x23, 0xF2, 0xCE
+ , 0xA8, 0x7B, 0x4A, 0x3B, 0x55, 0x29, 0x79, 0xBA, 0xBD, 0x1E, 0x9A, 0x22, 0x8F, 0xB1, 0x11, 0xDB
+ , 0x81, 0x70, 0x7D, 0xCC, 0xA3, 0x06, 0x6B, 0x75, 0xF9, 0xDE, 0xBB, 0xD7, 0xF2, 0x45, 0x9C, 0x94
+ , 0x32, 0xB2, 0xA4, 0x83, 0x3C, 0xCA, 0x8B, 0xEC, 0xB0, 0xD1, 0xDE, 0x93, 0x35, 0xDF, 0xD0, 0xFC
+ , 0xDC, 0x0A, 0x4E, 0x08, 0x31, 0x10, 0x9E, 0x12, 0x4F, 0x78, 0xED, 0x47, 0x8C, 0x94, 0x11, 0x29
+ , 0x76, 0x7F, 0x72, 0x50, 0x25, 0xE6, 0xAB, 0x73, 0x6B, 0xCC, 0x26, 0x46, 0xD7, 0xCA, 0x56, 0x48
+ , 0x54, 0xCF, 0xD8, 0xE4, 0x93, 0x4A, 0x89, 0xCD, 0x13, 0xCB, 0x95, 0x9B, 0x3F, 0x32, 0x54, 0x18
+ , 0xB7, 0x0D, 0xA1, 0x44, 0x97, 0x1D, 0x66, 0x22, 0x4E, 0x91, 0xE2, 0xB0, 0x6C, 0x76, 0x2C, 0x5F
+ , 0xA0, 0xDB, 0x00, 0x56, 0x0E, 0x9D, 0x6E, 0xDC, 0x92, 0xA9, 0x79, 0x06, 0x04, 0x2E, 0xC8, 0x3C
+ , 0x7D, 0x63, 0xA0, 0x0E, 0xFF, 0x3C, 0x96, 0x9D, 0x36, 0x74, 0x0F, 0x5A, 0xA2, 0xFD, 0x8B, 0xBE
+ , 0x50, 0x76, 0xB1, 0x48, 0x77, 0x2B, 0xE1, 0xAE, 0x0E, 0xBB, 0x0F, 0x92, 0x3D, 0xBC, 0xD8, 0x97
+ , 0x9D, 0x0B, 0x99, 0x8E, 0x04, 0x9E, 0x0A, 0x85, 0x3A, 0xCA, 0x05, 0xE8, 0xF6, 0xC2, 0x24, 0x70
+ , 0xCF, 0x5C, 0xAD, 0x11, 0x19, 0xC6, 0xCA, 0x70, 0xAF, 0x38, 0x1D, 0x2B, 0xD0, 0x27, 0xC4, 0x44
+ , 0xE9, 0xB9, 0x9B, 0x41, 0xBA, 0x9E, 0x72, 0x63, 0x67, 0x3D, 0xD5, 0xB4, 0xEC, 0x86, 0xED, 0xF5
+ , 0x77, 0xFA, 0xCB, 0xDB, 0xAB, 0xAD, 0xCA, 0x1E, 0x19, 0xFD, 0x03, 0xA2, 0x81, 0x59, 0x26, 0x2B
+ , 0xA8, 0x9B, 0x20, 0xAF, 0x66, 0x95, 0xDC, 0x67, 0x11, 0xF8, 0xB5, 0x85, 0x05, 0x26, 0x11, 0x53
+ , 0x05, 0x90, 0x71, 0x27, 0xA1, 0x52, 0xAF, 0x0D, 0x00, 0x60, 0xFB, 0x20, 0x85, 0x6D, 0x54, 0xF1
+ , 0x99, 0xF7, 0xF8, 0x03, 0x40, 0xE7, 0xF5, 0xE3, 0x2B, 0x4E, 0x18, 0x56, 0x81, 0x2C, 0xD9, 0x34
+ , 0x17, 0x5A, 0x61, 0xF2, 0x9F, 0xE2, 0x2C, 0xAA, 0xA6, 0x9F, 0x08, 0xF6, 0xCD, 0xE7, 0x62, 0x7C
+ , 0xEC, 0xA6, 0x86, 0x6F, 0x85, 0xBF, 0xAD, 0xB1, 0x7A, 0xBF, 0x0C, 0xC4, 0xBE, 0x13, 0x06, 0x1A
+ , 0x0D, 0xE7, 0x55, 0xE7, 0xCF, 0xF1, 0xB1, 0x16, 0xDE, 0x8B, 0xCE, 0x55, 0x69, 0x8E, 0x50, 0x1B
+ , 0x34, 0x01, 0x06, 0xA1, 0xD2, 0x5B, 0xE8, 0x8B, 0x37, 0x40, 0x2D, 0x3D, 0x0A, 0x86, 0x28, 0x53
+ , 0x19, 0x75, 0xB3, 0x86, 0x10, 0x84, 0x91, 0x7C, 0xC0, 0x91, 0x98, 0x08, 0x18, 0xE8, 0x01, 0x53
+ , 0xBD, 0xE2, 0xAD, 0xC5, 0x02, 0xE1, 0xF7, 0x2A, 0x9C, 0xE5, 0x8A, 0xCC, 0x80, 0xBD, 0x26, 0x63
+ , 0x02, 0x62, 0xEE, 0x36, 0xD2, 0x47, 0x81, 0xFB, 0x1D, 0x79, 0xD2, 0xDF, 0x53, 0xDA, 0xD0, 0xC7
+ , 0x5A, 0xDC, 0xE1, 0x18, 0x80, 0x00, 0x09, 0xE0, 0xAA, 0x85, 0xAE, 0x54, 0xA1, 0xB3, 0x22, 0x96
+ , 0x0C, 0x79, 0x4E, 0xA1, 0xD8, 0x95, 0x94, 0xA4, 0xD8, 0x49, 0x55, 0x81, 0x41, 0xA4, 0x86, 0x6D
+ , 0x3E, 0x32, 0x3E, 0x50, 0xFD, 0xDD, 0x74, 0x1F, 0x4E, 0xB6, 0xF6, 0x6C, 0x56, 0x1A, 0x8D, 0xCC
+ , 0x81, 0xA0, 0xC7, 0x1C, 0x52, 0xF8, 0x50, 0x9C, 0x0D, 0xC4, 0x70, 0xE3, 0x0E, 0xC5, 0x9C, 0xDC
+ , 0x3B, 0x92, 0xFA, 0xD1, 0x60, 0x83, 0xD4, 0xE2, 0xB0, 0x84, 0x84, 0xF6, 0xDD, 0xAC, 0x44, 0x4A
+ , 0x98, 0xD9, 0x30, 0x95, 0x7A, 0xEF, 0x6B, 0x47, 0x51, 0x0C, 0x44, 0x54, 0x3D, 0x83, 0x26, 0x9A
+ , 0x99, 0x19, 0x0A, 0x2C, 0xF9, 0xFE, 0xD7, 0x8F, 0x6C, 0xE9, 0x79, 0xAD, 0x7A, 0x1B, 0x2F, 0x92
+ , 0x20, 0xA0, 0xCA, 0x11, 0x61, 0x18, 0x94, 0x4E, 0x4C, 0xD2, 0x05, 0x3D, 0x65, 0x08, 0xDE, 0xF2
+ , 0x5D, 0x49, 0x61, 0xDE, 0x13, 0x71, 0x11, 0xCF, 0x89, 0x27, 0xD1, 0xCD, 0x2D, 0xE7, 0x4A, 0x70
+ , 0x0F, 0x89, 0x56, 0x08, 0x93, 0xA1, 0x1C, 0x0B, 0xE1, 0x2A, 0xBD, 0xF6, 0x7E, 0xEF, 0x9F, 0xD8
+ , 0x19, 0xB1, 0x78, 0x87, 0x88, 0xE8, 0x91, 0xCC, 0xB5, 0x73, 0x8F, 0x48, 0xDC, 0x91, 0xA1, 0xD0
+ , 0xEB, 0xCC, 0x36, 0xBA, 0x3D, 0x7E, 0x3F, 0xC2, 0xF7, 0x7F, 0xB1, 0x54, 0x4D, 0xA9, 0x9E, 0xD9
+ , 0xC1, 0xB8, 0x61, 0x2D, 0x35, 0x6C, 0x05, 0x12, 0x26, 0xBF, 0x71, 0x90, 0xAF, 0x0D, 0xF2, 0x42
+ , 0x95, 0x67, 0x8D, 0x84, 0x95, 0x8D, 0x88, 0x47, 0xF2, 0x9A, 0x80, 0xAF, 0x27, 0x71, 0x7A, 0x14
+ , 0x47, 0x41, 0xF8, 0xD9, 0xD2, 0x76, 0x4A, 0x6D, 0x3B, 0x90, 0xF8, 0x95, 0x5E, 0xBC, 0x81, 0x66
+ , 0x17, 0x74, 0x03, 0xBD, 0x1B, 0x56, 0x81, 0x8E, 0x58, 0x75, 0x5E, 0x96, 0x3E, 0xCC, 0x97, 0x87
+ , 0xD2, 0x84, 0x65, 0x76, 0xC7, 0xE1, 0x0D, 0xCB, 0xF5, 0x25, 0x18, 0xB7, 0xC2, 0x70, 0x03, 0xA0
+ , 0xA9, 0xC5, 0x86, 0x79, 0x17, 0x2C, 0xB6, 0x45, 0xC4, 0xF7, 0x3F, 0x08, 0x70, 0xD7, 0x46, 0xDF
+ , 0x1A, 0xED, 0xAC, 0xAE, 0x2E, 0xA7, 0x31, 0x9E, 0xD4, 0x56, 0xC0, 0x98, 0x23, 0x95, 0xDA, 0x61
+ , 0x28, 0x05, 0x0F, 0xF7, 0xB5, 0x62, 0x44, 0x81, 0x3B, 0x7D, 0xAB, 0x73, 0x83, 0xDB, 0xF1, 0xED
+ , 0x3D, 0x26, 0xB1, 0x22, 0x4A, 0x98, 0x08, 0xBB, 0xD2, 0x21, 0x5A, 0x5B, 0x7B, 0xA1, 0xEB, 0xEF
+ , 0x47, 0xD9, 0x92, 0x65, 0x45, 0x97, 0xE7, 0xE4, 0x89, 0x02, 0xFD, 0x62, 0x75, 0x08, 0x32, 0x2E
+ , 0x45, 0xE9, 0x8B, 0x17, 0xFD, 0x43, 0xC8, 0x6B, 0x5C, 0x12, 0x38, 0x0F, 0x5A, 0x55, 0x84, 0x85
+ , 0x42, 0xD4, 0x71, 0xE1, 0xFF, 0xAF, 0x59, 0xC4, 0xED, 0xB2, 0xCD, 0x1A, 0xD9, 0x45, 0x7C, 0x94
+ , 0x8A, 0x5B, 0x89, 0x31, 0x25, 0x41, 0xC5, 0x54, 0xE2, 0xE2, 0xCD, 0x99, 0xFF, 0x38, 0x89, 0xDF
+ , 0xDD, 0x1B, 0xC1, 0xFC, 0xB8, 0x06, 0x4C, 0xFA, 0x8C, 0xF2, 0xDA, 0xE4, 0x22, 0x73, 0x1A, 0xA3
+ , 0x53, 0x1D, 0x97, 0xCF, 0x21, 0x90, 0x42, 0xA4, 0x56, 0x17, 0x07, 0xF3, 0x3F, 0xA3, 0x1F, 0x10
+ , 0x8A, 0x28, 0x57, 0x1C, 0x81, 0xC0, 0xEC, 0x2C, 0x7B, 0x1C, 0xFC, 0xE8, 0x13, 0xF1, 0xAB, 0x59
+ , 0xA3, 0x6D, 0x0F, 0x65, 0xBD, 0x20, 0x01, 0x23, 0xA1, 0x08, 0x5E, 0x50, 0x37, 0xE0, 0x8B, 0x7D
+ , 0x16, 0x26, 0x36, 0xE9, 0x7D, 0xC0, 0x08, 0xA1, 0xDB, 0xBF, 0xB4, 0x85, 0x4B, 0xF8, 0xE8, 0x6A
+ , 0x73, 0xBD, 0x9C, 0x16, 0x47, 0xC0, 0x5A, 0x1C, 0x9E, 0xAD, 0x4F, 0xB2, 0x7C, 0x1B, 0x72, 0x12
+ , 0xB0, 0xB5, 0x41, 0x5F, 0xAB, 0x93, 0x5B, 0xF5, 0x1A, 0x23, 0xEE, 0x9B, 0x1A, 0x1E, 0x43, 0x39
+ , 0xC2, 0xBD, 0x9B, 0xAA, 0xEF, 0xE9, 0x26, 0xA6, 0xFE, 0xC1, 0x24, 0x24, 0xBF, 0xFB, 0xFC, 0x30
+ , 0x32, 0x51, 0x30, 0x7C, 0x17, 0x3B, 0xC0, 0x81, 0xA6, 0xB3, 0x38, 0x03, 0xD9, 0x6B, 0x49, 0x43
+ , 0xFB, 0x2E, 0x13, 0x99, 0x47, 0x19, 0xD8, 0x89, 0x59, 0xEB, 0x00, 0x44, 0x04, 0xA4, 0xC3, 0xA5
+ , 0x34, 0x00, 0x6B, 0x7F, 0x91, 0x09, 0xB8, 0x2C, 0xCE, 0x09, 0xF0, 0xE1, 0x5A, 0x3F, 0x3A, 0xE2
+ , 0x61, 0xE3, 0x67, 0x36, 0x80, 0xB5, 0x47, 0x35, 0x8E, 0x27, 0x1E, 0x71, 0x5E, 0xE9, 0x59, 0xE6
+ , 0x6B, 0x4A, 0x88, 0xDA, 0x1B, 0x2F, 0x4B, 0x2C, 0x31, 0xEA, 0x5D, 0x58, 0x08, 0x87, 0x67, 0x3F
+ , 0x59, 0x12, 0x0C, 0x39, 0xD3, 0x84, 0x5F, 0x3B, 0xB5, 0x29, 0x95, 0xC6, 0x58, 0xD7, 0xEA, 0x36
+ , 0x0B, 0x0F, 0x31, 0x9B, 0xDE, 0xB6, 0xDD, 0xFE, 0x40, 0x4A, 0x90, 0x07, 0x6B, 0xC5, 0x7B, 0xF5
+ , 0xA9, 0xDA, 0x7A, 0x5C, 0x15, 0x70, 0xA1, 0xBF, 0x56, 0x5D, 0x16, 0x69, 0x7E, 0x82, 0x60, 0xD6
+ , 0xB9, 0xF8, 0x67, 0x03, 0x37, 0x4E, 0xB7, 0xD1, 0x8D, 0x7D, 0x27, 0x8F, 0xFE, 0x53, 0xC6, 0x03
+ , 0x0E, 0xBE, 0x8D, 0x13, 0x08, 0xBE, 0x5A, 0xBD, 0x74, 0x67, 0xB6, 0xF8, 0x59, 0x02, 0xA6, 0x29
+ , 0x6A, 0x51, 0x65, 0xA0, 0xE1, 0x7B, 0xDC, 0x87, 0x19, 0x3C, 0x85, 0x44, 0xB9, 0xAD, 0x36, 0xD0
+ , 0xFC, 0xDC, 0x30, 0x26, 0xF9, 0x8C, 0x79, 0xCC, 0x2D, 0xC2, 0x73, 0x53, 0x0C, 0x54, 0x07, 0xF1
+ , 0x6F, 0xAA, 0x9E, 0x80, 0x30, 0x79, 0xC1, 0xDF, 0xEF, 0x12, 0x29, 0x83, 0xAB, 0xCF, 0x9E, 0x7A
+ , 0x95, 0x16, 0xDA, 0xCF, 0xBA, 0x31, 0x0D, 0xF1, 0xF5, 0x58, 0xA7, 0x49, 0x43, 0x73, 0x9E, 0x24
+ , 0xAC, 0xF8, 0x85, 0x10, 0xD1, 0x7D, 0x7F, 0x1A, 0x41, 0x06, 0x75, 0xE0, 0xF5, 0x10, 0x84, 0x39
+ , 0x2C, 0x1E, 0xB1, 0xDA, 0x15, 0x29, 0x66, 0x5F, 0x55, 0x7C, 0x5E, 0xF5, 0x14, 0xAF, 0x9D, 0x55
+ , 0x50, 0x94, 0xB7, 0x11, 0xAD, 0xC6, 0x7D, 0x79, 0xFF, 0x12, 0xD5, 0x19, 0x8A, 0x54, 0x00, 0x19
+ , 0x69, 0xAF, 0xD1, 0x76, 0xE9, 0x85, 0x8B, 0x24, 0xB0, 0xF7, 0x31, 0x1B, 0xEF, 0xC2, 0xD3, 0xA5
+ , 0x7F, 0xC7, 0xC5, 0x76, 0x84, 0x8B, 0x54, 0xA4, 0x93, 0x98, 0x86, 0xB3, 0x26, 0x1C, 0x76, 0xD4
+ , 0x8B, 0xDE, 0x2A, 0x49, 0xF1, 0xE2, 0x21, 0xC8, 0x8A, 0xE8, 0xB2, 0x3A, 0xE7, 0x67, 0x5E, 0x63
+ , 0x26, 0x27, 0xF4, 0x03, 0x8C, 0xFC, 0xFE, 0x9C, 0x13, 0xF9, 0x51, 0x9C, 0xED, 0xDA, 0x19, 0x08
+ , 0x6A, 0x14, 0x3A, 0xF0, 0x25, 0x92, 0xDF, 0x7E, 0x7A, 0xDC, 0x9E, 0x06, 0x7A, 0x1F, 0xCA, 0x5B
+ , 0x4D, 0xB1, 0x57, 0x3A, 0x2E, 0x13, 0xB8, 0xD0, 0x42, 0x1E, 0xC9, 0xE2, 0xF4, 0x4C, 0x84, 0x4F
+ , 0x5C, 0x04, 0xE4, 0xC6, 0xC2, 0x01, 0x99, 0x24, 0xA9, 0x53, 0xC3, 0x21, 0x24, 0x3C, 0x32, 0x0C
+ , 0x64, 0xA3, 0x65, 0xD5, 0xB9, 0x76, 0x0C, 0x0A, 0x96, 0x09, 0x5F, 0x57, 0x3E, 0x68, 0xBB, 0x8B
+ , 0x88, 0x34, 0xA7, 0xEE, 0xCC, 0x32, 0xEE, 0x63, 0x40, 0x77, 0x68, 0x6D, 0x0C, 0x6A, 0x9E, 0x1E
+ , 0x9A, 0x57, 0x77, 0x66, 0xCB, 0x63, 0x45, 0x99, 0xD6, 0x4E, 0x90, 0xF9, 0x14, 0xA8, 0xAE, 0x41
+ , 0xA3, 0x8C, 0x5E, 0xE2, 0xA0, 0x85, 0x25, 0xFF, 0x33, 0x7B, 0x6F, 0x1E, 0xAF, 0xAD, 0xE3, 0x37
+ , 0xBE, 0x76, 0xD3, 0x82, 0x19, 0x39, 0x4A, 0x7F, 0xF7, 0x58, 0xFC, 0xF5, 0x07, 0xE9, 0x08, 0x90
+ , 0xB9, 0x92, 0x55, 0x35, 0xD9, 0xC7, 0x8A, 0x1A, 0x38, 0x8A, 0xB5, 0xD5, 0xE5, 0x54, 0x84, 0x08
+ , 0x53, 0x93, 0xBB, 0x15, 0x9B, 0x55, 0x9F, 0x53, 0x11, 0x3B, 0xC1, 0xA7, 0xC3, 0x1B, 0x87, 0xD3
+ , 0x7B, 0xB7, 0x5E, 0x54, 0xC5, 0x00, 0xFB, 0x32, 0x95, 0x91, 0x6D, 0x32, 0x1C, 0xB3, 0x94, 0xB5
+ , 0x0D, 0x8F, 0xA2, 0x84, 0x4F, 0x77, 0xF6, 0x0F, 0x57, 0x12, 0x8F, 0x51, 0xB2, 0x05, 0xC6, 0x86
+ , 0x4B, 0x0E, 0x55, 0xCC, 0x39, 0xC1, 0x56, 0xF7, 0xB8, 0x90, 0xF5, 0x21, 0x45, 0x58, 0x5A, 0x3E
+ , 0xE1, 0xAF, 0x85, 0xC6, 0x2E, 0x4B, 0x9D, 0x01, 0xF4, 0x76, 0x99, 0xD5, 0x5F, 0x83, 0x38, 0x2B
+ , 0x6F, 0x44, 0xDE, 0x7D, 0x61, 0xF8, 0x70, 0x32, 0xE9, 0x6C, 0xC0, 0xBD, 0xA9, 0xC0, 0xA8, 0x5A
+ , 0x1B, 0xE2, 0xA5, 0xF0, 0xF9, 0x25, 0xA3, 0x5C, 0x7E, 0xEC, 0x78, 0xFE, 0x67, 0x14, 0x31, 0x4F
+ , 0x42, 0xFB, 0x61, 0x8B, 0x0C, 0x7A, 0xB4, 0xED, 0x65, 0x34, 0xE4, 0x2C, 0x01, 0x81, 0x46, 0xEF
+ , 0x6D, 0xE0, 0x49, 0x25, 0xAA, 0x6F, 0xD1, 0x8E, 0x82, 0xC7, 0x9B, 0xEB, 0xEB, 0x54, 0x25, 0x7E
+ , 0x4F, 0x5E, 0xE3, 0x11, 0x7C, 0xF7, 0x72, 0x18, 0x99, 0xD7, 0xCE, 0x83, 0x99, 0x24, 0x1D, 0x19
+ , 0x8B, 0xCE, 0xAD, 0x44, 0xDE, 0xCE, 0x34, 0x65, 0xA1, 0x5D, 0x1F, 0x0F, 0x3E, 0x50, 0x3E, 0x9B
+ , 0x8A, 0x82, 0xD2, 0x00, 0xC8, 0x84, 0x62, 0x9A, 0x66, 0xB1, 0x62, 0xCD, 0x01, 0x7A, 0x3B, 0xC6
+ , 0xB2, 0x82, 0x3E, 0x93, 0xDF, 0xB4, 0xC0, 0x13, 0xAC, 0x7D, 0x6D, 0x57, 0xFB, 0x40, 0xD2, 0xD8
+ , 0xCD, 0xE0, 0x88, 0x34, 0xF6, 0xC8, 0x4C, 0xE8, 0xA5, 0x0C, 0xA3, 0x1A, 0x5F, 0x61, 0x18, 0x72
+ , 0x48, 0x17, 0xCD, 0x7A, 0x5E, 0xD8, 0x77, 0x58, 0x43, 0x92, 0x1E, 0x9F, 0xD4, 0x57, 0x74, 0x89
+ , 0xF6, 0xDD, 0x5E, 0x7B, 0xFD, 0xA5, 0xE3, 0xC2, 0x3D, 0x53, 0xBF, 0x86, 0x75, 0x24, 0x32, 0x1A
+ , 0x74, 0xF7, 0xEB, 0x3B, 0xC8, 0x6E, 0x77, 0xA6, 0x93, 0x61, 0xD4, 0x95, 0x81, 0xDC, 0x2A, 0xAC
+ , 0xD5, 0x90, 0x9F, 0xBA, 0x64, 0x62, 0xBD, 0x70, 0x54, 0x3F, 0x87, 0xA8, 0xB2, 0x6C, 0x1F, 0xF0
+ , 0x81, 0x43, 0x47, 0x17, 0x90, 0x4E, 0xE6, 0x73, 0x24, 0x86, 0x6A, 0x5B, 0xC0, 0xF6, 0xDF, 0x28
+ , 0xF5, 0x25, 0x40, 0xF8, 0xB2, 0x2E, 0x96, 0xBF, 0xAA, 0xAA, 0xB1, 0x6D, 0xF6, 0xFC, 0xC9, 0x0E
+ , 0xDF, 0x8D, 0x89, 0xF8, 0xD1, 0x4B, 0xAE, 0x01, 0xAF, 0x15, 0xCE, 0xC2, 0x50, 0x60, 0x37, 0x16
+ , 0xE1, 0x35, 0xA2, 0xD4, 0xB8, 0xD6, 0x3B, 0x0F, 0xEF, 0x9C, 0x9B, 0xA0, 0x0D, 0xCE, 0x1E, 0xE7
+ , 0x6C, 0x16, 0x85, 0xB0, 0xC9, 0xB5, 0xBB, 0x27, 0xB3, 0x14, 0x53, 0x93, 0x2F, 0x65, 0xE9, 0x24
+ , 0xDA, 0x7B, 0x34, 0x09, 0x50, 0x88, 0x1A, 0xDF, 0x50, 0xBB, 0x1B, 0x35, 0xB4, 0xA5, 0x30, 0x20
+ , 0x74, 0x31, 0x52, 0xA2, 0x1D, 0x59, 0x78, 0xBD, 0x1B, 0x0C, 0xB1, 0x29, 0xE6, 0xE3, 0x31, 0x3C
+ , 0xF8, 0x22, 0xBE, 0xBF, 0x57, 0xE0, 0x02, 0xA8, 0xAC, 0xE6, 0x7D, 0x46, 0x6C, 0x96, 0x04, 0x97
+ , 0x53, 0x68, 0x46, 0x2B, 0xD8, 0xE0, 0x04, 0xA4, 0xA9, 0x78, 0xCF, 0xB7, 0x77, 0xB5, 0xD6, 0x6E
+ , 0x68, 0xDF, 0x7E, 0x3A, 0x68, 0x79, 0x0A, 0x13, 0x2E, 0x09, 0x89, 0xCB, 0x90, 0xC4, 0x1B, 0x4A
+ , 0x0F, 0x89, 0x9E, 0xD8, 0xC9, 0xE5, 0xF3, 0x2C, 0x16, 0x27, 0xE3, 0xE2, 0xA5, 0xC4, 0x23, 0x86
+ , 0x83, 0x65, 0x79, 0x1A, 0x06, 0x12, 0x3E, 0x84, 0x44, 0x42, 0x83, 0xA5, 0x14, 0x67, 0x47, 0x0B
+ , 0x60, 0x34, 0x8D, 0x54, 0x75, 0x6B, 0xE9, 0xDD, 0x58, 0xEB, 0x09, 0x8C, 0x07, 0x80, 0x26, 0x52
+ , 0x02, 0x43, 0xC8, 0x6B, 0x9E, 0xDF, 0xE4, 0x8B, 0xE1, 0xBF, 0x47, 0x1C, 0xCE, 0x27, 0x96, 0xAC
+ , 0x90, 0xB8, 0x29, 0xC6, 0x34, 0x18, 0x67, 0x8C, 0x05, 0xEC, 0xBE, 0x04, 0x6E, 0x85, 0xE9, 0x04
+ , 0x0C, 0x31, 0xB8, 0xD9, 0x09, 0x15, 0xAF, 0xAE, 0x0D, 0x6B, 0x96, 0x49, 0x88, 0x2C, 0x5F, 0xAD
+ , 0x73, 0xA4, 0x6A, 0xAF, 0x22, 0xF7, 0xF3, 0xC5, 0x80, 0x38, 0xEE, 0x4D, 0xB8, 0x28, 0xA1, 0x20
+ , 0x8D, 0xB8, 0x5B, 0x0A, 0x0D, 0xF5, 0x0A, 0x8C, 0xBE, 0x25, 0x80, 0xB2, 0x9F, 0xD3, 0x27, 0x85
+ , 0x57, 0x75, 0x39, 0x2F, 0xC5, 0x04, 0x31, 0x96, 0x67, 0xFC, 0x9C, 0x00, 0xB9, 0xCC, 0x74, 0x51
+ , 0x2B, 0x2E, 0x1E, 0x85, 0xF3, 0x5C, 0x7C, 0x8E, 0xA3, 0x5F, 0x26, 0xA3, 0xC3, 0xCC, 0x09, 0x04
+ , 0xA1, 0xD0, 0x51, 0x2F, 0x96, 0x53, 0xB1, 0x50, 0xD8, 0x7F, 0x7E, 0x10, 0x0F, 0x75, 0xA0, 0x54
+ , 0xF2, 0xC5, 0x99, 0xEA, 0x20, 0x87, 0x91, 0x0F, 0x60, 0x35, 0x88, 0xFE, 0xDF, 0xC1, 0xF1, 0xB1
+ , 0x76, 0x5F, 0x1A, 0xAE, 0xCE, 0x8A, 0x69, 0xE0, 0x1F, 0xA5, 0x37, 0x1D, 0xC5, 0x30, 0x0E, 0xFB
+ , 0x13, 0xC6, 0xC0, 0xDE, 0xD6, 0x92, 0xDF, 0x5B, 0x2E, 0x07, 0x42, 0xBE, 0xC9, 0x42, 0x76, 0x4D
+ , 0xC4, 0x98, 0xB4, 0x21, 0x9D, 0x14, 0x73, 0xF3, 0x44, 0x80, 0x83, 0x67, 0x6D, 0x42, 0x21, 0xD5
+ , 0x7E, 0xF1, 0xAC, 0x68, 0x4B, 0xF3, 0x5B, 0x0E, 0xCD, 0xBC, 0x40, 0xC5, 0xDD, 0x1F, 0xA6, 0x10
+ , 0x2C, 0x4B, 0xC1, 0xA5, 0xFA, 0xAC, 0xCA, 0xED, 0xD2, 0x6B, 0xEA, 0x44, 0xAA, 0xFF, 0x91, 0x7F
+ , 0x36, 0xDE, 0x4D, 0xA5, 0x0D, 0x16, 0x40, 0x4D, 0x29, 0xE6, 0xDD, 0xA6, 0x06, 0x37, 0xB6, 0x81
+ , 0x09, 0x34, 0x05, 0xF1, 0x5C, 0x8B, 0x8B, 0x45, 0x5F, 0xC1, 0xA0, 0xF7, 0x48, 0x35, 0x27, 0x64
+ , 0x2D, 0xC5, 0x58, 0x8B, 0xE1, 0xE3, 0x0C, 0x43, 0x65, 0x5E, 0x74, 0xF6, 0x34, 0x4F, 0xE2, 0x7D
+ , 0x13, 0x30, 0x99, 0x67, 0xA3, 0x24, 0xE3, 0xA9, 0xAD, 0x5D, 0x89, 0xCA, 0xA6, 0x32, 0xCF, 0xF4
+ , 0xAB, 0xC3, 0x36, 0xA5, 0x8E, 0xAE, 0xD6, 0x0D, 0x93, 0xFF, 0x22, 0xCD, 0x8F, 0xCA, 0xE6, 0x4E
+ , 0xC8, 0xCC, 0x0C, 0xEC, 0x5B, 0x49, 0x41, 0xA0, 0xFE, 0x74, 0xC9, 0x2F, 0x27, 0xE6, 0x0B, 0x9E
+ , 0xDB, 0xA6, 0x14, 0x44, 0x82, 0x97, 0x1D, 0xAA, 0xC3, 0x44, 0xC1, 0x1A, 0x16, 0xB4, 0xD9, 0xD4
+ , 0x93, 0x00, 0xF1, 0x83, 0x46, 0x07, 0xAA, 0xD3, 0x0D, 0x9E, 0x01, 0xD2, 0xE2, 0x2B, 0xB7, 0x1E
+ , 0xCC, 0x91, 0xDF, 0xF0, 0x41, 0x67, 0x82, 0x38, 0x05, 0x37, 0xC1, 0xE6, 0x15, 0xFA, 0x9E, 0x07
+ , 0x66, 0x6A, 0x18, 0x37, 0x53, 0x16, 0xA3, 0x5C, 0xC3, 0x2C, 0x35, 0xDC, 0x57, 0xF4, 0xEB, 0xC8
+ , 0x7F, 0xC8, 0xEB, 0x3F, 0x77, 0x13, 0xB3, 0x3F, 0x7A, 0x7A, 0x79, 0x65, 0x73, 0xA5, 0xA3, 0x72
+ , 0xA4, 0x4B, 0x3C, 0x04, 0x05, 0x24, 0x5B, 0xDC, 0x0D, 0x5F, 0x91, 0xAE, 0xA6, 0xA5, 0x6E, 0x15
+ , 0x06, 0x29, 0xD7, 0x28, 0x42, 0x42, 0xCA, 0xAC, 0xA0, 0x79, 0xF6, 0x68, 0x2B, 0xD2, 0x5E, 0xF9
+ , 0x36, 0x1C, 0x65, 0xD6, 0x75, 0x78, 0xB9, 0xC2, 0x9C, 0xDF, 0x0A, 0xD0, 0xD1, 0x55, 0xA0, 0xA2
+ , 0x74, 0xE0, 0x45, 0x0D, 0x66, 0x8C, 0x2B, 0xF3, 0x9B, 0x78, 0xD8, 0xCF, 0x48, 0xDC, 0x1C, 0x1F
+ , 0x9A, 0xD8, 0xD8, 0xD9, 0xC4, 0x03, 0xE8, 0x15, 0x6E, 0x85, 0xB7, 0x4A, 0x6A, 0x73, 0xB3, 0xAF
+ , 0x86, 0x0C, 0xD0, 0x5F, 0x06, 0xDE, 0x07, 0xF9, 0x95, 0x2A, 0x40, 0x7A, 0x5A, 0x96, 0x9F, 0x9B
+ , 0xFA, 0x0F, 0xAD, 0x71, 0x52, 0x56, 0x89, 0xC0, 0x90, 0xA7, 0x3E, 0x1C, 0xA1, 0x61, 0x63, 0xE9
+ , 0x99, 0x98, 0x63, 0x80, 0xF0, 0x7B, 0xD7, 0xDB, 0xEF, 0xC4, 0x62, 0x05, 0x43, 0xF5, 0xDF, 0xEF
+ , 0xD0, 0xD3, 0x7D, 0x28, 0x02, 0xB9, 0x26, 0xB0, 0xA0, 0x90, 0xF8, 0x80, 0x98, 0xD6, 0xFA, 0xD4
+ , 0x89, 0x79, 0xF2, 0x01, 0x90, 0x0B, 0xB8, 0x56, 0x44, 0xE7, 0x20, 0x5C, 0x70, 0x7C, 0x34, 0xF2
+ , 0xD0, 0x7C, 0xF7, 0x00, 0xD6, 0x3C, 0x46, 0x5F, 0xBE, 0xF3, 0xC9, 0x5D, 0x5F, 0x6A, 0xB3, 0x6D
+ , 0xC4, 0x90, 0x49, 0x5E, 0xF0, 0xD6, 0x04, 0x99, 0xDC, 0x76, 0xC8, 0xEE, 0x7F, 0x63, 0x26, 0x3F
+ , 0x98, 0xE1, 0xFB, 0x5C, 0x76, 0x14, 0x20, 0x0E, 0x6D, 0xE5, 0xF7, 0xD5, 0x8C, 0x72, 0x9D, 0x9B
+ , 0xF9, 0xEA, 0xD6, 0x0C, 0x1F, 0xD5, 0x31, 0x22, 0xDC, 0x9A, 0xA3, 0x56, 0x5B, 0xD6, 0xFD, 0x11
+ , 0xB7, 0x7E, 0x13, 0x74, 0xAF, 0xAC, 0x28, 0xAA, 0x3F, 0xDF, 0x5F, 0x35, 0x02, 0xD3, 0x4F, 0x7B
+ , 0x50, 0xB5, 0x80, 0xD8, 0x4E, 0xD9, 0x8D, 0x63, 0x1B, 0x69, 0xCF, 0x2E, 0xB2, 0xC5, 0x9D, 0x07
+ , 0xBA, 0x65, 0xB9, 0x1E, 0x56, 0xAC, 0x5F, 0x56, 0x54, 0x1A, 0x4B, 0x47, 0xD0, 0xE3, 0x99, 0xA7
+ , 0x7C, 0x29, 0x81, 0x11, 0x8D, 0xE1, 0xBC, 0x4D, 0x0F, 0x7F, 0x37, 0xFA, 0x69, 0x5B, 0x03, 0x47
+ , 0x53, 0x1C, 0x2A, 0x8A, 0x6B, 0xA8, 0xF0, 0xCB, 0xDF, 0x3A, 0x8E, 0x72, 0x05, 0xBF, 0x60, 0x24
+ , 0x0E, 0xFF, 0xF6, 0x90, 0xA0, 0xDC, 0xF1, 0x17, 0x20, 0xF2, 0x98, 0xF0, 0xA5, 0xDC, 0x50, 0x13
+ , 0xD8, 0x5C, 0x7A, 0x2D, 0xC2, 0xC1, 0xFF, 0xF2, 0x11, 0x10, 0x09, 0xAB, 0xF3, 0xF0, 0xC3, 0x5C
+ , 0x0A, 0x0B, 0xC8, 0x32, 0x19, 0x34, 0x93, 0xE4, 0x21, 0x57, 0x78, 0x32, 0xED, 0x51, 0x0A, 0xAC
+ , 0x33, 0x02, 0x97, 0x83, 0xD7, 0x7B, 0x26, 0xD9, 0xB7, 0xBC, 0xCA, 0xCE, 0xE3, 0x0F, 0x38, 0xD5
+ , 0xE2, 0x26, 0x4F, 0xAC, 0x0D, 0x77, 0x25, 0xF7, 0x68, 0x31, 0x70, 0x41, 0xE6, 0xCA, 0x1D, 0xDC
+ , 0x9D, 0xD8, 0x83, 0x22, 0xFF, 0xB9, 0xC9, 0x27, 0xEB, 0xC6, 0x82, 0x6D, 0xFC, 0x45, 0x3D, 0x5C
+ , 0x6D, 0x6B, 0x99, 0x9B, 0x46, 0x16, 0x96, 0x72, 0x5C, 0x2C, 0x5C, 0x24, 0x2D, 0xEC, 0xB5, 0x86
+ , 0x29, 0x8A, 0x3A, 0x94, 0x69, 0x28, 0xD5, 0x5C, 0x0C, 0x0C, 0x20, 0x0D, 0x65, 0x02, 0x6E, 0x0F
+ , 0xEF, 0xBA, 0x64, 0x88, 0x5C, 0x32, 0x9F, 0x45, 0xA3, 0xB1, 0x39, 0xB5, 0x72, 0x42, 0x94, 0x62
+ , 0x72, 0xF0, 0x34, 0xDC, 0x37, 0xD9, 0x28, 0xEE, 0xE5, 0xB2, 0xF7, 0xA8, 0xEE, 0x22, 0x46, 0xD0
+ , 0x59, 0x24, 0x4A, 0x97, 0x98, 0x00, 0x6D, 0x83, 0xC3, 0xE2, 0x38, 0x4E, 0x04, 0x4B, 0x08, 0x67
+ , 0x06, 0xFB, 0xD3, 0xE0, 0x5A, 0xFB, 0x8A, 0xC8, 0x72, 0xB3, 0xE4, 0xBB, 0x7C, 0x59, 0xA0, 0x66
+ , 0x9B, 0xB7, 0x0F, 0x16, 0xE3, 0xFC, 0xFC, 0x55, 0xDC, 0xE3, 0x98, 0x10, 0x66, 0xC3, 0x9B, 0x55
+ , 0xBA, 0xA1, 0xC4, 0x00, 0x58, 0x30, 0xDD, 0x96, 0x48, 0x82, 0x58, 0xED, 0x56, 0x77, 0xE3, 0xFA
+ , 0xF1, 0x3D, 0x09, 0xB7, 0x1A, 0x8F, 0xF2, 0xA2, 0x05, 0x2D, 0x1C, 0xAB, 0xA6, 0xE1, 0x5F, 0x44
+ , 0xD8, 0x4A, 0x56, 0x16, 0xD4, 0xE7, 0x42, 0x35, 0x6F, 0x62, 0x09, 0xA9, 0x63, 0x99, 0xD9, 0x62
+ , 0xE6, 0x65, 0x3F, 0xFA, 0xAF, 0x61, 0x83, 0x5C, 0x52, 0x5F, 0x51, 0x57, 0x82, 0x1B, 0xC9, 0xB0
+ , 0xE1, 0x3C, 0x06, 0x90, 0xEE, 0xF8, 0x17, 0x85, 0x73, 0xC4, 0x6E, 0x9C, 0xA6, 0x23, 0x27, 0x43
+ , 0x1B, 0x25, 0xC7, 0x6E, 0xD0, 0x6D, 0x68, 0x82, 0x92, 0x03, 0xA2, 0xEF, 0x3D, 0x6B, 0x50, 0x5A
+ , 0x3A, 0x1D, 0xD3, 0x0F, 0x1C, 0x82, 0x92, 0x8B, 0x6A, 0x30, 0xD4, 0xF7, 0x8C, 0x7C, 0xE1, 0x3E
+ , 0x83, 0xE3, 0xAB, 0x60, 0xB2, 0x5D, 0x06, 0xDA, 0x75, 0xB8, 0x0C, 0x31, 0x52, 0x6E, 0xD3, 0x0A
+ , 0xFD, 0x08, 0x4D, 0x2C, 0x87, 0x4E, 0x1D, 0x5E, 0x5B, 0x46, 0x8A, 0xDA, 0x29, 0x0D, 0xD8, 0xE6
+ , 0x75, 0x75, 0xF4, 0xA0, 0x79, 0xDC, 0xB9, 0xF8, 0xCE, 0xB0, 0x61, 0xF9, 0x45, 0x45, 0xE4, 0xFD
+ , 0x56, 0x3F, 0xF7, 0x2E, 0xA7, 0xC6, 0x69, 0x12, 0xBB, 0xAF, 0x0A, 0x2A, 0x44, 0xEE, 0x5E, 0x9A
+ , 0x65, 0x80, 0x4E, 0x68, 0x98, 0x54, 0xEB, 0x8B, 0x81, 0x3F, 0x41, 0x94, 0x13, 0x6B, 0x0F, 0x35
+ , 0x13, 0x60, 0x0F, 0x6D, 0x7D, 0xB9, 0x40, 0x2E, 0xC4, 0x0C, 0xBD, 0x89, 0x8F, 0xB5, 0x23, 0xBB
+ , 0x19, 0x63, 0x5F, 0x37, 0xB5, 0x70, 0xFE, 0x54, 0x8A, 0x73, 0x7E, 0x67, 0x50, 0x58, 0x81, 0x08
+ , 0x5F, 0x13, 0xA7, 0x12, 0xC3, 0x60, 0x2A, 0x7E, 0x8E, 0x3B, 0x32, 0x21, 0xEF, 0xA8, 0xE0, 0xDE
+ , 0xDA, 0x62, 0x73, 0x7F, 0xAE, 0xE5, 0xC4, 0x46, 0x9C, 0x54, 0x73, 0x15, 0x28, 0xD4, 0x14, 0x4A
+ , 0x7B, 0x1B, 0xE3, 0xEB, 0x18, 0x65, 0xE8, 0x9C, 0x36, 0xFA, 0xA8, 0x97, 0xB2, 0x36, 0xB5, 0xDD
+ , 0x49, 0x56, 0x4D, 0x81, 0x4A, 0x81, 0x32, 0x25, 0x50, 0xA4, 0x36, 0xE0, 0x36, 0x1C, 0x55, 0xE4
+ , 0x8F, 0x03, 0x7F, 0x61, 0xD9, 0xDE, 0x64, 0x7E, 0xE4, 0x2E, 0xF2, 0xF3, 0xFC, 0x66, 0x4E, 0x30
+ , 0x06, 0x9F, 0x4B, 0x9E, 0x0B, 0xE2, 0xBA, 0x93, 0xFD, 0x0F, 0xDD, 0xCE, 0xC9, 0x93, 0xE9, 0x3D
+ , 0x17, 0x3F, 0xB7, 0x45, 0x51, 0x3F, 0x0A, 0x12, 0x30, 0xFE, 0xB4, 0xF3, 0x59, 0x8D, 0x67, 0x3B
+ , 0x1B, 0x76, 0x6C, 0x08, 0x3C, 0x04, 0xC6, 0xCE, 0x48, 0x9C, 0x73, 0x5B, 0x80, 0xAA, 0x01, 0xB6
+ , 0x45, 0x16, 0xDF, 0x8A, 0x39, 0x5A, 0xF1, 0x98, 0xE4, 0xD4, 0xC5, 0x9C, 0x59, 0xC3, 0xDC, 0x4C
+ , 0x24, 0xC8, 0xFF, 0x1C, 0x63, 0x00, 0xBC, 0x7B, 0xC5, 0x4D, 0xA3, 0x11, 0xB7, 0x04, 0x49, 0xF7
+ , 0x34, 0x68, 0x4D, 0xAF, 0x84, 0xDF, 0xCF, 0xDB, 0xCC, 0x79, 0xF7, 0x72, 0x35, 0xBA, 0x57, 0x78
+ , 0x83, 0xBE, 0x82, 0x37, 0x3B, 0xC2, 0x6A, 0xE4, 0x3D, 0xFA, 0x6D, 0x21, 0xC7, 0x8C, 0x61, 0x7C
+ , 0x9A, 0x69, 0xD6, 0x6C, 0xEA, 0x34, 0x36, 0x37, 0x1F, 0x1F, 0xE3, 0x3F, 0xD0, 0x34, 0xFE, 0x20
+ , 0x87, 0xFD, 0xD1, 0x0A, 0x01, 0x1D, 0xB2, 0x27, 0x3E, 0x7B, 0x1C, 0x5B, 0xAE, 0x28, 0x18, 0x99
+ , 0xB9, 0x94, 0x8E, 0xF7, 0xD7, 0x6A, 0x53, 0x5E, 0x15, 0xB9, 0x48, 0xA0, 0x0E, 0xAF, 0xEB, 0xAE
+ , 0xEE, 0xBE, 0xE4, 0x55, 0x3A, 0x6C, 0xD9, 0xB9, 0xB8, 0x4D, 0xD0, 0x0E, 0x40, 0x45, 0x22, 0x7D
+ , 0x24, 0xDB, 0x32, 0xEB, 0x77, 0xC7, 0x21, 0x1D, 0x6C, 0xDF, 0xEF, 0xEA, 0x0F, 0xD9, 0x2C, 0x7A
+ , 0xA4, 0xA0, 0x2C, 0x8F, 0x03, 0x33, 0xE8, 0xB3, 0x6F, 0xF2, 0xC3, 0xA3, 0xC6, 0x08, 0x29, 0x38
+ , 0xFA, 0x30, 0x35, 0xA1, 0x38, 0x39, 0x1F, 0xE3, 0xB9, 0xA1, 0x58, 0x12, 0x91, 0x18, 0x4A, 0x1C
+ , 0xCC, 0x3D, 0xEA, 0xE6, 0xAA, 0x42, 0x5B, 0x28, 0x17, 0x15, 0xCE, 0x66, 0x09, 0xCA, 0x3F, 0x40
+ , 0x86, 0x2E, 0x6F, 0x95, 0xA9, 0x62, 0xCB, 0x8B, 0x81, 0xBC, 0x57, 0x59, 0xF5, 0xA7, 0x13, 0x30
+ , 0xF9, 0x5A, 0xF0, 0xA8, 0xEB, 0xFA, 0x90, 0x8D, 0x84, 0x15, 0xD7, 0xE2, 0x8C, 0xEB, 0x05, 0xFB
+ , 0xF8, 0xCE, 0x59, 0xFE, 0x1F, 0x1D, 0x19, 0x04, 0x2B, 0x72, 0xEB, 0x24, 0x45, 0x50, 0x5D, 0x56
+ , 0xCC, 0x97, 0xB4, 0x75, 0x2D, 0x31, 0x1F, 0xF4, 0x30, 0x7B, 0xF7, 0x27, 0x4A, 0x97, 0x65, 0x2D
+ , 0xE6, 0xDE, 0xDB, 0xEE, 0x7A, 0x0E, 0x2B, 0x26, 0xD1, 0xEE, 0x0F, 0x61, 0x81, 0xAA, 0x10, 0x71
+ , 0x72, 0xC0, 0xF4, 0xF5, 0x60, 0x81, 0xC2, 0xDE, 0x4D, 0xA8, 0xC7, 0x33, 0xEC, 0x6D, 0xE7, 0xC7
+ , 0x6E, 0x46, 0xAD, 0x9C, 0x6B, 0x6F, 0x20, 0x1E, 0xE0, 0x77, 0x1F, 0x71, 0x94, 0x7A, 0x15, 0x05
+ , 0xF0, 0xD7, 0xF0, 0x33, 0x70, 0x97, 0x0D, 0xB4, 0xB6, 0xD3, 0xBC, 0xA4, 0x50, 0x7A, 0x3C, 0x49
+ , 0xE2, 0xE8, 0x0F, 0x3E, 0x21, 0xB7, 0x17, 0x95, 0x9E, 0x31, 0x62, 0xB2, 0x49, 0xE8, 0x4F, 0x1E
+ , 0x86, 0xD4, 0xF9, 0xD5, 0x22, 0x89, 0x5B, 0x67, 0xE6, 0xDA, 0xFC, 0xA3, 0x3C, 0xFE, 0x5E, 0x8E
+ , 0xF9, 0x4D, 0xF5, 0x24, 0x3C, 0x56, 0xE5, 0x26, 0xFD, 0x3D, 0xA1, 0xAA, 0x86, 0x99, 0x54, 0x87
+ , 0x12, 0x85, 0x4D, 0x89, 0x64, 0x67, 0xD6, 0xCB, 0x8D, 0x40, 0xB7, 0xBA, 0x4A, 0x60, 0x8A, 0xE4
+ , 0xCC, 0x01, 0x04, 0x11, 0xE2, 0x38, 0x9F, 0x7F, 0xD1, 0xB5, 0x82, 0xCF, 0xD8, 0x50, 0x02, 0xF6
+ , 0x42, 0x2D, 0x63, 0x1B, 0x0D, 0x1A, 0xF9, 0xE5, 0x2A, 0x54, 0xCC, 0x7E, 0xDE, 0x43, 0x7B, 0xC9
+ , 0xF0, 0xF5, 0xBD, 0x64, 0xA2, 0x79, 0x55, 0x90, 0x8E, 0x19, 0x44, 0xE9, 0x85, 0x18, 0x6C, 0x58
+ , 0x9D, 0xA5, 0xCE, 0xF1, 0x38, 0xF0, 0xDD, 0x87, 0x4E, 0x72, 0xF0, 0x17, 0x09, 0xAC, 0xF6, 0x1B
+ , 0xD0, 0x8B, 0x1B, 0x78, 0xBF, 0x63, 0xA4, 0x33, 0xF9, 0x44, 0x5D, 0xD9, 0x97, 0x28, 0x06, 0x5B
+ , 0x4A, 0x26, 0xEB, 0xC0, 0x97, 0x1C, 0x67, 0x10, 0x65, 0x47, 0x7D, 0x52, 0x50, 0xE5, 0x55, 0x0F
+ , 0x68, 0xC6, 0x93, 0x37, 0x44, 0xB1, 0xB3, 0x4A, 0xF4, 0x0D, 0xBE, 0x15, 0x27, 0x6C, 0xE5, 0xEC
+ , 0x25, 0xDC, 0x65, 0xE9, 0x07, 0x1A, 0x6C, 0xA6, 0x0E, 0xB2, 0xDB, 0xDE, 0x75, 0xD0, 0xC3, 0x67
+ , 0x41, 0xCB, 0x4F, 0x5F, 0x00, 0xF5, 0x1E, 0x94, 0x45, 0x7D, 0xCA, 0x0F, 0xBF, 0xC4, 0x04, 0x83
+ , 0x9E, 0xBE, 0x25, 0xB1, 0x5E, 0x32, 0xBF, 0x4F, 0x28, 0x9B, 0x68, 0x2E, 0x5A, 0xE0, 0xD1, 0x4A
+ , 0xF3, 0xB2, 0x9E, 0xA9, 0x27, 0xD6, 0x6D, 0x58, 0x2E, 0x34, 0x67, 0x6B, 0xB8, 0x39, 0x15, 0x3A
+ , 0x10, 0xE3, 0xD8, 0x74, 0x28, 0x83, 0x5C, 0x2F, 0x7C, 0xF0, 0x3B, 0x76, 0xA6, 0xEE, 0x4E, 0xE4
+ , 0x38, 0x70, 0xBA, 0x20, 0x17, 0x9D, 0x28, 0x03, 0x87, 0x67, 0x6F, 0x90, 0x6F, 0x78, 0xA1, 0xFF
+ , 0x98, 0xD3, 0x82, 0xB6, 0x11, 0x4D, 0xFB, 0xF7, 0x8B, 0x85, 0x79, 0x01, 0x6B, 0x42, 0x68, 0x77
+ , 0x01, 0x51, 0xA4, 0x69, 0x2C, 0x11, 0x91, 0x1E, 0xBD, 0x64, 0xD3, 0x80, 0x68, 0x95, 0xFC, 0x1B
+ , 0x85, 0xA1, 0xD9, 0xEB, 0xD2, 0x63, 0xA5, 0x61, 0x2A, 0x40, 0x98, 0x2D, 0xB8, 0x44, 0xB6, 0x04
+ , 0xED, 0x00, 0xDB, 0xA1, 0xDB, 0xE4, 0x6A, 0x62, 0xC9, 0x8C, 0xA6, 0xFF, 0xA2, 0xBA, 0xE7, 0x3E
+ , 0x12, 0x58, 0x01, 0x37, 0xB0, 0xFA, 0xBB, 0xBB, 0x13, 0xAC, 0x10, 0x60, 0x2B, 0x4E, 0x8F, 0xCF
+ , 0x22, 0xD5, 0xC9, 0xA8, 0x59, 0x7A, 0xC9, 0xEE, 0xC4, 0xA6, 0xAE, 0x51, 0xE0, 0xD8, 0x4C, 0xF2
+ , 0xA0, 0xAA, 0x6B, 0xA0, 0x20, 0xE8, 0x99, 0xFF, 0xF6, 0xBF, 0x15, 0x3C, 0x6C, 0x23, 0xCC, 0x0B
+ , 0xC8, 0xF2, 0xD2, 0x3F, 0x43, 0x97, 0x74, 0x03, 0x6C, 0x3E, 0xA7, 0xF8, 0xE5, 0xD2, 0x04, 0x04
+ , 0x40, 0x37, 0xBE, 0x49, 0xD1, 0xAA, 0xCF, 0xA0, 0xAF, 0x0A, 0xDA, 0x75, 0x7E, 0x2B, 0x66, 0xE1
+ , 0x35, 0x72, 0x2A, 0xAF, 0x5F, 0x72, 0x11, 0x12, 0xEB, 0x67, 0xC0, 0x35, 0xAC, 0xAB, 0x03, 0x09
+ , 0xA4, 0x9A, 0x1C, 0x97, 0xC7, 0x76, 0xD2, 0x66, 0x5D, 0x4B, 0x70, 0xD2, 0x9C, 0xDF, 0x0D, 0xBE
+ , 0x74, 0x46, 0x9D, 0x1B, 0xC2, 0xA8, 0x33, 0xF7, 0x7A, 0xAB, 0xE0, 0xB0, 0xC2, 0x5D, 0xDE, 0x80
+ , 0xCA, 0xD3, 0x28, 0xC1, 0xEB, 0x64, 0xCE, 0xEB, 0x93, 0xB1, 0x9C, 0xE9, 0x58, 0x97, 0xB2, 0x57
+ , 0x7C, 0xB2, 0xD4, 0xCC, 0xFE, 0xEF, 0x0B, 0x10, 0x11, 0xAF, 0x0B, 0x55, 0x22, 0x30, 0xFA, 0xC1
+ , 0x17, 0x48, 0xBC, 0x14, 0x25, 0x12, 0x83, 0xD1, 0xB0, 0x08, 0x11, 0x1C, 0x41, 0x07, 0xF1, 0xA5
+ , 0x7D, 0x04, 0x51, 0x9C, 0x2B, 0x85, 0x49, 0xAD, 0x67, 0x78, 0xD9, 0x9B, 0x3C, 0xB7, 0x54, 0xD8
+ , 0xB3, 0xB5, 0x2B, 0x0B, 0xC1, 0xE9, 0xCF, 0xD7, 0xAF, 0x5E, 0x5D, 0x99, 0xED, 0x45, 0x79, 0xBD
+ , 0x3D, 0x37, 0xE6, 0x6B, 0x08, 0xA4, 0x96, 0x05, 0x51, 0xB8, 0x8A, 0xA6, 0xE9, 0x40, 0x7B, 0x25
+ , 0xF7, 0xE2, 0x8F, 0x0F, 0x8D, 0xF0, 0xC3, 0x9F, 0x7B, 0x26, 0xA3, 0xA3, 0x45, 0x0F, 0x30, 0x27
+ , 0xBF, 0xB0, 0xB3, 0xA9, 0xF1, 0xA5, 0xC4, 0xF3, 0xDD, 0xCD, 0x24, 0xF5, 0x5C, 0xC3, 0xFE, 0x4F
+ , 0xA2, 0xFD, 0xF1, 0x15, 0x4F, 0x3F, 0x50, 0xAF, 0xB8, 0x95, 0x72, 0x7A, 0x95, 0xCE, 0x1D, 0xFD
+ , 0xA7, 0x85, 0xD0, 0x92, 0x05, 0xEE, 0x42, 0x7B, 0xD8, 0x3D, 0xEE, 0x9C, 0xDB, 0x81, 0xF6, 0x7F
+ , 0x1D, 0x1F, 0xA8, 0xA9, 0x0A, 0xDB, 0xA8, 0xC3, 0xE2, 0x08, 0x7E, 0x49, 0x00, 0xFF, 0xC2, 0x11
+ , 0x32, 0xF8, 0x90, 0xE4, 0x40, 0x93, 0x34, 0x3A, 0x17, 0x4A, 0xAB, 0x67, 0x76, 0x36, 0x62, 0x1D
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xDB, 0xD2, 0xFC, 0x49, 0xEA, 0x27, 0x1B, 0xDD, 0x5C, 0x12, 0x14, 0x16, 0x4F, 0x54, 0xD2, 0x53
+ , 0x77, 0xC1, 0x2F, 0xEF, 0x0D, 0x4D, 0x10, 0x08, 0x69, 0xA6, 0xB9, 0x9B, 0xE4, 0xDF, 0xC1, 0x47
+ , 0xC2, 0x1E, 0x6F, 0xC7, 0xAF, 0x94, 0x9E, 0xF5, 0xEE, 0xAB, 0x07, 0x52, 0x02, 0x76, 0xB6, 0x0C
+ , 0x1E, 0x74, 0x26, 0x19, 0x75, 0x0E, 0x23, 0x6F, 0x7B, 0x10, 0x64, 0x45, 0x31, 0xF6, 0xAA, 0xA6
+ , 0x53, 0x78, 0x9D, 0xB0, 0xBC, 0xB2, 0xC7, 0x95, 0xAD, 0x87, 0x6D, 0x00, 0x86, 0x3C, 0x51, 0x34
+ , 0x8F, 0x74, 0x0F, 0x1E, 0x34, 0x71, 0x59, 0x06, 0x4B, 0x07, 0xA6, 0xCB, 0x5C, 0x30, 0x5E, 0xA6
+ , 0xA8, 0x2A, 0xBB, 0x4C, 0x5C, 0xD6, 0xAB, 0x38, 0xD0, 0xE7, 0x17, 0x94, 0x68, 0x90, 0xF1, 0x8B
+ , 0x43, 0x6B, 0x93, 0xC3, 0x3E, 0xD7, 0x8B, 0x25, 0x51, 0x49, 0x97, 0x2A, 0x07, 0x79, 0xA6, 0x44
+ , 0x65, 0x9D, 0x8C, 0x50, 0xA6, 0xC7, 0x7E, 0x17, 0xE7, 0x4D, 0x28, 0x81, 0x03, 0x69, 0x9C, 0xF7
+ , 0x31, 0xAB, 0xEB, 0x8C, 0x5E, 0x6F, 0x01, 0x10, 0x01, 0xB2, 0x0F, 0x16, 0x8B, 0xD4, 0x0A, 0x4F
+ , 0x3F, 0x27, 0xA1, 0xB1, 0x08, 0x74, 0x74, 0x26, 0x16, 0x35, 0x6E, 0x0D, 0x43, 0x64, 0xEA, 0xAA
+ , 0x83, 0x07, 0xB0, 0x47, 0x44, 0xDF, 0x80, 0x0D, 0x20, 0x4D, 0x0A, 0x97, 0x2D, 0x28, 0xE1, 0xF4
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xC2, 0x0A, 0xEA, 0x1A, 0xBC, 0xE4, 0x19, 0xFE, 0xDF, 0x12, 0x52, 0x61, 0xA6, 0xDA, 0x07, 0xB5
+ , 0xCF, 0x97, 0x8D, 0xF4, 0xFE, 0x97, 0xB7, 0xEF, 0x1B, 0xE7, 0xA4, 0x45, 0xD1, 0x58, 0xBB, 0xB1
+};
+
+
+
+#pragma arm section zidata="NONCACHEDZI", rwdata="NONCACHEDRW"
+__align(4) kal_uint8 sdiobuf[2048] = {0xff,};
+#pragma arm section zidata, rwdata
+kal_uint8 sdiobuf2[2048] = {0xff,};
+
+
+void test_hisr(void)
+{
+ kal_uint32 sdc_intsta;
+ dbg_print("interrupt callback\r\n");
+ msdc_dbg_print("[%s %d]SDIO EINT12 \r\n", __FUNCTION__, __LINE__);
+
+ //EINT_Set_Polarity(MT5931_EINT_NUM, KAL_FALSE);
+ //call = 1;
+ //SDIO_HISR_Entry();
+}
+
+kal_int32
+kalDevReadWithSdioCmd52(
+ kal_uint32 u4Register,
+ kal_uint8 * pucValue
+)
+{
+ DCL_CTRL_DATA_T Data;
+ DCL_SDC_CMD_STATUS Status;
+ Data.rSDIOCMD52.func = DCL_SDIO_FUCN_0;
+ Data.rSDIOCMD52.addr = u4Register;
+ Status = DclSDIO_Control(handle_sdio, SDIO_CTRL_CMD_CMD52_READ, &Data);
+
+ if (Status != STATUS_OK)
+ {
+ msdc_dbg_print("kalDevReadWithSdioCmd52() reports error: %d", Status);
+ return -1;
+ }
+ else
+ {
+ *pucValue = Data.rSDIOCMD52.rdata;
+ return 0;
+ }
+}
+
+kal_int32
+kalDevWriteWithSdioCmd52(
+ kal_uint32 u4Register,
+ kal_uint8 ucValue
+)
+{
+ DCL_CTRL_DATA_T Data;
+ DCL_SDC_CMD_STATUS Status;
+ Data.rSDIOCMD52.func = DCL_SDIO_FUCN_0;
+ Data.rSDIOCMD52.addr = u4Register;
+ Data.rSDIOCMD52.wdata = ucValue;
+ Status = DclSDIO_Control(handle_sdio, SDIO_CTRL_CMD_CMD52_WRITE, &Data);
+
+ if (Status != STATUS_OK)
+ {
+ msdc_dbg_print("kalDevWriteWithSdioCmd52() reports error: %x", Status);
+ return -1;
+ }
+ else
+ return 0;
+}
+
+#pragma arm section zidata = "NONCACHEDZI", rwdata = "NONCACHEDRW"
+__align(4) kal_uint8 uvalue[4] = {0xff,};
+#pragma arm section zidata, rwdata
+
+kal_int32
+kalDevRegRead (
+ //IN P_GLUE_INFO_T prGlueInfo,
+ kal_uint32 u4Register,
+ kal_uint32 * pu4Value
+)
+{
+ DCL_CTRL_DATA_T Data;
+ DCL_SDC_CMD_STATUS Status;
+
+ //Setup and Excute CMD53
+ Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+ Data.rSDIOCMD53.block = KAL_FALSE;
+ Data.rSDIOCMD53.addr = u4Register;
+ Data.rSDIOCMD53.buffer = (kal_uint32)&uvalue[0];
+ Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+ Data.rSDIOCMD53.count = 4; //4*8 Bits
+ /*Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_INIT,NULL);
+ if (Status == FALSE) {
+ ERRORLOG(("kalDevRegRead() CMD Init fail: %x", Status));
+ }*/
+
+ Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD53_READ, &Data);
+
+ if (Status != STATUS_OK)
+ {
+ msdc_dbg_print("kalDevRegRead() reports error: %d", Status);
+ return -1;
+ }
+ else
+ {
+ *pu4Value = ((kal_uint32)uvalue[3] << 24) + ((kal_uint32)uvalue[2] << 16) + ((kal_uint32)uvalue[1] << 8) + uvalue[0];
+ return 0;
+ }
+}
+kal_int32
+kalDevRegWrite (
+ //IN P_GLUE_INFO_T prGlueInfo,
+ kal_uint32 u4Register,
+ kal_uint32 u4Value)
+{
+ DCL_CTRL_DATA_T Data;
+ DCL_SDC_CMD_STATUS Status;
+
+ uvalue[0] = (kal_uint8)u4Value & 0xFF;
+ uvalue[1] = (kal_uint8)((u4Value >> 8) & 0xFF);
+ uvalue[2] = (kal_uint8)((u4Value >> 16) & 0xFF);
+ uvalue[3] = (kal_uint8)((u4Value >> 24) & 0xFF);
+ //Setup and Excute CMD53
+ Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+ Data.rSDIOCMD53.block = KAL_FALSE;
+ Data.rSDIOCMD53.addr = u4Register;
+ Data.rSDIOCMD53.buffer = (kal_uint32)&uvalue[0];
+ Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+ Data.rSDIOCMD53.count = 4; //4*8 Bits
+ /*Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_INIT,NULL);
+ if (Status == FALSE) {
+ ERRORLOG(("kalDevRegRead() CMD Init fail: %x", Status));
+ }*/
+
+ Status = DclSDIO_Control(handle_sdio, SDIO_CTRL_CMD_CMD53_WRITE, &Data);
+
+ if (Status != STATUS_OK)
+ {
+ msdc_dbg_print("kalDevRegWrite() reports error: %d", Status);
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int kalDevPortRead (
+ //IN P_GLUE_INFO_T prGlueInfo,
+ kal_uint16 u2Port,
+ kal_uint16 u2Len,
+ kal_uint8 * pucBuf
+ //IN UINT_16 u2ValidOutBufSize
+)
+{
+ DCL_CTRL_DATA_T Data;
+ DCL_SDC_CMD_STATUS Status;
+ kal_uint8 bNum = 0;
+ kal_uint16 i;
+ kal_uint32 u4TotalLen, u4Len;
+
+#if 1
+ u4Len = u2Len;
+
+ while (u2Len >= FUNC1_SDIO_BLK_SIZE)
+ {
+ u2Len -= FUNC1_SDIO_BLK_SIZE;
+ bNum++;
+ }
+
+ if (u2Len > 0 && bNum > 0)
+ {
+ bNum++;
+ }
+
+ if (bNum > 0) // block mode
+ {
+ Data.rSDIOCMD53.block = KAL_TRUE;
+ u4TotalLen = ALIGN_32(bNum * FUNC1_SDIO_BLK_SIZE);
+ Data.rSDIOCMD53.count = bNum;
+ }
+ else if (u2Len > DMA_THRESHOLD) //byte mode with DMA
+ {
+ Data.rSDIOCMD53.block = KAL_FALSE;
+ u4TotalLen = ALIGN_32(u2Len);
+ Data.rSDIOCMD53.count = u4TotalLen;
+ }
+ else //byte mode wit MCU
+ {
+ u4TotalLen = ALIGN_32(u2Len);
+ Data.rSDIOCMD53.block = KAL_FALSE;
+ Data.rSDIOCMD53.count = u2Len;
+ }
+
+ if (u4TotalLen >= DMA_THRESHOLD
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+ && is_predef_dyna_c_region((kal_uint32)pucBuf, u4TotalLen)
+#endif /* __ARM9_DCACHEABLE__ */
+ )
+ {
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+ dynamic_switch_cacheable_region((void *)&pucBuf, u4TotalLen, SWITCH_TO_NONCACHEABLE);
+#endif /*__ARM9_DCACHEABLE__*/
+ Data.rSDIOCMD53.buffer = (kal_uint32)pucBuf;
+ Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+ Data.rSDIOCMD53.addr = u2Port;
+ Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+ Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD53_READ, &Data);
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+ dynamic_switch_cacheable_region((void *)&pucBuf, u4TotalLen, SWITCH_TO_CACHEABLE);
+#endif /*__ARM9_DCACHEABLE__*/
+ }
+ else
+ {
+ if (u4TotalLen >= DMA_THRESHOLD)
+ {
+ Data.rSDIOCMDREG.data = 1;
+
+ if (STATUS_OK != DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_FORCEMCU_READ, &Data))
+ {
+ msdc_dbg_print("SDIO_CTRL_CMD_FORCEMCU_READ failed %s %d!!", __FUNCTION__, __LINE__);
+ }
+ }
+
+ Data.rSDIOCMD53.buffer = (kal_uint32)pucBuf;
+ Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+ Data.rSDIOCMD53.addr = u2Port;
+ Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+ Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD53_READ, &Data);
+
+ if (u4TotalLen >= DMA_THRESHOLD)
+ {
+ Data.rSDIOCMDREG.data = 0;
+
+ if (STATUS_OK != DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_FORCEMCU_READ, &Data))
+ {
+ msdc_dbg_print("SDIO_CTRL_CMD_FORCEMCU_READ failed %s %d!!", __FUNCTION__, __LINE__);
+ }
+ }
+ }
+
+ //printk(KERN_INFO DRV_NAME"-- kalDevPortWrite-- ret=%d\n", ret);
+ if (Status != STATUS_OK)
+ {
+ msdc_dbg_print("kalDevPortRead() reports error: %x", Status);
+ return KAL_FALSE;
+ }
+ else
+ {
+ return KAL_TRUE;
+ }
+
+#else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+/* under construction !*/
+#endif /*__ARM9_DCACHEABLE__*/
+/* under construction !*/
+/* under construction !*/
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+/* under construction !*/
+#endif /*__ARM9_DCACHEABLE__*/
+/* under construction !*/
+/* under construction !*/
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+/* under construction !*/
+#endif/*__ARM9_DCACHEABLE__*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+} /* end of kalDevPortRead() */
+
+int
+kalDevPortWrite (
+ //IN P_GLUE_INFO_T prGlueInfo,
+ kal_uint16 u2Port,
+ kal_uint16 u2Len,
+ kal_uint8 * pucBuf
+ //IN UINT_16 u2ValidInBufSize
+)
+{
+ DCL_CTRL_DATA_T Data;
+ DCL_SDC_CMD_STATUS Status;
+ kal_uint8 bNum = 0;
+ kal_uint32 u4TotalLen, u4Len;
+
+ u4Len = u2Len;
+
+ //Setup and Excute CMD53
+ /* Split buffer into multiple single block to workaround hifsys */
+ while (u2Len >= FUNC1_SDIO_BLK_SIZE)
+ {
+ u2Len -= FUNC1_SDIO_BLK_SIZE;
+ bNum++;
+ }
+
+ if (u2Len > 0 && bNum > 0)
+ {
+ bNum++;
+ }
+
+ if (bNum > 0) // block mode
+ {
+ Data.rSDIOCMD53.block = KAL_TRUE;
+ u4TotalLen = ALIGN_32(bNum * FUNC1_SDIO_BLK_SIZE);
+ Data.rSDIOCMD53.count = bNum;
+ }
+ else //byte mode
+ {
+ Data.rSDIOCMD53.block = KAL_FALSE;
+ u4TotalLen = ALIGN_32(u4Len);
+ Data.rSDIOCMD53.count = u4TotalLen;
+ }
+
+ if ((u4TotalLen - u4Len) >= sizeof(kal_uint32))
+ {
+ /* fill with single dword of zero as TX-aggregation termination */
+ *(kal_uint32 *) (&((pucBuf)[ALIGN_4(u4Len)])) = 0;
+ }
+
+ if (u4TotalLen >= DMA_THRESHOLD
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+ && is_predef_dyna_c_region((kal_uint32)pucBuf, u4TotalLen)
+#endif /* __ARM9_DCACHEABLE__ */
+ )
+ {
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+ dynamic_switch_cacheable_region((void *)&pucBuf, u4TotalLen, SWITCH_TO_NONCACHEABLE);
+#endif /*__ARM9_DCACHEABLE__*/
+ Data.rSDIOCMD53.buffer = (kal_uint32)pucBuf;
+ Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+ Data.rSDIOCMD53.addr = u2Port;
+ Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+ Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD53_WRITE, &Data);
+#if defined (__ARM9_DCACHEABLE__) || defined (__DYNAMIC_SWITCH_CACHEABILITY__)
+ dynamic_switch_cacheable_region((void *)&pucBuf, u4TotalLen, SWITCH_TO_CACHEABLE);
+#endif /*__ARM9_DCACHEABLE__*/
+ }
+ else
+ {
+ if (u4TotalLen >= DMA_THRESHOLD)
+ {
+ Data.rSDIOCMDREG.data = 1;
+
+ if (STATUS_OK != DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_FORCEMCU_WRITE, &Data))
+ {
+ msdc_dbg_print("SDIO_CTRL_CMD_FORCEMCU_WRITE failed %s %d!!", __FUNCTION__, __LINE__);
+ }
+ }
+
+ Data.rSDIOCMD53.buffer = (kal_uint32)pucBuf;
+ Data.rSDIOCMD53.func = DCL_SDIO_FUCN_1;
+ Data.rSDIOCMD53.addr = u2Port;
+ Data.rSDIOCMD53.op = DCL_SDIO_FIX;
+ Status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD53_WRITE, &Data);
+
+ if (u4TotalLen >= DMA_THRESHOLD)
+ {
+ Data.rSDIOCMDREG.data = 0;
+
+ if (STATUS_OK != DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_FORCEMCU_WRITE, &Data))
+ {
+ msdc_dbg_print("SDIO_CTRL_CMD_FORCEMCU_WRITE failed %s %d!!", __FUNCTION__, __LINE__);
+ }
+ }
+ }
+
+ //printk(KERN_INFO DRV_NAME"-- kalDevPortWrite-- ret=%d\n", ret);
+ if (Status != STATUS_OK)
+ {
+ msdc_dbg_print("kalDevPortWrite() reports error: %d", Status);
+ return KAL_FALSE;
+ }
+ else
+ {
+ return KAL_TRUE;
+ }
+} /* end of kalDevPortWrite() */
+
+
+kal_int32
+wlanImageSectionDownload (
+ // P_ADAPTER_T prAdapter,
+ kal_int32 u4DestAddr,
+ kal_int32 u4ImgSecSize,
+ kal_int8 *pucImgSecBuf
+)
+{
+
+
+ kal_uint32 i, u4Value;
+ P_HIF_HW_TX_HEADER_T prHifTxHeader;
+
+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
+
+ kal_uint8 * pucDmaBuf;
+ kal_uint32 u4TotalLen;
+ kal_uint32 u4DmaLen;
+ kal_uint32 u4DmaOffset;
+
+ //ASSERT(prAdapter);
+ //ASSERT(pucImgSecBuf);
+ //ASSERT(u4ImgSecSize <= CMD_PKT_SIZE_FOR_IMAGE);
+
+ msdc_dbg_print("wlanImageSectionDownload");
+ //DBGLOG(INIT, TRACE, ("Destination: 0x%08x / Length: 0x%08x\n", u4DestAddr, u4ImgSecSize));
+ msdc_dbg_print("Destination: 0x%08x / Length: 0x%08x", u4DestAddr, u4ImgSecSize);
+
+ if (u4ImgSecSize == 0)
+ {
+ return WLAN_STATUS_SUCCESS;
+ }
+
+ // 1. Use TX coalescing buffer
+ prHifTxHeader = (P_HIF_HW_TX_HEADER_T)(&wndrv_cmd_temp_buf[0]);
+
+ // 2. Setup HIF_TX_HEADER
+ //prHifTxHeader->u2TxByteCount = (UINT_16)(ALIGN_4(sizeof(HIF_HW_TX_HEADER_T) + u4ImgSecSize));
+ prHifTxHeader->u2TxByteCount = (kal_uint16)(ALIGN_4(HIF_HW_TX_HDR_SIZE + u4ImgSecSize));
+ prHifTxHeader->ucEtherTypeOffset = 0;
+ prHifTxHeader->ucCSflags = 0;
+
+ // 3. Copy payload
+ memcpy((void *)prHifTxHeader->aucBuffer, (void *)pucImgSecBuf, u4ImgSecSize);
+
+ // 3.1 add 4-bytes zero tail
+ //kalMemZero(&(prHifTxHeader->aucBuffer[ALIGN_4(u4ImgSecSize)]), sizeof(HIF_HW_TX_HEADER_T));
+ memset(&(prHifTxHeader->aucBuffer[ALIGN_4(u4ImgSecSize)]), 0, HIF_HW_TX_HDR_SIZE);
+
+ // 4. Poll til FWDL_RDY = 1
+ i = 0;
+
+ while (1)
+ {
+ kalDevRegRead(MCR_FWDLSR, &u4Value);//HAL_MCR_RD(prAdapter, MCR_FWDLSR, &u4Value);
+
+ if (u4Value & FWDLSR_FWDL_RDY)
+ {
+ //DBGLOG(INIT, TRACE, ("FWDL_RDY detected\n"));
+ msdc_dbg_print("FWDL_RDY detected", u4DestAddr, u4ImgSecSize);
+ break;
+ }
+ else if (i >= CFG_RESPONSE_POLLING_TIMEOUT)
+ {
+ //DBGLOG(INIT, ERROR, ("Waiting for FWDL_RDY: Timeout (0x%08X)\n", u4Value));
+ msdc_dbg_print("Waiting for FWDL_RDY: Timeout (0x%x)", u4Value);
+ u4Status = WLAN_STATUS_FAILURE;
+ break;
+ }
+ else
+ {
+ i++;
+ kal_sleep_task(10);
+ }
+ }
+
+ // 5. Send firmware
+ kalDevRegWrite(WEHTCR, ALIGN_4(prHifTxHeader->u2TxByteCount));//HAL_MCR_WR(prAdapter, WEHTCR, ALIGN_4(prHifTxHeader->u2TxByteCount));
+ u4TotalLen = ALIGN_4(prHifTxHeader->u2TxByteCount);
+
+ //HAL_PORT_WR(prAdapter,MCR_FWDLDR,u4TotalLen,(PUINT_8)prHifTxHeader,prAdapter->u4CoalescingBufCachedSize);
+ if (u4TotalLen > 4)
+ {
+ kalDevRegWrite(WEHTCR, ALIGN_4(u4TotalLen));//HAL_MCR_WR(_prAdapter, WEHTCR, ALIGN_4(u4TotalLen));
+ }
+
+ if (kalDevPortWrite(MCR_FWDLDR, u4TotalLen, (kal_uint8 *)prHifTxHeader) == KAL_FALSE)
+ {
+ //HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR);
+ //fgIsBusAccessFailed = TRUE;
+ msdc_dbg_print("HAL_PORT_WR access fail! 0x%x\n", MCR_FWDLDR);
+ }
+
+ kalDevRegWrite(WEHTCR, 4);//HAL_MCR_WR(prAdapter, WEHTCR, 4);
+
+ return u4Status;
+
+}
+void wndrv_wifi_hifsys_init( void )
+{
+ // P_ADAPTER_T prAdapter = wndrv_context.adpt_p;
+ kal_uint32 u4Value;
+ kal_uint32 counter = 0;
+
+ do
+ {
+ kalDevRegWrite(WHLPCR, 0x00000200);//HAL_MCR_WR( prAdapter, WHLPCR, 0x00000200 );
+ kalDevRegRead(WHLPCR, &u4Value);//HAL_MCR_RD(prAdapter, WHLPCR, &u4Value);
+
+ //kal_sleep_task(10);
+ if ( counter++ > 512 )
+ {
+ msdc_dbg_print("[eHPI test]Request FW-Own back failed! (times=%d)", counter );
+ break;
+ //ASSERT(0);
+ }
+ }
+ while ( !(u4Value & 0x00000100) );
+
+ kalDevRegWrite(WHIER, 0xffffff17);//HAL_MCR_WR( prAdapter, WHIER, 0xffffff17 );
+}
+int wndrv_prepare_test( int test_number )
+{
+ unsigned int response = 0;
+ //P_ADAPTER_T prAdapter = wndrv_context.adpt_p;
+ kal_uint32 reg_value = 0;
+ kal_uint32 ret;
+ kal_uint32 loop_count = 0;
+
+ msdc_dbg_print("wndrv_prepare_test():#%d", test_number);
+
+ /* write test number */
+ ret = kalDevRegWrite(H2DSM0R, (unsigned int)test_number);//HAL_MCR_WR( prAdapter, H2DSM0R, (unsigned int)test_number );
+
+ if (ret == -1)
+ {
+ msdc_dbg_print("Reg write error\r\n");
+ }
+
+
+ /* interrupt firmware: H2D[31] */
+ // HAL_MCR_WR( prAdapter, WSICR, 1 << 31 );
+ ret = kalDevRegWrite(WSICR, 0x80000000);//HAL_MCR_WR( prAdapter, WSICR, 0x80000000 );
+
+ if (ret == -1)
+ {
+ msdc_dbg_print("Reg write error\r\n");
+ }
+
+
+ /* wait for response */
+ while (1)
+ {
+ kalDevRegRead(WHISR, ®_value);//HAL_MCR_RD( prAdapter, WHISR, ®_value );
+
+ if ( reg_value & (0x80000000) ) /* check bit_31 of WHISR */
+ {
+ kalDevRegRead(D2HRM0R, &response);//HAL_MCR_RD( prAdapter, D2HRM0R, &response );
+ msdc_dbg_print("WHISR = [%x]", reg_value);
+ msdc_dbg_print("response = [%x]", response);
+ break;
+ }
+ else
+ {
+ kalDevRegWrite(WHIER, 0xffffff17);//HAL_MCR_WR( prAdapter, WHIER, 0xffffff17 ); /* enable interrupt */
+ kal_sleep_task(1);//kalUdelay(10);
+
+ //if ( loop_count++ > 500000 )
+ if ( loop_count++ > 5120 )
+ {
+ msdc_dbg_print("Pollin WHISR fail");
+ return -1;
+ }
+
+ msdc_dbg_print("Pollin WHISR...");
+ }
+ }
+
+ if ( response == test_number + 1 )
+ {
+ return 0;
+ }
+ else if ( response == test_number - 1 )
+ {
+ return -1;
+ }
+ else /* unexpected response */
+ {
+ return -1;
+ }
+}
+
+kal_int32 wndrv_generate_random_payload(unsigned char *buf, int len)
+{
+ int i;
+
+ //randomize();
+
+ for (i = 0 ; i < len ; i++)
+ buf[i] = (unsigned char)(rand() & 0xff);
+
+ return 0;
+}
+
+kal_int32 wndrv_generate_test_frame(unsigned char *buf, int len, Data_Pattern type)
+{
+ // controls pattern (initialization included)
+ //unsigned char test_cnt = 5;
+ //unsigned char i;
+ // unsigned char *payload = NULL;
+ unsigned short payload_s = 0;
+ unsigned char *dst = buf;
+ int offset = 0;
+ NIC_HIF_TX_HEADER_T txHeader;
+ // payload = get_ctrl_buffer(1500);
+ payload_s = len - sizeof(NIC_HIF_TX_HEADER_T);
+
+
+ // attach NIC_HIF_TX_HEADER_T in the head
+
+ txHeader.u2TxByteCount = len;
+ txHeader.ucEtherTypeOffset = 0x0;//(sizeof(NIC_HIF_TX_HEADER_T) + 12) / 2;
+ txHeader.ucCSUMFlags = 0x0; // [UT = 0 / I = 0]
+ txHeader.dummy[0] = 0x0;
+ txHeader.dummy[1] = 0x0;
+ txHeader.dummy[2] = 0x0;
+
+ kal_mem_cpy(&dst[offset], &txHeader, sizeof(NIC_HIF_TX_HEADER_T));
+ offset += sizeof(NIC_HIF_TX_HEADER_T);
+
+ // payload generation
+ switch (type)
+ {
+ case RANDOM:
+ if (payload_s > 0)
+ {
+ wndrv_generate_random_payload(&payload[0], payload_s);
+ }
+
+ break;
+
+ case DATA_FF:
+ memset (payload, 0xFF , payload_s);
+ break;
+
+ case DATA_00:
+ memset (payload, 0x00 , payload_s);
+ break;
+
+ case DATA_F0:
+ memset (payload, 0xF0 , payload_s);
+ break;
+
+ case DATA_0F:
+ memset (payload, 0x0F , payload_s);
+ break;
+
+ case DATA_55:
+ memset (payload, 0x55 , payload_s);
+ break;
+
+ case DATA_99:
+ memset (payload, 0x99 , payload_s);
+ break;
+
+ case DATA_AA:
+ memset (payload, 0xAA , payload_s);
+ break;
+
+ case DATA_66:
+ memset (payload, 0x66 , payload_s);
+ break;
+
+ default:
+ memset (payload, 0x11 , payload_s);
+ break;
+ }
+
+ // memcpy for generated frame
+ kal_mem_cpy(&dst[offset], &payload[0], payload_s);
+ // free_ctrl_buffer(payload);
+ return 0;
+}
+
+void HAL_PORT_WR(kal_uint16 _u4Port, kal_uint16 _u4Len, kal_uint8 * _pucBuf)
+{
+ if (_u4Len > 4)
+ {
+ kalDevRegWrite( WEHTCR, ALIGN_4(_u4Len));
+ }
+
+ if (kalDevPortWrite(_u4Port, _u4Len, _pucBuf) == KAL_FALSE)
+ {
+ msdc_dbg_print("HAL_PORT_WR access fail! 0x%x\n", _u4Port);
+ }
+ else
+ {
+ /*fgResult = TRUE;*/
+ }
+
+ kalDevRegWrite( WEHTCR, 4);
+}
+void HAL_PORT_RD(kal_uint16 _u4Port, kal_uint16 _u4Len, kal_uint8 * _pucBuf)
+{
+ if (_u4Len > 4)
+ {
+ kalDevRegWrite(WEHTCR, ALIGN_4(_u4Len));
+ }
+
+ if (kalDevPortRead(_u4Port, _u4Len, _pucBuf) == KAL_FALSE)
+ {
+ msdc_dbg_print(" access fail! 0x%x\n", _u4Port);
+ }
+ else
+ {
+ /*fgResult = TRUE;*/
+ }
+
+ kalDevRegWrite( WEHTCR, 4);
+}
+
+
+
+kal_int32 SDIO_test_main_MT5931_SDIOISR( SD_BITWIDTH bus )
+{
+ DCL_CTRL_DATA_T sdiodata;
+ DCL_CTRL_DATA_T Data;
+ DCL_SDC_CMD_STATUS status = STATUS_OK;
+ kal_uint32 counter, u4Status, u4Value, u4Pass = 0, u4FileSize, wndrv_firmware_loopback_size, u4Actual_length, reg_value, u4FwLoadAddr, i;
+ kal_uint8 const *wndrv_firmware_loopback_p;
+ kal_uint8 fgIsPass = 0;
+ kal_uint16 u2Packet_Len;
+ kal_uint8 TX_DMA = 0; //MCU
+ kal_uint8 RX_DMA = 0; //MCU
+ kal_uint8 data_type = 0;
+ kal_uint32 u4DmaLen, u4DmaOffset1, u4DmaOffset2;
+ kal_int32 ret;
+ // unsigned char *pucTXBuf = NULL;
+ // unsigned char *pucRXBuf = NULL;
+ kal_uint32 loopback_times = 10;
+ // pucTXBuf = get_ctrl_buffer(1500);
+ // pucRXBuf = get_ctrl_buffer(1500);
+
+POWER_ON_AGAIN:
+
+
+ msdc_dbg_print("[%s %d]start,bus=%d", __FUNCTION__, __LINE__, bus);
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+ //-------------------------------------------------------------------------
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+
+ //-------------------------------------------------------------------------
+ DclSDIO_Initialize();
+ handle_sdio = DclSDIO_Open(DCL_SDIO, DCL_SDIO_FLAGS_DEVICE_CARD1 | DCL_SDIO_FLAGS_USAGE_CMD | DCL_SDIO_FLAGS_SDIO1);
+ msdc_dbg_print( "[%s %d]The SDIO handle_sdio is 0x%x", __FUNCTION__, __LINE__, handle_sdio);
+
+ if ( handle_sdio == DCL_HANDLE_INVALID )
+ {
+ msdc_dbg_print("[%s %d]ERROR \r\n", __FUNCTION__, __LINE__);
+ return -1;
+ }
+
+ //-------------------------------------------------------------------------
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_INIT, NULL);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+
+ //-------------------------------------------------------------------------
+ status = SDIO_configure_bus(bus);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+ else
+ {
+ msdc_dbg_print("[%s %d]OK,bus=%d(0:1bit; 2:4bit)", __FUNCTION__, __LINE__, bus);
+ }
+
+ //-------------------------------------------------------------------------
+ sdiodata.rSDIOCMDREG.data = 128;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_MCUDMA_WRITE, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_MCUDMA_READ, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+ else
+ {
+ msdc_dbg_print("[%s %d]OK,mcudma=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMDREG.data);
+ }
+
+ //-------------------------------------------------------------------------
+ sdiodata.rSDIOCMDREG.data = 20000; // 20000KHZ
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_SETCLK, &sdiodata);
+
+ if (STATUS_OK == status)
+ {
+ sdiodata.rSDIOCMDREG.data = 0;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_GETCLK, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ kal_prompt_trace(MOD_MSDC_HISR, "[guilin %s %d]ERROR", __FUNCTION__, __LINE__);
+ return ;
+ }
+ else
+ {
+ kal_prompt_trace(MOD_MSDC_HISR, "[guilin %s %d]OK,SDIO_CTRL_CMD_GETCLK=%d", __FUNCTION__, __LINE__, sdiodata.rSDIOCMDREG.data);
+ }
+ }
+ else
+ {
+ kal_prompt_trace(MOD_MSDC_HISR, "[guilin %s %d]ERROR", __FUNCTION__, __LINE__);
+ return ;
+ }
+
+ //-------------------------------------------------------------------------
+ sdiodata.rSDIOCMDREG.data = 0;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CLKSRC_READ, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+ else
+ {
+ msdc_dbg_print("[%s %d]OK,clksrc=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMDREG.data);
+ }
+
+ //-------------------------------------------------------------------------
+ sdiodata.rSDIOCMDREG.data = 0;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_SCLKF_READ, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+ else
+ {
+ msdc_dbg_print("[%s %d]OK,sclkf=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMDREG.data);
+ }
+
+ //-------------------------------------------------------------------------
+ sdiodata.rSDIOCMDREG.data = 0;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CLKPADRED_READ, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+ else
+ {
+ msdc_dbg_print("[%s %d]OK,msdc_iocon.clkpadred=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMDREG.data);
+ }
+
+ //-------------------------------------------------------------------------
+ msdc_dbg_print("[%s %d]CCCR TEST \r\n", __FUNCTION__, __LINE__);
+ {
+ kal_int32 i;
+
+ for (i = 0; i < 0x14; i++)
+ {
+ sdiodata.rSDIOCMD52.func = DCL_SDIO_FUCN_0;
+ sdiodata.rSDIOCMD52.addr = i;
+ sdiodata.rSDIOCMD52.rdata = 0;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD52_READ, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+ else
+ {
+ msdc_dbg_print("[%s %d]OK,CCCR[0x%x]=0x%x,R5=0x%x \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMD52.addr, sdiodata.rSDIOCMD52.rdata, sdiodata.rSDIOCMD52.r5_resp);
+ }
+ }
+ }
+ //-------------------------------------------------------------------------
+ sdiodata.rSDIOCMD52.func = DCL_SDIO_FUCN_0;
+ sdiodata.rSDIOCMD52.addr = 4;
+ sdiodata.rSDIOCMD52.wdata = 3;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD52_WRITE, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+ else
+ {
+ sdiodata.rSDIOCMD52.func = DCL_SDIO_FUCN_0;
+ sdiodata.rSDIOCMD52.addr = 4;
+ sdiodata.rSDIOCMD52.rdata = 0;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_CMD52_READ, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+ else
+ msdc_dbg_print("[%s %d]OK,CCCR[0x%x]=0x%x,R5=0x%x \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOCMD52.addr, sdiodata.rSDIOCMD52.rdata, sdiodata.rSDIOCMD52.r5_resp);
+ }
+
+ //-------------------------------------------------------------------------
+ msdc_dbg_print("[%s %d]SET BLOCKSIZE=512 \r\n", __FUNCTION__, __LINE__);
+ sdiodata.rSDIOSetBlkSize.function = DCL_SDIO_FUCN_0;
+ sdiodata.rSDIOSetBlkSize.size = 512;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_SET_BLK_SIZE, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+
+ sdiodata.rSDIOSetBlkSize.size = 0;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_GET_BLK_SIZE, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+ else
+ {
+ msdc_dbg_print("[%s %d]OK,blocksize=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOSetBlkSize.size);
+ }
+
+ sdiodata.rSDIOSetBlkSize.function = DCL_SDIO_FUCN_1;
+ sdiodata.rSDIOSetBlkSize.size = 512;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_SET_BLK_SIZE, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+
+ sdiodata.rSDIOSetBlkSize.size = 0;
+ status = DclSDIO_Control (handle_sdio, SDIO_CTRL_CMD_GET_BLK_SIZE, &sdiodata);
+
+ if (STATUS_OK != status)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+ else
+ {
+ msdc_dbg_print("[%s %d]OK,blocksize=%d \r\n", __FUNCTION__, __LINE__, sdiodata.rSDIOSetBlkSize.size);
+ }
+
+ //guilin
+ status = kalDevWriteWithSdioCmd52(4, 3); // enable sdio interrupt
+
+ if (status != STATUS_OK)
+ {
+ msdc_dbg_print("[%s %d]Error,%d", __FUNCTION__, __LINE__, status);
+ return;
+ }
+
+ //-------------------------------------------------------------------------
+
+ //-------------------------------------------------------------------------
+ /* 0. Read Chip ID */
+ if (STATUS_OK != kalDevRegRead(WCIR, &u4Value)) //HAL_MCR_RD( prAdapter, WCIR, &u4Value );
+ {
+ msdc_dbg_print("[%s %d]Error", __FUNCTION__, __LINE__);
+ return;
+ }
+ else
+ {
+ msdc_dbg_print("[eHPI test]Chip ID = %x", u4Value & 0xfffff );
+ }
+
+ /* 1.1 wait for INIT_RDY */
+ i = 0;
+
+ while (1)
+ {
+ kalDevRegRead(MCR_WMCSR, &u4Value);//HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
+
+ if (u4Value & WMCSR_INI_RDY)
+ {
+ msdc_dbg_print("INIT-RDY detected");
+ break;
+ }
+ else if (i >= CFG_RESPONSE_POLLING_TIMEOUT)
+ {
+ msdc_dbg_print("Waiting for Init Ready bit: Timeout");
+ u4Status = WLAN_STATUS_FAILURE;
+ //ASSERT(u4Status == WLAN_STATUS_SUCCESS);
+ return;
+ }
+ else
+ {
+ i++;
+ kal_sleep_task(10);
+ }
+ }
+
+ wndrv_firmware_loopback_size = sizeof(mt5931_E3_Beta_loopback_firmware_hex);
+ u4FileSize = wndrv_firmware_loopback_size;
+ /* 1.2 set KSEL/FLEN */
+ msdc_dbg_print("1.2 set KSEL/FLEN = %d", u4FileSize);
+ kalDevRegWrite(MCR_FWCFG, u4FileSize >> 6);// HAL_MCR_WR(prAdapter, MCR_FWCFG, u4FileSize >> 6);
+ /* 1.3 enable FWDL_EN */
+ msdc_dbg_print("1.3 enable FWDL_EN");
+ kalDevRegWrite(FWDLCMR0, WMCSR_FWDLEN | WMCSR_FWDLRST); //HAL_MCR_WR( prAdapter, FWDLCMR0, WMCSR_FWDLEN|WMCSR_FWDLRST);
+ kalDevRegWrite(FWDLCMR0, WMCSR_FWDLEN);//HAL_MCR_WR( prAdapter, FWDLCMR0, WMCSR_FWDLEN);
+ /* 1.4 wait for PLL_RDY */
+ msdc_dbg_print("1.4 wait for PLL_RDY");
+ i = 0;
+
+ while (1)
+ {
+ kalDevRegRead(MCR_WMCSR, &u4Value);//HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
+ msdc_dbg_print("[%s %d]MCR_WMCSR=0x%x ", __FUNCTION__, __LINE__, u4Value);
+
+ if (u4Value & WMCSR_PLLRDY)
+ {
+ msdc_dbg_print("PLL-RDY detected\n");
+ break;
+ }
+ else if (i >= CFG_RESPONSE_POLLING_TIMEOUT)
+ {
+ msdc_dbg_print("Waiting for PLL Ready bit: Timeout\n");
+ u4Status = WLAN_STATUS_FAILURE;
+ //kal_sleep_task(1000);
+ //goto POWER_ON_AGAIN;
+ return;
+ }
+ else
+ {
+ i++;
+ kal_sleep_task(10);
+ }
+ }
+
+ /* 2.1 turn on HIFSYS firmware download mode */
+ msdc_dbg_print("2.1 turn on HIFSYS firmware download mode");
+ kalDevRegWrite(MCR_FWDLSR, FWDLSR_FWDL_MODE);//HAL_MCR_WR(prAdapter, MCR_FWDLSR, FWDLSR_FWDL_MODE);
+ /* 2.2 set starting address */
+ wndrv_firmware_loopback_p = mt5931_E3_Beta_loopback_firmware_hex;
+ u4FwLoadAddr = CFG_FW_LOAD_ADDRESS;
+ kalDevRegWrite(MCR_FWDLDSAR, u4FwLoadAddr);//HAL_MCR_WR(prAdapter, MCR_FWDLDSAR, u4FwLoadAddr);
+ msdc_dbg_print("[eHPI test]0. Firmware Download" );
+
+ for (i = 0; i < u4FileSize ; i += CMD_PKT_SIZE_FOR_IMAGE)
+ {
+ if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FileSize)
+ u4Actual_length = CMD_PKT_SIZE_FOR_IMAGE;
+ else
+ u4Actual_length = u4FileSize - i;
+
+ //if(wlanImageSectionDownload(prAdapter,u4FwLoadAddr + i,u4Actual_length,(kal_uint8 *)wndrv_firmware_loopback_p + i) != WLAN_STATUS_SUCCESS)
+ if (wlanImageSectionDownload(u4FwLoadAddr + i, u4Actual_length, (kal_uint8 *)wndrv_firmware_loopback_p + i) != WLAN_STATUS_SUCCESS)
+ {
+ msdc_dbg_print("Firmware scatter download failed!");
+ return;
+ }
+ }
+
+ /* 4.1 poll FWDL_OK & FWDL_FAIL bits */
+ i = 0;
+
+ while (1)
+ {
+ kalDevRegRead(MCR_WMCSR, &u4Value);//HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value);
+ msdc_dbg_print("[%s %d]MCR_WMCSR=0x%x ", __FUNCTION__, __LINE__, u4Value);
+
+ if (u4Value & WMCSR_DL_OK)
+ {
+ msdc_dbg_print("DL_OK detected\n");
+ break;
+ }
+ else if (i >= CFG_RESPONSE_POLLING_TIMEOUT)
+ {
+ msdc_dbg_print("Waiting for DL_OK/DL_FAIL bit: Timeout\n");
+ u4Status = WLAN_STATUS_FAILURE;
+ //ASSERT(u4Status == WLAN_STATUS_SUCCESS); //TODO(Nelson): error handling for this
+ return;
+ }
+ else
+ {
+ i++;
+ kal_sleep_task(10);
+ }
+ }
+
+ /* 4.2 turn off HIFSYS download mode */
+ kalDevRegWrite(MCR_FWDLSR, 0);//HAL_MCR_WR(prAdapter, MCR_FWDLSR, 0);
+
+ /* 5. disable interrupt */
+ kalDevRegWrite(MCR_WHLPCR, WHLPCR_INT_EN_CLR);//HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR);//nicDisableInterrupt(prAdapter);
+
+ msdc_dbg_print("wlanAdapterStart(): Waiting for Ready bit..\n");
+ /* 6. check Wi-Fi FW asserts ready bit */
+ i = 0;
+
+ while (1)
+ {
+ kalDevRegRead(MCR_WCIR, &u4Value);//HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value);
+
+ if (u4Value & WCIR_WLAN_READY)
+ {
+ msdc_dbg_print("Ready bit asserted\n");
+ break;
+ }
+ else if (i >= CFG_RESPONSE_POLLING_TIMEOUT)
+ {
+ msdc_dbg_print("Waiting for Ready bit: Timeout\n");
+ u4Status = WLAN_STATUS_FAILURE;
+ //ASSERT(u4Status == WLAN_STATUS_SUCCESS); //TODO(Nelson): error handling for this
+ return;
+ }
+ else
+ {
+ i++;
+ kal_sleep_task(10);
+ }
+ }
+
+ msdc_dbg_print("[eHPI test]1. Chip ID/Revision ID" );
+ kalDevRegRead(WCIR, ®_value );//HAL_MCR_RD( prAdapter, WCIR, ®_value );
+ msdc_dbg_print("[eHPI test]Chip ID/Revision ID = %x", reg_value );
+
+ msdc_dbg_print("[eHPI test]2. Request FW-Own back" );
+ kalDevRegWrite(MCR_WHLPCR, WHLPCR_INT_EN_SET);//HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_SET);
+
+
+#if 1
+ {
+ DCL_HANDLE handle_eint1;
+
+ //handle_eint1 = DclGPIO_Open(DCL_GPIO,MT5931_EINT); // MT5931,WIFI_EINT
+ //DclGPIO_Control(handle_eint1,GPIO_CMD_SET_MODE_6,0);
+ //DclGPIO_Control(handle_eint1,GPIO_CMD_SET_MODE_3,0);
+ //DclGPIO_Close(handle_eint1);
+
+ EINT_Registration( MT5931_EINT_NUM,
+ KAL_FALSE, /* DbounceEn */
+ KAL_TRUE, /* ACTPolarity */
+ test_hisr,
+ KAL_FALSE/* AutoUnmask */ );
+ /* set new debounce value */
+ EINTaddr(MT5931_EINT_NUM) |= 2;
+ /* Set Software debounce time 0 */
+ EINT_SW_Debounce_Modify(MT5931_EINT_NUM, 0);
+
+ // James modify for setting GPIO52 enable
+ kal_sleep_task(10);
+
+
+ }
+#endif
+ msdc_dbg_print("[%s %d]", __FUNCTION__, __LINE__);
+ wndrv_wifi_hifsys_init();
+ ret = kalDevRegWrite(MCR_WHLPCR, WHLPCR_INT_EN_SET);
+
+ if ( wndrv_prepare_test( 3 ) == -1 ) /* item 3 for intr loopback test */
+ {
+ msdc_dbg_print("Test #1: FW cannot do the test.\n");
+ //ASSERT(0);
+ }
+
+#if 1
+ /* Loopback test TXRX*/
+ fgIsPass = 1;
+ kalDevRegRead(WHCR, ®_value);//HAL_MCR_RD( prAdapter, WHCR, ®_value );
+ kalDevRegWrite(WHCR, reg_value | 0x00010000);//HAL_MCR_WR( prAdapter, WHCR, reg_value | 0x00010000 ); //Enable RX_Enhance_Mode
+ kalDevRegRead(WHCR, ®_value);//HAL_MCR_RD( prAdapter, WHCR, ®_value );
+ msdc_dbg_print("WHCR: %x\n", reg_value);
+ msdc_dbg_print("[eHPI test]>>WIFI HIFSYS Loopback test");
+
+ u2Packet_Len = TEST_PACKET_MIN_LENGTH;
+
+ do
+ {
+ u2Packet_Len = u2Packet_Len < TEST_PACKET_MAX_LENGTH ? u2Packet_Len += 4 : TEST_PACKET_MIN_LENGTH;
+ data_type = u4Pass % 10;
+ TX_DMA = (u4Pass + 3) % 3;
+ RX_DMA = (u4Pass + 2) % 2;
+ TX_DMA = 1;
+ RX_DMA = 1;
+
+ //TX with DMA or MCU Start
+ if (TX_DMA)
+ {
+ u4DmaLen = u2Packet_Len;
+ u4DmaOffset1 = CPU_CACHE_LINE_SIZE - ((kal_uint32)ucDmaBuf & CPU_CACHE_LINE_SIZE_MASK);
+
+ //1. 32byte non-ailgn block
+ if ( (u4DmaOffset1 != 0) && (u4DmaOffset1 != CPU_CACHE_LINE_SIZE) )
+ {
+ u4DmaLen -= u4DmaOffset1;
+ }
+
+ //2. 32byte-align block, Only 32byte-align block will be TX
+ u4DmaOffset2 = u4DmaLen & CPU_CACHE_LINE_SIZE_MASK;
+ //u4DmaLen -=u4DmaOffset2;
+ // generate test frame
+ wndrv_generate_test_frame(ucDmaBuf + u4DmaOffset1, u4DmaLen, (Data_Pattern) data_type);
+ kalDevRegWrite(WEHTCR, ALIGN_32(u4DmaLen));//HAL_MCR_WR(prAdapter, WEHTCR, ALIGN_32(u4DmaLen));
+ //kalDevPortWriteData( WTDR0, ALIGN_4(u4DmaLen), &ucDmaBuf[u4DmaOffset1] );
+ HAL_PORT_WR( WTDR0, u4DmaLen, ucDmaBuf + u4DmaOffset1);
+ kal_mem_cpy(pucTXBuf, ucDmaBuf + u4DmaOffset1, u4DmaLen);
+ //3. remain 32byte non-align block
+ /*pucTXBuf += u4DmaLen;
+ u4DmaLen = u4DmaOffset2;
+
+ if( u4DmaLen != 0)
+ {
+ kalDevPortWriteData(MCR_WTDR0, u4DmaLen, pucTXBuf);
+ }*/
+ }
+ else
+ {
+ u4DmaLen = u2Packet_Len;
+ u4DmaOffset1 = 0;
+ wndrv_generate_test_frame(pucTXBuf, u4DmaLen, (Data_Pattern) data_type);
+ kalDevRegWrite(WEHTCR, u4DmaLen);//HAL_MCR_WR( prAdapter, WEHTCR, u4DmaLen );
+ HAL_PORT_WR( WTDR0, u4DmaLen, pucTXBuf);
+ }
+
+ //TX with DMA or MCU END
+
+ counter = 0;
+
+ while (1)
+ {
+ kalDevRegRead(WHISR, ®_value);//HAL_MCR_RD( prAdapter, WHISR, ®_value );
+
+ if ( reg_value & 0x1 ) /* check TX0 TX1 done */
+ {
+ kalDevRegRead(WTSR0, ®_value);//HAL_MCR_RD( prAdapter, WTSR0, ®_value );
+ //WNDRV_PROMPT_TRACE0( TRACE_INFO, "[eHPI test]>> TX Done");
+ }
+ else if ( reg_value & 0x2 ) /* check RX0 RX1 done */
+ {
+ kalDevRegRead(WTSR0, ®_value);//HAL_MCR_RD( prAdapter, WTSR0, ®_value );
+ kal_sleep_task(10);
+ kalDevRegRead(WRPLR, ®_value);//HAL_MCR_RD( prAdapter, WRPLR, ®_value );
+ kalDevRegWrite(WEHTCR, reg_value);//HAL_MCR_WR( prAdapter, WEHTCR, reg_value );
+
+ if (RX_DMA)
+ {
+ u4DmaOffset1 = CPU_CACHE_LINE_SIZE - ((kal_uint32)ucDmaBuf & CPU_CACHE_LINE_SIZE_MASK);
+ reg_value = (reg_value + 31) & ~31u;
+ HAL_PORT_RD(WRDR0, reg_value, ucDmaBuf + u4DmaOffset1);
+ kal_mem_cpy(pucRXBuf, ucDmaBuf + u4DmaOffset1, u4DmaLen);
+ }
+ else
+ {
+ HAL_PORT_RD(WRDR0, reg_value, &pucRXBuf[0]);
+ }
+
+ break;
+ }
+ else
+ {
+ kal_sleep_task(10);
+ kalDevRegWrite(WHIER, 0xffffff17);//HAL_MCR_WR( prAdapter, WHIER, 0xffffff17 );
+
+ if ( counter++ > 1024 )
+ {
+ msdc_dbg_print("[eHPI test]>> loopback test fail");
+ fgIsPass = 0;
+ DclSDIO_Close(handle_sdio);//wlanAdapterStop(prAdapter);
+ return;
+ }
+ }
+ }
+
+ counter = 0;
+ reg_value = 0;
+
+ for (i = 0; i < (u4DmaLen - 16); i++)
+ {
+ u4Value = pucTXBuf[i + 16] - pucRXBuf[i + 12];
+
+ if (u4Value == 0)
+ {
+ counter++;
+ }
+ else
+ {
+ reg_value ++;
+ msdc_dbg_print("[eHPI test] Data Compare error, TX Mode: %x, RX Mode\n", TX_DMA, RX_DMA);
+ return;//ASSERT(0);
+ }
+ }
+
+ msdc_dbg_print("[eHPI test] Data Compare OK, TX Mode: %x, RX Mode\n", TX_DMA, RX_DMA);
+ kalDevRegWrite(WHIER, 0xffffff17);//HAL_MCR_WR( prAdapter, WHIER, 0xffffff17 );
+ kal_sleep_task(100);
+ u4Pass++ ;
+ msdc_dbg_print("[eHPI test]packets pass: %x", u4Pass );
+ }
+ while (u4Pass < loopback_times);
+
+ if ( fgIsPass == 1 )
+ {
+ msdc_dbg_print("[eHPI test]Total packets pass: 0x%x", u4Pass );
+ msdc_dbg_print("[eHPI test]Each Test Patern pass: 0x%x", u4Pass);
+ msdc_dbg_print("[eHPI test]TX DMA->RX DMA pass: 0x%x", u4Pass );
+ msdc_dbg_print("[eHPI test]TX DMA->RX MCU pass: 0x%x", u4Pass );
+ msdc_dbg_print("[eHPI test]TX MCU->RX DMA pass: 0x%x", u4Pass );
+ msdc_dbg_print("[eHPI test]TX MCU->RX MCU pass: 0x%x", u4Pass );
+ msdc_dbg_print("[eHPI test]Packet size 200 - 1500 loop count: 0x%x", u4Pass);
+ }
+
+ DclSDIO_Close(handle_sdio);//wlanAdapterStop(prAdapter);
+ // free_ctrl_buffer(pucTXBuf);
+ // free_ctrl_buffer(pucRXBuf);
+#endif
+
+ msdc_dbg_print("[%s %d]END", __FUNCTION__, __LINE__);
+}
+
+
+#endif
+
+#ifdef DRV_MSDC_BT
+
+#define MSC_CFG (MSDC_ADRS+0x60)
+#define MSC_CMD (MSDC_ADRS+0x64)
+
+#define MSC_CFG_SIEN 0x0001
+#define MSC_CFG_PMODE 0x8000
+
+kal_uint8 msdc_dmaport, msdc_dmaport2;
+DMA_INPUT msdc_input, msdc_input2;
+DMA_HWMENU msdc_menu, msdc_menu2;
+kal_uint32 tempReg;
+
+#pragma arm section zidata = "NONCACHEDZI", rwdata = "NONCACHEDRW"
+kal_uint32 msdc_bt_buffer[128];
+#pragma arm section zidata, rwdata
+
+msdc_bt()
+{
+ kal_uint32 loopIndex2;
+ kal_uint32 baseAddrSpace;
+ dbg_print("MSDC_bt start\n\r");
+
+ //baseAddrSpace = MSDC2_base - MSDC_base;
+
+ /*turn on MSDC power gating*/
+#ifdef __OLD_PDN_ARCH__
+ DRVPDN_Disable(DRVPDN_CON1, DRVPDN_CON1_MSDC, PDN_MSDC);
+#else
+ DRVPDN_Disable(PDN_MSDC);
+#endif
+
+ //DRVPDN_Disable(DRVPDN_CON0,DRVPDN_CON0_MSDC2,PDN_MSDC2);
+
+ if (NULL == msdc_dmaport)
+ {
+ msdc_dmaport = DMA_GetChannel(DMA_MSDC);
+ msdc_menu.TMOD.burst_mode = KAL_TRUE;
+ msdc_menu.TMOD.cycle = 0x4;
+ msdc_menu.master = DMA_MSDC;
+ msdc_menu.addr = (kal_uint32)msdc_bt_buffer;
+ msdc_input.type = DMA_HWRX;
+ msdc_input.size = DMA_LONG;
+ msdc_input.count = 128;
+ msdc_input.menu = &msdc_menu;
+
+
+ //msdc_dmaport2 = DMA_GetChannel(DMA_MSDC2);
+ //msdc_menu2.TMOD.burst_mode = KAL_TRUE;
+ //msdc_menu2.TMOD.cycle = 0x4;
+ //msdc_menu2.master = DMA_MSDC2;
+ //msdc_menu2.addr = (kal_uint32)msdc_bt_buffer;
+ //msdc_input2.type = DMA_HWRX;
+ //msdc_input2.size = DMA_LONG;
+ //msdc_input2.count = 128;
+ //msdc_input2.menu = &msdc_menu2;
+
+ }
+
+
+
+ /*
+ 0x81110000 = 0x1aa20021
+ 0x81110004 = 0x2
+ 0x81110010 = 0x010F0008
+ 0x81110014 = 0x01000036
+ 0x81110020 = 0x28038200
+ 0x81110028 = 0x00048200
+ write 0x02898 to 0x81110024 to write single block in 4bit SD mode
+ */
+
+ /*
+ 0x81110000 = 0x1aa20021
+ 0x81110004 = 0x2
+ 0x81110010 = 0x010F0008
+ 0x81110014 = 0x01000036
+ 0x81110020 = 0x28038200
+ 0x81110028 = 0x0
+ write 0x0891 to 0x81110024 to read single block in 4bit SD mode
+ */
+
+ /*MSDC 1*/
+
+ /*configure DMA*/
+ msdc_input.type = DMA_HWTX;
+ DMA_Config_B2W(msdc_dmaport, &msdc_input, KAL_TRUE, KAL_FALSE);
+ DRV_WriteReg32(MSDC_CFG, 0x1aa20021);
+ DRV_WriteReg32(MSDC_STA, 0x2);
+ DRV_WriteReg32(MSDC_PS, 0x010F0008);
+ DRV_WriteReg32(MSDC_IOCON, 0x01000036);
+ DRV_WriteReg32(SDC_CFG, 0x28038200);
+ DRV_WriteReg32(SDC_ARG, 0x00048200);
+ DRV_WriteReg32(SDC_CMD, 0x02898);
+
+ /*wait data transfer*/
+ for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+ /*read out CMDSTA and DATSTA*/
+ tempReg = DRV_Reg32(SDC_CMDSTA);
+ tempReg = DRV_Reg32(SDC_DATSTA);
+
+ DMA_Stop(msdc_dmaport);
+ /*stop MSDC DMA and reset MSDC*/
+ DRV_ClearBits32(MSDC_CFG, MSDC_CFG_DRQEN);
+ DRV_SetBits32(MSDC_CFG, MSDC_CFG_RST);
+
+ for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+ DRV_ClearBits32(MSDC_CFG, MSDC_CFG_RST);
+
+ msdc_input.type = DMA_HWRX;
+ DMA_Config_B2W(msdc_dmaport, &msdc_input, KAL_TRUE, KAL_FALSE);
+ DRV_WriteReg32(MSDC_CFG, 0x1aa20021);
+ DRV_WriteReg32(MSDC_STA, 0x2);
+ DRV_WriteReg32(MSDC_PS, 0x010F0008);
+ DRV_WriteReg32(MSDC_IOCON, 0x01000036);
+ DRV_WriteReg32(SDC_CFG, 0x28038200);
+ DRV_WriteReg32(SDC_ARG, 0x0);
+ DRV_WriteReg32(SDC_CMD, 0x0891);
+
+ /*wait data transfer*/
+ for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+ /*read out CMDSTA and DATSTA*/
+ tempReg = DRV_Reg32(SDC_CMDSTA);
+ tempReg = DRV_Reg32(SDC_DATSTA);
+
+ DMA_Stop(msdc_dmaport);
+ /*stop MSDC DMA and reset MSDC*/
+ DRV_ClearBits32(MSDC_CFG, MSDC_CFG_DRQEN);
+ DRV_SetBits32(MSDC_CFG, MSDC_CFG_RST);
+
+ for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+ DRV_ClearBits32(MSDC_CFG, MSDC_CFG_RST);
+
+ /*MS test*/
+ DRV_ClearBits32(MSDC_CFG, MSDC_CFG_MSDC);
+ DRV_SetBits(MSC_CFG, (MSC_CFG_PMODE | MSC_CFG_SIEN));
+ DRV_WriteReg(MSC_CMD, 0x20200);
+
+ for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+ DRV_SetBits32(MSDC_CFG, MSDC_CFG_RST);
+
+ for (loopIndex2 = 0; 4000 > loopIndex2; loopIndex2++);
+
+ DRV_ClearBits32(MSDC_CFG, MSDC_CFG_RST);
+
+
+ /*MSDC 2*/
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+ dbg_print("msdc_bt end\n\r");
+
+
+
+
+}
+#endif
+
+#ifdef MSDC_SDIO_DVT
+extern void test_sdio_ini(void );
+
+void MSDC_DVT_SDIO_test(void)
+{
+ test_sdio_ini();
+}
+#endif
+
+#ifdef MSDC2_SDIO_DVT
+extern void test_sdio_ini(void );
+
+void MSDC2_DVT_SDIO_test(void)
+{
+ test_sdio_ini();
+}
+#endif
+
+#ifdef __MSDC_BASIC_LOAD__
+
+
+
+void ssdbg1_main_msdc(task_entry_struct *task_entry_ptr)
+{
+ SDC_CMD_STATUS status;
+ ilm_struct current_ilm;
+ ssdbg1_localpara_struct *paraptr;
+ kal_uint32 my_index;
+
+ kal_uint32 i = 0;
+ double bestReadThroughput4Bit, worstReadThroughput4Bit, bestWriteThroughput4Bit, worstWriteThroughput4Bit;
+ kal_uint32 offset = 0, blkaddr, idx, loop;
+ char str[30];
+
+ /*
+ #ifdef MSDC_SDIO_DVT
+ MSDC_DVT_SDIO_test();
+ gMSDC_Handle->mIsInitialized = KAL_FALSE;
+ waitingSDIOTest = KAL_FALSE;
+ #endif
+
+ if(waitingSDIOTest){
+ kal_sleep_task(20);
+ }
+ */
+
+ kal_get_my_task_index (&my_index);
+ stack_set_active_module_id ( my_index, MOD_SSDBG1 );
+
+ //
+ // Initialize ILM, and timer
+ //
+ stack_init_timer(&ssdbg1_context.ssdbg1_timer0, "SSDBG1 Timer0", MOD_SSDBG1);
+
+ stack_start_timer(&ssdbg1_context.ssdbg1_timer0, 0, 10);
+
+ while (1)
+ {
+ kal_uint32 input, input2;
+ kal_uint32 addr;
+
+ MSDC_PDNControl(KAL_FALSE);
+
+ dbg_print("\r\n");
+ dbg_print("*********************************************************\r\n");
+ dbg_print("* *\r\n");
+ dbg_print("* MT6280 MSDC Basicload *\r\n");
+ dbg_print("* *\r\n");
+ dbg_print("*********************************************************\r\n");
+
+ dbg_print("============================\r\n");
+ dbg_print(" 1 mount test...\r\n");
+ dbg_print(" 2 reg default test...\r\n");
+ dbg_print(" 3 read single test...\r\n");
+ dbg_print(" 4 write single test...\r\n");
+ dbg_print(" 5 read multi test...\r\n");
+ dbg_print(" 6 write multi test...\r\n");
+ dbg_print(" 7 set clock/odc...\r\n");
+ dbg_print(" 8 1-4 bit BUS test...\r\n");
+ dbg_print(" 9 read/write stress test...\r\n");
+ dbg_print("10 non-4N test...\r\n");
+ dbg_print("11 cache test...\r\n");
+ dbg_print("12 mount stress test...\r\n");
+ dbg_print("13 clock stress test...\r\n");
+ dbg_print("14 CLKPAD_RED test...\r\n");
+ dbg_print("15 FAT fastformat test...\r\n");
+ dbg_print("16 DMA.fix test...\r\n");
+ dbg_print("17 error test...\r\n");
+ dbg_print("18 odd-size test...\r\n");
+ dbg_print("19 burst type test...\r\n");
+ dbg_print("20 erase test...\r\n");
+ dbg_print("21 gpio test...\r\n");
+ dbg_print("22 \r\n");
+ dbg_print("23 throughput test...\r\n");
+ dbg_print("24 SD CMD test...\r\n");
+ dbg_print("25 MSDC initialize...\r\n");
+ dbg_print("26 dump register...\r\n");
+ dbg_print("27 set block number...\r\n");
+ dbg_print("28 edit script...\r\n");
+ dbg_print("29 sdio initialize test...\r\n");
+ dbg_print("30 sdio read/write test...\r\n");
+ dbg_print("31 sdio interrupt test...\r\n");
+ dbg_print("32 sdio MT5931 1-bit test...\r\n");
+ dbg_print("33 sdio MT5931 4-bit test...\r\n");
+ dbg_print("34 memory card sequential read...\r\n");
+ dbg_print("35 memory card sequential write...\r\n");
+ dbg_print("36 memory card random read...\r\n");
+ dbg_print("37 memory card random write...\r\n");
+ dbg_print("============================\r\n");
+
+ dbg_print("input:");
+ //input = U_GetUARTByte(uart_port1);
+ msdc_dbg_input(&input);
+ dbg_print("%d\r\n", input);
+
+ switch (input)
+ {
+ case 1:
+ sdtestcase1();
+ break;
+
+ case 2:
+ sdtestcase2();
+ break;
+
+ case 3:
+ sdtestcase3(rand()%gSD->mCSD.capacity / 512 - 1, msdc_sector_buf1);;
+ break;
+
+ case 4:
+ sdtestcase4(0, msdc_sector_buf1, msdc_sector_buf2);
+ break;
+
+ case 5:
+ sdtestcase5(0, msdc_uncachedBuf1);
+ break;
+
+ case 6:
+ sdtestcase6(0, msdc_uncachedBuf1, msdc_uncachedBuf2);
+ break;
+
+ case 7:
+ sdtestcase7();
+ break;
+
+ case 8:
+ sdtestcase8();
+ break;
+
+ case 9:
+ sdtestcase9();
+ break;
+
+ case 10:
+ sdtestcase10();
+ break;
+
+ case 11:
+ sdtestcase11();
+ break;
+
+ case 12:
+ sdtestcase12();
+ break;
+
+ case 13:
+ dbg_print("Input a test round:");
+ msdc_dbg_input(&input);
+ dbg_print("%c\r\n", input);
+
+ dbg_print("Input a count of one round:");
+ msdc_dbg_input(&input2);
+ dbg_print("%c\r\n", input2);
+
+ for (i = 0; i < input; i++)
+ {
+ status = sdtestcase13(input2);
+
+ if (status != NO_ERROR)
+ break;
+ }
+
+ break;
+
+ case 14:
+ sdtestcase14();
+ break;
+
+ case 15:
+ sdtestcase15();
+ break;
+
+ case 16:
+ sdtestcase16();
+ break;
+
+ case 17:
+ sdtestcase17();
+ break;
+
+ case 18:
+ sdtestcase18();
+ break;
+
+ case 19:
+ sdtestcase19();
+ break;
+
+ case 20:
+ sdtestcase20(0, testsectors);
+ break;
+
+ case 21:
+ sdtestgpio2();
+ break;
+
+ case 22:
+
+ break;
+
+ case 23:
+ dbg_print("Input a test round:");
+ msdc_dbg_input(&input);
+ dbg_print("%c\r\n", input);
+
+ sdtestcase21(input);
+ break;
+
+ case 24:
+ sdtestcase22();
+ break;
+
+ case 25:
+ i = 0;
+ gMSDC_Handle->mIsInitMSDC = KAL_FALSE;
+ gMSDC_Handle->mIsInitialized = KAL_FALSE;
+ gMSDC_Handle->msdc_clkTuneUpperBund = MSDC_CLOCK / 2;
+ MSDC_PDNControl(KAL_FALSE);
+ kal_sleep_task(1);
+
+
+
+ MSDC_LSD_SetBits32(MSDC_CFG, MSDC_CFG_RST);
+
+ while (MSDC_Reg32(MSDC_CFG) & 0x02)
+ {
+ i++;
+ }
+
+ dbg_print("%d\r\n", i);
+
+ DclSD_Initialize();
+ break;
+
+ case 26:
+
+ dbg_print("\r\n0x");
+
+ while (1)
+ {
+ input = U_GetUARTByte(uart_port1);
+
+ if (input == 0x0d || input == 0x0a)
+ break;
+
+ if (input == ESCKEY)
+ return;
+
+ str[offset++] = input;
+ dbg_print("%c", input);
+ }
+
+ str[offset] = 0;
+
+ dbg_print("\r\n");
+ sscanf(str, "%x", &input2);
+
+ dbg_print("\r\n %x", MSDC_Reg32(input2));
+ break;
+
+ case 27:
+ dbg_print("input a block number:\r\n");
+ msdc_dbg_input(&testblnum);
+ dbg_print("%c\r\n", testblnum);
+ break;
+
+ case 28:
+ dbg_print("input test case number:(ESC to cancel)\r\n");
+
+ while (1)
+ {
+
+ msdc_dbg_input(&input);
+
+
+
+ }
+
+ break;
+
+ case 29:
+
+ status = vSDIOInitialisation_Test();
+ break;
+
+ case 30:
+ break;
+
+ case 31:
+ //status = vSDIOInterrupt_Test();
+ break;
+
+ case 32:
+#ifdef __MSDC_SD_SDIO__
+ gMSDC_Handle->trySingleLine = KAL_TRUE;
+ SDIO_test_main_MT5931_SDIOISR(BIT_1W);
+ dbg_print("\r\n\r\n");
+
+ //gMSDC_Handle->trySingleLine = KAL_FALSE;
+ //SDIO_test_main_MT5931_SDIOISR(BIT_4W);
+ //dbg_print("\r\n\r\n");
+#endif
+ break;
+
+ case 33:
+#ifdef __MSDC_SD_SDIO__
+ gMSDC_Handle->trySingleLine = KAL_FALSE;
+ SDIO_test_main_MT5931_SDIOISR(BIT_4W);
+ dbg_print("\r\n\r\n");
+#endif
+
+ break;
+
+ //
+ // sequential read.
+ //
+ case 34:
+
+ dbg_print("\r\nStart address:");
+ msdc_dbg_input(&input);
+ dbg_print("%c\r\n", input);
+
+ dbg_print("\r\nTransfer length:");
+ msdc_dbg_input(&input2);
+ dbg_print("%c\r\n", input2);
+
+
+
+ break;
+
+ case 35:
+
+ break;
+
+ case 36:
+
+ break;
+
+ //
+ // random read/write.
+ //
+ case 37:
+
+ while (1)
+ {
+
+ idx = rand() % 4;
+ blkaddr = rand() % gSD->mCSD.capacity / 512 - 1;
+
+ testblnum = 1;
+ loop = rand() % 10;
+
+ for (i = 0; i < loop; i++)
+ testblnum *= 2;
+
+ if (blkaddr < 0)
+ blkaddr = 0;
+
+ if (blkaddr + testblnum >= gSD->mCSD.capacity / 512)
+ blkaddr = gSD->mCSD.capacity / 512 - testblnum - 1;
+
+ switch (idx)
+ {
+
+ case 0:
+ status = sdtestcase3(blkaddr, msdc_sector_buf1);
+
+ if (status != NO_ERROR)
+ goto EXIT;
+
+ break;
+
+ case 1:
+ status = sdtestcase4(blkaddr, msdc_sector_buf1, msdc_sector_buf2);
+
+ if (status != NO_ERROR)
+ goto EXIT;
+
+ break;
+
+ case 2:
+ status = sdtestcase5(blkaddr, msdc_uncachedBuf1);
+
+ if (status != NO_ERROR)
+ goto EXIT;
+
+ break;
+
+ case 3:
+ status = sdtestcase6(blkaddr, msdc_uncachedBuf1, msdc_uncachedBuf2);
+
+ if (status != NO_ERROR)
+ goto EXIT;
+
+ break;
+
+ default:
+ dbg_print("\r\nswitch error\r\n");
+ break;
+ }
+ }
+
+ EXIT:
+
+ if (status != NO_ERROR)
+ msdc_dbg_print("[%s]Result: FAIL!!! (err=%d)", __FUNCTION__, status);
+ else
+ msdc_dbg_print("[%s]Result: PASS... ", __FUNCTION__);
+
+
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+ while (1)
+ {
+
+ //MSDC_DVT_sleepModeCardDetectionTestMT6268A();
+ //receive_msg_ext_q(task_info_g[task_entry_ptr->task_indx].task_ext_qid, ¤t_ilm );
+ //msg_receive_extq(task_info_g[task_entry_ptr->task_indx].task_ext_qid, ¤t_ilm );
+ msg_receive_extq(¤t_ilm);
+
+ switch (current_ilm.msg_id)
+ {
+
+ case MSG_ID_MSDC_CARD_DETECT_IND:
+ MSDC_GetCardStatus(&MSDC_Blk[0], 0);
+ bestReadThroughput = 0;
+ worstReadThroughput = 0;
+ bestWriteThroughput = 0;
+ worstWriteThroughput = 0;
+ dbg_print("card plug in/out");
+ MSDC_Blk[0].trySingleLine = KAL_FALSE;
+ MSDC_DVT_readWrite();
+ bestReadThroughput4Bit = bestReadThroughput;
+ bestReadThroughput = 0;
+ worstReadThroughput4Bit = worstReadThroughput;
+ worstReadThroughput = 0;
+ bestWriteThroughput4Bit = bestWriteThroughput;
+ bestWriteThroughput = 0;
+ worstWriteThroughput4Bit = worstWriteThroughput;
+ worstWriteThroughput = 0;
+ MSDC_Blk[0].trySingleLine = KAL_TRUE;
+ MSDC_Blk[0].mIsInitialized = KAL_FALSE;
+ MSDC_DVT_readWrite();
+
+ dbg_print("4 bit mode:");
+ dbg_print("\r\nwrite best: %f, worst:%f\r\n", bestWriteThroughput4Bit, worstWriteThroughput4Bit);
+ dbg_print("\r\nread best: %f, worst:%f\r\n", bestReadThroughput4Bit, worstReadThroughput4Bit);
+ dbg_print("1 bit mode:");
+ dbg_print("\r\nwrite best: %f, worst:%f\r\n", bestWriteThroughput, worstWriteThroughput);
+ dbg_print("\r\nread best: %f, worst:%f\r\n", bestReadThroughput, worstReadThroughput);
+ break;
+
+ default:
+ break;
+ }
+
+ free_ilm(¤t_ilm);
+ }
+}
+
+
+#ifdef DRV_MSDC_MT6238_SERIES
+void MSDC2_DVT_readWrite(void);
+
+
+void
+ssdbg2_main_msdc( task_entry_struct * task_entry_ptr )
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#ifdef MSDC2_SDIO_DVT
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+}
+
+void MSDC2_DVT_readWrite(void)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#if defined(NOT_4BYTES_ALIGN)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#if 0 // read & write testing
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+#if 1//write
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#if defined(NOT_4BYTES_ALIGN)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif //write
+/* under construction !*/
+#if 1 // read test
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif // read test
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+}
+#else
+void ssdbg2_main_msdc ( task_entry_struct * task_entry_ptr )
+{
+}
+#endif
+#endif
+
+#else //this is the original MSDC test code full set
+
+void ssdbg1_main_msdc ( task_entry_struct * task_entry_ptr )
+
+{
+
+
+
+#ifdef MULTIPLE_WRITE_TEST
+ gMSDC_Handle->mIsPresent = KAL_TRUE;
+ simple_multi_write_test();
+ return;
+#endif
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+ //MSDC_Initialize();
+ //SD_Initialize();
+
+
+
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+
+ {
+ kal_int32 i, j, result = 0, count = 0;
+ kal_uint32 access = 17893;
+ FS_HANDLE hFile = 0, wFile = 0;
+ kal_wchar full_name[100];
+ kal_uint32 file_size, len, total_len;
+ kal_uint32 time_1, time_2;
+ double rate;
+ volatile kal_bool format = 0;
+ kal_uint8 offset1 = 0, offset2 = 0;
+ kal_uint32 timeUsedinFS;
+ int card;
+ kal_uint8 path[10];
+ FS_DiskInfo info;
+
+#if 0 //defined(MTK_FORMAT)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+#ifdef TRANSCEND_CARD_ISSUE
+ j = 0;
+
+ if (gMSDC_Handle->mIsInitialized)
+ {
+ while (1)
+ {
+ result = FS_SdDrv.ReadSectors(gMSDC_Handle, 0x200, 4, w);
+ //result = FS_SdDrv.ReadSectors(gMSDC_Handle,0x100000,4,w);
+ //result = FS_SdDrv.ReadSectors(gMSDC_Handle,0x700000,4,w);
+ result = FS_SdDrv.ReadSectors(gMSDC_Handle, 0xf02c80, 4, w);
+
+ /*
+ for(i = 0; i<10; i++){
+ w[i] = w[i]+1;
+ }
+ result = FS_SdDrv.WriteSectors(gMSDC_Handle,0xf04c80,4,w);
+ result = FS_SdDrv.ReadSectors(gMSDC_Handle,0xf04c80,4,r);
+ */
+ for (i = 0; i < 10; i++)
+ {
+ if (w[i] != x[i])
+ {
+ dbg_print("%d-th byte has different in %d-th turn,%d, %d\r\n", i, j + 1, result, clkNeedB4Data);
+ }
+ }
+
+ if (w[0] != x[0])
+ {
+ errorCount ++;
+ dbg_print("error rate %d/%d\r\n", errorCount, j);
+ }
+
+ j++;
+
+ if ((j & 0xff) == 0)
+ {
+ dbg_print("finish %d-th turns\r\n", j);
+ }
+
+ }
+
+ }
+ else
+ {
+ while (1);
+ }
+
+#endif
+
+#ifdef WRITE_ALL_ZERO_DATA
+ j = 0;
+ //if(gMSDC_Handle->mIsInitialized){
+ DumpDiskInfo("d:\\");
+ /*make all zero data*/
+ kal_mem_set(allZeroDataArray, 0, 512);
+ i = min(gSD->mCSD.capacity / 512, 50);
+
+ for (j = 0; j < i; j++)
+ {
+ result = FS_SdDrv.WriteSectors(gMSDC_Handle, j, 1, allZeroDataArray);
+
+ if (0 != result)
+ {
+ dbg_print("write %d-th sector fail \r\n", j);
+ break;
+ }
+ }
+
+ if (0 == result)
+ {
+ dbg_print("clear all sector to zero doen\r\n");
+ }
+
+ while (1);
+
+ //}
+ //else{
+ // while(1);
+ //}
+#endif
+
+
+ result = FS_TestMSDC(gMSDC_Handle);
+
+ if (result < FS_NO_ERROR)
+ {
+ dbg_print("memory card card not present %d !!\r\n", result);
+
+ while (1)
+ kal_sleep_task(1000);
+ }
+
+ card = FS_GetDrive(FS_DRIVE_V_REMOVABLE, 1, FS_NO_ALT_DRIVE);
+
+ if (card >= FS_NO_ERROR)
+ {
+ kal_wsprintf((WCHAR*) path, "%c:\\", card);
+
+ result = FS_GetDiskInfo((WCHAR*) path, &info, FS_DI_BASIC_INFO | FS_DI_FREE_SPACE);
+
+ if (result < RTF_NO_ERROR)
+ {
+ ASSERT(0);
+ }
+
+
+ }
+ else
+ {
+ dbg_print("memory card card not present!!\r\n");
+
+ while (1)
+ kal_sleep_task(1000);
+ }
+
+#ifdef HW_FAST_FORMAT_TEST
+
+ while (1)
+ {
+ time_1 = drv_get_current_time();
+ result = FS_GeneralFormat((WCHAR*) path, FS_FORMAT_HIGH, NULL);
+
+ if (FS_NO_ERROR == result)
+ {
+ time_2 = drv_get_current_time();
+ dbg_print("format done %d, %f\n\r", time_2 - time_1, (double)(0.0005 * writeSectorsCount * 32000) / (double)(writeTimeCount));
+ writeSectorsCount = writeTimeCount = 0;
+ kal_sleep_task(1500);
+ }
+ else
+ {
+ dbg_print("format failed: %d \n\r", result);
+
+ while (1)
+ kal_sleep_task(1000);
+
+ }
+ }
+
+#endif
+ //DumpDiskInfo("d:\\");
+ kal_wsprintf(full_name, "%c:\\Write.bin", card);
+
+ for (i = 0; i < LEN + 3; i++)
+ {
+ w[i + offset1] = i % 256;
+ r[i + offset2] = 0;
+
+#ifdef CACHED_TEST
+ cached_w[i + offset1] = i % 256;
+ cached_r[i + offset2] = 0;
+#endif
+
+ }
+
+#if defined(NOT_4BYTES_ALIGN)
+ // test W to B or B to W(DMA)
+ offset1 = (kal_uint32)w % 4;
+
+ if (offset1 == 0)
+ offset1 = 1;
+ else
+ offset1 = 0;
+
+ offset2 = (kal_uint32)r % 4;
+
+ if (offset2 == 0)
+ offset2 = 1;
+ else
+ offset2 = 0;
+
+ for (i = 0; i < LEN + 3; i++)
+ {
+ w[i + offset1] = i % 256;
+ r[i + offset2] = 0;
+ }
+
+#endif
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+ while (1)
+ {
+
+#if 0 // read & write testing
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+#if 1//write
+
+ count++;
+ //Search_Dir(L"C:\\");
+ FS_Delete(full_name);
+#ifdef CACHED_TEST
+
+ if (KAL_TRUE == cachedTest)
+ cachedTest = KAL_FALSE;
+ else
+ cachedTest = KAL_TRUE;
+
+ if (KAL_TRUE == cachedTest)
+ dbg_print("\r\n===========Cached Write Test Start(%d) ====================\r\n", count);
+ else
+#endif
+ dbg_print("\r\n==================Write Test Start(%d) ====================\r\n", count);
+
+ hFile = FS_Open(full_name, FS_CREATE | FS_READ_WRITE);
+
+ if (hFile <= 0)
+ continue;
+
+ //ASSERT(hFile>0);
+
+#if defined(NOT_4BYTES_ALIGN)
+ // test W to B or B to W(DMA)
+ offset1 = (kal_uint32)w % 4;
+
+ if (offset1 == 0)
+ offset1 = 1;
+ else
+ offset1 = 0;
+
+ offset2 = (kal_uint32)r % 4;
+
+ if (offset2 == 0)
+ offset2 = 1;
+ else
+ offset2 = 0;
+
+ for (i = 0; i < LEN + 3; i++)
+ {
+ w[i + offset1] = i % 256;
+ r[i + offset2] = 0;
+ }
+
+#endif
+ i = 0;
+ total_len = 0;
+
+ kal_get_time(&time_1);
+
+ //readSectorCount = writeSectorCount = readTime = writeTime = writeSectorCount2 = writeTime2 = 0;
+ //writeTime3 = writeTime4 = writeTime5 = writeTime6 = 0;
+ while (1)
+ {
+
+#ifdef CACHED_TEST
+
+ if (KAL_TRUE == cachedTest)
+ result = FS_Write(hFile, cached_w + offset1, LEN, &len);
+ else
+#endif
+ result = FS_Write(hFile, w + offset1, LEN, &len);
+
+ total_len += len;
+ i++;
+
+ if (result < 0 )
+ {
+ if (result == RTF_DISK_FULL)
+ dbg_print("Disk Full %d\r\n", total_len);
+ else
+ dbg_print("write fail %d at: %d \r\n", result, total_len);
+
+ break;
+ }
+
+ if (len != LEN)
+ break;
+
+ if (i % TIMES == 0)
+ {
+ kal_get_time(&time_2);
+ rate = (double)(LEN * TIMES) / (double)(time_2 - time_1);
+ dbg_print("write[%d], total: %d, rate %f \r\n", i, total_len, rate / 0.004615);
+ //dbg_print("%d, %d, %d , %d\r\n", writeTime3 , writeTime4 , writeTime5,writeTime6);
+ //readSectorCount = writeSectorCount = readTime = writeTime = writeSectorCount2 = writeTime2= 0;
+ //writeTime3 = writeTime4 = writeTime5 = writeTime6 = 0;
+#ifdef CACHED_TEST
+
+ if (KAL_TRUE == cachedTest)
+ {
+ if ((rate / 0.004615) > cachedBestWriteThroughput || 0 == cachedBestWriteThroughput)
+ cachedBestWriteThroughput = (rate / 0.004615);
+
+ if ((rate / 0.004615) < cachedWorstWriteThroughput || 0 == cachedWorstWriteThroughput)
+ cachedWorstWriteThroughput = (rate / 0.004615);
+ }
+ else
+#endif
+ {
+ if ((rate / 0.004615) > bestWriteThroughput || 0 == bestWriteThroughput)
+ bestWriteThroughput = (rate / 0.004615);
+
+ if ((rate / 0.004615) < worstWriteThroughput || 0 == worstWriteThroughput)
+ worstWriteThroughput = (rate / 0.004615);
+ }
+
+ kal_get_time(&time_1);
+
+
+ if (i == TIMES * 5) break;
+ }
+ }
+
+ FS_Close(hFile);
+
+#ifdef CACHED_TEST
+
+ if (KAL_TRUE == cachedTest)
+ dbg_print("\r\nbest: %f, worst:%f\r\n", cachedBestWriteThroughput, cachedWorstWriteThroughput);
+ else
+#endif
+ dbg_print("\r\nbest: %f, worst:%f\r\n", bestWriteThroughput, worstWriteThroughput);
+
+ dbg_print("\r\n==================Write Test End(%d) ====================\r\n", count);
+#endif //write
+
+#if 1 // read test
+
+#ifdef CACHED_TEST
+
+ if (KAL_TRUE == cachedTest)
+ dbg_print("\r\n==========Cached Read Test Start(%d) ====================\r\n", count);
+ else
+#endif
+ dbg_print("\r\n==================Read Test Start(%d) ====================\r\n", count);
+
+ timeUsedinFS = 0;
+ i = 0;
+ total_len = 0;
+ hFile = FS_Open(full_name, FS_READ_WRITE);
+
+ if (hFile <= 0)
+ continue;
+
+ ASSERT(hFile > 0);
+
+ while (1)
+ {
+ kal_get_time(&time_1);
+
+#ifdef CACHED_TEST
+
+ if (KAL_TRUE == cachedTest)
+ result = FS_Read(hFile, cached_r + offset1, LEN, &len);
+ else
+#endif
+ result = FS_Read(hFile, r + offset2, LEN, &len);
+
+ kal_get_time(&time_2);
+ timeUsedinFS += (time_2 - time_1);
+ i++;
+ total_len += len;
+
+ if (check_read_content)
+ {
+#ifdef CACHED_TEST
+
+ if (KAL_TRUE == cachedTest)
+ {
+ for (j = 0; j < len; j++)
+ {
+ if (cached_r[j + offset2] != cached_w[j + offset1])
+ {
+ dbg_print("read not the same , at: %d, %d, %d, %d \r\n", total_len, j, offset2, offset1);
+
+ while (1);
+ }
+
+ }
+ }
+ else
+#endif
+ {
+ for (j = 0; j < len; j++)
+ {
+ if (r[j + offset2] != w[j + offset1])
+ {
+ dbg_print("read not the same , at: %d, %d, %d, %d \r\n", total_len, j, offset2, offset1);
+
+ while (1);
+ }
+
+ }
+ }
+
+ dbg_print(".");
+#ifdef CACHED_TEST
+
+ if (KAL_TRUE == cachedTest)
+ memset(cached_r, 0, sizeof(cached_r));
+ else
+#endif
+ memset(r, 0, sizeof(r));
+ }
+
+ if (result < 0)
+ {
+ if (result != RTF_DISK_FULL)
+ dbg_print("read fail %d, at: %d \r\n", result, total_len);
+ else
+ dbg_print("Disk Full \r\n");
+ }
+
+ if (len != LEN)
+ break;
+
+ if (i % TIMES == 0)
+ {
+
+ rate = (double)(LEN * TIMES) / (double)timeUsedinFS;
+ dbg_print("read[%d], total: %d, rate: %f \r\n", i, total_len, rate / 0.004615);
+
+#ifdef CACHED_TEST
+
+ if (KAL_TRUE == cachedTest)
+ {
+ if ((rate / 0.004615) > cachedBestReadThroughput || 0 == cachedBestReadThroughput)
+ cachedBestReadThroughput = (rate / 0.004615);
+
+ if ((rate / 0.004615) < cachedWorstReadThroughput || 0 == cachedWorstReadThroughput)
+ cachedWorstReadThroughput = (rate / 0.004615);
+ }
+ else
+#endif
+ {
+ if ((rate / 0.004615) > bestReadThroughput || 0 == bestReadThroughput)
+ bestReadThroughput = (rate / 0.004615);
+
+ if ((rate / 0.004615) < worstReadThroughput || 0 == worstReadThroughput)
+ worstReadThroughput = (rate / 0.004615);
+ }
+
+ timeUsedinFS = 0;
+
+ if (i == TIMES * 5) break;
+ }
+ }
+
+ FS_Close(hFile);
+
+#ifdef CACHED_TEST
+
+ if (KAL_TRUE == cachedTest)
+ dbg_print("\r\nbest: %f, worst:%f\r\n", cachedBestReadThroughput, cachedWorstReadThroughput);
+ else
+#endif
+ dbg_print("\r\nbest: %f, worst:%f\r\n", bestReadThroughput, worstReadThroughput);
+
+ dbg_print("\r\n==================Read Test End(%d) ====================\r\n", count);
+ FS_Delete(full_name);
+#endif // read test
+ }
+
+ //=======================================//
+
+ }
+#endif
+
+}
+
+#endif//MSDC_DVT
+#endif//__MSDC_BASIC_LOAD__
diff --git a/mcu/driver/storage/mc/src/sd.c b/mcu/driver/storage/mc/src/sd.c
new file mode 100644
index 0000000..a35e6be
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sd.c
@@ -0,0 +1,6853 @@
+ /*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * sd.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * driver functons for SD/MMC
+ *
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ *
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include "drv_features.h"
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+
+#include "kal_general_types.h"
+//#include "btif_sw.h"
+//#include "kal_public_api.h"
+#include "kal_public_defs.h"
+#include "kal_debug.h"
+#include "init.h"
+
+#include "kal_trace.h"
+#include "dcl.h"
+#include "drv_comm.h"
+#include "drv_features.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#include "qmu_bm.h"
+#include "qmu_bm_util.h"
+
+#if !defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+#include "us_timer.h"
+#include "msdc_reg_adap.h"
+#include "reg_base.h"
+#include "msdc_api.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "upll_ctrl.h"
+#include "drv_trc.h"
+#if defined(__AUDIO_DSP_LOWPOWER__)
+#include "audlp_exp.h"
+#endif
+
+#if defined(__EMMC_BOOTING__)
+#include "FTL.h"
+#endif
+
+#ifdef DRV_LSD
+#include "msdc_lsd.h"
+
+
+
+extern void LSD_Host74TCMDHigh(void);
+extern kal_bool LSD_HostDetectBusy(void);
+#endif
+
+#if defined(__MSDC_SD_MMC__)
+//global variables
+T_SDC_HANDLE gSD_blk[SD_NUM];
+T_SDC_HANDLE *gSD = gSD_blk;
+
+/*global veriable ,operation by DMA ,alloc in uncached memory*/
+#ifdef MSDC_GPD_BD_BUF_CACHED
+msdc_gpd_t MSDC_gpd[SD_NUM];
+msdc_gpd_t MSDC_gpd_end[SD_NUM];
+
+msdc_bd_t MSDC_bd[SD_NUM][MSDC_BD_MAX];
+#else
+__attribute__ ( (section ("NONCACHEDRW")))msdc_gpd_t MSDC_gpd[SD_NUM];
+__attribute__ ( (section ("NONCACHEDRW")))msdc_gpd_t MSDC_gpd_end[SD_NUM];
+
+__attribute__ ( (section ("NONCACHEDRW")))msdc_bd_t MSDC_bd[SD_NUM][MSDC_BD_MAX];
+#endif
+
+//static SDC_CMD_STATUS gblSDsta;
+
+extern MSDC_Custom_Handle msdc_custom_handle;
+void SD_Sleep4Wait(kal_int32 sleep_tick);
+void SD_Use13M_Clock(void);
+extern kal_uint8 MSDC_GetIOCtrlParam(void);
+extern kal_bool INT_USBBoot(void);
+#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
+extern void MSDC_SetLatchTuning(void);
+#else
+extern void MSDC_SetIOCONRegDLT(void);
+#endif//#if defined(DRV_MSDC_LATCH_MT6276_SERIES)
+//kal_uint32 sd_writeFailReason; // fix Lint warning
+#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+void SD_SetRedDlt(kal_uint32 redDlt);
+#endif//#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+extern void SLA_CustomLogging(kal_char *customJob, kal_int32 saAction);
+
+/*#ifdef DRV_MSDC_SDC_V3
+static kal_uint32 sd_cmd_extra = ((64) << 24); // CTOC = 64
+#else
+static kal_uint32 sd_cmd_extra = 0;
+#endif*/
+
+#if defined(__SIM_PLUS__)
+#if !defined(__CUST_NEW__)
+kal_char MSDC_GetClockWithoutSIMPlus(void);
+#endif
+#endif
+
+
+
+#ifdef DCL_MSDC_INTERFACE
+#include "dcl.h"
+
+SDC_CMD_STATUS SD_SetCallBack(MSDC_CALLBACK callback1, MSDC_CALLBACK callback2, MSDC_CALLBACK callback3, MSDC_CALLBACK callback4, MSDC_CALLBACK callback5, MSDC_CALLBACK callback6);
+SDC_CMD_STATUS SD_SetReadTestFlag(kal_uint32 readTestFlag);
+SDC_CMD_STATUS SD_readTest(void);
+SDC_CMD_STATUS SD_SetUpllClock(void);
+
+#ifdef __MEUT__
+SDDriver_t sd_driver_MTK1 =
+{
+ (DCL_SINGLE_BLK_RD)SD_ReadSingleBlock,
+ (DCL_MUL_BLK_RD)SD_ReadMultiBlock,
+ (DCL_SINGLE_BLK_WR)SD_WriteSingleBlock,
+ (DCL_MUL_BLK_WR)SD_WriteMultiBlock,
+ (DCL_SD_INITITALIZE)SD_Initialize,
+ (DCL_SET_PRE_ERASE_CNT)SD_SetPreEraseBlk,
+ (DCL_SD_SET_CALLBACK)SD_SetCallBack,
+ (DCL_SET_READ_TEST_FLAG)SD_SetReadTestFlag,
+ (DCL_SD_READ_TEST)SD_readTest,
+ (DCL_SD_SET_UPLL_CLOCK_TEST)SD_SetUpllClock,
+ (DCL_SD_ERASE_BLK)SD_FlushSectors,
+};
+#else
+SDDriver_t sd_driver_MTK1 =
+{
+ (DCL_SINGLE_BLK_RD)SD_ReadSingleBlock,
+ (DCL_MUL_BLK_RD)SD_ReadMultiBlock,
+ (DCL_SINGLE_BLK_WR)SD_WriteSingleBlock,
+ (DCL_MUL_BLK_WR)SD_WriteMultiBlock,
+ (DCL_SD_INITITALIZE)SD_Initialize,
+ (DCL_SET_PRE_ERASE_CNT)SD_SetPreEraseBlk,
+ (DCL_SD_SET_CALLBACK)NULL,
+ (DCL_SET_READ_TEST_FLAG)NULL,
+ (DCL_SD_READ_TEST)NULL,
+ (DCL_SD_SET_UPLL_CLOCK_TEST)NULL,
+ (DCL_SD_ERASE_BLK)SD_FlushSectors,
+ (DCL_GPD_MUL_BLK_RD)SD_GpdReadMultiBlock,
+ (DCL_GPD_MUL_BLK_WR)SD_GpdWriteMultiBlock,
+};
+#endif
+
+#endif
+
+#if defined( __MSDC_BASIC_LOAD__) || defined( __MEUT__)
+#define MSDC_TESTBUFFER_SIZE 512
+kal_uint32 msdc_testBuffer[(MSDC_TESTBUFFER_SIZE / 4)];
+kal_uint32 msdc_writeBuffer[(MSDC_TESTBUFFER_SIZE / 4)];
+
+#define CMD_DVT_TEST_STATUS 7
+kal_uint32 msdc_ReadTestFlag;
+MSDC_CALLBACK msdc_TestCallBack1;
+MSDC_CALLBACK msdc_TestCallBack2;
+MSDC_CALLBACK msdc_TestCallBack3;
+MSDC_CALLBACK msdc_TestCallBack4;
+MSDC_CALLBACK msdc_TestCallBack5;
+MSDC_CALLBACK msdc_TestCallBack6;
+static kal_uint32 sendCmdTimes = 0;
+#endif
+
+#ifdef __CARD_DOWNLOAD__
+extern kal_bool MSDC_QueryIsPowerControllable(void);
+extern void MSDC_SetPower(kal_bool enable);
+#endif
+
+
+
+
+/*************************************************************************
+* FUNCTION
+* SD_Acmd42
+*
+* DESCRIPTION
+* connect/disconnect the 50K Ohm pull-up resistor on CD/DAT3
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+*
+*
+*************************************************************************/
+
+// Get CID(CMD2)
+SDC_CMD_STATUS SD_Acmd42(kal_bool connect)
+{
+ SDC_CMD_STATUS status;
+ MSDC_DEBUG("[SD][%s %d]send cmd55\r\n",__FUNCTION__,__LINE__);
+
+ // send APP_CMD
+ if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+ return status;
+
+ MSDC_DEBUG("[SD][%s %d]send acmd42\r\n",__FUNCTION__,__LINE__);
+
+ // send cmd6
+ if ((status = SD_SendCmd(SDC_CMD_ACMD42, connect,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ //read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ gSD->mCD_DAT3 = KAL_FALSE; // pull-up resistor is disconnected for data trnasfer
+ return NO_ERROR;
+}
+
+
+#if defined(MSDC_MMC441_SUPPORT)
+
+kal_bool SD_eMMC_ECSD_setValue(kal_uint8 addr, kal_uint8 value)
+{
+ //kal_uint32 r0; // [TODO]: eMMC
+ //kal_bool status = KAL_FALSE;
+ kal_uint8 *pData;
+
+ if (192 <= addr) //addr above 192 is information registers, we can't write these registers
+ ASSERT(0);
+
+ MSDC_PDNControl(KAL_FALSE);
+
+ if (NO_ERROR != SD_Switch_MMC40(SET_BYTE, addr, value, 0))
+ ASSERT(0);
+
+ //if(NO_ERROR != SD_GetStatus(gSD->mRCA,(kal_uint32*)&r0))
+ // ASSERT(0);
+ if (NO_ERROR != SD_SendEXTCSD_MMC40(MSDC_Sector))
+ ASSERT(0);
+
+ pData = (kal_uint8 *)MSDC_Sector;
+
+ if (value != *(pData + addr))
+ ASSERT(0);
+
+ //status = KAL_TRUE;
+ MSDC_PDNControl(KAL_TRUE);
+ return KAL_TRUE;
+}
+
+/*
+ This API is to ask eMMC to start the partition.
+ That is, this API should be called after configuring partition settings.
+*/
+kal_bool SD_eMMC_ECSD_StartPartition()
+{
+ kal_bool status;
+
+ /*if this is not eMMC 4.4, assert it */
+ //EMMC44_CHECK_AND_ASSERT;
+
+ /*the device has been partitioned*/
+ if (EMMC_MASK_PARTITION_SETTING & gSD->mCSD.ext_csd->partition_settig)
+ {
+ ASSERT(0);
+ }
+
+ status = SD_eMMC_ECSD_setValue(EXT_CSD_PARTITION_CONFIG_INDEX, 1);
+
+ return status;
+}
+
+// unit: 512-byte
+kal_uint32 SD_eMMC_getWpgSize()
+{
+ if ((1 & gSD->mCSD.ext_csd->erase_grp_def) && (gSD->mCSD.ext_csd->hc_wp_grp_size > 0))
+ return 1024 * gSD->mCSD.ext_csd->hc_erase_grp_size * gSD->mCSD.ext_csd->hc_wp_grp_size;
+ else
+ return (gSD->mCSD.wp_grp_size_mmc >> 9);
+}
+
+/*
+ This API is called to configure partition settings. Size unit is 512-byte.
+*/
+kal_bool SD_eMMC_ECSD_configPartition(eMMC_partitions partition, kal_uint32 startAddr, kal_uint32 size, kal_bool isEnhanced)
+{
+
+ kal_bool status;
+ kal_uint32 maxEnhSizeMult;
+ kal_uint32 wpgSize;
+ kal_uint32 wpgNum;
+ kal_uint32 partitionSize[5];
+ kal_uint8 regIndex;
+ kal_uint8 value[3];
+
+ if (eMMC_GP_partition1 > partition || eMMC_user_Area < partition)
+ ASSERT(0);
+
+ /*if this is not eMMC 4.4, assert it */
+ //EMMC44_CHECK_AND_ASSERT;
+
+ /*1st, if this card does not support enhanced feature or does not support partition feature, we can not do this function*/
+
+ /* 2nd, there is a limitation for the total size of enhanced memory area.
+ we have to know the total size of other existed enhanced area and check whether the setting violet the limitation.
+ */
+ maxEnhSizeMult = gSD->mCSD.ext_csd->max_enh_size_mult[0] | ( gSD->mCSD.ext_csd->max_enh_size_mult[1] << 8) | ( gSD->mCSD.ext_csd->max_enh_size_mult[2] << 16);
+
+ /*get current all partition size*/
+ partitionSize[eMMC_GP_partition1 - eMMC_GP_partition1] = gSD->mCSD.ext_csd->gp_size_mult[0] | ( gSD->mCSD.ext_csd->gp_size_mult[1] << 8) | ( gSD->mCSD.ext_csd->gp_size_mult[2] << 16);
+ partitionSize[eMMC_GP_partition2 - eMMC_GP_partition1] = gSD->mCSD.ext_csd->gp_size_mult[3] | ( gSD->mCSD.ext_csd->gp_size_mult[4] << 8) | ( gSD->mCSD.ext_csd->gp_size_mult[5] << 16);
+ partitionSize[eMMC_GP_partition3 - eMMC_GP_partition1] = gSD->mCSD.ext_csd->gp_size_mult[6] | ( gSD->mCSD.ext_csd->gp_size_mult[7] << 8) | ( gSD->mCSD.ext_csd->gp_size_mult[8] << 16);
+ partitionSize[eMMC_GP_partition4 - eMMC_GP_partition1] = gSD->mCSD.ext_csd->gp_size_mult[9] | ( gSD->mCSD.ext_csd->gp_size_mult[10] << 8) | ( gSD->mCSD.ext_csd->gp_size_mult[11] << 16);
+ partitionSize[eMMC_user_Area - eMMC_GP_partition1] = gSD->mCSD.ext_csd->enh_size_mult[0] | ( gSD->mCSD.ext_csd->enh_size_mult[1] << 8) | ( gSD->mCSD.ext_csd->enh_size_mult[2] << 16);
+
+ /*calculate how many wpg we need to set*/
+ wpgSize = SD_eMMC_getWpgSize();
+ wpgNum = (size / wpgSize) + ((size % wpgSize) > 0 ? 1 : 0);
+
+ /*replace old size with the new size we want to set*/
+ partitionSize [partition - eMMC_GP_partition1] = wpgNum;
+
+ if ((partitionSize[0] + partitionSize[1] + partitionSize[2] + partitionSize[3] + partitionSize[4]) > maxEnhSizeMult)
+ return KAL_FALSE;
+
+ /*everything check passed, now we can set the value*/
+ if (eMMC_user_Area > partition)
+ regIndex = EXT_CSD_GP_SIZE_MULT_GP0_INDEX + 3 * (partition - eMMC_GP_partition1);
+ else
+ regIndex = EXT_CSD_ENH_SIZE_MULT_INDEX;
+
+ value[2] = wpgNum / 64;
+ value[1] = (wpgNum - (value[2] * 64)) / 8;
+ value[0] = wpgNum - (value[2] * 64) - (value[1] * 8);
+ status = SD_eMMC_ECSD_setValue(regIndex, value[0]);
+
+ if (KAL_TRUE != status)
+ goto err_exit;
+
+ status = SD_eMMC_ECSD_setValue(regIndex + 1, value[1]);
+
+ if (KAL_TRUE != status)
+ goto err_exit;
+
+ status = SD_eMMC_ECSD_setValue(regIndex + 2, value[2]);
+
+ if (KAL_TRUE != status)
+ goto err_exit;
+
+err_exit:
+ return status;
+
+}
+
+/*
+ This API is to configure to boot from specified partition.
+ By this API, DA can decide from wich partition, will card output the boot code in boot mode.
+*/
+kal_bool SD_eMMC_ECSD_setCurrentPart(eMMC_partitions partition)
+{
+ kal_uint8 regValue;
+ kal_bool status;
+ eMMC_partitions pt;
+
+ if (0 == partition || eMMC_user_Area < partition)
+ ASSERT(0);
+
+ /*if this is not eMMC 4.4, assert it */
+ //EMMC44_CHECK_AND_ASSERT;
+
+ pt = (partition == eMMC_user_Area) ? 0 : partition;
+
+ regValue = gSD->mCSD.ext_csd->partition_config;
+
+ /*currently it uses the setting DA want, no need to change*/
+ if (pt == (EMMC_MASK_PARTITION_CONFIG & regValue))
+ return KAL_TRUE;
+
+ regValue &= ~EMMC_MASK_PARTITION_CONFIG;
+ regValue |= pt;
+ status = SD_eMMC_ECSD_setValue(EXT_CSD_PARTITION_CONFIG_INDEX, regValue);
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#if defined(__EMMC_BOOTING__)
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+ return status;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_IsEMMC
+*
+* DESCRIPTION
+* Check inserted card is e-MMC 4.4
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+void SD_IsEmmcV44()
+{
+ /* from eMMC 4.3, EXT_CSD_REV has maximum value 3, and from eMMC 4.4, EXT_CSD_REV new value 4, 5
+ */
+ if (3 < gSD->mCSD.ext_csd->ext_csd_rev)
+ {
+ if (0 != gSD->mCSD.ext_csd->boot_size_mul) //has boot partition, this is eMMC
+ {
+ gSD->emmc_info.isEmmcV44 = (kal_bool)KAL_TRUE;
+ gSD->emmc_info.bootPartitionSize = 2 * 128 * gSD->mCSD.ext_csd->boot_size_mul;
+ gSD->emmc_info.gp1PartitionSize = SD_eMMC_getWpgSize() *
+ (gSD->mCSD.ext_csd->gp_size_mult[0]
+ + ( gSD->mCSD.ext_csd->gp_size_mult[1] * 256)
+ + ( gSD->mCSD.ext_csd->gp_size_mult[2] * 65536));
+
+ /*from spec, alternated boot method is mandatory for eMMC4.4*/
+ if ( 0 == (0x1 & gSD->mCSD.ext_csd->boot_info))
+ ASSERT(0);
+
+ /*we can't use the card that don't have RST signal support*/
+ if ( 0x2 == (0x3 & gSD->mCSD.ext_csd->rst_function))
+ ASSERT(0);
+
+ if ( 0x1 == (0x1 & gSD->mCSD.ext_csd->partition_support))
+ gSD->emmc_info.supportPartition = (kal_bool)KAL_TRUE;
+ else
+ gSD->emmc_info.supportPartition = (kal_bool)KAL_FALSE;
+
+ if ( 0x2 == (0x2 & gSD->mCSD.ext_csd->partition_support))
+ gSD->emmc_info.supportEnhancedPart = (kal_bool)KAL_TRUE;
+ else
+ gSD->emmc_info.supportEnhancedPart = (kal_bool)KAL_FALSE;
+ }
+ else //normal mmc card without boot support
+ {
+ gSD->emmc_info.isEmmcV44 = (kal_bool)KAL_FALSE;
+ }
+ }
+ else //spec version below or equals to eMMC 4.3
+ {
+ gSD->emmc_info.isEmmcV44 = (kal_bool)KAL_FALSE;
+ }
+}
+
+#endif//defined(MSDC_MMC441_SUPPORT)
+
+
+/*************************************************************************
+* FUNCTION
+* SD_SetMMC40_4bit_high_speed
+*
+* DESCRIPTION
+* Check inserted card is SD or MMC
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SD_CARD or MMC_CARD
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetMMC40_bus_high_speed(void)
+{
+ kal_uint32 clock, hs;
+ // kal_uint8 *pData;
+
+ #if !defined(__EMMC_BOOTING__)
+
+ if (SD_SetBlength(512) != NO_ERROR)
+ goto err;
+
+ #endif
+
+ #ifndef MSDC_SPECIAL_MMC_41_CARD
+
+ // read the EXT_CSD
+ if (SD_SendEXTCSD_MMC40(MSDC_Sector) != NO_ERROR)
+ goto err;
+
+ #endif
+
+ /*calculate size*/
+ if (MMC42_CARD == gMSDC_Handle->mMSDC_type)
+ {
+ gSD->mCSD.capacity = (kal_uint64)gSD->mCSD.ext_csd->sec_count * 512;
+ }
+
+ #if defined(MSDC_MMC441_SUPPORT)
+ SD_IsEmmcV44();
+ #endif
+
+ // set high speed
+ #ifndef MSDC_SPECIAL_MMC_41_CARD
+
+ if (gSD->mCSD.ext_csd->card_type & HS_52M)
+ #endif
+ {
+ // should be 52000
+ clock = 52000000;
+ //clock = gMSDC_Handle->msdc_clock / 2;
+
+ //if (52000000 < clock)
+ // clock = clock / 2;
+
+ hs = 1;
+ //MSDC_LSD_WriteReg32(MSDC_IOCON,0x010002FF)
+
+ MSDC_DEBUG("[MSDC][%s %d]1.Set clock to %d \r\n",__FUNCTION__,__LINE__,clock);
+ }
+
+ #ifndef MSDC_SPECIAL_MMC_41_CARD
+ else if (gSD->mCSD.ext_csd->card_type & HS_26M)
+ {
+ // should be 26000
+ clock = 26000000;
+ hs = 1;
+ }
+ else
+ {
+ clock = 13000000;
+ hs = 0;
+ }
+
+ #endif
+
+ if (hs)
+ {
+ //! [TODO]: eMMC
+ /* select proper power class
+ if(SD_Switch_MMC40(SET_BYTE,EXT_CSD_POW_CLASS_INDEX,
+ (gSD->mCSD.ext_csd->pwr_52_360&0xf) ,0) != NO_ERROR)
+ goto err;
+ */
+
+
+
+ /* enable high speed (26M or 52M)*/
+ if(SD_Switch_MMC40(SET_BYTE,EXT_CSD_HIGH_SPPED_INDEX,EXT_CSD_ENABLE_HIGH_SPEED,0) != NO_ERROR)
+ goto err;
+
+
+ // latch data at falling edge to cover the card driving capability
+ // MSDC_LSD_SetBits32(MSDC_CFG,MSDC_CFG_RED);
+ }
+
+ #ifndef DRV_LSD
+
+ //#ifndef DRV_MSDC_CLK_SEARCH
+ //gMSDC_Handle->msdc_clock = MSDC_CLOCK;
+ MSDC_SetClock(clock,KAL_FALSE);
+ //#endif
+ #else
+ LSD_HostSetClock(LSD_SPEED_52M);
+ #endif
+
+
+
+ if (NO_SINGLE_LINE == gMSDC_Handle->trySingleLine)
+ {
+ // select bus width
+ #if defined(MMC40_USE_4BIT_BUS)
+ // enable 4-bit bus width
+ if (SD_Switch_MMC40(SET_BYTE, EXT_CSD_BUS_WIDTH_INDEX, BIT_4_MMC40, 0) != NO_ERROR)
+ goto err;
+
+ #ifdef MSDC_SPECIAL_MMC_41_CARD
+
+ if (KAL_TRUE == kal_query_systemInit()
+ || KAL_TRUE == FTL_isPollingMode()
+ )
+ {
+ MSDC_GPTI_BusyWait(2);
+ }
+ else
+ {
+ kal_sleep_task(4);
+ }
+
+ #endif
+
+ MSDC_SetBusWidth(BIT_4W);
+ gSD->bus_width = 4;
+ #elif defined(MMC40_USE_8BIT_BUS)
+
+ // enable 8-bit bus width
+ if (SD_Switch_MMC40(SET_BYTE, EXT_CSD_BUS_WIDTH_INDEX, BIT_8_MMC40, 0) != NO_ERROR)
+ goto err;
+ MSDC_SetBusWidth(BIT_8W);
+ gSD->bus_width = 8;
+ #endif
+ }
+ else
+ {
+ gMSDC_Handle->trySingleLine&=(~TEMP_SINGLE_LINE);
+ }
+
+ #ifndef MSDC_SPECIAL_MMC_41_CARD
+
+ if (SD_SendEXTCSD_MMC40(MSDC_Sector) != NO_ERROR)
+ goto err;;
+
+ #endif
+
+ return NO_ERROR;
+err:
+
+ return ERR_MMC_BUS_HS_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_CheckSDorMMC
+*
+* DESCRIPTION
+* Check inserted card is SD or MMC
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SD_CARD or MMC_CARD
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+T_MSDC_CARD SD_CheckSDorMMC()
+{
+ SDC_CMD_STATUS status;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ SD_Cmd8();
+#endif
+ status = SD_Acmd41_SD();
+
+ if (status == NO_ERROR)
+ return gMSDC_Handle->mMSDC_type; // SD_CARD
+ else
+ MSDC_ERR("[SD]SD_Acmd41_SD returns error code: %d\r\n", status);
+
+ status = SD_Cmd1_MMC();
+
+ if (status == NO_ERROR)
+ return gMSDC_Handle->mMSDC_type; // MMC_CARD
+ else
+ MSDC_ERR("[SD]SD_Cmd1_MMC returns error code: %d\r\n", status);
+
+ return UNKNOWN_CARD;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SetDefault
+*
+* DESCRIPTION
+* set default values to gSD
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+void SD_SetDefault(void)
+{
+ MSDC_LOCK_TAG tempLock;
+ kal_mem_cpy(&tempLock, &gSD->mSDdrv_lock, sizeof(MSDC_LOCK_TAG));
+ kal_mem_set(gSD, 0, sizeof(T_SDC_HANDLE));
+
+ gSD->mBKLength = 0;
+ gSD->mRCA = 0;
+ gSD->mInactive = KAL_FALSE;
+ gSD->mState = IDLE_STA;
+ gSD->bus_width = 1;
+ //gSD->mCD_DAT3 = KAL_TRUE;
+
+ kal_mem_cpy(&gSD->mSDdrv_lock, &tempLock, sizeof(MSDC_LOCK_TAG));
+}
+
+void SD_Use24M_Clock(void)
+{
+
+}
+
+void SD_Use13M_Clock(void)
+{
+
+}
+
+#ifdef DRV_MSDC_CLK_MT6268_SERIES
+void SD_Use30M_Clock(void)
+{
+
+}
+
+void SD_Use45M_Clock(void)
+{
+
+}
+#endif
+
+#ifdef DRV_MSDC_CLK_SEARCH
+
+kal_uint32 whenToStop;
+kal_uint32 stopTimeout = 300;
+
+#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+void SD_SetRedDlt(kal_uint32 redDlt)
+{
+
+}
+#endif//#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+kal_bool sd_DltTestWithClkStopped(kal_uint32 data_adrs)
+{
+ return 0;
+
+}
+
+#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+kal_bool SD_setCLKAndTest(kal_uint32 targetCLK)
+{
+ return 0;
+}
+
+
+kal_uint32 SD_tuneCLK2()
+{
+ return 0;
+}
+
+#else//!defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+kal_bool SD_IsClkInRange(kal_uint32 clk)
+{
+ return 0;
+}
+
+kal_bool SD_CanCmdBeLatched(void)
+{
+ return 0;
+}
+
+/*kal_bool SD_CanDataBeLatched(msdc_clk_setting cs)
+{
+
+}*/
+
+/*SDC_CMD_STATUS MSDC_AutoCalibrate(
+ msdc_acb_mode mode,
+ msdc_acb_scan_mode scanMode,
+ msdc_acb_tun_scheme tunScheme,
+ kal_uint8 tunBlockNum
+)
+{
+
+}*/
+
+/*kal_uint32 MSDC_ManuCalibrate(
+ msdc_clk_setting cs,
+ msdc_acb_mode mode
+)
+{
+
+}*/
+
+#define MAX_NUM_MULTI_PHASE 32
+SDC_CMD_STATUS FindMostConsecutiveBits(
+ kal_uint32 word,
+ kal_uint8 wordLen,
+ kal_uint8 threshold,
+ kal_uint8 *pos
+)
+{
+ return 0;
+}
+
+/*SDC_CMD_STATUS MSDC_AutoCalibrate_FindBestLatchWindow(
+ msdc_acb_scan_mode scanMode,
+ kal_uint8 *pos
+)
+{
+
+}*/
+
+/*SDC_CMD_STATUS MSDC_ManuCali_FindBestLatchWindow(
+ msdc_clk_setting cs,
+ kal_uint32 phaseArraySeamless,
+ kal_uint8 *pos
+)
+{
+
+}*/
+
+/*kal_uint32 SD_ClkTuning_AutoCalibrate(msdc_clk_setting cs)
+{
+
+}*/
+
+/*kal_uint32 SD_ClkTuning_ManualCalibrate(msdc_clk_setting cs)
+{
+
+}*/
+
+/*kal_uint32 SD_ClkTuning_FeedbackClk(msdc_clk_setting cs)
+{
+
+}*/
+
+kal_uint32 SD_tuneCLK2()
+{
+ return 0;
+}
+
+#endif//!defined(DRV_MSDC_LATCH_MT6276_SERIES)
+
+#endif//#ifdef DRV_MSDC_CLK_SEARCH
+
+#ifdef __MEUT__
+kal_bool msdcOddNumberSizeTestByDMA;
+kal_bool msdcDoNotRST;
+SDC_CMD_STATUS msdcReadTest(kal_uint32 size, kal_uint8 *compareBuffer, kal_uint32 data_adrs)
+{
+
+ return 0;
+}
+
+#endif
+
+
+#ifdef __MSDC_BASIC_LOAD__
+
+kal_bool msdcOddNumberSizeTestByDMA;
+kal_bool msdcDoNotRST;
+SDC_CMD_STATUS msdcTransferLengthTest(kal_uint32 size, kal_uint8 *compareBuffer, kal_uint32 data_adrs)
+{
+ return 0;
+ }
+
+SDC_CMD_STATUS msdcWriteLengthTest(kal_uint32 size, kal_uint8 *compareBuffer, kal_uint32 data_adrs, kal_bool notChange)
+{
+ return 0;
+
+}
+#endif
+
+#if defined(MSDC_QMU_ENABLE)
+#define MSDC_QBM_BPS_NUM 1
+#define MSDC_QBM_BPS_BUF_SZ QBM_QUEUE_GET_MEM_SIZE(QBM_SIZE_TGPD_BPS, MSDC_QBM_BPS_NUM)
+kal_uint8 msdc_bps_buf[MSDC_QBM_BPS_BUF_SZ];
+void *g_p_msdc_bps[MSDC_QBM_BPS_NUM];
+
+/* Initialize the QUM buffer for MSDC queue transfer */
+kal_bool SD_QMU_Init(void)
+{
+ kal_bool ret = KAL_TRUE;
+ unsigned char idx = 0;
+ bm_queue_config conf;
+ qbm_gpd *p_cur_gpd = NULL ,*p_head_gpd = NULL , *p_tail_gpd = NULL;
+
+ /* Init the BPS pointer */
+ for (idx = 0; idx < MSDC_QBM_BPS_NUM; idx++)
+ g_p_msdc_bps[idx] = NULL;
+
+ /*initial non-free bypass GPD buffer pool*/
+ qbm_init_q_config(&conf);
+ conf.buff_num = MSDC_QBM_BPS_NUM;
+ conf.p_mem_pool_str = msdc_bps_buf;
+ conf.p_mem_pool_end = msdc_bps_buf + MSDC_QBM_BPS_BUF_SZ;
+
+ /*user must flush the GPD after this non-free init queue*/
+ if (QBM_ERROR_OK != qbm_init_queue_non_free(QBM_TYPE_TGPD_BPS, &conf , (void **)&p_head_gpd, (void **)&p_tail_gpd)) {
+ return KAL_FALSE;
+ }
+
+ idx = 0;
+ p_cur_gpd = p_head_gpd;
+
+ do {
+ qbm_set_non_free(p_cur_gpd);
+ qbm_set_used(p_cur_gpd);
+ QBM_DES_CLR_HWO(p_cur_gpd);
+ QBM_DES_SET_NEXT(p_cur_gpd, NULL);
+
+ g_p_msdc_bps[idx] = p_cur_gpd;
+
+ /*flush GPD here because qbm_init_queue_non_free don't flush GPD*/
+ QBM_CACHE_FLUSH(p_cur_gpd, sizeof(qbm_gpd));
+ idx ++;
+
+ /*should consider the bps_ptr array count*/
+ if ((p_cur_gpd == p_tail_gpd) || (idx >= MSDC_QBM_BPS_NUM)) {
+ break;
+ }
+
+ p_cur_gpd = p_cur_gpd->p_next;
+ } while(1);
+
+ return ret;
+}
+#endif
+
+/*************************************************************************
+* FUNCTION
+* SD_Initialize
+*
+* DESCRIPTION
+* Initial SD controller and card
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Initialize(void)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 cid[4], csd[4], scr[4];
+ kal_uint32 sd_status[16];
+ kal_uint16 rca;
+
+ /*check if init or not*/
+ if (gMSDC_Handle->mIsInitialized==KAL_TRUE)
+ {
+ return NO_ERROR;
+ }
+
+#if defined(MSDC_MMC441_SUPPORT)
+ gSD->emmc_info.isEmmcV44 = KAL_FALSE;
+#endif
+
+ /* Re-Init gSD */
+ kal_mem_set(&gSD->mSCR, 0, sizeof(T_SCR));
+
+ /*reset event*/
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events,0,KAL_AND);
+
+ /*reset MSDC*/
+ MSDC_RESET();
+
+ /*may switch to 1.8 last time,we should set signal volt to 3.3v and power cycle*/
+ gMSDC_Handle->signal_volt=3300;
+ MSDC_SetSignalPower(KAL_TRUE, gMSDC_Handle->signal_volt);
+ power_cycle(20);
+
+ /* Set INIT clock */
+ MSDC_SetClock(MSDC_INIT_CLOCK,KAL_FALSE);
+ /*set to 1 bit data line*/
+ MSDC_SetBusWidth(BIT_1W);
+ /*SD_SetDefault*/
+ SD_SetDefault(); //need check the function !!!!!!
+ /*set latch tuning*/
+
+ /*set IOCON1 */
+ /*set CARD_CK_PWDN=0 */
+ MSDC_ClearBits32(MSDC_CFG,MSDC_CFG_CKPDN);
+ /*enable bus clk*/
+ MSDC_SetBits32(MSDC_CFG,MSDC_CFG_CKDRV_EN);
+
+ /*reset cmd0*/
+ status=SD_Reset();
+ SD_INITIALIZE_STATUS_CHECK(); /*need check this function !!!!!!!!!!!!*/
+ /*checkSDorMMC cmd8 acmd41 cmd1*/
+ if (SD_CheckSDorMMC() == UNKNOWN_CARD)
+ {
+ MSDC_ERR("[SD][%s %d]unknow card\r\n",__FUNCTION__,__LINE__);
+ SD_TRACE2(TRACE_GROUP_5, MSDC_GENERAL_FAIL, MSDC_DRV_TRC_FILE_SD, __LINE__);
+ status = ERR_STATUS;
+ goto err;
+ }
+ /*getCID cmd2*/
+ status = SD_GetCID(cid);
+ SD_INITIALIZE_STATUS_CHECK();
+ /*validateRCA cmd3*/
+ status = SD_ValidateRCA(&rca);
+ SD_INITIALIZE_STATUS_CHECK();
+ /*GetCSD cmd9*/
+ status = SD_GetCSD(gSD->mRCA, csd);
+ SD_INITIALIZE_STATUS_CHECK();
+ MSDC_DEBUG("[SD][%s %d]send cmd4\r\n",__FUNCTION__,__LINE__);
+ /*setSDR cmd4*/
+ if (gSD->mCSD.dsr_imp){
+ if ((status = SD_SetDSR()) != NO_ERROR)
+ {
+ //dbg_print("6\r\n");
+ SD_TRACE2(TRACE_GROUP_5, MSDC_GENERAL_FAIL, MSDC_DRV_TRC_FILE_SD, __LINE__);
+ goto err;
+ }
+ }
+ /*check Write Protected*/
+#if defined(MSDC_WR_PROT_EN)
+#if defined(_MSDC_INTERNAL_CD_INT_PIN_)
+ if(!(MSDC_Reg32(MSDC_PS)&MSDC_PS_WP))
+ {
+ //gSD->mWPEnabled=KAL_TRUE;
+ if (gSD->mWPEnabled!=KAL_TRUE)
+ gSD->mWPEnabled=KAL_FALSE;
+ }
+ else
+ {
+ //gSD->mWPEnabled=KAL_FALSE;
+ gSD->mWPEnabled=KAL_TRUE;
+ }
+#else
+ {
+ DCL_HANDLE handle;
+
+ GPIO_CTRL_READ_T data;
+
+ /* when use EINT for card detect,get the status */
+ handle = DclGPIO_Open(DCL_GPIO, MSDC_WP_GPIO);
+ DclGPIO_Control(handle, GPIO_CMD_READ, (DCL_CTRL_DATA_T *)&data);
+
+ if (data.u1IOData)
+ gSD->mWPEnabled = KAL_TRUE;
+ else
+ gSD->mWPEnabled = KAL_FALSE;
+
+ DclGPIO_Close(handle);
+ }
+#endif
+#else /* MSDC_WR_PROT_EN */
+ gSD->mWPEnabled = KAL_FALSE;
+#endif
+
+ MSDC_CRIT("[SD][%s %d]Card is %s\r\n",__FUNCTION__,__LINE__,
+ gSD->mWPEnabled ? "WP-ed" : "Not WP-ed");
+
+ /*select Card cmd7*/
+ status = SD_SelectCard(gSD->mRCA);
+ if (status == CARD_IS_LOCKED)
+ gSD->mIsLocked = KAL_TRUE;
+ SD_INITIALIZE_STATUS_CHECK();
+
+
+ /*read SCR cmd16 acmd51*/
+ if (gMSDC_Handle->mMSDC_type==SD_CARD\
+ ||gMSDC_Handle->mMSDC_type==SD20_HCS_CARD ||gMSDC_Handle->mMSDC_type==SD20_LCS_CARD\
+ ||gMSDC_Handle->mMSDC_type==SD30_CARD)
+ {
+ status = SD_ReadSCR(scr);
+ SD_INITIALIZE_STATUS_CHECK();
+
+ status = SD_ReadSDStatus(sd_status);
+ SD_INITIALIZE_STATUS_CHECK();
+
+ /*set bus width acmd6*/
+ if (NO_SINGLE_LINE == gMSDC_Handle->trySingleLine)
+ {
+ status = SD_SetBusWidth(BIT_4W);
+ SD_INITIALIZE_STATUS_CHECK();
+ }
+ else
+ {
+ gMSDC_Handle->trySingleLine&=~(TEMP_SINGLE_LINE);
+ }
+
+ /*acmd42*/
+ #if !defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
+ status = SD_Acmd42(KAL_FALSE);
+ SD_INITIALIZE_STATUS_CHECK();
+ #endif
+
+ status=SD_SwitchSpeedMode();
+ SD_INITIALIZE_STATUS_CHECK();
+
+#if defined(MSDC_CONFIG_SD30_SUPPORT)
+ if (gMSDC_Handle->mMSDC_type==SD30_CARD)
+ {
+
+ switch (gSD->function_set.function1)
+ {
+ case FUN1_SET_SDR104:
+ MSDC_SetClock(208000000,KAL_FALSE);
+ gMSDC_Handle->msdc_clkTuneUpperBund = 100000000;
+ break;
+ case FUN1_SET_SDR50:
+ MSDC_SetClock(100000000,KAL_FALSE);
+ gMSDC_Handle->msdc_clkTuneUpperBund = 50000000;
+ break;
+ case FUN1_SET_SDR25_HS:
+ MSDC_SetClock(50000000,KAL_FALSE);
+ gMSDC_Handle->msdc_clkTuneUpperBund = 25000000;
+ break;
+ case FUN1_SET_SDR12_DS:
+ MSDC_SetClock(25000000,KAL_FALSE);
+ gMSDC_Handle->msdc_clkTuneUpperBund = 12500000;
+ break;
+ case FUN1_SET_DDR50:
+ MSDC_SetClock(50000000,KAL_TRUE);
+ gMSDC_Handle->msdc_clkTuneUpperBund = 25000000;
+ break;
+ }
+ }
+ else
+#endif
+ {
+ if (gSD->function_set.function1==1)
+ {
+ MSDC_CRIT("[SD][%s %d]set Bus Clock to 50M(HS)\r\n",__FUNCTION__,__LINE__);
+ MSDC_SetClock(50000000,KAL_FALSE);
+ gMSDC_Handle->msdc_clkTuneUpperBund = 25000000;
+ }
+ else
+ {
+ MSDC_CRIT("[SD][%s %d]set Bus Clock to 25M(DS)\r\n",__FUNCTION__,__LINE__);
+ MSDC_SetClock(25000000,KAL_FALSE);
+ gMSDC_Handle->msdc_clkTuneUpperBund = 12500000;
+ }
+ }
+
+ /* For SDA compliance test */
+ if (((gSD->mSCR.spec_ver==SD_SPEC_101)||(gSD->mSCR.spec_ver==SD_SPEC_110)||(gSD->mCSD.csd_ver==CSD_VER_1_0))&&
+ ((kal_uint32)(gSD->mCSD.capacity / (1024 * 1024)) > 2048)&&(status==NO_ERROR)) {
+ status = ERR_STATUS;
+ MSDC_ERR("[SD] We would not mount >2G Card which is compliant to SD1.x\r\n");
+ goto err;
+ }
+ if (((gSD->mSCR.spec_ver<=SD_SPEC_200))&&
+ ((kal_uint32)(gSD->mCSD.capacity / (1024 * 1024)) > 32768)&&(status==NO_ERROR)) {
+ status = ERR_STATUS;
+ MSDC_ERR("[SD] We would not mount >32GB Card which is compliant to SD2.0\r\n");
+ goto err;
+ }
+ }
+ else
+ {
+ MSDC_CRIT("[SD][%s %d]init mmc \r\n",__FUNCTION__,__LINE__);
+ //mmc card
+ if ((gMSDC_Handle->mMSDC_type == MMC_CARD || gMSDC_Handle->mMSDC_type == MMC42_CARD) && gSD->mCSD.spec_ver >= 4)
+ {
+ if (gMSDC_Handle->mMSDC_type == MMC_CARD) /*we don't need to change MMC42_CARD to MMC40_CARD*/
+ gMSDC_Handle->mMSDC_type = MMC40_CARD;
+ status = SD_SetMMC40_bus_high_speed();
+ SD_INITIALIZE_STATUS_CHECK();
+ #if defined(MSDC_MMC441_SUPPORT)
+ if ( gSD->mCSD.ext_csd->ext_csd_rev >= 5 )
+ {
+ // set ERASE_GROUP_DEF[175] before issuing read, write, erase, write protect
+ status = SD_Switch_MMC40(SET_BYTE, EXT_CSD_ERASE_GRP_DEF, 1 , 0);
+ SD_INITIALIZE_STATUS_CHECK();
+ }
+ #endif
+ }
+ else
+ {
+ MSDC_SetClock(13000000,KAL_FALSE);
+ }
+
+ }
+
+ /* Set block length cmd16 */
+ status = SD_SetBlength(512);
+ SD_INITIALIZE_STATUS_CHECK();
+
+err:
+
+ if (status != NO_ERROR)
+ {
+ MSDC_ERR("[SD][%s %d]mount fail %x\r\n",__FUNCTION__,__LINE__,status);
+ SD_SetDefault();
+ gMSDC_Handle->mIsInitialized = KAL_FALSE;
+ gMSDC_Handle->mIsPresent = KAL_FALSE;
+ MSDC_turnOnVMC(gMSDC_Handle->mIsPresent);
+ MSDC_SetVddPower(KAL_FALSE, gMSDC_Handle->vdd_volt);
+ MSDC_PDNControl(KAL_TRUE);
+ }
+ else
+ {
+ MSDC_CRIT("[SD][%s %d]mount ok %x\r\n",__FUNCTION__,__LINE__,status);
+ gMSDC_Handle->mIsInitialized = KAL_TRUE;
+ }
+
+ /*reset event*/
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+ return status;
+
+}
+
+#ifdef __MEUT__
+SDC_CMD_STATUS SD_SetCallBack(MSDC_CALLBACK callback1, MSDC_CALLBACK callback2, MSDC_CALLBACK callback3, MSDC_CALLBACK callback4, MSDC_CALLBACK callback5, MSDC_CALLBACK callback6)
+{
+ return 0;
+}
+SDC_CMD_STATUS SD_SetReadTestFlag(kal_uint32 readTestFlag)
+{
+ return 0;
+}
+SDC_CMD_STATUS SD_readTest(void)
+{
+
+ return 0;
+}
+
+SDC_CMD_STATUS SD_SetUpllClock(void)
+{
+
+ return 0;
+}
+#endif
+
+
+void SD_InvertN(kal_uint8 *dest, kal_uint8 *src, kal_uint8 len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ *(dest + len - 1 - i) = *(src + i);
+
+}
+/*************************************************************************
+* FUNCTION
+* power2
+*
+* DESCRIPTION
+* Calculate the power of 2
+*
+* PARAMETERS
+* num:
+*
+* RETURNS
+* 2^num
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+static kal_uint32 power2(kal_uint32 num)
+{
+ return 1 << num;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_AnalysisCSD
+*
+* DESCRIPTION
+* Analysis Card Specific Data and store in the member of gSD
+*
+* PARAMETERS
+* csd: input csd for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+void SD_AnalysisCSD(kal_uint32* csd)
+{
+ kal_uint8 *ptr;
+ kal_uint32 c_mult, c_size;
+
+ ptr = (kal_uint8*)csd;
+ c_mult = c_size = 0;
+ // these offsets refer to the spec. of SD and MMC
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.csd_ver, ptr, 126, 2);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.tacc, ptr, 112, 8);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.nsac, ptr, 104, 8);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.tran_speed, ptr, 96, 8);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.ccc, ptr, 84, 12);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.r_blk_len, ptr, 80, 4);
+ gSD->mCSD.r_blk_len = power2(gSD->mCSD.r_blk_len);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.r_blk_part, ptr, 79, 1);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.w_blk_misali, ptr, 78, 1);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.r_blk_misali, ptr, 77, 1);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.dsr_imp, ptr, 76, 1);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.w_blk_part, ptr, 21, 1);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.w_blk_len, ptr, 22, 4);
+ gSD->mCSD.w_blk_len = power2(gSD->mCSD.w_blk_len);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.wp_grp_enable, ptr, 31, 1);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.temp_wp,ptr,12,1);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.perm_wp,ptr,13,1);
+ if (gSD->mCSD.temp_wp || gSD->mCSD.perm_wp)
+ gSD->mWPEnabled = KAL_TRUE;
+
+ // there are some difference of CSD between SD and MMC
+ if (gMSDC_Handle->mMSDC_type == MMC_CARD || gMSDC_Handle->mMSDC_type == MMC42_CARD)
+ {
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.spec_ver, ptr, 122, 4);
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.erase_sec_size_mmc, ptr, 42, 5);
+ gSD->mCSD.erase_sec_size_mmc = (gSD->mCSD.erase_sec_size_mmc + 1) * gSD->mCSD.w_blk_len;
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.erase_grp_size_mmc, ptr, 37, 5);
+ gSD->mCSD.erase_grp_size_mmc = (gSD->mCSD.erase_grp_size_mmc + 1) * gSD->mCSD.erase_sec_size_mmc;
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.wp_grp_size_mmc, ptr, 32, 5);
+ gSD->mCSD.wp_grp_size_mmc = (gSD->mCSD.wp_grp_size_mmc + 1) * gSD->mCSD.erase_grp_size_mmc;
+ }
+ else // SD_CARD
+ {
+ if (gSD->mCSD.csd_ver == CSD_VER_2_0)
+ gSD->mIsBlkAddr = 1;
+ else
+ gSD->mIsBlkAddr = 0;
+
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.erase_sec_size_sd, ptr, 39, 7);
+ gSD->mCSD.erase_sec_size_sd += 1;
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.wp_prg_size_sd, ptr, 32, 7);
+ gSD->mCSD.wp_prg_size_sd = (gSD->mCSD.wp_prg_size_sd + 1) * gSD->mCSD.erase_sec_size_sd;
+ GetBitFieldN((kal_uint8*)&gSD->mCSD.erase_blk_en_sd, ptr, 46, 1);
+ }
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+
+ if ((gMSDC_Handle->mMSDC_type == SD20_HCS_CARD||\
+ gMSDC_Handle->mMSDC_type == SD30_CARD) && gSD->mCSD.csd_ver >= SD_CSD_VER_20)
+ {
+ GetBitFieldN((kal_uint8*)&c_size, ptr, 48, 22);
+ gSD->mBKNum = (c_size + 1);
+ gSD->mCSD.capacity = (kal_uint64)gSD->mBKNum * 512 * 1024;
+ }
+ else
+#endif
+ {
+ GetBitFieldN((kal_uint8*)&c_mult, ptr, 47, 3);
+ c_mult = power2(c_mult + 2);
+ GetBitFieldN((kal_uint8*)&c_size, ptr, 62, 12);
+ gSD->mBKNum = (c_size + 1) * c_mult;
+ gSD->mCSD.capacity = (kal_uint64)(c_size + 1) * (kal_uint64)c_mult * (kal_uint64)gSD->mCSD.r_blk_len;
+ }
+ if (!(gSD->mCSD.ccc &CCC_BLOCK_WRITE))
+ gSD->mWPEnabled = KAL_TRUE; //unsupport write command
+
+ MSDC_CRIT("[SD][%s %d]The capacity is %d MB, BLK_ADDR(%d)\r\n", __FUNCTION__, __LINE__,
+ (kal_uint32)(gSD->mCSD.capacity / (1024 * 1024)), gSD->mIsBlkAddr);
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_AnalysisCID
+*
+* DESCRIPTION
+* Analysis Card Identificaton and store in the member of gSD
+*
+* PARAMETERS
+* cid: input of card ID for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+void SD_AnalysisCID(kal_uint32* cid)
+{
+ kal_uint8 i;
+ kal_uint8* pcid;
+ pcid = (kal_uint8*)cid;
+
+ if (gMSDC_Handle->mMSDC_type == MMC_CARD || MMC42_CARD == gMSDC_Handle->mMSDC_type)
+ {
+ GetBitFieldN((kal_uint8*)&gSD->mCID.year, pcid, 8, 4);
+ gSD->mCID.year += 1997;
+ GetBitFieldN((kal_uint8*)&gSD->mCID.month, pcid, 12, 4);
+ GetBitFieldN((kal_uint8*)&gSD->mCID.psn, pcid, 16, 32);
+ GetBitFieldN((kal_uint8*)&gSD->mCID.prv, pcid, 48, 8);
+
+ for (i = 0; i < 6; i++)
+ gSD->mCID.pnm[i] = *(pcid + 7 + i);
+
+ GetBitFieldN((kal_uint8*)&gSD->mCID.oid, pcid, 104, 16);
+ GetBitFieldN((kal_uint8*)&gSD->mCID.mid, pcid, 120, 8);
+
+ // special case handling
+ {
+ kal_uint8 pnm[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x36, 0x31};
+
+ if (gSD->mCID.mid == 6 && gSD->mCID.oid == 0 &&
+ !kal_mem_cmp(gSD->mCID.pnm, pnm, 6))
+ {
+ gSD->flags |= SD_FLAG_MMC_MRSW_FAIL;
+ }
+ }
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+ {
+ kal_uint8 fullCardPnm[] = {0x55, 0x59, 0x4E, 0x41, 0x49, 0x54};
+
+ if (!kal_mem_cmp(gSD->mCID.pnm, fullCardPnm, 6)) /*Tianyu does not provide MID and OID*/
+ {
+ SD_setFullCard(KAL_TRUE);
+ gMSDC_Handle->msdc_clkTuneUpperBund = 15000;
+ }
+ else
+ SD_setFullCard(KAL_FALSE);
+ }
+#endif
+
+ }
+ else // SD_CARD
+ {
+ gSD->mCID.mid = *(pcid + 15);
+ gSD->mCID.oid = *(pcid + 13) + 256 * (*(pcid + 14));
+
+ for (i = 0; i < 5; i++)
+ gSD->mCID.pnm[i] = *(pcid + 8 + i);
+
+ gSD->mCID.prv = *(pcid + 7);
+ //gSD->mCID.psn = *(kal_uint32*)(pcid+3);
+ gSD->mCID.psn = (*(kal_uint32*)(pcid + 4) << 8) | *(pcid + 3);
+ gSD->mCID.month = (kal_uint8)GET_BIT(*(pcid + 1), 0, BIT_MASK_4);
+ gSD->mCID.year = GET_BIT(*(pcid + 1), 4, BIT_MASK_4) + 16 * GET_BIT(*(pcid + 2), 0, BIT_MASK_4) + 2000;
+ }
+
+#ifdef MSDC_TRACE_LEVEL1
+ MD_TRC_MSDC_INFORM_CID(gSD->mCID.mid, gSD->mCID.oid);
+#endif
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_AnalysisSCR
+*
+* DESCRIPTION
+* Analysis SD Card Configuration Register and store in the member of gSD
+*
+* PARAMETERS
+* scr: input of scr for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* Only for SD card.
+*
+*************************************************************************/
+void SD_AnalysisSCR(kal_uint32* scr)
+{
+ kal_uint8 *pscr;
+
+ pscr = (kal_uint8*)scr;
+ gSD->mSCR.spec_ver = (SD_SPEC)((kal_uint8)GET_BIT(*(pscr), 0, BIT_MASK_4));
+
+ if (gSD->mSCR.spec_ver > SD_SPEC_101)
+ gSD->flags |= SD_FLAG_CMD6_SUPPORT;
+
+ gSD->mSCR.dat_after_erase = (kal_uint8)GET_BIT(*(pscr + 1), 7, BIT_MASK_1);
+ gSD->mSCR.security = (kal_uint8)GET_BIT(*(pscr + 1), 4, BIT_MASK_3);
+ gSD->mSCR.bus_width = (kal_uint8)GET_BIT(*(pscr + 1), 0, BIT_MASK_4);
+ gSD->mSCR.cmd_support = (kal_uint8)GET_BIT(*(pscr + 3), 0, BIT_MASK_2);
+
+ gSD->mSCR.sd_spec3 = (kal_uint8)GET_BIT(*(pscr + 2), 7, BIT_MASK_1);
+ if ((gSD->mSCR.spec_ver == SD_SPEC_200) && (gSD->mSCR.sd_spec3))
+ gSD->mSCR.spec_ver = SD_SPEC_30X;
+ else
+ gSD->mSCR.spec_ver = SD_SPEC_200;
+
+ MSDC_CRIT("[SD] SD_SPEC(%d) SD_SPEC3(%d) SD_BUS_WIDTH=%d\r\n",
+ gSD->mSCR.spec_ver, gSD->mSCR.sd_spec3, gSD->mSCR.bus_width);
+ MSDC_CRIT("[SD] SD_SECU(%d) CMD_SUPP(%d): CMD23(%d), CMD20(%d)\r\n",
+ gSD->mSCR.security, gSD->mSCR.cmd_support,
+ (gSD->mSCR.cmd_support >> 1) & 0x1, gSD->mSCR.cmd_support & 0x1);
+}
+
+kal_uint32 SD_CmdPollResp(kal_uint32 * error,kal_uint32 pollTime_ms)
+{
+ kal_uint32 status;
+
+ if (!MSDC_TIMEOUT_WAIT(MSDC_Reg32(MSDC_INT)&MSDC_CMD_INTS,pollTime_ms))
+ {
+ status=MSDC_Reg32(MSDC_INT);
+ MSDC_WriteReg32(MSDC_INT,(status&MSDC_CMD_INTS));
+ if (status & MSDC_INT_CMDTMO)
+ {
+ MSDC_ERR("[SD][%s %d]CMDTMO(%d)\r\n",__FUNCTION__,
+ __LINE__, gMSDC_Handle->cmd);
+ *error=ERR_CMD_TIMEOUT;
+ }
+ else if (status & MSDC_INT_RSPCRCERR)
+ {
+ MSDC_ERR("[SD][%s %d]CMDCRC(%d)\r\n",__FUNCTION__,
+ __LINE__, gMSDC_Handle->cmd);
+ *error=ERR_CMD_RSPCRCERR;
+ }
+ else if (status & MSDC_INT_CMDRDY)
+ {
+ *error=NO_ERROR;
+ }
+ /*we get the interrupt information*/
+ return 0;
+ }
+ /*polling timeout ,so we need sleep and try wait interrupt*/
+ return 1; //tiemeout
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_WaitCmdRdyOrTo
+*
+* DESCRIPTION
+* Wait until command ready or timeout
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitCmdRdyOrTo(void)
+{
+ kal_uint32 ret;
+ kal_uint32 status;
+ kal_uint32 flag;
+ /*poll 5 ms first to check response*/
+ ret=SD_CmdPollResp(&(gMSDC_Handle->error),5);
+ if (ret)
+ {
+ MSDC_START_TIMER(MSDC_CMD_TIMEOUT/10);
+ /*enable interrupt*/
+ MSDC_SetBits32(MSDC_INTEN,MSDC_CMD_INTS|MSDC_INT_CDSC);
+ /*use interrupt handler*/
+ kal_retrieve_eg_events(gMSDC_Handle->MSDC_Events,EVENT_CMD_DONE,KAL_OR_CONSUME,&flag,KAL_SUSPEND);
+ /*disable interrupt*/
+ MSDC_ClearBits32(MSDC_INTEN, MSDC_CMD_INTS);
+ MSDC_STOP_TIMER();
+ if (gMSDC_Handle->is_timeout)
+ {
+ gMSDC_Handle->error=MSDC_GPT_TIMEOUT_ERR;
+ }
+ else
+ {
+ status=gMSDC_Handle->msdc_int&MSDC_CMD_INTS;
+
+ if (status &MSDC_INT_CMDRDY)
+ {
+ gMSDC_Handle->error=NO_ERROR;
+ }
+ else if (status& MSDC_INT_CMDTMO)
+ {
+ MSDC_ERR("[SD][%s %d]CMDTMO(%d), MSDC_CMD_INTS:%x\r\n",__FUNCTION__,
+ __LINE__, gMSDC_Handle->cmd, status);
+ gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+ }
+ else if (status & MSDC_INT_RSPCRCERR)
+ {
+ MSDC_ERR("[SD][%s %d]CMDCRC(%d), MSDC_CMD_INTS:%x\r\n",__FUNCTION__,
+ __LINE__, gMSDC_Handle->cmd, status);
+ gMSDC_Handle->error=ERR_CMD_RSPCRCERR;
+ }
+ else
+ {
+ MSDC_ERR("[SD][%s %d]ERR(%d), MSDC_CMD_INTS:%x\r\n",__FUNCTION__,
+ __LINE__, gMSDC_Handle->cmd, status);
+ gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+ }
+ ret=status;
+ }
+ }
+ return gMSDC_Handle->error;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_WaitDatRdyOrTo
+*
+* DESCRIPTION
+* Wait until data ready or timeout ,just for pio read and write
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* just polling
+*
+*************************************************************************/
+ SDC_CMD_STATUS SD_WaitDatRdyOrTo(kal_uint32 *buffer,kal_uint32 byte_len,kal_bool isWrite)
+ {
+ kal_uint32 intsts;
+ kal_uint8 * u8ptr;
+ kal_uint32 * ptr;
+ ptr=buffer;
+
+ gMSDC_Handle->abort=0;
+ MSDC_SetBits32(MSDC_INTEN,MSDC_INTEN_DATTMO|MSDC_INTEN_DATCRCERR);
+ if(!isWrite)
+ {
+ /*poll to read data from FIFO*/
+ while(byte_len)
+ {
+
+ if ((byte_len>=MSDC_FIFO_THD)&&(MSDC_RXFIFOCNT()>=MSDC_FIFO_THD)){
+ int count =MSDC_FIFO_THD>>2;
+ do{
+ *ptr++=MSDC_FIFO_READ32();
+ }while(--count);
+ byte_len-=MSDC_FIFO_THD;
+
+ }
+ else if ((byte_len<MSDC_FIFO_THD)&&(MSDC_RXFIFOCNT()>=byte_len))
+ {
+ while(byte_len>3){
+ *ptr++=MSDC_FIFO_READ32();
+ byte_len-=4;
+ }
+ u8ptr=(kal_uint8 *)ptr;
+ while(byte_len){
+ *u8ptr++=MSDC_FIFO_READ8();
+ byte_len--;
+ }
+ }
+ if (gMSDC_Handle->abort){
+ gMSDC_Handle->abort=0;
+ MSDC_ERR("[SD][%s %d]pio read abort ,byte_len=%d \r\n",__FUNCTION__,__LINE__,byte_len);
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*poll to write data into FIFO*/
+ while(byte_len){
+ if (byte_len >= MSDC_FIFO_SZ){
+ if (MSDC_TXFIFOCNT()==0){
+ int count =MSDC_FIFO_SZ>>2;
+ do {
+ MSDC_FIFO_WRITE32(*ptr);
+ ptr++;
+ }while(--count);
+ byte_len-=MSDC_FIFO_SZ;
+ }
+ }
+ else if ((byte_len<MSDC_FIFO_SZ)&&(MSDC_TXFIFOCNT()==0)){
+ while(byte_len){
+ while(byte_len>3){
+ MSDC_FIFO_WRITE32(*ptr);
+ ptr++;
+ byte_len-=4;
+ }
+ u8ptr=(kal_uint8 *)ptr;
+ while(byte_len){
+ MSDC_FIFO_WRITE8(*u8ptr);
+ u8ptr++;
+ byte_len--;
+ }
+ }
+ }
+ if (gMSDC_Handle->abort)
+ {
+ gMSDC_Handle->abort=0;
+ MSDC_ERR("[SD][%s %d]pio write abort ,byte_len=%d \r\n",__FUNCTION__,__LINE__,byte_len);
+ break;
+ }
+ }
+
+ }
+
+ MSDC_ClearBits32(MSDC_INTEN, MSDC_INTEN_DATTMO|MSDC_INTEN_DATCRCERR);
+ if (byte_len)
+ goto end;
+ intsts =MSDC_PollInts(MSDC_INT_XFER_COMPL|MSDC_INT_DATTMO|MSDC_INT_DATCRCERR,100);
+ MSDC_DEBUG("[SD][%s %d]intsts =%x \r\n",__FUNCTION__,__LINE__,intsts);
+ MSDC_CLR_FIFO();
+ if (intsts&MSDC_INT_XFER_COMPL)
+ {
+ gMSDC_Handle->error=NO_ERROR;
+ }
+ else if (intsts&MSDC_INT_DATCRCERR){
+ gMSDC_Handle->error=ERR_DAT_CRCERR;
+ }
+ else if (intsts&MSDC_INT_DATTMO)
+ {
+ gMSDC_Handle->error=ERR_DAT_TIMEOUT;
+ }
+end:
+ if (gMSDC_Handle->error)
+ {
+ MSDC_FatalErrorHandle();
+ }
+
+ /*wait busy for write operation*/
+ if (isWrite)
+ {
+ dbg_print("isWrite=%x ,go to MSDC_CheckCardBusy",isWrite);
+ MSDC_CheckCardBusy(KAL_FALSE,30*1000);
+ }
+ return gMSDC_Handle->error;
+ }
+
+/*************************************************************************
+* FUNCTION
+* SD_WaitCardNotBusy
+*
+* DESCRIPTION
+* Wait until card is not busy (R1b)
+*
+* PARAMETERS
+*
+* RETURNS
+* void
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+extern kal_bool FTL_isPollingMode();
+kal_uint32 direct_msdc_entry = 0;
+
+SDC_CMD_STATUS SD_WaitCardNotBusy(kal_uint32 timeout_ms)
+{
+ if(MSDC_TIMEOUT_WAIT((!SD_IS_R1B_BUSY())&&MSDC_Check_Card_Present(),timeout_ms))
+ {
+ gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+ MSDC_ERR("[SD][%s %d]R1B busy timeout ,wait %d ms\r\n",__FUNCTION__,__LINE__,timeout_ms);
+ return ERR_CMD_TIMEOUT;
+ }
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_CheckStatus
+*
+* DESCRIPTION
+* Check command status
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_CheckStatus(void)
+{
+ kal_uint32 status;
+
+ status= MSDC_Reg32(SDC_RESP0);
+ if ((status & SDC_CSTA_MASK) == 0 )
+ return NO_ERROR;
+
+ MSDC_ERR("[SD][%s %d]check status<%x>\r\n",__FUNCTION__,__LINE__,status);
+ if (status & SDC_CARD_IS_LOCKED)
+ {
+
+ return CARD_IS_LOCKED;
+ }
+ return ERR_STATUS;
+
+}
+
+
+
+/*************************************************************************
+* FUNCTION
+* SD_Send_Cmd
+*
+* DESCRIPTION
+* to launch the command packet to the card
+*
+* PARAMETERS
+* 1. cmd: the content of SDC_CMD register
+* 2. arg: the argument(if the command need no argument, fill it with 0)
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* 1. Check if controller is available before launch any commands
+* 2. Maybe add check if card is busy (R1b)
+*************************************************************************/
+SDC_CMD_STATUS SD_SendCmdOnly( kal_uint32 cmd, kal_uint32 arg,kal_uint32 timeout_ms)
+{
+ kal_uint32 retry_count=0;
+check_busy:
+ /*wait CMD busy and SDC busy*/
+ if (cmd == SDC_CMD_CMD12||cmd==SDC_CMD_CMD13)
+ {
+ if (MSDC_TIMEOUT_WAIT((!SD_IS_CMD_BUSY()),timeout_ms))
+ {
+ gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+ MSDC_FatalErrorHandle();
+ MSDC_ERR("[SD][%s %d]wait cmd busy timeout !!,retry %d times\r\n",__FUNCTION__,__LINE__,retry_count);
+ }
+ }
+ else
+ {
+ if (MSDC_TIMEOUT_WAIT((!SD_IS_SDC_BUSY()), timeout_ms))
+ {
+ gMSDC_Handle->error=ERR_CMD_TIMEOUT;
+ MSDC_FatalErrorHandle();
+ MSDC_ERR("[SD][%s %d]wait SDC busy %d ms timeout!!,retry %d times\r\n",__FUNCTION__,__LINE__,timeout_ms,retry_count);
+ goto retry;
+ }
+ }
+ if (gSD->mBKLength&&(gSD->mBKLength <= 0xfff))
+ {
+ cmd|=(gSD->mBKLength<<16);
+ }
+
+ /* If the card supports CMD23, enable AUTOCMD23 function of MSDC */
+ if (((cmd & 0x3F) == 18) || ((cmd & 0x3F) == 25)) {
+ if ((gSD->mSCR.cmd_support >> 1) & 0x1)
+ cmd |= (2 << 28);
+ }
+
+ MSDC_DEBUG("[SD]CMD=%d, arg=%X\r\n", cmd & 0x3F, arg);
+
+ /*set argument*/
+ MSDC_WriteReg32(SDC_ARG,arg);
+ /*set command*/
+ MSDC_WriteReg32(SDC_CMD,cmd);
+ gMSDC_Handle->cmd = (kal_uint8)(cmd & 0x3F);
+ gMSDC_Handle->error=NO_ERROR;
+ return gMSDC_Handle->error;
+
+retry:
+ if ((!SD_IS_SDC_BUSY())&&(retry_count<3)){
+ retry_count++;
+ goto check_busy;
+ }
+ return gMSDC_Handle->error;
+
+}
+
+#define MSDC_TUNE_CMD_RESP_TA_MAX (8)
+#define MSDC_TUNE_INT_DAT_LATCH_CK_MAX (8)
+#define MSDC_TUNE_WCRC_TA_MAX (8)
+
+static kal_uint8 fgCMDTuneLargeScale = 1;
+static kal_uint32 times_large = 0;
+static kal_uint32 times_small = 0;
+
+static kal_uint8 fgWrTuneLargeScale = 1;
+static kal_uint32 times_large_w = 0;
+static kal_uint32 times_small_w = 0;
+
+static kal_uint8 fgReadTuneLargeScale = 1;
+static kal_uint32 times_large_r = 0;
+static kal_uint32 times_small_r = 0;
+
+static kal_uint32 msdc_tune_cmd_retry(kal_uint32 cmd, kal_uint32 arg, kal_uint32 timeout_ms)
+{
+ kal_uint32 result = ERR_CMD_RSPCRCERR;
+
+ /* CMD12 CRCERR should not tune */
+ if ((cmd & 0x3F) == 12) {
+ result = NO_ERROR;
+ goto done;
+ }
+
+ /* Send 'STOP' command to complete 'TRANS' state */
+ if (MSDC_Reg32(SDC_CMD)&0x1800)
+ {
+ /*check if has data phase*/
+ result=SD_SendCmdOnly(SDC_CMD_CMD12,SDC_NO_ARG,1000);
+ result=SD_WaitCmdRdyOrTo();
+ if (result!=NO_ERROR)
+ goto err;
+ }
+
+ if (gMSDC_Handle->app_cmd)
+ {
+ /*for acmd ,we should send cmd55 again*/
+ result=SD_SendCmdOnly(SDC_CMD_CMD55,gSD->mRCA,1000);
+ if (result!=NO_ERROR)
+ goto err;
+ result=SD_WaitCmdRdyOrTo();
+ if (result!=NO_ERROR)
+ goto err;
+ }
+
+ result=SD_SendCmdOnly(cmd,arg,timeout_ms);
+
+ if (result!=NO_ERROR)
+ goto err;
+
+ result=SD_WaitCmdRdyOrTo();
+ if (result==NO_ERROR)
+ goto done;
+ if (result != ERR_CMD_RSPCRCERR)
+ goto err;
+
+err:
+ MSDC_FatalErrorHandle();
+done:
+ return result;
+}
+
+kal_uint32 msdc_tune_cmd_large_scale()
+{
+ kal_uint32 ret = 0;
+ kal_uint32 clk_mode, cmd_resp_ta_cntr, r_smpl;
+
+ times_large++;
+
+ MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+ MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, cmd_resp_ta_cntr);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl);
+
+ /*
+ * If MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz
+ * that is ultra high speed mode, tune CMD_RESP_TA first
+ */
+ if ((clk_mode == 1) || (clk_mode == 2) ||
+ (gMSDC_Handle->op_clock >= MSDC_TUNE_UHS_SCLK)) {
+ cmd_resp_ta_cntr++;
+ MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR,
+ cmd_resp_ta_cntr & (MSDC_TUNE_CMD_RESP_TA_MAX - 1));
+
+ if (cmd_resp_ta_cntr >= MSDC_TUNE_CMD_RESP_TA_MAX) {
+ r_smpl++;
+ MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl % 2);
+ }
+ }
+ else {
+ /*
+ * In low speed mode, just tune R_SMPL
+ * and set MSDC_CMD_RSP_TA_CNTR back to 0
+ */
+ r_smpl++;
+ cmd_resp_ta_cntr = 0;
+ MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl % 2);
+ MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, cmd_resp_ta_cntr &
+ (MSDC_TUNE_CMD_RESP_TA_MAX - 1));
+ }
+
+ /* Now all the parameters are set to 0 */
+ if (r_smpl >= 2)
+ ret = 1;
+
+ MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+ MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, cmd_resp_ta_cntr);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl);
+
+ MSDC_NOTICE("[SD] <TUNE_CMD_LS><%d> CKMOD=%d, CMD_RSP_TA=%d, R_SMPL=%d\r\n",
+ times_large, clk_mode, cmd_resp_ta_cntr, r_smpl);
+
+ if (ret)
+ times_large = 0;
+
+ return ret;
+}
+
+kal_uint32 msdc_tune_cmd_small_scale()
+{
+ kal_uint32 ret = 0;
+ kal_uint32 cmd_rxdly, clk_mode, cmd_resp_ta_cntr, r_smpl;
+
+ times_small++;
+ MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+ MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, cmd_resp_ta_cntr);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl);
+ MSDC_GET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, cmd_rxdly);
+
+ /* Adjust CMD_RXDLY in PAD macro */
+ cmd_rxdly++;
+ MSDC_SET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, cmd_rxdly & 0x1F);
+
+ /* Adjust R_SMPL */
+ if (cmd_rxdly >= 32) {
+ r_smpl++;
+ MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl % 2);
+ }
+
+ /*
+ * Adjust CMD_RSP_TA_CNTR
+ * if MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz
+ */
+ if (r_smpl >= 2) {
+ if ((clk_mode == 1) || (clk_mode == 2) || (gMSDC_Handle->op_clock >= MSDC_TUNE_UHS_SCLK)) {
+ cmd_resp_ta_cntr++;
+ MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR,
+ cmd_resp_ta_cntr & (MSDC_TUNE_CMD_RESP_TA_MAX - 1));
+
+ if (cmd_resp_ta_cntr >= MSDC_TUNE_CMD_RESP_TA_MAX)
+ ret = 1;
+ }
+ else
+ ret= 1;
+ }
+
+ MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, cmd_resp_ta_cntr);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RSPL, r_smpl);
+ MSDC_GET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, cmd_rxdly);
+
+ MSDC_NOTICE("[SD] <TUNE_CMD_SS><%d> CMD_RXDLY=%d, R_SMPL=%d, CMD_RSP_TA=%d\r\n",
+ times_small, cmd_rxdly, r_smpl, cmd_resp_ta_cntr);
+
+ /* Now all the parameters are set to 0 */
+ if (ret)
+ times_small = 0;
+
+ return ret;
+}
+
+SDC_CMD_STATUS SD_CmdTuneResp(kal_uint32 cmd,kal_uint32 arg,kal_uint32 timeout_ms)
+{
+ kal_uint32 result = ERR_CMD_RSPCRCERR;
+
+ do {
+ /* Retry the CMD with error handling */
+ result = msdc_tune_cmd_retry(cmd, arg, timeout_ms);
+
+ if ((result == ERR_CMD_TIMEOUT) ||
+ (result == NO_ERROR)) {
+ if (result == NO_ERROR) {
+ if (times_large)
+ fgCMDTuneLargeScale = 0;
+
+ times_small = 0;
+ }
+ goto done;
+ }
+
+ /* Large scale timing tuning */
+ if (fgCMDTuneLargeScale) {
+ if (msdc_tune_cmd_large_scale())
+ fgCMDTuneLargeScale = 0;
+ }
+ /* Small scale timing tuning */
+ else {
+ if (msdc_tune_cmd_small_scale())
+ goto done;
+ }
+
+ } while (1);
+
+done:
+ MSDC_CRIT("[SD] <TUNE_CMD%d_DONE>", cmd & 0x3F);
+ if (result == NO_ERROR)
+ MSDC_CRIT(" %s\r\n", "PASS");
+ else if (result == ERR_CMD_RSPCRCERR)
+ MSDC_CRIT(" %s\r\n", "CRCERR");
+ else if (result == ERR_CMD_TIMEOUT)
+ MSDC_CRIT(" %s\r\n", "TIMEOUT");
+
+ return result;
+}
+
+SDC_CMD_STATUS SD_SendCmd(kal_uint32 cmd,kal_uint32 arg,kal_uint32 timeout_ms)
+{
+ kal_uint32 status;
+ /*send command */
+ status = SD_SendCmdOnly(cmd,arg,timeout_ms);
+ if (status!=NO_ERROR)
+ {
+ MSDC_ERR("[SD][%s %d]send cmd %d error \r\n",__FUNCTION__,__LINE__,cmd);
+ return status;
+ }
+ /*wait command complete*/
+ status=SD_WaitCmdRdyOrTo();
+ if (status != NO_ERROR)
+ {
+ MSDC_FatalErrorHandle();
+ if (status == ERR_CMD_RSPCRCERR)
+ {
+ SD_CmdTuneResp(cmd, arg,timeout_ms);
+ }
+ status = gMSDC_Handle->error;
+
+ return status;
+ }
+ if (cmd== SDC_CMD_CMD55 )
+ {
+ gMSDC_Handle->app_cmd=1;
+ }
+ else
+ {
+ gMSDC_Handle->app_cmd=0;
+
+ }
+ return status;
+}
+kal_uint32 SD_PioRead(kal_uint32 * buffer,kal_uint32 num)
+{
+ kal_uint32 *ptr=buffer;
+ kal_uint8 *u8ptr;
+ kal_uint32 left;
+ ptr =buffer;
+ left=num;
+ while(left)
+ {
+ if ((left>=MSDC_FIFO_THD)&&(MSDC_RXFIFOCNT()>=MSDC_FIFO_THD)){
+ int count =MSDC_FIFO_THD>>2;
+ do{
+ *ptr++=MSDC_FIFO_READ32();
+ }while(--count);
+ left-=MSDC_FIFO_THD;
+
+ }
+ else if ((left<MSDC_FIFO_THD)&&(MSDC_RXFIFOCNT()>=left))
+ {
+ while(left>3){
+ *ptr++=MSDC_FIFO_READ32();
+ left-=4;
+ }
+ u8ptr=(kal_uint8 *)ptr;
+ while(left){
+ *u8ptr++=MSDC_FIFO_READ8();
+ left--;
+ }
+
+ if (gMSDC_Handle->abort){
+ gMSDC_Handle->abort=0;
+ MSDC_ERR("[SD][%s %d]pio read abort!!, num= %d \r\n",__FUNCTION__,__LINE__,num);
+ goto end;
+ }
+ }
+ }
+end:
+ return left;
+}
+
+kal_uint32 SD_PioWrite(kal_uint32 * buffer,kal_uint32 num)
+{
+ kal_uint32 * ptr=buffer;
+ kal_uint8 *u8ptr;
+ kal_uint32 left;
+ ptr=buffer;
+ left=num;
+ while(left){
+ if (left >= MSDC_FIFO_SZ){
+ if (MSDC_TXFIFOCNT()==0){
+ int count =MSDC_FIFO_SZ>>2;
+ do {
+ MSDC_FIFO_WRITE32(*ptr);
+ ptr++;
+ }while(--count);
+ left-=MSDC_FIFO_SZ;
+ }
+ }
+ else if ((left<MSDC_FIFO_SZ)&&(MSDC_TXFIFOCNT()==0)){
+ while(left){
+ while(left>3){
+ MSDC_FIFO_WRITE32(*ptr);
+ ptr++;
+ left-=4;
+ }
+ u8ptr=(kal_uint8 *)ptr;
+ while(left){
+ MSDC_FIFO_WRITE8(*u8ptr);
+ u8ptr++;
+ left--;
+ }
+ }
+ }
+ if (gMSDC_Handle->abort)
+ {
+ gMSDC_Handle->abort=0;
+ MSDC_ERR("[SD][%s %d]pio write abort %d \r\n",__FUNCTION__,__LINE__,num);
+ goto done;
+ }
+ }
+
+done:
+ return left;
+}
+
+#if !defined(MSDC_QMU_ENABLE)
+static kal_uint8 msdc_cal_checksum(const void *buf,kal_uint32 len)
+{
+ kal_uint32 i,sum=0;
+ kal_char *data=(char*)buf;
+ for(i=0;i<len;i++)
+ {
+ sum+=*data++;
+ }
+ return 0xFF-(kal_uint8)sum;
+}
+#endif
+
+static DCL_STATUS SD_ConfigGpdList(kal_uint32 size)
+{
+#if !defined(MSDC_QMU_ENABLE)
+ kal_uint32 i,buflen,data_count;
+ kal_uint32 * data_ptr;
+ kal_uint32 t1;
+ qbm_gpd* cur_gpd=NULL,*cur_bd=NULL;
+ msdc_gpd_t *gpd;
+ msdc_gpd_t *gpd_end;
+ qbm_gpd *head;
+ qbm_gpd *tail;
+ kal_uint8 sel = 0;
+
+ #define CONFIG_GPDLIST_TIMEOUT 10000
+
+ head = MSDC_Blk[sel].head;
+ tail = MSDC_Blk[sel].tail;
+ gpd = MSDC_Blk[sel].gpd;
+ gpd_end = MSDC_Blk[sel].gpd_end;
+
+ gpd->intr =1; /*don't generate DMA_done interrupt*/
+ gpd->extlen =0; /*ignore cmd,arg etc*/
+ gpd->hwo =1; /*config hardware owner*/
+ gpd->bdp =1; /*use buffer descriptor list*/
+ gpd->ptr =(void*)(&MSDC_bd[sel][0]);
+ gpd->next =(void*)gpd_end;
+
+ #ifdef MSDC_DMA_CHKSUM_EN
+ gpd->chksum =0;
+ gpd->chksum =msdc_cal_checksum(gpd,16);
+ #endif
+
+ gpd_end->intr =0; /*don't generate DMA_done interrupt*/
+ gpd_end->extlen =0; /*ignore cmd,arg etc*/
+ gpd_end->hwo =0; /*config hardware owner*/
+ gpd_end->bdp =0; /*use buffer descriptor list*/
+ gpd_end->ptr =0;
+ gpd_end->next =NULL;
+
+ #ifdef MSDC_DMA_CHKSUM_EN
+ gpd_end->chksum =0;
+ gpd_end->chksum =msdc_cal_checksum(gpd_end,16);
+ #endif
+
+ data_count = 0;
+ t1 = drv_get_current_time();
+
+ for (i=0,cur_gpd=head;;cur_gpd=QBM_DES_GET_NEXT(cur_gpd)) {
+ if (i > MSDC_BD_MAX)
+ {
+ MSDC_ERR("[%s %d]qbm_gpd list is to long,only supprot %d object \r\n",__FUNCTION__,__LINE__,MSDC_BD_MAX);
+ return STATUS_INVALID_ARGUMENT;
+ }
+
+ /* NULL pointer check */
+ if (cur_gpd == NULL) {
+ MSDC_ERR("[%s %d]cur_gpd is NULL pointer!\r\n",__FUNCTION__,__LINE__);
+ return STATUS_INVALID_ARGUMENT;
+ }
+
+ if (QBM_DES_GET_BDP(cur_gpd))
+ {
+ // if GPD with BD with data buffer
+ cur_bd=QBM_DES_GET_DATAPTR(cur_gpd);
+ while(1)
+ {
+ buflen=QBM_DES_GET_DATALEN(cur_bd);
+ data_ptr=(kal_uint32 *)QBM_DES_GET_DATAPTR(cur_bd);
+ if ((data_count+buflen)>size)
+ { //if buffer length is large the secotors we want to transfer
+ buflen=size-data_count;
+ data_count=size;
+ }
+ else
+ {
+ data_count+=buflen;
+ }
+ if (buflen)
+ { // if point to a buffer adress on this BD
+
+ if (((cur_gpd==tail)&&(QBM_DES_GET_EOL(cur_bd)))||(data_count==size))
+ MSDC_bd[sel][i].eol =1;
+ else
+ MSDC_bd[sel][i].eol =0;
+ MSDC_bd[sel][i].next =&MSDC_bd[sel][i+1];
+ MSDC_bd[sel][i].ptr =data_ptr;
+ MSDC_bd[sel][i].buflen =buflen;
+ clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)data_ptr),CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)data_ptr,buflen));
+ MSDC_bd[sel][i].blkpad =0;
+ MSDC_bd[sel][i].dwpad =0;
+ MSDC_bd[sel][i].chksum=0;
+ MSDC_bd[sel][i].chksum=msdc_cal_checksum(&MSDC_bd[sel][i],16);
+ i++;
+ }
+ if(QBM_DES_GET_EOL(cur_bd))
+ {
+ break;
+ }
+ cur_bd=QBM_DES_GET_NEXT(cur_bd);
+ }
+ }
+ else
+ {
+ // if GPD with data buffer
+ buflen=QBM_DES_GET_DATALEN(cur_gpd);
+ //dbg_print("%d buflen=%d\r\n",i,buflen);
+ data_ptr=(kal_uint32 *)QBM_DES_GET_DATAPTR(cur_gpd);
+ if ((data_count+buflen)>size)
+ {
+ buflen=size-data_count;
+ data_count=size;
+ //dbg_print("entry last data_count %d,buflen %d size %d\r\n",data_count,buflen,size);
+ }
+ else
+ {
+ data_count+=buflen;
+ }
+ if (buflen)
+ {
+ if (cur_gpd==tail||data_count==size)
+ MSDC_bd[sel][i].eol =1;
+ else
+ MSDC_bd[sel][i].eol =0;
+ MSDC_bd[sel][i].next =&MSDC_bd[sel][i+1];
+ MSDC_bd[sel][i].ptr =data_ptr;
+ MSDC_bd[sel][i].buflen =buflen;
+
+ /*
+ * There is NO need to clean the data cache, which is transfered
+ * from MSD and USB, because the buffer is directly read or write
+ * by DMA, CPU are not involved in.
+ */
+ #if defined(MSDC_SCAT_BUF_FLUSH) || defined(ATEST_DRV_MSDC)
+ clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)data_ptr),CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)data_ptr,buflen));
+ #endif
+
+ MSDC_bd[sel][i].blkpad =0;
+ MSDC_bd[sel][i].dwpad =0;
+
+ #ifdef MSDC_DMA_CHKSUM_EN
+ MSDC_bd[sel][i].chksum=0;
+ MSDC_bd[sel][i].chksum=msdc_cal_checksum(&MSDC_bd[sel][i], 16);
+ #endif
+
+ i++;
+ }
+ }
+ if (cur_gpd==tail)
+ break;
+
+ }
+
+ if (drv_get_duration_ms(t1)>CONFIG_GPDLIST_TIMEOUT)
+ {
+ MSDC_INFO("[%s %d]config gpd list timeout\r\n",__FUNCTION__,__LINE__,MSDC_BD_MAX);
+ return STATUS_INVALID_ARGUMENT;
+ }
+
+ //if data buffer is not enough
+ if (data_count!=size)
+ {
+ MSDC_INFO("[%s %d]data_count %d,size %d\r\n",__FUNCTION__,__LINE__,data_count,size);
+ return STATUS_INVALID_ARGUMENT;
+ }
+
+ /* Flush the GPD and BD from cache to memory */
+ #ifdef MSDC_GPD_BD_BUF_CACHED
+ clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)gpd),
+ CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)gpd, sizeof(msdc_gpd_t)));
+ clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)gpd_end),
+ CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)gpd_end, sizeof(msdc_gpd_t)));
+ clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)&MSDC_bd[sel][0]),
+ CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)&MSDC_bd[sel][0], i * sizeof(msdc_bd_t)));
+ #endif
+
+ return STATUS_OK;
+
+#else
+
+ qbm_gpd *head, *tail, *tail_bak, *p_bps_gpd, *p_cur_gpd;
+ kal_uint8 sel = 0;
+
+ head = MSDC_Blk[sel].head;
+ tail = MSDC_Blk[sel].tail;
+ tail_bak = tail;
+
+ /* In case of normal transfer */
+ if (!gMSDC_Handle->f_tuning) {
+ p_bps_gpd = g_p_msdc_bps[sel];
+ if (!p_bps_gpd) {
+ MSDC_ERR("[%s %d]Invalid loacal bypass GPD buffer!\r\n",__FUNCTION__,__LINE__);
+ return STATUS_FAIL;
+ }
+
+ /* Link the bypass GPD to tail */
+ qbmt_common_en_q_rx(p_bps_gpd, p_bps_gpd, (void **)&head, (void **)&tail);
+
+ /* Set HWO = 1, cause it is cleared by USB QMU */
+ p_cur_gpd = head;
+ do {
+ if (p_cur_gpd == tail_bak)
+ break;
+
+ QBM_DES_SET_HWO(p_cur_gpd);
+ QBM_CACHE_FLUSH(p_cur_gpd, 2);
+
+ p_cur_gpd = p_cur_gpd->p_next;
+ } while(1);
+ }
+ /* In case of re-try on tuning */
+ else {
+ p_cur_gpd = head;
+
+ /* Re-Set HWO = 1, and flush cache */
+ do {
+ QBM_DES_SET_HWO(p_cur_gpd);
+ QBM_CACHE_FLUSH(p_cur_gpd, sizeof(qbm_gpd));
+
+ if ((p_cur_gpd == tail))
+ break;
+
+ p_cur_gpd = p_cur_gpd->p_next;
+
+ } while(1);
+ }
+
+ /* Set the QMU start address */
+ gMSDC_Handle->buf_addr = (void *)MSDC_Blk[sel].head;
+
+ return STATUS_OK;
+
+#endif
+}
+
+SDC_CMD_STATUS SD_ReqHandleData(kal_uint32 data_adrs, void* buffer, kal_uint32 num,kal_bool isWrite,kal_bool isLinkListBuf)
+{
+ kal_uint32 status ;
+ kal_bool dma;
+ kal_uint32 intsts;
+ kal_uint8 cmd23_sup = 0;
+
+ MSDC_INFO("[SD]SD_Req: CMD%s Addr=%x BlkNum=%d Buf=%x\r\n",
+ isWrite ? "25(24)" : "18(17)", data_adrs, num, buffer);
+
+ /*Set block size and block num*/
+ if (gSD->mBKLength!=512)
+ {
+ status =SD_SetBlength(512);
+ if (status != NO_ERROR)
+ {
+ return status;
+ }
+
+ }
+ MSDC_WriteReg32(SDC_BLK_NUM,num);
+ /*set read timeout*/
+ /*check we use dma or pio*/
+ if(gSD->mBKLength*num <512)
+ {
+ /*use pio*/
+ dma=0;
+ //set to PIO mode
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=0;
+ }
+ else
+ {
+ /*use dma*/
+ dma=1;
+ //set to DMA mode
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, 0, MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=1;
+ }
+
+ dma=1; /*driver unsupport PIO now*/
+ gMSDC_Handle->dma_xfer=1;
+ if (dma)
+ {
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0,KAL_AND);
+ /*enable DMA*/
+ MSDC_ClearBits32(MSDC_CFG,MSDC_CFG_PIO);
+ /*start command*/
+ if (!isWrite)
+ {
+ if (num==1)
+ {
+ status=SD_SendCmdOnly(SDC_CMD_CMD17,data_adrs,MSDC_CMD_TIMEOUT);
+ }
+ else
+ {
+ status=SD_SendCmdOnly(SDC_CMD_CMD18,data_adrs,MSDC_CMD_TIMEOUT);
+ }
+ }
+ else
+ {
+ if (num==1)
+ {
+ status=SD_SendCmdOnly(SDC_CMD_CMD24,data_adrs,MSDC_CMD_TIMEOUT);
+ }
+ else
+ {
+ status=SD_SendCmdOnly(SDC_CMD_CMD25,data_adrs,MSDC_CMD_TIMEOUT);
+ }
+ }
+ if (status !=NO_ERROR)
+ {
+ goto done;
+ }
+ /*map dma data*/
+
+ /*config dma*/
+ gMSDC_Handle->total_count=num*gSD->mBKLength;
+ gMSDC_Handle->buf_addr=buffer;
+
+ if (isLinkListBuf) {
+ status = SD_ConfigGpdList(gMSDC_Handle->total_count);
+ if (status != STATUS_OK) {
+ MSDC_ERR("[%s %d]Config GPD list fail!\r\n",__FUNCTION__,__LINE__);
+ return status;
+ }
+ }
+
+ MSDC_DMATransferFirst(isWrite,isLinkListBuf);
+
+ /*wait cmd rsp*/
+ status=SD_WaitCmdRdyOrTo();
+ if (status != NO_ERROR)
+ {
+ MSDC_FatalErrorHandle();
+ if (status == ERR_CMD_RSPCRCERR)
+ {
+ if (!isWrite)
+ { if (num==1)
+ status=SD_CmdTuneResp(SDC_CMD_CMD17, data_adrs,MSDC_CMD_TIMEOUT);
+ else
+ status=SD_CmdTuneResp(SDC_CMD_CMD18, data_adrs,MSDC_CMD_TIMEOUT);
+ }
+ else
+ {
+ if(num==1)
+ status=SD_CmdTuneResp(SDC_CMD_CMD24, data_adrs,MSDC_CMD_TIMEOUT);
+ else
+ status=SD_CmdTuneResp(SDC_CMD_CMD25, data_adrs,MSDC_CMD_TIMEOUT);
+ }
+ }
+ if(status != NO_ERROR)
+ goto done;
+ }
+ /*start dma and wait data complete*/
+ status = MSDC_DMATransferFinal(isWrite,isLinkListBuf);
+ }
+ else
+ {
+ /*pio mode*/
+ if (SD_SendCmd(((isWrite==KAL_TRUE) ?SDC_CMD_CMD25:SDC_CMD_CMD18),data_adrs,MSDC_CMD_TIMEOUT))
+ {
+ goto done;
+ }
+ MSDC_SetBits32(MSDC_INTEN,MSDC_INTEN_DATTMO|MSDC_INTEN_DATCRCERR);
+ if(!isWrite)
+ {
+ /*poll to read data from FIFO*/
+ status =SD_PioRead(buffer,num*gSD->mBKLength);
+ }
+ else
+ {
+ /*poll to write data to FIFO*/
+ status =SD_PioWrite(buffer,num*gSD->mBKLength);
+ }
+
+ MSDC_ClearBits32(MSDC_INTEN, MSDC_INTEN_DATTMO|MSDC_INTEN_DATCRCERR);
+ if (status)
+ {
+ goto done;
+ }
+ intsts =MSDC_PollInts(MSDC_INT_XFER_COMPL|MSDC_INT_DATTMO|MSDC_INT_DATCRCERR,100);
+ if (intsts&MSDC_INT_XFER_COMPL)
+ {
+ status=gMSDC_Handle->error=NO_ERROR;
+ }
+ else if (intsts&MSDC_INT_DATCRCERR){
+ status=gMSDC_Handle->error=ERR_DAT_CRCERR;
+ }
+ else if (intsts&MSDC_INT_DATTMO)
+ {
+ status=gMSDC_Handle->error=ERR_DAT_TIMEOUT;
+ }
+ else
+ MSDC_ERR("[SD][%s %d]SW timeout in wait PIO data done\r\n",__FUNCTION__,__LINE__);
+ }
+done:
+ if (status)
+ {
+ MSDC_FatalErrorHandle();
+ }
+
+ /*cmd12 to stop data*/
+ cmd23_sup = (gSD->mSCR.cmd_support >> 1) & 0x1;
+ if (((num>1) && !cmd23_sup) || ((num>1) && cmd23_sup && status))
+ SD_SendCmd(SDC_CMD_CMD12, SDC_NO_ARG, MSDC_CMD_TIMEOUT);
+
+ /* Check card status after each operation */
+ MSDC_CheckCardBusy(KAL_FALSE, 10*1000);
+
+ return status;
+}
+
+kal_uint32 msdc_tune_write_large_scale()
+{
+ kal_uint32 ret = 0;
+ kal_uint32 ultra_hs = 0;
+ kal_uint32 clk_mode, wr_datcrc_ta, w_d_smpl;
+
+ times_large_w++;
+
+ MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+ MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, wr_datcrc_ta);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl);
+
+ /*
+ * If MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz
+ * that is ultra high speed mode, tune WRDAT_CRCS_TA_CNTR first
+ */
+ if ((clk_mode == 1) || (clk_mode == 2) || (gMSDC_Handle->op_clock > MSDC_TUNE_UHS_SCLK))
+ ultra_hs = 1;
+
+ if (ultra_hs) {
+ wr_datcrc_ta++;
+ MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR,
+ wr_datcrc_ta & (MSDC_TUNE_WCRC_TA_MAX - 1));
+
+ if (wr_datcrc_ta >= MSDC_TUNE_WCRC_TA_MAX) {
+ w_d_smpl++;
+ MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl % 2);
+ }
+ }
+ else {
+ w_d_smpl++;
+ wr_datcrc_ta = 0;
+ MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl % 2);
+ MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR,
+ wr_datcrc_ta & (MSDC_TUNE_WCRC_TA_MAX - 1));
+ }
+
+ if (w_d_smpl >= 2) {
+ ret = 1;
+ }
+
+ MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, wr_datcrc_ta);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl);
+
+ MSDC_NOTICE("[SD] <TUNE_WR_LS><%d> %s=%d, %s=%d, %s=%d\r\n",
+ times_large_w, "CKMOD", clk_mode,
+ "WR_DATCRC_TA", wr_datcrc_ta, "W_D_SMPL", w_d_smpl);
+
+ if (ret)
+ times_large_w = 0;
+
+ return ret;
+}
+
+kal_uint32 msdc_tune_write_small_scale()
+{
+ kal_uint32 ret = 0;
+ kal_uint32 ultra_hs = 0;
+ kal_uint32 clk_mode, wr_datcrc_ta, w_d_smpl, dat0_rd_dly, dat_wr_rxdly;
+
+ times_small_w++;
+
+ /*
+ * When re-enter the tuning flow,
+ * Clear the pad macro then tune from the beginning
+ */
+ if (times_small_w == 1) {
+ MSDC_SET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, 0);
+ }
+
+ MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+ MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, wr_datcrc_ta);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl);
+ MSDC_GET_FIELD(MSDC_DAT_RDDLY0, MSDC_DAT_RDDLY0_D0, dat0_rd_dly);
+ MSDC_GET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, dat_wr_rxdly);
+
+ /*
+ * If MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz
+ * that is ultra high speed mode, tune WRDAT_CRCS_TA_CNTR
+ * and PAT_DAT_WR_RXDLY at last
+ */
+ if ((clk_mode == 1) || (clk_mode == 2) || (gMSDC_Handle->op_clock > MSDC_TUNE_UHS_SCLK))
+ ultra_hs = 1;
+
+ dat_wr_rxdly++;
+ MSDC_SET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, dat_wr_rxdly & 0x1F);
+
+ if (dat_wr_rxdly >= 32) {
+ w_d_smpl++;
+ MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl % 2);
+ }
+
+ if (ultra_hs) {
+ if (w_d_smpl >= 2) {
+ wr_datcrc_ta++;
+ MSDC_SET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR,
+ wr_datcrc_ta & (MSDC_TUNE_WCRC_TA_MAX - 1));
+ }
+
+ if (wr_datcrc_ta >= MSDC_TUNE_WCRC_TA_MAX)
+ ret = 1;
+ }
+
+ if (w_d_smpl >= 2)
+ ret = 1;
+
+ MSDC_GET_FIELD(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, wr_datcrc_ta);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_WDSPL, w_d_smpl);
+ MSDC_GET_FIELD(MSDC_DAT_RDDLY0, MSDC_DAT_RDDLY0_D0, dat0_rd_dly);
+ MSDC_GET_FIELD(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, dat_wr_rxdly);
+
+ MSDC_NOTICE("[SD] <TUNE_WR_SS><%d> %s=%d, %s=%d, %s=%d\r\n",
+ times_small_w, "CKMOD", clk_mode,
+ "WR_DATCRC_TA", wr_datcrc_ta, "W_D_SMPL", w_d_smpl);
+ MSDC_NOTICE(" %s=%d, %s=%d\r\n",
+ "DAT0_RD_DLY", dat0_rd_dly, "DAT_WR_RXDLY", dat_wr_rxdly);
+
+ if (ret)
+ times_small_w = 0;
+
+ return ret;
+}
+
+kal_uint32 SD_TuneWrite(kal_uint32 address,void * txbuffer,kal_uint32 num,kal_bool isLinkListBuf)
+{
+ kal_uint32 result = ERR_DAT_CRCERR;
+
+ do {
+ /* Retry the Write with error handling */
+ result = SD_ReqHandleData(address,txbuffer,num,KAL_TRUE,isLinkListBuf);
+
+ if (/*(result == ERR_DAT_TIMEOUT) ||*/
+ (result == NO_ERROR)) {
+ if (times_large_w)
+ fgWrTuneLargeScale = 0;
+
+ times_small_w = 0;
+
+ goto done;
+ }
+
+ /* Large scale timing tuning */
+ if (fgWrTuneLargeScale) {
+ if (msdc_tune_write_large_scale())
+ fgWrTuneLargeScale = 0;
+ }
+ /* Small scale timing tuning */
+ else {
+ if (msdc_tune_write_small_scale())
+ goto done;
+ }
+
+ } while (1);
+
+done:
+ MSDC_CRIT("[SD] <TUNE_WRITE_DONE>");
+ if (result == NO_ERROR)
+ MSDC_CRIT(" %s\r\n", "PASS");
+ else if (result == ERR_DAT_CRCERR)
+ MSDC_CRIT(" %s\r\n", "CRCERR");
+ else if (result == ERR_DAT_TIMEOUT)
+ MSDC_CRIT(" %s\r\n", "TIMEOUT");
+
+ return result;
+}
+
+
+kal_uint32 msdc_tune_read_large_scale()
+{
+ kal_uint32 ret = 0;
+ kal_uint32 ultra_hs = 0;
+ kal_uint32 clk_mode, int_dat_latch, ckgen_dly, r_d_smpl;
+
+ times_large_r++;
+
+ MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+ MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, int_dat_latch);
+ MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl);
+
+ /*
+ * If MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz
+ * that is ultra high speed mode, tune INT_DAT_LATCH_CK_SEL
+ * and CKGEN_MSDC_DLY_SEL first
+ */
+ if ((clk_mode == 1) || (clk_mode == 2) || (gMSDC_Handle->op_clock > MSDC_TUNE_UHS_SCLK))
+ ultra_hs = 1;
+
+ if (ultra_hs) {
+ /* Sampling edge is fixed by default setting - rising edge */
+ int_dat_latch++;
+ MSDC_SET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL,
+ int_dat_latch & (MSDC_TUNE_INT_DAT_LATCH_CK_MAX - 1));
+
+ if (int_dat_latch >= MSDC_TUNE_INT_DAT_LATCH_CK_MAX) {
+ ckgen_dly++;
+ MSDC_SET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly & 0x1F);
+
+ if (ckgen_dly >= 32)
+ ret = 1;
+ }
+ }
+ else {
+ /*
+ * In low speed mode, just tune R_D_SMPL
+ * and set other parameters back to 0
+ */
+ r_d_smpl++;
+ int_dat_latch = 0;
+ ckgen_dly = 0;
+ MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl % 2);
+ MSDC_SET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL,
+ int_dat_latch & (MSDC_TUNE_INT_DAT_LATCH_CK_MAX - 1));
+ MSDC_SET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly & 0x1F);
+
+ }
+
+ if (r_d_smpl >= 2)
+ ret = 1;
+
+ MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, int_dat_latch);
+ MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl);
+
+ MSDC_NOTICE("[SD] <TUNE_RD_LS><%d> %s=%d, %s=%d, %s=%d, %s=%d\r\n",
+ times_large_r, "CKMOD", clk_mode,
+ "INT_DAT_L", int_dat_latch, "CKGEN_DLY", ckgen_dly,
+ "R_D_SMPL", r_d_smpl);
+
+ if (ret)
+ times_large_r = 0;
+
+ return ret;
+
+}
+
+kal_uint32 msdc_tune_read_small_scale()
+{
+ kal_uint32 ret = 0;
+ kal_uint32 ultra_hs = 0;
+ kal_uint32 clk_mode, int_dat_latch, ckgen_dly, r_d_smpl, dat_rddly0, dat_rddly1;
+ kal_uint32 dat0_rd_dly, dat1_rd_dly, dat2_rd_dly, dat3_rd_dly;
+ kal_uint32 dat4_rd_dly, dat5_rd_dly, dat6_rd_dly, dat7_rd_dly;
+
+ kal_uint32 ddr = 0, dcrc_sts;
+
+ times_small_r++;
+
+ MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, clk_mode);
+
+ /*
+ * If MSDC_CFG.CLK_MODE = 1 && Bus_Speed > 100MHz
+ * that is ultra high speed mode, tune INT_DAT_LATCH_CK_SEL
+ * and CKGEN_MSDC_DLY_SEL at last
+ */
+ if ((clk_mode == 1) || (clk_mode == 2) || (gMSDC_Handle->op_clock > MSDC_TUNE_UHS_SCLK))
+ ultra_hs = 1;
+
+ /*
+ * When re-enter the tune in Non-UHS mode,
+ * Clear the pad macro then tune from the beginning
+ */
+ if ((times_small_r == 1) && (ultra_hs == 0)) {
+ MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, 0);
+ MSDC_WriteReg32(MSDC_DAT_RDDLY0, 0);
+ MSDC_WriteReg32(MSDC_DAT_RDDLY1, 0);
+ }
+
+ MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, int_dat_latch);
+ MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl);
+ dat_rddly0 = MSDC_Reg32(MSDC_DAT_RDDLY0);
+ dat_rddly1 = MSDC_Reg32(MSDC_DAT_RDDLY1);
+
+ /* Get data CRC status */
+ MSDC_GET_FIELD(SDC_DCRC_STS, SDC_DCRC_STS_NEG | SDC_DCRC_STS_POS, dcrc_sts);
+
+ /* Check output clock is SDR mode or DDR mode */
+ ddr = (clk_mode == 2) ? 1 : 0;
+ if (!ddr)
+ dcrc_sts &= ~SDC_DCRC_STS_NEG;
+
+ /* Tune PAD macro first */
+ MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
+
+ dat0_rd_dly = (dat_rddly0 >> 24) & 0x1F;
+ dat1_rd_dly = (dat_rddly0 >> 16) & 0x1F;
+ dat2_rd_dly = (dat_rddly0 >> 8) & 0x1F;
+ dat3_rd_dly = (dat_rddly0 >> 0) & 0x1F;
+ dat4_rd_dly = (dat_rddly1 >> 24) & 0x1F;
+ dat5_rd_dly = (dat_rddly1 >> 16) & 0x1F;
+ dat6_rd_dly = (dat_rddly1 >> 8) & 0x1F;
+ dat7_rd_dly = (dat_rddly1 >> 0) & 0x1F;
+
+ if (ddr) {
+ dat0_rd_dly = (dcrc_sts & (1 << 0) || dcrc_sts & (1 << 8)) ? (dat0_rd_dly + 1) : dat0_rd_dly;
+ dat1_rd_dly = (dcrc_sts & (1 << 1) || dcrc_sts & (1 << 9)) ? (dat1_rd_dly + 1) : dat1_rd_dly;
+ dat2_rd_dly = (dcrc_sts & (1 << 2) || dcrc_sts & (1 << 10)) ? (dat2_rd_dly + 1) : dat2_rd_dly;
+ dat3_rd_dly = (dcrc_sts & (1 << 3) || dcrc_sts & (1 << 11)) ? (dat3_rd_dly + 1) : dat3_rd_dly;
+ dat4_rd_dly = (dcrc_sts & (1 << 4) || dcrc_sts & (1 << 12)) ? (dat4_rd_dly + 1) : dat4_rd_dly;
+ dat5_rd_dly = (dcrc_sts & (1 << 5) || dcrc_sts & (1 << 13)) ? (dat5_rd_dly + 1) : dat5_rd_dly;
+ dat6_rd_dly = (dcrc_sts & (1 << 6) || dcrc_sts & (1 << 14)) ? (dat6_rd_dly + 1) : dat6_rd_dly;
+ dat7_rd_dly = (dcrc_sts & (1 << 7) || dcrc_sts & (1 << 15)) ? (dat7_rd_dly + 1) : dat7_rd_dly;
+ } else {
+ dat0_rd_dly = (dcrc_sts & (1 << 0)) ? (dat0_rd_dly + 1) : dat0_rd_dly;
+ dat1_rd_dly = (dcrc_sts & (1 << 1)) ? (dat1_rd_dly + 1) : dat1_rd_dly;
+ dat2_rd_dly = (dcrc_sts & (1 << 2)) ? (dat2_rd_dly + 1) : dat2_rd_dly;
+ dat3_rd_dly = (dcrc_sts & (1 << 3)) ? (dat3_rd_dly + 1) : dat3_rd_dly;
+ dat4_rd_dly = (dcrc_sts & (1 << 4)) ? (dat4_rd_dly + 1) : dat4_rd_dly;
+ dat5_rd_dly = (dcrc_sts & (1 << 5)) ? (dat5_rd_dly + 1) : dat5_rd_dly;
+ dat6_rd_dly = (dcrc_sts & (1 << 6)) ? (dat6_rd_dly + 1) : dat6_rd_dly;
+ dat7_rd_dly = (dcrc_sts & (1 << 7)) ? (dat7_rd_dly + 1) : dat7_rd_dly;
+ }
+
+ dat_rddly0 = ((dat0_rd_dly & 0x1F) << 24) | ((dat1_rd_dly & 0x1F) << 16) |
+ ((dat2_rd_dly & 0x1F) << 8) | ((dat3_rd_dly & 0x1F) << 0);
+ dat_rddly1 = ((dat4_rd_dly & 0x1F) << 24) | ((dat5_rd_dly & 0x1F) << 16) |
+ ((dat6_rd_dly & 0x1F) << 8) | ((dat7_rd_dly & 0x1F) << 0);
+
+ MSDC_WriteReg32(MSDC_DAT_RDDLY0, dat_rddly0);
+ MSDC_WriteReg32(MSDC_DAT_RDDLY1, dat_rddly1);
+
+ /* Then R_D_SMPL */
+ if( (dat0_rd_dly >= 32) || (dat1_rd_dly >= 32) || (dat2_rd_dly >= 32) || (dat3_rd_dly >= 32)||
+ (dat4_rd_dly >= 32) || (dat5_rd_dly >= 32) || (dat6_rd_dly >= 32) || (dat7_rd_dly >= 32)){
+
+ /*
+ * On ultra-hs mode, do NOT tune sampling edge,
+ * because of the 'internal boundary' issue of the current IP
+ */
+ if (!ultra_hs) {
+ r_d_smpl++;
+ MSDC_SET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl % 2);
+ }
+
+ /* Re-tune the data pad macro */
+ MSDC_WriteReg32(MSDC_DAT_RDDLY0, 0);
+ MSDC_WriteReg32(MSDC_DAT_RDDLY1, 0);
+
+ /* Then CKGEN_MSDC_DLY_SEL if it is SDR104 mode */
+ if (ultra_hs) {
+ ckgen_dly++;
+ MSDC_SET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly & 0x1F);
+
+ if (ckgen_dly >= 32)
+ ret = 1;
+ }
+ else {
+ if (r_d_smpl >= 2)
+ ret = 1;
+ }
+
+ }
+
+ MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, int_dat_latch);
+ MSDC_GET_FIELD(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, ckgen_dly);
+ MSDC_GET_FIELD(MSDC_IOCON, MSDC_IOCON_RDSPL, r_d_smpl);
+ dat_rddly0 = MSDC_Reg32(MSDC_DAT_RDDLY0);
+ dat_rddly1 = MSDC_Reg32(MSDC_DAT_RDDLY1);
+
+ MSDC_NOTICE("[SD] <TUNE_RD_SS><%d> %s=%d, %s=%d, %s=%d, %s=%d\r\n",
+ times_small_r, "CKMOD", clk_mode,
+ "INT_DAT_L", int_dat_latch, "CKGEN_DLY", ckgen_dly,
+ "R_D_SMPL", r_d_smpl);
+ MSDC_NOTICE(" %s=0x%x, %s=0x%x\r\n",
+ "DAT_RDDLY0", dat_rddly0, "DAT_RDDLY1", dat_rddly1);
+
+ if (ret)
+ times_small_r = 0;
+
+ return ret;
+
+}
+
+SDC_CMD_STATUS SD_TuneRead(kal_uint32 data_adrs,void *rxbuffer,kal_uint32 num,kal_bool isLinkListBuf)
+{
+ kal_uint32 result = ERR_DAT_CRCERR;
+
+ do {
+ /* Retry the Read with error handling */
+ result = SD_ReqHandleData(data_adrs,rxbuffer,num,KAL_FALSE,isLinkListBuf);
+
+ if ((result == ERR_DAT_TIMEOUT) ||
+ (result == NO_ERROR)) {
+ if (result == NO_ERROR) {
+ if (times_large_r)
+ fgReadTuneLargeScale = 0;
+
+ times_small_r = 0;
+ }
+
+ goto done;
+ }
+
+ /* Large scale timing tuning */
+ if (fgReadTuneLargeScale) {
+ if (msdc_tune_read_large_scale())
+ fgReadTuneLargeScale = 0;
+ }
+ /* Small scale timing tuning */
+ else {
+ if (msdc_tune_read_small_scale())
+ goto done;
+ }
+
+ } while (1);
+
+done:
+ MSDC_CRIT("[SD] <TUNE_READ_DONE>");
+ if (result == NO_ERROR)
+ MSDC_CRIT(" %s\r\n", "PASS");
+ else if (result == ERR_DAT_CRCERR)
+ MSDC_CRIT(" %s\r\n", "CRCERR");
+ else if (result == ERR_DAT_TIMEOUT)
+ MSDC_CRIT(" %s\r\n", "TIMEOUT");
+
+ return result;
+}
+
+void msdc_tune_init(void)
+{
+ /* Initialize the tuning releated parameters and registers */
+ fgCMDTuneLargeScale = 1;
+ times_large = 0;
+ times_small = 0;
+ MSDC_SET_FIELD_NPW(MSDC_PATCH_BIT1, MSDC_CMD_RSP_TA_CNTR, 0);
+ MSDC_SET_FIELD_NPW(MSDC_IOCON, MSDC_IOCON_RSPL, 0);
+ MSDC_SET_FIELD_NPW(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, 0);
+
+ fgWrTuneLargeScale = 1;
+ times_large_w = 0;
+ times_small_w = 0;
+ MSDC_SET_FIELD_NPW(MSDC_PATCH_BIT1, MSDC_WRDAT_CRCS_TA_CNTR, 0);
+ MSDC_SET_FIELD_NPW(MSDC_IOCON, MSDC_IOCON_WDSPL, 0);
+ MSDC_SET_FIELD_NPW(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, 0);
+
+ fgReadTuneLargeScale = 1;
+ times_large_r = 0;
+ times_small_r = 0;
+ MSDC_WriteReg32_NPW(MSDC_DAT_RDDLY0, 0);
+ MSDC_WriteReg32_NPW(MSDC_DAT_RDDLY1, 0);
+ MSDC_SET_FIELD_NPW(MSDC_PATCH_BIT0, MSDC_INT_DAT_LATCH_CK_SEL, 0);
+ MSDC_SET_FIELD_NPW(MSDC_PATCH_BIT0, MSDC_CKGEN_MSDC_DLY_SEL, 0);
+ MSDC_SET_FIELD_NPW(MSDC_IOCON, MSDC_IOCON_RDSPL, 0);
+}
+
+SDC_CMD_STATUS SD_HandleWriteTMO(kal_uint32 address,void *txbuffer,kal_uint32 num,kal_bool isLinkListBuf)
+{
+ kal_uint32 cur_wrta,orig_wr_crcta;
+ kal_uint32 status,i,ret;
+
+ ret=SD_GetStatus(gSD->mRCA,&status);
+ if (ret){
+ return ERR_DAT_TIMEOUT;
+ }
+ if (status&(R1_OUT_OF_RANGE_31|R1_ADDRESS_ERROR_30)){
+ return ERR_DAT_TIMEOUT;
+ }
+ orig_wr_crcta=(MSDC_Reg32(MSDC_PATCH_BIT1)&MSDC_PATCH_BIT1_WRDAT_CRCS)>>(uffs(MSDC_PATCH_BIT1_WRDAT_CRCS)-1);
+ /*Ncrc may cause Write data timeout*/
+ for (i=0;i<8;i++){
+ cur_wrta=(orig_wr_crcta+i)%8;
+ MSDC_SetData32(MSDC_PATCH_BIT1,MSDC_PATCH_BIT1_WRDAT_CRCS,cur_wrta<<(uffs(MSDC_PATCH_BIT1_WRDAT_CRCS)-1));
+ ret=SD_ReqHandleData(address,txbuffer,num,KAL_TRUE,isLinkListBuf);
+ if (ret==0)
+ return 0;
+ if (ret==ERR_DAT_CRCERR||ret==ERR_CMD_RSPCRCERR)
+ {
+ return ret;
+ }
+ }
+ if (ret)
+ {
+ return ret;
+ }
+ ret=SD_TuneWrite( address,txbuffer,num,isLinkListBuf);
+ return ret;
+}
+/*************************************************************************
+* FUNCTION
+* SD_Reset
+*
+* DESCRIPTION
+* reset all cards to idle state
+*
+* PARAMETERS
+* 1. cmd: the content of SDC_CMD register
+* 2. arg: the argument(if the command need no argument, fill it with 0)
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Reset(void)
+{
+ SDC_CMD_STATUS status;
+ status=SD_SendCmd(SDC_CMD_CMD0,SDC_NO_ARG,MSDC_CMD_TIMEOUT);
+ gSD->mState=IDLE_STA;
+ return status;
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Cmd55
+*
+* DESCRIPTION
+* APP_CMD: inidicate to the card that the next command is an application specified command
+* rather than a standard command
+*
+* PARAMETERS
+* rca: relative card address
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Cmd55(kal_uint16 rca)
+{
+ SDC_CMD_STATUS status;
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD55, ((kal_uint32)rca << 16),MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ //read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ //check APP_CMD bit in status register
+ status=MSDC_Reg32(SDC_RESP0);
+
+ if (!(status & R1_APP_CMD_5))
+ return ERR_APPCMD_FAILED;
+
+ return NO_ERROR;
+
+}
+/*************************************************************************
+* FUNCTION
+* SD_Cmd8
+*
+* DESCRIPTION
+* 1. Sends SD Memory Card interface conditions for support larger than 2G cards
+* 2. check if the card is compliant to SD2.0 or higher
+* 3. only performed while at IDLE state.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD->mIsCMD8
+*
+*************************************************************************/
+void SD_Cmd8(void)
+{
+ kal_uint32 resp;
+ kal_uint32 retry = 4;
+ MSDC_DEBUG("[SD][%s %d]Cmd8 arg=%x\r\n",__FUNCTION__,__LINE__,SDC_CMD8_ARG);
+
+cmd8_retry:
+ if (SD_SendCmd(SDC_CMD_CMD8, SDC_CMD8_ARG,MSDC_CMD_TIMEOUT) != NO_ERROR)
+ {
+ MSDC_ERR("[SD][%s %d]SDC_Cmd8 fail\r\n",__FUNCTION__,__LINE__);
+ SD_Reset();
+ gSD->mCMD8Resp = SD_CMD8_RESP_NORESP;
+ return;
+ }
+
+ resp= MSDC_Reg32(SDC_RESP0);
+ MSDC_DEBUG("[SD][%s %d]Cmd8 resp=%x\r\n",__FUNCTION__,__LINE__,resp);
+
+ if (resp == SDC_CMD8_ARG)
+ gSD->mCMD8Resp = SD_CMD8_RESP_VALID;
+ else {
+ MSDC_ERR("[SD]CMD8 check pattern error, %X(%X)\r\n",SDC_CMD8_ARG,resp);
+
+ if (retry--)
+ goto cmd8_retry;
+
+ gSD->mCMD8Resp = SD_CMD8_RESP_INVALID;
+ }
+
+ return;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Cmd1_MMC
+*
+* DESCRIPTION
+* asks all cards in idle state to send their OCR in the response on the CMD line
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* only works for MMC
+*
+*************************************************************************/
+extern kal_bool FTL_isPollingMode();
+
+SDC_CMD_STATUS SD_Cmd1_MMC(void)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 _ocr, ocr_i, t2;
+
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+
+ if (gSD->mCMD8Resp == SD_CMD8_RESP_INVALID)
+ return ERR_CMD8_INVALID;
+
+ ocr_i = (SDC_OCR_DEFAULT | MMC_HIGH_DESITY_CHECK_BIT);
+ #else
+ ocr_i = SDC_OCR_DEFAULT;
+ #endif
+
+ if (gMSDC_Handle->is_init_timeout == KAL_TRUE)
+ return ERR_R3_OCR_BUSY;
+
+ t2 = drv_get_current_time();
+
+ do
+ {
+ /*send cmd1*/
+ if ((status=SD_SendCmd(SDC_CMD_CMD1,ocr_i,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ _ocr=MSDC_Reg32(SDC_RESP0);
+ MSDC_NOTICE("[SD]OCR = %x\r\n", _ocr);
+
+ if ((_ocr & SDC_OCR_DEFAULT) == 0)
+ return ERR_OCR_NOT_SUPPORT;
+
+ if (!gMSDC_Handle->mIsPresent)
+ return MSDC_CARD_NOT_PRESENT;
+
+ if (!(_ocr & SDC_OCR_BUSY))
+ {
+ if (drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+ {
+ gMSDC_Handle->is_init_timeout = KAL_TRUE;
+ break;
+ }
+
+ msdc_sleep(2);
+ }
+ else {
+ MSDC_CRIT("[SD]OCR = %x\r\n", _ocr);
+ break;
+ }
+ }
+ while (1);
+
+ if (gMSDC_Handle->is_init_timeout)
+ return ERR_CMD_TIMEOUT;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+
+ if ((_ocr & MMC_HIGH_DESITY_CHECK_MSK) == MMC_HIGH_DESITY_CHECK_BIT)
+ {
+ gSD->flags |= SD_FLAG_HCS_SUPPORT;
+ gMSDC_Handle->mMSDC_type = MMC42_CARD;
+ gSD->mIsBlkAddr = 1;
+ }
+ else
+#endif
+ gMSDC_Handle->mMSDC_type = MMC_CARD;
+
+ gSD->mInactive = KAL_FALSE;
+ gSD->mSDC_ocr = _ocr;
+ gSD->mState = READY_STA;
+
+ return NO_ERROR;
+}
+SDC_CMD_STATUS SD_Cmd11(void)
+{
+ SDC_CMD_STATUS status;
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD11, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ {
+ return status;
+ }
+ //read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+
+}
+kal_int32 SD_SwitchVolt18()
+{
+ kal_uint32 status,t2;
+ status=SD_Cmd11();
+ if (status !=NO_ERROR)
+ return status;
+ /*make sure SDC is not BUSY*/
+ if (MSDC_TIMEOUT_WAIT((!SD_IS_SDC_BUSY())&&MSDC_Check_Card_Present(),MSDC_CMD_TIMEOUT))
+ {
+ MSDC_ERR("[SD][%s %d]wait SDC busy timeout\r\n",__FUNCTION__,__LINE__);
+ return ERR_STATUS;
+ }
+ /*check data[3:0] and cmd is lower by card*/
+ if(MSDC_Reg32(MSDC_PS)&((1<<24)|(0xf<<16)))
+ return CHECK_DATA_CMD_LOW_FAIL;
+ /*pull up disabled in CMD and DAT[3:0]*/
+ MSDC_ConfigPin(MSDC_PIN_PULL_NONE);
+ /*switch signal voltage to 1.8v*/
+ gMSDC_Handle->signal_volt=1800;
+ MSDC_SetSignalPower(1,gMSDC_Handle->signal_volt);
+ /*wait 5ms*/
+ msdc_sleep(2);
+ /*PULL UP enable in CMD and DAT[3:0]*/
+ MSDC_ConfigPin(MSDC_PIN_PULL_UP);
+ msdc_sleep(1);
+ /*start to detect volt change */
+ MSDC_SetBits32(MSDC_CFG,MSDC_CFG_BV18SDT);
+ msdc_sleep(20);
+ t2=drv_get_current_time();
+ do{
+ if(((status=MSDC_Reg32(MSDC_CFG))& MSDC_CFG_BV18SDT)==0);
+ {
+ if (status&MSDC_CFG_BV18PSS)
+ {
+ //pass to switch volt to 1.8v
+ return NO_ERROR;
+ }
+ else
+ {
+ //fail to switch volt to 1.8v
+ MSDC_ERR("[SD][%s %d]1.8v fail ,MSDC_CFG %x\r\n",__FUNCTION__,__LINE__,status);
+ break;
+ }
+ }
+ if (drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+ {
+ //detect volt change timeout
+ MSDC_ERR("[SD][%s %d]detect volt change timeout\r\n",__FUNCTION__,__LINE__);
+ break;
+ }
+ }while(1);
+
+ //come to here ,mean timeout or switch 1.8v fail
+
+ return ERR_STATUS;
+}
+/*************************************************************************
+* FUNCTION
+* SD_Acmd41_SD
+*
+* DESCRIPTION
+* asks all cards in idle state to send their OCR in the response on the CMD line
+* OCR: Operation Condition Register
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* only works for SD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Acmd41_SD(void)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 _ocr = 0, ocr_i = 0, t2;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+
+ if (gSD->mCMD8Resp == SD_CMD8_RESP_NORESP)
+ ocr_i = SDC_OCR_DEFAULT;
+ else if (gSD->mCMD8Resp == SD_CMD8_RESP_VALID) {
+ #if defined(MSDC_CONFIG_SD30_SUPPORT)
+ if (TEMP_SINGLE_LINE == gMSDC_Handle->trySingleLine)
+ ocr_i = (SDC_OCR_DEFAULT | SD_ACMD41_HCS);
+ else
+ ocr_i = (SDC_OCR_DEFAULT | SD_ACMD41_HCS |SD_ACMD41_S18R | SD_ACMD41_XPC);
+
+ #else
+ ocr_i = (SDC_OCR_DEFAULT | SD_ACMD41_HCS);
+ #endif
+ }
+ else if (gSD->mCMD8Resp == SD_CMD8_RESP_INVALID)
+ return ERR_CMD8_INVALID;
+
+#else
+ ocr_i = SDC_OCR_DEFAULT;
+#endif
+ MSDC_CRIT("[SD][%s %d]Host OCR = %x\r\n",__FUNCTION__,__LINE__,ocr_i);
+ retry:
+ gMSDC_Handle->is_init_timeout = KAL_FALSE;
+ t2 = drv_get_current_time();
+
+ do
+ {
+ /*send ACMD41*/
+ status = SD_Cmd55(SDC_RCA_DEFAULT);
+
+ if (status != NO_ERROR)
+ {
+ return status;
+ }
+
+ status=SD_SendCmd(SDC_CMD_ACMD41, ocr_i, MSDC_CMD_TIMEOUT);
+ if (status != NO_ERROR)
+ {
+ return status;
+ }
+
+ /*check response*/
+ _ocr = MSDC_Reg32(SDC_RESP0);
+ MSDC_NOTICE("[SD]ACMD41 resp = %x\r\n", _ocr);
+
+ if ((_ocr & SDC_OCR_DEFAULT) == 0)
+ return ERR_OCR_NOT_SUPPORT;
+
+ if (!gMSDC_Handle->mIsPresent)
+ return ERR_CARD_NOT_PRESENT;
+
+ if (!(_ocr & SDC_OCR_BUSY))
+ {
+ /*if return busy ,we check timeout or not*/
+ if (drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+ {
+ gMSDC_Handle->is_init_timeout = KAL_TRUE;
+ MSDC_ERR("[SD]ACMD41 Polling BUSY timeout!\r\n");
+ break;
+ }
+
+ msdc_sleep(5);
+ }
+ else
+ {
+ /*not busy */
+ MSDC_CRIT("[SD]OCR = %x\r\n", _ocr);
+ break;
+ }
+ }
+ while (1);
+
+ if (gMSDC_Handle->is_init_timeout)
+ return ERR_R3_OCR_BUSY;
+
+ gSD->mInactive = KAL_FALSE;
+ gSD->mSDC_ocr = _ocr;
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ gSD->flags |= SD_FLAG_SD_TYPE_CARD;
+
+ if (_ocr & SD_ACMD41_HCS)
+ {
+ #if defined(MSDC_CONFIG_SD30_SUPPORT)
+ if (_ocr & SD_ACMD41_S18R )
+ {
+ status=SD_SwitchVolt18();
+ if (status != NO_ERROR)
+ {
+ return status; //need delete
+ //fail to switch to 1.8v ,so set signal voltage back to 3.3.v
+ gMSDC_Handle->signal_volt=3300;
+ MSDC_SetSignalPower(1,gMSDC_Handle->signal_volt);
+ power_cycle(1);
+ SD_Reset();
+ SD_Cmd8();
+ ocr_i = (SDC_OCR_DEFAULT | SD_ACMD41_HCS);
+ goto retry;
+ }
+
+ gSD->flags|=SD_FLAG_UHS_SUPPORT;
+ gMSDC_Handle->mMSDC_type=SD30_CARD;
+ MSDC_CRIT("[SD][%s %d]SD3.0 UHS Card\r\n",__FUNCTION__,__LINE__);
+ }
+ else
+ #endif
+ {
+ gSD->flags |= SD_FLAG_HCS_SUPPORT;
+ gMSDC_Handle->mMSDC_type = SD20_HCS_CARD;
+ MSDC_CRIT("[SD][%s %d]SD2.0 High Capacity Card\r\n",__FUNCTION__,__LINE__);
+
+ }
+
+
+ }
+ else if (gSD->mCMD8Resp == SD_CMD8_RESP_VALID)
+ gMSDC_Handle->mMSDC_type = SD20_LCS_CARD;
+ else
+#endif
+ gMSDC_Handle->mMSDC_type = SD_CARD;
+
+ gSD->mState = READY_STA;
+
+ return NO_ERROR;
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_GetCID
+*
+* DESCRIPTION
+* Read Card Identification.
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+*
+*
+*************************************************************************/
+
+// Get CID(CMD2)
+SDC_CMD_STATUS SD_GetCID(kal_uint32 *Cid)
+{
+ int i;
+ SDC_CMD_STATUS status;
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD2, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ {
+ return status;
+ }
+
+ //read R2
+ for (i = 0; i < 4; i++)
+ {
+ Cid[i]=MSDC_Reg32((SDC_RESP0 + i * sizeof(kal_uint32)));
+ }
+
+ SD_AnalysisCID(Cid);
+ gSD->mState = IDENT_STA;
+
+ return NO_ERROR;
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_ValidateRCA
+*
+* DESCRIPTION
+* assing or read RCA
+*
+* PARAMETERS
+* pRca: used for input or output RCA
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* RCA is assinged to MMC card fixed to SDC_RCA_MMC(1)
+*
+*************************************************************************/
+
+// assign or read RCA
+SDC_CMD_STATUS SD_ValidateRCA(kal_uint16* pRca)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 resp;
+ kal_uint8 state;
+ kal_uint32 retry;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+
+ if (gSD->flags & SD_FLAG_SD_TYPE_CARD )
+#else
+ if (gMSDC_Handle->mMSDC_type == SD_CARD)
+#endif
+ {
+ //read RCA form card
+ retry=10;
+ /*if card return RCA=0 we will retry,*/
+ while(retry--)
+ {
+ MSDC_DEBUG("[SD][%s %d]send cmd3\r\n",__FUNCTION__,__LINE__);
+ if ((status = SD_SendCmd(SDC_CMD_CMD3, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ //read R6
+ resp=MSDC_Reg32(SDC_RESP0);
+ MSDC_DEBUG("[SD][%s %d]cmd3 reps=%x\r\n",__FUNCTION__,__LINE__,resp);
+#ifdef MSDC_TRACE_LEVEL1
+ MD_TRC_MSDC_INFORM_R0(resp, __LINE__);
+#endif
+ if ((resp>>16)!=0)
+ {
+ *pRca = resp >> 16;
+ gSD->mRCA = *pRca;
+ break;
+ }
+ MSDC_DEBUG("[SD][%s %d]gSD->mRCA=%x\r\n",__FUNCTION__,__LINE__,gSD->mRCA);
+ }
+ if (retry==0)
+ {
+ /*always return RCA=0*/
+ return ERR_RCA_FAIL;
+ }
+
+ }
+ else
+ {
+ //assign RCA to card
+ if ((status = SD_SendCmd(SDC_CMD_CMD3_MMC, ((kal_uint32)SDC_RCA_MMC << 16),MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ //read R1
+ resp=MSDC_Reg32(SDC_RESP0);
+#ifdef MSDC_TRACE_LEVEL1
+ MD_TRC_MSDC_INFORM_R0(resp, __LINE__);
+#endif
+ SD_GetStatus(SDC_RCA_MMC, &resp);
+ state = 0;
+ GetBitFieldN((kal_uint8*)&state, (kal_uint8*)&resp, 9, 4);
+
+ if (STBY_STA != state)
+ return ERR_RCA_FAIL;
+
+ *pRca = gSD->mRCA = SDC_RCA_MMC;
+ }
+
+ gSD->mState = STBY_STA;
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SetDSR
+*
+* DESCRIPTION
+* set default value to the DSR
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* SDC_DSR_DEFAULT(0x404)
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetDSR(void)
+{
+ return SD_SendCmd(SDC_CMD_CMD4, (kal_uint32)SDC_DSR_DEFAULT << 16,MSDC_CMD_TIMEOUT);
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SelectCard
+*
+* DESCRIPTION
+* select/deselect card
+*
+* PARAMETERS
+* rca: relative card address
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SelectCard(kal_uint16 rca)
+{
+ SDC_CMD_STATUS status;
+ MSDC_DEBUG("[SD][%s %d]send cmd7\r\n",__FUNCTION__,__LINE__);
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD7, ((kal_uint32)rca << 16),MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ {
+ return status;
+ }
+
+ //read R1b
+ if ((status = SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_GetCSD
+*
+* DESCRIPTION
+* Get CSD from addressed card
+*
+* PARAMETERS
+* rca: relative card address
+* Csd: used for containing read CSD
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_GetCSD(kal_uint16 rca, kal_uint32 Csd[4])
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 i;
+ MSDC_DEBUG("[SD][%s %d]send cmd9\r\n",__FUNCTION__,__LINE__);
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD9, ((kal_uint32)rca << 16),MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ {
+ return status;
+ }
+
+
+ // read R2
+ for (i = 0; i < 4; i++)
+ {
+ Csd[i]=MSDC_Reg32((volatile kal_uint32 *)(SDC_RESP0 + i * 4));
+ #ifdef MSDC_DEBUG_PRINT
+ MSDC_DEBUG("%x ",Csd[i]);
+ #endif
+ }
+ #ifdef MSDC_DEBUG_PRINT
+ MSDC_DEBUG("\r\n ");
+ #endif
+ // analysis CSD...
+ SD_AnalysisCSD(Csd);
+
+ return NO_ERROR;
+}
+
+// addressed send CID
+SDC_CMD_STATUS SD_GetAddressedCID(kal_uint16 rca, kal_uint32 Cid[4])
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 i;
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD10, (kal_uint32)rca << 16,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ // read R2
+ for (i = 0; i < 4; i++)
+ {
+#ifndef DRV_LSD
+ Cid[i]=MSDC_Reg32((volatile kal_uint32 *)(SDC_RESP0 + i * 4));
+#else
+ Cid[i]=MSDC_Reg32(SDC_RESP0 + i);
+#endif
+ }
+
+ return NO_ERROR;
+}
+
+
+/*************************************************************************
+* FUNCTION
+* SD_StopTrans
+*
+* DESCRIPTION
+* Stop Muli-Block operation
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* definition of SD_STOP_SLOW is used for some erroneous card
+*************************************************************************/
+SDC_CMD_STATUS SD_StopTrans(void)
+{
+ SDC_CMD_STATUS status;
+ #define CMD12_TIMEOUT_MS 1000
+ status = SD_SendCmd(SDC_CMD_CMD12,SDC_NO_ARG,MSDC_CMD_TIMEOUT);
+ MSDC_CLR_FIFO();
+ return status;
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_GetStatus
+*
+* DESCRIPTION
+* addressed send status
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_GetStatus(kal_uint16 rca, kal_uint32* resp)
+{
+ SDC_CMD_STATUS status;
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD13, ((kal_uint32)rca << 16),MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ *resp=MSDC_Reg32(SDC_RESP0);
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SetBlength
+*
+* DESCRIPTION
+* set block length
+*
+* PARAMETERS
+* BKLength: block length u want to set
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD->mBKLength
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetBlength(kal_uint32 BKLength)
+{
+ SDC_CMD_STATUS status;
+
+ // maximal value of block length is 2048
+ if (BKLength > SDC_MAX_BKLENGTH)
+ return ERR_INVALID_BKLENGTH;
+
+ if (!gSD->mCSD.r_blk_part && BKLength < gSD->mCSD.max_r_blk_len )
+ return ERR_INVALID_BKLENGTH;
+ if ((status = SD_SendCmd(SDC_CMD_CMD16, BKLength,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ //read R1
+ status = SD_CheckStatus();
+ // 2. configure the controller
+ gSD->mBKLength = BKLength;
+ // BitFieldWrite32((kal_uint32*)SDC_CMD, BKLength, SDC_CMD_BLKLEN);
+ return status;
+}
+
+
+/*************************************************************************
+* FUNCTION
+* SD_ReadSingleBlock
+*
+* DESCRIPTION
+* 1. read a single block form data_adrs of card to the rxbuffer
+* 2. the block length is set by set block length
+*
+* PARAMETERS
+* data_adrs: starting address to read
+* rxbuffer: as name
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* the size of rxbuffer should be 4*n (n : integer)
+*
+*************************************************************************/
+#ifdef DRV_MSDC_SLIM
+SDC_CMD_STATUS SD_ReadSingleBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer) // slim
+{
+ return SD_ReadMultiBlock(data_adrs, rxbuffer, 1); // slim
+}
+#else
+SDC_CMD_STATUS SD_ReadSingleBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+ return SD_ReadMultiBlock(data_adrs, rxbuffer, 1);
+}
+#endif
+/*************************************************************************
+* FUNCTION
+* SD_ReadMultiBlock
+*
+* DESCRIPTION
+* read num of blocks into rxbuffer
+*
+* PARAMETERS
+* data_adrs: starting address to read
+* rxbuffer: as name
+* num: number of blocks to read
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+#ifdef DRV_MSDC_SLIM
+SDC_CMD_STATUS
+SD_ReadMultiBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer, kal_uint32 num_blk) // slim
+{
+
+
+}
+#else
+SDC_CMD_STATUS SD_ReadMultiBlock(kal_uint32 data_adrs, kal_uint32* rxbuffer, kal_uint32 num_blk)
+{
+ kal_uint32 status;
+
+ status = SD_ReqHandleData(data_adrs, rxbuffer,num_blk, KAL_FALSE,KAL_FALSE);
+ if (status==ERR_DAT_CRCERR)
+ {
+ status=SD_TuneRead(data_adrs,rxbuffer,num_blk,KAL_FALSE);
+ }
+ return status;
+}
+#endif
+
+
+
+/*************************************************************************
+* FUNCTION
+* SD_WriteSingleBlock
+*
+* DESCRIPTION
+* write a single block
+*
+* PARAMETERS
+* address: starting address to write
+* txbuffer: as name
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* block length is set by Set_Block_Length
+*
+*************************************************************************/
+#ifdef DRV_MSDC_SLIM
+//__attribute__ ((section ("EXT_BOOTLOADER_CODE"))) SDC_CMD_STATUS SD_WriteSingleBlock(kal_uint32 address, kal_uint32* txbuffer) // slim
+SDC_CMD_STATUS SD_WriteSingleBlock(kal_uint32 address, kal_uint32* txbuffer)
+{
+ return SD_WriteMultiBlock(address, txbuffer, 1); // slim
+}
+#else
+//__attribute__ ((section ("EXT_BOOTLOADER_CODE"))) SDC_CMD_STATUS SD_WriteSingleBlock(kal_uint32 address, kal_uint32* txbuffer)
+SDC_CMD_STATUS SD_WriteSingleBlock(kal_uint32 address, kal_uint32* txbuffer)
+{
+ return SD_WriteMultiBlock(address, txbuffer, 1);
+}
+#endif
+
+void SD_Sleep4Wait(kal_int32 sleep_tick)
+{
+
+}
+/*************************************************************************
+* FUNCTION
+* SD_WriteMultiBlock
+*
+* DESCRIPTION
+* write num blocks starting at address
+*
+* PARAMETERS
+* address: starting address to write
+* txbuffer: as name
+* num: number of blocks to write
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* block length is set by Set_Block_Length
+*
+*************************************************************************/
+//#ifndef DRV_MSDC_SLIM
+//__attribute__ ((section ("EXT_BOOTLOADER_CODE"))) SDC_CMD_STATUS SD_WriteMultiBlock(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num)
+SDC_CMD_STATUS SD_WriteMultiBlock(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num_blk)
+{
+ SDC_CMD_STATUS status;
+
+ if (gSD->mWPEnabled)
+ return ERR_WRITE_PROTECT;
+ if ((status=SD_ReqHandleData(address, txbuffer, num_blk, KAL_TRUE,KAL_FALSE))!=NO_ERROR)
+ {
+ if (status ==ERR_DAT_CRCERR)
+ {
+ status=SD_TuneWrite(address,txbuffer,num_blk,KAL_FALSE);
+ }
+ else if (status == ERR_DAT_TIMEOUT)
+ {
+ status=SD_HandleWriteTMO(address,txbuffer,num_blk,KAL_FALSE);
+ }
+ }
+
+ return status;
+}
+
+SDC_CMD_STATUS SD_GpdWriteMultiBlock(kal_uint32 address ,kal_uint32 num_blk,void *gpd_data)
+{
+ SDC_CMD_STATUS status;
+
+ gMSDC_Handle->f_tuning = 0;
+
+ if (gSD->mWPEnabled)
+ return ERR_WRITE_PROTECT;
+ if ((status=SD_ReqHandleData(address, gpd_data, num_blk, KAL_TRUE,KAL_TRUE))!=NO_ERROR)
+ {
+ gMSDC_Handle->f_tuning = 1;
+
+ if (status ==ERR_DAT_CRCERR)
+ {
+ status=SD_TuneWrite(address,gpd_data,num_blk,KAL_TRUE);
+ }
+ else if (status == ERR_DAT_TIMEOUT)
+ {
+ status=SD_HandleWriteTMO(address,gpd_data,num_blk,KAL_TRUE);
+ }
+ }
+ return status;
+}
+
+SDC_CMD_STATUS SD_GpdReadMultiBlock(kal_uint32 address ,kal_uint32 num_blk,void *gpd_data )
+{
+ kal_uint32 status;
+
+ gMSDC_Handle->f_tuning = 0;
+ status = SD_ReqHandleData(address, gpd_data,num_blk, KAL_FALSE,KAL_TRUE);
+
+ if (status==ERR_DAT_CRCERR)
+ {
+ gMSDC_Handle->f_tuning = 1;
+ status=SD_TuneRead(address,gpd_data,num_blk,KAL_TRUE);
+ }
+ return status;
+}
+
+
+//#else
+//__attribute__ ((section ("EXT_BOOTLOADER_CODE"))) SDC_CMD_STATUS SD_WriteMultiBlock(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num) // slim
+//SDC_CMD_STATUS SD_WriteMultiBlock(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num) // slim
+//{
+
+
+//}
+//#endif
+
+
+/*************************************************************************
+* FUNCTION
+* SD_SetBusWidth
+*
+* DESCRIPTION
+* ACMD6: set the data width 00 for 1 bit, 10 for 4 bits
+*
+* PARAMETERS
+* width: indicate the bus width
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Not every card support 4-bits bus
+* only for SD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetBusWidth(SD_BITWIDTH width)
+{
+ SDC_CMD_STATUS status;
+ MSDC_DEBUG("[SD][%s %d]send ACMD6 ,change bus width to %d\r\n",__FUNCTION__,__LINE__,width);
+
+ // check if card support 4 bits bus
+ if ((width == BIT_4W) && !(gSD->mSCR.bus_width & 0x04))
+ return ERR_NOT_SUPPORT_4BITS;
+
+ // send APP_CMD
+ if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+ return status;
+
+ // send cmd6
+ if ((status = SD_SendCmd(SDC_CMD_ACMD6, width,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ //read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+
+ // set the controler bus width
+ MSDC_SetBusWidth(width);
+ gSD->bus_width = width;
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_ReadSCR
+*
+* DESCRIPTION
+* ACMD51: read the SD Configuration Register(8bytes block read)
+*
+* PARAMETERS
+* scr: used for store SCR
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Make sure the size of SCR is 8 bytes
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadSCR(kal_uint32* scr)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 blklen;
+
+ ASSERT((kal_uint32)scr % 4 == 0);
+
+ MSDC_DEBUG("[SD][%s %d]send cmd55\r\n",__FUNCTION__,__LINE__);
+
+ // send APP_CMD
+ if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+ return status;
+
+ // set block number
+ blklen=gSD->mBKLength;
+ gSD->mBKLength = 8;
+ MSDC_WriteReg32(SDC_BLK_NUM,1);
+ MSDC_DEBUG("[SD][%s %d]send acmd51\r\n",__FUNCTION__,__LINE__);
+
+ // set to pio mode and clear fifo
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=0;
+ MSDC_CLR_FIFO();
+
+ // send command
+ if ((status = SD_SendCmd(SDC_CMD_ACMD51, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ // read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ // read data(8bytes)
+ status=SD_WaitDatRdyOrTo(scr,8,KAL_FALSE);
+ if (status !=NO_ERROR)
+ return status;
+ MSDC_DEBUG("[SD][%s %d]scr=%x %x\r\n",__FUNCTION__,__LINE__,*scr,*(scr+1));
+
+ SD_AnalysisSCR(scr);
+ MSDC_CLR_FIFO();
+
+ gSD->mBKLength = blklen;
+
+ return NO_ERROR;
+
+}
+
+static kal_uint32 unstuff_sd_status(kal_uint32 *raw_sd_status, kal_uint32 start, kal_uint32 size)
+{
+ kal_uint32 __mask = (1 << (size)) - 1;
+ int __off = 63 - ((start) / 8);
+ int __shft;
+ kal_uint8 *raw = (kal_uint8 *)raw_sd_status;
+ kal_uint32 __res = 0;
+
+ if ((start & 7) + 1 >= size)
+ {
+ __shft = ((start & 7) + 1) - size;
+ __res = raw[__off] >> __shft;
+ }
+ else if (size <= 32)
+ {
+ size -= ((start & 7) + 1);
+ __shft = size;
+ __res = raw[__off] << __shft;
+ while (size)
+ {
+ __off++;
+ if (size >= 8)
+ {
+ size -= 8;
+ __res |= raw[__off] << size;
+ }
+ else
+ {
+ __mask = (1 << (size)) - 1;
+ __res |= (raw[__off] >> (8 - size)) & __mask;
+ size = 0;
+ }
+ }
+ }
+ return __res & __mask;
+}
+#define UNSTUFF_SD_STATUS(r,s,sz) unstuff_sd_status(r,s,sz)
+
+/*************************************************************************
+* FUNCTION
+* SD_ReadSDStatus
+*
+* DESCRIPTION
+* ACMD13: read the SD Status Register(64bytes block read)
+*
+* PARAMETERS
+* sd_status: used for store SD Status
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Make sure the size of SD Status is 64 bytes
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadSDStatus(kal_uint32* sd_status)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 blklen;
+
+ ASSERT((kal_uint32)sd_status % 4 == 0);
+
+ MSDC_DEBUG("[SD][%s %d]send cmd55\r\n",__FUNCTION__,__LINE__);
+
+ // send APP_CMD
+ if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+ return status;
+
+ // set block number
+ blklen=gSD->mBKLength;
+ gSD->mBKLength = 64;
+ MSDC_WriteReg32(SDC_BLK_NUM,1);
+ MSDC_DEBUG("[SD][%s %d]send acmd13\r\n",__FUNCTION__,__LINE__);
+
+ // set to pio mode and clear fifo
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=0;
+
+ // send command
+ if ((status = SD_SendCmd(SDC_CMD_ACMD13, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ // read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ // read data(8bytes)
+ status=SD_WaitDatRdyOrTo(sd_status,64,KAL_FALSE);
+ gSD->mBKLength = blklen;
+
+ if (status !=NO_ERROR)
+ return status;
+ MSDC_DEBUG("[SD][%s %d]sd_status=%x %x\r\n",__FUNCTION__,__LINE__,*sd_status,*(sd_status+1));
+
+ gSD->mSDSts.dat_bus_width = UNSTUFF_SD_STATUS(sd_status, 511, 2);
+ gSD->mSDSts.secured_mode = UNSTUFF_SD_STATUS(sd_status, 509, 1);
+ gSD->mSDSts.sd_card_type = UNSTUFF_SD_STATUS(sd_status, 495, 16);
+ gSD->mSDSts.size_of_prot_area = UNSTUFF_SD_STATUS(sd_status, 479, 32);
+ gSD->mSDSts.speed_class = UNSTUFF_SD_STATUS(sd_status, 447, 8);
+ gSD->mSDSts.perf_move = UNSTUFF_SD_STATUS(sd_status, 439, 8);
+ gSD->mSDSts.au_size = UNSTUFF_SD_STATUS(sd_status, 431, 4);
+ gSD->mSDSts.erase_size = UNSTUFF_SD_STATUS(sd_status, 423, 16);
+ gSD->mSDSts.erase_timeout = UNSTUFF_SD_STATUS(sd_status, 407, 6);
+ gSD->mSDSts.erase_offset = UNSTUFF_SD_STATUS(sd_status, 401, 2);
+ gSD->mSDSts.uhs_speed_grade = UNSTUFF_SD_STATUS(sd_status, 399, 4);
+ gSD->mSDSts.uhs_au_size = UNSTUFF_SD_STATUS(sd_status, 395, 4);
+
+ /* If it is a SD ROM Card, set the WP flag */
+ if (gSD->mSDSts.sd_card_type == 0x0001) {
+ gSD->mWPEnabled = KAL_TRUE;
+ MSDC_CRIT("[SD]It is a ROM Card!\r\n");
+ }
+
+ return NO_ERROR;
+
+}
+
+
+/*************************************************************************
+* FUNCTION
+* SD_SetPreEraseBlk
+*
+* DESCRIPTION
+* ACMD23: set the number of write blocksto be pre-erased before writing
+* used for faster multiple Block Write
+*
+* PARAMETERS
+* num: used for storing number of blocks during multi-block operation
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetPreEraseBlk(kal_uint32 num)
+{
+ SDC_CMD_STATUS status;
+
+ //[22:0] number of blocks
+ num &= 0x003FFF;
+
+ // send APP_CMD
+ if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+ return status;
+
+ // send CMD23
+ if ((status = SD_SendCmd(SDC_CMD_ACMD23, num,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ //read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_EraseCmdClass
+*
+* DESCRIPTION
+* groups of erase commands including CMD32 ~CMD38
+*
+* PARAMETERS
+* cmd: indicate which command to execute
+* address: starting address wiht write protection
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* CMD34~CMD37 are only for MMC
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_EraseCmdClass(kal_uint32 cmd , kal_uint32 address)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 sdcard_status;
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
+
+ if (cmd != SDC_CMD_CMD38)
+ {
+ if ((status = SD_SendCmd(cmd, address,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+ }
+ else if ((status = SD_SendCmd(cmd, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ //read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+
+ if (cmd == SDC_CMD_CMD38)
+ {
+
+ if ((status = SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ do
+ {
+ if ((status = SD_GetStatus(gSD->mRCA, (kal_uint32*)&sdcard_status)) != NO_ERROR)
+ return status;
+
+ if (gMSDC_Handle->mIsPresent == KAL_FALSE)
+ return ERR_INVALID_CARD;
+ }
+ while (R1_CURRENT_STATE(sdcard_status) != TRAN_STA);
+ }
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_Switch_MMC40
+*
+* DESCRIPTION
+* CMD6: set the command set or write to the EXT_CSD (for MMC4.0)
+*
+* PARAMETERS
+* access: access mode
+* index: index to EXT_CSD
+* value: value to write to EXT_CSD
+* set: selected command set
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Switch_MMC40(kal_uint8 access, kal_uint8 index, kal_uint8 value, kal_uint8 set)
+{
+ SDC_CMD_STATUS status = NO_ERROR;
+ kal_uint32 arg = 0;
+ kal_uint32 resp = 0;
+ kal_bool retry = KAL_FALSE;
+// kal_uint8 *pData = NULL;
+
+switch_start:
+
+ arg = (access << 24) | (index << 16) | (value << 8) | set;
+
+ // send command
+ if ((status = SD_SendCmd(SDC_CMD_CMD6_MMC, arg,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ {
+ goto ERR_Exit;
+ }
+
+#ifndef DRV_LSD
+
+ //read R1b
+ if ((status = SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT)) != NO_ERROR)
+ goto ERR_Exit;
+
+#endif
+
+ SD_GetStatus(gSD->mRCA, (kal_uint32*)&status);
+
+ //read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ goto ERR_Exit;
+
+ resp=MSDC_Reg32(SDC_RESP0);
+
+ if ((resp & MMC_SWITCH_ERROR) != 0)
+ {
+ if (retry == KAL_FALSE)
+ {
+#ifdef MSDC_TRACE_LEVEL2
+ MD_TRC_MSDC_INFORM_R0(resp, __LINE__);
+#endif
+ retry = KAL_TRUE;
+ goto switch_start;
+ }
+ else
+ return ERR_MMC_SWITCH_ERROR;
+ }
+
+ return NO_ERROR;
+
+ERR_Exit:
+ return status;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SendEXTCSD_MMC40
+*
+* DESCRIPTION
+* CMD8: read the content of EXT_CSD register
+*
+* PARAMETERS
+* kal: access mode
+* index: index to EXT_CSD
+* value: value to write to EXT_CSD
+* set: selected command set
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#ifdef DRV_LSD
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+SDC_CMD_STATUS SD_SendEXTCSD_MMC40(kal_uint32* rxbuffer)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 blklen;
+ // SDC_CMD_STATUS status1;
+ // kal_bool retry = KAL_FALSE;
+ //kal_uint32 idx = 0;
+
+ //start:
+ blklen=gSD->mBKLength;
+ gSD->mBKLength = 512;
+ MSDC_WriteReg32(SDC_BLK_NUM,1);
+ //set to pio mode and clear fifo
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=0;
+ MSDC_CLR_FIFO();
+
+ // read the block of 512 bytes (make sure the rxbuffer is 4 byte aligned)
+ if ((status = SD_SendCmd(SDC_CMD_CMD8_MMC40, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ goto ERR_Exit;
+
+ //read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ goto ERR_Exit;
+
+ //idx = 0;
+ /*move data from FIFO to buffer*/
+ if ((status = SD_WaitDatRdyOrTo(rxbuffer,512,KAL_FALSE))!=NO_ERROR)
+ {
+ goto ERR_Exit;
+ }
+
+ kal_mem_cpy(MSDC_eCSD, rxbuffer, 512);
+ gSD->mCSD.ext_csd = (T_EXT_CSD_MMC40 *)MSDC_eCSD;//rxbuffer;
+ gSD->mBKLength=blklen;
+ return NO_ERROR;
+
+ERR_Exit:
+
+ MSDC_FatalErrorHandle();
+ return status;
+}
+#endif
+/*************************************************************************
+* FUNCTION
+* SD_CheckTimeoutWithSleep
+*
+* DESCRIPTION
+* check timeout or not and sleep 1 tick if has been waited more than 10 ms
+*
+* PARAMETERS
+* start_time: the time start to wait, get with drv_get_current_time
+* duration_ms: the timeout limitation
+*
+* RETURNS
+* kal_bool, timeout:KAL_TRUE; not timeout:KAL_FALSE;
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle->is_timeout
+*
+* NOTE:
+* This function should be called in the wait loop to prevent block other tasks.
+*
+*************************************************************************/
+kal_bool SD_CheckTimeoutWithSleep(kal_int32 start_time,
+ kal_int32 duration_ms)
+{
+ kal_int32 elapsed_time = drv_get_duration_ms(start_time);
+ //check timeout or not
+ if(elapsed_time > duration_ms)
+ {
+ gMSDC_Handle->is_timeout = KAL_TRUE;
+ return KAL_TRUE;
+ }
+ gMSDC_Handle->is_timeout = KAL_FALSE;
+
+ if(elapsed_time < 10)
+ {
+ return KAL_FALSE;
+ }
+ else if ((KAL_FALSE == kal_query_systemInit())
+#ifdef __TST_WRITE_TO_FILE__/*error recording: considering error recording additionally*/
+ && (KAL_FALSE == INT_QueryExceptionStatus())
+#endif
+ && (KAL_FALSE == kal_if_hisr())
+ && (KAL_FALSE == kal_if_lisr()))
+ {
+ kal_sleep_task(1);
+ }
+ return KAL_FALSE;
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Switch_SD11
+*
+* DESCRIPTION
+* CMD6: switch command to query and select the specific functions. (SD1.1 or later)
+* PARAMETERS
+* arg: argument
+* resp: buffer to contain the ther 64 bytes status information
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Switch_SD11(kal_uint32 arg, T_SWITCH_STATUS* info)
+{
+ SDC_CMD_STATUS status = NO_ERROR;
+ kal_uint32 blklen;
+ gSD->mBKNum=1;
+ blklen=gSD->mBKLength;
+ gSD->mBKLength = SD_CMD6_RESP_LEN;
+ MSDC_WriteReg32(SDC_BLK_NUM,1);
+ //set to pio mode and clear fifo
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=0;
+ MSDC_CLR_FIFO();
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD6_SD11, arg,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ status=SD_WaitDatRdyOrTo((kal_uint32 *)info,SD_CMD6_RESP_LEN,KAL_FALSE);
+ gSD->mBKLength=blklen;
+ return status;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Switch_SD11
+*
+* DESCRIPTION
+* Enable the high speed interface to support up to 50M Hz clock
+*
+* PARAMETERS
+* arg: argument
+* resp: buffer to contain the ther 64 bytes status information
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+
+#ifndef DRV_MSDC_CORRECT_CMD6
+SDC_CMD_STATUS SD_SelectHighSpeed_SD11(void)
+{
+ SDC_CMD_STATUS status;
+ T_SWITCH_STATUS *p = (T_SWITCH_STATUS*)MSDC_Sector;
+ MSDC_DEBUG("[SD][%s %d]send cmd6 \r\n",__FUNCTION__,__LINE__);
+
+ if ((status = SD_Switch_SD11(SD_CMD6_QUERY_HIGH_SPEED, p)) != NO_ERROR)
+ return status;
+
+ if (p->max_current == 0)
+ return ERR_SD_HS_FAIL;
+
+ if ((p->group1_info & (1 << SD_FUNC_HIGH_SPEED)) &&
+ (p->group1_result == SD_FUNC_HIGH_SPEED))
+ {
+ if ((status = SD_Switch_SD11(SD_CMD6_SELECT_HIGH_SPEED, p)) != NO_ERROR)
+ return status;
+
+ if (p->max_current == 0)
+ return ERR_SD_HS_FAIL;
+
+ if (p->group1_result == SD_FUNC_HIGH_SPEED)
+ gSD->flags |= SD_FLAG_HS_SUPPORT;
+ }
+ else
+ return ERR_SD_HS_FAIL;
+
+
+ return NO_ERROR;
+}
+#else
+typedef struct
+{
+ kal_uint16 max_current;
+ kal_uint16 group1_info;
+ kal_uint16 group1_status;
+ kal_uint8 group1_result;
+ kal_uint8 structure_version;
+}T_Group1SwitchStatus;
+/*************************************************************************
+* FUNCTION
+* SD_ParseGroup1FunctionStatus
+*
+* DESCRIPTION
+* Parse the Group1 functons' information form the data returned by CMD6
+*
+* PARAMETERS
+* arg:
+* T_Group1SwitchStatus* sf_status : information of group1 function
+* kal_uint8* crude_info : crude data returned by CMD6
+* resp:
+*
+* RETURNS
+* void
+*
+* GLOBALS AFFECTED
+* None
+* NOTE
+*
+*************************************************************************/
+void SD_ParseGroup1FunctionStatus(T_Group1SwitchStatus* sf_status, kal_uint8* crude_info)
+{
+ sf_status->max_current = (((*(kal_uint8 *)crude_info) << 8)
+ | (*(kal_uint8 *)(crude_info + 1)));
+ sf_status->group1_info = (((*(kal_uint8 *)(crude_info + 12)) << 8)
+ | (*(kal_uint8 *)(crude_info + 13)));
+ sf_status->group1_result = ((*(kal_uint8 *)(crude_info + 16)) & 0xf);
+ sf_status->structure_version = (*(kal_uint8 *)(crude_info + 17));
+ sf_status->group1_status = (((*(kal_uint8 *)(crude_info + 28)) << 8)
+ | (*(kal_uint8 *)(crude_info + 29)));
+}
+/*************************************************************************
+* FUNCTION
+* SD_QuerySwithHighSpeed
+*
+* DESCRIPTION
+* Send CMD6 with query or swith and check the response data.
+*
+* PARAMETERS
+* arg: kal_uint32 arg
+* resp:
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* MSDC_Sector
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_QuerySwithHighSpeed(kal_uint32 arg)
+{
+ T_Group1SwitchStatus sf_status;
+ SDC_CMD_STATUS cmd_status;
+ if ((cmd_status = SD_Switch_SD11(arg, (T_SWITCH_STATUS*)MSDC_Sector)) != NO_ERROR)
+ return cmd_status;
+ SD_ParseGroup1FunctionStatus(&sf_status,(kal_uint8*)MSDC_Sector);
+ if (0 == sf_status.max_current)
+ return ERR_HIGH_SPEED_CONSUMPTION;
+ if ((SD_FUNC_HIGH_SPEED == sf_status.group1_result)\
+ && (0==(sf_status.group1_status & (1 << SD_FUNC_HIGH_SPEED))))
+ return NO_ERROR;//the high speed function can be switched
+ if ((0xF == sf_status.group1_result) || (!(sf_status.group1_info & (1 << SD_FUNC_HIGH_SPEED))))
+ return ERR_HIGH_SPEED_NOT_SUPPORT;//not support
+ if (sf_status.group1_status & (1 << SD_FUNC_HIGH_SPEED))//busy
+ return ERR_HIGH_SPEED_BUSY;
+ return ERR_HIGH_SPEED_COMMON_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_SelectHighSpeed_SD11
+*
+* DESCRIPTION
+* Select high speed mode for the SD card that supports CMD6
+*
+* PARAMETERS
+* arg: void
+* resp:
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD->flags
+* NOTE
+*
+*************************************************************************/
+
+SDC_CMD_STATUS SD_SelectHighSpeed_SD11(void)
+{
+ SDC_CMD_STATUS high_speed_status;
+ kal_int32 t1;
+ t1 = drv_get_current_time();
+ do
+ {
+ high_speed_status = SD_QuerySwithHighSpeed(SD_CMD6_QUERY_HIGH_SPEED);//query
+ dbg_print("query high_speed_status: %x\r\n",high_speed_status);
+ if (NO_ERROR == high_speed_status)
+ {
+ high_speed_status = SD_QuerySwithHighSpeed(SD_CMD6_SELECT_HIGH_SPEED);//switch
+ dbg_print("switch high_speed_status: %x\r\n",high_speed_status);
+ if (NO_ERROR == high_speed_status)
+ {
+ gSD->flags |= SD_FLAG_HS_SUPPORT;
+ return NO_ERROR;
+ }
+ if (ERR_HIGH_SPEED_BUSY != high_speed_status)
+ break;
+ }
+ if (ERR_HIGH_SPEED_BUSY != high_speed_status)
+ break;
+ if (drv_get_duration_ms(t1)>500)
+ return ERR_HIGH_SPEED_TIMEOUT;
+ //if(SD_CheckTimeoutWithSleep(t1,500))
+ // return ERR_HIGH_SPEED_TIMEOUT;//timeout
+ }while(1);
+ return high_speed_status;
+}
+
+#endif
+
+void parse_Cmd6FunctionStatus(T_SWITCH_STATUS *new_status,kal_uint8 * cur_Status)
+{
+ new_status->max_current=((*(kal_uint8*)cur_Status)<<8)\
+ | (*(kal_uint8 *)(cur_Status+1));
+ new_status->ver=(*(kal_uint8 *)(cur_Status+17));
+ new_status->group1_info=((*(kal_uint8 *)(cur_Status+12))<<8)\
+ | (*(kal_uint8 *)(cur_Status+13));
+ new_status->group1_result=(*(kal_uint8*)(cur_Status+16))&0xf;
+ new_status->group1_busy=((*(kal_uint8*)(cur_Status+28))<<8)\
+ | (*(kal_uint8 *)(cur_Status+29));
+
+ new_status->group2_info=((*(kal_uint8 *)(cur_Status+10))<<8)\
+ | (*(kal_uint8 *)(cur_Status+11));
+ new_status->group2_result=((*(kal_uint8*)(cur_Status+16))>>4)&0xf;
+ new_status->group2_busy=((*(kal_uint8*)(cur_Status+26))<<8)\
+ | (*(kal_uint8 *)(cur_Status+27));
+
+ new_status->group3_info=((*(kal_uint8 *)(cur_Status+8))<<8)\
+ | (*(kal_uint8 *)(cur_Status+9));
+ new_status->group3_result=(*(kal_uint8*)(cur_Status+15))&0xf;
+ new_status->group3_busy=((*(kal_uint8*)(cur_Status+24))<<8)\
+ | (*(kal_uint8 *)(cur_Status+25));
+
+ new_status->group4_info=((*(kal_uint8 *)(cur_Status+6))<<8)\
+ | (*(kal_uint8 *)(cur_Status+7));
+ new_status->group4_result=((*(kal_uint8*)(cur_Status+15))>>4)&0xf;
+ new_status->group4_busy=((*(kal_uint8*)(cur_Status+22))<<8)\
+ | (*(kal_uint8 *)(cur_Status+23));
+
+ new_status->group5_info=((*(kal_uint8 *)(cur_Status+4))<<8)\
+ | (*(kal_uint8 *)(cur_Status+5));
+ new_status->group5_result=(*(kal_uint8*)(cur_Status+14))&0xf;
+ new_status->group5_busy=((*(kal_uint8*)(cur_Status+20))<<8)\
+ | (*(kal_uint8 *)(cur_Status+21));
+
+ new_status->group6_info=((*(kal_uint8 *)(cur_Status+2))<<8)\
+ | (*(kal_uint8 *)(cur_Status+3));
+ new_status->group6_result=((*(kal_uint8*)(cur_Status+14))>>4)&0xf;
+ new_status->group6_busy=((*(kal_uint8*)(cur_Status+18))<<8)\
+ | (*(kal_uint8 *)(cur_Status+19));
+ /*
+ dbg_print("new_status->group1_info :%x\r\n",new_status->group1_info);
+ dbg_print("new_status->group1_result:%x\r\n",new_status->group1_result);
+ dbg_print("new_status->group1_busy:%x\r\n",new_status->group1_busy);
+
+ dbg_print("new_status->group2_info :%x\r\n",new_status->group2_info);
+ dbg_print("new_status->group2_result:%x\r\n",new_status->group2_result);
+ dbg_print("new_status->group2_busy:%x\r\n",new_status->group2_busy);
+
+ dbg_print("new_status->group3_info :%x\r\n",new_status->group3_info);
+ dbg_print("new_status->group3_result:%x\r\n",new_status->group3_result);
+ dbg_print("new_status->group3_busy:%x\r\n",new_status->group3_busy);
+
+ dbg_print("new_status->group4_info :%x\r\n",new_status->group4_info);
+ dbg_print("new_status->group4_result:%x\r\n",new_status->group4_result);
+ dbg_print("new_status->group4_busy:%x\r\n",new_status->group4_busy);
+
+ dbg_print("new_status->group5_info :%x\r\n",new_status->group5_info);
+ dbg_print("new_status->group5_result:%x\r\n",new_status->group5_result);
+ dbg_print("new_status->group5_busy:%x\r\n",new_status->group5_busy);
+
+ dbg_print("new_status->group6_info :%x\r\n",new_status->group6_info);
+ dbg_print("new_status->group6_result:%x\r\n",new_status->group6_result);
+ dbg_print("new_status->group6_busy:%x\r\n",new_status->group6_busy);
+ dbg_print("new_status->max_current:%x\r\n",new_status->max_current);
+ dbg_print("new_status->ver:%x\r\n",new_status->ver);
+ */
+
+}
+
+SDC_CMD_STATUS SD_CheckSwitch(void)
+{
+ //read the function support by current card
+ kal_uint32 status;
+ T_SWITCH_STATUS funcStatus;
+
+ char *uhs_mode[] = {"SDR12", "SDR25", "SDR50", "SDR104", "DDR50"};
+ char *speed_mode[] = {"DS", "HS"};
+ char *drv_strength[] = {"TYPE_A", "TYPE_B", "TYPE_C", "TYPE_D"};
+ char *cur_limit[] = {"200mA", "400mA", "600mA", "800mA"};
+
+ if ((status = SD_Switch_SD11(SD_CMD6_QUERY_SUPPORT_FUNCTION, (T_SWITCH_STATUS*)MSDC_Sector)) != NO_ERROR)
+ return status;
+ parse_Cmd6FunctionStatus(&funcStatus,(kal_uint8*)MSDC_Sector);
+ gSD->card_support.function1=funcStatus.group1_info;
+ gSD->card_support.function2=funcStatus.group2_info;
+ gSD->card_support.function3=funcStatus.group3_info;
+ gSD->card_support.function4=funcStatus.group4_info;
+ #if defined(MSDC_CONFIG_SD30_SUPPORT)
+ if (gMSDC_Handle->mMSDC_type==SD30_CARD)
+ {
+ //for SD3.0
+ /*set bus speed mode*/
+ if(gSD->card_support.function1&gMSDC_Handle->host_support.function1&FUN1_SDR104)
+ gSD->function_set.function1=FUN1_SET_SDR104;
+ else if(gSD->card_support.function1&gMSDC_Handle->host_support.function1&FUN1_DDR50)
+ gSD->function_set.function1=FUN1_SET_DDR50;
+ else if(gSD->card_support.function1&gMSDC_Handle->host_support.function1&FUN1_SDR50)
+ gSD->function_set.function1=FUN1_SET_SDR50;
+ else if(gSD->card_support.function1&gMSDC_Handle->host_support.function1&FUN1_SDR25_HS)
+ gSD->function_set.function1=FUN1_SET_SDR25_HS;
+ else
+ gSD->function_set.function1=FUN1_SET_SDR12_DS;
+ /*set command system*/
+ gSD->function_set.function2=FUN2_SET_DEFAULT;
+ /*set driver strength */
+ if (gSD->card_support.function3&gMSDC_Handle->host_support.function3&FUN3_TYPE_A)
+ gSD->function_set.function3=FUN3_SET_TYPE_A;
+ else if(gSD->card_support.function3&gMSDC_Handle->host_support.function3&FUN3_TYPE_B)
+ gSD->function_set.function3=FUN3_SET_TYPE_B;
+ else if(gSD->card_support.function3&gMSDC_Handle->host_support.function3&FUN3_TYPE_C)
+ gSD->function_set.function3=FUN3_SET_TYPE_C;
+ else if(gSD->card_support.function3&gMSDC_Handle->host_support.function3&FUN3_TYPE_D)
+ gSD->function_set.function3=FUN3_SET_TYPE_D;
+ else
+ gSD->function_set.function3=FUN3_SET_TYPE_A;
+ /*set current limit*/
+ if (gSD->function_set.function1==FUN1_SET_SDR104||gSD->function_set.function1==FUN1_SET_DDR50
+ ||gSD->function_set.function1==FUN1_SET_SDR50)
+ {
+ if(gSD->card_support.function4&gMSDC_Handle->host_support.function4&FUN4_800MA)
+ gSD->function_set.function4=FUN4_SET_800MA;
+ else if (gSD->card_support.function4&gMSDC_Handle->host_support.function4&FUN4_600MA)
+ gSD->function_set.function4=FUN4_SET_600MA;
+ else if (gSD->card_support.function4&gMSDC_Handle->host_support.function4&FUN4_400MA)
+ gSD->function_set.function4=FUN4_SET_400MA;
+ else
+ gSD->function_set.function4=FUN4_SET_200MA;
+ }
+ else
+ {
+ gSD->function_set.function4=FUN4_SET_200MA;
+ }
+
+ MSDC_CRIT("[SD][%s]Switch to %s speed mode! \r\n", __FUNCTION__,
+ uhs_mode[gSD->function_set.function1]);
+ MSDC_CRIT("[SD][%s]Switch to %s drive strength! \r\n", __FUNCTION__,
+ drv_strength[gSD->function_set.function3]);
+ MSDC_CRIT("[SD][%s]Switch to %s current limit! \r\n", __FUNCTION__,
+ cur_limit[gSD->function_set.function4]);
+ }
+ else
+ #endif
+ {
+ //for 2.0 HS DS card
+ if(gSD->card_support.function1&gMSDC_Handle->host_support.function1&FUN1_SDR25_HS)
+ gSD->function_set.function1=FUN1_SET_SDR25_HS;
+ else
+ gSD->function_set.function1=FUN1_SET_SDR12_DS;
+
+ MSDC_CRIT("[SD][%s]Switch to %s speed mode! \r\n", __FUNCTION__,
+ speed_mode[gSD->function_set.function1]);
+ }
+ return NO_ERROR;
+
+}
+
+SDC_CMD_STATUS SD_QuerySwith(kal_uint32 cmd6_arg)
+{
+
+ SDC_CMD_STATUS cmd_status;
+ T_SWITCH_STATUS card_support;
+ if ((cmd_status = SD_Switch_SD11(cmd6_arg, (T_SWITCH_STATUS*)MSDC_Sector)) != NO_ERROR)
+ return cmd_status;
+ parse_Cmd6FunctionStatus(&card_support,(kal_uint8*)MSDC_Sector);
+ /*
+ dbg_print("card_support.group1_info :%x\r\n",card_support.group1_info);
+ dbg_print("card_support.group1_result:%x\r\n",card_support.group1_result);
+ dbg_print("card_support.group1_busy:%x\r\n",card_support.group1_busy);
+
+ dbg_print("card_support.group2_info :%x\r\n",card_support.group2_info);
+ dbg_print("card_support.group2_result:%x\r\n",card_support.group2_result);
+ dbg_print("card_support.group2_busy:%x\r\n",card_support.group2_busy);
+
+ dbg_print("card_support.group3_info :%x\r\n",card_support.group3_info);
+ dbg_print("card_support.group3_result:%x\r\n",card_support.group3_result);
+ dbg_print("card_support.group3_busy:%x\r\n",card_support.group3_busy);
+
+ dbg_print("card_support.group4_info :%x\r\n",card_support.group4_info);
+ dbg_print("card_support.group4_result:%x\r\n",card_support.group4_result);
+ dbg_print("card_support.group4_busy:%x\r\n",card_support.group4_busy);
+
+ dbg_print("card_support.group5_info :%x\r\n",card_support.group5_info);
+ dbg_print("card_support.group5_result:%x\r\n",card_support.group5_result);
+ dbg_print("card_support.group5_busy:%x\r\n",card_support.group5_busy);
+
+ dbg_print("card_support.group6_info :%x\r\n",card_support.group6_info);
+ dbg_print("card_support.group6_result:%x\r\n",card_support.group6_result);
+ dbg_print("card_support.group6_busy:%x\r\n",card_support.group6_busy);
+ dbg_print("card_support.max_current:%x\r\n",card_support.max_current);
+ dbg_print("card_support.ver:%x\r\n",card_support.ver);
+ */
+ if (0 == card_support.max_current)
+ return ERR_HIGH_SPEED_CONSUMPTION;
+ #if defined(MSDC_CONFIG_SD30_SUPPORT)
+ if (gMSDC_Handle->mMSDC_type==SD30_CARD)
+ {
+ if ((gSD->function_set.function1==card_support.group1_result)\
+ &&(0==(card_support.group1_busy &(1<<(gSD->function_set.function1)))))
+ {
+
+ if ((gSD->function_set.function3==card_support.group3_result)\
+ &&(0==(card_support.group3_busy &(1<<(gSD->function_set.function3)))))
+ {
+
+ if ((gSD->function_set.function4==card_support.group4_result)\
+ &&(0==(card_support.group4_busy &(1<<(gSD->function_set.function4)))))
+ {
+
+ return NO_ERROR;
+ }
+ }
+ }
+ dbg_print("gSD->function_set.function1=%x card_support.group1_result=%x\r\n",gSD->function_set.function1,card_support.group1_result);
+ dbg_print("gSD->function_set.function3=%x card_support.group3_result=%x\r\n",gSD->function_set.function3,card_support.group3_result);
+ dbg_print("gSD->function_set.function4=%x card_support.group4_result=%x\r\n",gSD->function_set.function4,card_support.group4_result);
+ dbg_print("busy1 %x busy3 %x busy4 %x\r\n",(card_support.group1_busy &(1<<(gSD->function_set.function1)))\
+ ,(card_support.group3_busy &(1<<(gSD->function_set.function3)))\
+ ,(card_support.group4_busy &(1<<(gSD->function_set.function4))));
+ if ((0xF == card_support.group1_result)\
+ || (!(card_support.group1_info & (1<<(gSD->function_set.function1)))))
+ return ERR_SPEED_MODE_UNSUPPORT;//not support
+ if ((0xF == card_support.group3_result)\
+ || (!(card_support.group3_info & (1<<(gSD->function_set.function3)))))
+ return ERR_DRIVER_TYPE_UNSUPPORT;//not support
+ if ((0xF == card_support.group4_result)\
+ || (!(card_support.group4_info & (1<<(gSD->function_set.function4)))))
+ return ERR_CURRENT_LIMIT_UNSUPPORT;//not support
+
+
+ if (card_support.group1_busy & (1 << (gSD->function_set.function1)))//busy
+ return ERR_SWITCH_BUSY;
+ if (card_support.group3_busy & (1 << (gSD->function_set.function3)))//busy
+ return ERR_SWITCH_BUSY;
+ if (card_support.group4_busy & (1 << (gSD->function_set.function4)))//busy
+ return ERR_SWITCH_BUSY;
+ }
+ else
+ #endif
+ {
+ if ((gSD->function_set.function1==card_support.group1_result)\
+ &&(0==(card_support.group1_busy &(1<<(gSD->function_set.function1)))))
+ return NO_ERROR;
+ if ((0xF == card_support.group1_result)\
+ || (!(card_support.group1_info & (1<<(gSD->function_set.function1)))))
+ return ERR_HIGH_SPEED_NOT_SUPPORT;//not support
+ if (card_support.group1_busy & (1 << (gSD->function_set.function1)))//busy
+ return ERR_HIGH_SPEED_BUSY;
+ }
+
+ return ERR_HIGH_SPEED_COMMON_ERROR;
+}
+
+SDC_CMD_STATUS SD_SwitchSpeedMode(void)
+{
+ kal_uint32 status,set_function;
+ kal_int32 t1;
+
+ if (gSD->mSCR.spec_ver<SCR_SEC_VER_1)
+ {
+ gSD->function_set.function1=0;
+ return NO_ERROR;
+ }
+ if (!(gSD->mCSD.ccc&CCC_SWITCH))
+ {
+ gSD->function_set.function1=0;
+ return NO_ERROR;
+ }
+
+ t1 = drv_get_current_time();
+ if ((status =SD_CheckSwitch()) != NO_ERROR)
+ return status;
+ #if defined(MSDC_CONFIG_SD30_SUPPORT)
+ if (gMSDC_Handle->mMSDC_type==SD30_CARD)
+ {
+ set_function=0x00ff0000|gSD->function_set.function1|(gSD->function_set.function3<<8)|(gSD->function_set.function4<<12);
+ }
+ else
+ #endif
+ {
+ set_function=0x00fffff0|gSD->function_set.function1;
+ }
+ do
+ {
+ status = SD_QuerySwith(SD_CMD6_QUERY_SWITCH|set_function);//query
+ if (NO_ERROR == status)
+ {
+ status = SD_QuerySwith(SD_CMD6_SELECT_SWITCH|set_function);//switch
+ if (NO_ERROR == status)
+ {
+ if (gMSDC_Handle->mMSDC_type==SD30_CARD)
+ {
+ gSD->flags |= SD_FLAG_UHS_ENABLED;
+ }
+ else if (gSD->function_set.function1==1)
+ {
+ gSD->flags |= SD_FLAG_HS_ENABLED;
+ }
+
+ return NO_ERROR;
+ }
+ if (ERR_SWITCH_BUSY != status)
+ break;
+ }
+ if (ERR_SWITCH_BUSY != status)
+ break;
+ if (drv_get_duration_ms(t1)>500)
+ return ERR_SWITCH_TIMEOUT;
+ }while(1);
+ return status;
+}
+SDC_CMD_STATUS SD_GoInactive(kal_uint16 rca)
+{
+ SDC_CMD_STATUS status;
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD15, (kal_uint32)rca << 16,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+
+SDC_CMD_STATUS SD_ReadStream_MMC(kal_uint32 address, kal_uint32* rxbuffer, kal_uint32 bytes)
+{
+
+ return 0;
+}
+
+
+// write data stream from card only for MMC
+SDC_CMD_STATUS SD_WriteStream_MMC(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 bytes)
+{
+ return 0;
+}
+
+//program CSD, transfer CSD through data line
+SDC_CMD_STATUS SD_ProgramCSD(kal_uint32 Csd[4])
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 blklen;
+ //set block length to 16 , num to 1
+
+ gSD->mBKNum=1;
+ blklen=gSD->mBKLength;
+ gSD->mBKLength = 16;
+ MSDC_WriteReg32(SDC_BLK_NUM,1);
+ //set to pio mode and clear fifo
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=0;
+ MSDC_CLR_FIFO();
+
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD27, 0,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ //read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ {
+ //SD_WaitDatRdyOrTo();
+ return status;
+ }
+ //send CSD 128 bits
+ status=SD_WaitDatRdyOrTo(Csd,16,KAL_TRUE);
+ //set block length back to 512
+ BitFieldWrite32((kal_uint32*)SDC_CMD, 512, SDC_CMD_BLKLEN);
+ gSD->mBKLength=blklen;
+ return status;
+}
+
+
+//set write protect
+SDC_CMD_STATUS SD_SetWriteProtect(kal_uint32 address)
+{
+ SDC_CMD_STATUS status;
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD28, address,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ //wait until data line is ready
+ status =SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT);
+ return status;
+}
+
+//clear write protect
+SDC_CMD_STATUS SD_ClrWriteProtect(kal_uint32 address)
+{
+ SDC_CMD_STATUS status;
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD29, address,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ status=SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT);
+ return status;
+}
+
+// send write protect(single block read)
+SDC_CMD_STATUS SD_SendWriteProtect(kal_uint32 address, kal_uint32* WPBits32)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 tmp,blklen;
+
+
+ BitFieldWrite32((kal_uint32*)SDC_CMD, 4, SDC_CMD_BLKLEN);
+ blklen=gSD->mBKLength;
+ gSD->mBKLength=4;
+ MSDC_WriteReg32(SDC_BLK_NUM,1);
+ MSDC_CLR_FIFO();
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD30, address,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ //read 32 write protection bits
+ tmp=MSDC_FIFO_READ32();
+ MSDC_InvertN((kal_uint8*)WPBits32, (kal_uint8*)&tmp, 4);
+ // configure the controller to the original block length
+ BitFieldWrite32((kal_uint32*)SDC_CMD, 512, SDC_CMD_BLKLEN);
+ gSD->mBKLength=blklen;
+
+ return NO_ERROR;
+}
+
+// CMD39: Fast IO-used to write and read 8 bit register
+SDC_CMD_STATUS SD_FastIO_MMC(kal_uint16 rca, kal_bool isWrite, kal_uint8 reg_adrs, kal_uint8 data)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 arg = 0;
+
+ arg = rca << 16;
+ arg |= isWrite << 15;
+ arg |= reg_adrs << 8;
+ arg |= data;
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD39_MMC, arg,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+
+
+// Sets the system into interrupt mode (MMC)
+SDC_CMD_STATUS SD_GoIRQ_MMC(void)
+{
+ SDC_CMD_STATUS status;
+
+ if ((status = SD_SendCmd(SDC_CMD_CMD40_MMC, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ status = *(kal_uint32*)SDC_RESP0;
+#ifdef MSDC_TRACE_LEVEL2
+ MD_TRC_MSDC_INFORM_R0(status, __LINE__);
+#endif
+
+ return NO_ERROR;
+}
+
+// Used to set/reset password ,lock/unlock the card and force erase total card.
+// similiar to a signle block write structure.(CMD42)
+// max password length = 16
+SDC_CMD_STATUS SD_LockUnlock(SD_LOCK_OP op, kal_char* Oldpwd, kal_char* Newpwd, kal_uint8 Oldlen, kal_uint8 Newlen)
+{
+ SDC_CMD_STATUS status;
+ kal_uint8 lockbk[SDC_MAX_LOCKBK];
+ kal_uint32 blklen, *ptr = (kal_uint32*)lockbk, count;
+
+ if (Oldlen > 16 || Newlen > 16)
+ return ERR_ERRORS;
+
+ /* save the original block length*/
+ blklen = gSD->mBKLength;
+
+ kal_mem_set(lockbk, 0, SDC_MAX_LOCKBK);
+
+ switch (op)
+ {
+ case SET_PWD:
+ lockbk[0] = 0x01;
+ break;
+
+ case CLR_PWD:
+ lockbk[0] = 0x02;
+ break;
+
+ case LOCK_CARD:
+ lockbk[0] = 0x04;
+ break;
+
+ case UNLOCK_CARD:
+ lockbk[0] = 0x00;
+ break;
+
+ case ERASE:
+ lockbk[0] = 0x08;
+ break;
+ }
+
+ lockbk[1] = Oldlen + Newlen;
+ kal_mem_cpy(&lockbk[2], Oldpwd, Oldlen);
+ kal_mem_cpy(&lockbk[2 + Oldlen], Newpwd, Newlen);
+
+ /* set block length */
+ if (op != ERASE)
+ {
+ SD_SetBlength(2 + lockbk[1]);
+ count = ((lockbk[1] + 2) % sizeof(kal_uint32)) ? ((lockbk[1] + 2) / sizeof(kal_uint32) + 1) :
+ ((lockbk[1] + 2) / sizeof(kal_uint32));
+ gSD->mBKNum=1;
+ blklen=gSD->mBKLength;
+ gSD->mBKLength = 2 + lockbk[1];
+ MSDC_WriteReg32(SDC_BLK_NUM,1);
+ //set to pio mode and clear fifo
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=0;
+ MSDC_CLR_FIFO();
+ }
+ else
+ {
+ SD_SetBlength(1);
+ gSD->mBKNum=1;
+ blklen=gSD->mBKLength;
+ gSD->mBKLength = 1;
+ MSDC_WriteReg32(SDC_BLK_NUM,1);
+ //set to pio mode and clear fifo
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=0;
+ MSDC_CLR_FIFO();
+ count = 1;
+ }
+ MSDC_WriteReg32(SDC_BLK_NUM,1);
+ /* send command */
+ if ((status = SD_SendCmd(SDC_CMD_CMD42, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ /* read R1b */
+ SD_CheckStatus();
+ /* clear FIFO */
+ MSDC_CLR_FIFO();
+
+
+#ifndef DRV_LSD
+ status=SD_WaitDatRdyOrTo(ptr,count,KAL_TRUE);
+
+#endif
+
+ /* wait util card has finished programming */
+ SD_WaitCardNotBusy(MSDC_DATA_TIMEOUT);
+ // restore the block length back
+ if (status != NO_ERROR)
+ {
+ return gMSDC_Handle->error;
+ }
+
+ // restore the block length back
+ SD_SetBlength(blklen);
+ gSD->mBKLength=blklen;
+ /* check status*/
+ SD_GetStatus(gSD->mRCA, &status);
+
+ if (status & R1_LOCK_UNLOCK_FAILED_24)
+ return ERR_LOCK_UNLOCK_FAILED;
+
+ if ((op == LOCK_CARD) && !(status & R1_CARD_IS_LOCKED_25))
+ return ERR_LOCK_UNLOCK_FAILED;
+
+ if ((op == UNLOCK_CARD) && (status & R1_CARD_IS_LOCKED_25))
+ return ERR_LOCK_UNLOCK_FAILED;
+
+ return NO_ERROR;
+}
+
+// ACMD13: read SD status(512bits = 64bytes single block read)
+SDC_CMD_STATUS SD_GetSDStatus(kal_uint32* sd_status)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 blklen;
+
+
+ //if ((status = SD_SetBlength(64)) != NO_ERROR)
+ // return status;
+
+ // send APP_CMD
+ if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+ return status;
+ // save the orignial block length
+ blklen=gSD->mBKLength;
+ gSD->mBKLength = 64;
+ MSDC_WriteReg32(SDC_BLK_NUM,1);
+ MSDC_DEBUG("[SD][%s %d]send acmd13\r\n",__FUNCTION__,__LINE__);
+
+ //set to pio mode and clear fifo
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=0;
+ MSDC_CLR_FIFO();
+ // send ACMD13
+ if ((status = SD_SendCmd(SDC_CMD_ACMD13, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ //read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ // read sd status(64bytes = 4x16)
+ status=SD_WaitDatRdyOrTo(sd_status,64,KAL_FALSE);
+ if (status !=NO_ERROR)
+ {
+ return status;
+ }
+ gSD->mBKLength=blklen;
+ return NO_ERROR;
+}
+//ACMD22: get the number of written write blocks(4bytes single block read)
+SDC_CMD_STATUS SD_GetNumWrittenBlk(kal_uint32* num)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 blklen, tmp;
+
+ // send APP_CMD
+ if ((status = SD_Cmd55(gSD->mRCA)) != NO_ERROR)
+ return status;
+
+ blklen=gSD->mBKLength;
+ gSD->mBKLength = 4;
+ MSDC_WriteReg32(SDC_BLK_NUM,1);
+ MSDC_DEBUG("[SD][%s %d]send acmd13\r\n",__FUNCTION__,__LINE__);
+
+ //set to pio mode and clear fifo
+ BitFieldWrite32((kal_uint32 *)MSDC_CFG, 1, MSDC_CFG_PIO);
+ gMSDC_Handle->dma_xfer=0;
+ MSDC_CLR_FIFO();
+
+ // send CMD22
+ if ((status = SD_SendCmd(SDC_CMD_ACMD22, SDC_NO_ARG,MSDC_CMD_TIMEOUT)) != NO_ERROR)
+ return status;
+
+ //read R1
+ if ((status = SD_CheckStatus()) != NO_ERROR)
+ return status;
+
+ // read the number of written write blocks(4bytes)
+
+ if ((status=SD_WaitDatRdyOrTo(&tmp,4,KAL_FALSE))!=NO_ERROR)
+ return status;
+
+ MSDC_InvertN((kal_uint8*)num, (kal_uint8*)&tmp, 4);
+
+ // resotre block length
+ gSD->mBKLength=blklen;
+ return NO_ERROR;
+}
+
+#ifdef DRV_MSDC_HW_CONTENTION
+extern kal_semid dclMsdcArb;
+#endif
+
+void SD_startFastFormat(void)
+{
+ #if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_LOCK(AUDMA_ID_MSDC);
+ #endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+ kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+ /* RVCT doesn't support inline assemlber; bypass temporarily */
+ retAddr = 0;
+#else /* __RVCT__ */
+ /* get the return address */
+ __asm
+ {
+ MOV retAddr, lr
+ }
+#endif /* __RVCT__ */
+
+
+ if (NULL == dclMsdcArb)
+ ASSERT(0);
+
+ if (kal_query_systemInit() == KAL_FALSE)
+ {
+ /*must gain resource here before calling writeSectors*/
+ kal_take_sem(dclMsdcArb, 1);
+ SD_setArbRetAddr(retAddr);
+ SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+ }
+
+#endif
+
+
+#ifdef DRV_LSD
+ LSD_startFastFormat();
+#elif defined(__DRV_MSDC_FAST_FORMAT__)
+ gMSDC_Handle->MSDC_fastFormat = KAL_TRUE;
+#endif
+}
+
+void SD_closeFastFormat(void)
+{
+ #ifdef DRV_LSD
+ LSD_closeFastFormat();
+ #elif defined(__DRV_MSDC_FAST_FORMAT__)
+ gMSDC_Handle->MSDC_fastFormat = KAL_FALSE;
+ #endif
+
+ #ifdef DRV_MSDC_HW_CONTENTION
+
+ if (kal_query_systemInit() == KAL_FALSE)
+ {
+ /*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+ SD_setArbThdId(NULL);
+ kal_give_sem(dclMsdcArb);
+ }
+
+ #endif
+
+ #if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_UNLOCK(AUDMA_ID_MSDC);
+ #endif
+
+}
+
+
+//__attribute__ ((section ("EXT_BOOTLOADER_CODE")))SDC_CMD_STATUS SD_FlushSectors(kal_uint32 startSector, kal_uint32 sectorNum)
+SDC_CMD_STATUS SD_FlushSectors(kal_uint32 startSector, kal_uint32 sectorNum)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 sectorMult,maxBlk;
+
+ if (gSD->flags & SD_FLAG_HCS_SUPPORT)
+ sectorMult = 1;
+ else
+ sectorMult = SECTOR_SIZE;
+ maxBlk=gSD->mCSD.capacity /512;
+ if(0 == sectorNum || sectorNum > maxBlk || startSector > maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+
+ /*check that ending block should be smaller than maximum block number*/
+ if((startSector + sectorNum - 1) > maxBlk){
+ //ASSERT(0);
+ status = STATUS_INVALID_CTRL_DATA;
+ return status;
+ }
+ MSDC_PDNControl(KAL_FALSE);
+
+ // there are differences between SD and MMC
+ // tag erase start(CMD32)
+ if ((status = SD_EraseCmdClass(SDC_CMD_CMD32, sectorMult * startSector)) != NO_ERROR)
+ {
+ goto ErrorExit;
+ }
+
+ // tag erase end(CMD33)
+ if ((status = SD_EraseCmdClass(SDC_CMD_CMD33, sectorMult * (startSector + sectorNum - 1))) != NO_ERROR)
+ {
+ goto ErrorExit;
+ }
+
+ // erase...(CMD38)
+ if ((status = SD_EraseCmdClass(SDC_CMD_CMD38, 0)) != NO_ERROR)
+ {
+ goto ErrorExit;
+ }
+
+ErrorExit:
+ MSDC_PDNControl(KAL_TRUE);
+ return status;
+}
+
+#ifdef IC_MODULE_TEST
+
+kal_bool MSDC_ModuleTest_Report(void)
+{
+
+ SDC_CMD_STATUS status;
+
+ if (gMSDC_Handle->mIsInitialized == KAL_FALSE)
+ return KAL_FALSE;
+
+ MSDC_PDNControl(KAL_FALSE);
+
+ gMSDC_Handle->mIsInitialized = KAL_TRUE;
+ gMSDC_Handle->trySingleLine = KAL_TRUE;
+
+ status = SD_Initialize();
+
+ if (status == NO_ERROR)
+ return KAL_TRUE;
+ else
+ return KAL_FALSE;
+
+}
+#endif
+
+#else
+#ifdef DRV_LSD
+T_SDC_HANDLE gSD_blk[SD_NUM];
+T_SDC_HANDLE *gSD = gSD_blk;
+#endif
+#endif // defined(__MSDC_SD_MMC__)
+
+#ifdef MSDC_DEBUG
+
+#define TST_ADRS 512*12
+kal_uint32 SD_MMC_Test(void)
+{
+
+ return 0;
+
+}
+#endif // FPGA_DEBUG
+
+#endif//!defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+
+#else //DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "kal_general_types.h"
+//#include "btif_sw.h"
+#include "kal_public_api.h"
+#include "kal_internal_api.h"
+#include "kal_public_defs.h"
+
+//#include "gpt_sw.h"
+#include "drv_comm.h"
+#include "reg_base.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "upll_ctrl.h"
+//#include "Drv_trc.h"
+#ifdef DCL_MSDC_INTERFACE
+#include "dcl.h"
+void SD_dummyAPI(void) {}
+SDC_CMD_STATUS SD_SetBlength(kal_uint32 BKLength) {}
+SDDriver_t sd_driver_MTK1 =
+{
+ (DCL_SINGLE_BLK_RD)SD_dummyAPI,
+ (DCL_MUL_BLK_RD)SD_dummyAPI,
+ (DCL_SINGLE_BLK_WR)SD_dummyAPI,
+ (DCL_MUL_BLK_WR)SD_dummyAPI,
+ (DCL_SD_INITITALIZE)SD_dummyAPI,
+ (DCL_SET_PRE_ERASE_CNT)SD_dummyAPI,
+ (DCL_SD_SET_CALLBACK)SD_dummyAPI,
+ (DCL_SET_READ_TEST_FLAG)SD_dummyAPI,
+ (DCL_SD_READ_TEST)SD_dummyAPI,
+ (DCL_SD_SET_UPLL_CLOCK_TEST)SD_dummyAPI,
+ (DCL_SD_ERASE_BLK)SD_dummyAPI,
+ (DCL_GPD_MUL_BLK_RD)SD_dummyAPI,
+ (DCL_GPD_MUL_BLK_WR)SD_dummyAPI,
+};
+#endif //DCL_MSDC_INTERFACE
+
+void SD_startFastFormat(void) {}
+void SD_closeFastFormat(void) {}
+T_SDC_HANDLE gSD_blk[SD_NUM];
+T_SDC_HANDLE *gSD = gSD_blk;
+
+#if defined( __MSDC_BASIC_LOAD__) || defined( __MEUT__)
+kal_uint32 msdc_ReadTestFlag;
+#endif
+
+#endif //DRV_MSDC_OFF
+
+
diff --git a/mcu/driver/storage/mc/src/sd2.c b/mcu/driver/storage/mc/src/sd2.c
new file mode 100644
index 0000000..c1b4dca
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sd2.c
@@ -0,0 +1,2414 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * sd.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * driver functons for SD/MMC
+ *
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//RHR ADD
+#include "kal_general_types.h"
+//#include "btif_sw.h"
+#include "kal_public_api.h"
+//#include "kal_internal_api.h"
+#include "kal_debug.h"
+#include "kal_public_defs.h"
+//RHR REMOVE
+/*
+//MSBB remove #include "app_buff_alloc.h"
+#include "intrCtrl.h"
+#include "gpio_sw.h"
+#include "init.h"
+*/
+//RHR
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "reg_base.h"
+#include "upll_ctrl.h"
+
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+T_SDC_HANDLE *gSD2 = &gSD_blk[SD_MSDC2];
+extern MSDC_HANDLE *msdc2_handle;
+extern kal_uint32 MSDC_Sector2[128];
+
+extern kal_uint8 MSDC_GetIOCtrlParam(void);
+extern kal_bool INT_USBBoot(void);
+extern int MSDC_GetCustom(void);
+
+/*************************************************************************
+* FUNCTION
+* SD_Acmd42
+*
+* DESCRIPTION
+* connect/disconnect the 50K Ohm pull-up resistor on CD/DAT3
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+*
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Acmd42_2(kal_bool connect)
+{
+ SDC_CMD_STATUS status;
+
+ // send APP_CMD
+ if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+ return status;
+ // send cmd6
+ if((status = SD_Send_Cmd_2(SDC_CMD_ACMD42,connect))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+
+ gSD2->mCD_DAT3 = KAL_FALSE; // pull-up resistor is disconnected for data trnasfer
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SetMMC40_4bit_high_speed
+*
+* DESCRIPTION
+* Check inserted card is SD or MMC
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SD_CARD or MMC_CARD
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetMMC40_bus_high_speed_2(void)
+{
+ kal_uint32 clock, hs;
+ #ifdef DRV_MSDC_MT6225_SERIES
+ /*use larger driving current. In mt6225 and mt6227D, IOCON is 32 bit register and DLT cannot be 0*/
+ MSDC_LSD_WriteReg(MSDC_IOCON2,0x36);
+ MSDC_SetIOCONRegDLT2();
+ #else
+ MSDC_LSD_WriteReg(MSDC_IOCON2,0x1B);
+ #endif
+
+ if(SD_SetBlength_2(512)!=NO_ERROR)
+ goto err;
+
+ // read the EXT_CSD
+ if(SD_SendEXTCSD_MMC40_2(MSDC_Sector2) != NO_ERROR)
+ goto err;;
+
+ // set high speed
+ if(gSD2->mCSD.ext_csd->card_type & HS_52M)
+ {
+ // should be 52000
+ //clock = 52000;
+ clock = msdc2_handle->msdc_clock / 2;
+ hs = 1;
+ //MSDC_LSD_WriteReg32(MSDC_IOCON,0x010002FF);
+ MSDC_LSD_ClearBits32(MSDC_CFG2,MSDC_CFG_CRED);;
+
+ }
+ else if(gSD2->mCSD.ext_csd->card_type & HS_26M)
+ {
+ // should be 26000
+ clock = 26000;
+ hs = 1;
+ }
+ else
+ {
+ clock = 13000;
+ hs = 0;
+ }
+ if(hs)
+ {
+ // select proper power class
+ if(SD_Switch_MMC40_2(SET_BYTE,EXT_CSD_POW_CLASS_INDEX,
+ (gSD2->mCSD.ext_csd->pwr_52_360&0xf) ,0) != NO_ERROR)
+ goto err;
+
+ // enable high speed (26M or 52M)
+ if(SD_Switch_MMC40_2(SET_BYTE,EXT_CSD_HIGH_SPPED_INDEX,
+ EXT_CSD_ENABLE_HIGH_SPEED,0) != NO_ERROR)
+ goto err;
+
+ // latch data at falling edge to cover the card driving capability
+ // MSDC_LSD_SetBits32(MSDC_CFG2,MSDC_CFG_RED);
+ }
+
+ msdc2_handle->msdc_clock = MSDC_CLOCK;
+ MSDC_SetClock2(clock);
+
+ #ifdef DRV_MSDC_MT6225_SERIES
+ /*change DLT and set cmd latch at rising edge*/
+ MSDC_LSD_WriteReg(MSDC_IOCON2,0x8036);
+ MSDC_SetIOCONRegDLT2();
+ #endif
+
+ #if 0 // MSDC2 only support 1-bit data
+/* under construction !*/
+ #if defined(MMC40_USE_4BIT_BUS)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #elif defined(MMC40_USE_8BIT_BUS)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ #endif
+
+ if(SD_SendEXTCSD_MMC40_2(MSDC_Sector2) != NO_ERROR)
+ goto err;;
+
+ return NO_ERROR;
+err:
+ return ERR_MMC_BUS_HS_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_CheckSDorMMC
+*
+* DESCRIPTION
+* Check inserted card is SD or MMC
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SD_CARD or MMC_CARD
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+T_MSDC_CARD SD_CheckSDorMMC_2()
+{
+ SDC_CMD_STATUS status;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ SD_Cmd8_2();
+#endif
+ if((status = SD_Acmd41_SD_2())==NO_ERROR)
+ return msdc2_handle->mMSDC_type; // SD_CARD
+ else if((status = SD_Cmd1_MMC_2())==NO_ERROR)
+ return msdc2_handle->mMSDC_type; // MMC_CARD
+
+ return UNKNOWN_CARD;
+}
+/*************************************************************************
+* FUNCTION
+* SD_SetDefault
+*
+* DESCRIPTION
+* set default values to gSD
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+void SD_SetDefault_2(void)
+{
+ kal_mem_set(gSD2,0,sizeof(T_SDC_HANDLE));
+ gSD2->mBKLength = 512;
+ gSD2->mRCA = 0;
+ gSD2->mInactive = KAL_FALSE;
+ gSD2->mState = IDLE_STA;
+ gSD2->bus_width = 1;
+ gSD2->mCD_DAT3 = KAL_TRUE;
+}
+
+void SD_Use24M_Clock_2(void)
+{
+ if(msdc2_handle->mMSDC_type == SD_CARD || msdc2_handle->mMSDC_type == SD20_LCS_CARD
+ || msdc2_handle->mMSDC_type == SD20_HCS_CARD)
+ {
+ UPLL_Enable(UPLL_OWNER_MSDC2);
+ MSDC_LSD_SetBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+ msdc2_handle->msdc_clock = MSDC_CLOCK_USB;
+ MSDC_SetClock2(MSDC_SD_OP_CLOCK);
+ gSD2->flags |= SD_FLAG_USE_USB_CLK;
+ }
+}
+
+void SD_Use13M_Clock_2(void)
+{
+ MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+ msdc2_handle->msdc_clock = MSDC_CLOCK;
+ MSDC_SetClock2(MSDC_OP_CLOCK);
+ gSD2->flags &= ~SD_FLAG_USE_USB_CLK;
+}
+
+
+/*************************************************************************
+* FUNCTION
+* SD_Initialize
+*
+* DESCRIPTION
+* Initial SD controller and card
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Initialize_2(void)
+{
+ kal_uint32 cid[4],csd[4],scr[4];
+ kal_uint16 rca, iocon;
+ SDC_CMD_STATUS status;
+
+ if(msdc2_handle->mIsInitialized == KAL_TRUE)
+ {
+ return NO_ERROR;
+ }
+ // reset the events
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+ // reset msdc
+ if(MSDC_Reg32(MSDC_CFG2) & MSDC_CFG_RST)
+ {
+ MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_RST);
+ }
+ else
+ {
+ RESET_MSDC2();
+ }
+
+ #if defined(DRV_MSDC_MT6225_SERIES)
+ MSDC_LSD_SetBits32(MSDC_CFG2,MSDC_CFG_CRED);
+ #endif
+
+ // set the output driving capability from customization interface
+ iocon = MSDC_SetData(MSDC_IOCON2, 0xff, MSDC_GetIOCtrlParam2());
+ // set pull up the data and cmd
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG0);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG1);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG2);
+ // set read timeout x5ms
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,(kal_uint32)40,SDC_CFG_DTOC);
+ //set clock of serial clcok for initialization
+ MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+ msdc2_handle->msdc_clock = MSDC_CLOCK;
+ MSDC_SetClock2(MSDC_INI_CLOCK);
+ MSDC_LSD_ClearBits32(SDC_CFG2,SDC_CFG_MDLEN);
+ // initial global sturctures
+ SD_SetDefault_2();
+
+ // send the card to IDLE state
+ if((status = SD_Reset_2())!=NO_ERROR)
+ {
+ goto err;
+ }
+
+ // and validate the OCR (CMD0,CMD1 or ADMD41)
+ if(SD_CheckSDorMMC_2() == UNKNOWN_CARD)
+ {
+ status = ERR_STATUS;
+ goto err;
+ }
+
+ // get CID(CMD2)
+ if((status = SD_GetCID_2(cid))!=NO_ERROR)
+ {
+ goto err;
+ }
+ // get or set RCA(CMD3)
+ if((status = SD_ValidateRCA_2(&rca))!=NO_ERROR)
+ {
+ goto err;
+ }
+ // get CSD and analysis the CSD(CMD9)
+ if((status = SD_GetCSD_2(gSD2->mRCA,csd))!=NO_ERROR)
+ {
+ goto err;
+ }
+ // Set driver stage register DSR to default value (0x0404)(CMD4)
+ if(gSD2->mCSD.dsr_imp)
+ if((status = SD_SetDSR_2())!=NO_ERROR)
+ {
+ //dbg_print("6\r\n");
+ goto err;
+ }
+
+ if(MSDC_GetCustom() & MSDC2_WP)
+ {
+ if((MSDC_Reg(SDC_STA2) & SDC_STA_WP))
+ gSD2->mWPEnabled = KAL_TRUE;
+ }
+ status = SD_SelectCard_2(gSD2->mRCA);
+ if(status == CARD_IS_LOCKED)
+ gSD2->mIsLocked = KAL_TRUE;
+
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD2->flags & SD_FLAG_SD_TYPE_CARD)
+ #else
+ if(msdc2_handle->mMSDC_type == SD_CARD)
+ #endif
+ {
+ SD_Use24M_Clock_2();
+ MSDC_SetIOCONRegDLT2();
+ if((status = SD_ReadSCR_2(scr))!=NO_ERROR)
+ {
+ goto err;
+ }
+ #if 0 // MSDC2 only support 1-bit data
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+
+ #if !defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
+ if((status = SD_Acmd42_2(KAL_FALSE))!=NO_ERROR)
+ {
+ goto err;
+ }
+ #endif
+
+ if(gSD2->flags & SD_FLAG_CMD6_SUPPORT)
+ {
+ status = SD_SelectHighSpeed_SD11_2();
+ if(status == NO_ERROR)
+ {
+ gSD2->flags |= SD_FLAG_HS_ENABLED;
+ MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+ msdc2_handle->msdc_clock = MSDC_CLOCK;
+ MSDC_SetClock(26000);
+ }
+ }
+ }
+ else
+ {
+ if(msdc2_handle->mMSDC_type == MMC_CARD && gSD2->mCSD.spec_ver >= 4)
+ {
+ msdc2_handle->mMSDC_type = MMC40_CARD;
+ if((status = SD_SetMMC40_bus_high_speed_2())!= NO_ERROR)
+ goto err;
+ }
+ else
+ {
+ SD_Use13M_Clock_2();
+ }
+ }
+ status = SD_SetBlength_2(512);
+err:
+ if(status != NO_ERROR)
+ {
+ tst_sys_trace("SD2 mount fail!");
+ SD_SetDefault();
+ msdc2_handle->mIsInitialized = KAL_FALSE;
+ }
+ else
+ {
+ tst_sys_trace("SD2 mount ok!");
+ msdc2_handle->mIsInitialized = KAL_TRUE;
+ }
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+
+ return status ;
+}
+
+static kal_uint32 power2(kal_uint32 num)
+{
+ return 1 << num;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_AnalysisCSD
+*
+* DESCRIPTION
+* Analysis Card Specific Data and store in the member of gSD
+*
+* PARAMETERS
+* csd: input csd for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+void SD_AnalysisCSD_2(kal_uint32* csd)
+{
+ kal_uint8 *ptr;
+ kal_uint32 c_mult,c_size;
+
+ ptr = (kal_uint8*)csd;
+ c_mult = c_size = 0;
+ // these offsets refer to the spec. of SD and MMC
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.csd_ver, ptr, 126,2);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.tacc,ptr,112,8);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.nsac,ptr,104,8);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.tran_speed,ptr,96,8);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.ccc,ptr,84,12);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.r_blk_len,ptr,80,4);
+ gSD2->mCSD.r_blk_len = power2(gSD2->mCSD.r_blk_len);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.r_blk_part,ptr,79,1);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.w_blk_misali,ptr,78,1);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.r_blk_misali,ptr,77,1);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.dsr_imp,ptr,76,1);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.w_blk_part,ptr,21,1);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.w_blk_len,ptr,22,4);
+ gSD2->mCSD.w_blk_len = power2(gSD2->mCSD.w_blk_len);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.wp_grp_enable,ptr,31,1);
+ // there are some difference of CSD between SD and MMC
+ if(msdc2_handle->mMSDC_type == MMC_CARD)
+ {
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.spec_ver, ptr, 122,4);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_sec_size_mmc,ptr,42,5);
+ gSD2->mCSD.erase_sec_size_mmc = (gSD2->mCSD.erase_sec_size_mmc+1)*gSD2->mCSD.w_blk_len;
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_grp_size_mmc,ptr,37,5);
+ gSD2->mCSD.erase_grp_size_mmc = (gSD2->mCSD.erase_grp_size_mmc+1)*gSD2->mCSD.erase_sec_size_mmc;
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.wp_grp_size_mmc,ptr,32,5);
+ gSD2->mCSD.wp_grp_size_mmc = (gSD2->mCSD.wp_grp_size_mmc + 1)*gSD2->mCSD.erase_grp_size_mmc;
+ }
+ else // SD_CARD
+ {
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_sec_size_sd,ptr,39,7);
+ gSD2->mCSD.erase_sec_size_sd += 1;
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.wp_prg_size_sd,ptr,32,7);
+ gSD2->mCSD.wp_prg_size_sd = (gSD2->mCSD.wp_prg_size_sd+1) * gSD2->mCSD.erase_sec_size_sd;
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_blk_en_sd,ptr,46,1);
+ }
+
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(msdc2_handle->mMSDC_type == SD20_HCS_CARD && gSD2->mCSD.csd_ver >= SD_CSD_VER_20)
+ {
+ GetBitFieldN((kal_uint8*)&c_size,ptr,48,22);
+ gSD2->mBKNum = (c_size+1);
+ gSD2->mCSD.capacity = (kal_uint64)gSD2->mBKNum*512*1024;
+ }
+ else
+ #endif
+ {
+ GetBitFieldN((kal_uint8*)&c_mult,ptr,47,3);
+ c_mult = power2(c_mult+2);
+ GetBitFieldN((kal_uint8*)&c_size,ptr,62,12);
+ gSD2->mBKNum = (c_size+1)*c_mult;
+ gSD2->mCSD.capacity = (c_size+1)*c_mult*gSD2->mCSD.r_blk_len;
+ }
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_AnalysisCID
+*
+* DESCRIPTION
+* Analysis Card Identificaton and store in the member of gSD
+*
+* PARAMETERS
+* cid: input of card ID for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+void SD_AnalysisCID_2(kal_uint32* cid)
+{
+ kal_uint8 i;
+ kal_uint8* pcid;
+ pcid = (kal_uint8*)cid;
+
+ if(msdc2_handle->mMSDC_type == MMC_CARD)
+ {
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.year,pcid,8,4);
+ gSD2->mCID.year += 1997;
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.month,pcid,12,4);
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.psn,pcid,16,32);
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.prv,pcid,48,8);
+ for(i=0;i<6;i++)
+ gSD2->mCID.pnm[i] = *(pcid+7+i);
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.oid,pcid,104,16);
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.mid,pcid,120,8);
+
+ // special case handling
+ {
+ kal_uint8 pnm[] = {0xFF,0xFF,0xFF,0xFF,0x36,0x31};
+ if(gSD2->mCID.mid == 6 && gSD2->mCID.oid == 0 &&
+ !kal_mem_cmp(gSD2->mCID.pnm,pnm,6))
+ {
+ gSD2->flags |= SD_FLAG_MMC_MRSW_FAIL;
+ }
+ }
+ }
+ else // SD_CARD
+ {
+ gSD2->mCID.mid = *(pcid+15);
+ gSD2->mCID.oid = *(pcid+13) + 256*(*(pcid+14));
+ for(i=0;i<5;i++)
+ gSD2->mCID.pnm[i] = *(pcid+8+i);
+ gSD2->mCID.prv = *(pcid+7);
+ //gSD2->mCID.psn = *(kal_uint32*)(pcid+3);
+ gSD->mCID.psn = (*(kal_uint32*)(pcid+4)<<8)|*(pcid+3);
+ gSD2->mCID.month = (kal_uint8)GET_BIT(*(pcid+1),0,BIT_MASK_4);
+ gSD2->mCID.year = GET_BIT(*(pcid+1),4,BIT_MASK_4)+16*GET_BIT(*(pcid+2),0,BIT_MASK_4) + 2000;
+ }
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_AnalysisSCR
+*
+* DESCRIPTION
+* Analysis SD Card Configuration Register and store in the member of gSD
+*
+* PARAMETERS
+* scr: input of scr for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* Only for SD card.
+*
+*************************************************************************/
+void SD_AnalysisSCR_2(kal_uint32* scr)
+{
+ kal_uint8 *pscr;
+
+ pscr = (kal_uint8*)scr;
+ gSD2->mSCR.spec_ver = (kal_uint8)GET_BIT(*(pscr),0,BIT_MASK_4);
+ if(gSD2->mSCR.spec_ver > SD_SPEC_101)
+ gSD2->flags |= SD_FLAG_CMD6_SUPPORT;
+ gSD2->mSCR.dat_after_erase = (kal_uint8)GET_BIT(*(pscr+1),7,BIT_MASK_1);
+ gSD2->mSCR.security = (kal_uint8)GET_BIT(*(pscr+1),4,BIT_MASK_3);
+ gSD2->mSCR.bus_width = (kal_uint8)GET_BIT(*(pscr+1),0,BIT_MASK_4);
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_WaitCmdRdyOrTo
+*
+* DESCRIPTION
+* Wait until command ready or timeout
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitCmdRdyOrTo_2(void)
+{
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+
+ {
+ volatile kal_uint16 sdc_cmdsta;
+ kal_uint32 t1;
+
+ t1 = drv_get_current_time();
+ while(!(sdc_cmdsta = MSDC_Reg(SDC_CMDSTA2))
+ && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_CMD*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ }
+ MSDC_STOP_TIMER2();
+ MSDC_CLR_INT2();
+ msdc2_handle->cmd_sta = sdc_cmdsta;
+ if(sdc_cmdsta & SDC_CMDSTA_CMDTO)
+ {
+ kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:cmd timeout");
+ return ERR_CMD_TIMEOUT;
+ }
+ else if(sdc_cmdsta & SDC_CMDSTA_RSPCRCERR)
+ {
+ kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:cmd crc");
+ return ERR_CMD_RSPCRCERR;
+ }
+ else if(sdc_cmdsta & SDC_CMDSTA_CMDRDY)
+ return NO_ERROR;
+ }
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_WaitDatRdyOrTo_2
+*
+* DESCRIPTION
+* Wait until data ready or timeout
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitDatRdyOrTo_2(void)
+{
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+
+
+ {
+ volatile kal_uint16 sdc_datsta;
+ kal_uint32 t1;
+
+ t1 = drv_get_current_time();
+ while(!(sdc_datsta = MSDC_Reg(SDC_DATSTA2))
+ && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ };
+ MSDC_STOP_TIMER2();
+ MSDC_CLR_INT2();
+ msdc2_handle->dat_sta = sdc_datsta;
+ if(sdc_datsta & SDC_DATSTA_DATTO)
+ {
+ kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:dat timeout");
+ return ERR_DAT_TIMEOUT;
+ }
+ else if(sdc_datsta & SDC_DATSTA_DATCRCERR)
+ {
+ kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:dat crc");
+ return ERR_DAT_CRCERR;
+ }
+ else if(sdc_datsta & SDC_DATSTA_BLKDONE)
+ return NO_ERROR;
+ }
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_WaitCardNotBusy_2
+*
+* DESCRIPTION
+* Wait until card is not busy (R1b)
+*
+* PARAMETERS
+*
+* RETURNS
+* void
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+
+SDC_CMD_STATUS SD_WaitCardNotBusy_2(void)
+{
+ kal_uint32 t1;
+
+ t1 = drv_get_current_time();
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+#ifdef MSDC_USE_INT
+ {
+ kal_uint32 flags = 0;
+ if(!msdc2_handle->mIsPresent)
+ return;
+ kal_retrieve_eg_events(msdc2_handle->MSDC_Events,EVENT_SDR1BIRQ,KAL_AND_CONSUME,&flags,KAL_SUSPEND);
+ }
+#else
+ {
+ while(SD_IS_R1B_BUSY_2 && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ };
+ MSDC_CLR_INT2();
+ MSDC_STOP_TIMER2();
+ }
+#endif
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_CheckStatus_2
+*
+* DESCRIPTION
+* Check command status
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_CheckStatus_2()
+{
+ kal_uint32 status;
+
+ MSDC_LSD_ReadReg32(SDC_RESP02,&status);
+ if(status & SDC_CSTA_MASK)
+ ASSERT(0);
+ if((status & SDC_CSTA_MASK)==0 )
+ return NO_ERROR;
+ if(status &SDC_CARD_IS_LOCKED)
+ return CARD_IS_LOCKED;
+
+ return ERR_STATUS;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Send_Cmd_2
+*
+* DESCRIPTION
+* to launch the command packet to the card
+*
+* PARAMETERS
+* 1. cmd: the content of SDC_CMD register
+* 2. arg: the argument(if the command need no argument, fill it with 0)
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* 1. Check if controller is available before launch any commands
+* 2. Maybe add check if card is busy (R1b)
+*************************************************************************/
+SDC_CMD_STATUS SD_Send_Cmd_2(kal_uint32 cmd, kal_uint32 arg)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 t1;
+
+ t1 = drv_get_current_time();
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+ // check the controller is ready (stop transaction will fail)
+ if(cmd != SDC_CMD_CMD12)
+ {
+ while(SD_IS_SDC_BUSY_2 && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ }
+ }
+ else
+ {
+ while(SD_IS_CMD_BUSY_2 && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ }
+ }
+ MSDC_STOP_TIMER2();
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+
+ MSDC_CLR_INT2();
+ // fill out the argument
+ MSDC_LSD_WriteReg32(SDC_ARG2,arg);
+ // launch the command
+ MSDC_LSD_WriteReg32(SDC_CMD2,cmd);
+ if((status = SD_WaitCmdRdyOrTo_2())!=NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Reset
+*
+* DESCRIPTION
+* reset all cards to idle state
+*
+* PARAMETERS
+* 1. cmd: the content of SDC_CMD register
+* 2. arg: the argument(if the command need no argument, fill it with 0)
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Reset_2(void)
+{
+ SDC_CMD_STATUS status;
+
+ status = SD_Send_Cmd_2(SDC_CMD_CMD0,SDC_NO_ARG);
+ gSD2->mState = IDLE_STA;
+
+ return status;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Cmd55_2
+*
+* DESCRIPTION
+* APP_CMD: inidicate to the card that the next command is an application specified command
+* rather than a standard command
+*
+* PARAMETERS
+* rca: relative card address
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Cmd55_2(kal_uint16 rca)
+{
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD55,(kal_uint32)rca<<16))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+ //check APP_CMD bit in status register
+ MSDC_LSD_ReadReg32(SDC_RESP02,&status);
+ if(status & SDC_CSTA_MASK)
+ ASSERT(0);
+ if(!(status & R1_APP_CMD_5))
+ return ERR_APPCMD_FAILED;
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_Cmd8
+*
+* DESCRIPTION
+* 1. Sends SD Memory Card interface conditions for support larger than 2G cards
+* 2. check if the card is compliant to SD2.0 or higher
+* 3. only performed while at IDLE state.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD2->mIsCMD8
+*
+*************************************************************************/
+void SD_Cmd8_2(void)
+{
+ kal_uint32 resp;
+
+ if(SD_Send_Cmd_2(SDC_CMD_CMD8,SDC_CMD8_ARG)!=NO_ERROR)
+ {
+ SD_Reset_2();
+ gSD2->mCMD8Resp = SD_CMD8_RESP_NORESP;
+ return;
+ }
+ MSDC_LSD_ReadReg32(SDC_RESP02,&resp);
+ if(resp == SDC_CMD8_ARG)
+ gSD2->mCMD8Resp = SD_CMD8_RESP_VALID;
+ else
+ gSD2->mCMD8Resp = SD_CMD8_RESP_INVALID;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Cmd1_MMC
+*
+* DESCRIPTION
+* asks all cards in idle state to send their OCR in the response on the CMD line
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* only works for MMC
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Cmd1_MMC_2(void)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 _ocr, ocr_i, t1, t2;
+
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD2->mCMD8Resp == SD_CMD8_RESP_INVALID)
+ return ERR_CMD8_INVALID;
+ ocr_i = (SDC_OCR_DEFAULT|MMC_HIGH_DESITY_CHECK_BIT);
+ #else
+ ocr_i = SDC_OCR_DEFAULT;
+ #endif
+
+ if(msdc2_handle->is_init_timeout == KAL_TRUE)
+ return ERR_R3_OCR_BUSY;
+ t2 = drv_get_current_time();
+ do{
+ t1 = drv_get_current_time();
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+ while((MSDC_IS_BUSY2)
+ && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ };
+ MSDC_STOP_TIMER2();
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+ MSDC_LSD_WriteReg32(SDC_ARG2,ocr_i);
+ MSDC_LSD_WriteReg32(SDC_CMD2,SDC_CMD_CMD1);
+ if((status = SD_WaitCmdRdyOrTo_2()) != NO_ERROR)
+ {
+ return status;
+ }
+ MSDC_LSD_ReadReg32(SDC_RESP02, &_ocr);
+ if((_ocr & SDC_OCR_DEFAULT) == 0)
+ return ERR_OCR_NOT_SUPPORT;
+ if(!msdc2_handle->mIsPresent)
+ return MSDC_CARD_NOT_PRESENT;
+
+ if(!(_ocr&SDC_OCR_BUSY))
+ {
+ if(drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+ {
+ msdc2_handle->is_init_timeout = KAL_TRUE;
+ break;
+ }
+ if((kal_query_systemInit() == KAL_TRUE)
+#ifdef __TST_WRITE_TO_FILE_ONLY__ /*error recording: considering error recording additionally*/
+ || (KAL_TRUE == INT_QueryExceptionStatus())
+#endif
+ )
+ MSDC_GPTI_BusyWait(30);
+ else
+ kal_sleep_task(7);
+
+ }
+ else
+ break;
+ }while(1);
+
+ if(msdc2_handle->is_init_timeout)
+ return ERR_CMD_TIMEOUT;
+
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if((_ocr & MMC_HIGH_DESITY_CHECK_MSK) == MMC_HIGH_DESITY_CHECK_BIT)
+ {
+ gSD2->flags |= SD_FLAG_HCS_SUPPORT;
+ msdc2_handle->mMSDC_type = MMC42_CARD;
+ tst_sys_trace("MMC4.2 or higher");
+ }
+ else
+ #endif
+ msdc2_handle->mMSDC_type = MMC_CARD;
+ gSD2->mInactive = KAL_FALSE;
+ gSD2->mSDC_ocr = _ocr;
+ gSD2->mState = READY_STA;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Acmd41_SD
+*
+* DESCRIPTION
+* asks all cards in idle state to send their OCR in the response on the CMD line
+* OCR: Operation Condition Register
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* only works for SD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Acmd41_SD_2(void)
+{
+
+ SDC_CMD_STATUS status;
+ kal_uint32 _ocr = 0, ocr_i, t1, t2;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD2->mCMD8Resp == SD_CMD8_RESP_NORESP)
+ ocr_i = SDC_OCR_DEFAULT;
+ else if(gSD2->mCMD8Resp == SD_CMD8_RESP_VALID)
+ ocr_i = (SDC_OCR_DEFAULT|SD_ACMD41_HCS);
+ else if(gSD2->mCMD8Resp == SD_CMD8_RESP_INVALID)
+ return ERR_CMD8_INVALID;
+#else
+ ocr_i = SDC_OCR_DEFAULT;
+#endif
+
+ msdc2_handle->is_init_timeout = KAL_FALSE;
+ t2 = drv_get_current_time();
+ do{
+ t1 = drv_get_current_time();
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+ while((MSDC_IS_BUSY2)
+ && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_CMD*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ };
+ MSDC_STOP_TIMER2();
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+ status=SD_Cmd55_2(SDC_RCA_DEFAULT);
+ if(status != NO_ERROR)
+ {
+ return status;
+ }
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+ t1 = drv_get_current_time();
+ while((MSDC_IS_BUSY2)
+ && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_CMD*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ };
+ MSDC_STOP_TIMER2();
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+ MSDC_LSD_WriteReg32(SDC_ARG2,ocr_i);
+ MSDC_LSD_WriteReg32(SDC_CMD2,SDC_CMD_CMD41_SD);
+ if((status = SD_WaitCmdRdyOrTo_2()) != NO_ERROR)
+ {
+ return status;
+ }
+ MSDC_LSD_ReadReg32(SDC_RESP02, &_ocr);
+ if((_ocr & SDC_OCR_DEFAULT) == 0)
+ return ERR_OCR_NOT_SUPPORT;
+ if(!msdc2_handle->mIsPresent)
+ return ERR_CARD_NOT_PRESENT;
+ if(!(_ocr&SDC_OCR_BUSY))
+ {
+ if(drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+ {
+ #ifdef DRV_LSD
+ LSD_ASSERT(0, __LINE__);
+ #endif
+ msdc2_handle->is_init_timeout = KAL_TRUE;
+ break;
+ }
+ if((kal_query_systemInit() == KAL_TRUE)
+#ifdef __TST_WRITE_TO_FILE_ONLY__ /*error recording: considering error recording additionally*/
+ || (KAL_TRUE == INT_QueryExceptionStatus())
+#endif
+ )
+ MSDC_GPTI_BusyWait(30);
+ else
+ kal_sleep_task(7);
+ }
+ else
+ break;
+ }
+ while(1);
+
+ if(msdc2_handle->is_init_timeout)
+ return ERR_R3_OCR_BUSY;
+
+ gSD2->mInactive = KAL_FALSE;
+ gSD2->mSDC_ocr = _ocr;
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ gSD2->flags |= SD_FLAG_SD_TYPE_CARD;
+ if(_ocr & SD_ACMD41_HCS)
+ {
+ gSD2->flags |= SD_FLAG_HCS_SUPPORT;
+ msdc2_handle->mMSDC_type = SD20_HCS_CARD;
+ tst_sys_trace("SD2.0 or higher");
+ }
+ else if(gSD2->mCMD8Resp == SD_CMD8_RESP_VALID)
+ msdc2_handle->mMSDC_type = SD20_LCS_CARD;
+ else
+ #endif
+ msdc2_handle->mMSDC_type = SD_CARD;
+ gSD2->mState = READY_STA;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_GetCID
+*
+* DESCRIPTION
+* Read Card Identification.
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+*
+*
+*************************************************************************/
+
+// Get CID(CMD2)
+SDC_CMD_STATUS SD_GetCID_2(kal_uint32 Cid[4])
+{
+ int i;
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD2,SDC_NO_ARG))!=NO_ERROR)
+ return status;
+ //read R2
+ for(i=0;i<4;i++)
+ MSDC_LSD_ReadReg32((SDC_RESP02+i*sizeof(kal_uint32)), &Cid[i]);
+ SD_AnalysisCID_2(Cid);
+ gSD2->mState = IDENT_STA;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_ValidateRCA
+*
+* DESCRIPTION
+* assing or read RCA
+*
+* PARAMETERS
+* pRca: used for input or output RCA
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* RCA is assinged to MMC card fixed to SDC_RCA_MMC(1)
+*
+*************************************************************************/
+
+// assign or read RCA
+SDC_CMD_STATUS SD_ValidateRCA_2(kal_uint16* pRca)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 resp;
+ kal_uint8 state;
+
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD2->flags & SD_FLAG_SD_TYPE_CARD )
+ #else
+ if(msdc2_handle->mMSDC_type == SD_CARD)
+ #endif
+ {
+ //read RCA form card
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD3_SD,SDC_NO_ARG))!=NO_ERROR)
+ return status;
+ //read R6
+ MSDC_LSD_ReadReg32(SDC_RESP02, &resp);
+ *pRca = resp >> 16;
+ gSD2->mRCA =*pRca;
+
+ }
+ else
+ {
+ //assign RCA to card
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD3_MMC,(kal_uint32)SDC_RCA_MMC<<16))!=NO_ERROR)
+ return status;
+
+ //read R1
+ MSDC_LSD_ReadReg32(SDC_RESP02, &resp);
+ SD_GetStatus_2(SDC_RCA_MMC,&resp);
+ state = 0;
+ GetBitFieldN((kal_uint8*)&state,(kal_uint8*)&resp,9,4);
+ if(STBY_STA != state)
+ return ERR_RCA_FAIL;
+ *pRca = gSD2->mRCA = SDC_RCA_MMC;
+ }
+
+ gSD2->mState = STBY_STA;
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SetDSR
+*
+* DESCRIPTION
+* set default value to the DSR
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* SDC_DSR_DEFAULT(0x404)
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetDSR_2(void)
+{
+ return SD_Send_Cmd_2(SDC_CMD_CMD4,(kal_uint32)SDC_DSR_DEFAULT<<16);
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SelectCard
+*
+* DESCRIPTION
+* select/deselect card
+*
+* PARAMETERS
+* rca: relative card address
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SelectCard_2(kal_uint16 rca)
+{
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD7,(kal_uint32)rca<<16))!=NO_ERROR)
+ return status;
+
+ //read R1b
+ if((status = SD_WaitCardNotBusy_2())!=NO_ERROR)
+ return status;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_GetCSD
+*
+* DESCRIPTION
+* Get CSD from addressed card
+*
+* PARAMETERS
+* rca: relative card address
+* Csd: used for containing read CSD
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_GetCSD_2(kal_uint16 rca, kal_uint32 Csd[4])
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 i;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD9,(kal_uint32)rca<<16))!=NO_ERROR)
+ return status;
+ for(i=0;i<4;i++)
+ {
+ MSDC_LSD_ReadReg32((volatile kal_uint32 *)(SDC_RESP02+i*4), &Csd[i]);
+ }
+ SD_AnalysisCSD_2(Csd);
+
+ return NO_ERROR;
+}
+
+// addressed send CID
+SDC_CMD_STATUS SD_GetAddressedCID_2(kal_uint16 rca, kal_uint32 Cid[4])
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 i;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD10,(kal_uint32)rca<<16))!=NO_ERROR)
+ return status;
+ for(i=0;i<4;i++)
+ {
+ MSDC_LSD_ReadReg32((volatile kal_uint32 *)(SDC_RESP02+i*4), &Cid[i]);
+ }
+ return NO_ERROR;
+}
+
+
+/*************************************************************************
+* FUNCTION
+* SD_StopTrans_2
+*
+* DESCRIPTION
+* Stop Muli-Block operation
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* definition of SD_STOP_SLOW is used for some erroneous card
+*************************************************************************/
+SDC_CMD_STATUS SD_StopTrans_2(kal_bool isTx)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 retry = 0;
+
+ while(retry < 30)
+ {
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD12,SDC_NO_ARG))!=NO_ERROR)
+ {
+ retry ++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if(retry >= 30)
+ {
+ return status;
+ }
+ if(isTx)
+ SD_WaitCardNotBusy_2();
+
+
+#ifdef SD_STOP_SLOW
+ while(MSDC_Reg(SDC_STA2) & SDC_STA_R1BSY);
+ do{
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&status);
+ }while((status & R1_CUR_STATE) >> 9 != TRAN_STA);
+#endif
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_GetStatus_2
+*
+* DESCRIPTION
+* addressed send status
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_GetStatus_2(kal_uint16 rca, kal_uint32* resp)
+{
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD13,(kal_uint32)rca <<16))!=NO_ERROR)
+ return status;
+
+ MSDC_LSD_ReadReg32(SDC_RESP02,resp);
+ if((*resp) & SDC_CSTA_MASK)
+ ASSERT(0);
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SetBlength_2
+*
+* DESCRIPTION
+* set block length
+*
+* PARAMETERS
+* BKLength: block length u want to set
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD2->mBKLength
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetBlength_2(kal_uint32 BKLength)
+{
+ SDC_CMD_STATUS status;
+
+ // maximal value of block length is 2048
+ if(BKLength > SDC_MAX_BKLENGTH)
+ return ERR_INVALID_BKLENGTH;
+ if(!gSD2->mCSD.r_blk_part && BKLength < gSD2->mCSD.max_r_blk_len )
+ return ERR_INVALID_BKLENGTH;
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD16,BKLength))!=NO_ERROR)
+ return status;
+ //read R1
+ status = SD_CheckStatus_2();
+ // 2. configure the controller
+ gSD2->mBKLength = BKLength;
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,BKLength,SDC_CFG_BLKLEN);
+
+ return NO_ERROR;
+}
+
+
+/*************************************************************************
+* FUNCTION
+* SD_ReadSingleBlock
+*
+* DESCRIPTION
+* 1. read a single block form data_adrs of card to the rxbuffer
+* 2. the block length is set by set block length
+*
+* PARAMETERS
+* data_adrs: starting address to read
+* rxbuffer: as name
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* the size of rxbuffer should be 4*n (n : integer)
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadSingleBlock_2(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+ kal_uint32 count;
+ SDC_CMD_STATUS status;
+
+
+ EnableMSDC_DMA2();
+ count = MSDC_SD_BLOCK_SIZE;
+ MSDC_DMATransferFirst2((kal_uint32)rxbuffer,count,KAL_FALSE);
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD17,data_adrs))!=NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto ERR_Exit;
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ {
+ goto ERR_Exit;
+ }
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+
+ DisableMSDC_DMA2();
+ MSDC_CLR_FIFO2();
+
+ return NO_ERROR;
+ERR_Exit:
+ {
+ kal_uint32 tmp;
+
+ #ifdef MSDC_USE_INT
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+ #endif
+ DisableMSDC_DMA2();
+ RESET_MSDC2();
+
+ // SD_StopTrans_2(KAL_FALSE);
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA2,&tmp);
+ MSDC_CLR_FIFO2();
+ return status;
+ }
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_ReadMultiBlock
+*
+* DESCRIPTION
+* read num of blocks into rxbuffer
+*
+* PARAMETERS
+* data_adrs: starting address to read
+* rxbuffer: as name
+* num: number of blocks to read
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadMultiBlock_2(kal_uint32 data_adrs, kal_uint32* rxbuffer, kal_uint32 num)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 j, count;
+ #ifndef MSDC_DMA
+ kal_uint32 i;
+ #endif
+
+ EnableMSDC_DMA2();
+ count = MSDC_SD_BLOCK_SIZE;
+ MSDC_DMATransferFirst2((kal_uint32)rxbuffer,count*num,KAL_FALSE);
+ #ifndef DRV_LSD
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD18,data_adrs))!=NO_ERROR)
+ #else
+ LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD18|(num<<20) ,data_adrs))!=NO_ERROR)
+ #endif
+ goto ERR_Exit;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto ERR_Exit;
+ count = MSDC_SD_BLOCK_SIZE;
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+
+
+ MSDC_CLR_INT2();
+ DisableMSDC_DMA2();
+
+ if(gSD2->flags & SD_FLAG_MMC_MRSW_FAIL)
+ {
+ kal_uint32 delay = 200;
+ while(delay--);
+ }
+ if((status = SD_StopTrans_2(KAL_FALSE))!=NO_ERROR)
+ {
+ //if((data_adrs/gSD2->mBKLength + j) < gSD2->mBKNum)
+ goto ERR_Exit;
+ }
+ MSDC_CLR_FIFO2();
+ return NO_ERROR;
+
+ERR_Exit:
+
+ #ifdef MSDC_USE_INT
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+ #endif
+ DisableMSDC_DMA2();
+ RESET_MSDC2();
+ SD_StopTrans_2(KAL_FALSE);
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&j);
+ MSDC_LSD_ReadReg32(SDC_DATSTA2,&j);
+ MSDC_CLR_FIFO2();
+ return status;
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_WriteSingleBlock
+*
+* DESCRIPTION
+* write a single block
+*
+* PARAMETERS
+* address: starting address to write
+* txbuffer: as name
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* block length is set by Set_Block_Length
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WriteSingleBlock_2(kal_uint32 address, kal_uint32* txbuffer)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 count;
+ kal_uint32 *ptr;
+#if defined(MT6225)
+ kal_bool is_aligned;
+ ECO_VERSION eco;
+ eco = INT_ecoVersion();
+#endif
+
+ if(gSD2->mWPEnabled)
+ return ERR_WRITE_PROTECT;
+ EnableMSDC_DMA2();
+ count = MSDC_SD_BLOCK_SIZE;
+
+ #if defined(MT6225)
+ if(eco <= ECO_E3)
+ {
+ is_aligned = ((kal_uint32)txbuffer%4 == 0);
+ if(is_aligned)
+ {
+ ptr = txbuffer;
+ }
+ else
+ {
+ kal_mem_cpy(MSDC_Sector2, txbuffer, 512);
+ ptr = MSDC_Sector2;
+ }
+ }
+ else
+ {
+ ptr = txbuffer;
+ }
+ #else
+ ptr = txbuffer;
+ #endif
+
+ EnableMSDC_DMA2();
+ count = MSDC_SD_BLOCK_SIZE;
+ MSDC_DMATransferFirst2((kal_uint32)ptr,count,KAL_TRUE);
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD24,address))!=NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto ERR_Exit;
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitCardNotBusy_2())!=NO_ERROR)
+ goto ERR_Exit;
+ DisableMSDC_DMA2();
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+
+
+ return NO_ERROR;
+ERR_Exit:
+ {
+ kal_uint32 tmp;
+
+ #ifdef MSDC_USE_INT
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+ #endif
+ DisableMSDC_DMA2();
+ RESET_MSDC2();
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA2,&tmp);
+ return status;
+ }
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_WriteMultiBlock
+*
+* DESCRIPTION
+* write num blocks starting at address
+*
+* PARAMETERS
+* address: starting address to write
+* txbuffer: as name
+* num: number of blocks to write
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* block length is set by Set_Block_Length
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WriteMultiBlock_2(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 count;
+ kal_uint32 *ptr;
+ #if defined(MT6225)
+ kal_bool is_aligned, dma_issue;
+ ECO_VERSION eco;
+ eco = INT_ecoVersion();
+ if(eco <= ECO_E3)
+ dma_issue = KAL_TRUE;
+ #endif
+
+ if(gSD2->mWPEnabled)
+ return ERR_WRITE_PROTECT;
+ EnableMSDC_DMA2();
+ count = MSDC_SD_BLOCK_SIZE;
+ #if defined(MT6225)
+ if(dma_issue)
+ {
+ is_aligned = ((kal_uint32)txbuffer%4 == 0);
+ if(is_aligned)
+ {
+ MSDC_DMATransferFirst2((kal_uint32)txbuffer,count*num,KAL_TRUE);
+ }
+ else
+ {
+ kal_mem_cpy(MSDC_Sector2, txbuffer, 512);
+ ptr = txbuffer;
+ MSDC_DMATransferFirst2((kal_uint32)MSDC_Sector2,count,KAL_TRUE);
+ }
+ }
+ else
+ {
+ MSDC_DMATransferFirst2((kal_uint32)txbuffer,count*num,KAL_TRUE);
+ }
+ #elif defined(MSDC_MULTI_BLOCK_WRITE)
+ MSDC_DMATransferFirst2((kal_uint32)txbuffer,count*num,KAL_TRUE);
+ #else
+ ptr = txbuffer;
+ MSDC_DMATransferFirst2((kal_uint32)ptr,count,KAL_TRUE);
+ #endif
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD25,address))!=NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto ERR_Exit;
+
+ #if defined(MT6225)
+ if(dma_issue)
+ {
+ if(is_aligned)
+ {
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+ }
+ else
+ {
+ kal_uint32 j;
+
+ for(j=0;j<num;j++)
+ {
+ if(msdc2_handle->mIsPresent == KAL_FALSE)
+ {
+ status = ERR_CARD_NOT_PRESENT;
+ goto ERR_Exit;
+ }
+ if(j!=0)
+ {
+ kal_mem_cpy(MSDC_Sector2, ptr, 512);
+ MSDC_DMATransferFirst2((kal_uint32)MSDC_Sector2,count,KAL_TRUE);
+ }
+ status = MSDC_DMATransferFinal2();
+ ptr += MSDC_SD_BLOCK_SIZE;
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+ }
+ }
+ }
+ else
+ {
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+ }
+ #elif defined(MSDC_MULTI_BLOCK_WRITE)
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+ #else // not MT6225
+ {
+ kal_uint32 j;
+
+ for(j=0;j<num;j++)
+ {
+ if(msdc2_handle->mIsPresent == KAL_FALSE)
+ {
+ status = ERR_CARD_NOT_PRESENT;
+ goto ERR_Exit;
+ }
+ if(j!=0)
+ {
+ MSDC_DMATransferFirst2((kal_uint32)ptr,count,KAL_TRUE);
+ }
+ status = MSDC_DMATransferFinal2();
+ ptr += MSDC_SD_BLOCK_SIZE;
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+ }
+
+ }
+ #endif // MT6225
+
+ DisableMSDC_DMA2();
+ if((status = SD_StopTrans_2(KAL_TRUE))!=NO_ERROR)
+ goto ERR_Exit;
+
+ MSDC_CLR_INT2();
+
+ return NO_ERROR;
+ERR_Exit:
+ {
+ kal_uint32 tmp;
+
+ DisableMSDC_DMA2();
+ RESET_MSDC2();
+ SD_StopTrans_2(KAL_TRUE);
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA2,&tmp);
+ return status;
+ }
+
+}
+/*************************************************************************
+* FUNCTION
+* SD_SetBusWidth
+*
+* DESCRIPTION
+* ACMD6: set the data width 00 for 1 bit, 10 for 4 bits
+*
+* PARAMETERS
+* width: indicate the bus width
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Not every card support 4-bits bus
+* only for SD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetBusWidth_2(SD_BITWIDTH width)
+{
+ SDC_CMD_STATUS status;
+
+ // check if card support 4 bits bus
+ if((width == BIT_4W) && !(gSD2->mSCR.bus_width&0x04))
+ return ERR_NOT_SUPPORT_4BITS;
+ // send APP_CMD
+ if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+ return status;
+ // send cmd6
+ if((status = SD_Send_Cmd_2(SDC_CMD_ACMD6,width))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+ // set the controler MDLEN to enalbe 4bits bus width
+ MSDC_LSD_SetBits32(SDC_CFG2,SDC_CFG_MDLEN);
+ gSD2->bus_width = 4;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_ReadSCR
+*
+* DESCRIPTION
+* ACMD51: read the SD Configuration Register(8bytes block read)
+*
+* PARAMETERS
+* scr: used for store SCR
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Make sure the size of SCR is 8 bytes
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadSCR_2(kal_uint32* scr)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 blklen,i, t1;
+
+ ASSERT((kal_uint32)scr % 4 == 0);
+ // save the original block length
+ blklen = gSD2->mBKLength;
+ // set block length(MSDC_CFG2)
+ if((status = SD_SetBlength_2(8))!=NO_ERROR)
+ return status;
+ // send APP_CMD
+ if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+ return status;
+ // send command
+ if((status = SD_Send_Cmd_2(SDC_CMD_ACMD51,SDC_NO_ARG))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+ // read data(8bytes)
+#ifndef DRV_LSD
+ // failed to use DMA with burst mode
+ t1 = drv_get_current_time();
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+ for(i=0;i<2;)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ if(!msdc2_handle->mIsPresent)
+ return ERR_CARD_NOT_PRESENT;
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+ if(!MSDC_IS_FIFO_EMPTY2)
+ {
+ *(kal_uint32*)(scr+i) = MSDC_Reg32(MSDC_DAT2);
+ i++;
+ }
+ }
+#else
+ LSD_readFIFO(scr ,2);
+
+#endif
+ MSDC_STOP_TIMER2();
+ // analysis scr
+ SD_AnalysisSCR(scr);
+ // clean EVENT_SDDATIRQ
+ #ifdef MSDC_USE_INT
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+ #endif
+ MSDC_CLR_FIFO2();
+ return NO_ERROR;
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SetPreEraseBlk
+*
+* DESCRIPTION
+* ACMD23: set the number of write blocksto be pre-erased before writing
+* used for faster multiple Block Write
+*
+* PARAMETERS
+* num: used for storing number of blocks during multi-block operation
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetPreEraseBlk_2(kal_uint32 num)
+{
+ SDC_CMD_STATUS status;
+
+ //[22:0] number of blocks
+ num &= 0x003FFF;
+ // send APP_CMD
+ if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+ return status;
+ // send CMD23
+ if((status = SD_Send_Cmd_2(SDC_CMD_ACMD23,num))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_EraseCmdClass
+*
+* DESCRIPTION
+* groups of erase commands including CMD32 ~CMD38
+*
+* PARAMETERS
+* cmd: indicate which command to execute
+* address: starting address wiht write protection
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* CMD34~CMD37 are only for MMC
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_EraseCmdClass_2(kal_uint32 cmd ,kal_uint32 address)
+{
+ SDC_CMD_STATUS status;
+
+ if(cmd != SDC_CMD_CMD38)
+ {
+ if((status = SD_Send_Cmd_2(cmd,address))!=NO_ERROR)
+ return status;
+ }
+ else if((status = SD_Send_Cmd_2(cmd,SDC_NO_ARG))!=NO_ERROR)
+ return status;
+
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+
+ if(cmd == SDC_CMD_CMD38)
+ {
+ SD_WaitCardNotBusy_2();
+ do{
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&status);
+ if(msdc2_handle->mIsPresent == KAL_FALSE)
+ break;
+ }while(CurState(status)!= TRAN_STA);
+ }
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_Switch_MMC40
+*
+* DESCRIPTION
+* CMD6: set the command set or write to the EXT_CSD (for MMC4.0)
+*
+* PARAMETERS
+* access: access mode
+* index: index to EXT_CSD
+* value: value to write to EXT_CSD
+* set: selected command set
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Switch_MMC40_2(kal_uint8 access, kal_uint8 index, kal_uint8 value, kal_uint8 set)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 arg = 0;
+
+ arg = (access<<24)|(index<<16)|(value<<8)|set;
+ // send command
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD6_MMC40,arg))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SendEXTCSD_MMC40
+*
+* DESCRIPTION
+* CMD8: read the content of EXT_CSD register
+*
+* PARAMETERS
+* kal: access mode
+* index: index to EXT_CSD
+* value: value to write to EXT_CSD
+* set: selected command set
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SendEXTCSD_MMC40_2(kal_uint32* rxbuffer)
+{
+ SDC_CMD_STATUS status;
+ kal_bool retry_4bit = KAL_FALSE;
+
+start:
+ // read the block of 512 bytes (make sure the rxbuffer is 4 byte aligned)
+ EnableMSDC_DMA2();
+ MSDC_DMATransferFirst2((kal_uint32)rxbuffer,128,KAL_FALSE);
+#ifdef DRV_LSD
+ LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+#endif
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD8_MMC40,SDC_NO_ARG))!=NO_ERROR)
+ goto ERR_Exit;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto ERR_Exit;
+ // read the block of 512 bytes (make sure the rxbuffer is 4 byte aligned)
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+
+ DisableMSDC_DMA2();
+ MSDC_CLR_FIFO2();
+ gSD2->mCSD.ext_csd = (T_EXT_CSD_MMC40 *)rxbuffer;
+ return NO_ERROR;
+
+ERR_Exit:
+
+ if(retry_4bit == KAL_FALSE)
+ {
+ retry_4bit = KAL_TRUE;
+ MSDC_LSD_SetBits32(SDC_CFG2,SDC_CFG_MDLEN);
+ gSD2->bus_width = 4;
+ goto start;
+ }
+ MSDC_LSD_ClearBits32(SDC_CFG2,SDC_CFG_MDLEN);
+ gSD2->bus_width = 1;
+ DisableMSDC_DMA2();
+ MSDC_CLR_FIFO2();
+ RESET_MSDC2();
+
+ return status;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Switch_SD11
+*
+* DESCRIPTION
+* CMD6: switch command to query and select the specific functions. (SD1.1 or later)
+* PARAMETERS
+* arg: argument
+* resp: buffer to contain the ther 64 bytes status information
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Switch_SD11_2(kal_uint32 arg, T_SWITCH_STATUS* info)
+{
+ SDC_CMD_STATUS status = NO_ERROR;
+
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,SD_CMD6_RESP_LEN,SDC_CFG_BLKLEN);
+ EnableMSDC_DMA2();
+ MSDC_DMATransferFirst2((kal_uint32)info,(SD_CMD6_RESP_LEN>>2),KAL_FALSE);
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD6_SD11,arg))!=NO_ERROR)
+ goto exit;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto exit;
+ status = MSDC_DMATransferFinal2();
+
+exit:
+ DisableMSDC_DMA2();
+ return status;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Switch_SD11
+*
+* DESCRIPTION
+* Enable the high speed interface to support up to 50M Hz clock
+*
+* PARAMETERS
+* arg: argument
+* resp: buffer to contain the ther 64 bytes status information
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SelectHighSpeed_SD11_2(void)
+{
+ SDC_CMD_STATUS status;
+ T_SWITCH_STATUS *p = (T_SWITCH_STATUS*)MSDC_Sector2;
+
+ if((status = SD_Switch_SD11(SD_CMD6_QUERY_HIGH_SPEED, p))!=NO_ERROR)
+ return status;
+ if(p->max_current == 0)
+ return ERR_SD_HS_FAIL;
+ if((p->group1_info & (1 << SD_FUNC_HIGH_SPEED)) &&
+ (p->group1_result == SD_FUNC_HIGH_SPEED))
+ {
+ if((status = SD_Switch_SD11(SD_CMD6_SELECT_HIGH_SPEED, p))!=NO_ERROR)
+ return status;
+ if(p->max_current == 0)
+ return ERR_SD_HS_FAIL;
+ if(p->group1_result == SD_FUNC_HIGH_SPEED)
+ gSD2->flags |= SD_FLAG_HS_SUPPORT;
+ }
+ else
+ return ERR_SD_HS_FAIL;
+
+
+ return NO_ERROR;
+}
+
+kal_bool MSDC_ModuleTest_Report_2(void)
+{
+ return msdc2_handle->mIsInitialized;
+}
+
+#endif // defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/sd_adap.c b/mcu/driver/storage/mc/src/sd_adap.c
new file mode 100644
index 0000000..2fc5fd6
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sd_adap.c
@@ -0,0 +1,343 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2007
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * sd_adap.c
+ *
+ * Project:
+ * --------
+ * Maui
+ *
+ * Description:
+ * ------------
+ * MSDC/SD driver adaption layer
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#ifdef __EMMC_BOOTING__
+
+#include "sd_adap.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "dcl.h"
+
+#if defined(__UBL__) || defined(__FUE__)
+#include <bl_MTK_BB_REG.H>
+#else
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#endif
+
+
+/*** external data & function ***/
+
+
+/*** internal data & function ***/
+
+static SDC_CMD_STATUS DRV_SD_AddrLookupTbl(unsigned int sector, emmc_addr *addr);
+
+/*** external function body ***/
+
+DRV_STATUS_CODE DRV_SD_Init(void)
+{
+#if (defined(__UBL__) || defined(__FUE__)) && defined(MT6256_S00)
+ // enable GPIO for MSDC
+ //DRV_WriteReg16(0x701D0610, 0x1110);
+ //DRV_WriteReg16(0x701D0620, 0x0111);
+ DRV_WriteReg16(GPIO_base+0x0610, 0x1110);
+ DRV_WriteReg16(GPIO_base+0x0620, 0x0111);
+ // enable GPT3
+ //DRV_WriteReg32(0x7007001C, 1);
+ DRV_WriteReg32(GPT_base+0x001C, 1);
+
+#endif
+
+#if !defined(DCL_MSDC_INTERFACE)
+ MSDC_Initialize();
+#else
+ DclSD_Initialize();
+#endif//!defined(DCL_MSDC_INTERFACE)
+
+ return DRV_SUCCESS;
+}
+
+DRV_STATUS_CODE DRV_SD_DeInit(void)
+{
+ MSDC_DeInit();
+
+ // reset GPIO to disable MSDC
+
+ return DRV_SUCCESS;
+}
+
+DRV_STATUS_CODE DRV_SD_MountDevice(
+ mcdev_enum id,
+ unsigned int flags
+ )
+{
+ SDC_CMD_STATUS status = NO_ERROR;
+ status = MountDevice(GetMsdcHandle(id), 0, 0, flags);
+ if (512 != status)
+ return DRV_MOUNT_DEV_FAILURE;
+
+ return DRV_SUCCESS;
+}
+
+DRV_STATUS_CODE DRV_SD_ReadSectors(
+ mcdev_enum id,
+ unsigned int sector,
+ unsigned int sectors,
+ void * buffer,
+ unsigned int flags
+ )
+{
+ SDC_CMD_STATUS status = NO_ERROR;
+ emmc_addr addr;
+
+ get_MSDC_lock(&gSD->mSDdrv_lock);
+
+ status = DRV_SD_AddrLookupTbl(sector, &addr);
+ if (NO_ERROR != status)
+ {
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+ return DRV_READ_FAILURE;
+ }
+
+ if (KAL_TRUE != SD_eMMC_ECSD_setCurrentPart(addr.partition))
+ {
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+ return DRV_READ_FAILURE;
+ }
+
+#if defined(DRV_MSDC_BLOCKING_TRANSFER_SUPPORT)
+ status = ReadSectors(GetMsdcHandle(id), addr.offset, sectors, buffer, SD_FLAG_BLOCKING_TRANSFER);
+#else
+ status = ReadSectors(GetMsdcHandle(id), addr.offset, sectors, buffer);
+#endif
+ if (NO_ERROR != status)
+ {
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+ return DRV_READ_FAILURE;
+ }
+
+ if (KAL_TRUE != SD_eMMC_ECSD_setCurrentPart(eMMC_user_Area))
+ {
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+ return DRV_READ_FAILURE;
+ }
+
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+ return DRV_SUCCESS;
+}
+
+//! under construction [Samuel, 2010/10/01]
+DRV_STATUS_CODE DRV_SD_WriteSectors(
+ mcdev_enum id,
+ unsigned int sector,
+ unsigned int sectors,
+ void * buffer,
+ unsigned int flags
+ )
+{
+ SDC_CMD_STATUS status = NO_ERROR;
+ emmc_addr addr;
+
+//#if !defined(__UBL__) && !defined(__FUE__)
+// ASSERT(0); // so far this function can only be used in bootloader
+//#endif
+
+ get_MSDC_lock(&gSD->mSDdrv_lock);
+
+ status = DRV_SD_AddrLookupTbl(sector, &addr);
+ if (NO_ERROR != status)
+ {
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+ return DRV_WRITE_FAILURE;
+ }
+
+ if (KAL_TRUE != SD_eMMC_ECSD_setCurrentPart(addr.partition))
+ {
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+ return DRV_WRITE_FAILURE;
+ }
+
+ status = WriteSectors(GetMsdcHandle(id), addr.offset, sectors, buffer);
+ if (NO_ERROR != status)
+ {
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+ return DRV_WRITE_FAILURE;
+ }
+
+ //! TODO: check why it fails
+ if (KAL_TRUE != SD_eMMC_ECSD_setCurrentPart(eMMC_user_Area))
+ {
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+ return DRV_WRITE_FAILURE;
+ }
+
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+ return DRV_SUCCESS;
+}
+
+/*** internal function body ***/
+
+//! 1st designed for eMMC
+static SDC_CMD_STATUS DRV_SD_AddrLookupTbl(unsigned int sector, emmc_addr *addr)
+{
+ if (gSD->emmc_info.isEmmcV44 == KAL_FALSE)
+ return ERR_INVALID_CARD;
+
+ if (sector >= (gSD->emmc_info.bootPartitionSize + gSD->emmc_info.gp1PartitionSize))
+ return ERR_INVALID_BLOCK; // out-of-range
+
+ if (sector < gSD->emmc_info.bootPartitionSize)
+ {
+ addr->partition = eMMC_boot_partition1;
+ addr->offset = sector;
+ }
+ else
+ {
+ addr->partition = eMMC_GP_partition1;
+ addr->offset = sector - gSD->emmc_info.bootPartitionSize;
+ }
+
+ return DRV_SUCCESS;
+}
+
+#endif//__EMMC_BOOTING__
+
+
+
+#ifdef __CARD_DOWNLOAD__
+
+#include "msdc_adap_bl.h"
+#include "drv_comm.h"
+#include "msdc_def.h"
+
+/*** external data & function ***/
+
+extern FS_Driver FS_SdDrv;
+
+/*** function body ***/
+
+int BL_MSDC_Init(void)
+{
+ // enable GPIO for MSDC
+ DRV_SetBits(0x80021800, 0x5540);
+ DRV_SetBits(0x80021900, 0x55);
+
+ MSDC_Initialize();
+
+ return 0;
+}
+
+int BL_MSDC_DeInit(void)
+{
+ MSDC_DeInit();
+
+ // reset GPIO to disable MSDC
+ DRV_ClearBits(0x80021800, 0x5540);
+ DRV_ClearBits(0x80021900, 0x55);
+
+ return 0;
+}
+
+int BL_MSDC_MountDevice(int DeviceNumber, int DeviceType, unsigned int Flags)
+{
+ return FS_SdDrv.MountDevice((void*)&MSDC_Blk[0], DeviceNumber, DeviceType, Flags);
+}
+
+int BL_MSDC_ReadSectors(unsigned int Sector, unsigned int Sectors, void * Buffer)
+{
+ return FS_SdDrv.ReadSectors((void*)&MSDC_Blk[0], Sector, Sectors, Buffer);
+}
+
+int BL_MSDC_GetDiskGeometry(FS_PartitionRecord * DiskGeometry, BYTE * MediaDescriptor)
+{
+ return FS_SdDrv.GetDiskGeometry((void*)&MSDC_Blk[0], DiskGeometry, MediaDescriptor);
+}
+
+int BL_MSDC_GetCardPSN(unsigned int *psn)
+{
+ FS_DeviceInfo info;
+ FS_SdDrv.IOCtrl((void*)&MSDC_Blk[0], FS_IOCTRL_QUERY_CARD_INFO, &info);
+
+ *psn = info.DeviceInfo.Card.PSN;
+
+ return 0;
+}
+
+#endif//__CARD_DOWNLOAD__
+
diff --git a/mcu/driver/storage/mc/src/sd_drv.c b/mcu/driver/storage/mc/src/sd_drv.c
new file mode 100644
index 0000000..cd52c95
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sd_drv.c
@@ -0,0 +1,3668 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * ms_drv.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * Adaption driver of file system for SD card
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include "drv_features.h"
+#ifndef DRV_MSDC_OFF
+//RHR ADD
+#include "kal_public_defs.h"
+//#include "btif_sw.h"
+#include "kal_public_api.h"
+#include "kal_debug.h"
+#include "drv_msgid.h"
+//RHR REMOVE
+/*
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//MSBB remove #include "kal_non_specific_general_types.h"
+//MSBB remove #include "app_buff_alloc.h"
+#include "fat_fs.h"
+#if defined(__MSDC_MS__)
+#include "ms_def.h"
+#endif
+#include "init.h"
+*/
+//RHR
+#include "kal_trace.h"
+#include "kal_general_types.h"
+#include "fs_errcode.h"
+#include "fs_iprot.h"
+#include "drv_comm.h"
+#include "drv_features.h"
+#include "drvpdn.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#if !defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+#include "msdc_reg_adap.h"
+#include "reg_base.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "intrCtrl.h"
+#include "msdc_lsd.h"
+#include "drv_trc.h"
+#if defined(__AUDIO_DSP_LOWPOWER__)
+#include "audlp_exp.h"
+#endif
+
+#include "cache_sw.h"
+#include "qmu_bm.h"
+
+//! EMB
+#include "init.h"
+
+#ifdef DCL_MSDC_INTERFACE
+#include "dcl.h"
+#endif
+#if defined(MSDC_TRACE_LEVEL3)
+#define __DRV_MSDC_DEBUG_PERF_MEASURE__
+#endif
+//#define __CMMB_CAS_FULL_CARD_SUPPORT__
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+#include "cas_drv.h"
+#endif
+
+#ifdef DRV_LSD
+//#define LSD_SINGLE_READ
+//#define LSD_SINGLE_WRITE
+/*to test where card consumes power whenever it is in transfer state*/
+//#define TEST_TRANSFER_STATE_CONSUME_POWER
+#endif
+
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON1
+#error "__CLKG_DEFINE__ & DRVPDN_CON1 are all defined"
+#else
+#define DRVPDN_CON1 CG_CON1
+#endif
+
+#ifdef DRVPDN_CON1_SIM
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SIM are all defined"
+#else
+#define DRVPDN_CON1_SIM CG_CON1_SIM
+#endif
+
+#ifndef MSDC_TEST_MSDC2_FROM_MSDC1_CODE
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC CG_CON1_MSDC
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR CG_CLR1
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET CG_SET1
+#endif
+
+#else /*when MSDC_TEST_MSDC2_FROM_MSDC1_CODE is defined, we direct CON1 related macro to CON0 related*/
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR CG_CLR0
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET CG_SET0
+#endif
+#endif//MSDC_TEST_MSDC2_FROM_MSDC1_CODE
+
+#endif
+
+#if defined(__MSDC_SD_MMC__)
+
+#define MAX_CLUSTERS (0x0FFF6 - 2)
+#define MSDC_MEDIA_DESCRIPTOR 0xF8
+#define SD_MAX_RETRY 2
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+kal_semid dualMsdcArb;
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+kal_semid dclMsdcArb;
+typedef struct{
+ kal_uint32 callerRetAddr;
+ kal_uint32 ownerThdId;
+} SD_ARB_DBG;
+static SD_ARB_DBG sdArbDbg;
+#endif
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+static kal_bool isFullCard;
+#endif
+
+#ifdef DRV_MSDC_2_DLT_FOR_RD_WR
+#define MSDC_DLT_NOT_TESTED 0xFFFFFFFF
+#define MSDC_RED_DLT_INVALID 0xFFFFFFFF
+#endif
+
+extern kal_bool INT_USBBoot(void);
+extern void SLA_CustomLogging(kal_char *customJob, kal_int32 saAction);
+
+#ifdef __DRV_MSDC_ENHANCE_FORMAT_BY_ERASE__
+kal_bool useEraseOnFormat = KAL_TRUE;
+#else
+kal_bool useEraseOnFormat = KAL_FALSE;
+#endif
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+// for read operation performance measurement
+kal_uint64 gMSDC_perf_block_read_freq[5] = {0, 0, 0, 0, 0};
+kal_uint64 gMSDC_perf_block_read_time[5] = {0, 0, 0, 0, 0};
+// for write operation performance measurement
+kal_uint64 gMSDC_perf_block_write_freq[5] = {0, 0, 0, 0, 0};
+kal_uint64 gMSDC_perf_block_write_time[5] = {0, 0, 0, 0, 0};
+#endif
+
+#if defined(__DEMAND_PAGING__) && !defined(__FUE__) && !defined(__UBL__)
+#define DEMP_LOCK(addr, size) \
+ demp_lock_pages(DEMP_LOCK_EMMC, (kal_uint32)addr, size)
+#define DEMP_UNLOCK(addr, size) \
+ demp_unlock_pages(DEMP_LOCK_EMMC, (kal_uint32)addr, size)
+#else
+#define DEMP_LOCK(addr, size)
+#define DEMP_UNLOCK(addr, size)
+#endif
+#if defined(DCL_MSDC_INTERFACE)
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+/*
+ 2008/12/16
+ sd driver was protected under file system, and now we have to share the resource with CAS CMD and SDIO
+ we have implemented new architecture by DCL ways, but DCL haven't been QC and
+ maybe dangerous to enable it in 08B. We adopt SIM driver's method to import new control interface without the
+ change of file system.
+*/
+
+int MountDevice(void * DriveData, int DeviceNumber, int DeviceType, kal_uint32 Flags);
+
+#ifdef DRV_MSDC_HW_CONTENTION
+void SD_setArbRetAddr(kal_uint32 retAddr)
+{
+ sdArbDbg.callerRetAddr = retAddr;
+}
+
+void SD_setArbThdId(kal_uint32 ThdId)
+{
+ sdArbDbg.ownerThdId = ThdId;
+}
+#endif
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+#define SD_FULL_CARD_DEBUG_BUF_SIZE (1024*32)
+kal_uint32 SD_casTxDebugBuffer[SD_FULL_CARD_DEBUG_BUF_SIZE];
+kal_uint32 SD_casRxDebugBuffer[SD_FULL_CARD_DEBUG_BUF_SIZE];
+kal_uint32 SD_casCmdState = 0;
+
+
+void SD_setFullCard(kal_bool cardType)
+{
+ isFullCard = cardType;
+}
+
+#endif
+
+int ReadSectors_NEW(void * DriveData, kal_uint32 Sector, UINT Sectors, void * Buffer)
+{
+ int status;
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+sd_select_enum sel;
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+ kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+ /* RVCT doesn't support inline assemlber; bypass temporarily */
+ retAddr = 0;
+#else /* __RVCT__ */
+ /* get the return address */
+ __asm {
+ MOV retAddr,lr
+ }
+#endif /* __RVCT__ */
+
+ if(NULL == dclMsdcArb)
+ ASSERT(0);
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*must gain resource here before calling ReadSectors*/
+ kal_take_sem(dclMsdcArb, 1);
+ SD_setArbRetAddr(retAddr);
+ SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+ }
+
+#endif//DRV_MSDC_HW_CONTENTION
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_take_sem(dualMsdcArb, 1);
+ }
+#endif//DRV_MSDC_HW_CONTENTION
+
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+ #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+ #endif
+ }
+ get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+ #else
+ get_MSDC_lock(&gSD->mSDdrv_lock);
+ #endif
+
+ /*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+ MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+ MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+ status = ReadSectors(DriveData, Sector, Sectors, Buffer);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+ if(2 == SD_casCmdState && FS_NO_ERROR == status){/*previous command is CAS write*/
+ if(4 == Sector) /*CAS read command*/
+ SD_casCmdState *= 3;
+ else/*FS read interleaved in CAS command, backup result*/
+ {
+ kal_mem_cpy(SD_casRxDebugBuffer, Buffer, (((SD_FULL_CARD_DEBUG_BUF_SIZE) < (Sectors * 512)) ? (SD_FULL_CARD_DEBUG_BUF_SIZE) : (Sectors * 512)));
+ }
+ }
+
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+ SD_setArbThdId(NULL);
+ kal_give_sem(dclMsdcArb);
+ }
+#endif
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_give_sem(dualMsdcArb);
+ }
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+ return status;
+
+}
+
+#if defined(__UBL__)
+#pragma arm section code = "EXT_BOOTLOADER_CODE", rwdata = "EXT_BOOTLOADER_RW", zidata = "EXT_BOOTLOADER_ZI"
+#endif
+
+static int WriteSectors_NEW(void * DriveData, kal_uint32 Sector, UINT Sectors, void * Buffer)
+{
+ int status;
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ #endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+ kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+ /* RVCT doesn't support inline assemlber; bypass temporarily */
+ retAddr = 0;
+#else /* __RVCT__ */
+ /* get the return address */
+ __asm {
+ MOV retAddr,lr
+ }
+#endif /* __RVCT__ */
+
+ if(NULL == dclMsdcArb)
+ ASSERT(0);
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*must gain resource here before calling WriteSectors*/
+ kal_take_sem(dclMsdcArb, 1);
+ SD_setArbRetAddr(retAddr);
+ SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+ }
+#endif//DRV_MSDC_HW_CONTENTION
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_take_sem(dualMsdcArb, 1);
+ }
+#endif
+ /*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+ MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+ MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+ if(M_CAM_CAS_HANDLE == (kal_uint32)DriveData) /*if CAS command, set debug state to 1*/
+ SD_casCmdState = 1;
+ else if(2 == SD_casCmdState)/*if FS command and debug state = 2, record the information*/
+ {
+ kal_mem_cpy(SD_casTxDebugBuffer, Buffer, (((SD_FULL_CARD_DEBUG_BUF_SIZE) < (Sectors * 512)) ? (SD_FULL_CARD_DEBUG_BUF_SIZE) : (Sectors * 512)));
+ }
+
+#endif
+
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+ #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+ #endif
+ }
+ get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+ #else
+ get_MSDC_lock(&gSD->mSDdrv_lock);
+ #endif
+
+ /*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+ MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+ MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+
+ status = WriteSectors(DriveData, Sector, Sectors, Buffer);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+ if (FS_NO_ERROR == status)
+ SD_casCmdState *= 2;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_give_sem(dualMsdcArb);
+ }
+#endif
+#ifdef DRV_MSDC_HW_CONTENTION
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+ SD_setArbThdId(NULL);
+ kal_give_sem(dclMsdcArb);
+ }
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+ return status;
+
+}
+
+#if defined(__UBL__)
+#pragma arm section code, rwdata, zidata
+#endif
+
+int MountDevice_NEW(void * DriveData, int DeviceNumber, int DeviceType, kal_uint32 Flags)
+{
+ int status;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+#endif
+
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+ kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+ /* RVCT doesn't support inline assemlber; bypass temporarily */
+ retAddr = 0;
+#else /* __RVCT__ */
+ /* get the return address */
+ __asm {
+ MOV retAddr,lr
+ }
+#endif /* __RVCT__ */
+
+ if(NULL == dclMsdcArb)
+ dclMsdcArb = kal_create_sem("MSDC lock", 1);
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*must gain resource here before calling MountDevice*/
+ kal_take_sem(dclMsdcArb, 1);
+ SD_setArbRetAddr(retAddr);
+ SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+ }
+#endif//DRV_MSDC_HW_CONTENTION
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_take_sem(dualMsdcArb, 1);
+ }
+#endif
+
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+ #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+ #endif
+ }
+ init_MSDC_lock(&gSD_blk[0].mSDdrv_lock, "SD_DRV_LOCK");
+ get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+ init_MSDC_lock(&gSD->mSDdrv_lock, "SD_DRV_LOCK");
+ get_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+
+ /*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+ MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+ MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+ status = MountDevice(DriveData, DeviceNumber, DeviceType, Flags);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_give_sem(dualMsdcArb);
+ }
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+ SD_setArbThdId(NULL);
+ kal_give_sem(dclMsdcArb);
+ }
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+ return status;
+
+}
+kal_uint32 Get_BDStructNum(void)
+{
+ return MSDC_BD_MAX;
+}
+int Gpd_ReadSectors(void * DriveData, kal_uint32 Sector, UINT Sectors, qbm_gpd *head,qbm_gpd *tail)
+{
+ kal_uint8 retry = 0,single_line=0;
+ DCL_STATUS dclStatus = 0;
+ SD_CTRL_GPD_READ_T data;
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ kal_uint32 time1,time2;
+#endif
+
+ DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+ DCL_BOOL isCardExist = KAL_FALSE;
+ DCL_BOOL isCardInited = KAL_FALSE;
+ DCL_BOOL isFFRunning = KAL_FALSE;
+#if defined(DRV_MSDC_RETRY_DLT_IN_READ_ERR)
+ kal_uint32 ClkFactor;
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+#if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+#endif
+ }
+
+ if(sel==SD_EXT)
+ {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_READ_SECTOR_ERROR;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_READ_SECTOR_ERROR;
+ #else
+ ASSERT(0);
+ #endif
+ }
+ prSwitch.u4TargetInterface=sel;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+ #else
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if(dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_READ_SECTOR_ERROR;
+#endif
+
+
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ if (!isCardExist)
+ {
+ DclSD_Close(dclHandle);
+ return FS_MSDC_MOUNT_ERROR;
+ }
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+
+ #if 0
+/* under construction !*/
+/* under construction !*/
+ #endif
+
+#ifdef __DRV_MSDC_FAST_FORMAT__
+/*since there is no readSectors command enclosed in fast format, this flag should be always flase when we do readSectors*/
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_FAST_FORMAT_RUNNING, (DCL_CTRL_DATA_T*)&isFFRunning);
+ if ((DCL_BOOL)KAL_TRUE == isFFRunning)
+ ASSERT(0);
+#endif
+
+ gMSDC_Handle->timeout_count = 0;
+ gMSDC_Handle->dataCrcError_count = 0;
+
+ //retry ++;
+ do{
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ time1 = drv_get_current_time();
+ MD_TRC_MSDC_INFORM_READSECTOR_START(time1, retry, gSD->sd_r, MSDC_Reg32(MSDC_IOCON));
+#endif
+
+ MSDC_SLA_Start_Logging("GPR");
+
+ data.bufferHead = head;
+ data.bufferTail = tail;
+ data.u4Sector = Sector;
+ data.u4Sectors = Sectors;
+ dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_GPD_READ, (DCL_CTRL_DATA_T*)&data);
+ //if (dclStatus == STATUS_ERROR_WRONG_STATE)
+ //{
+ // DclSD_Close(dclHandle);
+ // return FS_MSDC_MOUNT_ERROR;
+ //}
+
+ MSDC_SLA_Stop_Logging("GPR");
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ time2 = drv_get_current_time();
+ MD_TRC_MSDC_INFORM_READSECTOR_END(dclStatus, time2,\
+ (kal_uint32)kal_get_current_thread_ID(), (double)(Sectors*32768*5)/((time2-time1)*10));
+#endif
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+// for read operation performance measurement
+ switch (Sectors)
+ {
+ case 1:
+ gMSDC_perf_block_read_freq[0] += Sectors;
+ gMSDC_perf_block_read_time[0] += (time2-time1);
+ break;
+ case 2:
+ gMSDC_perf_block_read_freq[1] += Sectors;
+ gMSDC_perf_block_read_time[1] += (time2-time1);
+ break;
+ case 3:
+ case 4:
+ gMSDC_perf_block_read_freq[2] += Sectors;
+ gMSDC_perf_block_read_time[2] += (time2-time1);
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ gMSDC_perf_block_read_freq[3] += Sectors;
+ gMSDC_perf_block_read_time[3] += (time2-time1);
+ break;
+ default:// Sector > 8
+ gMSDC_perf_block_read_freq[4] += Sectors;
+ gMSDC_perf_block_read_time[4] += (time2-time1);
+ break;
+ }
+#endif
+
+ if(dclStatus != STATUS_OK )
+ {
+ if(kal_query_systemInit()== KAL_TRUE)
+ {
+ /*12/26, Blue remove this to enable read retry in booting up*/
+ #if defined(MSDC_TRACE_LEVEL3)
+ MSDC_add_dbg_msg(msdc_dbg_event_SD_read_fail_systemInit, dclStatus, gSD->sd_r);
+ #endif
+ //MSDC_PDNControl(KAL_TRUE);
+ //return FS_MSDC_READ_SECTOR_ERROR;
+ }
+
+ if (dclStatus ==STATUS_ERROR_CRCERROR)
+ {
+
+ if((gMSDC_Handle->op_clock / 2) >= gMSDC_Handle->msdc_clkTuneUpperBund)
+ {
+ gMSDC_Handle->op_clock = gMSDC_Handle->op_clock / 2;
+ MSDC_ERR("[MSDC]Read(GPD) CRC Error, reduce Bus Clock\r\n");
+ MSDC_SetClock(gMSDC_Handle->op_clock,KAL_FALSE);
+ }
+ else
+ {
+ MSDC_ERR("[MSDC]Read(GPD) CRC Error, try single line\r\n");
+
+ if (gMSDC_Handle->trySingleLine == NO_SINGLE_LINE&&single_line==0)
+ {
+ gMSDC_Handle->trySingleLine = TEMP_SINGLE_LINE;
+ single_line=1;
+ }
+ else
+ {
+ dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+ break;
+ }
+ DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+
+ if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK)
+ {
+ dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+ break;
+ }
+ }
+ }
+ else if (dclStatus==STATUS_ERROR_TIMEOUT)
+ {
+
+ if (retry++ >=3)
+ {
+ dclStatus= FS_MSDC_READ_SECTOR_ERROR;
+ break;
+ }
+ MSDC_ERR("[MSDC][%s]Timeout Error, retry count<%d>\r\n",__FUNCTION__,retry);
+
+ //gMSDC_Handle->mIsInitialized = KAL_FALSE;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+
+ if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK) {
+ dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+ break;
+ }
+ }
+ else
+ {
+
+ break;
+ }
+ } // end of if error
+
+ } while(dclStatus != STATUS_OK);
+
+//#if defined(MSDC_CACHED_SUPPORT_WRITE_THROUGH_SERIES) && !defined(__UBL__)
+// invalidate_wt_cache((kal_uint32)Buffer, 512 * Sectors);
+//#endif
+
+ DclSD_Close(dclHandle);
+ //return FS_NO_ERROR;
+ return dclStatus;
+}
+int Gpd_WriteSectors(void * DriveData, kal_uint32 Sector, UINT Sectors, qbm_gpd *head,qbm_gpd *tail)
+{
+ //SDC_CMD_STATUS status;
+ kal_uint8 retry = 0,single_line=0;
+ //kal_uint32 adrs;
+ DCL_STATUS dclStatus = 0;
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ kal_uint32 time1,time2;
+#endif
+
+ SD_CTRL_GPD_WRITE_T data;
+ DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+ //kal_uint32 timeout_count = 0;
+ DCL_BOOL isCardExist = DCL_FALSE;
+ DCL_BOOL isCardInited = KAL_FALSE;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+ //Need check this line !!!!!!!!!!!!!!!!!!!
+ // DEMP_LOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+#if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+#endif
+ }
+
+ if(sel==SD_EXT)
+ {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_WRITE_SECTOR_ERROR;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_WRITE_SECTOR_ERROR;
+ #else
+ ASSERT(0);
+ #endif
+ }
+ prSwitch.u4TargetInterface=sel;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+ #else
+
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if(dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_WRITE_SECTOR_ERROR;
+#endif
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+
+ #if 0
+/* under construction !*/
+/* under construction !*/
+ #endif
+
+if(!isCardExist)
+{
+ DclSD_Control(dclHandle, SD_CTRL_CMD_POLL_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ if(!isCardExist)
+ {
+ DclSD_Close(dclHandle);
+ return FS_MSDC_MOUNT_ERROR;
+ }
+}
+
+ gMSDC_Handle->timeout_count = 0;
+ do{
+ retry++;
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ time1 = drv_get_current_time();
+ MD_TRC_MSDC_INFORM_WRITESECTOR_START(time1, retry, gSD->sd_w, 0);
+#endif
+
+ MSDC_SLA_Start_Logging("GPW");
+
+ data.bufferHead = head;
+ data.bufferTail = tail;
+ data.u4Sector = Sector;
+ data.u4Sectors = Sectors;
+ dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_GPD_WRITE, (DCL_CTRL_DATA_T*)&data);
+ //if (dclStatus == STATUS_ERROR_WRONG_STATE)
+ //{
+ // DclSD_Close(dclHandle);
+ // DEMP_UNLOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+ // return FS_MSDC_WRITE_SECTOR_ERROR;
+ //}
+
+ MSDC_SLA_Stop_Logging("GPW");
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ time2 = drv_get_current_time();
+ MD_TRC_MSDC_INFORM_WRITESECTOR_END(dclStatus, time2,
+ (kal_uint32)kal_get_current_thread_ID(), (double)(Sectors*32768*5)/((time2-time1)*10));
+#endif
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+// for write operation performance measurement
+ switch (Sectors)
+ {
+ case 1:
+ gMSDC_perf_block_write_freq[0] += Sectors;
+ gMSDC_perf_block_write_time[0] += (time2-time1);
+ break;
+ case 2:
+ gMSDC_perf_block_write_freq[1] += Sectors;
+ gMSDC_perf_block_write_time[1] += (time2-time1);
+ break;
+ case 3:
+ case 4:
+ gMSDC_perf_block_write_freq[2] += Sectors;
+ gMSDC_perf_block_write_time[2] += (time2-time1);
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ gMSDC_perf_block_write_freq[3] += Sectors;
+ gMSDC_perf_block_write_time[3] += (time2-time1);
+ break;
+ default:// Sector > 8
+ gMSDC_perf_block_write_freq[4] += Sectors;
+ gMSDC_perf_block_write_time[4] += (time2-time1);
+ break;
+ }
+#endif
+
+ if(dclStatus != STATUS_OK)
+ {
+ if(kal_query_systemInit()== KAL_TRUE)
+ {
+ /*12/26, Blue remove this to enable read retry in booting up*/
+ #if defined(MSDC_TRACE_LEVEL3)
+ MSDC_add_dbg_msg(msdc_dbg_event_SD_read_fail_systemInit, dclStatus, gSD->sd_r);
+ #endif
+ //MSDC_PDNControl(KAL_TRUE);
+ //return FS_MSDC_READ_SECTOR_ERROR;
+ }
+
+ if (dclStatus ==STATUS_ERROR_CRCERROR)
+ {
+
+ if((gMSDC_Handle->op_clock / 2) >= gMSDC_Handle->msdc_clkTuneUpperBund)
+ {
+ gMSDC_Handle->op_clock = gMSDC_Handle->op_clock / 2;
+ MSDC_ERR("[MSDC]Write(GPD) CRC Error, reduce Bus Clock\r\n");
+ MSDC_SetClock(gMSDC_Handle->op_clock,KAL_FALSE);
+ }
+ else
+ {
+ MSDC_ERR("[MSDC]Write(GPD) CRC Error, try single line\r\n");
+
+ if (gMSDC_Handle->trySingleLine == NO_SINGLE_LINE&&single_line==0)
+ {
+ gMSDC_Handle->trySingleLine = TEMP_SINGLE_LINE;
+ single_line=1;
+ }
+ else
+ {
+ dclStatus=FS_MSDC_WRITE_SECTOR_ERROR;
+ break;
+ }
+ DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+
+ if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK)
+ {
+ dclStatus = FS_MSDC_WRITE_SECTOR_ERROR;
+ break;
+ }
+ }
+ }
+ else if (dclStatus==STATUS_ERROR_TIMEOUT)
+ {
+ if (retry++ >=3)
+ {
+ dclStatus = FS_MSDC_WRITE_SECTOR_ERROR;
+ break;
+ }
+ MSDC_ERR("[MSDC][%s]Timeout Error, retry count<%d>\r\n",__FUNCTION__,retry);
+
+ //gMSDC_Handle->mIsInitialized = KAL_FALSE;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+
+ if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK) {
+ dclStatus = FS_MSDC_WRITE_SECTOR_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }while(dclStatus!=STATUS_OK);
+ DclSD_Close(dclHandle);
+ //DEMP_UNLOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+ return dclStatus;
+}
+
+int Gpd_ReadSectors_NEW(void * DriveData, kal_uint32 Sector, UINT Sectors,qbm_gpd *head,qbm_gpd *tail)
+{
+ int status;
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+sd_select_enum sel;
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+ kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+ /* RVCT doesn't support inline assemlber; bypass temporarily */
+ retAddr = 0;
+#else /* __RVCT__ */
+ /* get the return address */
+ __asm {
+ MOV retAddr,lr
+ }
+#endif /* __RVCT__ */
+
+ if(NULL == dclMsdcArb)
+ ASSERT(0);
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*must gain resource here before calling ReadSectors*/
+ kal_take_sem(dclMsdcArb, 1);
+ SD_setArbRetAddr(retAddr);
+ SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+ }
+
+#endif//DRV_MSDC_HW_CONTENTION
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_take_sem(dualMsdcArb, 1);
+ }
+#endif//DRV_MSDC_HW_CONTENTION
+
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+ #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+ #endif
+ }
+ get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+ #else
+ //get_MSDC_lock(&gSD->mSDdrv_lock);
+ #endif
+
+ /*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+ MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+ MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+ status = Gpd_ReadSectors(DriveData, Sector, Sectors, head,tail);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+ //free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_give_sem(dualMsdcArb);
+ }
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+ return status;
+}
+int Gpd_WriteSectors_NEW(void * DriveData, kal_uint32 Sector, UINT Sectors, qbm_gpd *head,qbm_gpd *tail)
+{
+ int status;
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ #endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+ kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+ /* RVCT doesn't support inline assemlber; bypass temporarily */
+ retAddr = 0;
+#else /* __RVCT__ */
+ /* get the return address */
+ __asm {
+ MOV retAddr,lr
+ }
+#endif /* __RVCT__ */
+
+ if(NULL == dclMsdcArb)
+ ASSERT(0);
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*must gain resource here before calling WriteSectors*/
+ kal_take_sem(dclMsdcArb, 1);
+ SD_setArbRetAddr(retAddr);
+ SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+ }
+#endif//DRV_MSDC_HW_CONTENTION
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_take_sem(dualMsdcArb, 1);
+ }
+#endif
+ /*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+ MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+ MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+ #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+ #endif
+ }
+ get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+ #else
+ //get_MSDC_lock(&gSD->mSDdrv_lock);
+ #endif
+
+ /*switch related control*/
+#ifdef DRV_MSDC_SHARE_BY_SWITCH
+ MSDC_backupHwSetting();
+#endif
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+ MSDC_Switch_SDIO(SD_EXT);
+#endif
+
+
+ status = Gpd_WriteSectors(DriveData, Sector, Sectors,head,tail);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+ //free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+ if (FS_NO_ERROR == status)
+ SD_casCmdState *= 2;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_give_sem(dualMsdcArb);
+ }
+#endif
+#ifdef DRV_MSDC_HW_CONTENTION
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+ SD_setArbThdId(NULL);
+ kal_give_sem(dclMsdcArb);
+ }
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+ return status;
+}
+
+static int DiscardSectors(void * DriveData, kal_uint32 Sector, UINT Sectors)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+ return FS_NO_ERROR;
+}
+
+/*-----------------------------------*/
+int ReadSectors(void * DriveData, kal_uint32 Sector, UINT Sectors, void * Buffer)
+{
+ kal_uint8 retry = 0,single_line=0;
+ DCL_STATUS dclStatus = 0;
+ SD_CTRL_READ_T data;
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ kal_uint32 time1,time2;
+#endif
+
+ DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+ DCL_BOOL isCardExist = KAL_FALSE;
+ DCL_BOOL isCardInited = KAL_FALSE;
+ DCL_BOOL isFFRunning = KAL_FALSE;
+#if defined(DRV_MSDC_RETRY_DLT_IN_READ_ERR)
+ kal_uint32 ClkFactor;
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+#if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+#endif
+ }
+
+ if(sel==SD_EXT)
+ {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_READ_SECTOR_ERROR;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_READ_SECTOR_ERROR;
+ #else
+ ASSERT(0);
+ #endif
+ }
+ prSwitch.u4TargetInterface=sel;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+ #else
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if(dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_READ_SECTOR_ERROR;
+#endif
+
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ if (!isCardExist)
+ {
+ DclSD_Close(dclHandle);
+ return FS_MSDC_MOUNT_ERROR;
+ }
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+ MD_TRC_MSDC_INFORM_READSECTOR_ENTRY((kal_uint32)DriveData, Sector, Sectors, (kal_uint32)Buffer, \
+ (kal_uint32)kal_get_current_thread_ID(), MSDC_Reg32(MSDC_CFG), isCardExist, isCardInited);
+
+#ifdef __DRV_MSDC_FAST_FORMAT__
+/*since there is no readSectors command enclosed in fast format, this flag should be always flase when we do readSectors*/
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_FAST_FORMAT_RUNNING, (DCL_CTRL_DATA_T*)&isFFRunning);
+ if ((DCL_BOOL)KAL_TRUE == isFFRunning)
+ ASSERT(0);
+#endif
+
+ gMSDC_Handle->timeout_count = 0;
+ gMSDC_Handle->dataCrcError_count = 0;
+
+ //retry ++;
+ do{
+
+ #ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ time1 = drv_get_current_time();
+ MD_TRC_MSDC_INFORM_READSECTOR_START(time1, retry, gSD->sd_r, MSDC_Reg32(MSDC_IOCON));
+ #endif
+
+ MSDC_SLA_Start_Logging("BFR");
+
+ data.bufferAddr = Buffer;
+ data.u4Sector = Sector;
+ data.u4Sectors = Sectors;
+ dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_READ, (DCL_CTRL_DATA_T*)&data);
+ //if (dclStatus == STATUS_ERROR_WRONG_STATE)
+ //{
+ // DclSD_Close(dclHandle);
+ // return FS_MSDC_MOUNT_ERROR;
+ //}
+
+ MSDC_SLA_Stop_Logging("BFR");
+
+ #ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ time2 = drv_get_current_time();
+ MD_TRC_MSDC_INFORM_READSECTOR_END(dclStatus, time2,\
+ (kal_uint32)kal_get_current_thread_ID(), (double)(Sectors*32768*5)/((time2-time1)*10));
+ #endif
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+// for read operation performance measurement
+ switch (Sectors)
+ {
+ case 1:
+ gMSDC_perf_block_read_freq[0] += Sectors;
+ gMSDC_perf_block_read_time[0] += (time2-time1);
+ break;
+ case 2:
+ gMSDC_perf_block_read_freq[1] += Sectors;
+ gMSDC_perf_block_read_time[1] += (time2-time1);
+ break;
+ case 3:
+ case 4:
+ gMSDC_perf_block_read_freq[2] += Sectors;
+ gMSDC_perf_block_read_time[2] += (time2-time1);
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ gMSDC_perf_block_read_freq[3] += Sectors;
+ gMSDC_perf_block_read_time[3] += (time2-time1);
+ break;
+ default:// Sector > 8
+ gMSDC_perf_block_read_freq[4] += Sectors;
+ gMSDC_perf_block_read_time[4] += (time2-time1);
+ break;
+ }
+#endif
+
+ if(dclStatus != STATUS_OK )
+ {
+ if(kal_query_systemInit()== KAL_TRUE)
+ {
+ /*12/26, Blue remove this to enable read retry in booting up*/
+ #if defined(MSDC_TRACE_LEVEL3)
+ MSDC_add_dbg_msg(msdc_dbg_event_SD_read_fail_systemInit, dclStatus, gSD->sd_r);
+ #endif
+ //MSDC_PDNControl(KAL_TRUE);
+ //return FS_MSDC_READ_SECTOR_ERROR;
+ }
+
+ if (dclStatus ==STATUS_ERROR_CRCERROR)
+ {
+
+ if((gMSDC_Handle->op_clock / 2) >= gMSDC_Handle->msdc_clkTuneUpperBund)
+ {
+ gMSDC_Handle->op_clock = gMSDC_Handle->op_clock / 2;
+ MSDC_ERR("[MSDC]Read CRC Error, reduce Bus Clock\r\n");
+ MSDC_SetClock(gMSDC_Handle->op_clock,KAL_FALSE);
+ }
+ else
+ {
+ MSDC_ERR("[MSDC]Read CRC Error, try single line\r\n");
+ if (gMSDC_Handle->trySingleLine == NO_SINGLE_LINE&&single_line==0)
+ {
+ gMSDC_Handle->trySingleLine = TEMP_SINGLE_LINE;
+ single_line=1;
+ }
+ else
+ {
+ dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+ break;
+ }
+ DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+
+ if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK)
+ {
+ dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+ break;
+ }
+ }
+ }
+ else if (dclStatus==STATUS_ERROR_TIMEOUT)
+ {
+
+ if (retry++ >=3)
+ {
+ dclStatus= FS_MSDC_READ_SECTOR_ERROR;
+ break;
+ }
+ MSDC_ERR("[MSDC][%s]Timeout Error, retry,count<%d>\r\n",__FUNCTION__,retry);
+
+ //gMSDC_Handle->mIsInitialized = KAL_FALSE;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+
+ if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK) {
+ dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ } // end of if error
+
+ } while(dclStatus != STATUS_OK);
+
+#if defined(MSDC_CACHED_SUPPORT_WRITE_THROUGH_SERIES) && !defined(__UBL__)
+ invalidate_wt_cache((kal_uint32)Buffer, 512 * Sectors);
+#endif
+
+ DclSD_Close(dclHandle);
+ //return FS_NO_ERROR;
+ return dclStatus;
+}
+
+/*-----------------------------------*/
+
+#if defined(__UBL__)
+#pragma arm section code = "EXT_BOOTLOADER_CODE", rwdata = "EXT_BOOTLOADER_RW", zidata = "EXT_BOOTLOADER_ZI"
+#endif
+
+int WriteSectors(void * DriveData, kal_uint32 Sector, UINT Sectors, void * Buffer)
+{
+ //SDC_CMD_STATUS status;
+ kal_uint8 retry = 0,single_line=0;
+ //kal_uint32 adrs;
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ kal_uint32 time1, time2;
+#endif
+
+ DCL_STATUS dclStatus = 0;
+ SD_CTRL_READ_T data;
+ DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+ //kal_uint32 timeout_count = 0;
+ DCL_BOOL isCardExist = DCL_FALSE;
+ DCL_BOOL isCardInited = KAL_FALSE;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+ DEMP_LOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+#if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+#endif
+ }
+
+ if(sel==SD_EXT)
+ {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_WRITE_SECTOR_ERROR;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_WRITE_SECTOR_ERROR;
+ #else
+ ASSERT(0);
+ #endif
+ }
+ prSwitch.u4TargetInterface=sel;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+ #else
+
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if(dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_WRITE_SECTOR_ERROR;
+#endif
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+ MD_TRC_MSDC_INFORM_WRITESECTOR_ENTRY((kal_uint32)DriveData, Sector, Sectors, (kal_uint32)Buffer,
+ (kal_uint32)kal_get_current_thread_ID(), MSDC_Reg32(MSDC_CFG), isCardExist, isCardInited);
+
+ if(!isCardExist)
+ {
+ DclSD_Control(dclHandle, SD_CTRL_CMD_POLL_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ if(!isCardExist)
+ {
+ DclSD_Close(dclHandle);
+ return FS_MSDC_MOUNT_ERROR;
+ }
+ }
+
+ gMSDC_Handle->timeout_count = 0;
+ do{
+
+ #ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ time1 = drv_get_current_time();
+ MD_TRC_MSDC_INFORM_WRITESECTOR_START(time1, retry, gSD->sd_w, 0);
+ #endif
+
+ MSDC_SLA_Start_Logging("BFW");
+
+ data.bufferAddr = Buffer;
+ data.u4Sector = Sector;
+ data.u4Sectors = Sectors;
+ dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_WRITE, (DCL_CTRL_DATA_T*)&data);
+ //if (dclStatus == STATUS_ERROR_WRONG_STATE)
+ //{
+ // DclSD_Close(dclHandle);
+ // DEMP_UNLOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+ // return FS_MSDC_WRITE_SECTOR_ERROR;
+ //}
+
+ MSDC_SLA_Stop_Logging("BFW");
+
+ #ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+ time2 = drv_get_current_time();
+ MD_TRC_MSDC_INFORM_WRITESECTOR_END(dclStatus, time2,
+ (kal_uint32)kal_get_current_thread_ID(), (double)(Sectors*32768*5)/((time2-time1)*10));
+ #endif
+
+#ifdef __DRV_MSDC_DEBUG_PERF_MEASURE__
+// for write operation performance measurement
+ switch (Sectors)
+ {
+ case 1:
+ gMSDC_perf_block_write_freq[0] += Sectors;
+ gMSDC_perf_block_write_time[0] += (time2-time1);
+ break;
+ case 2:
+ gMSDC_perf_block_write_freq[1] += Sectors;
+ gMSDC_perf_block_write_time[1] += (time2-time1);
+ break;
+ case 3:
+ case 4:
+ gMSDC_perf_block_write_freq[2] += Sectors;
+ gMSDC_perf_block_write_time[2] += (time2-time1);
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ gMSDC_perf_block_write_freq[3] += Sectors;
+ gMSDC_perf_block_write_time[3] += (time2-time1);
+ break;
+ default:// Sector > 8
+ gMSDC_perf_block_write_freq[4] += Sectors;
+ gMSDC_perf_block_write_time[4] += (time2-time1);
+ break;
+ }
+#endif
+
+ if(dclStatus != STATUS_OK)
+ {
+ if(kal_query_systemInit()== KAL_TRUE)
+ {
+ /*12/26, Blue remove this to enable read retry in booting up*/
+ #if defined(MSDC_TRACE_LEVEL3)
+ MSDC_add_dbg_msg(msdc_dbg_event_SD_read_fail_systemInit, dclStatus, gSD->sd_r);
+ #endif
+ //MSDC_PDNControl(KAL_TRUE);
+ //return FS_MSDC_READ_SECTOR_ERROR;
+ }
+
+ if (dclStatus ==STATUS_ERROR_CRCERROR)
+ {
+
+ if((gMSDC_Handle->op_clock / 2) >= gMSDC_Handle->msdc_clkTuneUpperBund)
+ {
+ gMSDC_Handle->op_clock = gMSDC_Handle->op_clock / 2;
+ MSDC_ERR("[MSDC]CRC Error, reduce Bus Clock\r\n");
+ MSDC_SetClock(gMSDC_Handle->op_clock,KAL_FALSE);
+ }
+ else
+ {
+ MSDC_ERR("[MSDC]CRC Error, try single line\r\n");
+ if (gMSDC_Handle->trySingleLine == NO_SINGLE_LINE&&single_line==0)
+ {
+ gMSDC_Handle->trySingleLine = TEMP_SINGLE_LINE;
+ single_line=1;
+ }
+ else
+ {
+ dclStatus = FS_MSDC_WRITE_SECTOR_ERROR;
+ break;
+ }
+ DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+
+ if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK)
+ {
+ dclStatus = FS_MSDC_READ_SECTOR_ERROR;
+ break;
+ }
+ }
+ }
+ else if (dclStatus==STATUS_ERROR_TIMEOUT)
+ {
+ if (retry++ >=3)
+ {
+ dclStatus= FS_MSDC_WRITE_SECTOR_ERROR;
+ break;
+ }
+ MSDC_ERR("[MSDC][%s]Timeout Error, retry count<%d>\r\n",__FUNCTION__,retry);
+
+ //gMSDC_Handle->mIsInitialized = KAL_FALSE;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_GO_IDLE, NULL);
+
+ if (DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL) != STATUS_OK) {
+ dclStatus = FS_MSDC_WRITE_SECTOR_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ break;
+
+ }
+ }
+ }while(dclStatus!=STATUS_OK);
+
+ DclSD_Close(dclHandle);
+ DEMP_UNLOCK(Buffer, DCL_SECTOR_SIZE * Sectors);
+ return dclStatus;
+}
+
+#if defined(__UBL__)
+#pragma arm section code, rwdata, zidata
+#endif
+
+#if !defined(__FUE__) && !defined(__UBL__)
+void SD_SelfFormat(void)
+{
+
+ FS_PartitionRecord Par;
+ //static kal_uint8 p[512];
+
+ kal_mem_set((void*)&Par, 0, sizeof Par);
+ if(0x20000000000ULL > gSD->mCSD.capacity){
+ Par.Sectors = (kal_uint32)(gSD->mCSD.capacity/512);
+ }
+ else{
+ ASSERT(0);
+ }
+
+ FS_CreateMasterBootRecord(MSDC_Sector, &Par);
+
+ WriteSectors(gMSDC_Handle, 0, 1, MSDC_Sector);
+
+ Par = ((FS_MasterBootRecord *)MSDC_Sector)->PTable[0];
+ FS_CreateBootSector((void*)MSDC_Sector, &Par, 0xF8, 0, FS_FMT_SINGLE_FAT );
+ WriteSectors(gMSDC_Handle, Par.RelativeSector, 1, MSDC_Sector);
+ /* End of SelfFormat */
+
+}
+#endif//__UBL__
+
+/*-----------------------------------*/
+int MountDevice(void * DriveData, int DeviceNumber, int DeviceType, kal_uint32 Flags)
+{
+ kal_uint8 retry = 0;
+ DCL_STATUS dclStatus = 0;
+ DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+ DCL_BOOL isCardExist = DCL_FALSE;
+ DCL_BOOL isCardInited = KAL_FALSE;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+#if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+#endif
+ }
+ if(sel==SD_EXT)
+ {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_MOUNT_ERROR;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_MOUNT_ERROR;
+ #else
+ ASSERT(0);
+ #endif
+ }
+ prSwitch.u4TargetInterface=sel;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+ #else
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if(dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_MOUNT_ERROR;
+#endif
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+ if(isCardInited)
+ {
+ DclSD_Close(dclHandle);
+ return DCL_SECTOR_SIZE;
+ }
+ gMSDC_Handle->is_init_timeout = KAL_FALSE;
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ if(!isCardExist)
+ {
+ //dbg_print("not present \r\n");
+
+ #if defined(_NAND_FLASH_BOOTING_)
+ // add the following code for solving plug in or out the SD card during
+ // NFB loading process. The card detection interruptwill disapperared
+ // while interrupt controller is masked.
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_POLL_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+
+ #endif // _NAND_FLASH_BOOTING_
+
+ if (!isCardExist)
+ {
+ DclSD_Close(dclHandle);
+ return FS_MSDC_MOUNT_ERROR;
+ }
+ }
+start:
+#ifdef DRV_MSDC_2_DLT_FOR_RD_WR
+ gMSDC_Handle->msdc_clkTuneTriedWr = MSDC_DLT_NOT_TESTED;
+ gMSDC_Handle->msdc_clkTuneTriedRd = MSDC_DLT_NOT_TESTED;
+ gMSDC_Handle->msdc_RedDlt_forRd = MSDC_RED_DLT_INVALID;
+ gMSDC_Handle->msdc_RedDlt_forWr = MSDC_RED_DLT_INVALID;
+#endif
+
+ dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_INIT, NULL);
+ if (dclStatus != STATUS_OK)
+ goto err_exit;
+
+ //if(SD_MountDevice(DeviceType) != FS_NO_ERROR)
+ //return FS_MSDC_MOUNT_ERROR;
+
+ //dbg_print("Mount success! \r\n");
+
+ DclSD_Close(dclHandle);
+
+ init_MSDC_lock(&gSD->mSDdrv_lock, "SD_DRV_LOCK");
+
+#if defined(MSDC_SDMMC_NAND) && !defined(__UBL__)
+ /*for SDMMC NAND, some manufacturs sale NAND with all sectors zero, we should format it first*/
+ if (ReadSectors( DriveData, 0, 1, MSDC_Sector) != NO_ERROR)
+ goto err_exit;
+ if (0xaa550000 != (MSDC_Sector[127] & 0xffff0000)){/*it doesn't have correct MBR*/
+ if (ReadSectors(DriveData, 1, 1, MSDC_Sector) != NO_ERROR)
+ goto err_exit;
+ if (0xaa550000 != (MSDC_Sector[127] & 0xffff0000)){/*it doesn't have correct PBR*/
+ SD_SelfFormat();
+ }
+ }
+#endif
+
+ return DCL_SECTOR_SIZE;
+
+err_exit:
+ if(retry++ <= SD_MAX_RETRY && gMSDC_Handle->is_init_timeout == KAL_FALSE)
+ {
+ //dbg_print("SD MountDevice failed! retry: %d \r\n",retry);
+ goto start;
+ }
+ #if defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ isCardExist = KAL_FALSE;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_SET_CLEAR_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ #endif
+
+ /*these cards do not support hot plug and we should set it not present now*/
+ #if defined(__SIM_PLUS__)
+ if(INT_USBBoot() == KAL_TRUE && current_card == SD_SIM)
+ {
+ isCardExist = KAL_FALSE;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_SET_CLEAR_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ }
+ #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+
+ if(INT_USBBoot() == KAL_TRUE && current_card == SD_T_CARD_2)
+ {
+ isCardExist = KAL_FALSE;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_SET_CLEAR_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ }
+ #endif //__SIM_PLUS__ or DRV_MSDC_DUAL_TCARD_BY_SWITCH
+
+ DclSD_Close(dclHandle);
+ gMSDC_Handle->mIsPresent=KAL_FALSE;
+ return FS_MSDC_MOUNT_ERROR;
+
+}
+
+
+/*-----------------------------------*/
+static int MediaChanged(void * DriveData)
+{
+ //DCL_STATUS dclStatus = 0;
+ kal_bool everPlugOut = KAL_FALSE;
+ DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+ DCL_BOOL isCardExist = DCL_FALSE;
+ DCL_BOOL isCardInited = KAL_FALSE;
+ int status;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_take_sem(dualMsdcArb, 1);
+ }
+ #endif
+
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+ #endif
+ }
+
+ if(sel==SD_EXT)
+ {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ {
+ #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_give_sem(dualMsdcArb);
+ }
+ #endif
+ return FS_MSDC_READ_SECTOR_ERROR;
+ }
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ {
+ #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_give_sem(dualMsdcArb);
+ }
+ #endif
+ return FS_MSDC_READ_SECTOR_ERROR;
+ }
+ #else
+ ASSERT(0);
+ #endif
+ }
+
+ prSwitch.u4TargetInterface=sel;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+ #else
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if(dclHandle == DCL_HANDLE_INVALID)
+ return FS_MSDC_READ_SECTOR_ERROR; //safe for normal case
+#endif
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+
+#ifdef DRV_MSDC_VMC_CTRL
+ MSDC_turnOnVMC(isCardExist);
+#endif
+
+ if(isCardExist)
+ {
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+ if(isCardInited)
+ {
+#ifdef MSDC_MUST_RECORD_PLUGOUT
+ DclSD_Control(dclHandle, SD_CTRL_CMD_RESET_EVER_PLUGOUT, NULL);
+#endif
+ //DclSD_Close(dclHandle);
+ status=FS_NO_ERROR;
+ goto Error;
+ }
+ else
+ {
+#ifdef MSDC_MUST_RECORD_PLUGOUT
+ /*current state is present not mount, we have to check whether it plug out before*/
+ DclSD_Control(dclHandle, SD_CTRL_CMD_QUERY_EVER_PLUGOUT, (DCL_CTRL_DATA_T*)&everPlugOut);
+ if(KAL_TRUE == everPlugOut){
+ /*send FMT a new message, and return plug out*/
+ DclSD_Control(dclHandle, SD_CTRL_CMD_RESET_EVER_PLUGOUT, NULL);
+ #if !defined(FMT_NOT_PRESENT)
+ MSDC_SendCardInd(MOD_FMT, SD_EXT, MSG_ID_MSDC_CARD_DETECT_IND);
+ #endif
+ //DclSD_Close(dclHandle);
+ status=FS_MSDC_NOT_PRESENT;
+ goto Error;
+ }
+ DclSD_Control(dclHandle, SD_CTRL_CMD_RESET_EVER_PLUGOUT, NULL);
+#endif
+ //DclSD_Close(dclHandle);
+ status=FS_MSDC_PRESNET_NOT_READY;
+ goto Error;
+ }
+ }
+#ifdef MSDC_MUST_RECORD_PLUGOUT
+ DclSD_Control(dclHandle, SD_CTRL_CMD_RESET_EVER_PLUGOUT, NULL);
+#endif
+ status=FS_MSDC_NOT_PRESENT;
+Error:
+ DclSD_Close(dclHandle);
+ #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_give_sem(dualMsdcArb);
+ }
+ #endif
+ return status;
+}
+
+/*-----------------------------------*/
+static int GetDiskGeometry(void * DriveData, FS_PartitionRecord * DiskGeometry, BYTE * MediaDescriptor)
+{
+ DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+ DCL_BOOL isCardExist = DCL_FALSE;
+ DCL_BOOL isCardInited = KAL_FALSE;
+ int status = FS_NO_ERROR;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+ #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_take_sem(dualMsdcArb, 1);
+ }
+ #endif
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+ #endif
+ }
+ get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+ if(sel==SD_EXT)
+ {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID) {
+ status = FS_MSDC_READ_SECTOR_ERROR;
+ goto err_exit;
+ }
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID) {
+ status = FS_MSDC_READ_SECTOR_ERROR;
+ goto err_exit;
+ }
+ #else
+ ASSERT(0);
+ #endif
+ }
+
+ prSwitch.u4TargetInterface=sel;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+
+ #else
+ get_MSDC_lock(&gSD->mSDdrv_lock);
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if(dclHandle == DCL_HANDLE_INVALID) {
+ status = FS_MSDC_READ_SECTOR_ERROR;
+ goto err_exit;
+ }
+#endif
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_INITED, (DCL_CTRL_DATA_T*)&isCardInited);
+ if(isCardExist && isCardInited){
+ kal_mem_set((void*)DiskGeometry, 0, sizeof * DiskGeometry);
+ if(0x20000000000ULL > gSD->mCSD.capacity){
+ DiskGeometry->Sectors = (kal_uint32)(gSD->mCSD.capacity/512);
+ }
+ else{
+ DclSD_Close(dclHandle);
+ status = FS_MSDC_NOT_PRESENT;
+ goto err_exit;
+ //ASSERT(0);
+ }
+ // 0xF8 is the standard value for fixed media, 0xF0 is for removable media.
+ // The important point is whatever value is put in here must also be put in the first
+ // byte of he FAT[0].
+ *MediaDescriptor = MSDC_MEDIA_DESCRIPTOR;
+ if(gSD->mWPEnabled) {
+ status = FS_WRITE_PROTECTION;
+ goto err_exit;
+ }
+DclSD_Close(dclHandle);
+ status = FS_NO_ERROR;
+ }
+ else{
+DclSD_Close(dclHandle);
+ status = FS_MSDC_NOT_PRESENT;
+ }
+err_exit:
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_give_sem(dualMsdcArb);
+ }
+#endif
+
+ return status;
+}
+
+int SD_GetDiskGeometry(void * DriveData, FS_PartitionRecord * DiskGeometry, BYTE * MediaDescriptor)
+{
+ return GetDiskGeometry(DriveData, DiskGeometry, MediaDescriptor);
+}
+
+/*-----------------------------------*/
+extern void MSDC_ErrorRecordingReset();
+static int ShutDown(void * DriveData)
+{
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_LOCK(AUDMA_ID_MSDC);
+#endif
+
+#ifdef __TST_WRITE_TO_FILE__
+ /*error recording: write error log to memory card here*/
+ if(KAL_TRUE == INT_QueryExceptionStatus())
+ MSDC_ErrorRecordingReset();
+#endif
+#if defined(__AUDIO_DSP_LOWPOWER__)
+ AUDMA_UNLOCK(AUDMA_ID_MSDC);
+#endif
+ return FS_NO_ERROR;
+}
+
+#if defined(__UBL__)
+#pragma arm section code = "EXT_BOOTLOADER_CODE", rwdata = "EXT_BOOTLOADER_RW", zidata = "EXT_BOOTLOADER_ZI"
+#endif
+
+kal_bool SD_canUseErase()
+{
+ if (KAL_TRUE == useEraseOnFormat && 0 == gSD->mSCR.dat_after_erase){
+ if (MMC_CARD == gMSDC_Handle->mMSDC_type
+ || MMC40_CARD == gMSDC_Handle->mMSDC_type
+ || MMC42_CARD == gMSDC_Handle->mMSDC_type
+ || MMC_CARD_SIMPLUS == gMSDC_Handle->mMSDC_type) {
+ return KAL_FALSE;
+ }
+ else {
+ tst_sys_trace("enhanced format");
+ return KAL_TRUE;
+ }
+ }
+ else{
+ return KAL_FALSE;
+ }
+}
+
+#if defined(__UBL__)
+#pragma arm section code, rwdata, zidata
+#endif
+
+/*******************************************
+ * File System <--> Device Driver Interface
+ * High Level Format
+ *
+ * Sample Code
+ ******************************************/
+#include <fs_type.h>
+//#include <rtfiles.h>
+#include "fs_gprot.h"
+
+/* FIXME */
+//kal_uint8 SectorBuffer[512];
+
+#if defined(__UBL__)
+#pragma arm section code = "EXT_BOOTLOADER_CODE", rwdata = "EXT_BOOTLOADER_RW", zidata = "EXT_BOOTLOADER_ZI"
+#endif
+
+extern int SDCreateBootSector(void * BootSector, kal_uint32 Sectors, FS_PartitionRecord *Partition);
+extern int SDCreateMasterBootRecord(void * MasterBootRecord, kal_uint32 Sectors);
+
+int highlevelformat(void * DriveData, UINT BaseSectorNumber)
+{
+ int FATType;
+ int RootDirSectors;
+ int InfoSector;
+ int i;
+ kal_uint32 x, y;
+ kal_uint32 FATSectors, Written;
+ kal_uint32 FatCount, StartOfFAT;
+// kal_uint32 status;
+ kal_uint32 boot_sector_offset = BaseSectorNumber;
+#if __COOL_FORMAT__
+ kal_uint32 total_sectors;
+#endif
+ FS_BootRecord *PBR;
+ kal_uint8 MediaDescriptor;
+ int Result = FS_NO_ERROR;
+
+#if __COOL_FORMAT__
+ FS_MasterBootRecord *mbr;
+ FS_BootRecord *bs;
+#endif
+ DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ #endif
+
+ #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_take_sem(dualMsdcArb, 1);
+ }
+ #endif
+
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+ #elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+ #endif
+ }
+
+ get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+
+ #else
+ get_MSDC_lock(&gSD->mSDdrv_lock);
+ #endif
+
+ do {
+
+ #if __COOL_FORMAT__
+ mbr = (FS_MasterBootRecord *)MSDC_Sector;
+ bs = (FS_BootRecord *)msdc_uncachedBuf;
+
+ total_sectors = gSD->mCSD.capacity/512;
+
+// status = SD_FlushSectors(0, total_sectors);
+// if (status != NO_ERROR)
+// break;
+
+ //
+ // 1. Create MBR.
+ //
+ boot_sector_offset = SDCreateMasterBootRecord(mbr, total_sectors);
+
+ if (boot_sector_offset > 0) {
+
+ //
+ // 2. Write MBR.
+ //
+ Result = WriteSectors(&MSDC_Blk[0], 0, 1, (void *)mbr);
+ if (Result != STATUS_OK) {
+ break;
+ }
+
+ //
+ // 3. Create boot sector.
+ //
+ if (SDCreateBootSector(bs, total_sectors, &mbr->PTable[0]) > 0) {
+
+ //
+ // 4. Write boot sector to boot_sector_offset
+ //
+ Result = WriteSectors(&MSDC_Blk[0], boot_sector_offset, 1, bs);
+ if (Result != STATUS_OK) {
+ break;
+ }
+
+ }
+ else {
+ Result = FS_INVALID_FILE_SYSTEM;
+ break;
+ }
+ }
+ else {
+ Result = FS_INVALID_FILE_SYSTEM;
+ break;
+ }
+ #endif
+
+ //
+ // 5. Finally, perform high level format.
+ // According to SD spec, 2G~32G card's start address is 0x2000
+ //
+
+ /* HLF - 1 - Read the PBR sector */
+ ///* FIXME */ DrvDirect.ReadSector(SectorBuffer /* Buffer */ ,
+ // BaseSectorNumber /* Sector Number */);
+ Result = ReadSectors(DriveData, boot_sector_offset, 1, MSDC_Sector);
+ if (Result != STATUS_OK)
+ break;
+
+ //PBR = (FS_BootRecord*)&MSDC_Sector;
+ PBR = (FS_BootRecord*)MSDC_Sector;
+
+ /* HLF - 2 - Setup PBR sector content and attributes */
+ {
+ if (PBR->BP.SectorsOnDisk != 0)
+ PBR->BP.TotalSectors = PBR->BP.SectorsOnDisk;
+
+ if (PBR->Signature != 0xAA55 ||
+ //PBR->BP.TotalSectors > Par.Partition.Sectors ||
+ PBR->BP.TotalSectors > (gSD->mCSD.capacity/512) ||
+ PBR->BP.BytesPerSector != 512 ||
+ PBR->BP.SectorsPerCluster == 0 ||
+ PBR->BP.ReservedSectors == 0 ||
+ PBR->BP.NumberOfFATs == 0)
+ {
+ Result = FS_INVALID_FILE_SYSTEM;
+ break;
+ }
+
+ FATSectors = (PBR->BP.SectorsPerFAT) ? PBR->BP.SectorsPerFAT : PBR->BP.E._32.SectorsPerFAT;
+ RootDirSectors = (PBR->BP.DirEntries * 32 + (PBR->BP.BytesPerSector - 1)) / PBR->BP.BytesPerSector;
+
+ Written = PBR->BP.TotalSectors
+ - PBR->BP.ReservedSectors
+ - PBR->BP.NumberOfFATs * FATSectors
+ - RootDirSectors;
+ Written = Written / PBR->BP.SectorsPerCluster;
+
+ if (Written <= 0xFF4L) FATType = 12;
+ else if (Written <= 0xFFF4L) FATType = 16;
+ else if (Written <= 0xFFFFFF4L) FATType = 32;
+ else {
+ Result = FS_INVALID_FILE_SYSTEM;
+ break;
+ }
+ Written = 0;
+
+ if (FATType == 32)
+ {
+ RootDirSectors = PBR->BP.SectorsPerCluster;
+
+ if (PBR->BP.E._32.RootDirCluster != 2)
+ {
+ PBR->BP.E._32.RootDirCluster = 2;
+
+ //above seek and write seems mean write to specific sector
+ Result = WriteSectors(DriveData, boot_sector_offset, 1, (void *)PBR);
+ if (Result != STATUS_OK)
+ break;
+
+ Result = WriteSectors(DriveData, boot_sector_offset + PBR->BP.E._32.BackupBootSector , 1, (void *)PBR);
+ if (Result != STATUS_OK)
+ break;
+ }
+ }
+
+
+ FatCount = PBR->BP.NumberOfFATs;
+ StartOfFAT = PBR->BP.ReservedSectors;
+ InfoSector = PBR->BP.E._32.FSInfoSector;
+ }
+
+ /*we get MediaDescriptor for step 6 usage, since we will clear MSDC_Sector*/
+ MediaDescriptor = PBR->BP.MediaDescriptor;
+ /*we need MSDC_Sector to be 512-byte-0 now*/
+ kal_mem_set(MSDC_Sector, 0, 512);
+
+ /* HLF - 3 - Formating cont, FAT32 reserved sector write down */
+ if ((FATType == 32) && (InfoSector > 0) && (InfoSector < StartOfFAT))
+ {
+ /* FIXME */
+ //DrvDirect.ZeroSector( BaseSectorNumber + InfoSector /* Start Sector Number */ ,
+ // 1 /* Zero Sector Count */ );
+ Result = WriteSectors(DriveData, boot_sector_offset + InfoSector, 1, MSDC_Sector);
+ if (Result != STATUS_OK)
+ break;
+ }
+
+
+ if (KAL_TRUE == SD_canUseErase()) {
+
+ DCL_STATUS dclStatus = 0;
+ SD_CTRL_FLUSH_T flush;
+
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ ASSERT(0);
+
+ flush.startSector = boot_sector_offset + StartOfFAT;
+ flush.sectorNum = (FATSectors * FatCount) + RootDirSectors;
+
+ dclStatus = DclSD_Control(dclHandle, SD_CTRL_CMD_FLUSH, (DCL_CTRL_DATA_T*)&flush);
+ if (STATUS_OK != dclStatus)
+ ASSERT(0);
+
+ DclSD_Close(dclHandle);
+ }
+ else {
+ /* start and cloase API are only called in this section of this function, we don't called these API in other places
+ file system should help protect the single task accessing, so driver should be able to protect the integrity of this start-close pair
+ */
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ ASSERT(0);
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_START, NULL);
+ DclSD_Close(dclHandle);
+
+ /* HLF - 4 - Formating cont, start, FAT Table write down , remember FAT begin sector */
+ {
+ /* FIXME */
+ //DrvDirect.ZeroSector( BaseSectorNumber + StartOfFAT /* Start Sector Number */ ,
+ // FATSectors * FatCount /* Zero Sector Count */ );
+ #if defined(__DRV_MSDC_FAST_FORMAT__)
+
+ Result = WriteSectors(DriveData, boot_sector_offset + StartOfFAT, FATSectors * FatCount , MSDC_Sector);
+
+ if (Result != STATUS_OK) {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ ASSERT(0);
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_STOP, NULL);
+ DclSD_Close(dclHandle);
+ goto highlevelformat_exit;
+ }
+ #else
+ for (i = 0; i < FATSectors * FatCount; i++) {
+
+ Result = WriteSectors(DriveData, boot_sector_offset + StartOfFAT + i, 1 , MSDC_Sector);
+
+ if (Result != STATUS_OK) {
+
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ ASSERT(0);
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_STOP, NULL);
+ DclSD_Close(dclHandle);
+ goto highlevelformat_exit;
+ }
+ }
+ #endif
+ }
+
+ /* HLF - 5 - Formating cont, Root directory write down */
+ {
+
+ x = StartOfFAT + FATSectors * FatCount;
+ /* FIXME */
+ //DrvDirect.ZeroSector( BaseSectorNumber + x /* Start Sector Number */ ,
+ // RootDirSectors /* Zero Sector Count */ );
+ #if defined(__DRV_MSDC_FAST_FORMAT__)
+
+ Result = WriteSectors(DriveData, boot_sector_offset + x, RootDirSectors , MSDC_Sector);
+
+ if (Result != STATUS_OK) {
+
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+
+ if (dclHandle == DCL_HANDLE_INVALID)
+ ASSERT(0);
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_STOP, NULL);
+ DclSD_Close(dclHandle);
+ goto highlevelformat_exit;
+ }
+ #else
+ for (i = 0; i < RootDirSectors; i++) {
+
+ Result = WriteSectors(DriveData, boot_sector_offset + x + i, 1 , MSDC_Sector);
+
+ if (0 > Result) {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+
+ if (dclHandle == DCL_HANDLE_INVALID)
+ ASSERT(0);
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_STOP, NULL);
+ DclSD_Close(dclHandle);
+ goto highlevelformat_exit;
+ }
+ }
+ #endif
+ }
+
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ ASSERT(0);
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_FAST_FORMAT_STOP, NULL);
+ DclSD_Close(dclHandle);
+ }
+
+ /* HLF - 6 - Formating final, 1st FAT sector must be rewritten */
+ {
+ kal_uint16 * FPtr16;
+ kal_uint8 * FPtr8;
+ switch (FATType)
+ {
+ case 32:
+ //kal_uint32 * FPtr = (void*) ScratchSector;
+ MSDC_Sector[2] = 0x0FFFFFFF; // this is for the root dir
+ MSDC_Sector[1] = 0x0FFFFFFF;
+ //break;
+ case 16:
+ FPtr16 = (void*)MSDC_Sector;
+ FPtr16[1] = 0xFFFF;
+ //break;
+ case 12:
+ FPtr8 = (void *)MSDC_Sector;
+ /* FIXME */ FPtr8[2] = 0xFF;
+ /* FIXME */ FPtr8[1] = 0xFF;
+ /* FIXME */ FPtr8[0] = MediaDescriptor;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ for (i = 0, y = StartOfFAT;
+ i < FatCount;
+ i++ , y+= FATSectors)
+ {
+ ///* FIXME */ DrvDirect.WriteSector(SectorBuffer /* Buffer */ ,
+ // BaseSectorNumber + y /* Sector Number */);
+ Result = WriteSectors(DriveData, boot_sector_offset + y, 1 , MSDC_Sector);
+ }
+ }
+
+ } while (0);
+
+highlevelformat_exit:
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+ #else
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+ #endif
+
+ #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_give_sem(dualMsdcArb);
+ }
+ #endif
+
+ /* HLF - 7 - The END */
+ return Result;
+}
+
+#if defined(__UBL__)
+#pragma arm section code, rwdata, zidata
+#endif
+
+int SD_IOCtrl(void * DriveData, UINT CtrlAction, void * CtrlData)
+{
+ FS_DeviceInfo *info;
+ kal_bool on;
+ DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+// DCL_STATUS dclStatus = 0;
+ DCL_BOOL isCardExist = DCL_FALSE;
+// DCL_BOOL isCardInited = DCL_FALSE;
+ int status = FS_NO_ERROR;
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+#endif
+
+ #if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_take_sem(dualMsdcArb, 1);
+ }
+ #endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if ((MSDC_HANDLE *)DriveData == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+#if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+#endif
+ }
+ init_MSDC_lock(&gSD_blk[0].mSDdrv_lock, "SD_DRV_LOCK");//guilin++
+ get_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+
+ if(sel==SD_EXT)
+ {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID) {
+ status = FS_INVALID_OPERATION;
+ goto err_exit;
+ }
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID) {
+ status = FS_INVALID_OPERATION;
+ goto err_exit;
+ }
+ #else
+ ASSERT(0);
+ #endif
+ }
+ DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&sel);
+#else
+ init_MSDC_lock(&gSD->mSDdrv_lock, "SD_DRV_LOCK");//guilin++
+ get_MSDC_lock(&gSD->mSDdrv_lock);
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID) {
+ status = FS_INVALID_OPERATION;
+ goto err_exit;
+ }
+#endif
+
+ switch (CtrlAction)
+ {
+ case FS_IOCTRL_QUERY_CARD_INFO:
+ info = CtrlData;
+ /*
+ 1. If memory card is inserted, set flag FS_DEVICE_FLAG_PRESENT in info->DeviceInfo.Card.Flag
+ 2. If memory card is NOT inserted, clear flag FS_DEVICE_FLAG_PRESENT in info->DeviceInfo.Card.Flag
+ */
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+
+ if (isCardExist){
+ info->DeviceInfo.Card.Flag |= FS_DEVICE_FLAG_PRESENT;
+ info->DeviceInfo.Card.PSN = gSD->mCID.psn;
+ //
+ // bus_width = 5, -> 4bit
+ // bus_width = 1, -> 1bit
+ //
+ #if defined(MSDC_SD_BITS4_BUS)
+ info->DeviceInfo.Card.SerialMode = KAL_FALSE;
+ #else
+ info->DeviceInfo.Card.SerialMode = KAL_TRUE;
+ #endif
+ }
+ else{
+ info->DeviceInfo.Card.Flag &= ~FS_DEVICE_FLAG_PRESENT;
+ info->DeviceInfo.Card.PSN = 0;
+ info->DeviceInfo.Card.SerialMode = KAL_TRUE;
+ }
+ break;
+
+ case FS_IOCTRL_CONTROL_DEV_POWER:
+ on = *(kal_bool*)CtrlData;
+
+ if(gMSDC_Handle->msdc_custom_handle.PowerCtrl)
+ gMSDC_Handle->msdc_custom_handle.PowerCtrl(on);
+ break;
+
+ default:
+ status = FS_UNSUPPORTED_DRIVER_FUNCTION;
+ goto err_exit;
+ //ASSERT(0);
+ //break;
+ }
+
+err_exit:
+ DclSD_Close(dclHandle);
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ free_MSDC_lock(&gSD_blk[0].mSDdrv_lock);
+#else
+ free_MSDC_lock(&gSD->mSDdrv_lock);
+#endif
+#if defined(__MSDC_DUAL_CARD_SWITCH__) && !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+
+ if (KAL_FALSE == kal_query_systemInit() && (KAL_FALSE == INT_QueryExceptionStatus()))
+ {
+ kal_give_sem(dualMsdcArb);
+ }
+#endif
+
+ return status;
+}
+
+#endif//defined(DCL_MSDC_INTERFACE)
+
+FS_Driver FS_SdDrv = {
+ MountDevice_NEW,
+ ShutDown,
+ ReadSectors_NEW,
+ WriteSectors_NEW,
+ MediaChanged,
+ DiscardSectors,
+ GetDiskGeometry,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ highlevelformat,
+ NULL,
+ MSDC_GetCardStatus,
+ NULL,
+ NULL,
+ NULL,
+ SD_IOCtrl//ioctrl
+};
+
+#ifdef __CMMB_CAS_FULL_CARD_SUPPORT__
+
+kal_uint8 CommandTag[32] =
+{
+ 0x2A, 0x4D, 0x4D, 0x43, 0x2A, 0x4D, 0x45, 0x4D, 0x4F, 0x52, 0x59, 0x2A, 0x49, 0x4F, 0x2A, 0x43,
+ 0x4F, 0x53, 0x2A, 0x43, 0x4F, 0x4D, 0x4D, 0x41, 0x4E, 0x44, 0x2A, 0x20, 0x20, 0x20, 0x20, 0x20
+};
+
+static const kal_uint8 RETRY_TAG[3] =
+{
+ 0x00, 0x01, 0x60
+};
+
+extern FS_Driver FS_SdDrv;
+
+
+CAS_CMD_STA CAS_CMD(kal_uint8 *txBuffer, kal_uint32 txSize, kal_uint8 *rxBuffer, kal_uint32 *rxSize)
+{
+ kal_uint16 sizeTotal;
+ kal_uint32 txBlockNum, rxBlockNum;
+ kal_bool receiveDone;
+ CAS_CMD_STA status = CAS_CMD_NO_ERROR;
+ kal_uint32 retryTimes = 0, reWriteTimes = 0;
+ int retValue;
+
+
+ if(1 > (*rxSize) || 1 > txSize)
+ ASSERT(0);
+
+ if(KAL_FALSE == gMSDC_Handle->mIsPresent){
+ status = CAS_CMD_NOT_EXIST;
+ goto exit;
+ }
+
+ if(KAL_FALSE == isFullCard)
+ return CAS_CMD_NOT_CAS_CARD;
+
+ if((KAL_TRUE == gMSDC_Handle->mIsPresent) && (KAL_FALSE == gMSDC_Handle->mIsInitialized)){
+ status = CAS_CMD_EXIST_NOT_READY;
+ goto exit;
+ }
+
+ if(3 < (txSize/512))
+ txBlockNum = 16;
+ else
+ txBlockNum = 4;
+
+ rxBlockNum = 1 + (((*rxSize) -1)/512) ;
+
+ memcpy(txBuffer, CommandTag, 32);
+ txBuffer[32] = (kal_uint8)(txSize >> 8);
+ txBuffer[33] = (kal_uint8)(txSize);
+
+retry:
+ retValue = FS_SdDrv.WriteSectors((void *)M_CAM_CAS_HANDLE, M_CAM_CAS_BLOCK, txBlockNum, txBuffer);
+
+ if((FS_NO_ERROR != retValue) && (KAL_FALSE == gMSDC_Handle->mIsPresent)){
+ status = CAS_CMD_NOT_EXIST;
+ goto exit;
+ }
+
+ if (FS_NO_ERROR != retValue)
+ {
+ tst_sys_trace("CAS write failed\r\n");
+ status = CAS_CMD_WRITE_FAIL;
+ goto exit;
+ }
+
+
+ /*from M-CAM's spec, we should wait 15ms before the read command*/
+ kal_sleep_task(4);
+
+ receiveDone = KAL_FALSE;
+ while(KAL_FALSE == receiveDone){
+
+ retValue = FS_SdDrv.ReadSectors((void *)M_CAM_CAS_HANDLE, M_CAM_CAS_BLOCK, rxBlockNum, rxBuffer);
+
+ if (FS_NO_ERROR != retValue)
+ {
+ tst_sys_trace("CAS read failed\r\n");
+ status = CAS_CMD_READ_FAIL;
+ break;
+ }
+
+
+ // check header
+ if (kal_mem_cmp(rxBuffer, CommandTag, 32) != 0)
+ {
+ reWriteTimes++;
+ if(2 > reWriteTimes){
+ tst_sys_trace("read: not correct header, retry\r\n");
+ goto retry;
+ }
+
+ tst_sys_trace("read: not correct header\r\n");
+ status = CAS_CMD_NOT_CAS_CARD;
+ break;
+ }
+
+ // 0x00 01 60
+ if (kal_mem_cmp(rxBuffer + 32, RETRY_TAG, 3) == 0)
+ {
+ tst_sys_trace("card is busy");
+
+ if(134 < retryTimes){/*according to M-CAM's spec, it maybe busy for 2 seconds*/
+ tst_sys_trace("busy timeout");
+ status= CAS_CMD_BUSY_TIMEOUT;
+ break;
+ }
+
+ kal_sleep_task(4);
+ retryTimes++;
+ continue;
+ }
+ else
+ {
+ *rxSize = (rxBuffer[32]<<8) |rxBuffer[33];
+ status = CAS_CMD_NO_ERROR;
+ receiveDone = KAL_TRUE;
+ break;
+ }
+ }
+
+exit:
+
+ return status;
+}
+#endif //__CMMB_CAS_FULL_CARD_SUPPORT__
+
+#endif // (__MSDC_SD_MMC__)
+
+#endif//!defined(__UBL__) || defined(__CARD_DOWNLOAD__) || defined(__EMMC_BOOTING__)
+
+#else //DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//RHR ADD
+#include "kal_public_defs.h"
+//#include "btif_sw.h"
+#include "kal_public_api.h"
+#include "kal_debug.h"
+#include "fs_gprot.h"
+#include "qmu_bm.h"
+//RHR REMOVE
+/*
+//MSBB remove #include "app_buff_alloc.h"
+#include "fat_fs.h"
+*/
+//RHR
+/*following is dummy API*/
+
+
+static int MountDevice_NEW(void * DriveData, int DeviceNumber, int DeviceType, kal_uint32 Flags){}
+static int ShutDown(void * DriveData){}
+static int ReadSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, void * Buffer){}
+static int WriteSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, void * Buffer){}
+static int MediaChanged(void * DriveData){}
+static int DiscardSectors(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors){}
+static int GetDiskGeometry(void * DriveData, FS_PartitionRecord * DiskGeometry, BYTE * MediaDescriptor){}
+int highlevelformat(void * DriveData, kal_uint32 BaseSectorNumber){}
+int Gpd_ReadSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors,qbm_gpd *head,qbm_gpd *tail){}
+int Gpd_WriteSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, qbm_gpd *head,qbm_gpd *tail){}
+kal_uint32 Get_BDStructNum(void){}
+
+
+extern int MSDC_GetCardStatus(void * DriveData, int AckType);
+
+FS_Driver FS_SdDrv = {
+ MountDevice_NEW,
+ ShutDown,
+ ReadSectors_NEW,
+ WriteSectors_NEW,
+ MediaChanged,
+ DiscardSectors,
+ GetDiskGeometry,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ highlevelformat,
+ NULL,
+ MSDC_GetCardStatus
+};
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/sd_drv2.c b/mcu/driver/storage/mc/src/sd_drv2.c
new file mode 100644
index 0000000..275b98a
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sd_drv2.c
@@ -0,0 +1,421 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * sd_drv2.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * Adaption driver of file system for SD card for MSDC_2
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef DRV_MSDC_OFF
+//RHR ADD
+#include "kal_public_defs.h"
+//#include "btif_sw.h"
+#include "kal_public_api.h"
+#include "kal_internal_api.h"
+//RHR REMOVE
+/*
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//MSBB remove #include "kal_non_specific_general_types.h"
+//MSBB remove #include "app_buff_alloc.h"
+#include "fat_fs.h"
+#if defined(__MSDC_MS__)
+#include "ms_def.h"
+#endif
+#include "init.h"
+*/
+//RHR
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "intrCtrl.h"
+#include "cache_sw.h" //doublelo add
+#if defined(__MSDC2_SD_MMC__)
+
+#define SECTOR_SIZE 512
+#define MSDC_MEDIA_DESCRIPTOR 0xF8
+#define SD_MAX_RETRY 2
+extern MSDC_HANDLE *msdc2_handle;
+extern T_SDC_HANDLE *gSD2;
+
+static int ReadSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer);
+static int WriteSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer);
+static kal_uint32 sd_r,sd_w;
+
+static int DiscardSectors(void * DriveData, DWORD Sector, UINT Sectors)
+{
+ return FS_NO_ERROR;
+}
+
+static int ReadSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer)
+{
+
+ SDC_CMD_STATUS status;
+ kal_uint8 retry = 0;
+ kal_uint32 adrs;
+ MSDC_HANDLE *msdc = (MSDC_HANDLE *)DriveData ;
+
+#ifdef MSDC_CACHED_SUPPORT
+ /*tell buffer type each time this function called*/
+ if (INT_QueryIsCachedRAM(Buffer, Sectors * SECTOR_SIZE)){
+ msdc2_handle->isCachedBuf = KAL_TRUE;
+ }
+ else
+ msdc2_handle->isCachedBuf = KAL_FALSE;
+#endif
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD2->flags & SD_FLAG_HCS_SUPPORT)
+ adrs = Sector;
+ else
+#endif
+ adrs = Sector * SECTOR_SIZE;
+ msdc2_handle->timeout_count = 0;
+start:
+ if(!msdc2_handle->mIsInitialized)
+ {
+ //dbg_print("Read but not Initialized \r\n");
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_MSDC_READ_SECTOR_ERROR;
+ }
+ retry ++;
+ MSDC_PDNControl2(KAL_FALSE);
+ if(Sectors > 1)
+ status = SD_ReadMultiBlock_2((kal_uint32)adrs,(kal_uint32*)Buffer,(kal_uint32)Sectors);
+ else
+ status = SD_ReadSingleBlock_2((kal_uint32)adrs,(kal_uint32*)Buffer);
+ if(status != NO_ERROR )
+ {
+ sd_r++;
+ if(kal_query_systemInit()== KAL_TRUE)
+ {
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_MSDC_READ_SECTOR_ERROR;
+ }
+ //dbg_print("read retry:%d,status:%d,total %d\r\n",retry,status,sd_r);
+ if(status == ERR_CMD_TIMEOUT || status == MSDC_GPT_TIMEOUT_ERR)
+ msdc2_handle->timeout_count++;
+ if(msdc2_handle->timeout_count++ == 3 && msdc2_handle->mIsPresent == KAL_TRUE)
+ {
+ tst_sys_trace("[MSDC]:re-mount(read fail)");
+ msdc2_handle->mIsInitialized = KAL_FALSE;
+ retry = 0;
+ if(SD_Initialize_2() != NO_ERROR)
+ {
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_MSDC_READ_SECTOR_ERROR;
+ }
+ }
+ if(retry >= SD_MAX_RETRY)
+ {
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_MSDC_READ_SECTOR_ERROR;
+ }
+ else
+ {
+ // kal_prompt_trace(MOD_AUD,"CRC etry:%d,status:%d",retry,status);
+ goto start;
+ }
+ }
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_NO_ERROR;
+}
+
+static int WriteSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer)
+{
+ SDC_CMD_STATUS status;
+ kal_uint8 retry = 0;
+ kal_uint32 adrs;
+
+#ifdef MSDC_CACHED_SUPPORT
+ /*tell buffer type each time this function called*/
+ if (INT_QueryIsCachedRAM(Buffer, Sectors * SECTOR_SIZE)){
+ msdc2_handle->isCachedBuf = KAL_TRUE;
+
+ }
+ else
+ msdc2_handle->isCachedBuf = KAL_FALSE;
+#endif
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD2->flags & SD_FLAG_HCS_SUPPORT)
+ adrs = Sector;
+ else
+#endif
+ adrs = Sector * SECTOR_SIZE;
+ msdc2_handle->timeout_count = 0;
+start:
+ if(!msdc2_handle->mIsInitialized)
+ {
+ //dbg_print("Write but not Initialized \r\n");
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_MSDC_WRITE_SECTOR_ERROR;
+ }
+ retry++;
+ MSDC_PDNControl2(KAL_FALSE);
+ if(Sectors > 1)
+ {
+ if(msdc2_handle->mMSDC_type == SD_CARD)
+ SD_SetPreEraseBlk_2(Sectors);
+ status = SD_WriteMultiBlock_2((kal_uint32)adrs,(kal_uint32*)Buffer,(kal_uint32)Sectors);
+ }
+ else
+ status = SD_WriteSingleBlock_2((kal_uint32)adrs,(kal_uint32*)Buffer);
+ if(status != NO_ERROR)
+ {
+ sd_w++;
+ if(kal_query_systemInit()== KAL_TRUE)
+ {
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_MSDC_WRITE_SECTOR_ERROR;
+ }
+ if(status == ERR_CMD_TIMEOUT || status == MSDC_GPT_TIMEOUT_ERR)
+ msdc2_handle->timeout_count++;
+ if(msdc2_handle->timeout_count++ == 3 && msdc2_handle->mIsPresent == KAL_TRUE)
+ {
+ tst_sys_trace("[MSDC]:SD re-mount (write fail)");
+ msdc2_handle->mIsInitialized = KAL_FALSE;
+ retry = 0;
+ if(SD_Initialize_2() != NO_ERROR)
+ {
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_MSDC_WRITE_SECTOR_ERROR;
+ }
+ }
+ if(retry >= SD_MAX_RETRY)
+ {
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_MSDC_WRITE_SECTOR_ERROR;
+ }
+ else
+ {
+ // kal_prompt_trace(MOD_AUD,"CRC write Error retry %d",retry);
+ goto start;
+ }
+ }
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_NO_ERROR;
+}
+
+static int MountDevice(void * DriveData, int DeviceNumber, int DeviceType, DWORD Flags)
+{
+ kal_uint8 retry = 0;
+
+ if(msdc2_handle->mIsInitialized)
+ return SECTOR_SIZE;
+ msdc2_handle->is_init_timeout = KAL_FALSE;
+start:
+ if(!msdc2_handle->mIsPresent)
+ {
+ //dbg_print("not present \r\n");
+
+ #if defined(_NAND_FLASH_BOOTING_)
+ // add the following code for solving plug in or out the SD card during
+ // NFB loading process. The card detection interruptwill disapperared
+ // while interrupt controller is masked.
+ IRQMask(IRQ_MSDC2_CODE);
+ if(MSDC_Reg(MSDC_PS) & MSDC_PS_PIN0)
+ {
+ if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+ msdc2_handle->mIsPresent = KAL_FALSE;
+ else
+ msdc2_handle->mIsPresent = KAL_TRUE;
+ }
+ else
+ {
+ if(msdc2_handle->ins_level == MSDC_IOCTRL_PULL_UP)
+ msdc2_handle->mIsPresent = KAL_TRUE;
+ else
+ msdc2_handle->mIsPresent = KAL_FALSE;
+ }
+ IRQUnmask(IRQ_MSDC2_CODE);
+ #endif // _NAND_FLASH_BOOTING_
+
+ if(!msdc2_handle->mIsPresent)
+ {
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_MSDC_MOUNT_ERROR;
+ }
+ }
+ MSDC_PDNControl2(KAL_FALSE);
+ if(SD_Initialize_2() != NO_ERROR)
+ {
+ goto err_exit;
+ }
+ //if(SD_MountDevice(DeviceType) != FS_NO_ERROR)
+ //return FS_MSDC_MOUNT_ERROR;
+
+ //dbg_print("Mount success! \r\n");
+ MSDC_PDNControl2(KAL_TRUE);
+ return SECTOR_SIZE;
+
+err_exit:
+ if(retry++ <= SD_MAX_RETRY && msdc2_handle->is_init_timeout == KAL_FALSE)
+ {
+ //dbg_print("SD MountDevice failed! retry: %d \r\n",retry);
+ goto start;
+ }
+ #if defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
+ msdc2_handle->mIsPresent = KAL_FALSE;
+ #endif
+ MSDC_PDNControl2(KAL_TRUE);
+ return FS_MSDC_MOUNT_ERROR;
+
+}
+static int MediaChanged(void * DriveData)
+{
+ if(msdc2_handle->mIsPresent)
+ {
+ if(msdc2_handle->mIsInitialized)
+ {
+ return FS_NO_ERROR;
+ }
+ else
+ {
+ return FS_MSDC_PRESNET_NOT_READY;
+ }
+ }
+ return FS_MSDC_NOT_PRESENT;
+}
+
+/*-----------------------------------*/
+static int GetDiskGeometry(void * DriveData, FS_PartitionRecord * DiskGeometry, BYTE * MediaDescriptor)
+{
+ kal_mem_set((void*)DiskGeometry, 0, sizeof * DiskGeometry);
+ DiskGeometry->Sectors = gSD2->mCSD.capacity/512;
+ *MediaDescriptor = MSDC_MEDIA_DESCRIPTOR;
+ if(gSD2->mWPEnabled)
+ return FS_WRITE_PROTECTION;
+ return FS_NO_ERROR;
+}
+
+/*-----------------------------------*/
+static int ShutDown(void * DriveData)
+{
+#ifdef __TST_WRITE_TO_FILE_ONLY__
+ /*error recording: write error log to memory card here*/
+ MSDC_ErrorRecordingReset();
+#endif
+ return FS_NO_ERROR;
+}
+
+FS_Driver FS_SdDrv2 = {
+ MountDevice,
+ ShutDown,
+ ReadSectors,
+ WriteSectors,
+ MediaChanged,
+ DiscardSectors,
+ GetDiskGeometry,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ MSDC_GetCardStatus2
+};
+#endif // (__MSDC_SD_MMC__)
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/sdio_drv.c b/mcu/driver/storage/mc/src/sdio_drv.c
new file mode 100644
index 0000000..b64c066
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sdio_drv.c
@@ -0,0 +1,3460 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * sdio_drv.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * driver of for SDIO card
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ *
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/#include "drv_features.h"
+#include "drv_features.h"
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "drv_comm.h"
+#include "reg_base.h"
+#include "msdc_reg_adap.h"
+//#include "app_buff_alloc.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "sdio_def.h"
+#include "intrCtrl.h"
+#include "sdio_sw.h"
+#include "cache_sw.h"
+#include "init.h"
+#include "dma_hw.h"
+#include "drv_trc.h"
+#include "kal_debug.h"
+/*RHR*/
+#include "drvpdn.h"
+/*RHR*/
+
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON1
+#error "__CLKG_DEFINE__ & DRVPDN_CON1 are all defined"
+#else
+#define DRVPDN_CON1 CG_CON1
+#endif
+
+#ifdef DRVPDN_CON1_SIM
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SIM are all defined"
+#else
+#define DRVPDN_CON1_SIM CG_CON1_SIM
+#endif
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC CG_CON1_MSDC
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR CG_CLR1
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET CG_SET1
+#endif
+
+#ifdef DRVPDN_CON0_MSDC2
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_MSDC2 are all defined"
+#else
+#define DRVPDN_CON0_MSDC2 CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON0_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_CLR are all defined"
+#else
+#define DRVPDN_CON0_CLR CG_CLR0
+#endif
+
+#ifdef DRVPDN_CON0_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_SET are all defined"
+#else
+#define DRVPDN_CON0_SET CG_SET0
+#endif
+
+#endif
+
+
+#if defined(__MSDC_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
+
+#if defined(DRV_MSDC_MT6225_SERIES)
+#define DRV_MSDC_DATA_LATCH_TIMING
+#endif
+
+#pragma arm section zidata = "NONCACHEDZI", rwdata = "NONCACHEDRW" // doublelo modify for DMA non-cached issue
+ kal_uint32 sdio_uncachedU32;
+ kal_uint32 mcudma_flag=128;// mcu:<128byte ; dma:>=128byte
+ kal_uint32 forcemcu=0; // 1:forcemcu
+#pragma arm section zidata, rwdata
+
+#ifdef DCL_MSDC_INTERFACE
+#include "dcl.h"
+SDC_CMD_STATUS SDIO_Initialize(void);
+void SDIO_get_CCCR(kal_uint8 *buf, kal_uint32 bufLen);
+void SDIO_get_FBR(kal_uint8 *buf, kal_uint32 bufLen);
+
+SDIODriver_t sdio_driver_MTK1 = {
+ (DCL_SDIO_REG_WR)SDIO_Register_Write,
+ (DCL_SDIO_REG_WR_ISR)SDIO_Register_Write_isr,
+ (DCL_SDIO_DATA_WR)SDIO_Data_Write,
+ (DCL_SDIO_REG_RD)SDIO_Register_Read,
+ (DCL_SDIO_DATA_RD)SDIO_Data_Read,
+ (DCL_SDIO_CHECK_INTR)SDIO_check_IO_Int,
+ (DCL_SDIO_ENABLE_INTR)SDIO_enable_IO_Int,
+ (DCL_SDIO_INIT)SDIO_Initialize,
+ (DCL_SDIO_ABORT)SDIO_abort_IO,
+ (DCL_SDIO_SW_RST)SDIO_SW_reset,
+ (DCL_SDIO_QRY_BLOCK_SIZE)SDIO_query_BLK_size,
+ (DCL_SDIO_SET_BLOCK_SIZE)SDIO_configure_BLK_size,
+ (DCL_SDIO_GET_BLOCK_SIZE)SDIO_get_BLK_size,
+ (DCL_SDIO_ENABLE_IO)SDIO_enable_IO,
+ (DCL_SDIO_SET_BUS_WIDTH)SDIO_configure_bus,
+ (DCL_SDIO_GET_CCCR)SDIO_get_CCCR,
+ (DCL_SDIO_GET_FBR)SDIO_get_FBR,
+ (DCL_SDIO_CMD52_READ )SDIO_cmd52_read,
+ (DCL_SDIO_CMD52_WRITE)SDIO_cmd52_write,
+ (DCL_SDIO_CMD52_WRITE_READ)SDIO_cmd52_write_read,
+ (DCL_SDIO_CMD53_READ )SDIO_cmd53_read,
+ (DCL_SDIO_CMD53_WRITE)SDIO_cmd53_write,
+ (DCL_SDIO_int_registration)SDIO_int_registration,
+ (DCL_SDIO_MCUDMA_READ)SDIO_mcudma_read,
+ (DCL_SDIO_MCUDMA_WRITE)SDIO_mcudma_write,
+ (DCL_SDIO_CLKPADRED_READ)SDIO_clkpadred_read,
+ (DCL_SDIO_CLKPADRED_WRITE)SDIO_clkpadred_write,
+ (DCL_SDIO_FORCEMCU_READ)SDIO_forcemcu_read,
+ (DCL_SDIO_FORCEMCU_WRITE)SDIO_forcemcu_write,
+ (DCL_SDIO_GETCLK)SDIO_getclk,
+ (DCL_SDIO_SETCLK)SDIO_setclk
+};
+#endif
+__align(4) kal_uint8 sdio_cccr_reg[SDIO_CCCR_SIZE];
+__align(4) kal_uint8 sdio_fbr_reg[SDIO_FBR_SIZE];
+__align(4) kal_uint8 sdio_tuple[SDIO_MAX_FUCN_ID][SDIO_TUPLE_SIZE];
+sdio_dcb_struct gSDIO;
+kal_mutexid sdio_mutex;
+
+void sdio_dummyFunction(void)
+{
+ /*this function is to make source insight more visible since the usage of "__align" is out of the capability of source insight's parser*/
+}
+DCL_SDC_CMD_STATUS SDIO_cmd52_write_read_func(rw_dir_enum rwcmd, kal_bool rawcmd, DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT8 wdata, DCL_UINT8 *rdata, DCL_UINT8 *r5resp)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = rwcmd;
+ cmd52.func = function;
+ cmd52.raw = rawcmd;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = addr;
+ cmd52.data = wdata;
+ status = SDIO_Cmd52(&cmd52);
+ if(r5resp)
+ *r5resp = gSDIO.resp;
+ if(rdata)
+ *rdata = cmd52.data;
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+DCL_SDC_CMD_STATUS SDIO_cmd52_read(DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT8 *rdata, DCL_UINT8 *r5resp)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+ return SDIO_cmd52_write_read_func(SDIO_READ,KAL_FALSE,function,addr,0,rdata,r5resp);
+#endif
+}
+
+
+DCL_SDC_CMD_STATUS SDIO_cmd52_write(DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT8 wdata, DCL_UINT8 *r5resp)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+ return SDIO_cmd52_write_read_func(SDIO_WRITE,KAL_FALSE,function,addr,wdata,0,r5resp);
+#endif
+}
+
+DCL_SDC_CMD_STATUS SDIO_cmd52_write_read(DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT8 wdata, DCL_UINT8 *rdata, DCL_UINT8 *r5resp)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+ return SDIO_cmd52_write_read_func(SDIO_WRITE,KAL_TRUE,function,addr,wdata,rdata,r5resp);
+#endif
+}
+
+DCL_SDC_CMD_STATUS SDIO_cmd53_read_write_func(rw_dir_enum rwcmd, DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT32 data, DCL_SDIO_cmd53_op_enum op, DCL_UINT32 count, DCL_BOOL block, DCL_UINT8 *r5resp)
+{
+ SDC_CMD_STATUS status;
+ cmd53_config_struct cmd53;
+
+ SDIO_dispatch_IO(function);
+ cmd53.rw = rwcmd;
+ cmd53.func = function;
+ cmd53.block = block;
+ cmd53.buffer = data;
+ cmd53.count = count;
+ cmd53.op = op;
+ cmd53.adrs = (kal_uint32)addr;
+ status = SDIO_Cmd53(&cmd53);
+ if(r5resp)
+ *r5resp = gSDIO.resp;
+ SDIO_resume_IO(function);
+ return status;
+}
+
+
+DCL_SDC_CMD_STATUS SDIO_cmd53_read(DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT32 data, DCL_SDIO_cmd53_op_enum op, DCL_UINT32 count, DCL_BOOL block, DCL_UINT8 *r5resp)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+ return SDIO_cmd53_read_write_func(SDIO_READ, function, addr, data, op, count, block, r5resp);
+#endif
+}
+
+
+DCL_SDC_CMD_STATUS SDIO_cmd53_write(DCL_SDIO_function_id_enum function, DCL_UINT32 addr, DCL_UINT32 data, DCL_SDIO_cmd53_op_enum op, DCL_UINT32 count, DCL_BOOL block, DCL_UINT8 *r5resp)
+{
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+ return SDIO_cmd53_read_write_func(SDIO_WRITE, function, addr, data, op, count, block, r5resp);
+#endif
+}
+
+DCL_SDC_CMD_STATUS SDIO_mcudma_read(DCL_UINT32 *rdata)
+{
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ *rdata = mcudma_flag;
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return NO_ERROR;
+}
+
+DCL_SDC_CMD_STATUS SDIO_mcudma_write(DCL_UINT32 wdata)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ mcudma_flag = wdata;
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+
+
+DCL_SDC_CMD_STATUS SDIO_clkpadred_read(DCL_UINT32 *rdata)
+{
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ *rdata = 1&(MSDC_Reg32(MSDC_CLKACB_CFG)>>7);
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return NO_ERROR;
+}
+
+DCL_SDC_CMD_STATUS SDIO_clkpadred_write(DCL_UINT32 wdata)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ if(wdata & 1)
+ {
+ MSDC_SetBits32(MSDC_CLKACB_CFG, MSDC_CLKACB_CFG_CLKPAD_RED);
+ }
+ else
+ {
+ MSDC_ClearBits32(MSDC_CLKACB_CFG, MSDC_CLKACB_CFG_CLKPAD_RED);
+ }
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+
+DCL_SDC_CMD_STATUS SDIO_forcemcu_read(DCL_UINT32 *rdata)
+{
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ *rdata = forcemcu;
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return NO_ERROR;
+}
+
+DCL_SDC_CMD_STATUS SDIO_forcemcu_write(DCL_UINT32 wdata)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ forcemcu = wdata;
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+
+DCL_SDC_CMD_STATUS SDIO_getclk(DCL_UINT32 *rdata)
+{
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ *rdata = gMSDC_Handle->op_clock ;
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return NO_ERROR;
+}
+
+DCL_SDC_CMD_STATUS SDIO_setclk(DCL_UINT32 wdata)//KHZ
+{
+ msdc_clk_setting cs,cs2;
+ DCL_UINT32 temp1,temp2;
+ SDC_CMD_STATUS status=ERR_ERRORS;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ temp1=0;temp2=0x0fffffff;
+ cs2.cardClk = 0;
+ for (cs.sclkf = 0; cs.sclkf < MSDC_SCLKF_NUM; cs.sclkf ++)
+ {
+ for (cs.clksrc = 0; cs.clksrc < MSDC_CLKSRC_NUM; cs.clksrc ++)
+ {
+ cs.cardClk = gMsdcClksrcRate[cs.clksrc] / DIV_SCLKF(cs.sclkf);
+ if(wdata >= cs.cardClk)
+ {
+ temp1 = wdata - cs.cardClk;
+ if (temp1 <= temp2)
+ {
+ temp2 = temp1;
+ cs2.cardClk = cs.cardClk;
+ cs2.clksrc = cs.clksrc;
+ cs2.sclkf = cs.sclkf;
+ if(temp1 == 0)
+ goto SDIO_setclk_return;
+ }
+ }
+ }
+ }
+
+SDIO_setclk_return:
+ if(cs2.cardClk)
+ {
+ MSDC_LSD_ClearBits32(SDC_CFG,SDC_CFG_SIEN);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)cs2.sclkf,MSDC_CFG_SCLKF);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)cs2.clksrc,MSDC_CFG_CLKSRC);
+ MSDC_LSD_SetBits32(SDC_CFG,SDC_CFG_SIEN);
+ gMSDC_Handle->op_clock = cs2.cardClk;
+ status = NO_ERROR;
+ }
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+
+
+#ifdef __MSDC_CD_EINT__
+void SDIO_EINT_Registration()
+{
+ cardDetectionEINTPolarity = KAL_TRUE; // default pull high
+ MSDC_debounceTime = 30;
+
+ EINT_Mask(MSDC_EINT_NO);
+ EINT_Registration(MSDC_EINT_NO, KAL_TRUE, cardDetectionEINTPolarity, SDIO_HISR_Entry, KAL_TRUE); //PMU_CHR_EINT_PIN=8
+ EINT_SW_Debounce_Modify(MSDC_EINT_NO, MSDC_debounceTime); // 32768Hz
+ EINT_UnMask(MSDC_EINT_NO);
+
+}
+#endif
+/*************************************************************************
+* FUNCTION
+* SDIO_Initialize
+*
+* DESCRIPTION
+* SDIO Intialization function
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+extern kal_uint8 MSDC_GetIOCtrlParam(void);
+SDC_CMD_STATUS SDIO_Initialize(void)
+{
+ kal_uint16 rca;
+ #if !defined(DRV_MSDC_DATA_LATCH_TIMING)
+ kal_uint16 iocon;
+ #else
+ kal_uint32 iocon;
+ #endif
+ SDC_CMD_STATUS status;
+ kal_uint32 flags;
+ kal_uint32 retry_count = 0;
+ kal_uint32 count=0;
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+ MSDC_PDNControl(KAL_FALSE);//guilin
+ TurnOnMSDC();
+ #ifdef MSDC_INT
+ kal_retrieve_eg_events(gMSDC_Handle->MSDC_Events,
+ (EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ|EVENT_PINIRQ),
+ KAL_OR_CONSUME,&flags,KAL_NO_SUSPEND);
+ #else
+ /*check if the card is present*/
+ if(MSDC_Reg(MSDC_PS) & MSDC_PS_PIN0)
+ { /*card not present (1)*/
+ gMSDC_Handle->mIsPresent = KAL_FALSE;
+ }
+ else
+ { /*card present (0)*/
+ gMSDC_Handle->mIsPresent = KAL_TRUE;
+ }
+ #endif
+#ifdef __MSDC_NOT_SUPPORT_HOT_PLUG__
+ gMSDC_Handle->mIsPresent = KAL_TRUE;
+#endif
+ /*create mutex*/
+ sdio_mutex = kal_create_mutex("MutexSDIO");
+
+ /* reset msdc*/
+ RESET_MSDC();//MSDC_SetBits32(MSDC_CFG, MSDC_CFG_RST);
+
+ /*Driving current*/
+ //MSDC_WriteReg32(MSDC_IOCON,0xC3);
+ //MSDC_WriteReg32(MSDC_IOCON,0xdb);
+
+ /* set the output driving capability from customization interface*/
+ #if !defined(DRV_MSDC_DATA_LATCH_TIMING)
+ MSDC_SetData(MSDC_IOCON, 0xff, MSDC_GetIOCtrlParam());
+ #else /* !defined(DRV_MSDC_DATA_LATCH_TIMING) */
+
+ iocon = 0;
+ iocon |= MSDC_GetIOCtrlParam();
+ #ifdef MCU_208M
+ iocon |= 0x08000000;
+ #elif defined(MCU_78M)
+ iocon |= 0x04000000;
+ #elif defined(MCU_52M)
+ iocon |= 0x02000000;
+ #endif
+
+ MSDC_SetData32(MSDC_IOCON, 0xff0000ff, iocon);
+
+ #if defined(MCU_52M)
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)1, MSDC_CFG_CRED);
+ #endif
+ #endif /* !defined(DRV_MSDC_DATA_LATCH_TIMING) */
+#if !defined(DRV_MSDC_REG_V3) // guilin
+ /*set pull up in CMD/DAT line configuration*/
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)2,MSDC_CFG_PRCFG1);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)2,MSDC_CFG_PRCFG2);
+#endif // guilin
+ /*set write timeout=(40+1)*65536*(1/serial clock)*/
+ BitFieldWrite32((kal_uint32*)SDC_CFG,(kal_uint32)255,SDC_CFG_DTOC);
+ /*set write timeout=(40+1)*65536*(1/serial clock)*/
+ BitFieldWrite32((kal_uint32*)SDC_CFG,(kal_uint32)15,SDC_CFG_WDOD);
+
+ /* disable 4-bit*/
+ MSDC_ClearBits32(SDC_CFG,SDC_CFG_MDLEN);
+ /* enable serila clock 104/8=13MHz*/
+ //BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)FREQ_1BY8,MSDC_CFG_SCLKF);
+ /* enable serila clock 104/255*4=100KHz*/
+ //MSDC_Reg32(MSDC_CFG)|= 0x8;
+ MSDC_ClearBits32(SDC_CFG,SDC_CFG_SIEN);
+ #ifdef MCU_208M
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)32,MSDC_CFG_SCLKF);
+ #else
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)32,MSDC_CFG_SCLKF);
+ #endif
+
+ gMSDC_Handle->msdc_clock = MSDC_CLOCK;
+ MSDC_SetClock(MSDC_INI_CLOCK);
+#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+ MSDC_SetIOCONRegDLT();
+#endif
+ MSDC_SetBits32(SDC_CFG,SDC_CFG_SIEN);
+ /* config the sdio controller*/
+ /* enable SDIO mode*/
+ MSDC_SetBits32(SDC_CFG, SDC_CFG_SDIO);
+ /* enable 74 SD clk by s/w */
+ MSDC_SetBits32(MSDC_CFG, 0x80);
+ /* enable SDIO interrupt*/
+ MSDC_WriteReg32(SDIO_CFG, 1);
+ {
+ kal_uint32 i;
+ for(i=0;i<100000;i++);
+ }
+
+ /* stop SD clk by s/w */
+ MSDC_ClearBits32(MSDC_CFG, 0x80);
+
+ /*SDIO initialization CMD*/
+ status = SDIO_Cmd5(0);
+ SDIO_STATUS_CHECK;
+ #ifdef _SDIO_DEBUG_
+ dbg_print("write CMD5(0) %d\r\n", status);
+ dbg_print("card OCR %d\r\n", gSDIO.ocr);
+ #endif
+ do
+ {
+ retry_count++;
+ if(gSDIO.ocr & 0x8000)
+ {
+ if((status = SDIO_Cmd5(0x8000))!=NO_ERROR)
+ {
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card deny OCR \r\n");
+ #endif
+
+ }
+ else
+ {
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card accept OCR \r\n");
+ #endif
+ }
+
+ gSDIO.ocr_valid = KAL_TRUE;
+ }
+ else
+ {
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card not match OCR \r\n");
+ dbg_print("uses card's OCR \r\n");
+ #endif
+ if((status = SDIO_Cmd5(gSDIO.ocr))!=NO_ERROR)
+ {
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card deny OCR \r\n");
+ #endif
+ }
+ else
+ {
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card accept OCR \r\n");
+ #endif
+ }
+
+ gSDIO.ocr_valid = KAL_TRUE;
+ }
+ if(retry_count>=100)
+ goto err;
+ }while(gSDIO.io_ready!=KAL_TRUE);
+ MSDC_ClearBits32(SDC_CFG,SDC_CFG_SIEN);
+ #ifdef MCU_208M
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)4,MSDC_CFG_SCLKF);
+ #elif defined(MCU_78M)
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)FREQ_1BY8,MSDC_CFG_SCLKF);
+ #else
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)FREQ_1BY4,MSDC_CFG_SCLKF);
+ #endif /*MCU_208M*/
+
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,1,MSDC_CFG_CLKSRC);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG,1,MSDC_CFG_SCLKF);
+ SD_Use24M_Clock();
+ //SD_Use45M_Clock();
+#if !defined(DRV_MSDC_LATCH_MT6276_SERIES)
+ MSDC_SetIOCONRegDLT();
+#endif
+
+ MSDC_SetBits32(SDC_CFG,SDC_CFG_SIEN);
+ status = SD_ValidateRCA(&rca);
+ SDIO_STATUS_CHECK;
+ #ifdef _SDIO_DEBUG_
+ dbg_print("CMD7 select card \r\n");
+ dbg_print("CMD3 request RCA \r\n");
+ #endif
+
+ status = SD_SelectCard(rca);
+ SDIO_STATUS_CHECK;
+
+ /* get parameters*/
+ /*read CCCR, FBR, CIS tuple*/
+ status=SDIO_read_CCCR();
+ SDIO_STATUS_CHECK;
+ status=SDIO_read_capacity();
+ SDIO_STATUS_CHECK;
+ status=SDIO_read_power_control();
+ SDIO_STATUS_CHECK;
+
+ #if 1/*support 4-bits*/
+ /*enable multiple block interrupt */
+ if(!(SDIO_support_LSC()))
+ {
+#ifndef DRV_MSDC_USING_2ND
+ if(SDIO_support_S4MI()){
+ status=SDIO_enable_E4MI(KAL_TRUE);
+ SDIO_STATUS_CHECK;
+ }
+
+ if(gMSDC_Handle->trySingleLine == KAL_FALSE) //guilin
+ status=SDIO_configure_bus(BIT_4W);
+ else
+ status=SDIO_configure_bus(BIT_1W);
+ SDIO_STATUS_CHECK;
+
+ /* enable serila clock 104/8=13MHz*/
+ //BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)FREQ_1BY8,MSDC_CFG_SCLKF);
+#else
+ //MSDC2 only support 1-bit Mode
+ status=SDIO_configure_bus(BIT_1W);
+ SDIO_STATUS_CHECK;
+#endif
+ }
+ else/*low speed card*/
+ {
+#ifndef DRV_MSDC_USING_2ND
+ if(SDIO_support_4BLS()){
+ status=SDIO_configure_bus(BIT_4W);
+ SDIO_STATUS_CHECK;
+ }
+#else
+ //MSDC2 only support 1-bit Mode
+#endif
+ }
+ #else
+/* under construction !*/
+ #endif
+ status=SDIO_read_CIS(SDIO_FUCN_0);
+ SDIO_STATUS_CHECK;
+ /*enable I/O function*/
+ for(count=SDIO_FUCN_1;count<SDIO_MAX_FUCN_ID;count++)
+ {
+ kal_uint32 retry=0;
+ kal_bool ready;
+ for(retry=0;retry<100;retry++)
+ {
+ status=SDIO_enable_IO(count, KAL_TRUE);
+ SDIO_STATUS_CHECK;
+ status = SDIO_check_IO_ready(count, &ready);
+ SDIO_STATUS_CHECK;
+ if(ready==KAL_TRUE)
+ break;
+ }
+ status=SDIO_read_FBR(count);
+ SDIO_STATUS_CHECK;
+ for(retry=0;retry<100;retry++)
+ {
+ status=SDIO_read_CIS(count);
+ if(status==NO_ERROR)
+ break;
+ }
+
+ }
+ if(SDIO_support_MPS()){
+ status=SDIO_enable_MPS(KAL_TRUE);
+ SDIO_STATUS_CHECK;
+ }
+
+ status=SDIO_read_CCCR();
+ SDIO_STATUS_CHECK;
+ /* for Sandisk SDIO WIFI card*/
+#if 0//guilin test #ifdef __MSDC_BASIC_LOAD__
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+
+err:
+ if(status != NO_ERROR)
+ {
+ tst_sys_trace("sdio_initialize error \r\n");
+ kal_prompt_trace(MOD_MSDC_HISR,"sdio_initialize error");
+ kal_mem_set(gSD,0,sizeof(gSD));
+ gMSDC_Handle->mIsInitialized = KAL_FALSE;
+ }
+ else
+ {
+ tst_sys_trace("sdio_initialize ok \r\n");
+ kal_prompt_trace(MOD_MSDC_HISR,"sdio_initialize ok");
+ gMSDC_Handle->mIsInitialized = KAL_TRUE;
+
+ return status;
+}
+
+/*SDIO commnad set*/
+/*************************************************************************
+* FUNCTION
+* SD_StopTrans
+*
+* DESCRIPTION
+* Stop Muli-Block operation
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Use polling to check write command completely
+*************************************************************************/
+SDC_CMD_STATUS SD_StopTrans_poll(void)
+{
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_poll(SDC_CMD_CMD12,SDC_NO_ARG))!=NO_ERROR)
+ return status;
+ /*Read R1b*/
+ if((status = SD_CheckStatus())!=NO_ERROR)
+ return status;
+
+
+#ifdef SD_STOP_SLOW
+ //while(MSDC_Reg(SDC_STA) & SDC_STA_R1BSY);
+ //do{
+ //SD_GetStatus(gSD->mRCA,(kal_uint32*)&status);
+ //}while((status & R1_CUR_STATE) >> 9 != TRAN_STA);
+#endif
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_WaitCardNotBusy
+*
+* DESCRIPTION
+* Wait until card is not busy (R1b)
+*
+* PARAMETERS
+*
+* RETURNS
+* void
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+/*R1b*/
+void SDIO_WaitCardNotBusy(void)
+{
+ while( MSDC_Reg(SDC_STA) & SDC_STA_R1BSY);
+}
+/*************************************************************************
+* FUNCTION
+* SD_WaitCmdRdyOrTo_poll
+*
+* DESCRIPTION
+* write command completely
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitCmdRdyOrTo_poll(void)
+{
+ kal_uint16 sdc_cmdsta = 0;
+ kal_uint32 counter = 0;
+
+ while(MSDC_Reg(SDC_STA)&0x2){};
+ #if 1
+ do{
+ sdc_cmdsta = MSDC_Reg(SDC_CMDSTA);
+ if(sdc_cmdsta & SDC_CMDSTA_CMDTO)
+ return ERR_CMD_TIMEOUT;
+ else if(sdc_cmdsta & SDC_CMDSTA_RSPCRCERR)
+ return ERR_CMD_RSPCRCERR;
+ else if(sdc_cmdsta & SDC_CMDSTA_CMDRDY)
+ break;
+ }while(counter++ < 10000);
+ #endif
+ if (counter >= 10000)
+ {
+ return ERR_NORESP;
+ }
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_WaitCmdRdyOrTo_poll
+*
+* DESCRIPTION
+* write command completely
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Send_Cmd_poll(kal_uint32 cmd, kal_uint32 arg)
+{
+ SDC_CMD_STATUS status;
+ volatile kal_uint16 sdc_cmdsta,sdc_datsta;
+// kal_prompt_trace(MOD_MSDC_HISR,"[%s %d]cmd=%d(0x%x) arg=0x%x",__FUNCTION__,__LINE__,cmd&0x03f,cmd,arg);
+ /*check the controller is ready (stop transaction will fail)*/
+ //if( != SDC_CMD_CMD12)
+ if(!(SDC_CMD_STOP&cmd))
+ while(SD_IS_SDC_BUSY && gMSDC_Handle->mIsPresent);
+ else
+ while(SD_IS_CMD_BUSY && gMSDC_Handle->mIsPresent);
+
+ sdc_cmdsta = MSDC_Reg(SDC_CMDSTA);
+ sdc_datsta = MSDC_Reg(SDC_DATSTA);
+
+ /* fill out the argument*/
+ MSDC_WriteReg32(SDC_ARG,arg);
+ /* launch the command*/
+ MSDC_WriteReg32(SDC_CMD,cmd);
+ if((status = SD_WaitCmdRdyOrTo_poll())!=NO_ERROR){
+// kal_prompt_trace(MOD_MSDC_HISR,"[%s %d]cmd=%d(0x%x) arg=0x%x status=0x%x",__FUNCTION__,__LINE__,cmd&0x03f,cmd,arg,status);
+ return status;
+}
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_Cmd53
+*
+* DESCRIPTION
+* IO_RW_DIRECT command
+*
+* PARAMETERS
+* command 53 structrue
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_uint8 debug_flag = 0;
+SDC_CMD_STATUS SDIO_Cmd53(cmd53_config_struct *p)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 arg;
+ kal_uint32 cmd;
+ kal_uint32 *ptr = (kal_uint32 *) p->buffer;
+
+//guilin ASSERT(p->adrs < 0x20000 && p->count < 0x200);
+ #ifdef MSDC_DMA
+ /*
+ if (INT_QueryIsCachedRAM(ptr, p->count))
+ {
+ EXT_ASSERT(0, (kal_uint32)ptr, p->count, 0);
+ }
+*/
+#ifdef MSDC_CACHED_SUPPORT
+ /*tell buffer type each time this function called*/
+ if (INT_QueryIsCachedRAM(ptr, p->count)){
+ gMSDC_Handle->isCachedBuf = KAL_TRUE;
+ }
+ else
+ gMSDC_Handle->isCachedBuf = KAL_FALSE;
+#endif
+
+ #endif /* MSDC_DMA */
+#ifndef DRV_MSDC_USING_2ND
+ IRQMask(IRQ_MSDC_CODE);
+#else
+ IRQMask(IRQ_MSDC2_CODE);
+#endif
+ MSDC_CLR_FIFO(); // guilin
+
+ arg = (p->rw << 31)|(p->func << 28)|(p->block << 27)|(p->op << 26)|(p->adrs << 9)|(p->count);
+ cmd = SDC_CMD_CMD53 | (p->rw << 13);
+ if(p->block)
+ {
+ cmd |= (2 << 11); // multi-block
+ BitFieldWrite32((kal_uint32*)SDC_CFG,gSDIO.block_size[1],SDC_CFG_BLKLEN);
+ }
+ else
+ {
+ cmd |= (1 << 11); // single-block
+ BitFieldWrite32((kal_uint32*)SDC_CFG,p->count,SDC_CFG_BLKLEN);
+ }
+
+ // send cmd53
+ //if(p->rw == SDIO_WRITE)
+ if(0)/*R1b*/
+ {
+ cmd &= ~0x380;
+ cmd |= 0x380;
+ }
+ else/*R1*/
+ {
+ cmd &= ~0x380;
+ cmd |= 0x80;
+ }
+ #ifdef MSDC_DMA
+ if ((forcemcu==0)&&(p->block ==1 || (p->block ==0 && p->count >= mcudma_flag) )) // guilin
+ {
+ kal_uint32 total_size=0;
+
+ EnableMSDC_DMA();
+ if(p->block)
+ total_size = (p->count*gSDIO.block_size[p->func]);
+ else
+ total_size =p->count;
+ total_size=total_size>>2;
+
+ if(p->rw == SDIO_READ)
+ MSDC_DMATransferFirst((kal_uint32)ptr,total_size,KAL_FALSE);
+ else
+ MSDC_DMATransferFirst((kal_uint32)ptr,total_size,KAL_TRUE);
+ }
+ #endif /* MSDC_DMA */
+
+ if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+ {
+ goto ERROR_EXIT;
+ }
+ MSDC_LSD_ReadReg32(SDC_RESP0,&status);
+ status = (status & 0xff00)>>8;
+ gSDIO.resp = status;
+ if(gSDIO.resp & 0xcf)//guilin
+ {
+ status = gSDIO.resp;
+ goto ERROR_EXIT;
+ }
+ /* start data transfer*/
+ if(p->rw == SDIO_READ)
+ {
+ kal_uint32 i;
+ #ifdef MSDC_DMA
+ if ((forcemcu==0)&&(p->block ==1 || (p->block ==0 && p->count >= mcudma_flag) )) // guilin
+ {
+ status = MSDC_DMATransferFinal();
+ /*check DMA*/
+ if(status != NO_ERROR)
+ goto ERROR_EXIT;
+ /*check Data ready*/
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+
+ DisableMSDC_DMA();
+ MSDC_CLR_FIFO();
+ }
+ else
+ #endif/*MSDC_DMA*/
+ if(p->block)
+ {
+ kal_uint32 total;
+
+ total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+ for(i=0;i< total;)
+ {
+ if(!MSDC_IS_FIFO_EMPTY)
+ {
+ *(ptr+i) = MSDC_Reg32(MSDC_DAT);
+ i++;
+ if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+ }
+ }
+ else
+ {
+ for(i=0;i< (p->count+3)>>2;)
+ {
+ if(!MSDC_IS_FIFO_EMPTY)
+ {
+ *(ptr+i) = MSDC_Reg32(MSDC_DAT);
+ i++;
+ if((i%((p->count+3)>> 2)==0)&&(i!=0))
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+ }
+ }
+ }
+ else
+ { // SDIO_WRITE
+ kal_uint32 i;
+ #ifdef MSDC_DMA
+ if ((forcemcu==0)&&(p->block ==1 || (p->block ==0 && p->count >= mcudma_flag) )) // guilin
+ {
+ status = MSDC_DMATransferFinal();
+ /*check DMA*/
+ if(status != NO_ERROR)
+ goto ERROR_EXIT;
+ /*check Data ready*/
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+
+ DisableMSDC_DMA();
+ MSDC_CLR_FIFO();
+ }
+ else
+ #endif/*MSDC_DMA*/
+ if(p->block)
+ {
+ kal_uint32 total;
+
+ total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+ for(i=0;i< total;)
+ {
+ if(!MSDC_IS_FIFO_FULL)
+ {
+ MSDC_WriteReg32(MSDC_DAT, *(ptr+i));
+ i++;
+ if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+ }
+ }
+ else
+ {
+ for(i=0;i< (p->count+3)>>2;)
+ {
+ if(!MSDC_IS_FIFO_FULL)
+ {
+ MSDC_WriteReg32(MSDC_DAT, *(ptr+i));
+ i++;
+ if(i%((p->count+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+ }
+ }
+ }
+ //SD_StopTrans_poll();
+ /*Blue modify for Inno SDIO card*/
+#if 0
+/* under construction !*/
+/* under construction !*/
+#endif
+ /*Blue modify for Innofidi SDIO card. Innofidi SDIO card has issue on this command, when 1) block mode read, 2)limited block counts, 3) no timeout occur, we skill this command*/
+ if((p->block) && (SDIO_READ == p->rw) && (p->count < 0x200) && (KAL_FALSE == gMSDC_Handle->is_timeout)){
+ /*do nothing*/
+ }
+ else{
+ SDIO_stop();
+ }
+
+#ifndef DRV_MSDC_USING_2ND
+ IRQUnmask(IRQ_MSDC_CODE);
+#else
+ IRQUnmask(IRQ_MSDC2_CODE);
+#endif
+ RESET_MSDC(); // guilin
+ MSDC_CLR_FIFO(); // guilin
+
+ return NO_ERROR;
+ ERROR_EXIT:
+ {
+ kal_uint32 tmp;
+ #ifdef MSDC_DMA
+ DisableMSDC_DMA();
+ #endif
+ if(p->block)
+ SD_StopTrans_poll();
+ SDIO_stop();
+ MSDC_LSD_ReadReg32(SDC_CMDSTA,&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA,&tmp);
+ MSDC_CLR_FIFO();
+#ifndef DRV_MSDC_USING_2ND
+ IRQUnmask(IRQ_MSDC_CODE);
+#else
+ IRQUnmask(IRQ_MSDC2_CODE);
+#endif
+ return status;
+ }
+}
+
+/*SDIO_Cmd53_poll*/
+SDC_CMD_STATUS SDIO_Cmd53_isr(cmd53_config_struct *p)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 arg;
+ kal_uint32 cmd,i;
+ kal_uint32 *ptr = (kal_uint32 *) p->buffer;
+
+ ASSERT(p->adrs < 0x20000 && p->count < 0x200);
+ arg = (p->rw << 31)|(p->func << 28)|(p->block << 27)|(p->op << 26)|(p->adrs << 9)|(p->count);
+ cmd = SDC_CMD_CMD53 | (p->rw << 13);
+ if(p->block)
+ {
+ cmd |= (2 << 11); // multi-block
+ BitFieldWrite32((kal_uint32*)SDC_CFG,gSDIO.block_size[1],SDC_CFG_BLKLEN);
+ }
+ else
+ {
+ cmd |= (1 << 11); // single-block
+ BitFieldWrite32((kal_uint32*)SDC_CFG,p->count,SDC_CFG_BLKLEN);
+ }
+
+ // send cmd53
+ //if(p->rw == SDIO_WRITE)
+ if(0)/*R1b*/
+ {
+ cmd &= ~0x380;
+ cmd |= 0x380;
+ }
+ else/*R1*/
+ {
+ cmd &= ~0x380;
+ cmd |= 0x80;
+ }
+ if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+ {
+ goto ERROR_EXIT;
+ }
+ MSDC_LSD_ReadReg32(SDC_RESP0,&status);
+ status = (status & 0xff00)>>8;
+ gSDIO.resp = status;
+ /* start data transfer*/
+ if(p->rw == SDIO_READ)
+ {
+
+ if(p->block)
+ {
+ kal_uint32 total;
+
+ total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+ for(i=0;i< total;)
+ {
+
+ if(!MSDC_IS_FIFO_EMPTY)
+ {
+ *(ptr+i) = MSDC_Reg32(MSDC_DAT);
+ i++;
+ if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+
+ }
+ }
+ else
+ {
+ for(i=0;i< (p->count+3)>>2;)
+ {
+ if(!MSDC_IS_FIFO_EMPTY)
+ {
+ *(ptr+i) = MSDC_Reg32(MSDC_DAT);
+ i++;
+ if(i%((p->count+3)>> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+
+ }
+
+ }
+ }
+ else
+ { // SDIO_WRITE
+ if(p->block)
+ {
+ kal_uint32 total;
+
+ total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+ for(i=0;i< total;)
+ {
+ if(!MSDC_IS_FIFO_FULL)
+ {
+ MSDC_WriteReg32(MSDC_DAT, *(ptr+i));
+ i++;
+ if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+
+
+ }
+ }
+ else
+ {
+ for(i=0;i< (p->count+3)>>2;)
+ {
+ if(!MSDC_IS_FIFO_FULL)
+ {
+ MSDC_WriteReg32(MSDC_DAT, *(ptr+i));
+ i++;
+ if(i%((p->count+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+
+ }
+
+ }
+ }
+
+ /*Blue modify for Inno SDIO card*/
+ if((p->block) && (MSDC_Reg(SDC_STA) & SDC_STA_DATBUSY) )
+ SD_StopTrans_poll();
+ SDIO_stop();
+ return NO_ERROR;
+ ERROR_EXIT:
+ {
+ kal_uint32 tmp;
+ #ifdef MSDC_DMA
+ DisableMSDC_DMA();
+ #endif
+ if(p->block)
+ SD_StopTrans_poll();
+ SDIO_stop();
+ MSDC_LSD_ReadReg32(SDC_CMDSTA,&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA,&tmp);
+ MSDC_CLR_FIFO();
+ return status;
+ }
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_Cmd52
+*
+* DESCRIPTION
+* IO_RW_DIRECT command
+*
+* PARAMETERS
+* command 52 structrue
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+/* refer to the IO_RW_DIRECT command (CMD52) in SDIO 1.1 chapter 5.1*/
+SDC_CMD_STATUS SDIO_Cmd52(cmd52_config_struct *p)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 arg = 0;
+ kal_uint32 cmd;
+
+#ifndef DRV_MSDC_USING_2ND
+ IRQMask(IRQ_MSDC_CODE);
+#else
+ IRQMask(IRQ_MSDC2_CODE);
+#endif
+
+ if(p->rw == SDIO_WRITE)
+ {
+ arg |= (IO_ARG_RW_FLAG|p->data);
+ }
+ arg |= ((p->raw << 27)|(p->func << 28)|(p->adrs <<9));
+
+ cmd = SDC_CMD_CMD52 ;
+ if(p->stop)
+ cmd |= SDC_CMD_STOP;
+
+ if(p->stop)
+ //if(0)
+ {
+ cmd &= ~0x380;
+ cmd |= 0x380;
+ }
+ #if 1
+ else
+ {
+ cmd &= ~0x380;
+ cmd |= 0x80;
+ }
+ #endif
+ if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+ goto ERROR_EXIT;
+ while(MSDC_Reg(SDC_STA) & SDC_STA_R1BSY);
+ MSDC_LSD_ReadReg32(SDC_RESP0,&status);
+ if((p->rw == SDIO_READ)||((p->rw==SDIO_WRITE)&&(p->raw==KAL_TRUE)) ) // guilin
+ {
+ p->data = status & 0xff;
+ }
+ status = (status & 0xff00)>>8;
+ gSDIO.state = (status & 0x30)>>4;
+ gSDIO.resp = status;
+ if(gSDIO.resp & R5_ERROR_CHECK)//guilin
+ {
+ status = gSDIO.resp;
+ goto ERROR_EXIT;
+ }
+#ifndef DRV_MSDC_USING_2ND
+ IRQUnmask(IRQ_MSDC_CODE);
+#else
+ IRQUnmask(IRQ_MSDC2_CODE);
+#endif
+
+ return NO_ERROR;
+ ERROR_EXIT:
+ {
+ kal_uint32 tmp;
+ MSDC_LSD_ReadReg32(SDC_CMDSTA,&tmp);
+ MSDC_CLR_FIFO();
+#ifndef DRV_MSDC_USING_2ND
+ IRQUnmask(IRQ_MSDC_CODE);
+#else
+ IRQUnmask(IRQ_MSDC2_CODE);
+#endif
+ return status;
+ }
+
+
+}
+SDC_CMD_STATUS SDIO_Cmd52_isr(cmd52_config_struct *p)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 arg = 0;
+ kal_uint32 cmd;
+
+ if(p->rw == SDIO_WRITE)
+ {
+ arg |= (IO_ARG_RW_FLAG|p->data);
+ }
+ arg |= ((p->raw << 27)|(p->func << 28)|(p->adrs <<9));
+
+ cmd = SDC_CMD_CMD52 ;
+ if(p->stop)
+ cmd |= SDC_CMD_STOP;
+ if(p->stop)
+ //if(0)
+ {
+ cmd &= ~0x380;
+ cmd |= 0x380;
+ }
+ #if 1
+ else
+ {
+ cmd &= ~0x380;
+ cmd |= 0x80;
+ }
+ #endif
+ if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+ goto ERROR_EXIT;
+ while(MSDC_Reg(SDC_STA) & SDC_STA_R1BSY);
+ MSDC_LSD_ReadReg32(SDC_RESP0,&status);
+ if(p->rw == SDIO_READ)
+ {
+ p->data = status & 0xff;
+ }
+ status = (status & 0xff00)>>8;
+ gSDIO.state = (status & 0x30)>>4;
+ gSDIO.resp = status;
+ return NO_ERROR;
+ /*error handle*/
+ ERROR_EXIT:
+ {
+ kal_uint32 tmp;
+ MSDC_LSD_ReadReg32(SDC_CMDSTA,&tmp);
+ MSDC_CLR_FIFO();
+ return status;
+ }
+
+}
+
+/* for SDIO*/
+/*************************************************************************
+* FUNCTION
+* SDIO_Cmd5
+*
+* DESCRIPTION
+* SDIO initialization command
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* it is similar to the operation of ACMD41 for SD memory cards.
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_Cmd5(kal_uint32 ocr)
+{
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_poll(SDC_CMD_CMD5,ocr))!=NO_ERROR)
+ return status;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ /*we use different flag to distinguish SD and MMC, we have to set this flag to enable high density support*/
+ gSD->flags |= SD_FLAG_SD_TYPE_CARD;
+#endif
+ /*read R4*/
+ MSDC_LSD_ReadReg32(SDC_RESP0,&status);
+ gSDIO.ocr = status &0xFFFFFF;
+ status >>= 24;
+ gSDIO.num_func = (kal_uint8)(status & 0x70) >> 4;
+ gSDIO.mem_present = ((status & 0x08) != 0) ;
+ gSDIO.io_ready = ((status & SDIO_R4_CARD_READY)!=0);
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card function number %d\r\n", gSDIO.num_func);
+ dbg_print("memory card present %d\r\n", gSDIO.mem_present);
+ dbg_print("card ready %d\r\n", gSDIO.io_ready);
+ #endif
+ return NO_ERROR;
+}
+
+void SDIO_dispatch_IO(SDIO_function_id_enum function)
+{
+ /*single function*/
+ kal_take_mutex(sdio_mutex);
+ /*multiple function*/
+ /*not support now*/
+}
+
+void SDIO_resume_IO(SDIO_function_id_enum function)
+{
+ /*single function*/
+ kal_give_mutex(sdio_mutex);
+ /*multiple function*/
+ /*not support now*/
+
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_CIS
+*
+* DESCRIPTION
+* This function is to read function's CIS
+*
+* PARAMETERS
+* function: function id
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* This function is only user for SDIO bus driver
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_CIS(SDIO_function_id_enum function)
+{
+ kal_uint32 i=0, j=0;
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+ ASSERT(function<8);
+ /* read all configuration register of CCCR*/
+ while(1)
+ {
+ cmd52.rw = SDIO_READ;
+ cmd52.func = SDIO_FUCN_0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ if(function==0)
+ cmd52.adrs =(kal_uint32)((sdio_cccr_reg[11]<<16)|(sdio_cccr_reg[10]<<8)|
+ (sdio_cccr_reg[9])+i);
+ else
+ cmd52.adrs =(kal_uint32)((sdio_fbr_reg[11]<<16)|(sdio_fbr_reg[10]<<8)|
+ (sdio_fbr_reg[9])+i);
+ cmd52.data = 0;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ sdio_tuple[function][i]=cmd52.data;
+ i++;
+ if(cmd52.data==CISTPL_NULL||cmd52.data==CISTPL_END)
+ return NO_ERROR;
+ else
+ {
+ kal_uint32 tuple_size=0;
+ cmd52.rw = SDIO_READ;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs++;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ sdio_tuple[function][i]=cmd52.data;
+ tuple_size=cmd52.data;
+ i++;
+ for(j=0;j<tuple_size;j++)
+ {
+ cmd52.adrs++;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ sdio_tuple[function][i]=cmd52.data;
+ i++;
+ }
+ }
+ }
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_CCCR_ver
+*
+* DESCRIPTION
+* This function is to read card's CCCR version
+*
+* PARAMETERS
+* *version
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+/*read SDIO CCCR version*/
+SDC_CMD_STATUS SDIO_read_CCCR_ver(kal_uint8 *version)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+
+ #if 1
+ *version=sdio_cccr_reg[0]&SDIO_CCCR_VERISON_MASK;
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ return status;
+
+}
+
+SDC_CMD_STATUS SDIO_stop(void)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+
+ cmd52_config_struct cmd52;
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_TRUE;
+ cmd52.adrs = 6;
+ cmd52.data = 1;
+ status = SDIO_Cmd52(&cmd52);
+ /*wait card is not busy*/
+ SDIO_WaitCardNotBusy();
+ return status;
+}
+SDC_CMD_STATUS SDIO_WaitDatRdyOrTo(void)
+{
+ // maybe have to add a timer
+ register kal_uint16 sdc_datsta = 0;
+
+ int counter = 0;
+ //while(MSDC_Reg(SDC_STA)&0x4){};
+ do{
+ sdc_datsta = MSDC_Reg(SDC_DATSTA);
+
+ /*Blue modify for Inno SDIO card, in SDIO, this data timeout is legal*/
+ if((0 == MSDC_Reg(DMA_RLCT(gMSDC_Handle->msdc_dmaport))) && (0x3 == sdc_datsta))
+ sdc_datsta = 0x1;
+
+ if(sdc_datsta & SDC_DATSTA_DATTO)
+ return ERR_DAT_TIMEOUT;
+ else if(sdc_datsta & SDC_DATSTA_DATCRCERR)
+ return ERR_DAT_CRCERR;
+ else if(sdc_datsta & SDC_DATSTA_BLKDONE)
+ break;
+ }while(1);//(counter++ < 1000);
+
+ if (counter >= 1000)
+ return ERR_NORESP;
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_SDIO_ver
+*
+* DESCRIPTION
+* This function is to read card's SDIO version
+*
+* PARAMETERS
+* *version
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+/*read SDIO spec version*/
+SDC_CMD_STATUS SDIO_read_SDIO_ver(kal_uint8 *version)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+
+ #if 1
+ *version=sdio_cccr_reg[0]&SDIO_VERISON_MASK>>SDIO_VERISON_SHIFT;
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ return status;
+
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_SD_ver
+*
+* DESCRIPTION
+* This function is to read card's SD version
+*
+* PARAMETERS
+* *version
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+/*read SD spec version*/
+SDC_CMD_STATUS SDIO_read_SD_ver(kal_uint8 *version)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+
+ #if 1
+ *version=sdio_cccr_reg[1]&SDIO_SD_VERISON_MASK;
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_CCCR
+*
+* DESCRIPTION
+* This function is to read card CCCR
+*
+* PARAMETERS
+* *version
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_CCCR(void)
+{
+ #if 1
+ kal_uint32 i;
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ for(i=0;i<SDIO_CCCR_SIZE;i++)
+ {
+ cmd52.adrs =i;
+ status = SDIO_Cmd52(&cmd52);
+ if(status != NO_ERROR)
+ return status;
+ sdio_cccr_reg[i]=cmd52.data;
+ }
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_FBR
+*
+* DESCRIPTION
+* This function is to read card FBR
+*
+* PARAMETERS
+* function: function id
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_FBR(SDIO_function_id_enum function)
+{
+ #if 1 /*to cover 5911 issue*/
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+ kal_uint32 i=0;
+
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.data = 0;
+ for(i=0;i<SDIO_FBR_SIZE;i++)
+ {
+ cmd52.adrs = 0x100*function+i;
+ status=SDIO_Cmd52(&cmd52);
+ sdio_fbr_reg[i] = cmd52.data;
+ }
+
+ return status;
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_power_control
+*
+* DESCRIPTION
+* This function is to read card's power control
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_power_control(void)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0x12;
+ cmd52.data = 0;
+ status=SDIO_Cmd52(&cmd52);
+ gSDIO.power_control = cmd52.data;
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_MPS
+*
+* DESCRIPTION
+* This function is to query card's power control
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+kal_bool SDIO_support_MPS(void)
+{
+ return ((gSDIO.power_control&0x1));
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_enable_MPS
+*
+* DESCRIPTION
+* This function is to enable card's power control
+*
+* PARAMETERS
+* enable: enable or disable
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_MPS(kal_bool enable)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0x12;
+ if(enable)
+ cmd52.data |= 0x2;
+ else
+ cmd52.data &= ~0x2;
+
+ status=SDIO_Cmd52(&cmd52);
+ if(enable)
+ gSDIO.power_control |= 0x2;
+ else
+ gSDIO.power_control &= ~0x2;
+
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_capacity
+*
+* DESCRIPTION
+* This function is to read card's capacity
+*
+* PARAMETERS
+* enable: None
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_capacity(void)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+ #if 1
+ gSDIO.capability = sdio_cccr_reg[8];
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_SDC
+*
+* DESCRIPTION
+* This function is to query if card can support SDC
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+/*query card capacity*/
+kal_bool SDIO_support_SDC(void)
+{
+ return ((gSDIO.capability&0x1));
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_SMB
+*
+* DESCRIPTION
+* This function is to query if card can support Multiple Block
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_SMB(void)
+{
+ return ((gSDIO.capability&0x2)>>1);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_SRW
+*
+* DESCRIPTION
+* This function is to query if card can support Suspend/Resume
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_SRW(void)
+{
+ return ((gSDIO.capability&0x4)>>2);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_SBS
+*
+* DESCRIPTION
+* This function is to query if card can support Read/Wait
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_SBS(void)
+{
+ return ((gSDIO.capability&0x8)>>3);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_S4MI
+*
+* DESCRIPTION
+* This function is to query if card can support interrupt during multiple block
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_S4MI(void)
+{
+ return ((gSDIO.capability&0x10)>>4);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_enable_E4MI
+*
+* DESCRIPTION
+* This function is to enable interrupt during multiple block
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_E4MI(kal_bool enable)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+ kal_uint8 temp_data;
+
+ if(!SDIO_support_S4MI())
+ return SDIO_4MI_NOT_SUPPORT;
+
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 8;
+ if(enable)
+ {
+ cmd52.data = 0x20;
+ temp_data=0x20;
+ }
+ else
+ {
+ cmd52.data = 0;
+ temp_data=0;
+ }
+ if((status = SDIO_Cmd52(&cmd52))==NO_ERROR)
+ {
+ /*double check*/
+ cmd52.rw = SDIO_READ;
+ status = SDIO_Cmd52(&cmd52);
+ if((cmd52.data&0x20)!=temp_data)
+ ASSERT(0);
+
+ if(enable)
+ gSDIO.capability|=0x20;
+ else
+ gSDIO.capability&=~0x20;
+ }
+
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_enable_E4MI
+*
+* DESCRIPTION
+* This function is to query if card is a low speed card
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_LSC(void)
+{
+ return ((gSDIO.capability&0x40)>>6);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_4BLS
+*
+* DESCRIPTION
+* This function is to query if card can support 4-bits in low speed card
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_4BLS(void)
+{
+ return ((gSDIO.capability&0x80)>>7);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_configure_bus
+*
+* DESCRIPTION
+* This function is to configure bus width
+*
+* PARAMETERS
+* bus: bus width
+*
+* RETURNS
+* bus
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_configure_bus(SD_BITWIDTH bus)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 7;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ {
+ return status;
+ }
+ cmd52.data &= ~0x3;
+ cmd52.data |= (bus|0x80);/*also disable card detection*/
+ cmd52.rw = SDIO_WRITE;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ {
+ return status;
+ }
+ gSDIO.bit_width=bus;
+ if(bus==BIT_4W)
+ MSDC_SetBits32(SDC_CFG,SDC_CFG_MDLEN);
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_enable_IO
+*
+* DESCRIPTION
+* This function is to enable function
+*
+* PARAMETERS
+* function: function id
+* enable: enable or disable
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_IO(SDIO_function_id_enum function, kal_bool enable)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 2;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ {
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+ }
+ if(enable)
+ cmd52.data |= (function<<1);
+ else
+ cmd52.data &= ~(function<<1);
+
+ cmd52.rw = SDIO_WRITE;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ {
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+ }
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_check_IO_ready
+*
+* DESCRIPTION
+* This function is to check function status
+*
+* PARAMETERS
+* function: function id
+* *ready: ready or not
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_ready(SDIO_function_id_enum function, kal_bool *ready)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 3;
+ status = SDIO_Cmd52(&cmd52);
+ *ready=(cmd52.data&(1<<function))>>function;
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_enable_IO_Int
+*
+* DESCRIPTION
+* This function is to configure function interrupt enable
+*
+* PARAMETERS
+* function: function id
+* enable: enable or diable
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_IO_Int(SDIO_function_id_enum function, kal_bool enable)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 4;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ {
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+ }
+ if(enable)
+ cmd52.data |= (1<<function);
+ else
+ cmd52.data &= ~(1<<function);
+
+ cmd52.rw = SDIO_WRITE;
+
+ status = SDIO_Cmd52(&cmd52);
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_int_registration
+*
+* DESCRIPTION
+* This function is to register interrupt handler
+*
+* PARAMETERS
+* function: function id
+* func: interrupt handler
+* RETURNS
+* None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void SDIO_int_registration(SDIO_function_id_enum function, void (func)(void))
+{
+ gSDIO.callback[function]=func;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_HISR_Entry
+*
+* DESCRIPTION
+* This function is to handle SDIO interrupt
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS int_status;
+void SDIO_HISR_Entry(void)
+{
+
+ cmd52_config_struct cmd52;
+ cmd53_config_struct cmd53;
+ kal_uint8 uvalue[4];
+ kal_uint32 count;
+ if(gSDIO.state!=CMD&&gSDIO.state!=TRN)
+ {
+ #ifdef MSDC_INT
+ kal_set_eg_events(gMSDC_Handle->MSDC_Events,EVENT_SDMCIRQ,KAL_OR);
+ #endif
+ }
+ else
+ {
+ #if 1
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 5;
+
+ if((int_status = SDIO_Cmd52_isr(&cmd52))==NO_ERROR)
+ {
+ //kalDevRegWrite//HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR);
+ uvalue[0]=2;
+ uvalue[1]=0;
+ uvalue[2]=0;
+ uvalue[3]=0;
+ cmd53.adrs = 0x04;
+ cmd53.block = KAL_FALSE;
+ cmd53.buffer=(kal_uint32)&uvalue[0];
+ cmd53.count =4;
+ cmd53.func=DCL_SDIO_FUCN_1;
+ cmd53.op=DCL_SDIO_FIX;
+ cmd53.rw=SDIO_WRITE;
+ SDIO_Cmd53_isr(&cmd53);
+
+//guilin for(count=SDIO_FUCN_1;count<SDIO_MAX_FUCN_ID;count++)
+//guilin {
+//guilin if(cmd52.data&(1<<count))
+//guilin gSDIO.callback[count]();
+//guilin }
+ }
+ else
+ {
+ /*dbg_print("int read failed\r\n");*/
+ }
+ #endif
+ }
+}
+
+/*************************************************************************
+* FUNCTION
+* SDIO_check_IO_Int
+*
+* DESCRIPTION
+* This function is to check interrupt status
+*
+* PARAMETERS
+* function: function id
+* *pending: interrupt status
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_Int(SDIO_function_id_enum function, kal_bool *pending)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 5;
+ status = SDIO_Cmd52(&cmd52);
+ *pending=(cmd52.data&(1<<function))>>function;
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_configure_BLK_size
+*
+* DESCRIPTION
+* This function is to configure block size
+*
+* PARAMETERS
+* function: function id
+* size: block size
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_configure_BLK_size(SDIO_function_id_enum function, kal_uint32 size)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0x10+0x100*function;
+ cmd52.data = size&0xff;
+ status = SDIO_Cmd52(&cmd52);
+ if(size>=256)
+ {
+ cmd52.adrs = 0x11+0x100*function;
+ cmd52.data = (size&0xff00)>>8;
+ status = SDIO_Cmd52(&cmd52);
+ }
+ if(status==NO_ERROR)
+ {
+ gSDIO.block_size[function]=size;
+ /*set block length as size*/
+ BitFieldWrite32((kal_uint32*)SDC_CFG,(kal_uint32)size,SDC_CFG_BLKLEN);
+ }
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+
+SDC_CMD_STATUS SDIO_get_BLK_size(SDIO_function_id_enum function, kal_uint32 *size)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+ kal_uint32 temp,temp1;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+
+ temp = MSDC_Reg32(SDC_CFG)&SDC_CFG_BLKLEN;
+
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;//function;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0x10+0x100*function;
+ status = SDIO_Cmd52(&cmd52);
+ if(status==NO_ERROR)
+ {
+ temp1 = cmd52.data;
+ }
+ else
+ {
+ goto SDIO_get_BLK_size_exit;
+ }
+ cmd52.adrs = 0x11+0x100*function;
+ status = SDIO_Cmd52(&cmd52);
+ if(status==NO_ERROR)
+ {
+ temp1 |= (kal_uint32)cmd52.data <<8;
+ }
+ else
+ {
+ goto SDIO_get_BLK_size_exit;
+ }
+
+ if(temp == temp1 && temp ==gSDIO.block_size[function])
+ {
+ *size = temp;
+ }
+ else
+ {
+ *size = temp1;
+ status = ERR_INVALID_BKLENGTH; // error
+ kal_prompt_trace(MOD_MSDC_HISR,"ERROR,block=%d %d %d",temp,temp1,gSDIO.block_size[function]);
+ }
+
+SDIO_get_BLK_size_exit:
+
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_query_BLK_size
+*
+* DESCRIPTION
+* This function is to query function's maximum block size
+*
+* PARAMETERS
+* function: function id
+*
+* RETURNS
+* size: block size
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_uint32 SDIO_query_BLK_size(SDIO_function_id_enum function)
+{
+ kal_uint32 max_block_size;
+ kal_uint32 i;
+ for(i=0;i<SDIO_TUPLE_SIZE;i++)
+ {
+ if(sdio_tuple[function][i]==0x22)
+ {
+ if(function==SDIO_FUCN_0)
+ max_block_size=(sdio_tuple[function][i+3])|(sdio_tuple[function][i+4]<<8);
+ else
+ max_block_size=(sdio_tuple[function][i+14])|(sdio_tuple[function][i+15]<<8);
+ return max_block_size;
+ }
+ }
+ return 0;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_query_IO_id
+*
+* DESCRIPTION
+* This function is to query application function id
+*
+* PARAMETERS
+* ap: application type
+*
+* RETURNS
+* function: function id
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDIO_function_id_enum SDIO_query_IO_id(SDIO_interface_code_enum ap)
+{
+ switch(ap)
+ {
+ case SDIO_INTERFACE_NULL:
+ break;
+ case SDIO_INTERFACE_UART:
+ break;
+ case SDIO_INTERFACE_A_BT:
+ break;
+ case SDIO_INTERFACE_B_BT:
+ break;
+ case SDIO_INTERFACE_GPS:
+ break;
+ case SDIO_INTERFACE_CAMERA:
+ break;
+ case SDIO_INTERFACE_PHS:
+ break;
+ case SDIO_INTERFACE_WLAN:
+ return 1;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_SW_reset
+*
+* DESCRIPTION
+* This function is to reset all I/O function
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_SW_reset(void)
+{
+ cmd52_config_struct cmd52;
+ SDC_CMD_STATUS status;
+
+ /*use CMD52 to reset card*/
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 6;
+ cmd52.data = 0xff;
+ status=SDIO_Cmd52(&cmd52);
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_abort_IO
+*
+* DESCRIPTION
+* This function is to abort function
+*
+* PARAMETERS
+* function:function id
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_abort_IO(SDIO_function_id_enum function)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 6;
+ cmd52.data = function&0x7;
+ status = SDIO_Cmd52(&cmd52);
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+/*Function for WiFi */
+/*************************************************************************
+* FUNCTION
+* SDIO_Register_Write
+*
+* DESCRIPTION
+* This function is to write register
+*
+* PARAMETERS
+* function:function id
+* addr: address
+* data: write data
+* op: fixed or incrementing address
+* RETURNS
+* success or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+/*Write Register*/
+kal_bool SDIO_Register_Write(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint32 data,
+ cmd53_op_enum op)
+{
+
+ kal_uint32 tmp = data;
+ cmd53_config_struct cmd53;
+
+ SDIO_dispatch_IO(function);
+ sdio_uncachedU32 = data;
+ cmd53.rw = SDIO_WRITE;
+ cmd53.func = function;
+ cmd53.block = KAL_FALSE;
+ cmd53.buffer = (kal_uint32)&sdio_uncachedU32;
+ cmd53.count = 4;
+ cmd53.op = op;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+ {
+ SDIO_resume_IO(function);
+ return KAL_FALSE;
+ }
+ else
+ {
+ SDIO_resume_IO(function);
+ return KAL_TRUE;
+ }
+}
+kal_bool SDIO_Register_Write_isr(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint32 data,
+ cmd53_op_enum op)
+{
+
+ kal_uint32 tmp = data;
+ cmd53_config_struct cmd53;
+
+ cmd53.rw = SDIO_WRITE;
+ cmd53.func = function;
+ cmd53.block = KAL_FALSE;
+ cmd53.buffer = (kal_uint32)&tmp;
+ cmd53.count = 4;
+ cmd53.op = op;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53_isr(&cmd53)!=NO_ERROR))
+ {
+ return KAL_FALSE;
+ }
+ else
+ {
+ return KAL_TRUE;
+ }
+}
+/*Write Data */
+/*************************************************************************
+* FUNCTION
+* SDIO_Data_Write
+*
+* DESCRIPTION
+* This function is to write memory
+*
+* PARAMETERS
+* function:function id
+* addr: address
+* data: write data
+* op: fixed or incrementing address
+* count: transfer count
+* block: block/byte mode
+*
+* RETURNS
+* success or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_Data_Write(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint8 *data,
+ cmd53_op_enum op,
+ kal_uint32 count,
+ kal_bool block)
+{
+ cmd53_config_struct cmd53;
+ //kal_uint32 size, i;
+ //kal_uint32 sdio_buffer[256];
+
+ SDIO_dispatch_IO(function);
+ #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ cmd53.rw = SDIO_WRITE;
+ cmd53.func = function;
+ cmd53.block = block;
+ cmd53.buffer = (kal_uint32)data;//(kal_uint32)&sdio_buffer[0];
+ cmd53.count = count;
+ cmd53.op = op;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+ {
+ SDIO_resume_IO(function);
+ return KAL_FALSE;
+ }
+ else
+ {
+ SDIO_resume_IO(function);
+ return KAL_TRUE;
+ }
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_Register_Read
+*
+* DESCRIPTION
+* This function is to Read register
+*
+* PARAMETERS
+* function:function id
+* addr: address
+* data: write data
+* op: fixed or incrementing address
+*
+* RETURNS
+* success or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+/*Read Register*/
+kal_bool SDIO_Register_Read(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint32 *data,
+ cmd53_op_enum op)
+{
+ cmd53_config_struct cmd53;
+
+ SDIO_dispatch_IO(function);
+ cmd53.rw = SDIO_READ;
+ cmd53.func = function;
+ cmd53.block = KAL_FALSE;
+ cmd53.buffer = (kal_uint32) &sdio_uncachedU32;
+ cmd53.count = 4;
+ cmd53.op = op;;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+ {
+ SDIO_resume_IO(function);
+ return KAL_FALSE;
+ }
+ else
+ {
+ *data = sdio_uncachedU32 ;
+ SDIO_resume_IO(function);
+ return KAL_TRUE;
+ }
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_Register_Read_poll
+*
+* DESCRIPTION
+* This function is to Read register by SDIO bus driver
+*
+* PARAMETERS
+* function:function id
+* addr: address
+* data: write data
+* op: fixed or incrementing address
+*
+* RETURNS
+* success or not
+*
+* GLOBALS AFFECTED
+* only for SDIO bus driver
+*************************************************************************/
+kal_bool SDIO_Register_Read_poll(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint32 *data,
+ cmd53_op_enum op)
+{
+ cmd53_config_struct cmd53;
+
+ cmd53.rw = SDIO_READ;
+ cmd53.func = function;
+ cmd53.block = KAL_FALSE;
+ cmd53.buffer = (kal_uint32)data;
+ cmd53.count = 4;
+ cmd53.op = op;;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53_isr(&cmd53)!=NO_ERROR))
+ {
+ return KAL_FALSE;
+ }
+ else
+ {
+ return KAL_TRUE;
+ }
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_Data_Read
+*
+* DESCRIPTION
+* This function is to read memory
+*
+* PARAMETERS
+* function:function id
+* addr: address
+* data: write data
+* op: fixed or incrementing address
+* count: transfer count
+* block: block/byte mode
+*
+* RETURNS
+* success or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_Data_Read(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint8 *data,
+ cmd53_op_enum op,
+ kal_uint32 count,
+ kal_bool block)
+{
+ cmd53_config_struct cmd53;
+ SDIO_dispatch_IO(function);
+ cmd53.rw = SDIO_READ;
+ cmd53.func = function;
+ cmd53.block = block;
+ cmd53.buffer = (kal_uint32)data;
+ cmd53.count = count;
+ cmd53.op = op;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+ {
+ SDIO_resume_IO(function);
+ return KAL_FALSE;
+ }
+ else
+ {
+ SDIO_resume_IO(function);
+ return KAL_TRUE;
+ }
+}
+
+void SDIO_get_CCCR(kal_uint8 *buf, kal_uint32 bufLen)
+{
+ if(bufLen < SDIO_CCCR_SIZE)
+ ASSERT(0);
+ if(NULL == buf)
+ ASSERT(0);
+
+ kal_mem_cpy(buf, sdio_cccr_reg, SDIO_CCCR_SIZE);
+}
+
+void SDIO_get_FBR(kal_uint8 *buf, kal_uint32 bufLen)
+{
+ if(bufLen < SDIO_FBR_SIZE)
+ ASSERT(0);
+ if(NULL == buf)
+ ASSERT(0);
+
+ kal_mem_cpy(buf, sdio_fbr_reg, SDIO_FBR_SIZE);
+}
+
+/*not support in MT6228 and MT6229*/
+#ifdef __SDIO_SRW_SRW__
+/*************************************************************************
+* FUNCTION
+* SDIO_suspend_IO
+*
+* DESCRIPTION
+* This function is to suspend function
+*
+* PARAMETERS
+* bus_status: bus status
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_suspend_IO(SDIO_bus_status_enum *bus_status)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_TRUE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0xc;
+ cmd52.data = 1;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ *bus_status=(cmd52.data&0x2)>>1;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SDIO_select_IO
+*
+* DESCRIPTION
+* This function is to resume function
+*
+* PARAMETERS
+* bus_status: bus status
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_select_IO(SDIO_function_id_enum function, kal_bool *resume_data)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_TRUE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0xd;
+ cmd52.data = function&0xf;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ *resume_data=(cmd52.data&0x80)>>7;
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_check_IO_exec
+*
+* DESCRIPTION
+* This function is to check function execution status
+*
+* PARAMETERS
+* execute_status: execute status
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_exec(SDIO_function_id_enum function, kal_bool *execution)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0xe;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ if(function!=SDIO_FUCN_MEM)
+ *execution=(cmd52.data&(1<<function))>>function ;
+ else
+ *execution=cmd52.data&0x1;
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_check_IO_ready_flag
+*
+* DESCRIPTION
+* This function is to check function execution status
+*
+* PARAMETERS
+* bus_status: bus status
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_ready_flag(SDIO_function_id_enum function, kal_bool *ready)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0xf;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ if(function!=SDIO_FUCN_MEM)
+ *ready=(cmd52.data&(1<<function))>>function ;
+ else
+ *ready=cmd52.data&0x1;
+
+ return NO_ERROR;
+}
+#endif
+
+#ifdef DRV_MSDC_HW_CONTENTION
+extern kal_semid dclMsdcArb;
+#endif
+
+
+
+/*here is the interface for device driver, since SDIO should share the same HW resouce with SD card*/
+SDC_CMD_STATUS SDIO_Initialize_al()
+{
+ kal_uint32 retAddr;
+ SDC_CMD_STATUS status;
+
+#if defined(__RVCT__)
+ /* RVCT doesn't support inline assemlber; bypass temporarily */
+ retAddr = 0;
+#else /* __RVCT__ */
+ /* get the return address */
+ __asm {
+ MOV retAddr,lr
+ }
+#endif /* __RVCT__ */
+
+#ifdef DRV_MSDC_HW_CONTENTION
+ if(NULL == dclMsdcArb)
+ ASSERT(0);
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*must gain resource here */
+ kal_take_sem(dclMsdcArb, 1);
+ SD_setArbRetAddr(retAddr);
+ SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+ }
+#endif
+
+ /*switch related control*/
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+ MSDC_backupHwSetting();
+ MSDC_Switch_SDIO(SD_SDIO);
+#endif
+ MD_TRC_MSDC_SDIO_API_INIT();
+
+ status = SDIO_Initialize();
+
+ MD_TRC_MSDC_SDIO_API_INIT_END(status);
+
+ /*release arbitor*/
+#ifdef DRV_MSDC_HW_CONTENTION
+ if(KAL_FALSE == kal_query_systemInit()){
+ /*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+ SD_setArbThdId(NULL);
+ kal_give_sem(dclMsdcArb);
+ }
+#endif
+
+ return status;
+}
+
+SDC_CMD_STATUS SDIO_configure_BLK_size_al(SDIO_function_id_enum function, kal_uint32 size)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+ /* RVCT doesn't support inline assemlber; bypass temporarily */
+ retAddr = 0;
+#else /* __RVCT__ */
+ /* get the return address */
+ __asm {
+ MOV retAddr,lr
+ }
+#endif /* __RVCT__ */
+
+#ifdef DRV_MSDC_HW_CONTENTION
+ if(NULL == dclMsdcArb)
+ ASSERT(0);
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*must gain resource here */
+ kal_take_sem(dclMsdcArb, 1);
+ SD_setArbRetAddr(retAddr);
+ SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+ }
+#endif
+
+ /*switch related control*/
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+ MSDC_backupHwSetting();
+ MSDC_Switch_SDIO(SD_SDIO);
+#endif
+
+ /*do original job*/
+ status = SDIO_configure_BLK_size(function, size);
+
+ MD_TRC_MSDC_SDIO_API_SET_BLK_SIZE(function, size, status, 0);
+
+ /*release arbitor*/
+#ifdef DRV_MSDC_HW_CONTENTION
+ if(KAL_FALSE == kal_query_systemInit()){
+ /*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+ SD_setArbThdId(NULL);
+ kal_give_sem(dclMsdcArb);
+ }
+#endif
+
+ return status;
+}
+
+SDC_CMD_STATUS SDIO_Cmd52_al(cmd52_config_struct *p)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 retAddr;
+
+#if defined(__RVCT__)
+ /* RVCT doesn't support inline assemlber; bypass temporarily */
+ retAddr = 0;
+#else /* __RVCT__ */
+ /* get the return address */
+ __asm {
+ MOV retAddr,lr
+ }
+#endif /* __RVCT__ */
+
+#ifdef DRV_MSDC_HW_CONTENTION
+ if(NULL == dclMsdcArb)
+ ASSERT(0);
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*must gain resource here */
+ kal_take_sem(dclMsdcArb, 1);
+ SD_setArbRetAddr(retAddr);
+ SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+ }
+#endif
+
+ /*switch related control*/
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+ MSDC_backupHwSetting();
+ MSDC_Switch_SDIO(SD_SDIO);
+#endif
+
+ MD_TRC_MSDC_SDIO_API_CMD52(p->rw, p->func, p->raw, p->stop, p->data, p->adrs,
+ 0, MSDC_Reg32(MSDC_CFG));
+
+ status = SDIO_Cmd52(p);
+
+ MD_TRC_MSDC_SDIO_API_CMD52_END(status, MSDC_Reg32(SDC_RESP0));
+ /*release arbitor*/
+#ifdef DRV_MSDC_HW_CONTENTION
+ if(KAL_FALSE == kal_query_systemInit()){
+ /*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+ SD_setArbThdId(NULL);
+ kal_give_sem(dclMsdcArb);
+ }
+#endif
+
+ return status;
+}
+
+kal_bool SDIO_Data_Read_al
+(
+ SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint8 *data,
+ cmd53_op_enum op,
+ kal_uint32 count,
+ kal_bool block
+)
+{
+ kal_bool status;
+ kal_uint32 retAddr;
+ kal_uint32 time1, time2;
+
+#if defined(__RVCT__)
+ /* RVCT doesn't support inline assemlber; bypass temporarily */
+ retAddr = 0;
+#else /* __RVCT__ */
+ /* get the return address */
+ __asm {
+ MOV retAddr,lr
+ }
+#endif /* __RVCT__ */
+
+#ifdef DRV_MSDC_HW_CONTENTION
+ if(NULL == dclMsdcArb)
+ ASSERT(0);
+ if(kal_query_systemInit()== KAL_FALSE){
+ /*must gain resource here before calling ReadSectors*/
+ kal_take_sem(dclMsdcArb, 1);
+ SD_setArbRetAddr(retAddr);
+ SD_setArbThdId((kal_uint32)kal_get_current_thread_ID());
+ }
+#endif
+
+ /*switch related control*/
+#ifdef DRV_MSDC_SD_SDIO_SHARE_BY_SWITCH
+ MSDC_backupHwSetting();
+ MSDC_Switch_SDIO(SD_SDIO);
+#endif
+
+ MD_TRC_MSDC_SDIO_API_DREAD(function, addr, (kal_uint32)data, op, count,
+ block, 0, MSDC_Reg32(MSDC_CFG));
+
+ time1 = drv_get_current_time();
+
+ status = SDIO_Data_Read(function, addr, data, op, count, block);
+
+ time2 = drv_get_current_time();
+ MD_TRC_MSDC_SDIO_API_DREAD_END(status, (double)(count*32768)/(time2-time1), MSDC_Reg32(MSDC_IOCON), MSDC_Reg32(SDC_CFG));
+
+ /*release arbitor*/
+#ifdef DRV_MSDC_HW_CONTENTION
+ if(KAL_FALSE == kal_query_systemInit()){
+ /*when the semaphore is returned, we set thdId to zero, but not retAddr, we can know that it is released from here*/
+ SD_setArbThdId(NULL);
+ kal_give_sem(dclMsdcArb);
+ }
+#endif
+
+ return status;
+}
+#endif
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/sdio_drv2.c b/mcu/driver/storage/mc/src/sdio_drv2.c
new file mode 100644
index 0000000..e788c47
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sdio_drv2.c
@@ -0,0 +1,2540 @@
+#include "drv_features.h"
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "drv_comm.h"
+#include "reg_base.h"
+#include "msdc_reg_adap.h"
+//MSBB remove #include "app_buff_alloc.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "sdio_def.h"
+
+#include "intrCtrl.h"
+#include "sdio_sw.h"
+#include "cache_sw.h"
+#include "init.h"
+#ifdef __CLKG_DEFINE__
+#ifdef DRVPDN_CON1
+#error "__CLKG_DEFINE__ & DRVPDN_CON1 are all defined"
+#else
+#define DRVPDN_CON1 CG_CON1
+#endif
+
+#ifdef DRVPDN_CON1_SIM
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SIM are all defined"
+#else
+#define DRVPDN_CON1_SIM CG_CON1_SIM
+#endif
+
+#ifdef DRVPDN_CON1_MSDC
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_MSDC are all defined"
+#else
+#define DRVPDN_CON1_MSDC CG_CON1_MSDC
+#endif
+
+#ifdef DRVPDN_CON1_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_CLR are all defined"
+#else
+#define DRVPDN_CON1_CLR CG_CLR1
+#endif
+
+#ifdef DRVPDN_CON1_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON1_SET are all defined"
+#else
+#define DRVPDN_CON1_SET CG_SET1
+#endif
+
+#ifdef DRVPDN_CON0_MSDC2
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_MSDC2 are all defined"
+#else
+#define DRVPDN_CON0_MSDC2 CG_CON0_MSDC2
+#endif
+
+#ifdef DRVPDN_CON0_CLR
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_CLR are all defined"
+#else
+#define DRVPDN_CON0_CLR CG_CLR0
+#endif
+
+#ifdef DRVPDN_CON0_SET
+#error "__CLKG_DEFINE__ & DRVPDN_CON0_SET are all defined"
+#else
+#define DRVPDN_CON0_SET CG_SET0
+#endif
+
+#endif
+
+#if defined(__MSDC2_SD_SDIO__)
+
+#if defined(__MSDC_SD_SDIO)
+#error__MSDC_SD_SDIO can not coexit with __MSDC2_SD_SDIO__
+#endif
+
+#if defined(DRV_MSDC_MT6225_SERIES)
+#define DRV_MSDC_DATA_LATCH_TIMING
+#endif
+__align(4) kal_uint8 sdio_cccr_reg[SDIO_CCCR_SIZE];
+__align(4) kal_uint8 sdio_fbr_reg[SDIO_FBR_SIZE];
+__align(4) kal_uint8 sdio_tuple[SDIO_MAX_FUCN_ID][SDIO_TUPLE_SIZE];
+sdio_dcb_struct gSDIO;
+kal_mutexid sdio_mutex;
+MSDC_HANDLE *msdc2_sdio = &MSDC_Blk[SD_MSDC2];
+extern T_SDC_HANDLE *gSD2;
+
+extern kal_uint8 MSDC_GetIOCtrlParam(void);
+extern kal_uint32 MSDC_GetCustom(void);
+/*************************************************************************
+* FUNCTION
+* SDIO_Initialize
+*
+* DESCRIPTION
+* SDIO Intialization function
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_Initialize(void)
+{
+ kal_uint16 rca;
+ #if !defined(DRV_MSDC_DATA_LATCH_TIMING)
+ kal_uint16 iocon;
+ #else
+ kal_uint32 iocon;
+ #endif
+ SDC_CMD_STATUS status;
+ kal_uint32 flags;
+ kal_uint32 retry_count = 0;
+ kal_uint32 count=0;
+
+ TurnOnMSDC2();
+ #ifdef MSDC_INT
+ kal_retrieve_eg_events(msdc2_sdio->MSDC_Events,
+ (EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ|EVENT_PINIRQ),
+ KAL_OR_CONSUME,&flags,KAL_NO_SUSPEND);
+ #else
+ /*check if the card is present*/
+ if(MSDC_Reg(MSDC_PS2) & MSDC_PS_PIN0)
+ { /*card not present (1)*/
+ msdc2_sdio->mIsPresent = KAL_FALSE;
+ }
+ else
+ { /*card present (0)*/
+ msdc2_sdio->mIsPresent = KAL_TRUE;
+ }
+ #endif
+
+ /*create mutex*/
+ sdio_mutex = kal_create_mutex("MutexSDIO");
+
+ /* reset msdc*/
+ MSDC_SetBits32(MSDC_CFG2, MSDC_CFG_RST);
+
+ /* set the output driving capability from customization interface*/
+ #if !defined(DRV_MSDC_DATA_LATCH_TIMING)
+ MSDC_SetData(MSDC_IOCON2, 0xff, MSDC_GetIOCtrlParam2());
+ #else /* !defined(DRV_MSDC_DATA_LATCH_TIMING) */
+
+ iocon = 0;
+ iocon |= MSDC_GetIOCtrlParam2();
+ #ifdef MCU_78M
+ iocon |= 0x04000000;
+ #elif defined(MCU_52M)
+ iocon |= 0x02000000;
+ #endif
+ MSDC_SetData(MSDC_IOCON2, 0xff0000ff, iocon);
+
+ #if defined(MCU_52M)
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)1, MSDC_CFG_CRED);
+ #endif
+ #endif /* !defined(DRV_MSDC_DATA_LATCH_TIMING) */
+
+ /*set pull up in CMD/DAT line configuration*/
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG1);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG2);
+
+ /*set write timeout=(40+1)*65536*(1/serial clock)*/
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,(kal_uint32)255,SDC_CFG_DTOC);
+ /*set write timeout=(40+1)*65536*(1/serial clock)*/
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,(kal_uint32)15,SDC_CFG_WDOD);
+
+ /* disable 4-bit*/
+ MSDC_ClearBits32(SDC_CFG2,SDC_CFG_MDLEN);
+ /* enable serila clock 104/8=13MHz*/
+ //BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)FREQ_1BY8,MSDC_CFG_SCLKF);
+ /* enable serila clock 104/255*4=100KHz*/
+ //MSDC_Reg32(MSDC_CFG2)|= 0x8;
+ MSDC_ClearBits32(SDC_CFG2,SDC_CFG_SIEN);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)64,MSDC_CFG_SCLKF);
+ msdc2_sdio->msdc_clock = MSDC_CLOCK;
+ MSDC_SetClock(MSDC_INI_CLOCK);
+ MSDC_SetIOCONRegDLT();
+
+ MSDC_SetBits32(SDC_CFG2,SDC_CFG_SIEN);
+ /* config the sdio controller*/
+ /* enable SDIO mode*/
+ MSDC_Reg32(SDC_CFG2)|= SDC_CFG_SDIO;
+ /* enable SDIO interrupt*/
+ MSDC_WriteReg32(SDIO_CFG2, 1);
+ {
+ kal_uint32 i;
+ for(i=0;i<1000;i++);
+ }
+ /*SDIO initialization CMD*/
+ status = SDIO_Cmd5(0);
+ #ifdef _SDIO_DEBUG_
+ dbg_print("write CMD5(0) %d\r\n", status);
+ dbg_print("card OCR %d\r\n", gSDIO.ocr);
+ #endif
+ do
+ {
+ retry_count++;
+ if(gSDIO.ocr & 0x8000)
+ {
+ if((status = SDIO_Cmd5(0x8000))!=NO_ERROR)
+ {
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card deny OCR \r\n");
+ #endif
+
+ }
+ else
+ {
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card accept OCR \r\n");
+ #endif
+ }
+
+ gSDIO.ocr_valid = KAL_TRUE;
+ gSD2->flags |= SD_FLAG_SD_TYPE_CARD;
+ }
+ else
+ {
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card not match OCR \r\n");
+ dbg_print("uses card's OCR \r\n");
+ #endif
+ if((status = SDIO_Cmd5(gSDIO.ocr))!=NO_ERROR)
+ {
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card deny OCR \r\n");
+ #endif
+ }
+ else
+ {
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card accept OCR \r\n");
+ #endif
+ }
+
+ gSDIO.ocr_valid = KAL_TRUE;
+ gSD2->flags |= SD_FLAG_SD_TYPE_CARD;
+ }
+ if(retry_count>=100)
+ goto err;
+ }while(gSDIO.io_ready!=KAL_TRUE);
+ MSDC_ClearBits32(SDC_CFG2,SDC_CFG_SIEN);
+#ifdef MCU_78M
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)FREQ_1BY8,MSDC_CFG_SCLKF);
+#elif defined(MCU_208M)
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)FREQ_1BY16,MSDC_CFG_SCLKF);
+#else
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)FREQ_1BY4,MSDC_CFG_SCLKF);
+#endif /*MCU_78M*/
+
+ SD_Use24M_Clock_2();
+ //SD_Use45M_Clock();
+ MSDC_SetIOCONRegDLT2();
+
+ MSDC_SetBits32(SDC_CFG2,SDC_CFG_SIEN);
+ status = SD_ValidateRCA_2(&rca);
+ #ifdef _SDIO_DEBUG_
+ dbg_print("CMD7 select card \r\n");
+ dbg_print("CMD3 request RCA \r\n");
+ #endif
+
+ status = SD_SelectCard_2(rca);
+
+ /* get parameters*/
+ /*read CCCR, FBR, CIS tuple*/
+ status=SDIO_read_CCCR();
+ status=SDIO_read_capacity();
+ status=SDIO_read_power_control();
+
+#if 0
+ #if 0/*support 4-bits*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #else
+/* under construction !*/
+ #endif
+#endif
+
+ /*enable multiple block interrupt */
+ if(!(SDIO_support_LSC()))
+ {
+ //MSDC2 only support 1-bit Mode
+ status=SDIO_configure_bus(BIT_1W);
+ }
+ else/*low speed card*/
+ {
+ //MSDC2 only support 1-bit Mode
+ }
+
+
+ status=SDIO_read_CIS(SDIO_FUCN_0);
+ /*enable I/O function*/
+ for(count=SDIO_FUCN_1;count<SDIO_MAX_FUCN_ID;count++)
+ {
+ kal_uint32 retry=0;
+ kal_bool ready;
+ for(retry=0;retry<100;retry++)
+ {
+ status=SDIO_enable_IO(count, KAL_TRUE);
+ SDIO_check_IO_ready(count, &ready);
+ if(ready==KAL_TRUE)
+ break;
+ }
+ status=SDIO_read_FBR(count);
+ for(retry=0;retry<100;retry++)
+ {
+ status=SDIO_read_CIS(count);
+ if(status==NO_ERROR)
+ break;
+ }
+
+ }
+ if(SDIO_support_MPS())
+ status=SDIO_enable_MPS(KAL_TRUE);
+
+ status=SDIO_read_CCCR();
+
+ /* for Sandisk SDIO WIFI card*/
+
+
+
+err:
+ if(status != NO_ERROR)
+ {
+ //dbg_print("10\r\n");
+ kal_mem_set(gSD,0,sizeof(gSD));
+ msdc2_sdio->mIsInitialized = KAL_FALSE;
+
+ }
+ else
+ msdc2_sdio->mIsInitialized = KAL_TRUE;
+
+ return status;
+}
+
+/*SDIO commnad set*/
+/*************************************************************************
+* FUNCTION
+* SD_StopTrans
+*
+* DESCRIPTION
+* Stop Muli-Block operation
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Use polling to check write command completely
+*************************************************************************/
+SDC_CMD_STATUS SD_StopTrans_poll(void)
+{
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_poll(SDC_CMD_CMD12,SDC_NO_ARG))!=NO_ERROR)
+ return status;
+ /*Read R1b*/
+ if((status = SD_CheckStatus())!=NO_ERROR)
+ return status;
+
+
+#ifdef SD_STOP_SLOW
+ while(MSDC_Reg(SDC_STA2) & SDC_STA_R1BSY);
+ do{
+ SD_GetStatus_2(gSD->mRCA,(kal_uint32*)&status);
+ }while((status & R1_CUR_STATE) >> 9 != TRAN_STA);
+#endif
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_WaitCardNotBusy
+*
+* DESCRIPTION
+* Wait until card is not busy (R1b)
+*
+* PARAMETERS
+*
+* RETURNS
+* void
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+/*R1b*/
+void SDIO_WaitCardNotBusy(void)
+{
+ while( MSDC_Reg(SDC_STA2) & SDC_STA_R1BSY);
+}
+/*************************************************************************
+* FUNCTION
+* SD_WaitCmdRdyOrTo_poll
+*
+* DESCRIPTION
+* write command completely
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitCmdRdyOrTo_poll(void)
+{
+ kal_uint16 sdc_cmdsta = 0;
+ kal_uint32 counter = 0;
+
+ while(MSDC_Reg(SDC_STA2)&0x2){};
+ #if 1
+ do{
+ sdc_cmdsta = MSDC_Reg(SDC_CMDSTA2);
+ if(sdc_cmdsta & SDC_CMDSTA_CMDTO)
+ return ERR_CMD_TIMEOUT;
+ else if(sdc_cmdsta & SDC_CMDSTA_RSPCRCERR)
+ return ERR_CMD_RSPCRCERR;
+ else if(sdc_cmdsta & SDC_CMDSTA_CMDRDY)
+ break;
+ }while(counter++ < 10000);
+ #endif
+ if (counter >= 10000)
+ {
+ return ERR_NORESP;
+ }
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_WaitCmdRdyOrTo_poll
+*
+* DESCRIPTION
+* write command completely
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Send_Cmd_poll(kal_uint32 cmd, kal_uint32 arg)
+{
+ SDC_CMD_STATUS status;
+
+ /*check the controller is ready (stop transaction will fail)*/
+ //if( != SDC_CMD_CMD12)
+ if(!(SDC_CMD_STOP&cmd))
+ while(SD_IS_SDC_BUSY_2 && msdc2_sdio->mIsPresent);
+ else
+ while(SD_IS_CMD_BUSY_2 && msdc2_sdio->mIsPresent);
+
+ /* fill out the argument*/
+ MSDC_WriteReg32(SDC_ARG2,arg);
+ /* launch the command*/
+ MSDC_WriteReg32(SDC_CMD2,cmd);
+ if((status = SD_WaitCmdRdyOrTo_poll())!=NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_Cmd53
+*
+* DESCRIPTION
+* IO_RW_DIRECT command
+*
+* PARAMETERS
+* command 53 structrue
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_uint8 debug_flag = 0;
+SDC_CMD_STATUS SDIO_Cmd53(cmd53_config_struct *p)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 arg;
+ kal_uint32 cmd;
+ kal_uint32 *ptr = (kal_uint32 *) p->buffer;
+
+ ASSERT(p->adrs < 0x20000 && p->count < 0x200);
+ #ifdef MSDC_DMA
+ if (INT_QueryIsCachedRAM(ptr, p->count))
+ {
+ EXT_ASSERT(0, (kal_uint32)prt, p->count, 0);
+ }
+ #endif /* MSDC_DMA */
+ IRQMask(IRQ_MSDC2_CODE);
+ arg = (p->rw << 31)|(p->func << 28)|(p->block << 27)|(p->op << 26)|(p->adrs << 9)|(p->count);
+ cmd = SDC_CMD_CMD53 | (p->rw << 13);
+ if(p->block)
+ {
+ cmd |= (2 << 11); // multi-block
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,gSDIO.block_size[1],SDC_CFG_BLKLEN);
+ }
+ else
+ {
+ cmd |= (1 << 11); // single-block
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,p->count,SDC_CFG_BLKLEN);
+ }
+
+ // send cmd53
+ //if(p->rw == SDIO_WRITE)
+ if(0)/*R1b*/
+ {
+ cmd &= ~0x380;
+ cmd |= 0x380;
+ }
+ else/*R1*/
+ {
+ cmd &= ~0x380;
+ cmd |= 0x80;
+ }
+ #ifdef MSDC_DMA
+ {
+ kal_uint32 total_size=0;
+
+ EnableMSDC_DMA2();
+ if(p->block)
+ total_size = (p->count*gSDIO.block_size[p->func]);
+ else
+ total_size =p->count;
+ total_size=total_size>>2;
+
+ if(p->rw == SDIO_READ)
+ MSDC_DMATransferFirst2((kal_uint32)ptr,total_size,KAL_FALSE);
+ else
+ MSDC_DMATransferFirst2((kal_uint32)ptr,total_size,KAL_TRUE);
+ }
+ #endif /* MSDC_DMA */
+
+ if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+ {
+ goto ERROR_EXIT;
+ }
+ MSDC_Reg32(SDC_RESP02,&status);
+ status = (status & 0xff00)>>8;
+ gSDIO.resp = status;
+ /* start data transfer*/
+ if(p->rw == SDIO_READ)
+ {
+ #ifdef MSDC_DMA
+ status = MSDC_DMATransferFinal2();
+ /*check DMA*/
+ if(status != NO_ERROR)
+ goto ERROR_EXIT;
+ /*check Data ready*/
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+
+ DisableMSDC_DMA2();
+ MSDC_CLR_FIFO2();
+
+ #else/*!MSDC_DMA*/
+ kal_uint32 i;
+ if(p->block)
+ {
+ kal_uint32 total;
+
+ total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+ for(i=0;i< total;)
+ {
+ if(!MSDC_IS_FIFO_EMPTY2)
+ {
+ *(ptr+i) = MSDC_Reg32(MSDC_DAT2);
+ i++;
+ if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+ }
+ }
+ else
+ {
+ for(i=0;i< (p->count+3)>>2;)
+ {
+ if(!MSDC_IS_FIFO_EMPTY2)
+ {
+ *(ptr+i) = MSDC_Reg32(MSDC_DAT2);
+ i++;
+ if((i%((p->count+3)>> 2)==0)&&(i!=0))
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+ }
+ }
+ #endif/*MSDC_DMA*/
+ }
+ else
+ { // SDIO_WRITE
+ #ifdef MSDC_DMA
+ status = MSDC_DMATransferFinal2();
+ /*check DMA*/
+ if(status != NO_ERROR)
+ goto ERROR_EXIT;
+ /*check Data ready*/
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+
+ DisableMSDC_DMA2();
+ MSDC_CLR_FIFO2();
+ #else/* MSDC_DMA*/
+ kal_uint32 i;
+ if(p->block)
+ {
+ kal_uint32 total;
+
+ total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+ for(i=0;i< total;)
+ {
+ if(!MSDC_IS_FIFO_FULL2)
+ {
+ MSDC_WriteReg32(MSDC_DAT2, *(ptr+i));
+ i++;
+ if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+ }
+ }
+ else
+ {
+ for(i=0;i< (p->count+3)>>2;)
+ {
+ if(!MSDC_IS_FIFO_FULL2)
+ {
+ MSDC_WriteReg32(MSDC_DAT2, *(ptr+i));
+ i++;
+ if(i%((p->count+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+ }
+ }
+ #endif/*MSDC_DMA*/
+ }
+ //SD_StopTrans_poll();
+ if(p->block)
+ SD_StopTrans_poll();
+ SDIO_stop();
+ IRQUnmask(IRQ_MSDC2_CODE);
+ return NO_ERROR;
+ ERROR_EXIT:
+ {
+ kal_uint32 tmp;
+ #ifdef MSDC_DMA
+ DisableMSDC_DMA2();
+ #endif
+ if(p->block)
+ SD_StopTrans_poll();
+ SDIO_stop();
+ MSDC_Reg32(SDC_CMDSTA2,&tmp);
+ MSDC_Reg32(SDC_DATSTA2,&tmp);
+ MSDC_CLR_FIFO2();
+ IRQUnmask(IRQ_MSDC2_CODE);
+ return status;
+ }
+}
+
+/*SDIO_Cmd53_poll*/
+SDC_CMD_STATUS SDIO_Cmd53_isr(cmd53_config_struct *p)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 arg;
+ kal_uint32 cmd,i;
+ kal_uint32 *ptr = (kal_uint32 *) p->buffer;
+
+ ASSERT(p->adrs < 0x20000 && p->count < 0x200);
+ arg = (p->rw << 31)|(p->func << 28)|(p->block << 27)|(p->op << 26)|(p->adrs << 9)|(p->count);
+ cmd = SDC_CMD_CMD53 | (p->rw << 13);
+ if(p->block)
+ {
+ cmd |= (2 << 11); // multi-block
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,gSDIO.block_size[1],SDC_CFG_BLKLEN);
+ }
+ else
+ {
+ cmd |= (1 << 11); // single-block
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,p->count,SDC_CFG_BLKLEN);
+ }
+
+ // send cmd53
+ //if(p->rw == SDIO_WRITE)
+ if(0)/*R1b*/
+ {
+ cmd &= ~0x380;
+ cmd |= 0x380;
+ }
+ else/*R1*/
+ {
+ cmd &= ~0x380;
+ cmd |= 0x80;
+ }
+ if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+ {
+ goto ERROR_EXIT;
+ }
+ MSDC_Reg32(SDC_RESP02,&status);
+ status = (status & 0xff00)>>8;
+ gSDIO.resp = status;
+ /* start data transfer*/
+ if(p->rw == SDIO_READ)
+ {
+
+ if(p->block)
+ {
+ kal_uint32 total;
+
+ total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+ for(i=0;i< total;)
+ {
+
+ if(!MSDC_IS_FIFO_EMPTY2)
+ {
+ *(ptr+i) = MSDC_Reg32(MSDC_DAT2);
+ i++;
+ if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+
+ }
+ }
+ else
+ {
+ for(i=0;i< (p->count+3)>>2;)
+ {
+ if(!MSDC_IS_FIFO_EMPTY2)
+ {
+ *(ptr+i) = MSDC_Reg32(MSDC_DAT2);
+ i++;
+ if(i%((p->count+3)>> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+
+ }
+
+ }
+ }
+ else
+ { // SDIO_WRITE
+ if(p->block)
+ {
+ kal_uint32 total;
+
+ total = (p->count*gSDIO.block_size[p->func]+3)>>2;
+ for(i=0;i< total;)
+ {
+ if(!MSDC_IS_FIFO_FULL2)
+ {
+ MSDC_WriteReg32(MSDC_DAT2, *(ptr+i));
+ i++;
+ if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+
+
+ }
+ }
+ else
+ {
+ for(i=0;i< (p->count+3)>>2;)
+ {
+ if(!MSDC_IS_FIFO_FULL2)
+ {
+ MSDC_WriteReg32(MSDC_DAT2, *(ptr+i));
+ i++;
+ if(i%((p->count+3) >> 2)==0)
+ {
+ debug_flag = 1;
+ if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
+ goto ERROR_EXIT;
+ }
+ }
+
+ }
+
+ }
+ }
+ if(p->block)
+ SD_StopTrans_poll();
+ SDIO_stop();
+ return NO_ERROR;
+ ERROR_EXIT:
+ {
+ kal_uint32 tmp;
+ #ifdef MSDC_DMA
+ DisableMSDC_DMA2();
+ #endif
+ if(p->block)
+ SD_StopTrans_poll();
+ SDIO_stop();
+ MSDC_Reg32(SDC_CMDSTA2,&tmp);
+ MSDC_Reg32(SDC_DATSTA2,&tmp);
+ MSDC_CLR_FIFO2();
+ return status;
+ }
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_Cmd52
+*
+* DESCRIPTION
+* IO_RW_DIRECT command
+*
+* PARAMETERS
+* command 52 structrue
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+/* refer to the IO_RW_DIRECT command (CMD52) in SDIO 1.1 chapter 5.1*/
+SDC_CMD_STATUS SDIO_Cmd52(cmd52_config_struct *p)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 arg = 0;
+ kal_uint32 cmd;
+
+ IRQMask(IRQ_MSDC2_CODE);
+ if(p->rw == SDIO_WRITE)
+ {
+ arg |= (IO_ARG_RW_FLAG|p->data);
+ }
+ arg |= ((p->raw << 27)|(p->func << 28)|(p->adrs <<9));
+
+ cmd = SDC_CMD_CMD52 ;
+ if(p->stop)
+ cmd |= SDC_CMD_STOP;
+
+ if(p->stop)
+ //if(0)
+ {
+ cmd &= ~0x380;
+ cmd |= 0x380;
+ }
+ #if 1
+ else
+ {
+ cmd &= ~0x380;
+ cmd |= 0x80;
+ }
+ #endif
+ if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+ goto ERROR_EXIT;
+ while(MSDC_Reg(SDC_STA2) & SDC_STA_R1BSY);
+ MSDC_Reg32(SDC_RESP02,&status);
+ if(p->rw == SDIO_READ)
+ {
+ p->data = status & 0xff;
+ }
+ status = (status & 0xff00)>>8;
+ gSDIO.state = (status & 0x30)>>4;
+ gSDIO.resp = status;
+ IRQUnmask(IRQ_MSDC2_CODE);
+ return NO_ERROR;
+ ERROR_EXIT:
+ {
+ kal_uint32 tmp;
+ MSDC_Reg32(SDC_CMDSTA2,&tmp);
+ MSDC_CLR_FIFO2();
+ IRQUnmask(IRQ_MSDC2_CODE);
+ return status;
+ }
+
+
+}
+SDC_CMD_STATUS SDIO_Cmd52_isr(cmd52_config_struct *p)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 arg = 0;
+ kal_uint32 cmd;
+
+ if(p->rw == SDIO_WRITE)
+ {
+ arg |= (IO_ARG_RW_FLAG|p->data);
+ }
+ arg |= ((p->raw << 27)|(p->func << 28)|(p->adrs <<9));
+
+ cmd = SDC_CMD_CMD52 ;
+ if(p->stop)
+ cmd |= SDC_CMD_STOP;
+ if(p->stop)
+ //if(0)
+ {
+ cmd &= ~0x380;
+ cmd |= 0x380;
+ }
+ #if 1
+ else
+ {
+ cmd &= ~0x380;
+ cmd |= 0x80;
+ }
+ #endif
+ if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
+ goto ERROR_EXIT;
+ while(MSDC_Reg(SDC_STA2) & SDC_STA_R1BSY);
+ MSDC_Reg32(SDC_RESP02,&status);
+ if(p->rw == SDIO_READ)
+ {
+ p->data = status & 0xff;
+ }
+ status = (status & 0xff00)>>8;
+ gSDIO.state = (status & 0x30)>>4;
+ gSDIO.resp = status;
+ return NO_ERROR;
+ /*error handle*/
+ ERROR_EXIT:
+ {
+ kal_uint32 tmp;
+ MSDC_Reg32(SDC_CMDSTA2,&tmp);
+ MSDC_CLR_FIFO2();
+ return status;
+ }
+
+}
+
+/* for SDIO*/
+/*************************************************************************
+* FUNCTION
+* SDIO_Cmd5
+*
+* DESCRIPTION
+* SDIO initialization command
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* it is similar to the operation of ACMD41 for SD memory cards.
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_Cmd5(kal_uint32 ocr)
+{
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_poll(SDC_CMD_CMD5,ocr))!=NO_ERROR)
+ return status;
+
+ /*read R4*/
+ MSDC_Reg32(SDC_RESP02,&status);
+ gSDIO.ocr = status &0xFFFFFF;
+ status >>= 24;
+ gSDIO.num_func = (kal_uint8)(status & 0x70) >> 4;
+ gSDIO.mem_present = ((status & 0x08) != 0) ;
+ gSDIO.io_ready = ((status & SDIO_R4_CARD_READY)!=0);
+ #ifdef _SDIO_DEBUG_
+ dbg_print("card function number %d\r\n", gSDIO.num_func);
+ dbg_print("memory card present %d\r\n", gSDIO.mem_present);
+ dbg_print("card ready %d\r\n", gSDIO.io_ready);
+ #endif
+ return NO_ERROR;
+}
+
+void SDIO_dispatch_IO(SDIO_function_id_enum function)
+{
+ /*single function*/
+ kal_take_mutex(sdio_mutex);
+ /*multiple function*/
+ /*not support now*/
+}
+
+void SDIO_resume_IO(SDIO_function_id_enum function)
+{
+ /*single function*/
+ kal_give_mutex(sdio_mutex);
+ /*multiple function*/
+ /*not support now*/
+
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_CIS
+*
+* DESCRIPTION
+* This function is to read function's CIS
+*
+* PARAMETERS
+* function: function id
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* This function is only user for SDIO bus driver
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_CIS(SDIO_function_id_enum function)
+{
+ kal_uint32 i=0, j=0;
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+ ASSERT(function<8);
+ /* read all configuration register of CCCR*/
+ while(1)
+ {
+ cmd52.rw = SDIO_READ;
+ cmd52.func = function;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ if(function==0)
+ cmd52.adrs =(kal_uint32)((sdio_cccr_reg[11]<<16)|(sdio_cccr_reg[10]<<8)|
+ (sdio_cccr_reg[9]<<8)+i);
+ else
+ cmd52.adrs =(kal_uint32)((sdio_fbr_reg[11]<<16)|(sdio_fbr_reg[10]<<8)|
+ (sdio_fbr_reg[9]<<8)+i);
+ cmd52.data = 0;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ sdio_tuple[function][i]=cmd52.data;
+ i++;
+ if(cmd52.data==CISTPL_NULL||cmd52.data==CISTPL_END)
+ return NO_ERROR;
+ else
+ {
+ kal_uint32 tuple_size=0;
+ cmd52.rw = SDIO_READ;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs++;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ sdio_tuple[function][i]=cmd52.data;
+ tuple_size=cmd52.data;
+ i++;
+ for(j=0;j<tuple_size;j++)
+ {
+ cmd52.adrs++;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ sdio_tuple[function][i]=cmd52.data;
+ i++;
+ }
+ }
+ }
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_CCCR_ver
+*
+* DESCRIPTION
+* This function is to read card's CCCR version
+*
+* PARAMETERS
+* *version
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+/*read SDIO CCCR version*/
+SDC_CMD_STATUS SDIO_read_CCCR_ver(kal_uint8 *version)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+
+ #if 1
+ *version=sdio_cccr_reg[0]&SDIO_CCCR_VERISON_MASK;
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ return status;
+
+}
+
+SDC_CMD_STATUS SDIO_stop(void)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+
+ cmd52_config_struct cmd52;
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_TRUE;
+ cmd52.adrs = 6;
+ cmd52.data = 1;
+ status = SDIO_Cmd52(&cmd52);
+ /*wait card is not busy*/
+ SDIO_WaitCardNotBusy();
+ return status;
+}
+SDC_CMD_STATUS SDIO_WaitDatRdyOrTo(void)
+{
+ // maybe have to add a timer
+ register kal_uint16 sdc_datsta = 0;
+
+ int counter = 0;
+ //while(MSDC_Reg(SDC_STA2)&0x4){};
+ do{
+ sdc_datsta = MSDC_Reg(SDC_DATSTA2);
+ if(sdc_datsta & SDC_DATSTA_DATTO)
+ return ERR_DAT_TIMEOUT;
+ else if(sdc_datsta & SDC_DATSTA_DATCRCERR)
+ return ERR_DAT_CRCERR;
+ else if(sdc_datsta & SDC_DATSTA_BLKDONE)
+ break;
+ }while(1);//(counter++ < 1000);
+
+ if (counter >= 1000)
+ return ERR_NORESP;
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_SDIO_ver
+*
+* DESCRIPTION
+* This function is to read card's SDIO version
+*
+* PARAMETERS
+* *version
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+/*read SDIO spec version*/
+SDC_CMD_STATUS SDIO_read_SDIO_ver(kal_uint8 *version)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+
+ #if 1
+ *version=sdio_cccr_reg[0]&SDIO_VERISON_MASK>>SDIO_VERISON_SHIFT;
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ return status;
+
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_SD_ver
+*
+* DESCRIPTION
+* This function is to read card's SD version
+*
+* PARAMETERS
+* *version
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*
+*************************************************************************/
+/*read SD spec version*/
+SDC_CMD_STATUS SDIO_read_SD_ver(kal_uint8 *version)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+
+ #if 1
+ *version=sdio_cccr_reg[1]&SDIO_SD_VERISON_MASK;
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_CCCR
+*
+* DESCRIPTION
+* This function is to read card CCCR
+*
+* PARAMETERS
+* *version
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_CCCR(void)
+{
+ #if 1
+ kal_uint32 i;
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ for(i=0;i<SDIO_CCCR_SIZE;i++)
+ {
+ cmd52.adrs =i;
+ status = SDIO_Cmd52(&cmd52);
+ sdio_cccr_reg[i]=cmd52.data;
+ }
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_FBR
+*
+* DESCRIPTION
+* This function is to read card FBR
+*
+* PARAMETERS
+* function: function id
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_FBR(SDIO_function_id_enum function)
+{
+ #if 1 /*to cover 5911 issue*/
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+ kal_uint32 i=0;
+
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.data = 0;
+ for(i=0;i<SDIO_FBR_SIZE;i++)
+ {
+ cmd52.adrs = 0x100*function+i;
+ status=SDIO_Cmd52(&cmd52);
+ sdio_fbr_reg[i] = cmd52.data;
+ }
+
+ return status;
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_power_control
+*
+* DESCRIPTION
+* This function is to read card's power control
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_power_control(void)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0x12;
+ cmd52.data = 0;
+ status=SDIO_Cmd52(&cmd52);
+ gSDIO.power_control = cmd52.data;
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_MPS
+*
+* DESCRIPTION
+* This function is to query card's power control
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+kal_bool SDIO_support_MPS(void)
+{
+ return ((gSDIO.power_control&0x1));
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_enable_MPS
+*
+* DESCRIPTION
+* This function is to enable card's power control
+*
+* PARAMETERS
+* enable: enable or disable
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_MPS(kal_bool enable)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0x12;
+ if(enable)
+ cmd52.data |= 0x2;
+ else
+ cmd52.data &= ~0x2;
+
+ status=SDIO_Cmd52(&cmd52);
+ if(enable)
+ gSDIO.power_control |= 0x2;
+ else
+ gSDIO.power_control &= ~0x2;
+
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_read_capacity
+*
+* DESCRIPTION
+* This function is to read card's capacity
+*
+* PARAMETERS
+* enable: None
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_read_capacity(void)
+{
+ SDC_CMD_STATUS status=NO_ERROR;
+ #if 1
+ gSDIO.capability = sdio_cccr_reg[8];
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_SDC
+*
+* DESCRIPTION
+* This function is to query if card can support SDC
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+/*query card capacity*/
+kal_bool SDIO_support_SDC(void)
+{
+ return ((gSDIO.capability&0x1));
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_SMB
+*
+* DESCRIPTION
+* This function is to query if card can support Multiple Block
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_SMB(void)
+{
+ return ((gSDIO.capability&0x2)>>1);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_SRW
+*
+* DESCRIPTION
+* This function is to query if card can support Suspend/Resume
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_SRW(void)
+{
+ return ((gSDIO.capability&0x4)>>2);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_SBS
+*
+* DESCRIPTION
+* This function is to query if card can support Read/Wait
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_SBS(void)
+{
+ return ((gSDIO.capability&0x8)>>3);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_S4MI
+*
+* DESCRIPTION
+* This function is to query if card can support interrupt during multiple block
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_S4MI(void)
+{
+ return ((gSDIO.capability&0x10)>>4);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_enable_E4MI
+*
+* DESCRIPTION
+* This function is to enable interrupt during multiple block
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+* only used for SDIO bus driver
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_E4MI(kal_bool enable)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+ kal_uint8 temp_data;
+
+ if(!SDIO_support_S4MI())
+ return SDIO_4MI_NOT_SUPPORT;
+
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 8;
+ if(enable)
+ {
+ cmd52.data = 0x20;
+ temp_data=0x20;
+ }
+ else
+ {
+ cmd52.data = 0;
+ temp_data=0;
+ }
+ if((status = SDIO_Cmd52(&cmd52))==NO_ERROR)
+ {
+ /*double check*/
+ cmd52.rw = SDIO_READ;
+ status = SDIO_Cmd52(&cmd52);
+ if((cmd52.data&0x20)!=temp_data)
+ ASSERT(0);
+
+ if(enable)
+ gSDIO.capability|=0x20;
+ else
+ gSDIO.capability&=~0x20;
+ }
+
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_enable_E4MI
+*
+* DESCRIPTION
+* This function is to query if card is a low speed card
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_LSC(void)
+{
+ return ((gSDIO.capability&0x40)>>6);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_support_4BLS
+*
+* DESCRIPTION
+* This function is to query if card can support 4-bits in low speed card
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* support or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_support_4BLS(void)
+{
+ return ((gSDIO.capability&0x80)>>7);
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_configure_bus
+*
+* DESCRIPTION
+* This function is to configure bus width
+*
+* PARAMETERS
+* bus: bus width
+*
+* RETURNS
+* bus
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_configure_bus(SD_BITWIDTH bus)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 7;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ {
+ return status;
+ }
+ cmd52.data &= ~0x3;
+ cmd52.data |= (bus|0x80);/*also disable card detection*/
+ cmd52.rw = SDIO_WRITE;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ {
+ return status;
+ }
+ gSDIO.bit_width=bus;
+ if(bus==BIT_4W)
+ MSDC_SetBits32(SDC_CFG2,SDC_CFG_MDLEN);
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_enable_IO
+*
+* DESCRIPTION
+* This function is to enable function
+*
+* PARAMETERS
+* function: function id
+* enable: enable or disable
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_IO(SDIO_function_id_enum function, kal_bool enable)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 2;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ {
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+ }
+ if(enable)
+ cmd52.data |= (function<<1);
+ else
+ cmd52.data &= ~(function<<1);
+
+ cmd52.rw = SDIO_WRITE;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ {
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+ }
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_check_IO_ready
+*
+* DESCRIPTION
+* This function is to check function status
+*
+* PARAMETERS
+* function: function id
+* *ready: ready or not
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_ready(SDIO_function_id_enum function, kal_bool *ready)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 3;
+ status = SDIO_Cmd52(&cmd52);
+ *ready=(cmd52.data&(1<<function))>>function;
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_enable_IO_Int
+*
+* DESCRIPTION
+* This function is to configure function interrupt enable
+*
+* PARAMETERS
+* function: function id
+* enable: enable or diable
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_enable_IO_Int(SDIO_function_id_enum function, kal_bool enable)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 4;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ {
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+ }
+ if(enable)
+ cmd52.data |= (1<<function);
+ else
+ cmd52.data &= ~(1<<function);
+
+ cmd52.rw = SDIO_WRITE;
+
+ status = SDIO_Cmd52(&cmd52);
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_int_registration
+*
+* DESCRIPTION
+* This function is to register interrupt handler
+*
+* PARAMETERS
+* function: function id
+* func: interrupt handler
+* RETURNS
+* None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void SDIO_int_registration(SDIO_function_id_enum function, void (func)(void))
+{
+ gSDIO.callback[function]=func;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_HISR_Entry
+*
+* DESCRIPTION
+* This function is to handle SDIO interrupt
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS int_status;
+void SDIO_HISR_Entry(void)
+{
+
+ cmd52_config_struct cmd52;
+ kal_uint32 count;
+ if(gSDIO.state!=CMD&&gSDIO.state!=TRN)
+ {
+ #ifdef MSDC_INT
+ kal_set_eg_events(msdc2_sdio->MSDC_Events,EVENT_SDMCIRQ,KAL_OR);
+ #endif
+ }
+ else
+ {
+ #if 1
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 5;
+
+ if((int_status = SDIO_Cmd52_isr(&cmd52))==NO_ERROR)
+ {
+ for(count=SDIO_FUCN_1;count<SDIO_MAX_FUCN_ID;count++)
+ {
+ if(cmd52.data&(1<<count))
+ gSDIO.callback[count]();
+ }
+ }
+ else
+ {
+ /*dbg_print("int read failed\r\n");*/
+ }
+ #endif
+ }
+}
+
+/*************************************************************************
+* FUNCTION
+* SDIO_check_IO_Int
+*
+* DESCRIPTION
+* This function is to check interrupt status
+*
+* PARAMETERS
+* function: function id
+* *pending: interrupt status
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_Int(SDIO_function_id_enum function, kal_bool *pending)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 5;
+ status = SDIO_Cmd52(&cmd52);
+ *pending=(cmd52.data&(1<<function))>>function;
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_configure_BLK_size
+*
+* DESCRIPTION
+* This function is to configure block size
+*
+* PARAMETERS
+* function: function id
+* size: block size
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_configure_BLK_size(SDIO_function_id_enum function, kal_uint32 size)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0x10+0x100*function;
+ cmd52.data = size&0xff;
+ status = SDIO_Cmd52(&cmd52);
+ if(size>=256)
+ {
+ cmd52.adrs = 0x11+0x100*function;
+ cmd52.data = (size&0xff00)>>8;
+ status = SDIO_Cmd52(&cmd52);
+ }
+ if(status==NO_ERROR)
+ {
+ gSDIO.block_size[function]=size;
+ /*set block length as size*/
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,(kal_uint32)size,SDC_CFG_BLKLEN);
+ }
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_query_BLK_size
+*
+* DESCRIPTION
+* This function is to query function's maximum block size
+*
+* PARAMETERS
+* function: function id
+*
+* RETURNS
+* size: block size
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_uint32 SDIO_query_BLK_size(SDIO_function_id_enum function)
+{
+ kal_uint32 max_block_size;
+ kal_uint32 i;
+ for(i=0;i<SDIO_TUPLE_SIZE;i++)
+ {
+ if(sdio_tuple[function][i]==0x22)
+ {
+ if(function==SDIO_FUCN_0)
+ max_block_size=(sdio_tuple[function][i+3])|(sdio_tuple[function][i+4]<<8);
+ else
+ max_block_size=(sdio_tuple[function][i+14])|(sdio_tuple[function][i+15]<<8);
+ return max_block_size;
+ }
+ }
+ return 0;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_query_IO_id
+*
+* DESCRIPTION
+* This function is to query application function id
+*
+* PARAMETERS
+* ap: application type
+*
+* RETURNS
+* function: function id
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDIO_function_id_enum SDIO_query_IO_id(SDIO_interface_code_enum ap)
+{
+ switch(ap)
+ {
+ case SDIO_INTERFACE_NULL:
+ break;
+ case SDIO_INTERFACE_UART:
+ break;
+ case SDIO_INTERFACE_A_BT:
+ break;
+ case SDIO_INTERFACE_B_BT:
+ break;
+ case SDIO_INTERFACE_GPS:
+ break;
+ case SDIO_INTERFACE_CAMERA:
+ break;
+ case SDIO_INTERFACE_PHS:
+ break;
+ case SDIO_INTERFACE_WLAN:
+ return 1;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_SW_reset
+*
+* DESCRIPTION
+* This function is to reset all I/O function
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_SW_reset(void)
+{
+ cmd52_config_struct cmd52;
+ SDC_CMD_STATUS status;
+
+ /*use CMD52 to reset card*/
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 6;
+ cmd52.data = 0xff;
+ status=SDIO_Cmd52(&cmd52);
+ return status;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_abort_IO
+*
+* DESCRIPTION
+* This function is to abort function
+*
+* PARAMETERS
+* function:function id
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_abort_IO(SDIO_function_id_enum function)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ SDIO_dispatch_IO(SDIO_FUCN_0);
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 6;
+ cmd52.data = function&0x7;
+ status = SDIO_Cmd52(&cmd52);
+ SDIO_resume_IO(SDIO_FUCN_0);
+ return status;
+}
+/*Function for WiFi */
+/*************************************************************************
+* FUNCTION
+* SDIO_Register_Write
+*
+* DESCRIPTION
+* This function is to write register
+*
+* PARAMETERS
+* function:function id
+* addr: address
+* data: write data
+* op: fixed or incrementing address
+* RETURNS
+* success or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+/*Write Register*/
+kal_bool SDIO_Register_Write(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint32 data,
+ cmd53_op_enum op)
+{
+
+ kal_uint32 tmp = data;
+ cmd53_config_struct cmd53;
+
+ SDIO_dispatch_IO(function);
+ cmd53.rw = SDIO_WRITE;
+ cmd53.func = function;
+ cmd53.block = KAL_FALSE;
+ cmd53.buffer = (kal_uint32)&tmp;
+ cmd53.count = 4;
+ cmd53.op = op;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+ {
+ SDIO_resume_IO(function);
+ return KAL_FALSE;
+ }
+ else
+ {
+ SDIO_resume_IO(function);
+ return KAL_TRUE;
+ }
+}
+kal_bool SDIO_Register_Write_isr(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint32 data,
+ cmd53_op_enum op)
+{
+
+ kal_uint32 tmp = data;
+ cmd53_config_struct cmd53;
+
+ cmd53.rw = SDIO_WRITE;
+ cmd53.func = function;
+ cmd53.block = KAL_FALSE;
+ cmd53.buffer = (kal_uint32)&tmp;
+ cmd53.count = 4;
+ cmd53.op = op;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53_isr(&cmd53)!=NO_ERROR))
+ {
+ return KAL_FALSE;
+ }
+ else
+ {
+ return KAL_TRUE;
+ }
+}
+/*Write Data */
+/*************************************************************************
+* FUNCTION
+* SDIO_Data_Write
+*
+* DESCRIPTION
+* This function is to write memory
+*
+* PARAMETERS
+* function:function id
+* addr: address
+* data: write data
+* op: fixed or incrementing address
+* count: transfer count
+* block: block/byte mode
+*
+* RETURNS
+* success or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_Data_Write(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint8 *data,
+ cmd53_op_enum op,
+ kal_uint32 count,
+ kal_bool block)
+{
+ cmd53_config_struct cmd53;
+ //kal_uint32 size, i;
+ //kal_uint32 sdio_buffer[256];
+
+ SDIO_dispatch_IO(function);
+ #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ cmd53.rw = SDIO_WRITE;
+ cmd53.func = function;
+ cmd53.block = block;
+ cmd53.buffer = (kal_uint32)data;//(kal_uint32)&sdio_buffer[0];
+ cmd53.count = count;
+ cmd53.op = op;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+ {
+ SDIO_resume_IO(function);
+ return KAL_FALSE;
+ }
+ else
+ {
+ SDIO_resume_IO(function);
+ return KAL_TRUE;
+ }
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_Register_Read
+*
+* DESCRIPTION
+* This function is to Read register
+*
+* PARAMETERS
+* function:function id
+* addr: address
+* data: write data
+* op: fixed or incrementing address
+*
+* RETURNS
+* success or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+/*Read Register*/
+kal_bool SDIO_Register_Read(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint32 *data,
+ cmd53_op_enum op)
+{
+ cmd53_config_struct cmd53;
+
+ SDIO_dispatch_IO(function);
+ cmd53.rw = SDIO_READ;
+ cmd53.func = function;
+ cmd53.block = KAL_FALSE;
+ cmd53.buffer = (kal_uint32)data;
+ cmd53.count = 4;
+ cmd53.op = op;;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+ {
+ SDIO_resume_IO(function);
+ return KAL_FALSE;
+ }
+ else
+ {
+ SDIO_resume_IO(function);
+ return KAL_TRUE;
+ }
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_Register_Read_poll
+*
+* DESCRIPTION
+* This function is to Read register by SDIO bus driver
+*
+* PARAMETERS
+* function:function id
+* addr: address
+* data: write data
+* op: fixed or incrementing address
+*
+* RETURNS
+* success or not
+*
+* GLOBALS AFFECTED
+* only for SDIO bus driver
+*************************************************************************/
+kal_bool SDIO_Register_Read_poll(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint32 *data,
+ cmd53_op_enum op)
+{
+ cmd53_config_struct cmd53;
+
+ cmd53.rw = SDIO_READ;
+ cmd53.func = function;
+ cmd53.block = KAL_FALSE;
+ cmd53.buffer = (kal_uint32)data;
+ cmd53.count = 4;
+ cmd53.op = op;;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53_isr(&cmd53)!=NO_ERROR))
+ {
+ return KAL_FALSE;
+ }
+ else
+ {
+ return KAL_TRUE;
+ }
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_Data_Read
+*
+* DESCRIPTION
+* This function is to read memory
+*
+* PARAMETERS
+* function:function id
+* addr: address
+* data: write data
+* op: fixed or incrementing address
+* count: transfer count
+* block: block/byte mode
+*
+* RETURNS
+* success or not
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool SDIO_Data_Read(SDIO_function_id_enum function,
+ kal_uint32 addr,
+ kal_uint8 *data,
+ cmd53_op_enum op,
+ kal_uint32 count,
+ kal_bool block)
+{
+ cmd53_config_struct cmd53;
+ SDIO_dispatch_IO(function);
+ cmd53.rw = SDIO_READ;
+ cmd53.func = function;
+ cmd53.block = block;
+ cmd53.buffer = (kal_uint32)data;
+ cmd53.count = count;
+ cmd53.op = op;
+ cmd53.adrs = (kal_uint32)addr;
+ if((SDIO_Cmd53(&cmd53)!=NO_ERROR))
+ {
+ SDIO_resume_IO(function);
+ return KAL_FALSE;
+ }
+ else
+ {
+ SDIO_resume_IO(function);
+ return KAL_TRUE;
+ }
+}
+
+/*not support in MT6228 and MT6229*/
+#ifdef __SDIO_SRW_SRW__
+/*************************************************************************
+* FUNCTION
+* SDIO_suspend_IO
+*
+* DESCRIPTION
+* This function is to suspend function
+*
+* PARAMETERS
+* bus_status: bus status
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_suspend_IO(SDIO_bus_status_enum *bus_status)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_TRUE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0xc;
+ cmd52.data = 1;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ *bus_status=(cmd52.data&0x2)>>1;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SDIO_select_IO
+*
+* DESCRIPTION
+* This function is to resume function
+*
+* PARAMETERS
+* bus_status: bus status
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_select_IO(SDIO_function_id_enum function, kal_bool *resume_data)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_WRITE;
+ cmd52.func = 0;
+ cmd52.raw = KAL_TRUE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0xd;
+ cmd52.data = function&0xf;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ *resume_data=(cmd52.data&0x80)>>7;
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_check_IO_exec
+*
+* DESCRIPTION
+* This function is to check function execution status
+*
+* PARAMETERS
+* execute_status: execute status
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_exec(SDIO_function_id_enum function, kal_bool *execution)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0xe;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ if(function!=SDIO_FUCN_MEM)
+ *execution=(cmd52.data&(1<<function))>>function ;
+ else
+ *execution=cmd52.data&0x1;
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SDIO_check_IO_ready_flag
+*
+* DESCRIPTION
+* This function is to check function execution status
+*
+* PARAMETERS
+* bus_status: bus status
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+SDC_CMD_STATUS SDIO_check_IO_ready_flag(SDIO_function_id_enum function, kal_bool *ready)
+{
+ SDC_CMD_STATUS status;
+ cmd52_config_struct cmd52;
+
+ cmd52.rw = SDIO_READ;
+ cmd52.func = 0;
+ cmd52.raw = KAL_FALSE;
+ cmd52.stop = KAL_FALSE;
+ cmd52.adrs = 0xf;
+ if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
+ return status;
+ if(function!=SDIO_FUCN_MEM)
+ *ready=(cmd52.data&(1<<function))>>function ;
+ else
+ *ready=cmd52.data&0x1;
+
+ return NO_ERROR;
+}
+#endif
+#endif
+
+#endif //DRV_MSDC_OFF
diff --git a/mcu/driver/storage/mc/src/sdiotest.c b/mcu/driver/storage/mc/src/sdiotest.c
new file mode 100644
index 0000000..7cda55b
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sdiotest.c
@@ -0,0 +1,596 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2001
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * sdiotest.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * SDIO test code
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+// MTK
+#include "drv_features.h"
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#include "reg_base.h"
+#include "intrCtrl.h"
+
+// SDIO
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "sdio_def.h"
+#include "sdio_test.h"
+#include "sdio_sw.h"
+
+#if (defined(__MSDC_SD_MMC__)&&defined(__MSDC_SD_SDIO__)) || defined(__MSDC2_SD_SDIO__)
+extern cmd52_config_struct cmd52_config;
+extern cmd53_config_struct cmd53_config;
+#define WIFI_FUNC 1
+
+
+
+__align(4) kal_uint8 buffer[1024];
+extern __align(4) kal_uint8 sdio_cccr_reg[SDIO_CCCR_SIZE];
+extern __align(4) kal_uint8 sdio_fbr_reg[SDIO_FBR_SIZE];
+extern __align(4) kal_uint8 sdio_tuple[SDIO_MAX_FUCN_ID][SDIO_TUPLE_SIZE];
+volatile kal_uint32 cmd = 0, arg = 0;
+volatile kal_uint32 flag52 = 1, flag53 = 0, flag_SD = 0, flag_4bit = 1;
+cmd52_config_struct cmd52_config;
+cmd53_config_struct cmd53_config;
+void SDIO_test_main2(void);
+extern MSDC_HANDLE *msdc2_handle ;
+
+void sdio_clr_int(void)
+{
+ UINT32 mcrValue;
+ //SDIO_Register_Read_poll(SDIO_FUCN_1, MCR_ISAR, (kal_uint32*)&mcrValue , SDIO_FIX);
+ //NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+}
+void test_hisr(void)
+{
+ dbg_print("interrupt callback\r\n");
+ sdio_clr_int();
+}
+
+
+void test_sdio_ini(void)
+{
+ SDC_CMD_STATUS status;
+ kal_uint8 version;
+ kal_uint16 tick;
+ kal_bool ready;
+ kal_uint32 retry_count=0;
+ kal_uint32 block_size=0;
+
+
+ /*initialize*/
+ dbg_print("SDIO initilaization start\r\n");
+ status=SDIO_Initialize();
+ dbg_print("SDIO initilaization end=%d\r\n", status);
+ dbg_print("SDIO test start\r\n");
+
+ /*CCCR verison*/
+ status=SDIO_read_CCCR_ver(&version);
+ dbg_print("read CCCR ver status %d ver %d \r\n", status, version);
+ /*SDIO verison*/
+ status=SDIO_read_SDIO_ver(&version);
+ dbg_print("read SDIO ver status %d ver %d \r\n", status, version);
+ /*SD verison*/
+ status=SDIO_read_SD_ver(&version);
+ dbg_print("read SDIO SD status %d ver %d \r\n", status, version);
+
+ /* check card capability*/
+ status=SDIO_read_capacity();
+ if(!status)
+ {
+ dbg_print("SDC %d%\r\n", SDIO_support_SDC());
+ dbg_print("SMB %d%\r\n", SDIO_support_SMB());
+ dbg_print("SRW %d%\r\n", SDIO_support_SRW());
+ dbg_print("SBS %d%\r\n", SDIO_support_SBS());
+ dbg_print("S4MI %d%\r\n", SDIO_support_S4MI());
+ //dbg_print("E4MI %d%\r\n", SDIO_enable_E4MI(KAL_TRUE));
+ dbg_print("LSC %d%\r\n", SDIO_support_LSC());
+ dbg_print("4BLS %d%\r\n", SDIO_support_4BLS());
+ }
+ else
+ {
+ dbg_print("read capacity %d failed \r\n", cmd52_config.adrs);
+ }
+
+ /* enable SDIO function*/
+ retry_count=0;
+
+
+ /* set the block size of func1 to 128*/
+
+ dbg_print("set function block size %d \r\n", 128);
+
+ status=SDIO_configure_BLK_size(SDIO_FUCN_1, 128);
+ dbg_print("set block size (function 1) %d\r\n", status);
+ status=SDIO_configure_BLK_size(SDIO_FUCN_0, 128);
+ dbg_print("set block size(function 0) %d\r\n", status);
+
+ // config the sdio controller
+ MSDC_SetBits32(SDC_CFG, SDC_CFG_SDIO);// enable SDIO mode
+ MSDC_WriteReg32(SDIO_CFG, 1); // enable SDIO interrupt
+
+ // *****************************************//
+ // always turn on the serial clock
+ // MSDC_SetBits32(MSDC_CFG, MSDC_CFG_SCKON);
+ // *****************************************//
+
+
+
+ status=SDIO_query_IO_id(SDIO_INTERFACE_WLAN);
+ dbg_print("SDIO_INTERFACE_WLAN function id =%d\r\n", status);
+
+ status=SDIO_query_IO_id(SDIO_INTERFACE_WLAN);
+ dbg_print("SDIO_INTERFACE_WLAN function id =%d\r\n", status);
+ block_size=SDIO_query_BLK_size(SDIO_FUCN_1);
+ dbg_print("function 1 block size =%d\r\n", block_size);
+
+ SDIO_int_registration(SDIO_FUCN_1, test_hisr);
+ status=SDIO_enable_IO_Int(SDIO_FUCN_0, KAL_TRUE);
+ dbg_print("enable card int%d \r\n",status);
+ status=SDIO_enable_IO_Int(SDIO_FUCN_1, KAL_TRUE);
+ dbg_print("enable function %d int%d \r\n",SDIO_FUCN_1, status);
+ /* read all configuration register of CCCR*/
+ status=SDIO_read_CCCR();
+ dbg_print("read all CCCR=%d\r\n", status);
+ status=SDIO_read_FBR(1);
+ dbg_print("read all FBR=%d\r\n", status);
+
+
+ /*start WiFi test*/
+#ifndef MSDC2_SDIO_DVT
+ if(KAL_TRUE == gMSDC_Handle->mIsInitialized)
+#else
+ if(KAL_TRUE == msdc2_handle->mIsInitialized)
+#endif
+ {
+ SDIO_test_main2();
+ SDIO_test_main();
+ }
+ else{
+ return;
+ }
+ while(0)
+ {
+ if(flag52)
+ {
+ cmd52_config.rw = SDIO_READ;
+ cmd52_config.func = 0;
+ cmd52_config.raw = KAL_FALSE;
+ cmd52_config.stop = KAL_FALSE;
+ cmd52_config.adrs = 0;
+ cmd52_config.data = 0;
+ SDIO_Cmd52(&cmd52_config);
+ }
+ // check SMB first (Support Multi-Block)
+ // config the block size
+ if(flag53)
+ {
+ cmd53_config.rw = SDIO_READ;
+ cmd53_config.func = 0;
+ cmd53_config.block = KAL_FALSE;
+ cmd53_config.buffer = (kal_uint32)buffer;
+ cmd53_config.count = 4;
+ cmd53_config.op = SDIO_INC;
+ cmd53_config.adrs = 0;
+ SDIO_Cmd53(&cmd53_config);
+ //dbg_print("SDIO initilaization end=%d\r\n", status);
+ }
+ }
+
+}
+
+
+
+kal_bool IPC_2126_MCR_Read(kal_uint16 offset, kal_uint32 *pValue)
+{
+ kal_bool status;
+ #if 1
+ status = SDIO_Register_Read(SDIO_FUCN_1,
+ (kal_uint32) offset,
+ pValue,
+ SDIO_FIX);
+ return status;
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+}
+void IPC_2126_MCR_Read_N(kal_uint16 offset, kal_uint32 pValue, kal_uint32 count, kal_bool block )
+{
+ cmd53_config.rw = SDIO_READ;
+ cmd53_config.func = WIFI_FUNC;
+ cmd53_config.block = block;
+ cmd53_config.buffer = (kal_uint32)pValue;
+ cmd53_config.count = count;
+ cmd53_config.op = SDIO_FIX;
+ cmd53_config.adrs = (kal_uint32)offset;
+ SDIO_Cmd53(&cmd53_config);
+
+}
+kal_bool IPC_2126_MCR_Write(kal_uint16 offset, kal_uint32 value)
+{
+ kal_uint32 tmp = value;
+ kal_bool status;
+ #if 1
+ status = SDIO_Register_Write(SDIO_FUCN_1,
+ (kal_uint32) offset,
+ value,
+ SDIO_FIX);
+
+ return status;
+ #else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+}
+void IPC_2126_MCR_Write_N(kal_uint16 offset, kal_uint32 value, kal_uint32 count, kal_bool block )
+{
+ cmd53_config.rw = SDIO_WRITE;
+ cmd53_config.func = WIFI_FUNC;
+ cmd53_config.block = block;
+ cmd53_config.buffer = (kal_uint32)value;
+ cmd53_config.count = count;
+ cmd53_config.op = SDIO_FIX;
+ cmd53_config.adrs = (kal_uint32)offset;
+ SDIO_Cmd53(&cmd53_config);
+
+}
+/*----------------------------------------------------------------*/
+/*!
+* \brief
+*
+* \param
+* \return
+*/
+/*----------------------------------------------------------------*/
+volatile kal_bool my_flag = 1;
+volatile kal_bool my_flag_2 = 0;
+__align(4) kal_uint8 value[1024]= {0xff};
+int SDIO_test_main(void)
+{
+ kal_uint32 mcrValue;
+ int tbttCount = 0;
+ kal_uint32 test_count=0;
+ kal_bool pending;
+ SDC_CMD_STATUS status;
+ //SDIO_ARG arg;
+
+ kal_uint32 i;
+ kal_uint32 loopTestIndex;
+
+ /* Reset chip and enable all clocks */
+ NIC_MCR_WRITE(NULL, MCR_SCR, (SCR_BB_MRST | SCR_MAC_RST |
+ SCR_BB_SIORST | SCR_MAC_REGRST));
+ NIC_MCR_WRITE(NULL, MCR_SCR, SCR_CLK_ALL_EN);
+ NIC_MCR_READ(NULL, MCR_SCR, value);
+
+ /* Here maybe need delay for OSC stable */
+ for(i=0;i<10000;i++);
+
+ /* Check chip ID */
+ NIC_MCR_READ(NULL, MCR_PCICR, &mcrValue);
+ //printk("IPN2128 ChipIDVersion read test: [0x%08lX] \n", mcrValue);
+ if ((mcrValue & CHIP_ID_MASK) != CHIP_ID_REV) {
+ //printk(KERN_ALERT "IPN2128 not found... \n");
+ }
+ //if(my_flag)
+ NIC_MCR_WRITE(NULL, MCR_SDCR, BITS(4,6)); /* Use enhanced mode */
+
+ /* Reset TSF and enable TBTT interrupt */
+ /* Set our local TSF timer to 0 */
+ NIC_MCR_WRITE(NULL, MCR_TTAR1, 0);
+ NIC_MCR_WRITE(NULL, MCR_TTAR2, 0);
+ NIC_MCR_WRITE(NULL, MCR_TTAR0, TTAR0_TSF_TIMER_VALUE_CHANGE);
+
+ /* Set the next TBTT time and the TBTT event generation period. */
+ NIC_MCR_WRITE(NULL, MCR_NTTCR, ((100) &
+ NTTCR_NEXT_TBTT_TIME) | (100 << 16));
+
+ /* Enable the TBTT event generator. */
+ NIC_MCR_WRITE(NULL, MCR_MPTCR, MPTCR_EN_COMP_NEXT_TBTT_TIME | MPTCR_TBTT_ENABLE);
+
+ /* Enable interrupt */ //IER_PRE_TBTT_INT, IER_SDIO_ABNORMAL_INT
+ NIC_MCR_WRITE(NULL, MCR_IER, IER_GLOBAL_ENABLE | IER_TBTT_INT);
+ NIC_MCR_READ(NULL, MCR_IER, &mcrValue);
+
+ /* In loop, cmd53 is repeated to test interrupt event with cmd53 read */
+ while (1)
+ {
+
+ /*cmd52_config.rw = SDIO_READ;
+ cmd52_config.func = 0;
+ cmd52_config.raw = KAL_FALSE;
+ cmd52_config.stop = KAL_FALSE;
+ cmd52_config.adrs = 5;
+ cmd52_config.data = 0;
+ SDIO_Cmd52(&cmd52_config);*/
+ //status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);
+ //if( pending != 0 )
+ if(mcrValue!=0)
+ {
+ tbttCount++;
+ dbg_print("Int Pending %d \r\n", pending);
+ dbg_print("TBTT count %d \r\n", tbttCount);
+ NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+ dbg_print("ISAR %d \r\n", mcrValue);
+ }
+ else
+ NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+ /*
+ NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+ if (mcrValue & ISAR_TBTT_INT) {
+ tbttCount++;
+ //printk("TBTT event occurs %d\n", tbttCount);
+ */
+ if (tbttCount >= 10) break; /* 10sec */
+
+ }
+
+ /* Enable interrupt of abnormal interrupt */
+ NIC_MCR_WRITE(NULL, MCR_IER, IER_GLOBAL_ENABLE | IER_SDIO_ABNORMAL_INT);
+ NIC_MCR_READ(NULL, MCR_IER, &mcrValue);
+
+#if 1
+ /* Do illegal (byte/block) Read/Write to trigger abnormal interrupt */
+ loopTestIndex = 30;
+ while (loopTestIndex--)
+ {
+ kal_uint8 test;
+
+ dbg_print("start %d int test\r\n", test_count);
+
+ test = 0;
+
+ test++;
+ IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[0],8, KAL_FALSE);
+ status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);
+#ifndef MSDC2_SDIO_DVT
+ if(MSDC_Reg(SDIO_STA) == 1)
+#else
+ if(MSDC_Reg(SDIO_STA2) == 1)
+#endif
+ test--;
+ //NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+ //dbg_print("ISAR %d \r\n", mcrValue);
+ if(test)
+ ASSERT(0);
+
+ test++;
+ IPC_2126_MCR_Write_N(0x0128,(kal_uint32)&value[0],8, KAL_FALSE);
+ status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);
+#ifndef MSDC2_SDIO_DVT
+ if(MSDC_Reg(SDIO_STA) == 1)
+#else
+ if(MSDC_Reg(SDIO_STA2) == 1)
+#endif
+ test--;
+ //NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+ //dbg_print("ISAR %d \r\n", mcrValue);
+ if(test)
+ ASSERT(0);
+
+ test++;
+ IPC_2126_MCR_Write_N(0x0128,(kal_uint32)&value[0], 1, KAL_TRUE);
+ status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);
+#ifndef MSDC2_SDIO_DVT
+ if(MSDC_Reg(SDIO_STA) == 1)
+#else
+ if(MSDC_Reg(SDIO_STA2) == 1)
+#endif
+ test--;
+ NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+ //dbg_print("ISAR %d \r\n", mcrValue);
+ if(test)
+ ASSERT(0);
+
+ test++;
+ IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[0], 1, KAL_TRUE);
+ status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);
+#ifndef MSDC2_SDIO_DVT
+ if(MSDC_Reg(SDIO_STA) == 1)
+#else
+ if(MSDC_Reg(SDIO_STA2) == 1)
+#endif
+ test--;
+ //NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+ //dbg_print("ISAR %d \r\n", mcrValue);
+ if(test)
+ ASSERT(0);
+
+ #if 0
+ #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+ if(my_flag_2)
+ break;
+ }
+#endif
+
+ return 0;
+} /* end of main() */
+
+
+void SDIO_test_main2(void)
+{
+ UINT32 mcrValue;
+ UINT32 tmcrValue;
+ UINT32 i;
+ UINT8 mcr[4];
+ int tbttCount;
+ SDC_CMD_STATUS status;
+ kal_uint32 j;
+
+
+ /* Reset chip and enable all clocks */
+ NIC_MCR_WRITE(NULL, MCR_SCR, (SCR_BB_MRST | SCR_MAC_RST |
+ SCR_BB_SIORST | SCR_MAC_REGRST));
+ for(j=0;j<100000;j++);
+ /* Here delay 1us to complete reset process */
+ NIC_MCR_WRITE(NULL, MCR_SCR, SCR_CLK_ALL_EN);
+ /* Check chip ID */
+ NIC_MCR_READ(NULL, MCR_PCICR, &mcrValue);
+ IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[0], 4, KAL_TRUE);
+ //SDIO_Register_Read(SDIO_FUCN_1, MCR_PCICR, (kal_uint32*)&tmcrValue, SDIO_FIX);
+ //SDIO_Data_Read(SDIO_FUCN_1, MCR_PCICR, &mcr[0], SDIO_FIX, 4, KAL_FALSE);
+
+ //printk("IPN2128 ChipIDVersion read test: [0x%08lX] \n", mcrValue);
+ if ((mcrValue & CHIP_ID_MASK) != CHIP_ID_REV) {
+ //printk(KERN_ALERT "IPN2128 not found... \n");
+ }
+ NIC_MCR_WRITE(NULL, MCR_SDCR, BITS(4,6)); /* Use enhanced mode */
+
+ /* Reset TSF and enable TBTT interrupt */
+ /* Set our local TSF timer to 0 */
+ NIC_MCR_WRITE(NULL, MCR_TTAR1, 0);
+ NIC_MCR_WRITE(NULL, MCR_TTAR2, 0);
+ NIC_MCR_WRITE(NULL, MCR_TTAR0, TTAR0_TSF_TIMER_VALUE_CHANGE);
+
+ /* Set the next TBTT time and the TBTT event generation period (20ms). */
+ NIC_MCR_WRITE(NULL, MCR_NTTCR, ((100) &
+ NTTCR_NEXT_TBTT_TIME) | (20 << 16));
+
+ /* Enable the TBTT event generator. */
+ NIC_MCR_WRITE(NULL, MCR_MPTCR, MPTCR_EN_COMP_NEXT_TBTT_TIME | MPTCR_TBTT_ENABLE);
+
+ /* Enable interrupt */
+ NIC_MCR_WRITE(NULL, MCR_IER, IER_GLOBAL_ENABLE | IER_TBTT_INT | IER_SDIO_ABNORMAL_INT);
+
+#if 1
+ /* In loop, cmd53 is repeated to test interrupt event with cmd53 read */
+ tbttCount = 0;
+ dbg_print("trigger interrupt during sigle block \r\n");
+ while (1)
+ {
+ kal_bool pending;
+ //status=SDIO_check_IO_Int(SDIO_FUCN_1, &pending);
+ NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue);
+ if (mcrValue & ISAR_TBTT_INT)
+ {
+ kal_uint32 test_count;
+ tbttCount++;
+ dbg_print("TBTT event occurs %d\r\n", tbttCount);
+ for(test_count=0;test_count<100;test_count++)
+ {}
+ if (tbttCount >= 100) break; /* 10sec */
+ }
+ }
+#endif
+
+#if 1
+ /* Read/Writel multiple block with TBTT interrupt */
+ while (1) {
+ /*
+ arg = BUILD_IO_RW_EXTENDED_ARG(SDIO_RWFLAG_WRITE,
+ 1, SDIO_IO_BLOCK_MODE, SDIO_IO_FIX_ADDR, 0x0128, 4);
+ sdioCmd53ReadWrite(x_slot, arg, (__u8*)&value[0]);
+ */
+
+
+ /*
+ arg = BUILD_IO_RW_EXTENDED_ARG(SDIO_RWFLAG_READ,
+ 1, SDIO_IO_BLOCK_MODE, SDIO_IO_FIX_ADDR, 0x0128, 4);
+ sdioCmd53ReadWrite(x_slot, arg, (__u8*)&value[0]);
+ */
+ dbg_print("trigger interrupt during multiple block \r\n");
+ memset(value, 0, 1024);
+ IPC_2126_MCR_Write_N(0x0128,(kal_uint32)&value[0], 4, KAL_TRUE);
+ //memset(value, 0x5, 1024);
+ NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue); /* Clear TBTT Interrupt */
+ //IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[0], 128, KAL_FALSE);
+ //IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[128], 128, KAL_FALSE);
+ //IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[256], 128, KAL_FALSE);
+ //IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[384], 128, KAL_FALSE);
+ //memset(value, 0x5, 1024);
+ NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue); /* Clear TBTT Interrupt */
+ IPC_2126_MCR_Read_N(0x0128,(kal_uint32)&value[0], 4, KAL_TRUE);
+ NIC_MCR_READ(NULL, MCR_ISAR, &mcrValue); /* Clear TBTT Interrupt */
+ NIC_MCR_READ(NULL, 0x118, &mcrValue);
+
+ if(my_flag)
+ break;
+
+
+ }
+#endif
+
+}
+#endif
+
+
diff --git a/mcu/driver/storage/mc/src/usbms_msdc.c b/mcu/driver/storage/mc/src/usbms_msdc.c
new file mode 100644
index 0000000..fafceb6
--- /dev/null
+++ b/mcu/driver/storage/mc/src/usbms_msdc.c
@@ -0,0 +1,784 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * usbms_msdc.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * This file implements usb adaption layer of msdc card for mass storage
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#if defined(__USB_MSD_SUPPORT__) || defined(ATEST_DRV_MSDC)
+
+//RHR ADD
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#include "qmu_bm.h"
+//RHR REMOVE
+/*
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//MSBB remove #include "kal_non_specific_general_types.h"
+#include "drv_comm.h"
+#include "gpt_sw.h"
+#include "usb_comm.h"
+#include "usb_drv.h"
+#include "usb.h"
+#include "usbms_drv.h"
+#include "usbms_adap.h"
+#include "usb_custom.h"
+#include "Rtfiles.h"
+#include "fat_fs.h"
+#include "custom_fs.h"
+*/
+//RHR
+#include "msdc_def.h"
+#include "fs_type.h"
+/***********************************************
+ MS and SD Disk Related functions
+************************************************/
+
+//#if !defined(DCL_MSDC_INTERFACE)
+#include "msdc_def.h"
+//#endif
+
+#ifdef __MSDC_MS__
+ #include "ms_def.h"
+ extern FS_Driver FS_MsDrv;
+ FS_Driver *CardDrv = &FS_MsDrv;
+#elif defined(__MSDC_MSPRO__)
+ #include "mspro_def.h"
+ FS_Driver *CardDrv = &FS_MspDrvAll;
+#elif defined(__MSDC_SD_MMC__)
+ #if defined(DCL_MSDC_INTERFACE)
+ #include "dcl.h"
+ #else
+ #include "sd_def.h"
+ #endif
+ extern FS_Driver FS_SdDrv;
+ FS_Driver *CardDrv = &FS_SdDrv;
+#endif
+
+#include "qmu_bm.h"
+#include "usbms_msdc.h"
+
+extern int Gpd_ReadSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors,qbm_gpd *head,qbm_gpd *tail);
+extern int Gpd_WriteSectors_NEW(void * DriveData, kal_uint32 Sector, kal_uint32 Sectors, qbm_gpd *head,qbm_gpd *tail);
+extern kal_uint32 Get_BDStructNum(void);
+kal_bool usbms_query_max_bd_num(kal_uint16 * max_bd_num)
+{
+ *max_bd_num = (kal_uint16)Get_BDStructNum();
+ return KAL_TRUE;
+}
+#if ( (defined(__MSDC_MS__)) || (defined(__MSDC_SD_MMC__)) || (defined(__MSDC_MSPRO__)) )
+kal_bool usbms_read_all(void *data, kal_uint32 LBA, kal_uint16 sec_len, MSDC_EXT_MEM_TYPE type)
+{
+ kal_int32 status;
+ void *ID = NULL;
+ ASSERT(CardDrv != NULL);
+ switch(type)
+ {
+ case MSDC_MEM_TYPE_EXT:
+ ID = EXT_MEM_ID;
+ break;
+#if defined(__SIM_PLUS__)
+ case MSDC_MEM_TYPE_SIMPLUS:
+ ID = SIMPLUS_MEM_ID;
+ break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+ case MSDC_MEM_TYPE_TCARD2:
+ ID = TCARD_2_MEM_ID;
+ break;
+#endif
+ default:
+ ID = NULL;
+ return KAL_FALSE;
+ }
+
+ status = CardDrv->ReadSectors((void*)ID, LBA, sec_len, data);
+
+ if(status)
+ return KAL_FALSE;
+
+ return KAL_TRUE;
+}
+kal_bool usbms_gpd_read_all(qbm_gpd *head,qbm_gpd *tail,kal_uint32 LBA,kal_uint16 sec_len,MSDC_EXT_MEM_TYPE type)
+{
+ kal_int32 status;
+ void *ID = NULL;
+ ASSERT(CardDrv != NULL);
+ switch(type)
+ {
+ case MSDC_MEM_TYPE_EXT:
+ ID = EXT_MEM_ID;
+ break;
+#if defined(__SIM_PLUS__)
+ case MSDC_MEM_TYPE_SIMPLUS:
+ ID = SIMPLUS_MEM_ID;
+ break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+ case MSDC_MEM_TYPE_TCARD2:
+ ID = TCARD_2_MEM_ID;
+ break;
+#endif
+ default:
+ ID = NULL;
+ return KAL_FALSE;
+ }
+ status = Gpd_ReadSectors_NEW((void*)ID, LBA, sec_len, head,tail);
+
+ if(status)
+ return KAL_FALSE;
+
+ return KAL_TRUE;
+}
+kal_bool usbms_write_all(void *data, kal_uint32 LBA, kal_uint16 sec_len, MSDC_EXT_MEM_TYPE type)
+{
+ kal_int32 status;
+ void *ID = NULL;
+ ASSERT(CardDrv != NULL);
+ switch(type)
+ {
+ case MSDC_MEM_TYPE_EXT:
+ ID = EXT_MEM_ID;
+ break;
+#if defined(__SIM_PLUS__)
+ case MSDC_MEM_TYPE_SIMPLUS:
+ ID = SIMPLUS_MEM_ID;
+ break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+ case MSDC_MEM_TYPE_TCARD2:
+ ID = TCARD_2_MEM_ID;
+ break;
+#endif
+ default:
+ ID = NULL;
+ return KAL_FALSE;
+ }
+
+ status = CardDrv->WriteSectors((void*)ID, LBA, sec_len, data);
+
+ if(status)
+ return KAL_FALSE;
+
+ return KAL_TRUE;
+}
+kal_bool usbms_gpd_write_all(qbm_gpd *head,qbm_gpd *tail,kal_uint32 LBA,kal_uint16 sec_len,MSDC_EXT_MEM_TYPE type)
+{
+ kal_int32 status;
+ void *ID = NULL;
+ ASSERT(CardDrv != NULL);
+
+ switch(type)
+ {
+ case MSDC_MEM_TYPE_EXT:
+ ID = EXT_MEM_ID;
+ break;
+#if defined(__SIM_PLUS__)
+ case MSDC_MEM_TYPE_SIMPLUS:
+ ID = SIMPLUS_MEM_ID;
+ break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+ case MSDC_MEM_TYPE_TCARD2:
+ ID = TCARD_2_MEM_ID;
+ break;
+#endif
+ default:
+ ID = NULL;
+ return KAL_FALSE;
+ }
+ status = Gpd_WriteSectors_NEW((void*)ID, LBA, sec_len, head,tail);
+
+ if(status)
+ return KAL_FALSE;
+
+ return KAL_TRUE;
+}
+
+/*
+typedef enum{
+ USB_MS_EXIST,
+ USB_MS_CHANGED,
+ USB_MS_NOT_EXIST,
+ USB_MS_LOCKED
+}USB_MS_EXIST_ENUM;
+*/
+/*status =0(ok),1(MediaChanged),2(NoMedia)*/
+
+#if defined(DCL_MSDC_INTERFACE)
+
+kal_int16 usbms_checkmedia_exist_all(MSDC_EXT_MEM_TYPE type)
+{
+ DCL_BOOL changed = DCL_FALSE;
+ DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+ DCL_BOOL isCardExist = DCL_FALSE;
+ DCL_BOOL isWP = DCL_FALSE;
+#if defined(__MSDC_SD_MMC__)&&(defined (LIPTON_BB) ||defined(ROSEMARY_BB))
+ SD_CTRL_GET_CAPACITY_T capacity;
+#endif
+//jinxing add for dual T-card.
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ SD_CTRL_ANALOG_SWITCH_T prSwitch;
+ void *ID = NULL;
+
+
+ switch(type)
+ {
+ case MSDC_MEM_TYPE_EXT:
+ ID = EXT_MEM_ID;
+ break;
+ #if defined(__SIM_PLUS__)
+ case MSDC_MEM_TYPE_SIMPLUS:
+ ID = SIMPLUS_MEM_ID;
+ break;
+ #endif
+
+ #if defined(__MSDC_DUAL_CARD_SWITCH__)
+ case MSDC_MEM_TYPE_TCARD2:
+ ID = TCARD_2_MEM_ID;
+ break;
+ #endif
+ default:
+ ID = NULL;
+ return DEV_STATUS_NOMEDIA;
+ }
+#endif
+
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)ID == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+#if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+#endif
+ }
+
+ if(sel==SD_EXT)
+ {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return DEV_STATUS_NOMEDIA;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return DEV_STATUS_NOMEDIA;
+ #else
+ ASSERT(0);
+ #endif
+ }
+ prSwitch.u4TargetInterface=sel;
+ //DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+#else
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return DEV_STATUS_NOMEDIA;
+#endif
+//jinxing add done
+ DclSD_Control(dclHandle, SD_CTRL_CMD_GET_AND_CLEAR_MEDIA_CHANGED, (DCL_CTRL_DATA_T*)&changed);
+ if(changed)
+ {
+ DclSD_Close(dclHandle);
+ return DEV_STATUS_MEDIA_CHANGE;
+ }
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_IS_EXISTENCE, (DCL_CTRL_DATA_T*)&isCardExist);
+ if (isCardExist)
+ {
+ #if defined(__MSDC_SD_MMC__)
+ DclSD_Control(dclHandle, SD_CTRL_CMD_WRITE_PROTECTION, (DCL_CTRL_DATA_T*)&isWP);
+ if(isWP)
+ {
+ DclSD_Close(dclHandle);
+ return DEV_STATUS_WP;
+ }
+ #endif
+ #if defined(__MSDC_MS__)
+ if(gMS.is_wp)
+ {
+ return DEV_STATUS_WP;
+ }
+ #endif
+ #if defined(__MSDC_MSPRO__)
+ if(gMSP.is_wp)
+ {
+ //return USB_MS_LOCKED;
+ return DEV_STATUS_WP;
+ }
+ #endif
+ //return USB_MS_EXIST;
+
+ #if defined(__MSDC_SD_MMC__)
+ #if (defined (LIPTON_BB) ||defined(ROSEMARY_BB))
+ // TFlash larger than 8GB is not support
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_GET_CAPACITY, (DCL_CTRL_DATA_T*)&capacity);
+ if (*(capacity.pu8Capacity) > ((unsigned long long)FS_MAX_DISK_SIZE*1024*1024))
+ {
+ DclSD_Close(dclHandle);
+ return DEV_STATUS_NOMEDIA;
+ }
+ #endif //(LIPTON_BB) ||defined(ROSEMARY_BB))
+ #endif
+
+ DclSD_Close(dclHandle);
+ return DEV_STATUS_OK;
+ }
+
+ DclSD_Close(dclHandle);
+
+ return DEV_STATUS_NOMEDIA;
+}
+
+#else
+
+kal_int16 usbms_checkmedia_exist_all(MSDC_EXT_MEM_TYPE type)
+{
+ kal_bool changed;
+ void *ID = NULL;
+
+ switch(type)
+ {
+ case MSDC_MEM_TYPE_EXT:
+ ID = EXT_MEM_ID;
+ break;
+#if defined(__SIM_PLUS__)
+ case MSDC_MEM_TYPE_SIMPLUS:
+ ID = SIMPLUS_MEM_ID;
+ break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+ case MSDC_MEM_TYPE_TCARD2:
+ ID = TCARD_2_MEM_ID;
+ break;
+#endif
+
+ default:
+ ID = NULL;
+ return DEV_STATUS_NOMEDIA;
+ }
+
+ changed = MSDC_GetMediaChanged((void*)ID);
+ if(changed)
+ {
+ //return USB_MS_CHANGED;
+ return DEV_STATUS_MEDIA_CHANGE;
+ }
+
+ if(gMSDC_Handle->mIsPresent)
+ {
+ #if defined(__MSDC_SD_MMC__)
+ if(gSD->mWPEnabled)
+ {
+ //return USB_MS_LOCKED;
+ return DEV_STATUS_WP;
+ }
+ #endif
+ #if defined(__MSDC_MS__)
+ if(gMS.is_wp)
+ {
+ //return USB_MS_LOCKED;
+ return DEV_STATUS_WP;
+ }
+ #endif
+ #if defined(__MSDC_MSPRO__)
+ if(gMSP.is_wp)
+ {
+ //return USB_MS_LOCKED;
+ return DEV_STATUS_WP;
+ }
+ #endif
+ //return USB_MS_EXIST;
+
+ #if defined(__MSDC_SD_MMC__)
+ #if (defined (LIPTON_BB) ||defined(ROSEMARY_BB))
+ // TFlash larger than 8GB is not support
+ if (gSD->mCSD.capacity > ((unsigned long long)FS_MAX_DISK_SIZE*1024*1024))
+ return DEV_STATUS_NOMEDIA;
+ #endif //(LIPTON_BB) ||defined(ROSEMARY_BB))
+ #endif
+
+ return DEV_STATUS_OK;
+ }
+
+ //return USB_MS_NOT_EXIST;
+ return DEV_STATUS_NOMEDIA;
+}
+
+#endif//defined(DCL_MSDC_INTERFACE)
+
+kal_bool usbms_format_all(MSDC_EXT_MEM_TYPE type)
+{
+ kal_uint32 status;
+ void *ID = NULL;
+
+ switch(type)
+ {
+ case MSDC_MEM_TYPE_EXT:
+ ID = EXT_MEM_ID;
+ break;
+#if defined(__SIM_PLUS__)
+ case MSDC_MEM_TYPE_SIMPLUS:
+ ID = SIMPLUS_MEM_ID;
+ break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+ case MSDC_MEM_TYPE_TCARD2:
+ ID = TCARD_2_MEM_ID;
+ break;
+#endif
+
+ default:
+ return KAL_FALSE;
+ }
+
+ ASSERT(CardDrv != NULL);
+ status = CardDrv->MountDevice((void*)ID,0,0,0);
+ if(status != 512)
+ return KAL_FALSE;
+
+ return KAL_TRUE;
+}
+
+kal_bool usbms_prevmedia_removal_all(kal_bool enable)
+{
+ return KAL_TRUE;
+}
+
+#if defined(DCL_MSDC_INTERFACE)
+
+kal_bool usbms_read_capacity_all(kal_uint32 *max_lba, kal_uint32 *sec_len, MSDC_EXT_MEM_TYPE type)
+{
+ kal_int32 status;
+ DCL_HANDLE dclHandle = DCL_HANDLE_NONE;
+ SD_CTRL_GET_CAPACITY_T capacity;
+ void *ID = NULL;
+//jinxing add for dual T-card.
+#if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sd_select_enum sel;
+ SD_CTRL_ANALOG_SWITCH_T prSwitch;
+#endif
+
+ ASSERT(CardDrv != NULL);
+ switch(type)
+ {
+ case MSDC_MEM_TYPE_EXT:
+ ID = EXT_MEM_ID;
+ break;
+#if defined(__SIM_PLUS__)
+ case MSDC_MEM_TYPE_SIMPLUS:
+ ID = SIMPLUS_MEM_ID;
+ break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+ case MSDC_MEM_TYPE_TCARD2:
+ ID = TCARD_2_MEM_ID;
+ break;
+#endif
+
+ default:
+ return KAL_FALSE;
+ }
+
+ status = CardDrv->MountDevice((void*)ID, 0, 0, 0);
+ if(status != 512)
+ return KAL_FALSE;
+
+ #if defined(__MSDC_MS__)
+ *max_lba = gMS.TotalSectors-1;
+ #elif defined(__MSDC_MSPRO__)
+ *max_lba = gMSP.user_block*gMSP.block_size-1;
+ #elif defined(__MSDC_SD_MMC__)
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ if((MSDC_HANDLE *)ID == &MSDC_Blk[0])
+ {
+ sel = SD_EXT;
+ }
+ else
+ {
+#if defined(__SIM_PLUS__)
+ sel = SD_SIM;
+#elif defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ sel = SD_T_CARD_2;
+#endif
+ }
+
+ if(sel==SD_EXT)
+ {
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return KAL_FALSE;
+ }
+ else
+ {
+ #if defined(__SIM_PLUS__) || defined(DRV_MSDC_DUAL_TCARD_BY_SWITCH)
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_SIMPLUS|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return KAL_FALSE;
+ #else
+ ASSERT(0);
+ #endif
+ }
+ prSwitch.u4TargetInterface=sel;
+ DclSD_Control(dclHandle, SD_CTRL_CMD_ANALOG_SWITCH, (DCL_CTRL_DATA_T*)&prSwitch);
+ #else
+ dclHandle = DclSD_Open(DCL_SD, DCL_SD_FLAGS_DEVICE_CARD1|DCL_SD_FLAGS_USAGE_CMD);
+ if (dclHandle == DCL_HANDLE_INVALID)
+ return KAL_FALSE;
+#endif
+//jinxing add done
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+ DclSD_Control(dclHandle, SD_CTRL_CMD_GET_CAPACITY, (DCL_CTRL_DATA_T*)&capacity);
+ DclSD_Close(dclHandle);
+ *max_lba =(capacity.pu8Capacity)/512 -1;
+ #endif
+ *sec_len =512;
+ return KAL_TRUE;
+}
+
+#else
+
+kal_bool usbms_read_capacity_all(kal_uint32 *max_lba, kal_uint32 *sec_len, MSDC_EXT_MEM_TYPE type)
+{
+ kal_int32 status;
+ void *ID = NULL;
+
+ ASSERT(CardDrv != NULL);
+ switch(type)
+ {
+ case MSDC_MEM_TYPE_EXT:
+ ID = EXT_MEM_ID;
+ break;
+#if defined(__SIM_PLUS__)
+ case MSDC_MEM_TYPE_SIMPLUS:
+ ID = SIMPLUS_MEM_ID;
+ break;
+#endif
+
+#if defined(__MSDC_DUAL_CARD_SWITCH__)
+ case MSDC_MEM_TYPE_TCARD2:
+ ID = TCARD_2_MEM_ID;
+ break;
+#endif
+
+ default:
+ return KAL_FALSE;
+ }
+ status = CardDrv->MountDevice((void*)ID, 0, 0, 0);
+ if(status != 512)
+ return KAL_FALSE;
+
+ #if defined(__MSDC_MS__)
+ *max_lba = gMS.TotalSectors-1;
+ #elif defined(__MSDC_MSPRO__)
+ *max_lba = gMSP.user_block*gMSP.block_size-1;
+ #elif defined(__MSDC_SD_MMC__)
+ *max_lba = gSD->mCSD.capacity/512 -1;
+ #endif
+ *sec_len =512;
+ return KAL_TRUE;
+}
+
+#endif//defined(DCL_MSDC_INTERFACE)
+
+#endif /*__MSDC_MS__,__MSDC_SD_MMC__*/
+
+#endif /*__USB_MSD_SUPPORT__*/
+