Annotation of XNU/iokit/Families/IOAudio/IOAudioParts.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved. 
                     24:  *
                     25:  * IOAudioDevice.cpp
                     26:  *
                     27:  * HISTORY
                     28:  *
                     29:  */
                     30: 
                     31: #include <IOKit/assert.h>
                     32: 
                     33: #include <IOKit/IOLib.h>
                     34: #include <IOKit/IOSyncer.h>
                     35: #include <IOKit/IOWorkLoop.h>
                     36: #include <IOKit/IOCommandQueue.h>
                     37: #include <IOKit/IOMemoryDescriptor.h>
                     38: #include <IOKit/audio/IOAudioController.h>
                     39: 
                     40: //************************************************************************
                     41: // Implementation of protocol classes.
                     42: //************************************************************************
                     43: OSDefineMetaClass(  IOAudioStream, IOUserClient )
                     44: OSDefineAbstractStructors(  IOAudioStream, IOUserClient )
                     45: 
                     46: OSDefineMetaClass(  IOAudioComponent, IOUserClient )
                     47: OSDefineAbstractStructors(  IOAudioComponent, IOUserClient )
                     48: 
                     49: //************************************************************************
                     50: // Begin implementation of IOAudioStreamImpl class.
                     51: //************************************************************************
                     52: 
                     53: #undef super
                     54: #define super IOAudioStream
                     55: OSDefineMetaClassAndStructors( IOAudioStreamImpl, IOAudioStream )
                     56: 
                     57: bool
                     58: IOAudioStreamImpl::initWithPropsIndexQueue(OSDictionary *props,
                     59:         AudioStreamIndex index, IOCommandQueue *queue)
                     60: {
                     61:     if(!super::init(props))
                     62:         return false;
                     63: 
                     64:     if(!queue)
                     65:         return false;
                     66: 
                     67:     fIndex = index;
                     68:     fCmdQueue = queue;
                     69: 
                     70:     fMappedMem.fMixBuffer = NULL;
                     71: 
                     72:     // make sure essential stuff is there
                     73:     assert(OSDynamicCast(OSNumber, getProperty("In")) != NULL);
                     74:     assert(OSDynamicCast(OSNumber, getProperty("Out")) != NULL);
                     75: 
                     76:     fMethods[kCallSetFlow].object = this;
                     77:     fMethods[kCallSetFlow].func = (IOMethod) &IOAudioStream::setFlow;
                     78:     fMethods[kCallSetFlow].count0 = 1;
                     79:     fMethods[kCallSetFlow].count1 = 0;
                     80:     fMethods[kCallSetFlow].flags = kIOUCScalarIScalarO;
                     81: 
                     82:     fMethods[kCallFlush].object = this;
                     83:     fMethods[kCallFlush].func = (IOMethod) &IOAudioStream::Flush;
                     84:     fMethods[kCallFlush].count0 = sizeof(IOAudioStreamPosition);
                     85:     fMethods[kCallFlush].count1 = 0;
                     86:     fMethods[kCallFlush].flags = kIOUCStructIStructO;
                     87: 
                     88:     fMethods[kCallSetErase].object = this;
                     89:     fMethods[kCallSetErase].func = (IOMethod) &IOAudioStream::setErase;
                     90:     fMethods[kCallSetErase].count0 = 1;
                     91:     fMethods[kCallSetErase].count1 = 1;
                     92:     fMethods[kCallSetErase].flags = kIOUCScalarIScalarO;
                     93: 
                     94:     return true;
                     95: }
                     96: 
                     97: void IOAudioStreamImpl::free()
                     98: {
                     99:     if (fMappedMem.fMixBuffer) {
                    100:         // Need to free mix buffer here - it will leak now
                    101:     }
                    102: 
                    103:     super::free();
                    104: }
                    105: 
                    106: /*
                    107:  * Connect a client, possibly starting DMA for the stream if it's
                    108:  * the first client.
                    109:  */
                    110: IOReturn
                    111: IOAudioStreamImpl::newUserClient( task_t owningTask, void * security_id,
                    112:                                        UInt32 type, IOUserClient ** handler )
                    113: {
                    114:     IOSyncer *syncWakeup;
                    115: 
                    116:     *handler = this;
                    117:     (*handler)->retain();
                    118: 
                    119:     syncWakeup = IOSyncer::create();
                    120: 
                    121:     fCmdQueue->enqueueCommand(true, syncWakeup, (void *)kConnect,
                    122:                                                (void *)fIndex, &fMappedMem);
                    123: 
                    124:     syncWakeup->wait();
                    125: 
                    126:     return kIOReturnSuccess;
                    127: }
                    128: 
                    129: IOReturn IOAudioStreamImpl::clientDied()
                    130: {
                    131:     /*
                    132:      * Decrememt connection count, possibly freeing DMA buffers
                    133:      */
                    134:     fCmdQueue->enqueueCommand(true, 0, (void *)kDetach, (void *)fIndex);
                    135: 
                    136:     return kIOReturnSuccess;
                    137: }
                    138: 
                    139: IOReturn IOAudioStreamImpl::clientClose()
                    140: {
                    141:     /*
                    142:      * Decrememt connection count, possibly freeing DMA buffers
                    143:      */
                    144:     //fCmdQueue->enqueueCommand(true, 0, (void *)kDetach, (void *)fIndex);
                    145: 
                    146:     return kIOReturnSuccess;
                    147: }
                    148: 
                    149: IOReturn IOAudioStreamImpl::Flush(IOAudioStreamPosition *end)
                    150: {
                    151: // Tell device when it'll be safe to stop the stream
                    152:     fCmdQueue->enqueueCommand(true, 0, (void *)kFlush, (void *)fIndex, (void *)end);
                    153:     return kIOReturnSuccess;
                    154: }
                    155: 
                    156: IOReturn IOAudioStreamImpl::setFlow(bool flowing)
                    157: {
                    158:     fCmdQueue->enqueueCommand(true, 0, (void *)kSetFlow, (void *)fIndex,
                    159:                                                        (void *)flowing);
                    160:     return kIOReturnSuccess;
                    161: }
                    162: 
                    163: IOReturn IOAudioStreamImpl::isOutput(SInt32 *res) const
                    164: {
                    165:     const OSNumber *obj;
                    166:     obj = getOutputDescriptor();
                    167:     if(obj)
                    168:         *res = obj->unsigned8BitValue();
                    169:     else
                    170:         *res = 0;
                    171: 
                    172:     return kIOReturnSuccess;
                    173: }
                    174: 
                    175: IOReturn IOAudioStreamImpl::getMixBuffer(void **mixBuffer)
                    176: {
                    177:     *mixBuffer = fMappedMem.fMixBuffer;
                    178: 
                    179:     return kIOReturnSuccess;
                    180: }
                    181: 
                    182: IOReturn IOAudioStreamImpl::setErase(bool erase, SInt32 *oldErase)
                    183: {
                    184:     assert(fMappedMem.fStatus != NULL); // Must be a user attached.
                    185:     *oldErase = fMappedMem.fStatus->fErases;
                    186:     fMappedMem.fStatus->fErases = erase;
                    187:     return kIOReturnSuccess;
                    188: }
                    189: 
                    190: IOReturn
                    191: IOAudioStreamImpl::setProperties( OSObject * properties )
                    192: {
                    193:     return kIOReturnNotPrivileged;
                    194: }
                    195: 
                    196: 
                    197: IOReturn IOAudioStreamImpl::clientMemoryForType( UInt32 type,
                    198:     UInt32 * flags, IOMemoryDescriptor ** memory )
                    199: {
                    200: //    kprintf("IOAudioStream::clientMemoryForType(%d, %d, %d, %d)\n",
                    201: //        type, flags, address, size);
                    202: 
                    203:     switch(type) {
                    204:         case kSampleBuffer:
                    205:            *memory = IOMemoryDescriptor::withAddress(
                    206:                                     (void *)fMappedMem.fSampleBuffer,
                    207:                                     fMappedMem.fStatus->fBufSize,
                    208:                                    kIODirectionNone);
                    209:             *flags = 0;
                    210:         break;
                    211:         case kStatus:
                    212:            *memory = IOMemoryDescriptor::withAddress(
                    213:                                     (void *)fMappedMem.fStatus,
                    214:                                     sizeof(IOAudioStreamStatus),
                    215:                                    kIODirectionNone);
                    216:             *flags = kIOMapReadOnly;
                    217:         break;
                    218:         case kMixBuffer:
                    219:             if (fMappedMem.fMixBuffer == NULL) {
                    220:                 IOSyncer *syncWakeup;
                    221: 
                    222:                 syncWakeup = IOSyncer::create();
                    223: 
                    224:                 fCmdQueue->enqueueCommand(true, syncWakeup, (void *)kAllocMixBuffer,
                    225:                                           (void *)fIndex, (void *)&fMappedMem.fMixBuffer);
                    226:                 syncWakeup->wait();
                    227:             }
                    228:             fMappedMem.fStatus->fMixBufferInUse = true;
                    229:             *memory = IOMemoryDescriptor::withAddress(
                    230:                                     (void *)fMappedMem.fMixBuffer,
                    231:                                     (fMappedMem.fStatus->fBufSize / fMappedMem.fStatus->fSampleSize * sizeof(float)),
                    232:                                     kIODirectionNone);
                    233:             *flags = 0;
                    234:         break;
                    235:         default:
                    236:             return kIOReturnUnsupported;
                    237:         break;
                    238:     }
                    239:     return kIOReturnSuccess;
                    240: }
                    241: 
                    242: IOExternalMethod *
                    243: IOAudioStreamImpl::getExternalMethodForIndex( UInt32 index )
                    244: {
                    245:     IOExternalMethod *method = NULL;
                    246: 
                    247:     if(index < kNumCalls)
                    248:         method = &fMethods[index];
                    249:     return method;
                    250: }
                    251: 
                    252: 
                    253: //************************************************************************
                    254: // Begin implementation of IOAudioComponentImpl class.
                    255: //************************************************************************
                    256: 
                    257: #undef super
                    258: #define super IOAudioComponent
                    259: OSDefineMetaClassAndStructors( IOAudioComponentImpl, IOAudioComponent )
                    260: 
                    261: 
                    262: bool
                    263: IOAudioComponentImpl::initWithStuff(IOAudioController *owner, OSDictionary *props,
                    264:                                                IOCommandQueue *queue)
                    265: {
                    266:     if(!super::init(props))
                    267:         return false;
                    268: 
                    269:     if(!queue || !owner)
                    270:         return false;
                    271: 
                    272:     fCmdQueue = queue;
                    273:     fOwner = owner;
                    274:     return true;
                    275: }
                    276: 
                    277: void
                    278: IOAudioComponentImpl::free()
                    279: {
                    280:     if(fNotifyMsg)
                    281:         IOFree(fNotifyMsg, sizeof (struct _notifyMsg));
                    282: 
                    283:     super::free();
                    284: }
                    285: 
                    286: IOReturn
                    287: IOAudioComponentImpl::updateVal(UInt32 val, OSDictionary *control, bool direct)
                    288: {
                    289:     IOReturn ret = kIOReturnSuccess;
                    290:     OSNumber * oldVal;
                    291: 
                    292:     oldVal = (OSNumber *)control->getObject(IOAudioController::gValSym);
                    293:     if(val != oldVal->unsigned32BitValue()) {
                    294:         OSNumber * id;
                    295:         OSNumber * newVal;
                    296:         newVal = OSNumber::withNumber(val, oldVal->numberOfBits());
                    297:         control->setObject(IOAudioController::gValSym, newVal);
                    298:         id = (OSNumber *)control->getObject(IOAudioController::gIdSym);
                    299:         if(id) {
                    300:             if(direct)
                    301:                 fOwner->SetControl(id->unsigned16BitValue(), val);
                    302:             else
                    303:                 fCmdQueue->enqueueCommand(true, 0, (void *)kSetVal,
                    304:                     (void *)id->unsigned16BitValue(), (void *)val);
                    305: 
                    306:         }
                    307:     }
                    308:     return ret;
                    309: }
                    310: 
                    311: void
                    312: IOAudioComponentImpl::Set(const OSSymbol *type, const OSSymbol *name, int val)
                    313: {
                    314:     OSDictionary *controls;
                    315: 
                    316:     controls = OSDynamicCast(OSDictionary, getProperty(type));
                    317: 
                    318:     if(controls) {
                    319:         OSDictionary *valDict;
                    320:         OSNumber * old;
                    321:         OSNumber * newObj;
                    322:         valDict = OSDynamicCast(OSDictionary,
                    323:                                        controls->getObject(name));
                    324:        if(valDict) {
                    325:             old = OSDynamicCast(OSNumber, valDict->getObject(IOAudioController::gValSym));
                    326:             if(old) {
                    327:                 newObj = OSNumber::withNumber(val, old->numberOfBits());
                    328:                 valDict->setObject(IOAudioController::gValSym, newObj);
                    329:                 newObj->release(); // XXX -- svail: added.
                    330:                 /* FIXME: Don't block */
                    331:                 if(fNotifyMsg)
                    332:                     mach_msg_send_from_kernel((mach_msg_header_t *)fNotifyMsg,
                    333:                                                             fNotifyMsg->h.msgh_size);
                    334:                 else if(type == IOAudioController::gInputsSym &&
                    335:                         name == IOAudioController::gJackSym &&
                    336:                         ( GetType() == IOAudioController::gHeadphonesSym ||
                    337:                          GetType() == IOAudioController::gLineOutSym)) {
                    338:                     /*
                    339:                      * This is a headphone or line out jack, mute/unmute any speakers
                    340:                      * with the same IOAudio parent
                    341:                      */
                    342:                     OSIterator * parents =
                    343:                         getParentIterator(IOAudioController::gIOAudioPlane);
                    344:                     IORegistryEntry *parent;
                    345:                     while((parent = OSDynamicCast(IORegistryEntry, parents->getNextObject()))) {
                    346:                         OSIterator * siblings =
                    347:                             parent->getChildIterator(IOAudioController::gIOAudioPlane);
                    348:                         IOAudioComponentImpl *sibling;
                    349:                         while((sibling = OSDynamicCast(IOAudioComponentImpl, siblings->getNextObject()))) {
                    350:                             if(sibling->GetType() == IOAudioController::gSpeakerSym) {
                    351:                                 // Set all controls of type Mute to the new value
                    352:                                 OSDictionary *spkrCtls =
                    353:                                     OSDynamicCast(OSDictionary, sibling->getProperty(IOAudioController::gControlsSym));
                    354:                                 OSCollectionIterator *iter = OSCollectionIterator::withCollection(spkrCtls);
                    355:                                 OSSymbol *iterKey;
                    356:                                 while((iterKey = OSDynamicCast(OSSymbol, iter->getNextObject()))){
                    357:                                     OSObject *spkrCtlObj = spkrCtls->getObject(iterKey);
                    358:                                     if(GetType(spkrCtlObj) == IOAudioController::gMuteSym) {
                    359:                                         // Safe to just cast because GetType checks object type.
                    360:                                         // Update hardware directly
                    361:                                         updateVal(val, (OSDictionary *)spkrCtlObj, true);
                    362:                                     }
                    363:                                 }
                    364:                             }
                    365:                         }
                    366:                     }                        
                    367:                }
                    368:             }
                    369:        }
                    370:     }
                    371: }
                    372: 
                    373: IOReturn IOAudioComponentImpl::clientClose( void )
                    374: {
                    375:     return kIOReturnSuccess;
                    376: }
                    377: 
                    378: IOReturn IOAudioComponentImpl::clientDied( void )
                    379: {
                    380:     return kIOReturnSuccess;
                    381: }
                    382: /*
                    383:  * Return a subclass of IOUserClient for User<->kernel comminication
                    384:  * Since IOAudioStream is such a suclass, we can return the object
                    385:  * itself (remembering to increment its retain count!).
                    386:  */
                    387: IOReturn IOAudioComponentImpl::newUserClient( task_t owningTask,
                    388:                 void * security_id, UInt32 type, IOUserClient ** handler )
                    389: {
                    390: //kprintf("task:%d, sec_id:0x%x, type:%d\n", owningTask, security_id, type);
                    391:     *handler = this;
                    392:     (*handler)->retain();
                    393: 
                    394:     return kIOReturnSuccess;
                    395: }
                    396: 
                    397: 
                    398: IOReturn
                    399: IOAudioComponentImpl::setProperties( OSObject * properties )
                    400: {
                    401:     OSDictionary *myControls;
                    402:     OSDictionary *newControls;
                    403:     OSDictionary *newDict;
                    404:     OSCollectionIterator *iter;
                    405:     OSObject *iterKey;
                    406:     IOReturn ret = kIOReturnSuccess;
                    407: 
                    408:     newDict = OSDynamicCast(OSDictionary, properties);
                    409:     if(!newDict)
                    410:         return kIOReturnBadArgument;
                    411: 
                    412:     myControls = OSDynamicCast(OSDictionary, getProperty(IOAudioController::gControlsSym));
                    413:     newControls = OSDynamicCast(OSDictionary, newDict->getObject(IOAudioController::gControlsSym));
                    414:     if(!newControls)
                    415:         return kIOReturnBadArgument;
                    416: 
                    417:     /*
                    418:      * Look through the Controls dictionary, for each one that has a new Val
                    419:      * make a kSetVal command, updating the hardware.
                    420:      */
                    421:     iter = OSCollectionIterator::withCollection(newControls);
                    422:     while((iterKey = iter->getNextObject())) {
                    423:         OSSymbol *key = OSDynamicCast(OSSymbol, iterKey);
                    424:         OSDictionary *newCtrl;
                    425:         OSNumber* newVal;
                    426:         if(!key) {
                    427:             ret = kIOReturnBadArgument;
                    428:             break;
                    429:         }
                    430:         OSDictionary *myCtrl;
                    431:         myCtrl = (OSDictionary *)myControls->getObject(key);
                    432:         if(!myCtrl) {
                    433:             ret = kIOReturnBadArgument;
                    434:             break;
                    435:         }
                    436:         newCtrl = OSDynamicCast(OSDictionary, newControls->getObject(key));
                    437:         if(!newCtrl) {
                    438:             ret = kIOReturnBadArgument;
                    439:             break;
                    440:         }
                    441:         newVal = OSDynamicCast(OSNumber, newCtrl->getObject(IOAudioController::gValSym));
                    442:         if(!newVal) {
                    443:             ret = kIOReturnBadArgument;
                    444:             break;
                    445:         }
                    446:         // Update hardware via command queue
                    447:         ret = updateVal(newVal->unsigned16BitValue(), myCtrl, false);
                    448:         if(kIOReturnSuccess != ret)
                    449:             break;
                    450:     }
                    451:     
                    452:     return ret;
                    453: }
                    454: 
                    455: IOReturn
                    456: IOAudioComponentImpl::registerNotificationPort(
                    457:             mach_port_t port, UInt32 type, UInt32 refCon)
                    458: {
                    459:     static IOAudioNotifyMsg notify_msg = {{
                    460:         // mach_msg_bits_t     msgh_bits;
                    461:         MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND,0),
                    462:         // mach_msg_size_t     msgh_size;
                    463:         sizeof (IOAudioNotifyMsg),
                    464:         // mach_port_t msgh_remote_port;
                    465:         MACH_PORT_NULL,
                    466:         // mach_port_t msgh_local_port;
                    467:         MACH_PORT_NULL,
                    468:         // mach_msg_size_t     msgh_reserved;
                    469:         0,
                    470:         // mach_msg_id_t       msgh_id;
                    471:         type },
                    472:         // UInt32 refCon
                    473:         refCon
                    474:     };
                    475: 
                    476:     if( type != kIOAudioInputNotification)
                    477:        return( kIOReturnUnsupported);
                    478:     if ( fNotifyMsg == NULL )
                    479:         fNotifyMsg = (struct _notifyMsg *)
                    480:                         IOMalloc( sizeof (IOAudioNotifyMsg) );
                    481:     // Initialize the events available message.
                    482:     *fNotifyMsg = notify_msg;
                    483: 
                    484:     fNotifyMsg->h.msgh_remote_port = port;
                    485: 
                    486:     return kIOReturnSuccess;
                    487: }
                    488: 
                    489: const OSSymbol *
                    490: IOAudioComponentImpl::GetType() const
                    491: {
                    492:     const OSString *type;
                    493:     type = OSDynamicCast(OSString, getProperty(IOAudioController::gTypeSym));
                    494: 
                    495:     return OSSymbol::withString(type);
                    496: }
                    497: 
                    498: const OSSymbol *
                    499: IOAudioComponentImpl::GetType(const OSObject *obj) const
                    500: {
                    501:     const OSString *type;
                    502:     const OSDictionary *dict;
                    503:     dict = OSDynamicCast(OSDictionary, obj);
                    504:     if(NULL == dict)
                    505:        return NULL;
                    506:     type = OSDynamicCast(OSString, dict->getObject(IOAudioController::gTypeSym));
                    507: 
                    508:     return OSSymbol::withString(type);
                    509: }

unix.superglobalmegacorp.com

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