/*
* AudioHardwareDetect.cpp (implementation)
* Project : AppleOnboardAudio
*
* Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
* are subject to the Apple Public Source License Version 1.1 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
*
* This Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*
* An AudioHardwareDetect is a method to see if a device has been
* connected to the main CPU. It can be based on a different methods
* - A status is polled on a chip (usually the Codec itself) and is tested
* agains the detect properties. There are two kind of subdetects :
* + the InSense : when a device is connected, a bit is set in
* the status. The status is masked with the detect bit-mask, and
* compared with the bit-match. If the comparison is stisfied
* the detect is activated
* + the AnyInSense : the presence of one or more bits, tells that
* the detect is activated
* - An interrupt is detected, and depending on its value triggers or not
* the detect
*
* As of this version of the AppleOnboardAudio project (01/2001), and for the Screamer
* chip, the test for detect activation is made by creating a timer in the Codec driver
* and polling regularly. However we should change this method
* + make it work on the IOWorkloop of the driver
* + make it as asynchronous as possible
*
* Usually the driver has a field of type sndHWSpec (or UInt32) that contains all devices
* detected. This sndHWSpec field is then passed to the AudioHardwareOutput,
* and AudioHardwareINput objects in order to have the audio ports answering to
* a change in the connected device. Eventually, this communication will occur through
* a notification system.
*/
#include"AudioHardwareCommon.h"
#include"AudioHardwareConstants.h"
#include"AudioHardwareDetect.h"
#definesuper OSObject
OSDefineMetaClassAndStructors(AudioHardwareDetect, OSObject)
// Class creation function. Can be called from anywhere
AudioHardwareDetect *AudioHardwareDetect::create(UInt32 cntrlID, AudioHardwareDetectInfo myInfo){
AudioHardwareDetect *myDetect;
//we verify it is a known type of AudioHardwareDetect
if (kAudioHardwareDetectUnknown == myInfo.detectKind) {
myDetect = 0;
gotoEXIT;
}
myDetect = new AudioHardwareDetect;
if(myDetect) {
if(!(myDetect->init(cntrlID, myInfo))){
myDetect->release();
myDetect = 0;
}
}
EXIT:
return myDetect;
}
//Private creation method
boolAudioHardwareDetect::init(UInt32 cntrlID, AudioHardwareDetectInfo myInfo) {
if(!super::init())
return false;
dKind = myInfo.detectKind;
dDevice = myInfo.device;
dbitMask = myInfo.bitMask;
if(dKind == kAudioHardwareDetectInSense)
dbitMatch = myInfo.bitMatch;
else
dbitMatch = 0;
return(true);
}
//Release method (maybe we should implement a release??)
voidAudioHardwareDetect::free(){
super::free();
}
// This is the most useful method : given a series of bits
// representing the state of all AudioHardwareDetect, this method
// verifies if its device is connected. If yes it returns
// it, and otherwise 0.
UInt32 AudioHardwareDetect::refreshDevices(UInt32 inSense){
UInt32 result;
switch(dKind) {
casekAudioHardwareDetectInSense:
if((inSense & dbitMask) == dbitMatch)
result = dDevice;
else
result = 0;
break;
casekAudioHardwareDetectAnyInSense:
if((inSense & dbitMask) != 0)
result = dDevice;
else
result = 0;
break;
casekAudioHardwareDetectGPIO: //We need to add the GPIO detect
result = 0;
break;
casekAudioHardwareDetectUnknown:
default:
result = 0;
break;
}
ioLog();
if(0 != result){
CLOG(" --> Detect Activated\n");
}
return(result);
}
voidAudioHardwareDetect::ioLog(){
#ifdefDEBUGLOG
debugIOLog( "+ Detect for device : ");
switch (dDevice) {
casekSndHWInternalSpeaker: debugIOLog("kSndHWInternalSpeaker\n"); break;
casekSndHWCPUHeadphone: debugIOLog("kSndHWCPUHeadphone\n"); break;
casekSndHWCPUExternalSpeaker: debugIOLog("kSndHWCPUExternalSpeaker\n");break;
casekSndHWCPUSubwoofer: debugIOLog("kSndHWCPUSubwoofer\n"); break;
casekSndHWCPUMicrophone: debugIOLog("kSndHWCPUMicrophone\n"); break;
casekSndHWCPUPlainTalk: debugIOLog("kSndHWCPUPlainTalk\n"); break;
casekSndHWMonitorHeadphone: debugIOLog("kSndHWMonitorHeadphone\n"); break;
casekSndHWMonitorPlainTalk: debugIOLog("kSndHWMonitorPlainTalk\n"); break;
casekSndHWModemRingDetect: debugIOLog("kSndHWModemRingDetect\n"); break;
casekSndHWModemLineCurrent: debugIOLog("kSndHWModemLineCurrent\n"); break;
casekSndHWModemESquared: debugIOLog("kSndHWModemESquared\n"); break;
default: break;
}
switch(dKind) {
casekAudioHardwareDetectInSense:
debugIOLog(" -- Type : InSense\n");
debug3IOLog(" -- Insense mask is %ld, insense match is %ld\n",dbitMask, dbitMatch );
break;
casekAudioHardwareDetectAnyInSense:
debugIOLog(" -- Type : AnyInSense\n");
debug2IOLog(" -- Insense mask is %ld \n",dbitMask);
break;
casekAudioHardwareDetectGPIO: //We need to add the GPIO detect information
debugIOLog(" -- Type : GPIO\n");
break;
casekAudioHardwareDetectUnknown:
default:
debugIOLog(" -- Type : Unknown\n");
break;
}
#endif
}