Annotation of XNU/iokit/Drivers/audio/drvPPCBurgundy/PPCBurgundy.cpp, revision 1.1.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.