⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmc_asic3.c

📁 三星公司ARM芯片S3C2410 SD/MMC LINUX 驱动程序源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
		buf[13] = data & 0xff;		data = H3900_ASIC3_SD_CTRL_Response0;		buf[14] = data >> 8;		buf[15] = data & 0xff;		buf[16] = 1; // ecc flag	} else { // R1, R1B, R3 handle		if (request->rtype == RESPONSE_R3)			buf[0] = 0x3f;		else			buf[0] = request->cmd;		data = H3900_ASIC3_SD_CTRL_Response1;		buf[1] = data >> 8;		buf[2] = data & 0xff;		data = H3900_ASIC3_SD_CTRL_Response0;		buf[3] = data >> 8;		buf[4] = data & 0xff;	}	START_MMC_DEBUG(3) {		printk(__FILE__ ":%s - Response byte stream: ", __FUNCTION__);		for (i = 0; i < len; i++)			printk("%02x ", buf[i]);		printk("\n");	} END_MMC_DEBUG;}static void mmc_asic3_send_command(struct mmc_request *request){	u16 card_status, buffer_status;	int retval = MMC_NO_ERROR, timeout, res_end = 0, rw_end = 0;	int read_enable = 0, write_enable = 0, transfer = 0, cdc = 0;	MMC_DEBUG(2, "request=%p cmd=%d (%s) arg=%08x", request, 	      request->cmd, get_cmd_name(request->cmd), request->arg);	g_data.request = request;	request->result = MMC_NO_RESPONSE;   // Flag to indicate don't have a result yet	if (request->cmd == MMC_CIM_RESET) {		retval = mmc_asic3_reset_asic();		goto end_command;	}	if (request->cmd == MMC_STOP_TRANSMISSION) {		H3900_ASIC3_SD_CTRL_StopInternal = SD_CTRL_STOP_INTERNAL_ISSSUE_CMD12;                request->response[0] = request->cmd;                request->response[1] = 0;                request->response[2] = 0;                request->response[3] = 0;                request->response[4] = 0;		retval = MMC_NO_ERROR;		goto end_command;	}	// reset card status	card_status = H3900_ASIC3_SD_CTRL_CardStatus; // detect if state of card is changed first	card_status &= (SD_CTRL_CARDSTATUS_CARD_REMOVED_0 |			SD_CTRL_CARDSTATUS_CARD_INSERTED_0 |			SD_CTRL_CARDSTATUS_SIGNAL_STATE_PRESENT_0 |			SD_CTRL_CARDSTATUS_WRITE_PROTECT);	H3900_ASIC3_SD_CTRL_CardStatus = card_status;	// reset buffer status	H3900_ASIC3_SD_CTRL_BufferCtrl = 0;	H3900_ASIC3_SD_CTRL_ErrorStatus0 = 0;	H3900_ASIC3_SD_CTRL_ErrorStatus1 = 0;	timeout = 0;	do {	// check and wait if SD/MMC controller is ready for receive commands		buffer_status = H3900_ASIC3_SD_CTRL_BufferCtrl;		if ((buffer_status & (SD_CTRL_BUFFERSTATUS_ILLEGAL_ACCESS |				SD_CTRL_BUFFERSTATUS_CMD_INDEX_ERROR |				SD_CTRL_BUFFERSTATUS_CRC_ERROR |				SD_CTRL_BUFFERSTATUS_DATA_TIMEOUT |				SD_CTRL_BUFFERSTATUS_STOP_BIT_END_ERROR |				SD_CTRL_BUFFERSTATUS_BUFFER_OVERFLOW |				SD_CTRL_BUFFERSTATUS_BUFFER_UNDERFLOW |				SD_CTRL_BUFFERSTATUS_CMD_TIMEOUT)) != 0) {			MMC_DEBUG(0, "Buffer status ERROR 0x%04x - inside check buffer\n", buffer_status);			MMC_DEBUG(0, "detail0 error status 0x%04x\n", H3900_ASIC3_SD_CTRL_ErrorStatus0);			MMC_DEBUG(0, "detail1 error status 0x%04x\n", H3900_ASIC3_SD_CTRL_ErrorStatus1);			retval = MMC_ERROR_GENERAL;			goto end_command;		}		if (timeout > 3000000) {			MMC_DEBUG(0, "TIMEOUT - inside check buffer\n");			retval = MMC_ERROR_TIMEOUT;			goto end_command;		}			timeout++;		udelay(1);	} while ((buffer_status & SD_CTRL_BUFFERSTATUS_CMD_BUSY) != 0);	MMC_DEBUG(3, "Buffer status 0x%04x - after check buffer\n", buffer_status);	switch (request->cmd) {	case MMC_READ_MULTIPLE_BLOCK:		H3900_ASIC3_SD_CTRL_StopInternal = SD_CTRL_STOP_INTERNAL_AUTO_ISSUE_CMD12;		cdc = SD_CTRL_COMMAND_TRANSFER_READ | SD_CTRL_COMMAND_DATA_PRESENT | SD_CTRL_COMMAND_MULTI_BLOCK;		cdc |= rinfo[request->rtype].cdc_flags;		mmc_asic3_set_transfer(request->block_len, request->nob);		mmc_asic3_set_command(request->cmd | cdc, request->arg);		transfer = 1;		break;	case MMC_WRITE_MULTIPLE_BLOCK:		H3900_ASIC3_SD_CTRL_StopInternal = SD_CTRL_STOP_INTERNAL_AUTO_ISSUE_CMD12;		cdc = SD_CTRL_COMMAND_TRANSFER_WRITE | SD_CTRL_COMMAND_DATA_PRESENT | SD_CTRL_COMMAND_MULTI_BLOCK;		cdc |= rinfo[request->rtype].cdc_flags;		mmc_asic3_set_transfer(request->block_len, request->nob);		mmc_asic3_set_command(request->cmd | cdc, request->arg);		transfer = 1;		break;	case MMC_READ_SINGLE_BLOCK:		cdc = SD_CTRL_COMMAND_TRANSFER_READ | SD_CTRL_COMMAND_DATA_PRESENT;		cdc |= rinfo[request->rtype].cdc_flags;		mmc_asic3_set_transfer(request->block_len, request->nob);		mmc_asic3_set_command(request->cmd | cdc, request->arg);		transfer = 1;		break;	case MMC_WRITE_BLOCK:		cdc = SD_CTRL_COMMAND_TRANSFER_WRITE | SD_CTRL_COMMAND_DATA_PRESENT;		cdc |= rinfo[request->rtype].cdc_flags;		mmc_asic3_set_transfer(request->block_len, request->nob);		mmc_asic3_set_command(request->cmd | cdc, request->arg);		transfer = 1;		break;	default:		if (request->cmd == MMC_GO_IDLE_STATE)		    cdc |= SD_CTRL_COMMAND_TYPE_IDLE;		if (request->cmd == MMC_APP_CMD)		    cdc |= SD_CTRL_COMMAND_TYPE_ACMD;		cdc |= rinfo[request->rtype].cdc_flags;		mmc_asic3_set_command(request->cmd | cdc, request->arg);		rw_end = 1;		break;	}	timeout = 0;	do {		buffer_status = H3900_ASIC3_SD_CTRL_BufferCtrl;		if ((buffer_status & SD_CTRL_BUFFERSTATUS_CMD_TIMEOUT) != 0) {			MMC_DEBUG(0, "got status buffer COMMAND TIMEOUT - inside loop after send cmd\n");			MMC_DEBUG(0, "detail0 error status 0x%04x\n", H3900_ASIC3_SD_CTRL_ErrorStatus0);			MMC_DEBUG(0, "detail1 error status 0x%04x\n", H3900_ASIC3_SD_CTRL_ErrorStatus1);			retval = MMC_ERROR_TIMEOUT;			goto end_command;		}		if ((buffer_status & SD_CTRL_BUFFERSTATUS_DATA_TIMEOUT) != 0) {			MMC_DEBUG(0, "got status buffer DATA TIMEOUT - inside loop after send cmd\n");			MMC_DEBUG(0, "detail0 error status 0x%04x\n", H3900_ASIC3_SD_CTRL_ErrorStatus0);			MMC_DEBUG(0, "detail1 error status 0x%04x\n", H3900_ASIC3_SD_CTRL_ErrorStatus1);			retval = MMC_ERROR_TIMEOUT;			goto end_command;		}		if ((buffer_status & (SD_CTRL_BUFFERSTATUS_ILLEGAL_ACCESS |				SD_CTRL_BUFFERSTATUS_CMD_INDEX_ERROR |				SD_CTRL_BUFFERSTATUS_CRC_ERROR |				SD_CTRL_BUFFERSTATUS_STOP_BIT_END_ERROR |				SD_CTRL_BUFFERSTATUS_BUFFER_OVERFLOW |				SD_CTRL_BUFFERSTATUS_BUFFER_UNDERFLOW)) != 0) {			retval = MMC_ERROR_GENERAL;			MMC_DEBUG(0, "Buffer status ERROR 0x%04x - inside loop after send cmd\n", buffer_status);			MMC_DEBUG(0, "detail0 error status 0x%04x\n", H3900_ASIC3_SD_CTRL_ErrorStatus0);			MMC_DEBUG(0, "detail1 error status 0x%04x\n", H3900_ASIC3_SD_CTRL_ErrorStatus1);			goto end_command;		}		if ((buffer_status & SD_CTRL_BUFFERSTATUS_BUFFER_READ_ENABLE) != 0) {			MMC_DEBUG(3, "got status buffer READ ENABLE\n");			read_enable = 1;			H3900_ASIC3_SD_CTRL_BufferCtrl &= ~SD_CTRL_BUFFERSTATUS_BUFFER_READ_ENABLE;		}		if ((buffer_status & SD_CTRL_BUFFERSTATUS_BUFFER_WRITE_ENABLE) != 0) {			MMC_DEBUG(3, "got status buffer WRITE ENABLE\n");			write_enable = 1;			H3900_ASIC3_SD_CTRL_BufferCtrl &= ~SD_CTRL_BUFFERSTATUS_BUFFER_WRITE_ENABLE;		}		if ((read_enable == 1) && (transfer == 1) && (request->nob > 0)) {			MMC_DEBUG(3, "starting receive data\n");			mmc_asic3_receive_data(request);			timeout = 0;		}		if ((write_enable == 1) && (transfer == 1) && (request->nob > 0)) {			MMC_DEBUG(3, "starting transit data\n");			mmc_asic3_transmit_data(request);			timeout = 0;		}		if ((H3900_ASIC3_SD_CTRL_CardStatus & SD_CTRL_CARDSTATUS_RW_END) != 0) {			MMC_DEBUG(3, "got END of RW buffer operation - inside loop after send cmd\n");			rw_end = 1;			H3900_ASIC3_SD_CTRL_CardStatus &= ~SD_CTRL_CARDSTATUS_RW_END;			H3900_ASIC3_SD_CTRL_StopInternal = 0;		}		if ((H3900_ASIC3_SD_CTRL_CardStatus & SD_CTRL_CARDSTATUS_RESPONSE_END) != 0) {			MMC_DEBUG(2, "got RESPONSE - inside loop after send cmd\n");			res_end = 1;			H3900_ASIC3_SD_CTRL_CardStatus &= ~SD_CTRL_CARDSTATUS_RESPONSE_END;			mmc_asic3_get_response(request);		}		if (timeout > 3000000) {			MMC_DEBUG(0, "TIMEOUT - inside loop after send cmd\n");			retval = MMC_ERROR_TIMEOUT;			goto end_command;		}		timeout++;		udelay(1);	} while ((res_end == 0) || (rw_end == 0));	MMC_DEBUG(3, "Card status 0x%04x - after cmd, before response parse\n", H3900_ASIC3_SD_CTRL_CardStatus);	MMC_DEBUG(3, "Buffer status 0x%04x - after cmd, before response parse\n", H3900_ASIC3_SD_CTRL_BufferCtrl);	if ((request->cmd == SD_APP_OP_COND) && (retval == MMC_NO_ERROR)) {		g_data.flag = 1;	}	if ((request->cmd == SD_APP_SET_BUS_WIDTH) && (retval == MMC_NO_ERROR)) {		H3900_ASIC3_SD_CTRL_MemCardOptionSetup = MEM_CARD_OPTION_REQUIRED |						MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(14) |						MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT |						MEM_CARD_OPTION_DATA_XFR_WIDTH_4;	}end_command:        request->result = retval;        mmc_cmd_complete(request);}static void mmc_asic3_enable_hardware(void){}static void mmc_asic3_disable_hardware(void){}static int mmc_asic3_slot_is_empty(int slot){	return 0;}static void mmc_asic3_slot_up(void){}static void mmc_asic3_slot_down(void){}static int mmc_asic3_slot_init(void){	MMC_DEBUG(2, "");//	mmc_asic3_slot_up();	return 0;}static void mmc_asic3_slot_cleanup(void){	MMC_DEBUG(2, "");//	mmc_asic3_slot_down();}int mmc_asic3_suspend(void){//	mmc_asic3_slot_down();	return 0;}void mmc_asic3_resume(void){//	mmc_asic3_slot_up();}static struct mmc_slot_driver dops = {	owner:     THIS_MODULE,	name:      "ASIC3 MMC/SD",	ocr:       0x00ffc000,	flags:     MMC_SDFLAG_MMC_MODE | MMC_SDFLAG_SD_MODE | MMC_SDFLAG_4BIT_BUS,	init:      mmc_asic3_slot_init,	cleanup:   mmc_asic3_slot_cleanup,	is_empty:  mmc_asic3_slot_is_empty,	send_cmd:  mmc_asic3_send_command,	set_clock: mmc_asic3_set_clock,};int __init mmc_asic3_init(void){	int retval = 0;	MMC_DEBUG(2, "");	if (!machine_is_h3900 ()) {	/* seems to put h3900 into some bad state */		if (machine_is_h1900 ()) {			H3900_ASIC3_SDHWCTRL_SDConf = ASIC3_SDHWCTRL_CLKSEL | ASIC3_SDHWCTRL_SUSPEND;			mdelay(10);		} else /* No one else uses asic3, so return an error code so we can unload the module */			return -ENODEV;	}	g_data.flag = 0;	retval = mmc_register_slot_driver(&dops, 1);	if (retval < 0)		PALERT("unable to register slot");	return retval;}void __exit mmc_asic3_cleanup(void){	MMC_DEBUG(2, "");	H3900_ASIC3_SD_CONFIG_SDHC_Power1 = SD_CONFIG_POWER1_PC_OFF;	mdelay(1);	H3900_ASIC3_SDHWCTRL_SDConf &= ~ASIC3_SDHWCTRL_SDPWR;	mdelay(1);        H3900_ASIC3_CLOCK_CDEX &= ~CLOCK_CDEX_EX1;	mdelay(1);        H3900_ASIC3_SDHWCTRL_SDConf |= ASIC3_SDHWCTRL_SUSPEND;	mdelay(10);	mmc_unregister_slot_driver(&dops);}module_init(mmc_asic3_init);module_exit(mmc_asic3_cleanup);MODULE_AUTHOR("Pawel Kolodziejski");MODULE_DESCRIPTION("ASIC3 MMC/SD controller driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -