first and last commit

This commit is contained in:
Chris Nutter committed 2023-07-08 13:03:17 -07:00
commit 1bf4efd552
2612 files changed
+636500

No files matched your search

@@ -0,0 +1,76 @@
/*
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#include "sdhc_debug.h"
#ifdef PLATFORM_VARIANT_IOP
#include <lib/libc.h>
#else
#include <libkern/libkern.h>
#endif
void
sdhc_dumpRegisterFile(const SDHCRegisters_t *sdhc)
{
printf("SDHC @ %p, size = %lu\n", sdhc, sizeof(*sdhc));
printf(" SD Command Generation:\n");
printf(" sdmaSystemAddr = 0x%08X\n", (uint32_t)sdhc->sdmaSystemAddr);
printf(" blockSize = 0x%04X\n", sdhc->blockSize);
printf(" blockCount = 0x%04X\n", sdhc->blockCount);
printf(" argument = 0x%08X\n", (uint32_t)sdhc->argument);
printf(" transferMode = 0x%04X\n", sdhc->transferMode);
printf(" command = 0x%04X\n", sdhc->command);
printf(" Response:\n");
for(unsigned i=0; i<4; i++) {
printf(" response[%u] = 0x%08X\n", i, (uint32_t)sdhc->response[i]);
}
printf(" Buffer Data Port:\n");
printf(" bufferDataPort = 0x%08X\n", (uint32_t)sdhc->bufferDataPort);
printf(" Host Controls:\n");
printf(" presentState = 0x%08X\n", (uint32_t)sdhc->presentState);
printf(" hostControl = 0x%02X\n", sdhc->hostControl);
printf(" powerControl = 0x%02X\n", sdhc->powerControl);
printf(" blockGapControl = 0x%02X\n", sdhc->blockGapControl);
printf(" wakeupControl = 0x%02X\n", sdhc->wakeupControl);
printf(" clockControl = 0x%04X\n", sdhc->clockControl);
printf(" timeoutControl = 0x%02X\n", sdhc->timeoutControl);
printf(" softwareReset = 0x%02X\n", sdhc->softwareReset);
printf(" Interrupt Controls:\n");
printf(" normalInterruptStatus = 0x%04X\n", sdhc->normalInterruptStatus);
printf(" errorInterruptStatus = 0x%04X\n", sdhc->errorInterruptStatus);
printf(" normalInterruptStatusEnable = 0x%04X\n", sdhc->normalInterruptStatusEnable);
printf(" errorInterruptStatusEnable = 0x%04X\n", sdhc->errorInterruptStatusEnable);
printf(" normalInterruptSignalEnable = 0x%04X\n", sdhc->normalInterruptSignalEnable);
printf(" errorInterruptSignalEnable = 0x%04X\n", sdhc->errorInterruptSignalEnable);
printf(" autoCmd12ErrorStatus = 0x%04X\n", sdhc->autoCmd12ErrorStatus);
printf(" Capabilities:\n");
printf(" capabilities = 0x%016llX\n", sdhc->capabilities);
printf(" maxCurrentCapabilities = 0x%016llX\n", sdhc->maxCurrentCapabilities);
printf(" Force Event:\n");
printf(" forceEventAutoCmd12ErrorStatus = 0x%04X\n", sdhc->forceEventAutoCmd12ErrorStatus);
printf(" forceEventErrorInterruptStatus = 0x%04X\n", sdhc->forceEventErrorInterruptStatus);
printf(" ADMA:\n");
printf(" admaErrorStatus = 0x%02X\n", sdhc->admaErrorStatus);
printf(" admaSystemAddr = 0x%016llX\n", sdhc->admaSystemAddr);
printf(" Common:\n");
printf(" slotInterruptStatus = 0x%04X\n", sdhc->slotInterruptStatus);
printf(" hostControllerVersion = 0x%04X\n", sdhc->hostControllerVersion);
}
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#ifndef _SDHC_DEBUG_H
#define _SDHC_DEBUG_H
#ifdef PLATFORM_VARIANT_IOP
#include <sdiocommon/sdhc_registers.h>
#else
#include <IOKit/sdio/sdhc_registers.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
void sdhc_dumpRegisterFile(const SDHCRegisters_t *sdhc);
#ifdef __cplusplus
}
#endif
#endif /* _SDHC_DEBUG_H */
@@ -0,0 +1,647 @@
/*
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#include "sdhc_registers.h"
// TODO: Endianness
#pragma mark -
#pragma mark Macros
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
#pragma mark -
#pragma mark Capabilities
enum SDHCCapabilitiesFieldOffset
{
kSDHCCapabilityBaseClockRateOffset = 8,
kSDHCCapabilityMaxBlockLengthOffset = 16,
kSDHCCapabilityHighSpeedSupportOffset = 21,
kSDHCCapabilitySuspendResumeSupportOffset = 23
};
enum SDHCCapabilitiesField
{
kSDHCCapabilityBaseClockRate = (0x3F << kSDHCCapabilityBaseClockRateOffset),
kSDHCCapabilityMaxBlockLength = (0x3 << kSDHCCapabilityMaxBlockLengthOffset),
kSDHCCapabilityHighSpeedSupport = (1 << kSDHCCapabilityHighSpeedSupportOffset),
kSDHCCapabilitySuspendResumeSupport = (1 << kSDHCCapabilitySuspendResumeSupportOffset),
};
UInt16
sdhc_getMaxBlockLength(const SDHCRegisters_t *sdhc)
{
static UInt16 mapBlkLenCapToLen[] = {512, 1024, 2048, 0};
UInt8 cap = (sdhc->capabilities & kSDHCCapabilityMaxBlockLength) >> kSDHCCapabilityMaxBlockLengthOffset;
return mapBlkLenCapToLen[cap];
}
UInt32
sdhc_getBaseClockFrequencyHz(const SDHCRegisters_t *sdhc)
{
UInt32 rateMHz = (sdhc->capabilities & kSDHCCapabilityBaseClockRate) >> kSDHCCapabilityBaseClockRateOffset;
return rateMHz * 1000000;
}
bool
sdhc_isSuspendResumeSupported(const SDHCRegisters_t *sdhc)
{
return sdhc->capabilities & kSDHCCapabilitySuspendResumeSupport;
}
bool
sdhc_isHighSpeedSupported(const SDHCRegisters_t *sdhc)
{
return sdhc->capabilities & kSDHCCapabilityHighSpeedSupport;
}
#pragma mark -
#pragma mark Present State
enum PresentStateFieldOffsets
{
kCmdInhibitOffset = 0,
kDataInhibitOffset = 1,
};
enum PresentStateField
{
kCmdInhibit = (1 << kCmdInhibitOffset),
kDataInhibit = (1 << kDataInhibitOffset),
};
bool
sdhc_isCommandInhibitedOnCmd(const SDHCRegisters_t *sdhc)
{
return sdhc->presentState & kCmdInhibit;
}
bool
sdhc_isCommandInhibitedOnData(const SDHCRegisters_t *sdhc)
{
return sdhc->presentState & kDataInhibit;
}
#pragma mark -
#pragma mark Clocks
#define kMaxClockDivisor (256)
enum ClkControlFieldOffsets
{
kInternalClkEnableOffset = 0,
kInternalClkStableOffset = 1,
kSDClkEnableOffset = 2,
kSDClkFrequencySelectOffset = 8
};
enum ClkControlFields
{
kInternalClkEnable = (1 << kInternalClkEnableOffset),
kInternalClkStable = (1 << kInternalClkStableOffset),
kSDClkEnable = (1 << kSDClkEnableOffset),
kSDClkFrequencySelect = (0xFF << kSDClkFrequencySelectOffset)
};
UInt32
sdhc_setClockDividerRate(SDHCRegisters_t *sdhc, UInt32 targetSDClkRateHz, UInt32 inputClkRateHz)
{
UInt16 divisor = 1;
while(inputClkRateHz / divisor > targetSDClkRateHz) {
divisor *= 2;
}
divisor = min(divisor, kMaxClockDivisor);
sdhc_setClockDivider(sdhc, divisor);
return inputClkRateHz / divisor;
}
void
sdhc_setClockDivider(SDHCRegisters_t *sdhc, UInt16 divisor)
{
divisor >>= 1; // divisor is offset, 0x00 == clk / 1
divisor <<= kSDClkFrequencySelectOffset; // shift to correct offset
sdhc->clockControl &= ~kSDClkFrequencySelect;
// Note: must enable internal clock here or SDIO block will lock up
sdhc->clockControl |= (divisor | kInternalClkEnable);
}
UInt16
sdhc_getClockDivider(const SDHCRegisters_t *sdhc)
{
UInt16 clkControl = sdhc->clockControl & kSDClkFrequencySelect;
clkControl >>= kSDClkFrequencySelectOffset; // shift to correct offset
// divisor is offset, 0x00 == clk / 1
clkControl <<= 1;
if(0 == clkControl) {
clkControl = 1;
}
return clkControl;
}
void
sdhc_enableInternalClock(SDHCRegisters_t *sdhc, bool enable)
{
UInt16 clkControl = sdhc->clockControl;
if(enable) {
clkControl |= kInternalClkEnable;
} else {
clkControl &= ~kInternalClkEnable;
}
sdhc->clockControl = clkControl;
}
bool
sdhc_isInternalClockStable(const SDHCRegisters_t *sdhc)
{
return sdhc->clockControl & kInternalClkStable;
}
void
sdhc_enableSDClock(SDHCRegisters_t *sdhc, bool enable)
{
UInt16 clkControl = sdhc->clockControl;
if(enable) {
clkControl |= kSDClkEnable;
} else {
clkControl &= ~kSDClkEnable;
}
sdhc->clockControl = clkControl;
}
bool
sdhc_isSDClockEnabled(const SDHCRegisters_t *sdhc)
{
return sdhc->clockControl & kSDClkEnable;
}
#pragma mark -
#pragma mark Block Size
enum SDHCBlockSizeOffset
{
kSDHCTransferSizeOffset = 0,
kSDHCHostSDMABufferSizeOffset = 12,
kSDHCTransferSizeHighOffset = 15,
};
enum SDHCBlockSizeMask
{
kSDHCTransferSize = (0xFFF << kSDHCTransferSizeOffset),
kSDHCHostSDMABufferSize = (0x7 << kSDHCTransferSizeOffset),
kSDHCTransferSizeHigh = (1 << kSDHCTransferSizeHighOffset),
};
void
sdhc_setBlockSize(SDHCRegisters_t *sdhc, UInt16 size)
{
UInt16 blockSize = sdhc->blockSize & ~(kSDHCTransferSizeHigh | kSDHCTransferSize);
blockSize |= size & kSDHCTransferSize;
// High bit
blockSize |= (size & (1 << kSDHCHostSDMABufferSizeOffset))
<< (kSDHCTransferSizeHighOffset - kSDHCHostSDMABufferSizeOffset);
sdhc->blockSize = blockSize;
}
#pragma mark -
#pragma mark Commands
void
sdhc_copyCommandResponse(const SDHCRegisters_t *sdhc, struct SDIOCommandResponse *response)
{
for(UInt16 i=0; i < 4; ++i) {
response->response[i] = sdhc->response[i];
}
}
#pragma mark -
#pragma mark Command State
enum NormalIntFieldOffsets
{
kCmdCompleteIntOffset = 0,
kTransferCompleteIntOffset = 1,
kBlockGapIntOffset = 2,
kDMAIntOffset = 3,
kBufferWriteReadyIntOffset = 4,
kBufferReadReadyIntOffset = 5,
kCardInsertionIntOffset = 6,
kCardRemovalIntOffset = 7,
kCardIntOffset = 8,
kErrorIntOffset = 15
};
enum NormalIntFields
{
kCmdCompleteInt = (1 << kCmdCompleteIntOffset),
kTransferCompleteInt = (1 << kTransferCompleteIntOffset),
kBlockGapInt = (1 << kBlockGapIntOffset),
kDMAInt = (1 << kDMAIntOffset),
kBufferWriteReadyInt = (1 << kBufferWriteReadyIntOffset),
kBufferReadReadyInt = (1 << kBufferReadReadyIntOffset),
kCardInsertionInt = (1 << kCardInsertionIntOffset),
kCardRemovalInt = (1 << kCardRemovalIntOffset),
kCardInt = (1 << kCardIntOffset),
kErrorInt = (1 << kErrorIntOffset),
};
enum ErrorIntFieldOffsets
{
kCmdTimeoutErrorIntOffset = 0,
kCmdCRCErrorIntOffset = 1,
kCmdEndBitErrorIntOffset = 2,
kCmdIndexErrorIntOffset = 3,
kDataTimeoutErrorIntOffset = 4,
kDataCRCErrorIntOffset = 5,
kDataEndBitErrorIntOffset = 6,
kCurrentLimitErrorIntOffset = 7,
kAutoCmd12ErrorIntOffset = 8,
kADMAErrorIntOffset = 9
};
enum ErrorIntFields
{
kCmdTimeoutErrorInt = (1 << kCmdTimeoutErrorIntOffset),
kCmdCRCErrorInt = (1 << kCmdCRCErrorIntOffset),
kCmdEndBitErrorInt = (1 << kCmdEndBitErrorIntOffset),
kCmdIndexErrorInt = (1 << kCmdIndexErrorIntOffset),
kDataTimeoutErrorInt = (1 << kDataTimeoutErrorIntOffset),
kDataCRCErrorInt = (1 << kDataCRCErrorIntOffset),
kDataEndBitErrorInt = (1 << kDataEndBitErrorIntOffset),
kCurrentLimitErrorInt = (1 << kCurrentLimitErrorIntOffset),
kAutoCmd12ErrorInt = (1 << kAutoCmd12ErrorIntOffset),
kADMAErrorInt = (1 << kADMAErrorIntOffset)
};
void
sdhc_enableCommandStatus(SDHCRegisters_t *sdhc, bool enable)
{
if(enable) {
sdhc->normalInterruptStatusEnable |= kCmdCompleteInt;
sdhc->errorInterruptStatusEnable |= (kCmdIndexErrorInt | kCmdEndBitErrorInt | kCmdCRCErrorInt | kCmdTimeoutErrorInt);
} else {
sdhc->normalInterruptStatusEnable &= ~kCmdCompleteInt;
sdhc->errorInterruptStatusEnable &= ~(kCmdIndexErrorInt | kCmdEndBitErrorInt | kCmdCRCErrorInt | kCmdTimeoutErrorInt);
}
}
bool
sdhc_isCommandComplete(const SDHCRegisters_t *sdhc)
{
return (sdhc->normalInterruptStatus & kCmdCompleteInt)
|| (sdhc->errorInterruptStatus
& (kCmdIndexErrorInt | kCmdEndBitErrorInt | kCmdCRCErrorInt | kCmdTimeoutErrorInt));
}
SDIOReturn_t
sdhc_getCommandStatus(const SDHCRegisters_t *sdhc)
{
const UInt16 state = kCmdTimeoutErrorInt | kCmdCRCErrorInt;
const UInt16 errorStatus = sdhc->errorInterruptStatus;
if((errorStatus & state) == state) {
return kSDIOReturnCmdLineConflict;
} else if(errorStatus & kCmdTimeoutErrorInt) {
return kSDIOReturnCmdTimeout;
} else if(errorStatus & kCmdCRCErrorInt) {
return kSDIOReturnCmdCRCError;
} else if(errorStatus & kCmdEndBitErrorInt) {
return kSDIOReturnCmdEndBitError;
} else if(errorStatus & kCmdIndexErrorInt) {
return kSDIOReturnCmdIndexError;
} else {
return kSDIOReturnSuccess;
}
}
void
sdhc_clearCommandStatus(SDHCRegisters_t *sdhc)
{
sdhc->normalInterruptStatus = kCmdCompleteInt;
sdhc->errorInterruptStatus = (kCmdIndexErrorInt | kCmdEndBitErrorInt | kCmdCRCErrorInt | kCmdTimeoutErrorInt);
}
#pragma mark -
#pragma mark Transfer State
void
sdhc_enableTransferStatus(SDHCRegisters_t *sdhc, bool enable)
{
if(enable) {
sdhc->normalInterruptStatusEnable |= kTransferCompleteInt;
sdhc->errorInterruptStatusEnable |= (kDataTimeoutErrorInt | kDataCRCErrorInt | kDataEndBitErrorInt);
} else {
sdhc->normalInterruptStatusEnable &= ~kTransferCompleteInt;
sdhc->errorInterruptStatusEnable &= ~(kDataTimeoutErrorInt | kDataCRCErrorInt | kDataEndBitErrorInt);
}
}
bool
sdhc_isTransferComplete(const SDHCRegisters_t *sdhc)
{
return (sdhc->normalInterruptStatus & kTransferCompleteInt)
|| (sdhc->errorInterruptStatus
& (kDataTimeoutErrorInt | kDataCRCErrorInt | kDataEndBitErrorInt));
}
SDIOReturn_t
sdhc_getTransferStatus(const SDHCRegisters_t *sdhc)
{
const UInt16 errorStatus = sdhc->errorInterruptStatus;
if((errorStatus & kDataTimeoutErrorInt)
&& !(sdhc->normalInterruptStatus & kTransferCompleteInt)) {
return kSDIOReturnDataTimeout;
} else if(errorStatus & kDataCRCErrorInt) {
return kSDIOReturnDataCRCError;
} else if(errorStatus & kDataEndBitErrorInt) {
return kSDIOReturnDataEndBitError;
} else {
return kSDIOReturnSuccess;
}
}
void
sdhc_clearTransferStatus(SDHCRegisters_t *sdhc)
{
sdhc->normalInterruptStatus = kTransferCompleteInt;
sdhc->errorInterruptStatus = (kDataTimeoutErrorInt | kDataCRCErrorInt | kDataEndBitErrorInt);
}
#pragma mark -
#pragma mark PIO
bool
sdhc_isBufferReadReady(const SDHCRegisters_t *sdhc)
{
return sdhc->normalInterruptStatus & kBufferReadReadyInt;
}
void
sdhc_enableBufferReadReady(SDHCRegisters_t *sdhc, bool enable)
{
if(enable) {
sdhc->normalInterruptStatusEnable |= kBufferReadReadyInt;
} else {
sdhc->normalInterruptStatusEnable &= ~kBufferReadReadyInt;
}
}
void
sdhc_clearBufferReadReady(SDHCRegisters_t *sdhc)
{
sdhc->normalInterruptStatus = kBufferReadReadyInt;
}
bool
sdhc_isBufferWriteReady(const SDHCRegisters_t *sdhc)
{
return sdhc->normalInterruptStatus & kBufferWriteReadyInt;
}
void
sdhc_enableBufferWriteReady(SDHCRegisters_t *sdhc, bool enable)
{
if(enable) {
sdhc->normalInterruptStatusEnable |= kBufferWriteReadyInt;
} else {
sdhc->normalInterruptStatusEnable &= ~kBufferWriteReadyInt;
}
}
void
sdhc_clearBufferWriteReady(SDHCRegisters_t *sdhc)
{
sdhc->normalInterruptStatus = kBufferWriteReadyInt;
}
#pragma mark -
#pragma mark Data Timeout
enum SDHCTimeoutControlOffset
{
kSDHCDataTimeoutCounterOffset = 0,
};
enum SDHCTimeoutControl
{
kSDHCDataTimeoutCounter = (0xF << kSDHCDataTimeoutCounterOffset),
};
void
sdhc_setDataTimeoutCounter(SDHCRegisters_t *sdhc)
{
UInt16 divisor = sdhc->clockControl & kSDClkFrequencySelect;
// BCOM algorithm
UInt8 timeout = 7;
while(timeout && (divisor & 1) == 0) {
timeout--;
divisor >>= 1;
}
bool on = sdhc->errorInterruptStatusEnable & kDataTimeoutErrorInt;
sdhc->errorInterruptStatusEnable &= ~kDataTimeoutErrorInt;
sdhc->timeoutControl |= (divisor & kSDHCDataTimeoutCounter);
if(on) {
sdhc->errorInterruptStatusEnable |= kDataTimeoutErrorInt;
}
}
#pragma mark -
#pragma mark Reset
void
sdhc_reset(SDHCRegisters_t *sdhc, SDHCResetFlags_t flags)
{
sdhc->softwareReset |= (flags & (kSDHCResetDataLine | kSDHCResetCmdLine | kSDHCResetAll));
}
SDHCResetFlags_t
sdhc_isResetting(const SDHCRegisters_t *sdhc)
{
return sdhc->softwareReset & (kSDHCResetDataLine | kSDHCResetCmdLine | kSDHCResetAll);
}
#pragma mark -
#pragma mark Interrupts
bool
sdhc_isSignalingInterrupt(const SDHCRegisters_t *sdhc)
{
return (sdhc->normalInterruptStatus & sdhc->normalInterruptSignalEnable)
|| (sdhc->errorInterruptStatus & sdhc->errorInterruptSignalEnable);
}
void
sdhc_clearInterruptSignals(SDHCRegisters_t *sdhc)
{
UInt16 clear;
sdhc->forceEventAutoCmd12ErrorStatus = 0;
sdhc->forceEventErrorInterruptStatus = 0;
clear = sdhc->errorInterruptSignalEnable & sdhc->errorInterruptStatus;
if(clear & kAutoCmd12ErrorInt) {
UInt16 cmd12Clear = sdhc->autoCmd12ErrorStatus;
sdhc->autoCmd12ErrorStatus = cmd12Clear;
}
sdhc->errorInterruptStatus = clear;
clear = sdhc->normalInterruptSignalEnable & sdhc->normalInterruptStatus;
sdhc->normalInterruptStatus = clear;
}
#pragma mark -
#pragma mark Card Interrupt
bool
sdhc_isCardInterrupt(const SDHCRegisters_t *sdhc)
{
return sdhc->normalInterruptStatus & kCardInt;
}
void
sdhc_enableCardInterrupt(SDHCRegisters_t *sdhc, bool enable)
{
if(enable) {
sdhc->normalInterruptStatusEnable |= kCardInt;
sdhc->normalInterruptSignalEnable |= kCardInt;
} else {
sdhc->normalInterruptStatusEnable &= ~kCardInt;
sdhc->normalInterruptSignalEnable &= ~kCardInt;
}
}
bool
sdhc_isCardInterruptEnabled(const SDHCRegisters_t *sdhc)
{
return sdhc->normalInterruptStatusEnable & kCardInt
&& sdhc->normalInterruptSignalEnable & kCardInt;
}
#pragma mark -
#pragma mark Host Control
enum HostControlFieldOffsets
{
kDataTransferWidthOffset = 1,
kHighSpeedEnableOffset = 2,
};
enum HostControlFields
{
kDataTransferWidth = (1 << kDataTransferWidthOffset), // 1 == 4 bit, 0 == 1 bit
kHighSpeedEnable = (1 << kHighSpeedEnableOffset),
};
void
sdhc_setHighSpeedMode(SDHCRegisters_t *sdhc, bool enabled)
{
if(enabled) {
sdhc->hostControl |= kHighSpeedEnable;
} else {
sdhc->hostControl &= ~kHighSpeedEnable;
}
}
void
sdhc_setDataTransferWidth(SDHCRegisters_t *sdhc, UInt8 width)
{
bool cardIntOn = sdhc_isCardInterruptEnabled(sdhc);
sdhc_enableCardInterrupt(sdhc, false);
if(width == 4) {
sdhc->hostControl |= kDataTransferWidth;
} else {
sdhc->hostControl &= ~kDataTransferWidth;
}
sdhc_enableCardInterrupt(sdhc, cardIntOn);
}
@@ -0,0 +1,276 @@
/*
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#ifndef _SDIO_SDHC_H
#define _SDIO_SDHC_H
#ifdef PLATFORM_VARIANT_IOP
#include <sdiocommon/sdio_types.h>
#include <sys/types.h>
#else
#include <IOKit/sdio/sdio_types.h>
#include <IOKit/IOTypes.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#pragma mark -
#pragma mark SDHC Register File
/** Safe typedef for use of SDHCRegisters register file. */
typedef volatile struct SDHCRegisters SDHCRegisters_t;
/** Standard SDIO Host Controller 2.0 Register File. */
struct SDHCRegisters
{
// SD Command Generation: 0x00 - 0x0F
volatile UInt32 sdmaSystemAddr;
volatile UInt16 blockSize;
volatile UInt16 blockCount;
volatile UInt32 argument;
volatile UInt16 transferMode;
volatile UInt16 command;
// Response: 0x10 - 0x1F
volatile UInt32 response[4];
// Buffer Data Port: 0x20 - 0x23
volatile UInt32 bufferDataPort;
// Host Controls: 0x24 - 0x2F
volatile UInt32 presentState;
volatile UInt8 hostControl;
volatile UInt8 powerControl;
volatile UInt8 blockGapControl;
volatile UInt8 wakeupControl;
volatile UInt16 clockControl;
volatile UInt8 timeoutControl;
volatile UInt8 softwareReset;
// Interrupt Controls: 0x30 - 0x3D
volatile UInt16 normalInterruptStatus;
volatile UInt16 errorInterruptStatus;
volatile UInt16 normalInterruptStatusEnable;
volatile UInt16 errorInterruptStatusEnable;
volatile UInt16 normalInterruptSignalEnable;
volatile UInt16 errorInterruptSignalEnable;
volatile UInt16 autoCmd12ErrorStatus;
volatile UInt8 __reservedIntArea[2] SDIO_RESERVED; // Do not use, will change
// Capabilities: 0x40 - 0x4F
volatile UInt64 capabilities;
volatile UInt64 maxCurrentCapabilities;
// Force Event: 0x50 - 0x53
volatile UInt16 forceEventAutoCmd12ErrorStatus;
volatile UInt16 forceEventErrorInterruptStatus;
// ADMA: 0x54 - 0x5F
volatile UInt8 admaErrorStatus;
volatile UInt8 __reservedCapArea[3] SDIO_RESERVED; // Do not use, will change
volatile UInt64 admaSystemAddr;
// Reserved: 0x60 - 0xEF
volatile UInt8 __reserved[0x90] SDIO_RESERVED; // Do not use, will change
// Common Area: 0xF0 - 0xFF
volatile UInt8 __reservedCommonArea[0xC] SDIO_RESERVED; // Do not use, will change
volatile UInt16 slotInterruptStatus;
volatile UInt16 hostControllerVersion;
};
#pragma mark -
#pragma mark SDHC Register Bits
enum SDIOTransferModeField
{
kSDIOTransferEnableDMA = (1 << 0),
kSDIOTransferEnableBlockCount = (1 << 1),
kSDIOTransferEnableAutoCmd12 = (1 << 2),
kSDIOTransferReadFromCard = (1 << 4),
kSDIOTransferMultipleBlocks = (1 << 5),
};
#pragma mark -
#pragma mark Capabilities
UInt16 sdhc_getMaxBlockLength(const SDHCRegisters_t *sdhc);
UInt32 sdhc_getBaseClockFrequencyHz(const SDHCRegisters_t *sdhc);
bool sdhc_isSuspendResumeSupported(const SDHCRegisters_t *sdhc);
bool sdhc_isHighSpeedSupported(const SDHCRegisters_t *sdhc);
#pragma mark -
#pragma mark Present State
bool sdhc_isCommandInhibitedOnCmd(const SDHCRegisters_t *sdhc);
bool sdhc_isCommandInhibitedOnData(const SDHCRegisters_t *sdhc);
#pragma mark -
#pragma mark Clocks
/** @brief Sets the SD Clock rate.
* @param[in] hcReg
* Target SDIO Host Controller.
* @param[in] targetSDClkRateHz
* Desired SD Clock rate, in Hz
* @param[in] inputClkRateHz
* SD Block's input clock rate, in Hz
* @return
* The actual clock rate set, in Hz.
*/
UInt32 sdhc_setClockDividerRate(SDHCRegisters_t *sdhc, UInt32 targetSDClkRateHz, UInt32 inputClkRateHz);
void sdhc_setClockDivider(SDHCRegisters_t *sdhc, UInt16 divider);
UInt16 sdhc_getClockDivider(const SDHCRegisters_t *sdhc);
void sdhc_enableInternalClock(SDHCRegisters_t *sdhc, bool enable);
bool sdhc_isInternalClockStable(const SDHCRegisters_t *sdhc);
void sdhc_enableSDClock(SDHCRegisters_t *sdhc, bool enable);
bool sdhc_isSDClockEnabled(const SDHCRegisters_t *sdhc);
#pragma mark -
#pragma mark Block Size
void sdhc_setBlockSize(SDHCRegisters_t *sdhc, UInt16 size);
#pragma mark -
#pragma mark Commands
void sdhc_copyCommandResponse(const SDHCRegisters_t *sdhc, struct SDIOCommandResponse *response);
#pragma mark -
#pragma mark Command State
/** @brief Enable/Disable status bits needed for command completion and error checking. */
void sdhc_enableCommandStatus(SDHCRegisters_t *sdhc, bool enable);
/** @brief True if the command has completed for any reason. */
bool sdhc_isCommandComplete(const SDHCRegisters_t *sdhc);
/** @brief Gets the command status after completion. */
SDIOReturn_t sdhc_getCommandStatus(const SDHCRegisters_t *sdhc);
/** @brief Clear status bits needed for command completion and error checking. */
void sdhc_clearCommandStatus(SDHCRegisters_t *sdhc);
#pragma mark -
#pragma mark Transfer State
/** @brief Enable/Disable status bits needed for transfer completion and error checking. */
void sdhc_enableTransferStatus(SDHCRegisters_t *sdhc, bool enable);
/** @brief True if the transfer has completed for any reason. */
bool sdhc_isTransferComplete(const SDHCRegisters_t *sdhc);
/** @brief Gets the current transfer status after completion. */
SDIOReturn_t sdhc_getTransferStatus(const SDHCRegisters_t *sdhc);
/** @brief Clear status bits needed for transfer completion and error checking. */
void sdhc_clearTransferStatus(SDHCRegisters_t *sdhc);
#pragma mark -
#pragma mark PIO
bool sdhc_isBufferReadReady(const SDHCRegisters_t *sdhc);
void sdhc_enableBufferReadReady(SDHCRegisters_t *sdhc, bool enable);
void sdhc_clearBufferReadReady(SDHCRegisters_t *sdhc);
bool sdhc_isBufferWriteReady(const SDHCRegisters_t *sdhc);
void sdhc_enableBufferWriteReady(SDHCRegisters_t *sdhc, bool enable);
void sdhc_clearBufferWriteReady(SDHCRegisters_t *sdhc);
#pragma mark -
#pragma mark Data Timeout
void sdhc_setDataTimeoutCounter(SDHCRegisters_t *sdhc);
#pragma mark -
#pragma mark Reset
enum SDHCResetFlags
{
kSDHCResetAll = (1 << 0),
kSDHCResetCmdLine = (1 << 1),
kSDHCResetDataLine = (1 << 2),
};
typedef UInt8 SDHCResetFlags_t;
void sdhc_reset(SDHCRegisters_t *sdhc, SDHCResetFlags_t flags);
SDHCResetFlags_t sdhc_isResetting(const SDHCRegisters_t *sdhc);
#pragma mark -
#pragma mark Interrupts
bool sdhc_isSignalingInterrupt(const SDHCRegisters_t *sdhc);
/** @brief Clear all interrupt signals.
* Only the status fields that are signaling an interrupt are cleared.
*/
void sdhc_clearInterruptSignals(SDHCRegisters_t *sdhc);
#pragma mark -
#pragma mark Card Interrupt
bool sdhc_isCardInterrupt(const SDHCRegisters_t *sdhc);
void sdhc_enableCardInterrupt(SDHCRegisters_t *sdhc, bool enable);
bool sdhc_isCardInterruptEnabled(const SDHCRegisters_t *sdhc);
#pragma mark -
#pragma mark Host Control
void sdhc_setHighSpeedMode(SDHCRegisters_t *sdhc, bool enabled);
void sdhc_setDataTransferWidth(SDHCRegisters_t *sdhc, UInt8 width);
#ifdef __cplusplus
}
#endif
#endif /* _SDIO_SDHC_H */
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2009-2010 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#ifndef _SDIO_CCCR_H_
#define _SDIO_CCCR_H_
#ifdef __cplusplus
extern "C" {
#endif
enum SDIOCccrRegisterAddress
{
kSDIOCccrRevisionAddr = 0x00,
kSDIOCccrSpecRevAddr = 0x01,
kSDIOCccrIOEnableAddr = 0x02,
kSDIOCccrIOReadyAddr = 0x03,
kSDIOCccrIntEnableAddr = 0x04,
kSDIOCccrIntPendingAddr = 0x05,
kSDIOCccrIOAbortAddr = 0x06,
kSDIOCccrBusInterfaceControlAddr= 0x07,
kSDIOCccrCardCapabilityAddr = 0x08,
kSDIOCccrCommonCISPtrLowAddr = 0x09,
kSDIOCccrCommonCISPtrMidAddr = 0x0A,
kSDIOCccrCommonCISPtrHighAddr = 0x0B,
kSDIOCccrBusSuspendAddr = 0x0C,
kSDIOCccrFunctionSelectAddr = 0x0D,
kSDIOCccrExecFlagsAddr = 0x0E,
kSDIOCccrReadyFlagsAddr = 0x0F,
kSDIOCccrFn0BlockSizeLSBAddr = 0x10,
kSDIOCccrFn0BlockSizeMSBAddr = 0x11,
kSDIOCccrPowerControlAddr = 0x12,
kSDIOCccrHighSpeedAddr = 0x13,
};
// Bus Interface Control
enum SDIOCccrBusInterfaceControlMask
{
kSDIOCccrBusWidthMask = (1 << 1) | (1 << 0),
};
enum SDIOCccrBusInterfaceControl
{
kSDIOCccrBusIfWidth1Bit = ((0 << 1)|(0 << 0)),
kSDIOCccrBusIfWidth4Bit = ((1 << 1)|(0 << 0)),
kSDIOCccrBusIfContinuousSPIIntEnabled = (1 << 5),
kSDIOCccrBusIfContinuousSPIInt = (1 << 6),
kSDIOCccrBusIfCardDetectDisable = (1 << 7),
};
// Card Capabilities
enum SDIOCccrCardCapability
{
kSDIOCccrCapDirectCommands = (1 << 0),
kSDIOCccrCapMultiBlock = (1 << 1),
kSDIOCccrCapReadWait = (1 << 2),
kSDIOCccrCapSuspendResume = (1 << 3),
kSDIOCccrCap4BitIntraBlockInt = (1 << 4),
kSDIOCccrCap4BitIntraBlockIntEnable = (1 << 5),
kSDIOCccrCapLowSpeed = (1 << 6),
kSDIOCccrCap4BitLowSpeed = (1 << 7),
};
// High Speed
enum SDIOCccrHighSpeed
{
kSDIOCccrHighSpeedSupported = (1 << 0),
kSDIOCccrHighSpeedEnabled = (1 << 1),
};
#ifdef __cplusplus
}
#endif
#endif /* _SDIO_CCCR_H_ */
+184
View File
@@ -0,0 +1,184 @@
/*
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#ifndef _SDIO_CIS_H
#define _SDIO_CIS_H
#ifdef PLATFORM_VARIANT_IOP
#include <sdiocommon/sdio_types.h>
#include <sys/types.h>
#else
#include <IOKit/sdio/sdio_types.h>
#include <IOKit/IOTypes.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
enum SDIOCISTupleCode {
kSDIOCISTupleNull = 0x00,
kSDIOCISTupleChecksum = 0x10,
kSDIOCISTupleVers1 = 0x15,
kSDIOCISTupleManfID = 0x20,
kSDIOCISTupleFuncID = 0x21,
kSDIOCISTupleFuncE = 0x22,
kSDIOCISTupleSDIOStd = 0x91,
kSDIOCISTupleSDIOExt = 0x92,
kSDIOCISTupleEnd = 0xFF,
kSDIOCISTupleVendor80 = 0x80,
kSDIOCISTupleVendor81 = 0x81,
kSDIOCISTupleVendor82 = 0x82,
kSDIOCISTupleVendor83 = 0x83,
kSDIOCISTupleVendor84 = 0x84,
kSDIOCISTupleVendor85 = 0x85,
kSDIOCISTupleVendor86 = 0x86,
kSDIOCISTupleVendor87 = 0x87,
kSDIOCISTupleVendor88 = 0x88,
kSDIOCISTupleVendor89 = 0x89,
kSDIOCISTupleVendor8A = 0x8A,
kSDIOCISTupleVendor8B = 0x8B,
kSDIOCISTupleVendor8C = 0x8C,
kSDIOCISTupleVendor8D = 0x8D,
kSDIOCISTupleVendor8E = 0x8E,
kSDIOCISTupleVendor8F = 0x8F,
};
enum SDIOCISTupleHeaderSize
{
kSDIOCISTupleSpecialHeaderSize = 1 * sizeof(UInt8),
kSDIOCISTupleStandardHeaderSize = 2 * sizeof(UInt8),
};
struct SDIOCISTupleChecksum
{
UInt16 address;
UInt16 length;
UInt8 checksum;
} SDIO_PACKED;
struct SDIOCISTupleVers1
{
UInt8 major;
UInt8 minor;
UInt8 strings[0];
} SDIO_PACKED;
enum
{
kSDIOCISTupleVers1NumStrings = 4,
/** Minimum size of the Vers1 body.
* This is: major + minor + NULL for each string + end of chain
*/
kSDIOCISTupleVers1MinBodySize = 2 + kSDIOCISTupleVers1NumStrings + 1,
};
struct SDIOCISTupleManfID
{
UInt16 manufacturerID;
UInt16 cardID;
} SDIO_PACKED;
struct SDIOCISTupleFuncID
{
UInt8 functionCode;
UInt8 sysVInitMask;
} SDIO_PACKED;
struct SDIOCISTupleFunc0E
{
UInt8 type;
UInt16 fn0BlockSize;
UInt8 maxTransferSpeed;
} SDIO_PACKED;
struct SDIOCISTupleFuncE
{
UInt8 type;
UInt8 functionInfo;
UInt8 stdIORev;
UInt32 cardPSN;
UInt32 csaSize;
UInt8 csaProperty;
UInt16 maxBlockSize;
UInt32 ocr;
UInt8 operatingMinPower;
UInt8 operatingpAvgPower;
UInt8 operatingMaxPower;
UInt8 standbyMinPower;
UInt8 standbyAvgPower;
UInt8 standbyMaxPower;
UInt16 minBandwidth;
UInt16 optimalBandwidth;
UInt16 enableTimeoutValue;
UInt16 spAvgPower33;
UInt16 spMaxPower33;
UInt16 highCurrentAvgPower33;
UInt16 highCurrentMaxPower33;
UInt16 lowCurrentAvgPower33;
UInt16 lowCurrentMaxPower33;
} SDIO_PACKED;
struct SDIOCISTupleStd
{
UInt8 stdID;
UInt8 stdType;
UInt8 stdData[0];
} SDIO_PACKED;
struct SDIOCISTupleExt
{
UInt8 extData[0];
} SDIO_PACKED;
struct SDIOCisTupleHeader
{
UInt8 code;
UInt8 link;
} SDIO_PACKED;
union SDIOCisTupleBody
{
struct SDIOCISTupleChecksum checksumTpl;
struct SDIOCISTupleVers1 vers1Tpl;
struct SDIOCISTupleManfID manfIDTpl;
struct SDIOCISTupleFuncID funcIDTpl;
struct SDIOCISTupleFunc0E func0ETpl;
struct SDIOCISTupleFuncE funcETpl;
struct SDIOCISTupleStd stdTpl;
struct SDIOCISTupleExt extTpl;
UInt8 byte[0];
} SDIO_PACKED;
struct SDIOCISTuple
{
struct SDIOCisTupleHeader header;
union SDIOCisTupleBody body;
} SDIO_PACKED;
#ifdef __cplusplus
}
#endif
#endif /* _SDIO_CIS_H */
@@ -0,0 +1,145 @@
/*
* Copyright (c) 2009-2010 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#include "sdio_cmdfields.h"
#pragma mark -
#pragma mark Common
enum CommandOffset
{
kSDIOCmdAddressOffset = 9,
kSDIOCmdFunctionOffset = 28,
};
enum CommandMask
{
kSDIOCmdFunctionMask = 0x7,
kSDIOCmdAddressMask = 0x1FFFF,
};
enum SDIOCmdDirection
{
kSDIOCmdDirectionRead = (0 << 31),
kSDIOCmdDirectionWrite = (1 << 31),
};
static inline UInt32
convertFunctionToArg(UInt8 function)
{
return (function & kSDIOCmdFunctionMask) << kSDIOCmdFunctionOffset;
}
static inline UInt32
convertAddressToArg(UInt32 address)
{
return (address & kSDIOCmdAddressMask) << kSDIOCmdAddressOffset;
}
enum SDIODirection
sdio_getCommandDirection(enum SDIOCommandIndex index, UInt32 argument)
{
switch (index) {
case kSDIOCmd52_IORWDirect:
case kSDIOCmd53_IORWExtended:
return (argument & kSDIOCmdDirectionWrite) ? kSDIODirectionWrite : kSDIODirectionRead;
default:
return kSDIODirectionNone;
}
}
#pragma mark -
#pragma mark Cmd5
UInt32
sdio_getOCR(const struct SDIOCommandResponse *cmd5Response)
{
return cmd5Response->response[0] & 0x00fffff;
}
bool
sdio_getNumIOFunctions(const struct SDIOCommandResponse *cmd5Response)
{
return (cmd5Response->response[0] & 0x70000000) >> 28;
}
bool
sdio_isMemoryPresent(const struct SDIOCommandResponse *cmd5Response)
{
return cmd5Response->response[0] & 0x08000000; // >> 27
}
bool
sdio_isIOReady(const struct SDIOCommandResponse *cmd5Response)
{
return cmd5Response->response[0] & 0x80000000; // >> 31
}
#pragma mark -
#pragma mark Cmd52
UInt32
sdio_generateCmd52Arg(enum SDIODirection direction,
UInt8 sdioFunction, UInt32 cardAddress, UInt8 data,
SDIOCmd52Flags flags)
{
UInt32 dir = (direction & kSDIODirectionWrite) ? kSDIOCmdDirectionWrite : kSDIOCmdDirectionRead;
return dir | convertFunctionToArg(sdioFunction) | flags
| convertAddressToArg(cardAddress) | data;
}
#pragma mark -
#pragma mark Cmd53
enum SDIOCmd53Mask
{
kSDIOCmd53CountMask = 0x1FF
};
static inline UInt32
convertCmd53CountToArg(UInt32 count)
{
return (count & kSDIOCmd53CountMask);
}
UInt32
sdio_generateCmd53Arg(enum SDIODirection direction,
UInt8 sdioFunction, UInt32 cardAddress, UInt16 count,
SDIOCmd53Flags flags)
{
UInt32 dir = (direction & kSDIODirectionWrite) ? kSDIOCmdDirectionWrite : kSDIOCmdDirectionRead;
return dir | convertFunctionToArg(sdioFunction) | flags
| convertAddressToArg(cardAddress) | convertCmd53CountToArg(count);
}
UInt16
sdio_getCmd53Count(UInt32 cmdArg)
{
return cmdArg & kSDIOCmd53CountMask;
}
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2009-2010 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#ifndef _SDIO_CMDFIELDS_H_
#define _SDIO_CMDFIELDS_H_
#ifdef PLATFORM_VARIANT_IOP
#include <sdiocommon/sdio_types.h>
#include <sys/types.h>
#else
#include <IOKit/sdio/sdio_types.h>
#include <IOKit/IOTypes.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#pragma mark -
#pragma mark Common
enum SDIODirection sdio_getCommandDirection(enum SDIOCommandIndex index, UInt32 argument);
#pragma mark -
#pragma mark Cmd 5
enum SDIOCmd5OperationConditions {
kSDIOOpCond_None = (0x000000),
kSDIOOpCond_20_21 = (1 << 8),
kSDIOOpCond_21_22 = (1 << 9),
kSDIOOpCond_22_23 = (1 << 10),
kSDIOOpCond_23_24 = (1 << 11),
kSDIOOpCond_24_25 = (1 << 12),
kSDIOOpCond_25_26 = (1 << 13),
kSDIOOpCond_26_27 = (1 << 14),
kSDIOOpCond_27_28 = (1 << 15),
kSDIOOpCond_28_29 = (1 << 16),
kSDIOOpCond_29_30 = (1 << 17),
kSDIOOpCond_30_31 = (1 << 18),
kSDIOOpCond_31_32 = (1 << 19),
kSDIOOpCond_32_33 = (1 << 20),
kSDIOOpCond_33_34 = (1 << 21),
kSDIOOpCond_34_35 = (1 << 22),
kSDIOOpCond_35_36 = (1 << 23),
kSDIOOpCond_All = (0xFFFF00)
};
UInt32 sdio_getOCR(const struct SDIOCommandResponse *cmd5Response);
bool sdio_getNumIOFunctions(const struct SDIOCommandResponse *cmd5Response);
bool sdio_isMemoryPresent(const struct SDIOCommandResponse *cmd5Response);
bool sdio_isIOReady(const struct SDIOCommandResponse *cmd5Response);
#pragma mark -
#pragma mark Cmd 52
enum SDIOCmd52Flag
{
kSDIOCmd52RAW = (1 << 27),
};
typedef UInt32 SDIOCmd52Flags;
UInt32 sdio_generateCmd52Arg(enum SDIODirection direction,
UInt8 sdioFunction, UInt32 cardAddress, UInt8 data,
SDIOCmd52Flags flags);
#pragma mark -
#pragma mark Cmd 53
enum SDIOCmd53Flag
{
kSDIOCmd53ByteMode = (0 << 27),
kSDIOCmd53BlockMode = (1 << 27),
kSDIOCmd53FixedAddress = (0 << 26),
kSDIOCmd53IncrementAddress = (1 << 26),
};
typedef UInt32 SDIOCmd53Flags;
UInt32 sdio_generateCmd53Arg(enum SDIODirection direction,
UInt8 sdioFunction, UInt32 cardAddress, UInt16 count,
SDIOCmd53Flags flags);
UInt16 sdio_getCmd53Count(UInt32 cmdArg);
#ifdef __cplusplus
}
#endif
#endif /* _SDIO_CMDFIELDS_H_ */
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#include "sdio_cmdprop.h"
#include "sdio_types.h"
enum CommandRegFieldOffsets
{
kResponseTypeOffset = 0,
kCmdCRCCheckEnabledOffset = 3,
kCmdIndexCheckEnabledOffset = 4,
kDataPresentSelectOffset = 5,
kCommandTypeOffset = 6,
kCommandIndexOffset = 8,
};
enum CommandRegFieldMasks
{
kResponseTypeSelectMask = (0x3 << kResponseTypeOffset),
kCmdCRCCheckEnabled = (1 << kCmdCRCCheckEnabledOffset),
kCmdIndexCheckEnabled = (1 << kCmdIndexCheckEnabledOffset),
kDataPresentSelect = (1 << kDataPresentSelectOffset),
kCommandTypeMask = (0x3 << kCommandTypeOffset),
kCommandIndexMask = (0x3F << kCommandIndexOffset),
};
enum CommandRegCommandType
{
kSDIOCommandNormal = (0x0 << kCommandTypeOffset),
kSDIOCommandSuspend = (0x1 << kCommandTypeOffset),
kSDIOCommandResume = (0x2 << kCommandTypeOffset),
kSDIOCommandAbort = (0x3 << kCommandTypeOffset),
};
enum CommandRegResponseTypeSelect
{
kNoResponse = (0x0 << kResponseTypeOffset),
kResponseLength136 = (0x1 << kResponseTypeOffset),
kResponseLength48 = (0x2 << kResponseTypeOffset),
kResponseLength48CheckBusy = (0x3 << kResponseTypeOffset),
};
bool
sdio_isDataPresent(UInt16 cmdIndex)
{
// TODO: Support other data commands
return kSDIOCmd53_IORWExtended == cmdIndex;
}
static bool
sdio_shouldCheckIndex(UInt16 cmdIndex)
{
return cmdIndex != kSDIOCmd5_IOSendOpCond;
}
static bool
sdio_shouldCheckCRC(UInt16 cmdIndex)
{
return cmdIndex != kSDIOCmd5_IOSendOpCond;
}
static enum CommandRegResponseTypeSelect
sdio_getResponseType(UInt16 cmdIndex)
{
// TODO: Support other response types
return kResponseLength48;
}
UInt16 sdio_generateCommand(UInt16 cmdIndex)
{
UInt16 cmd = 0;
// Command Index
cmd |= (cmdIndex << kCommandIndexOffset) & kCommandIndexMask;
// Command Type
// TODO: Support abort & suspend / resume commands
cmd |= kSDIOCommandNormal;
// Data present select
if(sdio_isDataPresent(cmdIndex)) {
cmd |= kDataPresentSelect;
}
// Command Index Check
if(sdio_shouldCheckIndex(cmdIndex)) {
cmd |= kCmdIndexCheckEnabled;
}
// Command CRC Check
if(sdio_shouldCheckCRC(cmdIndex)) {
cmd |= kCmdCRCCheckEnabled;
}
// Response type select
cmd |= sdio_getResponseType(cmdIndex);
return cmd;
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#ifndef _SDIO_CMDPROP_H
#define _SDIO_CMDPROP_H
#ifdef PLATFORM_VARIANT_IOP
#include <sys/types.h>
#else
#include <IOKit/IOTypes.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** @brief true if the command has an associated data transfer. */
bool sdio_isDataPresent(UInt16 cmdIndex);
/** @brief Generates the value for the command register. */
UInt16 sdio_generateCommand(UInt16 cmdIndex);
#ifdef __cplusplus
}
#endif
#endif /* _SDIO_CMDPROP_H */
+276
View File
@@ -0,0 +1,276 @@
/*
* Copyright (c) 2009-2010 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#ifndef _SDIO_TYPES_H_
#define _SDIO_TYPES_H_
#ifdef PLATFORM_VARIANT_IOP
#include <sys/types.h>
#else
#include <IOKit/IOTypes.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __GNUC__
#define SDIO_PACKED __attribute__((packed))
#define SDIO_DEPRECATED __attribute__((deprecated))
#define SDIO_RESERVED __attribute__((deprecated))
#else
#error Unknown Compiler
#endif
typedef UInt32 IOSDIOClockRate;
enum
{
kIOSDIOMaxClockRate = 50000000
};
enum IOSDIOClockMode
{
kIOSDIOClockOff = -1,
kIOSDIOClockOn = +1
};
enum IOSDIOBusWidth
{
kIOSDIO1BitMode = 1,
kIOSDIO4BitMode = 4
};
enum IOSDIOBusSpeedMode
{
kIOSDIONormalSpeed = 1,
kIOSDIOHighSpeed = 2
};
enum SDIOCommandIndex
{
kSDIOCmd0_GoIdleState = 0,
kSDIOCmd1_SendOpCond = 1,
kSDIOCmd2_AllSendCID = 2,
kSDIOCmd3_SendRelativeAddr = 3,
kSDIOCmd4_SetDSR = 4,
kSDIOCmd5_IOSendOpCond = 5,
kSDIOCmd6_SwitchFunc = 6,
kSDIOCmd7_SelectDeselectCard = 7,
kSDIOCmd9_SendCSD = 9,
kSDIOCmd10_SendCID = 10,
kSDIOCmd12_StopTransmission = 12,
kSDIOCmd13_SendStatus = 13,
kSDIOCmd15_GoInactiveState = 15,
kSDIOCmd16_SetBlockLength = 16,
kSDIOCmd17_ReadSingleBlock = 17,
kSDIOCmd18_ReadMultipleBlock = 18,
kSDIOCmd24_WriteBlock = 24,
kSDIOCmd25_WriteMultipleBlock = 25,
kSDIOCmd27_ProgramCSD = 27,
kSDIOCmd28_SetWriteProt = 28,
kSDIOCmd29_ClearWriteProt = 29,
kSDIOCmd30_SendWriteProt = 30,
kSDIOCmd32_EraseWrBlkStart = 32,
kSDIOCmd33_EraseWrBlkEnd = 33,
kSDIOCmd38_Erase = 38,
kSDIOCmd42_LockUnlock = 42,
kSDIOCmd52_IORWDirect = 52,
kSDIOCmd53_IORWExtended = 53,
kSDIOCmd55_AppCmd = 55,
kSDIOCmd56_GenCmd = 56,
kSDIOCmd58_ReadOCR = 58,
kSDIOCmd59_CRCOnOff = 59,
kSDIOAcmd6_SetBusWidth = 6,
kSDIOAcmd13_SDStatus = 13,
kSDIOAcmd22_SendNumWrBlocks = 22,
kSDIOAcmd23_SetWrBlkEraseCount = 23,
kSDIOAcmd41_SDAppOpCond = 41,
kSDIOAcmd42_SetClrCardDetect = 42,
kSDIOAcmd51_SendSCR = 51,
};
enum SDIODirection
{
kSDIODirectionNone = 0, // Same as kIODirectionNone
kSDIODirectionRead = (1 << 0), // Same as kIODirectionIn
kSDIODirectionWrite = (1 << 1), // Same as kIODirectionOut
};
struct SDIOCommand
{
UInt16 index; // SDIOCommandIndex
UInt32 argument;
};
struct SDIOCommandResponse
{
UInt32 response[4];
};
struct SDIOMemorySegments
{
UInt64 dataLength;
UInt32 segmentCount;
void *segmentList;
};
struct SDIOTransfer
{
struct SDIOCommand command;
UInt8 direction; // SDIODirection
UInt16 blockSize;
UInt16 blockCount;
};
enum SDIOReturn
{
/** @brief Success. */
kSDIOReturnSuccess = 0,
// Generic IOReturn-derived Errors
/** @brief Invalid Argument. */
kSDIOReturnBadArgument = 0x2c2,
/** @brief Can't allocate memory. */
kSDIOReturnNoMemory = 0x2bd,
// General SDIO Errors
/** @brief General SDIO Error. */
kSDIOReturnSDIOError = 0x300,
// Host Controller Errors
/** @brief General Host Controller Error. */
kSDIOReturnSDHCError = 0x400,
/** @brief Host controller physical address invalid. */
kSDIOReturnNoHostController = 0x401,
/** @brief Couldn't perform command because SD Clock is disabled. */
kSDIOReturnInternalClockUnstable= 0x402,
/** @brief Couldn't perform command because SD Clock is disabled. */
kSDIOReturnSDClockDisabled = 0x403,
/** @brief Failed due to errors in ADMA transfer. */
kSDIOReturnADMAError = 0x404,
/** @brief Failed due to errors in SDMA transfer. */
kSDIOReturnSDMAError = 0x405,
/** @brief Error performing Auto CMD12. */
kSDIOReturnAutoCMD12Error = 0x406,
/** @brief HC not supplying power to card. */
kSDIOReturnCurrentLimitError = 0x407,
/** @brief Vendor-specific error. */
kSDIOReturnVendorError = 0x408,
/** @brief Device in reset. */
kSDIOReturnInReset = 0x409,
/** @brief Block never signaled command complete. */
kSDIOReturnNoCmdComplete = 0x40A,
/** @brief Block never signaled transfer complete. */
kSDIOReturnNoTransferComplete = 0x40B,
/** @brief DMA transfer timed out. */
kSDIOReturnDMATimeout = 0x40C,
// Card Errors
/** @brief General Card Error. */
kSDIOReturnCardError = 0x500,
/** @brief Failed because no card is inserted. */
kSDIOReturnNoCard = 0x501,
/** @brief Failed because the card was ejected. */
kSDIOReturnCardEjected = 0x502,
/** @brief Failed because card is write protected. */
kSDIOReturnWriteProtected = 0x503,
// Problems on SDIO Command Line
/** @brief General SDIO Cmd line error. */
kSDIOReturnCmdError = 0x600,
/** @brief SDIO Cmd line is busy. */
kSDIOReturnCmdLineBusy = 0x601,
/** @brief SDIO Cmd line's signal level is incorrect. */
kSDIOReturnCmdSignalInvalid = 0x602,
/** @brief Command index error in response. */
kSDIOReturnCmdIndexError = 0x603,
/** @brief Conflict on SDIO Command Line. */
kSDIOReturnCmdLineConflict = 0x604,
/** @brief SDIO Cmd failed with a CRC error. */
kSDIOReturnCmdCRCError = 0x605,
/** @brief SDIO Cmd failed with a End Bit error. */
kSDIOReturnCmdEndBitError = 0x606,
/** @brief SDIO Cmd Timed out (no response. */
kSDIOReturnCmdTimeout = 0x607,
// Problems on SDIO Data Line
/** @brief General SDIO Data Line Error. */
kSDIOReturnDataError = 0x700,
/** @brief SDIO Data line is busy. */
kSDIOReturnDataLineBusy = 0x701,
/** @brief SDIO Data line's signal level is incorrect. */
kSDIOReturnDataSignalInvalid = 0x702,
/** @brief SDIO Data failed with a CRC error. */
kSDIOReturnDataCRCError = 0x703,
/** @brief SDIO Data failed with a CRC error. */
kSDIOReturnDataEndBitError = 0x704,
/** @brief SDIO Data Timed out (no response. */
kSDIOReturnDataTimeout = 0x705,
};
typedef enum SDIOReturn SDIOReturn_t;
#ifdef __cplusplus
}
#endif
#endif /* _SDIO_TYPES_H_ */