Annotation of XNU/iokit/Drivers/audio/drvPPCBurgundy/PPCBurgundy.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved. 
        !             3:  *
        !             4:  * Hardware independent (relatively) code for the Burgundy Controller 
        !             5:  *
        !             6:  * HISTORY
        !             7:  *
        !             8:  *
        !             9:  */
        !            10: #include <IOKit/assert.h>
        !            11: #include <IOKit/system.h>
        !            12: 
        !            13: #include <IOKit/IOLib.h>
        !            14: #include <IOKit/IODeviceTreeSupport.h>
        !            15: #include <IOKit/IOPlatformExpert.h>
        !            16: #include <IOKit/ppc/IODBDMA.h>
        !            17: #include "PPCBurgundy.h"
        !            18: #include "burgundy_hw.h"
        !            19: 
        !            20: /*
        !            21:  * Prototyes for the "very private methods" at the end of this
        !            22:  * file. They provide access to the burgundy registers:
        !            23:  */
        !            24: static void writeSoundControlReg( volatile UInt8*, int);
        !            25: static int readCodecSenseLines( volatile UInt8*);
        !            26: static int readCodecReg( volatile UInt8*, int);
        !            27: static void writeCodecReg( volatile UInt8*, int, int);
        !            28: 
        !            29: #define super IOAudioBus
        !            30: OSDefineMetaClassAndStructors( PPCBurgundy, IOAudioBus )
        !            31: 
        !            32: /* ==============
        !            33:  * Public Methods
        !            34:  * ============== */
        !            35: bool
        !            36: PPCBurgundy::init(OSDictionary * properties)
        !            37: {
        !            38:     if (!super::init(properties)) {
        !            39: #ifdef DEBUGMODE
        !            40:         IOLog( "PPCBurgundy::init (this = 0x%08lx) super fails\n", (UInt32)this);
        !            41: #endif
        !            42:         return false;
        !            43:     }
        !            44:  
        !            45:     if(!properties){
        !            46: #ifdef DEBUGMODE
        !            47:         IOLog( "PPCBurgundy::init (this = 0x%08lx) Need to know where Burgundy is !!\n", (UInt32)this);
        !            48: #endif
        !            49:         return false;  // Need to know where Burgundy is!
        !            50:     }
        !            51:        
        !            52:     // This invalidate the cache of the machine architecture
        !            53:     machineType = kMachineTypeUnknown;
        !            54: 
        !            55:     // Nulls the pointers for the arrays we allocate:
        !            56:     fInputComponents = NULL;
        !            57:     fOutputComponents = NULL;
        !            58:     sound = NULL;
        !            59: 
        !            60:     // We start with a clean status register mirror so first read will
        !            61:     // set the driver in the correct mode:
        !            62:     lastStatusRegister = 0L;
        !            63: 
        !            64: #ifdef DEBUGMODE
        !            65:     IOLog( "PPCBurgundy::init (this = 0x%08lx)\n", (UInt32)this);
        !            66: #endif
        !            67:     return true;
        !            68: }
        !            69: 
        !            70: void
        !            71: PPCBurgundy::free()
        !            72: {
        !            73:     // Releases the sound:
        !            74:     if(sound != NULL)
        !            75:         sound->release();
        !            76:     sound = NULL;
        !            77: 
        !            78:     super::free();
        !            79: }
        !            80: 
        !            81: IOService*
        !            82: PPCBurgundy::probe(IOService* provider, SInt32*    score)
        !            83: {
        !            84:     IOService *myService = this;
        !            85: 
        !            86:     // We CAN fail the tye check:
        !            87:     super::probe(provider, score);
        !            88:     *score = kIODefaultProbeScore;
        !            89: 
        !            90:     // finds and cashes the hardware we are running on:
        !            91:     int mType = findHostingHardware(provider);
        !            92: 
        !            93:     // If it one of the machine I know supports
        !            94:     // burgundy I'm going to increment the score
        !            95:     if ((mType == kMachineTypeYosemite) || (mType == kMachineTypeiMac)) {
        !            96:         // One score increment because this is a burgundy-hosting motherboard
        !            97:         *score = *score + 1;
        !            98:     }
        !            99: 
        !           100:     // Figure out if this is a bugundy and if it is a bordeaux
        !           101:     sound = NULL;
        !           102:     isBordeaux = false;
        !           103: 
        !           104:     // This is likely to be the case that this is perch
        !           105:     if (implementsBurgundy(IORegistryEntry::fromPath("/perch", gIODTPlane))) {
        !           106:         *score = *score + 1;
        !           107:         myService = this;
        !           108:     }
        !           109:     else if ((sound = provider->childFromPath("sound", gIODTPlane)) != NULL) {
        !           110:         // IOLog("PPCBurgundy::probe looking for sound\n");
        !           111:         if (implementsBurgundy(sound)) {
        !           112:             *score = *score + 1;
        !           113:             myService = this;
        !           114:         }
        !           115:     }
        !           116:     
        !           117:     if (myService != NULL) {
        !           118:         IOLog("Found Burgundy compatible chip %s\n", (isBordeaux ? "and Bordeaux card": "NON  Bordeaux card"));
        !           119:     }
        !           120: 
        !           121:     return (myService);
        !           122: }
        !           123: 
        !           124: #define kNumDMAStreams 2
        !           125: 
        !           126: bool
        !           127: PPCBurgundy::start(IOService* provider)
        !           128: {
        !           129:     // Gets the base for the burgundy registers:
        !           130:     IOMemoryMap *map;
        !           131:     int i;
        !           132: 
        !           133:     if( !super::start(provider))
        !           134:         return (false);
        !           135: 
        !           136:     map = provider->mapDeviceMemoryWithIndex(kAudioDMAdeviceInt);
        !           137:     if(!map) {
        !           138:         return false;
        !           139:     }
        !           140:     ioBaseBurgundy = (UInt8 *)map->getVirtualAddress();
        !           141: 
        !           142:     if (!AllocateStreams(kNumDMAStreams))
        !           143:         return false;
        !           144: 
        !           145:     map = provider->mapDeviceMemoryWithIndex(kAudioDMAtxInt);
        !           146:     if(!map) {
        !           147:         return false;
        !           148:     }
        !           149:     DefineStream(kAudioDMAOutputStream, kOutput, outputFrameRate(), (IODBDMAChannelRegisters*)map->getVirtualAddress());
        !           150: 
        !           151:     map = provider->mapDeviceMemoryWithIndex(kAudioDMArxInt);
        !           152:     if(!map) {
        !           153:         return false;
        !           154:     }
        !           155:     DefineStream(kAudioDMAInputStream, kInput, inputFrameRate(), (IODBDMAChannelRegisters*)map->getVirtualAddress());
        !           156: 
        !           157:     // Creates the array of input and output components
        !           158:     numInputComponents = numberOfOutputComponents();
        !           159:     numOutputComponents = numberOfInputComponents();
        !           160: 
        !           161:     fInputComponents = (IOAudioComponentImplPtr*)IOMalloc(sizeof(IOAudioComponentImplPtr) * numInputComponents);
        !           162:     if (fInputComponents == NULL) {
        !           163:         // Free the DMA and exit:
        !           164:         FreeStreams();
        !           165:         return false;
        !           166:     }
        !           167: 
        !           168:     fOutputComponents = (IOAudioComponentImplPtr*)IOMalloc(sizeof(IOAudioComponentImplPtr) * numOutputComponents);
        !           169:     if (fOutputComponents == NULL) {
        !           170:         // Free the input components
        !           171:         IOFree(fInputComponents, sizeof(IOAudioComponentImplPtr) * numInputComponents);
        !           172:         fInputComponents = NULL;
        !           173:         numInputComponents = 0;
        !           174:  
        !           175:         // Free the DMA and exit:
        !           176:         FreeStreams();
        !           177:         return false;
        !           178:     }
        !           179: 
        !           180:     // Initalizes all the components:
        !           181:     for (i = 0; i < numInputComponents; i++)
        !           182:         fInputComponents[i] = NULL;
        !           183: 
        !           184:     for (i = 0; i < numOutputComponents; i++)
        !           185:         fOutputComponents[i] = NULL;
        !           186: 
        !           187:     // Initializes the sound control register:
        !           188:     soundControlRegister = ( kSoundCtlReg_InSubFrame0      | \
        !           189:                              kSoundCtlReg_OutSubFrame0     | \
        !           190:                              kSoundCtlReg_Rate_44100        );
        !           191:     writeSoundControlReg(ioBaseBurgundy, soundControlRegister);
        !           192: 
        !           193:     // Set Input Source A gain to default
        !           194:     writeCodecReg( ioBaseBurgundy, kGASALReg, kGAS_Default_Gain );
        !           195:     writeCodecReg( ioBaseBurgundy, kGASARReg, kGAS_Default_Gain );
        !           196:     writeCodecReg( ioBaseBurgundy, kVGA2Reg,   0x44 );
        !           197:     writeCodecReg( ioBaseBurgundy, kGAS2LReg,  255 );
        !           198:     writeCodecReg( ioBaseBurgundy, kGAS2RReg,  255 );
        !           199:     
        !           200:     // Set mixer 1 input to Input Source A (Serial-in Subframe 0)
        !           201:     writeCodecReg( ioBaseBurgundy, kMX1Reg, kMX1Reg_Select_ISAL | kMX1Reg_Select_ISAR );
        !           202:     writeCodecReg( ioBaseBurgundy, kSDInReg, kSDInReg_ASA_From_SF0 );
        !           203: 
        !           204:     // Set mixer 0-3 outputs to default gain
        !           205:     writeCodecReg( ioBaseBurgundy, kMXEQ1LReg, kMXEQ_Default_Gain );
        !           206:     writeCodecReg( ioBaseBurgundy, kMXEQ1RReg, kMXEQ_Default_Gain );
        !           207:     writeCodecReg( ioBaseBurgundy, kMXEQ2LReg, kMXEQ_Default_Gain );
        !           208:     writeCodecReg( ioBaseBurgundy, kMXEQ2RReg, kMXEQ_Default_Gain );
        !           209:     writeCodecReg( ioBaseBurgundy, kMXEQ3LReg, kMXEQ_Default_Gain );
        !           210:     writeCodecReg( ioBaseBurgundy, kMXEQ3RReg, kMXEQ_Default_Gain );
        !           211: 
        !           212:     // Set Output Source 0 gain to default
        !           213:     writeCodecReg( ioBaseBurgundy, kGAP0LReg, kGAP_Default_Gain );
        !           214:     writeCodecReg( ioBaseBurgundy, kGAP0RReg, kGAP_Default_Gain );
        !           215: 
        !           216:     startWorkLoop();
        !           217:     
        !           218:     return true;
        !           219: }
        !           220: 
        !           221: void
        !           222: PPCBurgundy::stop(IOService *provider)
        !           223: {
        !           224:     // Releases all DMA streams:
        !           225:     FreeStreams();
        !           226: 
        !           227:     // Releases the input components
        !           228:     if (fInputComponents != NULL) {
        !           229:         IOFree(fInputComponents, sizeof(IOAudioComponentImplPtr) * numInputComponents);
        !           230:         fInputComponents = NULL;
        !           231:         numInputComponents = 0;
        !           232:     }
        !           233: 
        !           234:     // Releases the output components
        !           235:     if (fOutputComponents != NULL) {
        !           236:         IOFree(fOutputComponents, sizeof(IOAudioComponentImplPtr) * numOutputComponents);
        !           237:         fOutputComponents = NULL;
        !           238:         numOutputComponents = 0;
        !           239:     }
        !           240: }
        !           241: 
        !           242: void
        !           243: PPCBurgundy::CreateAudioTopology(IOCommandQueue *queue)
        !           244: {
        !           245:     IOAudioComponentImpl *mixerIn;
        !           246:     IOAudioComponentImpl *mixerOut;
        !           247:     IOAudioComponentImpl *microphone;
        !           248:     IOAudioComponentImpl *lineout;
        !           249:     IOAudioComponentImpl *linein;
        !           250:     IOAudioComponentImpl *headphones;
        !           251:     IOAudioComponentImpl *cd;
        !           252:     IOAudioComponentImpl *speaker;
        !           253:     IOAudioComponentImpl *passtru;
        !           254: 
        !           255:     AudioStreamIndex outputStream;
        !           256:     AudioStreamIndex inputStream;
        !           257:     
        !           258:     if (!fStreams)
        !           259:         return;
        !           260: 
        !           261:     outputStream = firstStreamAfter(kOutput, 0);
        !           262:     inputStream = firstStreamAfter(kInput, 0);
        !           263: 
        !           264:     if ((outputStream == kInvalidStreamIndex) || (inputStream == kInvalidStreamIndex)) {
        !           265:         IOLog("PPCBurgundy::CreateAudioTopology called without available DMA streams\n");
        !           266:         return;
        !           267:     }
        !           268:     else
        !           269:         IOLog("PPCBurgundy::CreateAudioTopology input stream is %d output is %d\n", inputStream, outputStream);
        !           270: 
        !           271:     mixerOut = buildComponentAndAttach(GetStream(outputStream), NULL, componentDictionaryMixerOut(), queue);
        !           272:     headphones = buildComponentAndAttach(mixerOut, NULL, componentDictionaryHeadphones(), queue);
        !           273:     speaker = buildComponentAndAttach(mixerOut, NULL, componentDictionarySpeaker(), queue);
        !           274:     lineout = buildComponentAndAttach(mixerOut, NULL, componentDictionaryLineout(), queue);
        !           275: 
        !           276:     mixerIn = buildComponentAndAttach(NULL, GetStream(inputStream), componentDictionaryMixerIn(), queue);
        !           277:     cd = buildComponentAndAttach(NULL, NULL,  componentDictionaryCD(), queue);
        !           278:     linein = buildComponentAndAttach(NULL, NULL,  componentDictionaryLinein(), queue);
        !           279:     microphone = buildComponentAndAttach(NULL, mixerIn, componentDictionaryMicrophone(), queue);
        !           280: 
        !           281:     passtru = buildComponentAndAttach(mixerIn, mixerOut, componentDictionaryPassThru(), queue);
        !           282: 
        !           283:     buildComponentAndAttach(mixerIn, mixerOut, componentDictionaryPassThru(), queue);
        !           284:     fInputComponents[kCD] = buildComponentAndAttach(NULL, mixerIn, componentDictionaryCD(), queue);
        !           285: 
        !           286:     // FIXME: the component connection could be done better than so
        !           287:     if (fInputComponents != NULL) {
        !           288:         fInputComponents[kMicroPhone] = microphone;
        !           289: 
        !           290:         if (numInputComponents > 1)
        !           291:             fInputComponents[kCD] = cd;
        !           292: 
        !           293:         if (numInputComponents > 2)
        !           294:             fInputComponents[kLineIn] = linein;
        !           295:     }
        !           296: 
        !           297:     if (fOutputComponents != NULL) {
        !           298:         fOutputComponents[kSpeaker] = speaker;
        !           299: 
        !           300:         if (numOutputComponents > 1)
        !           301:             fOutputComponents[kHeadphones] = headphones;
        !           302: 
        !           303:         if (numOutputComponents > 2)
        !           304:             fOutputComponents[kLineOut] = lineout;
        !           305:     }
        !           306: 
        !           307:     // Sets ups the burgundy as required by this machine wiring
        !           308:     // configuration:
        !           309:     if (!dependentSetup())
        !           310:         IOLog("PPCBurgundy::CreateAudioTopology burgundy setup failed\n");
        !           311: }
        !           312: 
        !           313: void
        !           314: PPCBurgundy::DoClockTick(IOTimerEventSource *t)
        !           315: {
        !           316:     checkStatusRegister();
        !           317:     super::DoClockTick(t);
        !           318: }
        !           319: 
        !           320: void
        !           321: PPCBurgundy::calculateTickInterval(AbsoluteTime *tickInterval)
        !           322: {
        !           323:     AbsoluteTime maxInterval;
        !           324: 
        !           325:     // We want to check the status at least one a second
        !           326:     nanoseconds_to_absolutetime(NSEC_PER_SEC, &maxInterval);
        !           327:     if(CMP_ABSOLUTETIME(&maxInterval, tickInterval) < 0) {
        !           328:         *tickInterval = maxInterval;
        !           329:     }
        !           330:     super::calculateTickInterval(tickInterval);
        !           331: }
        !           332: 
        !           333: IOReturn
        !           334: PPCBurgundy::SetControl(UInt16 id, int val)
        !           335: {
        !           336:     IOReturn res = kIOReturnSuccess;
        !           337:     
        !           338:     switch(id) {
        !           339:         case kSpeakerMute:
        !           340:             muteInternalSpeaker(val != 0);
        !           341:             muteHeadphones(val == 0);
        !           342:             break;
        !           343: 
        !           344:         case kHeadphonesMute:
        !           345:             muteHeadphones(val != 0);
        !           346:             muteInternalSpeaker(val == 0);
        !           347:             break;
        !           348: 
        !           349:         case kMicrophoneMute:
        !           350:             setMicInput(val == 0);
        !           351:             break;
        !           352: 
        !           353:         case kSpeakerVolLeft:
        !           354:             volumeInternalSpeakerLeft(val);
        !           355:             break;
        !           356: 
        !           357:         case kSpeakerVolRight:
        !           358:             volumeInternalSpeakerRight(val);
        !           359:             break;
        !           360: 
        !           361:         case kHeadphonesVolLeft:
        !           362:             volumeHeadphonesLeft(val);
        !           363:             break;
        !           364: 
        !           365:         case kHeadphonesVolRight:
        !           366:             volumeHeadphonesRight(val);
        !           367:             break;
        !           368: 
        !           369:         case kCDMute:
        !           370:             muteCDLine(val != 0);
        !           371:             break;
        !           372: 
        !           373:         case kMixerInVolLeft:
        !           374:             volumeMixerInLeft(val);
        !           375:             break;
        !           376: 
        !           377:         case kMixerInVolRight:
        !           378:             volumeMixerInRight(val);
        !           379:             break;
        !           380: 
        !           381:         case kPassThruVolLeft:
        !           382:             break;
        !           383: 
        !           384:         case kPassThruVolRight:
        !           385:             break;
        !           386: 
        !           387:         case kPassThruMute:
        !           388:             break;
        !           389: 
        !           390:         default:
        !           391:             res = kIOReturnUnsupported;
        !           392:     }
        !           393:     return res;
        !           394: }
        !           395: 
        !           396: /* ===============
        !           397:  * Private Methods
        !           398:  * =============== */
        !           399: 
        !           400: // --------------------------------------------------------------------------
        !           401: // Method: implementsBurgundy
        !           402: //
        !           403: // Purpose:
        !           404: //   Attempts to discover if the device implements burgundy:
        !           405: bool
        !           406: PPCBurgundy::implementsBurgundy(IORegistryEntry *device)
        !           407: {    
        !           408:     if (device != NULL) {
        !           409:         OSData *s = NULL;
        !           410: 
        !           411:         //IOLog("Matching burgundy compatibility with %s\n", device->getName());
        !           412: 
        !           413:         s = OSDynamicCast(OSData, device->getProperty("compatible"));
        !           414: 
        !           415:         if (s != NULL) {
        !           416:             if(s->isEqualTo("burgundy", sizeof("burgundy")-1)) {
        !           417:                 return true;
        !           418:             }
        !           419:             else if(s->isEqualTo("DVD-Video and Audio/Video", sizeof("DVD-Video and Audio/Video")-1)) {
        !           420:                 // also sets the isBordeaux flag
        !           421:                 isBordeaux = true;
        !           422:                 return true;
        !           423:             }
        !           424:             else {
        !           425:                 //IOLog("PPCBurgundy::probe sound is not burgundy compatible.\n");
        !           426:             }
        !           427:         }
        !           428:         else {
        !           429:             //IOLog("PPCBurgundy::probe sound does not have a compatible property.\n");
        !           430:         }
        !           431:     }
        !           432:     else{
        !           433:         //IOLog("PPCBurgundy::probe this hardware does not have a sound chip\n");
        !           434:     }
        !           435:     return false;
        !           436: }
        !           437: 
        !           438: // --------------------------------------------------------------------------
        !           439: // Method: findHostingHardware
        !           440: //
        !           441: // Purpose:
        !           442: //   Finds the kind of hardware we are running on. Since all the older machines
        !           443: //   do not have all the information about how burgundy is wired, knowing which
        !           444: //   machine we are running on helps to set up the driver correctly.
        !           445: //   The method recognizes more machines than the ones that use bugundy (e.g.
        !           446: //   "'AAPL,9500'" has an AWACS).
        !           447: 
        !           448: int
        !           449: PPCBurgundy::findHostingHardware(IOService *provider)
        !           450: {
        !           451:     IOService *topProvider = NULL;
        !           452: 
        !           453:     // If we already found the machine the driver is running on
        !           454:     // just returns the value previously found:
        !           455:     if ((machineType >= kMachineTypeUnknown) ||
        !           456:        (machineType == 0)) {
        !           457:         // if the argument is missing I've to get from myself:
        !           458:         if (provider == NULL)
        !           459:             provider = getProvider();
        !           460: 
        !           461:           // See if we find the top of the tree (with the machine type)
        !           462:         // iterating all the way up:
        !           463:         while (provider != NULL) {
        !           464:             topProvider = provider;
        !           465:             provider = topProvider->getProvider();
        !           466:         }
        !           467: 
        !           468:          // by default the hardware is unknown:
        !           469:         machineType = kMachineTypeUnknown;
        !           470: 
        !           471:         if (topProvider != NULL) {
        !           472:             if (IODTMatchNubWithKeys(topProvider, "'AAPL,9500'"))
        !           473:                 machineType = kMachine9500;
        !           474:             if (IODTMatchNubWithKeys(topProvider, "'AAPL,Gossamer'"))
        !           475:                 machineType = kMachineGenericGossamer;
        !           476:             if (IODTMatchNubWithKeys(topProvider, "'AAPL,PowerMac G3'"))
        !           477:                 machineType = kMachineTypeSilk;
        !           478:             else if (IODTMatchNubWithKeys(topProvider, "'AAPL,PowerBook1998'"))
        !           479:                 machineType = kMachineTypeWallstreet;
        !           480:             else if (IODTMatchNubWithKeys(topProvider, "'iMac,1'"))
        !           481:                 machineType = kMachineTypeiMac;
        !           482:             else if (IODTMatchNubWithKeys(topProvider, "('PowerMac1,1', 'PowerMac1,2')"))
        !           483:                 machineType = kMachineTypeYosemite;
        !           484:             else if (IODTMatchNubWithKeys(topProvider, "'PowerMac3,1'"))
        !           485:                 machineType = kMachineTypeSawtooth;
        !           486:             else if (IODTMatchNubWithKeys(topProvider, "'PowerBook1,1'"))
        !           487:                 machineType = kMachineType101;
        !           488:             else if (IODTMatchNubWithKeys(topProvider, "'PowerBook2,1'"))
        !           489:                 machineType = kMachineTypeiBook;
        !           490:             else
        !           491:                 IOLog("PPCBurgundy::findHostingHardware unknown machine type\n");
        !           492:         }
        !           493:         else
        !           494:             IOLog("PPCBurgundy::findHostingHardware misses the top provider\n");
        !           495:     }
        !           496: 
        !           497:     //Just to ease up the debugging
        !           498:     //IOLog("PPCBurgundy::findHostingHardware found %d\n", machineType);
        !           499: 
        !           500:     return (machineType);
        !           501: }
        !           502: 
        !           503: // --------------------------------------------------------------------------
        !           504: // Method: numberOfInputComponents
        !           505: //
        !           506: // Purpose:
        !           507: //        returns the number of components for the input lines
        !           508: //        usually are 2 one is the microphone and the other is
        !           509: //        microphone jack.
        !           510: #define kCommonNumberOfInputComponents 2
        !           511: 
        !           512: int
        !           513: PPCBurgundy::numberOfInputComponents()
        !           514: {
        !           515:     if(sound) {
        !           516:         OSData *t;
        !           517:   
        !           518:         t = OSDynamicCast(OSData, sound->getProperty("#-detects"));
        !           519:         if (t != NULL) {
        !           520:             return *(UInt32*)(t->getBytesNoCopy());
        !           521:         }
        !           522:     }
        !           523: 
        !           524:     return kCommonNumberOfInputComponents;
        !           525: }
        !           526: 
        !           527: // --------------------------------------------------------------------------
        !           528: // Method: numberOfOutputComponents
        !           529: //
        !           530: // Purpose:
        !           531: //        returns the number of components for the output lines
        !           532: //        usually are 2 one is the internal speacker and the other
        !           533: //        is the headphone line.
        !           534: #define kCommonNumberOfOutputComponents 2
        !           535: 
        !           536: int
        !           537: PPCBurgundy::numberOfOutputComponents()
        !           538: {
        !           539:     if(sound) {
        !           540:         OSData *t;
        !           541:         
        !           542:         t = OSDynamicCast(OSData, sound->getProperty("#-outputs"));
        !           543:         if (t != NULL) {
        !           544:             return *(UInt32*)(t->getBytesNoCopy());
        !           545:         }
        !           546:     }
        !           547:     return kCommonNumberOfOutputComponents;
        !           548: }
        !           549: 
        !           550: 
        !           551: // --------------------------------------------------------------------------
        !           552: // Method: inputFrameRate
        !           553: //
        !           554: // Purpose:
        !           555: //        returns the input frame rate as in the registry, if it is
        !           556: //        not found in the registry, it returns the default value.
        !           557: #define kCommonInputFrameRate 44100
        !           558: 
        !           559: UInt16
        !           560: PPCBurgundy::inputFrameRate()
        !           561: {
        !           562:     if(sound) {
        !           563:         OSData *t;
        !           564: 
        !           565:         t = OSDynamicCast(OSData, sound->getProperty("input-frame-rates"));
        !           566:         if (t != NULL) {
        !           567:             UInt16 fr = *(UInt32*)(t->getBytesNoCopy());
        !           568: 
        !           569: #ifdef DEBUGMODE
        !           570:             IOLog( "PPCBurgundy::inputFrameRate = %d\n", fr);
        !           571: #endif
        !           572:             return fr;
        !           573:         }
        !           574:     }
        !           575: 
        !           576:     return kCommonInputFrameRate;
        !           577: }
        !           578: 
        !           579: 
        !           580: // --------------------------------------------------------------------------
        !           581: // Method: outputFrameRate
        !           582: //
        !           583: // Purpose:
        !           584: //        returns the output frame rate as in the registry, if it is
        !           585: //        not found in the registry, it returns the default value.
        !           586: #define kCommonOutputFrameRate 44100
        !           587: 
        !           588: UInt16
        !           589: PPCBurgundy::outputFrameRate()
        !           590: {
        !           591:      if(sound) {
        !           592:         OSData *t;
        !           593: 
        !           594:         t = OSDynamicCast(OSData, sound->getProperty("output-frame-rates"));
        !           595:         if (t != NULL) {
        !           596:             UInt16 fr = *(UInt32*)(t->getBytesNoCopy());
        !           597: 
        !           598: #ifdef DEBUGMODE
        !           599:             IOLog( "PPCBurgundy::outputFrameRate = %d\n", fr);
        !           600: #endif
        !           601:             return fr;
        !           602:         }
        !           603:     }
        !           604: 
        !           605:     return kCommonOutputFrameRate;
        !           606: }
        !           607: 
        !           608: // --------------------------------------------------------------------------
        !           609: // Method(s): componentDictionaryXXXXXX
        !           610: //
        !           611: // Purpose:
        !           612: //        the next N methods return the strings for the component dictionaries
        !           613: //        for each kind of component. As stated in the AWACS driver, these should
        !           614: //        end in the driver resources.
        !           615: 
        !           616: // NOTE: (This is important !!!) the soundControls enum in the header file is
        !           617: //       bounded to the following stings in this way:
        !           618: //       for each component the control Id in the string must have the same value
        !           619: //       of the corrispondent soundControls enum item. For example the sound control
        !           620: //       enum item kHeadphonesVolLeft has value 4, so in sHeadphones the ID of the
        !           621: //       volume left control must be 4.
        !           622: 
        !           623: char*
        !           624: PPCBurgundy::componentDictionarySpeaker()
        !           625: {
        !           626:     static const char *sSpeaker =
        !           627:     "{
        !           628:     'Type' = 'Speaker';
        !           629:     'Channels' = 2:8;
        !           630:     'Master' = 1:8;
        !           631:     'Controls' = {
        !           632:         'MuteAll' = {
        !           633:             'Type' = 'Mute';
        !           634:             'Id' = 0:16;
        !           635:             'Val' = 0:8;
        !           636:             'Min' = 0:8;
        !           637:             'Max' = 1:8;
        !           638:             'Chan' = 0:8;
        !           639:         };
        !           640:         'VolumeLeft' = {
        !           641:             'Type' = 'Volume';
        !           642:             'Id' = 1:16;
        !           643:             'Val' = 65535:16;
        !           644:             'Min' = 0:16;
        !           645:             'Max' = 65535:16;
        !           646:             'Chan' = 1:8;
        !           647:         };
        !           648:         'VolumeRight' = {
        !           649:             'Type' = 'Volume';
        !           650:             'Id' = 2:16;
        !           651:             'Val' = 65535:16;
        !           652:             'Min' = 0:16;
        !           653:             'Max' = 65535:16;
        !           654:             'Chan' = 2:8;
        !           655:         };
        !           656:     };
        !           657:     }";
        !           658:     return (char*)sSpeaker;
        !           659: }
        !           660: 
        !           661: char*
        !           662: PPCBurgundy::componentDictionaryHeadphones()
        !           663: {
        !           664:     static const char *sHeadphones =
        !           665:     "{
        !           666:     'Type' = 'Headphones';
        !           667:     'Channels' = 2:8;
        !           668:     'Master' = 1:8;
        !           669:     'Controls' = {
        !           670:         'MuteAll' = {
        !           671:             'Type' = 'Mute';
        !           672:             'Id' = 3:16;
        !           673:             'Val' = 0:8;
        !           674:             'Min' = 0:8;
        !           675:             'Max' = 1:8;
        !           676:             'Chan' = 0:8;
        !           677:         };
        !           678:         'VolumeLeft' = {
        !           679:             'Type' = 'Volume';
        !           680:             'Id' = 4:16;
        !           681:             'Val' = 65535:16;
        !           682:             'Min' = 0:16;
        !           683:             'Max' = 65535:16;
        !           684:             'Chan' = 1:8;
        !           685:         };
        !           686:         'VolumeRight' = {
        !           687:             'Type' = 'Volume';
        !           688:             'Id' = 5:16;
        !           689:             'Val' = 65535:16;
        !           690:             'Min' = 0:16;
        !           691:             'Max' = 65535:16;
        !           692:             'Chan' = 2:8;
        !           693:         };
        !           694:     };
        !           695:     'Inputs' = {
        !           696:         'Jack' = {
        !           697:             'Val' = 0:8;
        !           698:             'Min' = 0:8;
        !           699:             'Max' = 1:8;
        !           700:         };
        !           701:     };
        !           702:     }";
        !           703:     return (char*)sHeadphones;
        !           704: }
        !           705: 
        !           706: char*
        !           707: PPCBurgundy::componentDictionaryMicrophone()
        !           708: {
        !           709:     static const char *sMicrophone =
        !           710:     "{
        !           711:     'Type' = 'Microphone';
        !           712:     'Channels' = 2:8;
        !           713:     'Controls' = {
        !           714:         'MuteAll' = {
        !           715:             'Type' = 'Mute';
        !           716:             'Id' = 6:16;
        !           717:             'Val' = 0:8;
        !           718:             'Min' = 0:8;
        !           719:             'Max' = 1:8;
        !           720:             'Chan' = 0:8;
        !           721:         };
        !           722:     };
        !           723:     'Inputs' = {
        !           724:         'Jack' = {
        !           725:             'Val' = 0:8;
        !           726:             'Min' = 0:8;
        !           727:             'Max' = 1:8;
        !           728:         };
        !           729:     };
        !           730:     }";
        !           731:     return (char*)sMicrophone;
        !           732: }
        !           733: 
        !           734: char*
        !           735: PPCBurgundy::componentDictionaryLinein()
        !           736: {
        !           737:     static const char *sLinein =
        !           738:     "{
        !           739:     'Type' = 'LineIn';
        !           740:     'Channels' = 2:8;
        !           741:     'Controls' = {
        !           742:         'MuteAll' = {
        !           743:             'Type' = 'Mute';
        !           744:             'Id' = 14:16;
        !           745:             'Val' = 0:8;
        !           746:             'Min' = 0:8;
        !           747:             'Max' = 1:8;
        !           748:             'Chan' = 0:8;
        !           749:         };
        !           750:     };
        !           751:     'Inputs' = {
        !           752:         'Jack' = {
        !           753:             'Val' = 0:8;
        !           754:             'Min' = 0:8;
        !           755:             'Max' = 1:8;
        !           756:         };
        !           757:     };
        !           758:     }";
        !           759:     return (char*)sLinein;
        !           760: }
        !           761: 
        !           762: char*
        !           763: PPCBurgundy::componentDictionaryLineout()
        !           764: {
        !           765:     static const char *sLineout =
        !           766:     "{
        !           767:     'Type' = 'LineOut';
        !           768:     'Channels' = 2:8;
        !           769:     'Controls' = {
        !           770:         'MuteAll' = {
        !           771:             'Type' = 'Mute';
        !           772:             'Id' = 13:16;
        !           773:             'Val' = 0:8;
        !           774:             'Min' = 0:8;
        !           775:             'Max' = 1:8;
        !           776:             'Chan' = 0:8;
        !           777:         };
        !           778:     };
        !           779:     'Inputs' = {
        !           780:         'Jack' = {
        !           781:             'Val' = 0:8;
        !           782:             'Min' = 0:8;
        !           783:             'Max' = 1:8;
        !           784:         };
        !           785:     };
        !           786:     }";
        !           787:     return (char*)sLineout;
        !           788: }
        !           789: 
        !           790: char*
        !           791: PPCBurgundy::componentDictionaryCD()
        !           792: {
        !           793:     static const char *sCD =
        !           794:     "{
        !           795:     'Type' = 'CD';
        !           796:     'Channels' = 2:8;
        !           797:     'Controls' = {
        !           798:         'MuteAll' = {
        !           799:             'Type' = 'Mute';
        !           800:             'Id' = 7:16;
        !           801:             'Val' = 0:8;
        !           802:             'Min' = 0:8;
        !           803:             'Max' = 1:8;
        !           804:             'Chan' = 0:8;
        !           805:         };
        !           806:     };
        !           807:     }";
        !           808:     return (char*)sCD;
        !           809: }
        !           810: 
        !           811: char*
        !           812: PPCBurgundy::componentDictionaryMixerIn()
        !           813: {
        !           814:     static const char *sMixerIn =
        !           815:     "{
        !           816:     'Type' = 'Mixer';
        !           817:     'Channels' = 2:8;
        !           818:     'Controls' = {
        !           819:         'VolumeLeft' = {
        !           820:             'Type' = 'Volume';
        !           821:             'Id' = 8:16;
        !           822:             'Val' = 65535:16;
        !           823:             'Min' = 0:16;
        !           824:             'Max' = 65535:16;
        !           825:             'Chan' = 1:8;
        !           826:         };
        !           827:         'VolumeRight' = {
        !           828:             'Type' = 'Volume';
        !           829:             'Id' = 9:16;
        !           830:             'Val' = 65535:16;
        !           831:             'Min' = 0:16;
        !           832:             'Max' = 65535:16;
        !           833:             'Chan' = 2:8;
        !           834:         };
        !           835:     };
        !           836:     }";
        !           837:     return (char*)sMixerIn;
        !           838: }
        !           839: 
        !           840: char*
        !           841: PPCBurgundy::componentDictionaryMixerOut()
        !           842: {
        !           843:     static const char *sMixerOut =
        !           844:     "{
        !           845:     'Type' = 'Mixer';
        !           846:     'Channels' = 2:8;
        !           847:     }";
        !           848:     return (char*)sMixerOut;
        !           849: }
        !           850: 
        !           851: char*
        !           852: PPCBurgundy::componentDictionaryPassThru()
        !           853: {
        !           854:     static const char *sPassThru =
        !           855:     "{
        !           856:     'Type' = 'Feature';
        !           857:     'Channels' = 2:8;
        !           858:     'Controls' = {
        !           859:         'MuteAll' = {
        !           860:             'Type' = 'Mute';
        !           861:             'Id' = 12:16;
        !           862:             'Val' = 1:8;
        !           863:             'Min' = 0:8;
        !           864:             'Max' = 1:8;
        !           865:             'Chan' = 0:8;
        !           866:         };
        !           867:         'VolumeLeft' = {
        !           868:             'Type' = 'Volume';
        !           869:             'Id' = 10:16;
        !           870:             'Val' = 65535:16;
        !           871:             'Min' = 0:16;
        !           872:             'Max' = 65535:16;
        !           873:             'Chan' = 1:8;
        !           874:         };
        !           875:         'VolumeRight' = {
        !           876:             'Type' = 'Volume';
        !           877:             'Id' = 11:16;
        !           878:             'Val' = 65535:16;
        !           879:             'Min' = 0:16;
        !           880:             'Max' = 65535:16;
        !           881:             'Chan' = 2:8;
        !           882:         };
        !           883:     };
        !           884:     }";
        !           885:     return (char*)sPassThru;
        !           886: }
        !           887: 
        !           888: // --------------------------------------------------------------------------
        !           889: // Method: dependentSetup
        !           890: //
        !           891: // Purpose:
        !           892: //        this handles the setup of the burgundy chip for each kind of
        !           893: //        hosting hardware.
        !           894: bool
        !           895: PPCBurgundy::dependentSetup()
        !           896: {
        !           897:     UInt32 OSReg = 0;
        !           898:  
        !           899:     //
        !           900:     // G3-Gossamer DVD-card assignments (Bordeaux)
        !           901:     //
        !           902:     //                 Port 17  - Internal speaker
        !           903:     //          Port 15  - Rear panel RCA Out
        !           904:     //         Port 16  - Rear panel MiniJack Out
        !           905:     //
        !           906:     // Yosemite assignments
        !           907:     //
        !           908:     //         Port 17 - Internal speaker
        !           909:     //         Port 14 - Rear panel MiniJack Out
        !           910:     //
        !           911:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort17Reg,        kOutputLvl_Default );
        !           912: 
        !           913:     switch (findHostingHardware(NULL))
        !           914:     {
        !           915:         case kMachineTypeSilk:
        !           916:             // G3-Gossamer DVD-card
        !           917:             assert(isBordeaux);
        !           918:             writeCodecReg( ioBaseBurgundy, kOutputLvlPort15Reg, kOutputLvl_Default );
        !           919:             writeCodecReg( ioBaseBurgundy, kOutputLvlPort16Reg, kOutputLvl_Default );
        !           920: 
        !           921:             writeCodecReg( ioBaseBurgundy, kGAP1LReg, kGAP_Default_Gain );
        !           922:             writeCodecReg( ioBaseBurgundy, kGAP1RReg, kGAP_Default_Gain );
        !           923: 
        !           924:             currentOutputMuteReg = kOutputMuteReg_Port15L | kOutputMuteReg_Port15R |
        !           925:                 kOutputMuteReg_Port16L | kOutputMuteReg_Port16R |
        !           926:                 kOutputMuteReg_Port17M;
        !           927: 
        !           928:             OSReg = kOSReg_OS0_Select_MXO1 | kOSReg_OS1_Select_MXO1;
        !           929:             break;
        !           930: 
        !           931:         case kMachineTypeiMac:
        !           932:         case kMachineTypeYosemite:
        !           933:             // Yosemite:  (FIXME as soon as newwolds works I should move this in the newworld handling
        !           934:             //            this should be done also for the others switch statements in this file)
        !           935:             writeCodecReg( ioBaseBurgundy, kOutputLvlPort14Reg, kOutputLvl_Default );
        !           936: 
        !           937:             currentOutputMuteReg = kOutputMuteReg_Port14L | kOutputMuteReg_Port14R |
        !           938:                 kOutputMuteReg_Port17M;
        !           939: 
        !           940:             OSReg = kOSReg_OS0_Select_MXO1;
        !           941:             break;
        !           942:         default:
        !           943:             // FIXME: this may be a newworld, so the registry holds
        !           944:             // all we need to know about how the burgundy is wired:
        !           945:             // Add here the code to interpret it.
        !           946:             break;
        !           947:     }
        !           948:     
        !           949:     writeCodecReg( ioBaseBurgundy, kOSReg,         OSReg );
        !           950:     writeCodecReg( ioBaseBurgundy, kOutputMuteReg, currentOutputMuteReg         );
        !           951:     writeCodecReg( ioBaseBurgundy, kOutputCtl0Reg, kOutputCtl0Reg_OutCtl1_High );
        !           952: 
        !           953:     // while this acts on the analog volume controls
        !           954:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort13Reg, 0x00);
        !           955:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort14Reg, 0x00);
        !           956:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort15Reg, 0x00);
        !           957:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort16Reg, 0x00);
        !           958:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort17Reg, 0x00);
        !           959: 
        !           960:     // and writes the digital volumes:
        !           961:     writeCodecReg( ioBaseBurgundy, kGAP0LReg, 0xFF);
        !           962:     writeCodecReg( ioBaseBurgundy, kGAP1LReg, 0xFF);
        !           963:     writeCodecReg( ioBaseBurgundy, kGAP2LReg, 0xFF);
        !           964:     writeCodecReg( ioBaseBurgundy, kGAP3LReg, 0xFF);
        !           965:     
        !           966:     writeCodecReg( ioBaseBurgundy, kGAP0RReg, 0xFF);
        !           967:     writeCodecReg( ioBaseBurgundy, kGAP1RReg, 0xFF);
        !           968:     writeCodecReg( ioBaseBurgundy, kGAP2RReg, 0xFF);
        !           969:     writeCodecReg( ioBaseBurgundy, kGAP3RReg, 0xFF);
        !           970:     return true;
        !           971: }
        !           972: 
        !           973: // --------------------------------------------------------------------------
        !           974: // Method: checkStatusRegister
        !           975: //
        !           976: // Purpose:
        !           977: //        if the argument is true mutes the internal speaker, otherwise
        !           978: //        it "unmutes" it.
        !           979: void
        !           980: PPCBurgundy::checkStatusRegister()
        !           981: {
        !           982:     if (burgundyStatusChanged())  {
        !           983:         int i;
        !           984:         
        !           985:         OSNumber * num = OSNumber::withNumber(lastStatusRegister, 32);
        !           986:         setProperty("Status", num);
        !           987:         num->release();
        !           988: 
        !           989: #ifdef DEBUGMODE
        !           990:        IOLog("Status changes in: 0x%08lx\n", lastStatusRegister);
        !           991: #endif
        !           992:         // Something changed, act on it:
        !           993:         // For each sense line we call the action attached
        !           994:         // to thar sense line:
        !           995:         for (i = 0; i < numInputComponents; i++)
        !           996:             if (fInputComponents[i] != NULL)
        !           997:                 fInputComponents[i]->Set(gInputsSym, gJackSym, inputComponentStatus(i));
        !           998: 
        !           999:         for (i = 0; i < numOutputComponents; i++)
        !          1000:             if (fOutputComponents[i] != NULL)
        !          1001:                 fOutputComponents[i]->Set(gInputsSym, gJackSym, outputComponentStatus(i));
        !          1002:     }
        !          1003: }
        !          1004: 
        !          1005: // --------------------------------------------------------------------------
        !          1006: // Method: inputComponentStatus
        !          1007: //
        !          1008: // Purpose:
        !          1009: //        checks the status of the jack line of the ith output component:
        !          1010: bool
        !          1011: PPCBurgundy::inputComponentStatus(int index)
        !          1012: {
        !          1013:     switch(index)
        !          1014:     {
        !          1015:         case kMicroPhone: // check the microphone
        !          1016:             return microphoneInserted();
        !          1017: 
        !          1018:         case kCD:       // the cd input is not associated to a jack
        !          1019:             return false;
        !          1020: 
        !          1021:         case kLineIn:  // the RCA line does not have a jack
        !          1022:             return false;
        !          1023:     }
        !          1024: 
        !          1025:     return false;      // by deafult there is no jack
        !          1026: }
        !          1027: 
        !          1028: 
        !          1029: // --------------------------------------------------------------------------
        !          1030: // Method: outputComponentStatus
        !          1031: //
        !          1032: // Purpose:
        !          1033: //        checks the status of the jack line of the ith output component:
        !          1034: bool
        !          1035: PPCBurgundy::outputComponentStatus(int index)
        !          1036: {
        !          1037:     switch(index)
        !          1038:     {
        !          1039:         case kSpeaker:
        !          1040:             return false;      // the internal speaker does not have a jack
        !          1041: 
        !          1042:         case kHeadphones:      // check the headphones:
        !          1043:             return headphonesInserted();
        !          1044: 
        !          1045:         case kLineOut:
        !          1046:             return false;      // the RCA line does not have a jack
        !          1047:     }
        !          1048: 
        !          1049:     return false;      // by deafult there is no jack
        !          1050: }
        !          1051: 
        !          1052: // --------------------------------------------------------------------------
        !          1053: // Method: muteInternalSpeaker
        !          1054: //
        !          1055: // Purpose:
        !          1056: //        if the argument is true mutes the internal speaker, otherwise
        !          1057: //        it "unmutes" it.
        !          1058: 
        !          1059: void
        !          1060: PPCBurgundy::muteInternalSpeaker(bool mute)
        !          1061: {
        !          1062:     UInt32 outputSourceMask = 0;
        !          1063: 
        !          1064:     switch (findHostingHardware(NULL))
        !          1065:     {
        !          1066:         case kMachineTypeSilk:
        !          1067:             // G3-Gossamer DVD-card
        !          1068:             assert(isBordeaux);
        !          1069:             outputSourceMask = kOutputMuteReg_Port17M;
        !          1070:             break;
        !          1071: 
        !          1072:         case kMachineTypeiMac:
        !          1073:               // iMac:  (FIXME as soon as newwolds works I should move this in the newworld handling)
        !          1074:               outputSourceMask = kOutputMuteReg_Port14L | kOutputMuteReg_Port14R;
        !          1075:             break;
        !          1076: 
        !          1077:         case kMachineTypeYosemite:
        !          1078:             outputSourceMask = kOutputMuteReg_Port17M;
        !          1079:             break;
        !          1080: 
        !          1081:         default:
        !          1082:             // FIXME: this may be a newworld, so the registry holds
        !          1083:             // all we need to know about how the burgundy is wired:
        !          1084:             // Add here the code to interpret it.
        !          1085:             break;
        !          1086:     }
        !          1087:  
        !          1088:     if (mute)
        !          1089:         currentOutputMuteReg &= ~outputSourceMask;
        !          1090:     else
        !          1091:         currentOutputMuteReg |= outputSourceMask;
        !          1092: 
        !          1093:     writeCodecReg(ioBaseBurgundy, kOutputMuteReg, currentOutputMuteReg);
        !          1094: }
        !          1095: 
        !          1096: // --------------------------------------------------------------------------
        !          1097: // Method: muteRCAOutput
        !          1098: //
        !          1099: // Purpose:
        !          1100: //        if the argument is true mutes the rear panel RCA, otherwise
        !          1101: //        it "unmutes" it.
        !          1102: void
        !          1103: PPCBurgundy::muteRCAOutput(bool mute)
        !          1104: {
        !          1105:     UInt32 outputSourceMask = 0;
        !          1106: 
        !          1107:     switch (findHostingHardware(NULL))
        !          1108:      {
        !          1109:          case kMachineTypeSilk:
        !          1110:              // G3-Gossamer DVD-card
        !          1111:              assert(isBordeaux);
        !          1112:              outputSourceMask = kOutputMuteReg_Port15L | kOutputMuteReg_Port15R;
        !          1113:              break;
        !          1114: 
        !          1115:          case kMachineTypeYosemite:
        !          1116:              // Yosemite does not have an RCA
        !          1117:              outputSourceMask = 0;
        !          1118:              break;
        !          1119: 
        !          1120:          default:
        !          1121:              // FIXME: this may be a newworld, so the registry holds
        !          1122:              // all we need to know about how the burgundy is wired:
        !          1123:              // Add here the code to interpret it.
        !          1124:              outputSourceMask = 0;
        !          1125:              break;
        !          1126:      }
        !          1127: 
        !          1128:     if (mute)
        !          1129:         currentOutputMuteReg &= ~outputSourceMask;
        !          1130:     else
        !          1131:         currentOutputMuteReg |= outputSourceMask;
        !          1132: 
        !          1133:     writeCodecReg(ioBaseBurgundy, kOutputMuteReg, currentOutputMuteReg);
        !          1134: }
        !          1135: 
        !          1136: // --------------------------------------------------------------------------
        !          1137: // Method: muteHeadphones
        !          1138: //
        !          1139: // Purpose:
        !          1140: //        if the argument is true mutes the rear panel mini jack, otherwise
        !          1141: //        it "unmutes" it.
        !          1142: void
        !          1143: PPCBurgundy::muteHeadphones(bool mute)
        !          1144: {
        !          1145:     UInt32 outputSourceMask = 0;
        !          1146: 
        !          1147:     switch (findHostingHardware(NULL))
        !          1148:       {
        !          1149:           case kMachineTypeSilk:
        !          1150:               // G3-Gossamer DVD-card
        !          1151:               assert(isBordeaux);
        !          1152:               outputSourceMask = kOutputMuteReg_Port16L | kOutputMuteReg_Port16R;
        !          1153:               break;
        !          1154: 
        !          1155:           case kMachineTypeiMac:
        !          1156:               // iMac:  (FIXME I do not know how this is wired, as soon  as I have the iMac motherboard I should fix it)
        !          1157:               outputSourceMask |= kOutputMuteReg_Port15L | kOutputMuteReg_Port15R;
        !          1158:               outputSourceMask |= kOutputMuteReg_Port16L | kOutputMuteReg_Port16R;
        !          1159:               outputSourceMask |= kOutputMuteReg_Port13M | kOutputMuteReg_Port17M;
        !          1160:               break;
        !          1161: 
        !          1162:           case kMachineTypeYosemite:
        !          1163:               // Yosemite:  (FIXME as soon as newwolds works I should move this in the newworld handling)
        !          1164:               outputSourceMask = kOutputMuteReg_Port14L | kOutputMuteReg_Port14R;
        !          1165:               break;
        !          1166: 
        !          1167:           default:
        !          1168:               // FIXME: this may be a newworld, so the registry holds
        !          1169:               // all we need to know about how the burgundy is wired:
        !          1170:               // Add here the code to interpret it.
        !          1171:               break;
        !          1172:       }
        !          1173: 
        !          1174:     if (mute)
        !          1175:         currentOutputMuteReg &= ~outputSourceMask;
        !          1176:     else
        !          1177:         currentOutputMuteReg |= outputSourceMask;
        !          1178: 
        !          1179:     writeCodecReg(ioBaseBurgundy, kOutputMuteReg, currentOutputMuteReg);
        !          1180: }
        !          1181: 
        !          1182: // --------------------------------------------------------------------------
        !          1183: // Method: muteCDLine
        !          1184: //
        !          1185: // Purpose:
        !          1186: //        if the argument is true mutes the line of the cd player
        !          1187: void
        !          1188: PPCBurgundy::muteCDLine(bool mute)
        !          1189: {
        !          1190:     // FIXME: Figure out how this is wired up:
        !          1191: }
        !          1192: 
        !          1193: // --------------------------------------------------------------------------
        !          1194: // Method: setMicInput
        !          1195: //
        !          1196: // Purpose:
        !          1197: //        selects the microphone as input source (if bool = true)
        !          1198: void
        !          1199: PPCBurgundy::setMicInput(bool mic)
        !          1200: {
        !          1201:     UInt32 reg;
        !          1202: 
        !          1203: #ifdef DEBUGMODE
        !          1204:     IOLog( "PPCBurgundy::setMicInput: %s\n", (mic ? "True" : "False"));
        !          1205: #endif
        !          1206: 
        !          1207:     if (mic) {
        !          1208:         reg  = readCodecReg( ioBaseBurgundy, kMux2Reg );
        !          1209:         reg |= kMux2Reg_Mux2L_SelectPort6L | kMux2Reg_Mux2R_SelectPort6R;
        !          1210:         writeCodecReg( ioBaseBurgundy, kMux2Reg, reg );
        !          1211: 
        !          1212:         reg  = readCodecReg( ioBaseBurgundy, kMX3Reg );
        !          1213:         reg |= kMX3Reg_Select_IS2L | kMX3Reg_Select_IS2R;
        !          1214:         writeCodecReg( ioBaseBurgundy, kMX3Reg, reg);
        !          1215: 
        !          1216:         reg  = readCodecReg( ioBaseBurgundy, kOSReg );
        !          1217:         reg |= kOSReg_OSE_Select_MXO3;
        !          1218:         writeCodecReg( ioBaseBurgundy, kOSReg, reg );
        !          1219: 
        !          1220:         reg  = readCodecReg( ioBaseBurgundy, kSDOutReg );
        !          1221:         reg |= kSDOutReg_OSE_To_SF0;
        !          1222:         writeCodecReg( ioBaseBurgundy, kSDOutReg, reg );
        !          1223:     }
        !          1224:     else {
        !          1225:         reg  = readCodecReg( ioBaseBurgundy, kMux2Reg );
        !          1226:         reg &= ~(kMux2Reg_Mux2L_SelectPort6L | kMux2Reg_Mux2R_SelectPort6R);
        !          1227:         writeCodecReg( ioBaseBurgundy, kMux2Reg, reg );
        !          1228: 
        !          1229:         reg  = readCodecReg( ioBaseBurgundy, kMX3Reg );
        !          1230:         reg &= ~(kMX3Reg_Select_IS2L | kMX3Reg_Select_IS2R);
        !          1231:         writeCodecReg( ioBaseBurgundy, kMX3Reg, reg);
        !          1232: 
        !          1233:         reg  = readCodecReg( ioBaseBurgundy, kOSReg );
        !          1234:         reg &= ~kOSReg_OSE_Select_MXO3;
        !          1235:         writeCodecReg( ioBaseBurgundy, kOSReg, reg );
        !          1236: 
        !          1237:         reg  = readCodecReg( ioBaseBurgundy, kSDOutReg );
        !          1238:         reg &= ~kSDOutReg_OSE_To_SF0;
        !          1239:         writeCodecReg( ioBaseBurgundy, kSDOutReg, reg );
        !          1240:    }
        !          1241: }
        !          1242: 
        !          1243: 
        !          1244: // --------------------------------------------------------------------------
        !          1245: // Method: burgundyStatusChanged()
        !          1246: //
        !          1247: // Purpose:
        !          1248: //        returns true if something changed in the status register:.
        !          1249: bool
        !          1250: PPCBurgundy::burgundyStatusChanged()
        !          1251: {
        !          1252:     UInt32 currentStatusRegister = readCodecSenseLines(ioBaseBurgundy);
        !          1253:     bool returnValue = (currentStatusRegister != lastStatusRegister);
        !          1254:     lastStatusRegister = currentStatusRegister;
        !          1255: 
        !          1256:     return (returnValue);
        !          1257: }
        !          1258: 
        !          1259: // --------------------------------------------------------------------------
        !          1260: // Method: headphonesInserted
        !          1261: //
        !          1262: // Purpose:
        !          1263: //        returns true if the headphones are inserted.
        !          1264: bool
        !          1265: PPCBurgundy::headphonesInserted()
        !          1266: {
        !          1267:     UInt32 codecSense;
        !          1268:     UInt32 inputSourceMask = 0;
        !          1269: 
        !          1270:     switch (findHostingHardware(NULL))
        !          1271:       {
        !          1272:           case kMachineTypeSilk:
        !          1273:               // G3-Gossamer DVD-card
        !          1274:               assert(isBordeaux);
        !          1275:               inputSourceMask = kCodecStatusReg_Sense_Headphones;
        !          1276:               break;
        !          1277: 
        !          1278:           case kMachineTypeiMac:
        !          1279:               // iMac:  (FIXME as soon as newwolds works I should move this in the newworld handling)
        !          1280:               inputSourceMask = kCodecStatusReg_Sense_Headphones | kCodecStatusReg_Sense_Headphones2 | kCodecStatusReg_Sense_Bit;
        !          1281:               break;
        !          1282:                
        !          1283:           case kMachineTypeYosemite:
        !          1284:               // Yosemite:  (FIXME as soon as newwolds works I should move this in the newworld handling)
        !          1285:               inputSourceMask = kCodecStatusReg_Sense_Headphones;
        !          1286:               break;
        !          1287: 
        !          1288:           default:
        !          1289:               // FIXME: this may be a newworld, so the registry holds
        !          1290:               // all we need to know about how the burgundy is wired:
        !          1291:               // Add here the code to interpret it.
        !          1292:               break;
        !          1293:       }
        !          1294: 
        !          1295:     codecSense = readCodecSenseLines(ioBaseBurgundy);
        !          1296: 
        !          1297: #ifdef DEBUGMODE
        !          1298:     IOLog( "PPCBurgundy::headphonesInserted = %d\n\r", (codecSense & inputSourceMask) != 0);
        !          1299: #endif
        !          1300: 
        !          1301:     return (codecSense & inputSourceMask) != 0;
        !          1302: }
        !          1303: 
        !          1304: 
        !          1305: // --------------------------------------------------------------------------
        !          1306: // Method: microphoneInserted
        !          1307: //
        !          1308: // Purpose:
        !          1309: //        returns true if the microphone is inserted.
        !          1310: bool
        !          1311: PPCBurgundy::microphoneInserted()
        !          1312: {
        !          1313:     UInt32 codecSense;
        !          1314:     UInt32 inputSourceMask = 0;
        !          1315: 
        !          1316:     switch (findHostingHardware(NULL))
        !          1317:       {
        !          1318:           case kMachineTypeSilk:
        !          1319:               // G3-Gossamer DVD-card
        !          1320:               assert(isBordeaux);
        !          1321:               inputSourceMask = kCodecStatusReg_Sense_Mic;
        !          1322:               break;
        !          1323: 
        !          1324:           case kMachineTypeiMac:
        !          1325:               // iMac:  (FIXME as soon as newwolds works I should move this in the newworld handling)
        !          1326:               inputSourceMask = kCodecStatusReg_Sense_Mic;
        !          1327:               break;
        !          1328: 
        !          1329:           case kMachineTypeYosemite:
        !          1330:               // Yosemite:  (FIXME as soon as newwolds works I should move this in the newworld handling)
        !          1331:               inputSourceMask = kCodecStatusReg_Sense_Mic;
        !          1332:               break;
        !          1333: 
        !          1334:           default:
        !          1335:               // FIXME: this may be a newworld, so the registry holds
        !          1336:               // all we need to know about how the burgundy is wired:
        !          1337:               // Add here the code to interpret it.
        !          1338:               break;
        !          1339:       }
        !          1340: 
        !          1341:     codecSense = readCodecSenseLines(ioBaseBurgundy);
        !          1342: 
        !          1343: #ifdef DEBUGMODE
        !          1344:     IOLog( "PPCBurgundy::microphoneInserted = %d\n\r", (codecSense & inputSourceMask) != 0);
        !          1345: #endif
        !          1346: 
        !          1347:     // FIXME: This should not be necessary, but since it does not work by default
        !          1348:     // I'll add this call myself:
        !          1349:     setMicInput((codecSense & inputSourceMask) != 0);
        !          1350:     
        !          1351:     return (codecSense & inputSourceMask) != 0;
        !          1352: }
        !          1353: 
        !          1354: // --------------------------------------------------------------------------
        !          1355: // Method: scaleVolume
        !          1356: //
        !          1357: // Purpose:
        !          1358: //        Scale the volume to the range used by burgundy:
        !          1359: //        note, this considers that the volume can range from
        !          1360: //        0 to 65536 as in the control strings above (e.g. componentDictionaryMixerIn)
        !          1361: UInt8
        !          1362: PPCBurgundy::scaleVolume(int vol)
        !          1363: {
        !          1364:     int output;
        !          1365: 
        !          1366:     output  = vol / 4096;
        !          1367:     
        !          1368:     if ( output  > 15 )
        !          1369:         output  = 15;
        !          1370: 
        !          1371:     if (output  < 0 )
        !          1372:         output  = 0;
        !          1373: 
        !          1374: #ifdef DEBUGMODE
        !          1375:     IOLog("Volume input: %d, output (scaled) %d\n", vol, output);
        !          1376: #endif
        !          1377: 
        !          1378:     return (UInt8)output;
        !          1379: }
        !          1380: 
        !          1381: // --------------------------------------------------------------------------
        !          1382: // Method: volumeHeadphonesLeft & volumeHeadphonesRight
        !          1383: //
        !          1384: // Purpose:
        !          1385: //        sets the volume for the left and right channel of the internal
        !          1386: //        headphones.
        !          1387: void
        !          1388: PPCBurgundy::volumeHeadphonesLeft(int vol)
        !          1389: {
        !          1390:     // FIXME: This sets all the output volumes, but we may wish to have
        !          1391:     // a more discriminating volume handling. As soon as I know for sure
        !          1392:     // how burgundy is wired we can do it. For now this should be fine.
        !          1393:     volumeAllLeft(vol);
        !          1394: }
        !          1395: 
        !          1396: void
        !          1397: PPCBurgundy::volumeHeadphonesRight(int vol)
        !          1398: {
        !          1399:     // FIXME: This sets all the output volumes, but we may wish to have
        !          1400:     // a more discriminating volume handling. As soon as I know for sure
        !          1401:     // how burgundy is wired we can do it. For now this should be fine.
        !          1402:     volumeAllRight(vol);
        !          1403: }
        !          1404: 
        !          1405: // --------------------------------------------------------------------------
        !          1406: // Method: volumeInternalSpeakerLeft & volumeInternalSpeakerRight
        !          1407: //
        !          1408: // Purpose:
        !          1409: //        sets the volume for the left and right channel of the internal
        !          1410: //        speaker.
        !          1411: void
        !          1412: PPCBurgundy::volumeInternalSpeakerLeft(int vol)
        !          1413: {
        !          1414:     // FIXME: This sets all the output volumes, but we may wish to have
        !          1415:     // a more discriminating volume handling. As soon as I know for sure
        !          1416:     // how burgundy is wired we can do it. For now this should be fine.
        !          1417:     volumeAllLeft(vol);
        !          1418: }
        !          1419: 
        !          1420: void
        !          1421: PPCBurgundy::volumeInternalSpeakerRight(int vol)
        !          1422: {
        !          1423:     // FIXME: This sets all the output volumes, but we may wish to have
        !          1424:     // a more discriminating volume handling. As soon as I know for sure
        !          1425:     // how burgundy is wired we can do it. For now this should be fine.
        !          1426:     volumeAllRight(vol);
        !          1427: }
        !          1428: 
        !          1429: // --------------------------------------------------------------------------
        !          1430: // Method: volumeCDLineLeft & volumeCDLineRight
        !          1431: //
        !          1432: // Purpose:
        !          1433: //        sets the volume for the left and right channel of the CD
        !          1434: //        line.
        !          1435: void
        !          1436: PPCBurgundy::volumeCDLineLeft(int vol)
        !          1437: {
        !          1438:     // FIXME: This sets all the output volumes, but we may wish to have
        !          1439:     // a more discriminating volume handling. As soon as I know for sure
        !          1440:     // how burgundy is wired we can do it. For now this should be fine.
        !          1441:     volumeAllLeft(vol);
        !          1442: }
        !          1443: 
        !          1444: void
        !          1445: PPCBurgundy::volumeCDLineRight(int vol)
        !          1446: {
        !          1447:     // FIXME: This sets all the output volumes, but we may wish to have
        !          1448:     // a more discriminating volume handling. As soon as I know for sure
        !          1449:     // how burgundy is wired we can do it. For now this should be fine.
        !          1450:     volumeAllRight(vol);
        !          1451: }
        !          1452: 
        !          1453: // --------------------------------------------------------------------------
        !          1454: // Method: volumeRCAOutputLeft & volumeRCAOutputRight
        !          1455: //
        !          1456: // Purpose:
        !          1457: //        sets the volume for the left and right channel of the RCA
        !          1458: //        line.
        !          1459: void
        !          1460: PPCBurgundy::volumeRCAOutputLeft(int vol)
        !          1461: {
        !          1462:     // FIXME: This sets all the output volumes, but we may wish to have
        !          1463:     // a more discriminating volume handling. As soon as I know for sure
        !          1464:     // how burgundy is wired we can do it. For now this should be fine.
        !          1465:     volumeAllLeft(vol);
        !          1466: }
        !          1467: 
        !          1468: void
        !          1469: PPCBurgundy::volumeRCAOutputRight(int vol)
        !          1470: {
        !          1471:     // FIXME: This sets all the output volumes, but we may wish to have
        !          1472:     // a more discriminating volume handling. As soon as I know for sure
        !          1473:     // how burgundy is wired we can do it. For now this should be fine.
        !          1474:     volumeAllRight(vol);
        !          1475: }
        !          1476: 
        !          1477: // --------------------------------------------------------------------------
        !          1478: // Method: volumeAllRight & volumeAllLeft
        !          1479: //
        !          1480: // Purpose:
        !          1481: //        sets the volume to all the output ports. This is because I do not
        !          1482: //        really know how burgundy is wired up. (and because however the
        !          1483: //        OS has only one control for the volume).
        !          1484: void
        !          1485: PPCBurgundy::volumeAllLeft(int vol)
        !          1486: {
        !          1487:     UInt8 newVol = scaleVolume(vol);
        !          1488: 
        !          1489:     // This changes all the digital volume controls (used only to mute and unmute the oputput)
        !          1490:     if (newVol > 0) {
        !          1491:         writeCodecReg( ioBaseBurgundy, kGAP0LReg, 0xFF);
        !          1492:         writeCodecReg( ioBaseBurgundy, kGAP1LReg, 0xFF);
        !          1493:         writeCodecReg( ioBaseBurgundy, kGAP2LReg, 0xFF);
        !          1494:         writeCodecReg( ioBaseBurgundy, kGAP3LReg, 0xFF);        
        !          1495:     }
        !          1496:     else {
        !          1497:         writeCodecReg( ioBaseBurgundy, kGAP0LReg, 0x00);
        !          1498:         writeCodecReg( ioBaseBurgundy, kGAP1LReg, 0x00);
        !          1499:         writeCodecReg( ioBaseBurgundy, kGAP2LReg, 0x00);
        !          1500:         writeCodecReg( ioBaseBurgundy, kGAP3LReg, 0x00);        
        !          1501:     }
        !          1502:     
        !          1503:     // while this acts on the analog volume controls
        !          1504:     newVol = 15 - newVol;
        !          1505:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort13Reg, (readCodecReg(ioBaseBurgundy, kOutputLvlPort13Reg) & 0xF0) | (newVol & 0x0F));
        !          1506:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort14Reg, (readCodecReg(ioBaseBurgundy, kOutputLvlPort14Reg) & 0xF0) | (newVol & 0x0F));
        !          1507:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort15Reg, (readCodecReg(ioBaseBurgundy, kOutputLvlPort15Reg) & 0xF0) | (newVol & 0x0F));
        !          1508:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort16Reg, (readCodecReg(ioBaseBurgundy, kOutputLvlPort16Reg) & 0xF0) | (newVol & 0x0F));
        !          1509:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort17Reg, (readCodecReg(ioBaseBurgundy, kOutputLvlPort17Reg) & 0xF0) | (newVol & 0x0F));
        !          1510: }
        !          1511: 
        !          1512: void
        !          1513: PPCBurgundy::volumeAllRight(int vol)
        !          1514: {
        !          1515:     UInt8 newVol = scaleVolume(vol);
        !          1516: 
        !          1517:     // This changes all the digital volume controls (used only to mute and unmute the oputput)
        !          1518:     if (newVol > 0) {
        !          1519:         writeCodecReg( ioBaseBurgundy, kGAP0RReg, 0xFF);
        !          1520:         writeCodecReg( ioBaseBurgundy, kGAP1RReg, 0xFF);
        !          1521:         writeCodecReg( ioBaseBurgundy, kGAP2RReg, 0xFF);
        !          1522:         writeCodecReg( ioBaseBurgundy, kGAP3RReg, 0xFF);
        !          1523:     }
        !          1524:     else {
        !          1525:         writeCodecReg( ioBaseBurgundy, kGAP0RReg, 0x00);
        !          1526:         writeCodecReg( ioBaseBurgundy, kGAP1RReg, 0x00);
        !          1527:         writeCodecReg( ioBaseBurgundy, kGAP2RReg, 0x00);
        !          1528:         writeCodecReg( ioBaseBurgundy, kGAP3RReg, 0x00);
        !          1529:     }
        !          1530: 
        !          1531:     // while this acts on the analog volume controls
        !          1532:     newVol = (15 - newVol) << 4;
        !          1533:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort13Reg, (readCodecReg(ioBaseBurgundy, kOutputLvlPort13Reg) & 0x0F) | (newVol & 0xF0));
        !          1534:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort14Reg, (readCodecReg(ioBaseBurgundy, kOutputLvlPort14Reg) & 0x0F) | (newVol & 0xF0));
        !          1535:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort15Reg, (readCodecReg(ioBaseBurgundy, kOutputLvlPort15Reg) & 0x0F) | (newVol & 0xF0));
        !          1536:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort16Reg, (readCodecReg(ioBaseBurgundy, kOutputLvlPort16Reg) & 0x0F) | (newVol & 0xF0));
        !          1537:     writeCodecReg( ioBaseBurgundy, kOutputLvlPort17Reg, (readCodecReg(ioBaseBurgundy, kOutputLvlPort17Reg) & 0x0F) | (newVol & 0xF0)); 
        !          1538: }
        !          1539: 
        !          1540: 
        !          1541: // --------------------------------------------------------------------------
        !          1542: // Method: volumeMixerInLeft
        !          1543: //
        !          1544: // Purpose:
        !          1545: //        sets the gain for the input left line
        !          1546: void
        !          1547: PPCBurgundy::volumeMixerInLeft(int vol)
        !          1548: {
        !          1549:     UInt8 left = scaleVolume(vol);
        !          1550:     
        !          1551:     writeCodecReg( ioBaseBurgundy, kVGA2Reg,   0x44 );
        !          1552:     writeCodecReg( ioBaseBurgundy, kGAS2LReg,  left );
        !          1553: }
        !          1554: 
        !          1555: // --------------------------------------------------------------------------
        !          1556: // Method: volumeMixerInRight
        !          1557: //
        !          1558: // Purpose:
        !          1559: //        sets the gain for the input right line
        !          1560: void
        !          1561: PPCBurgundy::volumeMixerInRight(int vol)
        !          1562: {
        !          1563:     UInt8 right = scaleVolume(vol);
        !          1564: 
        !          1565:     writeCodecReg( ioBaseBurgundy, kVGA2Reg,   0x44 );
        !          1566:     writeCodecReg( ioBaseBurgundy, kGAS2RReg,  right );
        !          1567: }
        !          1568: 
        !          1569: 
        !          1570: /* =============================================================
        !          1571:  * VERY Private Methods used to access to the burgundy registers
        !          1572:  * ============================================================= */
        !          1573: 
        !          1574: static void
        !          1575: writeCodecReg( volatile UInt8 *ioBaseBurgundy, int regInfo, int value )
        !          1576: {
        !          1577:   u_int32_t            regBits;
        !          1578:   u_int32_t            regValue;
        !          1579:   u_int32_t            i;
        !          1580:   volatile u_int32_t   CodecControlReg;
        !          1581: 
        !          1582:   struct _reg
        !          1583:   {
        !          1584:       UInt8    unused0;
        !          1585:       UInt8  size;
        !          1586:       UInt8  addr;
        !          1587:       UInt8  offset;
        !          1588:   } *reg = (struct _reg *)&regInfo;
        !          1589: 
        !          1590: 
        !          1591:   regBits =   (kCodecCtlReg_Write | kCodecCtlReg_Reset)
        !          1592:             | ((u_int32_t) reg->addr                    * kCodecCtlReg_Addr_Bit)
        !          1593:             | ((u_int32_t)(reg->size + reg->offset - 1) * kCodecCtlReg_LastByte_Bit);
        !          1594: 
        !          1595:   for ( i=0; i < reg->size; i++ )
        !          1596:   {
        !          1597:       regValue = regBits | ((u_int32_t)(reg->offset + i) * kCodecCtlReg_CurrentByte_Bit) | (value & 0xFF);
        !          1598:       OSWriteLittleInt32(ioBaseBurgundy, kCodecCtlReg, regValue );
        !          1599:       eieio();
        !          1600: 
        !          1601: #ifdef DEBUGMODE
        !          1602:       IOLog( "PPCSound(burgundy): CodecWrite = %08x\n\r", regValue );
        !          1603: #endif
        !          1604: 
        !          1605:       value >>= 8;
        !          1606: 
        !          1607:       regBits &= ~kCodecCtlReg_Reset;
        !          1608: 
        !          1609:       do
        !          1610:       {
        !          1611:           CodecControlReg =  OSReadLittleInt32( ioBaseBurgundy, kCodecCtlReg  );
        !          1612:           eieio();
        !          1613:       }
        !          1614:       while ( CodecControlReg & kCodecCtlReg_Busy );
        !          1615:   }
        !          1616: }
        !          1617: 
        !          1618: 
        !          1619: static int
        !          1620: readCodecReg( volatile UInt8 *ioBaseBurgundy, int regInfo )
        !          1621: {
        !          1622:   u_int32_t            regBits;
        !          1623:   u_int32_t            regValue = 0;
        !          1624:   u_int32_t            i,j;
        !          1625:   int                  value;
        !          1626:   u_int32_t            byteCounter;
        !          1627:   u_int32_t            currentCounter;
        !          1628:   volatile u_int32_t   CodecControlReg;
        !          1629:   volatile u_int32_t   CodecStatusReg;
        !          1630: 
        !          1631: 
        !          1632:   struct _reg
        !          1633:   {
        !          1634:       UInt8    unused0;
        !          1635:       UInt8  size;
        !          1636:       UInt8  addr;
        !          1637:       UInt8  offset;
        !          1638:   } *reg = (struct _reg *)&regInfo;
        !          1639: 
        !          1640:   value   = 0;
        !          1641: 
        !          1642:   regBits =   (kCodecCtlReg_Reset)
        !          1643:             | ((u_int32_t) reg->addr                    * kCodecCtlReg_Addr_Bit)
        !          1644:             | ((u_int32_t)(reg->size + reg->offset - 1) * kCodecCtlReg_LastByte_Bit);
        !          1645: 
        !          1646:   CodecStatusReg =  OSReadLittleInt32( ioBaseBurgundy, kCodecStatusReg  );
        !          1647:   eieio();
        !          1648:   byteCounter = ((CodecStatusReg & kCodecStatusReg_ByteCounter_Mask) / kCodecStatusReg_ByteCounter_Bit + 1) & 0x03;
        !          1649: 
        !          1650:   for ( i=0; i < reg->size; i++ )
        !          1651:   {
        !          1652:       regValue = regBits | ((u_int32_t)(reg->offset + i) * kCodecCtlReg_CurrentByte_Bit);
        !          1653:       OSWriteLittleInt32(ioBaseBurgundy, kCodecCtlReg, regValue );
        !          1654:       eieio();
        !          1655:       regBits &= ~kCodecCtlReg_Reset;
        !          1656: 
        !          1657:       do
        !          1658:       {
        !          1659:           CodecControlReg =  OSReadLittleInt32( ioBaseBurgundy, kCodecCtlReg  );
        !          1660:           eieio();
        !          1661:       }
        !          1662:       while ( CodecControlReg & kCodecCtlReg_Busy );
        !          1663: 
        !          1664:       j=0;
        !          1665:       do
        !          1666:       {
        !          1667:           CodecStatusReg =  OSReadLittleInt32( ioBaseBurgundy, kCodecStatusReg  );
        !          1668:           eieio();
        !          1669:           currentCounter = ((CodecStatusReg & kCodecStatusReg_ByteCounter_Mask) / kCodecStatusReg_ByteCounter_Bit) & 0x03;
        !          1670:       }
        !          1671:       while ( (byteCounter != currentCounter) && (j++ < 1000));
        !          1672: 
        !          1673:       byteCounter++;
        !          1674: 
        !          1675:       IODelay(10);
        !          1676:       CodecStatusReg =  OSReadLittleInt32( ioBaseBurgundy, kCodecStatusReg  );
        !          1677: 
        !          1678:       value |= ((CodecStatusReg & kCodecStatusReg_Data_Mask) / kCodecStatusReg_Data_Bit) << 8*i;
        !          1679:   }
        !          1680: 
        !          1681: #ifdef DEBUGMODE
        !          1682:       IOLog( "PPCSound(burgundy): CodecRead = %08x %08x\n\r", regValue, value );
        !          1683: #endif
        !          1684: 
        !          1685:   return value;
        !          1686: }
        !          1687: 
        !          1688: static int
        !          1689: readCodecSenseLines( volatile UInt8 *ioBaseBurgundy )
        !          1690: {
        !          1691:     return ((OSReadLittleInt32( ioBaseBurgundy, kCodecStatusReg  ) / kCodecStatusReg_Sense_Bit) & kCodecStatusReg_Sense_Mask);
        !          1692: }
        !          1693: 
        !          1694: 
        !          1695: static void
        !          1696: writeSoundControlReg( volatile UInt8 *ioBaseBurgundy, int value )
        !          1697: {
        !          1698: 
        !          1699: #ifdef DEBUGMODE
        !          1700:       IOLog( "PPCSound(burgundy): SoundControlReg = %08x\n", value);
        !          1701: #endif
        !          1702: 
        !          1703:   OSWriteLittleInt32( ioBaseBurgundy, kSoundCtlReg, value );
        !          1704:   eieio();
        !          1705: }  
        !          1706: 
        !          1707: 
        !          1708: 
        !          1709:  

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.