📄 mmc_drv.c
字号:
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Copyright (C) 2002 Motorola Semiconductors HK Ltd * *//****************************************************************************** * * Copyright (C) 2001, Motorola All Rights Reserved * * File Name: mmcsd.c * * Progammers: Yiwei Zhao * * Date of Creations: 30 DEC,2001 * * Synopsis: * * Modification History: * 30 DEC, 2001 * *****************************************************************************///#include "dbmx1_type.h"#include "mmc_def.h"#include "mmc_main.h"/* Functions List: * *///Karen add for write protect#define _reg_I2C_IADR (*((volatile unsigned long*)(0xf0217000))) #define _reg_I2C_IFDR (*((volatile unsigned long*)(0xf0217004)))#define _reg_I2C_I2CR (*((volatile unsigned long*)(0xf0217008))) #define _reg_I2C_I2SR (*((volatile unsigned long*)(0xf021700c))) #define _reg_I2C_I2DR (*((volatile unsigned long*)(0xf0217010))) #define _reg_PTA_GIUS (*((volatile unsigned long*)(0xf021C020))) #define _reg_PTA_PUEN (*((volatile unsigned long*)(0xf021C040)))unsigned long* pI2CReadData;unsigned short nI2CReadData;//number of dataunsigned short nI2CData; // index of dataunsigned long dI2CReadData[2];unsigned char bTransferDone;unsigned char bTransferCurMode;unsigned char gSDWriteProtect;#define KAREN_DEBUG/* * Implementation of the MMCSD Driver. *//****************************************************************************** * Function Name: _MMCSD_InitCard * * Input: None. * * Value Returned: * * MMCSD_STATUS * * Description: * * this routine will initialize the cards. * * Modification History: * 30 DEC,2001, Initial version. Yiwei Zhao *****************************************************************************/MMCSD_STATUS _MMCSD_InitSDHC(int port){ MMCSD_STATUS ret; #ifdef CONFIG_ARCH_MX2ADS if(port == 0)//sdhc1 {//set i/o driving strength _reg_SYS_DSCR1 &= ~0x07;// _reg_SYS_DSCR1 |= 0x01;//4mA _reg_SYS_DSCR1 |= 0x03;//6mA //check hardware revision ret=_MMCSD_ChectHardwareRevision(port); if(ret) return ret; //softreset ret=_MMCSD_SoftReset(port); if(ret) return ret; _MMCSD_SetClk(MMCSD_LOW_SPEED,port); _MMCSD_ReadTimeOut(0x2DB4,port); } else if(port == 1) { _reg_SYS_DSCR1 &= ~0x00380000;// _reg_SYS_DSCR1 |= 0x00080000;//4mA _reg_SYS_DSCR1 |= 0x00180000;//6mA //check hardware revision ret=_MMCSD_ChectHardwareRevision(port); if(ret) return ret; //softreset ret=_MMCSD_SoftReset(port); if(ret) return ret; _MMCSD_SetClk(MMCSD_LOW_SPEED,port); _MMCSD_ReadTimeOut(0x2DB4,port); } #else ret=_MMCSD_ChectHardwareRevision(0); if(ret) return ret; ret=_MMCSD_SoftReset(0); if(ret) return ret; _MMCSD_SetClk(MMCSD_LOW_SPEED,0); _MMCSD_ReadTimeOut(0x2DB4,0); #endif return 0;}MMCSD_STATUS _MMCSD_InitMMC(int port){ u16 i, count; MMCSD_STATUS ret; u8 Cid_buff[20]; u16 card_type = 0xFFFF; count = 0; ret = 0; //TRACE("Card Identify\n"); /*------------------------------------------------------------------*/ /* CMD0 CALL PROCEDURE (PLACES CARDS IN IDLE STATE) */ /*------------------------------------------------------------------*/ ret =_MMCSD_GoIdleState(port); if(ret != 0 ) { /*--------- WHEN NO ERROR OCCURS (= FINISH INIT)*/ FAILED("Place Cards into Idle State Failed(%ld)",(unsigned long)ret); return ret; } /*------------------------------------------------------------------*/ /* CMD1 */ /*------------------------------------------------------------------*/ i = MMCSD_ADP_REPEATNUM; while(i--) { ret = _MMCSD_SendOpCond(MMCSD_MMC_CARD_VOLTAGE,port);// MMC if (ret == 0) {/*--------- WHEN NO ERROR OCCURS (= FINISH INIT)*/ card_type = MMCSD_TYPE_MMC; INFO("IT'S MMC CARD"); break; } if(ret!=MMCSD_CARD_BUSY) { //FAILED("Command SendOpCond Failed"); return ret; //CMD send ERROR } } /*------------------------------------------------------------------*/ /* Registe CARDS */ /*------------------------------------------------------------------*/ if(card_type == MMCSD_TYPE_MMC) { g_mmcsd_devices[port].card_type = MMCSD_TYPE_MMC; /* TRACE("Set Op Condition.."); ret = _MMCSD_Set_SendOpCond(MMCSD_MMC_CARD_VOLTAGE, MMCSD_CARD_SET_VOLTAGE); if(ret) { FAILED("MMCSD_SendOpCond(SET_VOLTAGE) error with 0x%x",ret); return ret; } */ while(1) { ret = _MMCSD_AllSendCID(Cid_buff,port);//CMD2 if(ret&MMCSD_CMD_TIMEOUT) { FAILED("_MMCSD_AllSendCID failed with 0x%lx",(unsigned long)ret); g_mmcsd_devices[port].card_state = MMCSD_NOTREADY; return ret; } ret = _MMCSD_SetRelativeAddr(g_mmcsd_devices[port].card_rca,port); //CMD3 if(ret&MMCSD_CMD_TIMEOUT) { FAILED("_MMCSD_SetRelativeAddr failed with 0x%lx",ret); g_mmcsd_devices[0].card_state = MMCSD_NOTREADY; return ret; } else { break; } g_mmcsd_devices[port].card_rca++; } g_mmcsd_devices[port].card_state = MMCSD_STANDBY; count++; } else { FAILED("UNKNOWN CARD TYPE"); return MMCSD_ERROR; // ISSUE } /*----------------------------------------------------------------------*/ /* CHECK IF EFFECTIVE CARDS EXIST */ /*----------------------------------------------------------------------*/ if ( count ) { /*------------------------- IF THERE IS AN EFFECTIVE CARD */ g_mmcsd_num = count; /* ACQUIRE THE NUMBER */ //TRACE("Finish Init Card. %d Cards have beed detected\n",count); return MMCSD_OK; } else { /*--------------------- WHEN NO EFFECTIVE CARD IS IDENTIFIED */ INFO("No Card is detected\n"); return( MMCSD_NO_CARD ); } return( ret );}/****************************************************************************** * Function Name: _MMCSD_InitCard * * Input: * device: pointer to MMCSD_Dev structure. * * Value Returned: * * MMCSD_STATUS * * Description: * * Check and aqquire CSD/CID register data * * Modification History: * 30 DEC,2001, Initial version. Yiwei Zhao *****************************************************************************/MMCSD_STATUS _MMCSD_GetInfo(MMCSD_Dev *device){ MMCSD_STATUS ret; u8 Csd_buff[20]; /* BUFFER FOR RECEIVING CSD */ u8 Cid_buff[20]; /* BUFFER FOR RECEIVING CID */ u32 port; TRACE("Get Card Info\n"); ret = 0; port = device->port; _MMCSD_SetBlockLenReg(0x10,port); // Why???? ret = _MMCSD_SendCSD( device->card_rca,Csd_buff,port); //CMD9 if (ret) { FAILED("_MMCSD_SendCSD() error with 0x%lx",(unsigned long)ret); return ret; } else { ret = _MMCSD_CSDCheck(Csd_buff); if ( ret ) { FAILED("_MMCSD_CSDCheck error, ret=0x%lx",ret); return ret; } else { _MMCSD_SetCSD(device,Csd_buff); } } ret = _MMCSD_SendCID( device->card_rca,Cid_buff,port); //CMD10 if ( ret ) { FAILED("_MMCSD_SendCID() error with 0x%lx",(unsigned long)ret); device->card_state = MMCSD_NOTREADY; } else { ret = _MMCSD_CIDCheck(Cid_buff); if ( ret ) { FAILED("_MMCSD_CIDCheck() error with 0x%lx",ret); return ret; } else { _MMCSD_SetCID(device, Cid_buff); } } return( ret );}/****************************************************************************** * Function Name: _MMCSD_SetSectLen * * Input: None. * * Value Returned: * * MMCSD_STATUS * * Description: * * * Modification History: * 30 DEC,2001, Initial version. Yiwei Zhao * Why??? this function must be here, otherwise CRC-WRITE-ERROR while polling write. *****************************************************************************/MMCSD_STATUS _MMCSD_SetSectLen(MMCSD_Dev *device){ u8 type; MMCSD_STATUS ret; /*----------------------------------------------------------------------*/ /* INITIALIZE LOCAL VARIABLES */ /*----------------------------------------------------------------------*/ type = 0; /* CMD TYPE = NO DATA TRANSFER */ ret = 0; /* SEND/RECEIVE ERROR */ /*--------------------------------------------------------------*/ /* CARD SELECT */ /*--------------------------------------------------------------*/ ret = _MMCSD_SelectDeselectCard(device->card_rca,device->port); if ( ret ) { device->card_state = MMCSD_NOTREADY; return ret; }/* ret = _MMCSD_SetBlockLen(MMCSD_MINIMUM_BLK_SIZE,1); // if ( ret ) { device->card_state = MMCSD_NOTREADY; return ret; } device->blksize = MMCSD_MINIMUM_BLK_SIZE;*/ ret = _MMCSD_SelectDeselectCard(0,device->port); if ( ret ) { device->card_state = MMCSD_NOTREADY; return ret; } device->card_state = MMCSD_STANDBY; return( ret );}/****************************************************************************** * Function Name: _MMCSD_GetStatus * * Input: None. * * Value Returned: * * MMCSD_STATUS * * Description: * * * Modification History: * 30 DEC,2001, Initial version. Yiwei Zhao *****************************************************************************/u32 _MMCSD_GetStatus(MMCSD_Dev *device){ u32 state; MMCSD_STATUS ret=_MMCSD_SendStatus(device->card_rca,&state,device->port); ret&=MMCSD_STATUS_NOERROR|0xFFFF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -