📄 sdio_bus_misc.c
字号:
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@file: sdio_bus_misc.c@abstract: OS independent bus driver support#notes: this file contains miscellaneous control functions@notice: Copyright (c), 2004-2006 Atheros Communications, Inc.$ATH_LICENSE_SDIOSTACK0$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/#define MODULE_NAME SDBUSDRIVER#include <linux/sdio/ctsystem.h>#include <linux/sdio/sdio_busdriver.h>#include <linux/sdio/sdio_lib.h>#include "_busdriver.h"#include <linux/sdio/_sdio_defs.h>#include <linux/sdio/mmc_defs.h>/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ IssueBusRequestBd - issue a bus request Input: pHcd - HCD object Cmd - command to issue Argument - command argument Flags - request flags Output: pReqToUse - request to use (if caller wants response data) Return: SDIO Status Notes: This function only issues 1 block data transfers This function issues the request synchronously++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/SDIO_STATUS _IssueBusRequestBd(PSDHCD pHcd, UINT8 Cmd, UINT32 Argument, SDREQUEST_FLAGS Flags, PSDREQUEST pReqToUse, PVOID pData, INT Length){ SDIO_STATUS status = SDIO_STATUS_SUCCESS; PSDREQUEST pReq; if (NULL == pReqToUse) { /* caller doesn't care about the response data, allocate locally */ pReq = AllocateRequest(); if (NULL == pReq) { return SDIO_STATUS_NO_RESOURCES; } } else { /* use the caller's request buffer */ pReq = pReqToUse; } pReq->Argument = Argument; pReq->Flags = Flags; pReq->Command = Cmd; if (pReq->Flags & SDREQ_FLAGS_DATA_TRANS) { pReq->pDataBuffer = pData; pReq->BlockCount = 1; pReq->BlockLen = Length; } status = IssueRequestToHCD(pHcd,pReq); if (NULL == pReqToUse) { DBG_ASSERT(pReq != NULL); FreeRequest(pReq); } return status;}/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ConvertVoltageCapsToOCRMask - initialize card Input: VoltageCaps - voltage cap to look up Return: 32 bit OCR mask Notes: this function sets voltage for +- 10%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/static UINT32 ConvertVoltageCapsToOCRMask(SLOT_VOLTAGE_MASK VoltageCaps){ UINT32 ocrMask; ocrMask = 0; if (VoltageCaps & SLOT_POWER_3_3V) { ocrMask |= SD_OCR_3_2_TO_3_3_VDD | SD_OCR_3_3_TO_3_4_VDD; } if (VoltageCaps & SLOT_POWER_3_0V) { ocrMask |= SD_OCR_2_9_TO_3_0_VDD | SD_OCR_3_0_TO_3_1_VDD; } if (VoltageCaps & SLOT_POWER_2_8V) { ocrMask |= SD_OCR_2_7_TO_2_8_VDD | SD_OCR_2_8_TO_2_9_VDD; } if (VoltageCaps & SLOT_POWER_2_0V) { ocrMask |= SD_OCR_1_9_TO_2_0_VDD | SD_OCR_2_0_TO_2_1_VDD; } if (VoltageCaps & SLOT_POWER_1_8V) { ocrMask |= SD_OCR_1_7_TO_1_8_VDD | SD_OCR_1_8_TO_1_9_VDD; } if (VoltageCaps & SLOT_POWER_1_6V) { ocrMask |= SD_OCR_1_6_TO_1_7_VDD; } return ocrMask;}static UINT32 GetUsableOCRValue(UINT32 CardOCR, UINT32 SlotOCRMask){ INT i; UINT32 mask = 0; for (i = 0; i < 32; i++) { mask = 1 << i; if ((SlotOCRMask & mask) && (CardOCR & mask)) { return mask; } } return mask;}/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ GetPowerSetting - power up the SDIO card Input: pHcd - HCD object pOCRvalue - OCR value of the card Output: pOCRvalue - OCR to actually use Return: power setting for HCD based on card's OCR, zero indicates unsupported Notes:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/static SLOT_VOLTAGE_MASK GetPowerSetting(PSDHCD pHcd, UINT32 *pOCRvalue){ UINT32 ocrMask; SLOT_VOLTAGE_MASK hcdVoltage = 0; SLOT_VOLTAGE_MASK hcdVMask; INT i; /* check preferred value */ ocrMask = ConvertVoltageCapsToOCRMask(pHcd->SlotVoltagePreferred); if (ocrMask & *pOCRvalue) { /* using preferred voltage */ *pOCRvalue = GetUsableOCRValue(*pOCRvalue, ocrMask); hcdVoltage = pHcd->SlotVoltagePreferred; } else { /* walk through the slot voltage caps and find a match */ for (i = 0; i < 8; i++) { hcdVMask = (1 << i); if (hcdVMask & pHcd->SlotVoltageCaps) { ocrMask = ConvertVoltageCapsToOCRMask((SLOT_VOLTAGE_MASK)(pHcd->SlotVoltageCaps & hcdVMask)); if (ocrMask & *pOCRvalue) { /* found a match */ *pOCRvalue = GetUsableOCRValue(*pOCRvalue, ocrMask); hcdVoltage = pHcd->SlotVoltageCaps & hcdVMask; break; } } } } return hcdVoltage;}/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TestPresence - test the presence of a card/function Input: pHcd - HCD object TestType - type of test to perform Output: pReq - Request to use (optional) Return: Notes:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/SDIO_STATUS TestPresence(PSDHCD pHcd, CARD_INFO_FLAGS TestType, PSDREQUEST pReq){ SDIO_STATUS status = SDIO_STATUS_ERROR; switch (TestType) { case CARD_SDIO: /* issue CMD5 */ status = _IssueSimpleBusRequest(pHcd,CMD5,0, SDREQ_FLAGS_RESP_SDIO_R4 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT,pReq); break;#ifndef CT_CONFIG_NO_SDMMC case CARD_SD: if (IS_HCD_BUS_MODE_SPI(pHcd)) { /* ACMD41 just starts initialization when in SPI mode, argument is ignored * Note: In SPI mode ACMD41 uses an R1 response */ status = _IssueSimpleBusRequest(pHcd,ACMD41,0, SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R1,pReq); } else { /* issue ACMD41 with OCR value of zero */ /* ACMD41 on SD uses an R3 response */ status = _IssueSimpleBusRequest(pHcd,ACMD41,0, SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R3,pReq); } break; case CARD_MMC: /* issue CMD1 */ if (IS_HCD_BUS_MODE_SPI(pHcd)) { /* note: in SPI mode an R1 response is used */ status = _IssueSimpleBusRequest(pHcd,CMD1,0,SDREQ_FLAGS_RESP_R1,pReq); } else { status = _IssueSimpleBusRequest(pHcd,CMD1,0,SDREQ_FLAGS_RESP_R3,pReq); } break;#endif default: DBG_ASSERT(FALSE); break; } return status;}/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ReadOCR - read the OCR Input: pHcd - HCD object ReadType - type of read to perform OCRValue - OCR value to use as an argument Output: pReq - Request to use pOCRValueRd - OCR value read back (can be NULL) Return: Notes:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/static SDIO_STATUS ReadOCR(PSDHCD pHcd, CARD_INFO_FLAGS ReadType, PSDREQUEST pReq, UINT32 OCRValue, UINT32 *pOCRValueRd){ SDIO_STATUS status = SDIO_STATUS_ERROR; switch (ReadType) { case CARD_SDIO: /* CMD5 for SDIO cards */ if (IS_HCD_BUS_MODE_SPI(pHcd)) { /* skip the SPI filter, we will decode the response here */ status = _IssueSimpleBusRequest(pHcd,CMD5, OCRValue, SDREQ_FLAGS_RESP_SDIO_R4 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT, pReq); } else { /* native SD */ status = _IssueSimpleBusRequest(pHcd,CMD5, OCRValue, SDREQ_FLAGS_RESP_SDIO_R4, pReq); } break;#ifndef CT_CONFIG_NO_SDMMC case CARD_SD: if (IS_HCD_BUS_MODE_SPI(pHcd)) { /* CMD58 is used to read the OCR */ status = _IssueSimpleBusRequest(pHcd,CMD58, 0, /* argument ignored */ (SDREQ_FLAGS_RESP_R3 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT), pReq); } else { /* SD Native uses ACMD41 */ status = _IssueSimpleBusRequest(pHcd,ACMD41, OCRValue, SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R3, pReq); } break; case CARD_MMC: if (IS_HCD_BUS_MODE_SPI(pHcd)) { /* CMD58 is used to read the OCR */ status = _IssueSimpleBusRequest(pHcd,CMD58, 0, /* argument ignored */ (SDREQ_FLAGS_RESP_R3 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT), pReq); } else { /* MMC Native uses CMD1 */ status = _IssueSimpleBusRequest(pHcd,CMD1, OCRValue, SDREQ_FLAGS_RESP_R3, pReq); } break;#endif default: DBG_ASSERT(FALSE); break; } if (SDIO_SUCCESS(status) && (pOCRValueRd != NULL)) { *pOCRValueRd = 0; /* someone wants the OCR read back */ switch (ReadType) { case CARD_SDIO: if (IS_HCD_BUS_MODE_SPI(pHcd)) { *pOCRValueRd = SPI_SDIO_R4_GET_OCR(pReq->Response); } else { *pOCRValueRd = SD_SDIO_R4_GET_OCR(pReq->Response); } break;#ifndef CT_CONFIG_NO_SDMMC case CARD_SD: case CARD_MMC: if (IS_HCD_BUS_MODE_SPI(pHcd)) { *pOCRValueRd = SPI_R3_GET_OCR(pReq->Response); } else { *pOCRValueRd = SD_R3_GET_OCR(pReq->Response); } break;#endif default: DBG_ASSERT(FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -