#include "K2Platform.h"
#include "PlatformInterface.h"
#include "AudioHardwareCommon.h"
#include "AppleOnboardAudioUserClient.h"
#include <IOKit/i2c/PPCI2CInterface.h>
#include <IOKit/IOInterruptEventSource.h>
#include <IOKit/IOFilterInterruptEventSource.h>
#include <IOKit/IOWorkLoop.h>
#include <IOKit/IORegistryEntry.h>
#include <IOKit/IOCommandGate.h>
#include <IOKit/ppc/IODBDMA.h>
#ifndef _APPLEI2S_H
#define _APPLEI2S_H
#include <IOKit/IOService.h>
#ifdef DLOG
#undef DLOG
#endif
#ifdef APPLEI2S_DEBUG
#define DLOG(fmt, args...) kprintf(fmt, ## args)
#else
#define DLOG(fmt, args...)
#endif
class AppleI2S : public IOService
{
OSDeclareDefaultStructors(AppleI2S)
private:
IOService *keyLargoDrv;
UInt32 i2sBaseAddress;
void publishBelow(IOService *provider);
public:
virtual bool init(OSDictionary *dict);
virtual void free(void);
virtual IOService *probe(IOService *provider, SInt32 *score);
virtual bool start(IOService *provider);
virtual void stop(IOService *provider);
virtual IOReturn callPlatformFunction( const char *functionName,
bool waitForFunction,
void *param1, void *param2,
void *param3, void *param4 );
virtual IOReturn callPlatformFunction( const OSSymbol *functionName,
bool waitForFunction,
void *param1, void *param2,
void *param3, void *param4 );
};
#define kSafeWriteRegUInt32 "keyLargo_safeWriteRegUInt32"
#define kSafeReadRegUInt32 "keyLargo_safeReadRegUInt32"
#define noMask 0xFFFFFFFF
#define kI2SGetIntCtlReg "I2SGetIntCtlReg"
#define kI2SSetIntCtlReg "I2SSetIntCtlReg"
#define kI2SGetSerialFormatReg "I2SGetSerialFormatReg"
#define kI2SSetSerialFormatReg "I2SSetSerialFormatReg"
#define kI2SGetCodecMsgOutReg "I2SGetCodecMsgOutReg"
#define kI2SSetCodecMsgOutReg "I2SSetCodecMsgOutReg"
#define kI2SGetCodecMsgInReg "I2SGetCodecMsgInReg"
#define kI2SSetCodecMsgInReg "I2SSetCodecMsgInReg"
#define kI2SGetFrameCountReg "I2SGetFrameCountReg"
#define kI2SSetFrameCountReg "I2SSetFrameCountReg"
#define kI2SGetFrameMatchReg "I2SGetFrameMatchReg"
#define kI2SSetFrameMatchReg "I2SSetFrameMatchReg"
#define kI2SGetDataWordSizesReg "I2SGetDataWordSizesReg"
#define kI2SSetDataWordSizesReg "I2SSetDataWordSizesReg"
#define kI2SGetPeakLevelSelReg "I2SGetPeakLevelSelReg"
#define kI2SSetPeakLevelSelReg "I2SSetPeakLevelSelReg"
#define kI2SGetPeakLevelIn0Reg "I2SGetPeakLevelIn0Reg"
#define kI2SSetPeakLevelIn0Reg "I2SSetPeakLevelIn0Reg"
#define kI2SGetPeakLevelIn1Reg "I2SGetPeakLevelIn1Reg"
#define kI2SSetPeakLevelIn1Reg "I2SSetPeakLevelIn1Reg"
#define kI2SIntCtlOffset 0x0000
#define kI2SSerialFormatOffset 0x0010
#define kI2SCodecMsgOutOffset 0x0020
#define kI2SCodecMsgInOffset 0x0030
#define kI2SFrameCountOffset 0x0040
#define kI2SFrameMatchOffset 0x0050
#define kI2SDataWordSizesOffset 0x0060
#define kI2SPeakLevelSelOffset 0x0070
#define kI2SPeakLevelIn0Offset 0x0080
#define kI2SPeakLevelIn1Offset 0x0090
#define kI2SBaseOffset 0x10000
#define kIOPFInterruptRegister "IOPFInterruptRegister"
#define kIOPFInterruptUnRegister "IOPFInterruptUnRegister"
#define kIOPFInterruptEnable "IOPFInterruptEnable"
#define kIOPFInterruptDisable "IOPFInterruptDisable"
#endif
#ifndef __K2HW_PLATFORM
#define __K2HW_PLATFORM
#if 0
#define kIODMAInputOffset 0x00000900
#define kIODMAOutputOffset 0x00000800
#else
#define kIODMAInputOffset 0x00000100
#endif
#define kIODMASizeOfChannelBuffer 256
#define kGPIO_DATA_WR_PIN_LEVEL_H 0x07
#define kGPIO_DATA_WR_PIN_LEVEL_L 0x04
#define kAUDIO_MAC_IO_BASE_ADDRESS 0x80000000
#define kAUDIO_MAC_IO_SIZE 256
#define kAUDIO_I2S_BASE_ADDRESS 0x80010000
#define kAUDIO_I2S_SIZE 4096
#define kAUDIO_MAC_IO_FCR1 0x0000003C
#define kAUDIO_MAC_IO_FCR3 0x00000044
#define kAUDIO_I2S_SERIAL_FORMAT 0x00000010
#define kAUDIO_I2S_INTERRUPT_CONTROL 0x00000000
#define kAUDIO_I2S_DATA_WORD_SIZES 0x00000060
#define kAUDIO_I2S_FRAME_COUNTER 0x00000040
#define kAUDIO_GPIO_INPUT_DATA_MUX_SELECT 0x0000005B
#define kAUDIO_GPIO_LINE_IN_SENSE 0x0000005C
#define kAUDIO_GPIO_CODEC_ERROR_IRQ 0x0000005D
#define kAUDIO_GPIO_DIGITAL_CODEC_RESET 0x00000064
#define kAUDIO_GPIO_LINE_OUT_SENSE 0x00000066
#define kAUDIO_GPIO_HEADPHONE_SENSE 0x00000067
#define kAUDIO_GPIO_CODEC_IRQ 0x00000068
#define kAUDIO_GPIO_HEADPHONE_MUTE 0x0000006F
#define kAUDIO_GPIO_AMPLIFIER_MUTE 0x00000070
#define kAUDIO_GPIO_ANALOG_CODEC_RESET 0x00000074
#define kAUDIO_GPIO_LINE_OUT_MUTE 0x00000075
#define kAUDIO_GPIO_CLOCK_MUX_SELECT 0x00000076
class K2HWPlatform : public K2Platform {
OSDeclareDefaultStructors(K2HWPlatform);
public:
virtual bool init (IOService* device, AppleOnboardAudio* provider, UInt32 inDBDMADeviceIndex);
virtual void free();
virtual bool readCodecRegister(UInt8 address, UInt8 subAddress, UInt8 *data, UInt16 len, BusMode mode);
virtual bool writeCodecRegister(UInt8 address, UInt8 subAddress, UInt8 *data, UInt16 len, BusMode mode);
virtual IOReturn setCodecReset ( CODEC_RESET target, GpioAttributes reset );
virtual GpioAttributes getCodecReset ( CODEC_RESET target );
virtual IOReturn requestI2SClockSource(I2SClockFrequency inFrequency);
virtual IOReturn releaseI2SClockSource(I2SClockFrequency inFrequency);
virtual IOReturn setI2SEnable(bool enable);
virtual bool getI2SEnable();
virtual IOReturn setI2SClockEnable(bool enable);
virtual bool getI2SClockEnable();
virtual IOReturn setI2SCellEnable(bool enable);
virtual bool getI2SCellEnable();
virtual IOReturn setI2SSWReset(bool enable);
virtual bool getI2SSWReset();
virtual IOReturn setSerialFormatRegister(UInt32 serialFormat);
virtual UInt32 getSerialFormatRegister();
virtual IOReturn setDataWordSizes(UInt32 dataWordSizes);
virtual UInt32 getDataWordSizes();
virtual IOReturn setFrameCount(UInt32 value);
virtual UInt32 getFrameCount();
virtual IOReturn setI2SIOMIntControl(UInt32 intCntrl);
virtual UInt32 getI2SIOMIntControl();
virtual GpioAttributes getComboInJackTypeConnected();
virtual GpioAttributes getComboOutJackTypeConnected();
virtual GpioAttributes getDigitalInConnected();
virtual GpioAttributes getDigitalOutConnected();
virtual GpioAttributes getLineInConnected();
virtual GpioAttributes getLineOutConnected();
virtual GpioAttributes getHeadphoneConnected();
virtual GpioAttributes getSpeakerConnected();
virtual GpioAttributes getCodecInterrupt();
virtual GpioAttributes getCodecErrorInterrupt();
virtual IOReturn setHeadphoneMuteState(GpioAttributes muteState);
virtual GpioAttributes getHeadphoneMuteState();
virtual IOReturn setInputDataMux(GpioAttributes muxState);
virtual GpioAttributes getInputDataMux();
virtual IOReturn setLineOutMuteState(GpioAttributes muteState);
virtual GpioAttributes getLineOutMuteState();
virtual IOReturn setSpeakerMuteState(GpioAttributes muteState);
virtual GpioAttributes getSpeakerMuteState();
virtual IOReturn setClockMux(GpioAttributes muxState);
virtual GpioAttributes getClockMux();
virtual IOReturn disableInterrupt ( PlatformInterruptSource source );
virtual IOReturn enableInterrupt ( PlatformInterruptSource source );
virtual IOReturn registerInterruptHandler (IOService * theDevice, void * interruptHandler, PlatformInterruptSource source );
virtual IOReturn unregisterInterruptHandler (IOService * theDevice, void * interruptHandler, PlatformInterruptSource source );
inline const OSSymbol* makeFunctionSymbolName(const char * name,UInt32 pHandle);
virtual IODBDMAChannelRegisters * GetInputChannelRegistersVirtualAddress ( IOService * dbdmaProvider );
virtual IODBDMAChannelRegisters * GetOutputChannelRegistersVirtualAddress ( IOService * dbdmaProvider );
virtual IOReturn getPlatformState ( PlatformStateStructPtr outState );
virtual IOReturn setPlatformState ( PlatformStateStructPtr inState );
private:
IOService * mK2Service;
UInt32 mI2SCell;
IORegistryEntry *mI2S;
UInt32 mI2SPHandle;
UInt32 mI2SOffset;
UInt32 mMacIOPHandle;
UInt32 mMacIOOffset;
IODBDMAChannelRegisters * mIOBaseDMAInput;
IODBDMAChannelRegisters * mIOBaseDMAOutput;
static const char * kAppleK2pHandle;
static const char * kAppleI2S0pHandle;
static const char * kAppleGPIOpHandle;
static const char * kAppleI2S_Enable;
static const char * kAppleI2S_Disable;
static const char * kAppleI2S_ClockEnable;
static const char * kAppleI2S_ClockDisable;
static const char * kAppleI2S_Reset;
static const char * kAppleI2S_Run;
static const char * kAppleI2S_CellEnable;
static const char * kAppleI2S_CellDisable;
static const char * kAppleI2S_GetEnable;
static const char * kAppleI2S_GetClockEnable;
static const char * kAppleI2S_GetReset;
static const char * kAppleI2S_GetCellEnable;
static const char * kAppleI2S_SetIntCtrl;
static const char * kAppleI2S_SetSerialFormat;
static const char * kAppleI2S_SetCodecMessageOut;
static const char * kAppleI2S_SetCodecMessageIn;
static const char * kAppleI2S_SetFrameCount;
static const char * kAppleI2S_SetFrameCountToMatch;
static const char * kAppleI2S_SetDataWordSizes;
static const char * kAppleI2S_SetPeakLevelSFSelect;
static const char * kAppleI2S_SetPeakLevelIn0;
static const char * kAppleI2S_SetPeakLevelIn1;
static const char * kAppleI2S_GetIntCtrl;
static const char * kAppleI2S_GetSerialFormat;
static const char * kAppleI2S_GetCodecMessageOut;
static const char * kAppleI2S_GetCodecMessageIn;
static const char * kAppleI2S_GetFrameCount;
static const char * kAppleI2S_GetFrameCountToMatch;
static const char * kAppleI2S_GetDataWordSizes;
static const char * kAppleI2S_GetPeakLevelSFSelect;
static const char * kAppleI2S_GetPeakLevelIn0;
static const char * kAppleI2S_GetPeakLevelIn1;
static const char * kAppleGPIO_DisableSpeakerDetect;
static const char * kAppleGPIO_EnableSpeakerDetect;
static const char * kAppleGPIO_GetSpeakerDetect;
static const char * kAppleGPIO_RegisterSpeakerDetect;
static const char * kAppleGPIO_UnregisterSpeakerDetect;
static const char * kAppleGPIO_DisableDigitalInDetect;
static const char * kAppleGPIO_EnableDigitalInDetect;
static const char * kAppleGPIO_GetDigitalInDetect;
static const char * kAppleGPIO_RegisterDigitalInDetect;
static const char * kAppleGPIO_UnregisterDigitalInDetect;
static const char * kAppleGPIO_GetComboInJackType;
static const char * kAppleGPIO_GetComboOutJackType;
static const char * kAppleGPIO_DisableDigitalOutDetect;
static const char * kAppleGPIO_EnableDigitalOutDetect;
static const char * kAppleGPIO_GetDigitalOutDetect;
static const char * kAppleGPIO_RegisterDigitalOutDetect;
static const char * kAppleGPIO_UnregisterDigitalOutDetect;
static const char * kAppleGPIO_DisableLineInDetect;
static const char * kAppleGPIO_EnableLineInDetect;
static const char * kAppleGPIO_GetLineInDetect;
static const char * kAppleGPIO_RegisterLineInDetect;
static const char * kAppleGPIO_UnregisterLineInDetect;
static const char * kAppleGPIO_DisableLineOutDetect;
static const char * kAppleGPIO_EnableLineOutDetect;
static const char * kAppleGPIO_GetLineOutDetect;
static const char * kAppleGPIO_RegisterLineOutDetect;
static const char * kAppleGPIO_UnregisterLineOutDetect;
static const char * kAppleGPIO_DisableHeadphoneDetect;
static const char * kAppleGPIO_EnableHeadphoneDetect;
static const char * kAppleGPIO_GetHeadphoneDetect;
static const char * kAppleGPIO_RegisterHeadphoneDetect;
static const char * kAppleGPIO_UnregisterHeadphoneDetect;
static const char * kAppleGPIO_SetHeadphoneMute;
static const char * kAppleGPIO_GetHeadphoneMute;
static const char * kAppleGPIO_SetAmpMute;
static const char * kAppleGPIO_GetAmpMute;
static const char * kAppleGPIO_SetAudioHwReset;
static const char * kAppleGPIO_GetAudioHwReset;
static const char * kAppleGPIO_SetAudioDigHwReset;
static const char * kAppleGPIO_GetAudioDigHwReset;
static const char * kAppleGPIO_SetLineOutMute;
static const char * kAppleGPIO_GetLineOutMute;
static const char * kAppleGPIO_DisableCodecIRQ;
static const char * kAppleGPIO_EnableCodecIRQ;
static const char * kAppleGPIO_GetCodecIRQ;
static const char * kAppleGPIO_RegisterCodecIRQ;
static const char * kAppleGPIO_UnregisterCodecIRQ;
static const char * kAppleGPIO_EnableCodecErrorIRQ;
static const char * kAppleGPIO_DisableCodecErrorIRQ;
static const char * kAppleGPIO_GetCodecErrorIRQ;
static const char * kAppleGPIO_RegisterCodecErrorIRQ;
static const char * kAppleGPIO_UnregisterCodecErrorIRQ;
static const char * kAppleGPIO_SetCodecClockMux;
static const char * kAppleGPIO_GetCodecClockMux;
static const char * kAppleGPIO_SetCodecInputDataMux;
static const char * kAppleGPIO_GetCodecInputDataMux;
static const char * kAppleGPIO_GetInternalSpeakerID;
bool mAppleI2S_Enable;
bool mAppleI2S_ClockEnable;
bool mAppleI2S_Reset;
bool mAppleI2S_CellEnable;
GpioAttributes mAppleGPIO_AmpMute;
GpioAttributes mAppleGPIO_AnalogCodecReset;
GpioAttributes mAppleGPIO_CodecClockMux;
GpioAttributes mAppleGPIO_CodecInputDataMux;
GpioAttributes mAppleGPIO_DigitalCodecReset;
GpioAttributes mAppleGPIO_HeadphoneMute;
GpioAttributes mAppleGPIO_LineOutMute;
GpioAttributes mAppleGPIO_InternalSpeakerID;
GpioAttributes mAppleGPIO_SpeakerID;
bool findAndAttachI2C();
bool detachFromI2C();
bool openI2C();
void closeI2C();
UInt32 mI2CPort;
PPCI2CInterface* mI2CInterface;
bool mI2C_lastTransactionResult;
typedef enum i2sReference {
kUseI2SCell0 = 0,
kUseI2SCell1 = 1,
kNoI2SCell = 0xFFFFFFFF
} I2SCell;
I2SCell mI2SInterfaceNumber;
IOReturn initI2S(IOMemoryMap* map);
typedef enum SoundFormat
{
kSndIOFormatI2SSony,
kSndIOFormatI2S64x,
kSndIOFormatI2S32x,
kSndIOFormatUnknown
} SoundFormat;
#ifndef kBUILD_FOR_DIRECT_I2S_HW_ACCESS
bool findAndAttachI2S();
bool detachFromI2S();
bool openI2S();
void closeI2S();
AppleI2S * mI2SInterface;
#endif
GpioAttributes GetCachedAttribute ( GPIOSelector selector, GpioAttributes defaultResult );
static void gpioTimerCallback ( OSObject *target, IOAudioDevice *device );
bool interruptUsesTimerPolling( PlatformInterruptSource source );
void poll ( void );
void pollGpioInterrupts ( void );
GpioAttributes readGpioState ( GPIOSelector selector );
IOReturn writeGpioState ( GPIOSelector selector, GpioAttributes gpioState );
IOReturn translateGpioAttributeToGpioState ( GPIOType gpioType, GpioAttributes gpioAttribute, UInt32 * valuePtr );
volatile UInt8 * mHwPtr;
volatile UInt8 * mHwI2SPtr;
IOReturn setupI2SClockSource( UInt32 cell, bool requestClock, UInt32 clockSource );
public:
void LogFCR ( void );
void LogI2S ( void );
void LogGPIO ( void );
void LogInterruptGPIO ( void );
private:
volatile UInt32 * mFcr1;
volatile UInt32 * mFcr3;
volatile UInt32 * mSerialFormat;
volatile UInt32 * mI2SIntCtrl;
volatile UInt32 * mDataWordSize;
volatile UInt32 * mFrameCounter;
IOTimerEventSource * mGpioPollTimer;
volatile UInt8 * mGPIO_analogCodecReset;
volatile UInt8 * mGPIO_mclkMuxSelect;
volatile UInt8 * mGPIO_digitalCodecErrorIrq;
volatile UInt8 * mGPIO_digitalCodecReset;
volatile UInt8 * mGPIO_digitalCodecIrq;
volatile UInt8 * mGPIO_headphoneSense;
volatile UInt8 * mGPIO_headphoneMute;
volatile UInt8 * mGPIO_inputDataMuxSelect;
volatile UInt8 * mGPIO_internalSpeakerID;
volatile UInt8 * mGPIO_lineInSense;
volatile UInt8 * mGPIO_lineOutSense;
volatile UInt8 * mGPIO_lineOutMute;
volatile UInt8 * mGPIO_speakerMute;
void * mCodecInterruptHandler;
void * mCodecErrorInterruptHandler;
void * mDigitalInDetectInterruptHandler;
void * mDigitalOutDetectInterruptHandler;
void * mHeadphoneDetectInterruptHandler;
void * mLineInputDetectInterruptHandler;
void * mLineOutputDetectInterruptHandler;
void * mSpeakerDetectInterruptHandler;
bool mCodecInterruptEnable;
bool mCodecErrorInterruptEnable;
bool mDigitalInDetectInterruptEnable;
bool mDigitalOutDetectInterruptEnable;
bool mHeadphoneDetectInterruptEnable;
bool mLineInputDetectInterruptEnable;
bool mLineOutputDetectInterruptEnable;
bool mSpeakerDetectInterruptEnable;
};
#endif