ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mintopo.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2006-2007 dogbert <dogber1@gmail.com>
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions
00007 are met:
00008 1. Redistributions of source code must retain the above copyright
00009    notice, this list of conditions and the following disclaimer.
00010 2. Redistributions in binary form must reproduce the above copyright
00011    notice, this list of conditions and the following disclaimer in the
00012    documentation and/or other materials provided with the distribution.
00013 3. The name of the author may not be used to endorse or promote products
00014    derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00020 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00021 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00022 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00023 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00025 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 */
00027 
00028 #include "limits.h"
00029 #include "mintopo.hpp"
00030 #include "mintopotables.hpp"
00031 #define NTSTRSAFE_LIB //for Windows 2000 compatibility
00032 #include "ntstrsafe.h"
00033 
00034 #ifdef _MSC_VER
00035 #pragma code_seg("PAGE") /* warning - ignored by GCC compiler */
00036 #endif
00037 
00038 const GUID KSPROPSETID_CMI = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFF}};
00039 
00040 HRESULT NTAPI CreateMiniportTopologyCMI(PUNKNOWN* Unknown, REFCLSID, PUNKNOWN UnknownOuter, POOL_TYPE PoolType)
00041 {
00042     //PAGED_CODE();
00043     //ASSERT(Unknown);
00044     STD_CREATE_BODY_(CCMITopology,Unknown,UnknownOuter,PoolType,PMINIPORTTOPOLOGY);
00045 }
00046 
00047 STDMETHODIMP CCMITopology::QueryInterface(REFIID Interface, PVOID* Object)
00048 {
00049     //PAGED_CODE();
00050     //ASSERT(Object);
00051     DBGPRINT(("CCMITopology::NonDelegatingQueryInterface"));
00052 
00053     if (IsEqualGUIDAligned(Interface, IID_IUnknown)) {
00054         *Object = PVOID(PUNKNOWN(PMINIPORTTOPOLOGY(this)));
00055     } else if (IsEqualGUIDAligned(Interface,IID_IMiniport)) {
00056         *Object = PVOID(PMINIPORT(this));
00057     } else if (IsEqualGUIDAligned(Interface,IID_IMiniportTopology)) {
00058         *Object = PVOID(PMINIPORTTOPOLOGY(this));
00059     } else if (IsEqualGUIDAligned (Interface, IID_ICMITopolgy)) {
00060         *Object = (PVOID)(PMINIPORTTOPOLOGY)this;
00061     } else {
00062         *Object = NULL;
00063     }
00064 
00065     if (*Object) {
00066         PUNKNOWN(*Object)->AddRef();
00067         return STATUS_SUCCESS;
00068     }
00069 
00070     return STATUS_INVALID_PARAMETER;
00071 }
00072 
00073 CCMITopology::~CCMITopology()
00074 {
00075     //PAGED_CODE();
00076 
00077     DBGPRINT(("CCMITopology::~CCMITopology"));
00078 
00079     storeMixerSettingsToRegistry(); //or not. during system shutdown, this doesn't seem to work.
00080     cm->TopoMiniport = NULL;
00081 
00082     if (CMIAdapter) {
00083         CMIAdapter->Release();
00084     }
00085 }
00086 
00087 STDMETHODIMP CCMITopology::Init(PUNKNOWN UnknownAdapter, PRESOURCELIST ResourceList, PPORTTOPOLOGY Port)
00088 {
00089     //PAGED_CODE();
00090     //ASSERT(UnknownAdapter);
00091     //ASSERT(Port);
00092     DBGPRINT(("CCMITopology::Init"));
00093 
00094     NTSTATUS ntStatus = UnknownAdapter->QueryInterface(IID_ICMIAdapter, (PVOID *)&CMIAdapter);
00095 
00096     if (!NT_SUCCESS(ntStatus)) {
00097         DBGPRINT(("UnknownAdapter->QueryInterface() failed"));
00098         return STATUS_INVALID_PARAMETER;
00099     }
00100 
00101     CMIAdapter->resetMixer();
00102     auxVolumeRegister = CMIAdapter->readUInt8(REG_MIXER3);
00103     micVolumeRegister = CMIAdapter->readUInt8(REG_MIXER2);
00104     functrl1Register = 0;
00105     chformatRegister = 0;
00106     legacyRegister   = 0;
00107     miscctrlRegister = 0;
00108 
00109     cm = CMIAdapter->getCMI8738Info();
00110     cm->TopoMiniport = this; //this is not really nice
00111     loadMixerSettingsFromRegistry();
00112 
00113     return STATUS_SUCCESS;
00114 }
00115 
00116 STDMETHODIMP CCMITopology::GetDescription(PPCFILTER_DESCRIPTOR*  OutFilterDescriptor)
00117 {
00118     //PAGED_CODE();
00119     //ASSERT(OutFilterDescriptor);
00120     DBGPRINT(("CCMITopology::GetDescription"));
00121 
00122     *OutFilterDescriptor = &MiniportFilterDescriptor;
00123 
00124     return STATUS_SUCCESS;
00125 }
00126 
00127 STDMETHODIMP CCMITopology::loadMixerSettingsFromRegistry()
00128 {
00129     //PAGED_CODE();
00130     DBGPRINT(("CCMITopology::loadMixerSettingsFromRegistry"));
00131 
00132     PREGISTRYKEY       DriverKey;
00133     PREGISTRYKEY       SettingsKey;
00134     UNICODE_STRING     KeyName;
00135     PCPROPERTY_REQUEST PropertyRequest;
00136     PCPROPERTY_ITEM    PropertyItem;
00137     DWORD              Channel;
00138     PVOID              KeyInfo;
00139     ULONG              ResultLength;
00140     WCHAR              buffer[128];
00141 
00142     if ((!CMIAdapter) || (!(CMIAdapter->getDeviceObject()))) {
00143         DBGPRINT(("CMIAdapter->getDeviceObject() failed"));
00144         return STATUS_UNSUCCESSFUL;
00145     }
00146 
00147     settingsLoaded = FALSE;
00148 
00149     NTSTATUS ntStatus = PcNewRegistryKey(&DriverKey, NULL, DriverRegistryKey, KEY_ALL_ACCESS, CMIAdapter->getDeviceObject(), NULL, NULL, 0, NULL);
00150 
00151     if(!NT_SUCCESS(ntStatus)) {
00152         DBGPRINT(("PcNewRegistryKey() failed"));
00153         return STATUS_UNSUCCESSFUL;
00154     }
00155 
00156     RtlInitUnicodeString(&KeyName, L"Settings");
00157 
00158     ntStatus = DriverKey->NewSubKey(&SettingsKey, NULL, KEY_ALL_ACCESS, &KeyName, REG_OPTION_NON_VOLATILE, NULL);
00159     if(!NT_SUCCESS(ntStatus)) {
00160         DBGPRINT(("DriverKey->NewSubKey() failed"));
00161         return STATUS_UNSUCCESSFUL;
00162     }
00163 
00164     KeyInfo = ExAllocatePoolWithTag(PagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD), 'dbrt');
00165     if(KeyInfo == NULL) {
00166         DBGPRINT(("ExAllocatePoolWithTag() failed"));
00167         return STATUS_UNSUCCESSFUL;
00168     }
00169 
00170     PropertyRequest.MajorTarget  = this;
00171     PropertyRequest.Verb         = KSPROPERTY_TYPE_SET;
00172     PropertyRequest.Instance     = &Channel;
00173     PropertyRequest.InstanceSize = sizeof(DWORD);
00174     PropertyRequest.Value        = &(PKEY_VALUE_PARTIAL_INFORMATION(KeyInfo)->Data);
00175     PropertyRequest.ValueSize    = sizeof(DWORD);
00176     PropertyRequest.PropertyItem = &PropertyItem;
00177 
00178     for ( UINT i=0; i < SIZEOF_ARRAY(TopologyNodes); i++ ) {
00179         PropertyRequest.Node = i;
00180 
00181         Channel = CHAN_LEFT;
00182         ntStatus = RtlStringCbPrintfW(buffer, sizeof(buffer), L"Node%dLeft", i);
00183         if (!NT_SUCCESS(ntStatus)) {
00184             DBGPRINT(("RtlStringCbPrintfW() failed"));
00185         }
00186         RtlInitUnicodeString(&KeyName, buffer);
00187         ntStatus = SettingsKey->QueryValueKey(&KeyName, KeyValuePartialInformation, KeyInfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD), &ResultLength);
00188         if (NT_SUCCESS(ntStatus)) {
00189             if(PKEY_VALUE_PARTIAL_INFORMATION(KeyInfo)->DataLength == sizeof(DWORD)) {
00190                 if (IsEqualGUIDAligned(*(TopologyNodes[i].Type), KSNODETYPE_VOLUME)) {
00191                     PropertyItem.Id = KSPROPERTY_AUDIO_VOLUMELEVEL;
00192                     PropertyHandler_Level(&PropertyRequest);
00193                 }
00194                 if (IsEqualGUIDAligned(*(TopologyNodes[i].Type), KSNODETYPE_MUTE)) {
00195                     PropertyItem.Id = KSPROPERTY_AUDIO_MUTE;
00196                     PropertyHandler_OnOff(&PropertyRequest);
00197                 }
00198                 if (IsEqualGUIDAligned(*(TopologyNodes[i].Type), KSNODETYPE_LOUDNESS)) {
00199                     PropertyItem.Id = KSPROPERTY_AUDIO_LOUDNESS;
00200                     PropertyHandler_OnOff(&PropertyRequest);
00201                 }
00202             }
00203         } else {
00204             // default values
00205             if (i == KSNODE_TOPO_IEC_OUT) {
00206                 PropertyItem.Id = KSPROPERTY_AUDIO_LOUDNESS;
00207                 *(PBOOL(PropertyRequest.Value)) = true;
00208                 PropertyHandler_OnOff(&PropertyRequest);
00209             }
00210             if (i == KSNODE_TOPO_WAVEOUT_MUTE_IN) {
00211                 PropertyItem.Id = KSPROPERTY_AUDIO_MUTE;
00212                 *(PBOOL(PropertyRequest.Value)) = true;
00213                 PropertyHandler_OnOff(&PropertyRequest);
00214             }
00215             if (i == KSNODE_TOPO_CENTER2MIC) {
00216                 PropertyItem.Id = KSPROPERTY_AUDIO_LOUDNESS;
00217                 *(PBOOL(PropertyRequest.Value)) = false;
00218                 PropertyHandler_OnOff(&PropertyRequest);
00219             }
00220         }
00221 
00222         Channel = CHAN_RIGHT;
00223         ntStatus = RtlStringCbPrintfW(buffer, sizeof(buffer), L"Node%dRight", i);
00224         if (!NT_SUCCESS(ntStatus)) {
00225             DBGPRINT(("RtlStringCbPrintfW() failed"));
00226         }
00227         RtlInitUnicodeString(&KeyName, buffer);
00228         ntStatus = SettingsKey->QueryValueKey(&KeyName, KeyValuePartialInformation, KeyInfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD), &ResultLength);
00229         if (NT_SUCCESS(ntStatus)) {
00230             if(PKEY_VALUE_PARTIAL_INFORMATION(KeyInfo)->DataLength == sizeof(DWORD)) {
00231                 if (IsEqualGUIDAligned(*(TopologyNodes[i].Type), KSNODETYPE_VOLUME)) {
00232                     PropertyItem.Id = KSPROPERTY_AUDIO_VOLUMELEVEL;
00233                     PropertyHandler_Level(&PropertyRequest);
00234                 }
00235                 if (IsEqualGUIDAligned(*(TopologyNodes[i].Type), KSNODETYPE_MUTE)) {
00236                     PropertyItem.Id = KSPROPERTY_AUDIO_MUTE;
00237                     PropertyHandler_OnOff(&PropertyRequest);
00238                 }
00239                 if (IsEqualGUIDAligned(*(TopologyNodes[i].Type), KSNODETYPE_LOUDNESS)) {
00240                     PropertyItem.Id = KSPROPERTY_AUDIO_LOUDNESS;
00241                     PropertyHandler_OnOff(&PropertyRequest);
00242                 }
00243             }
00244         } else {
00245             if (i == KSNODE_TOPO_WAVEOUT_MUTE_IN) {
00246                 PropertyItem.Id = KSPROPERTY_AUDIO_MUTE;
00247                 *(PBOOL(PropertyRequest.Value)) = true;
00248                 PropertyHandler_OnOff(&PropertyRequest);
00249             }
00250         }
00251 
00252     }
00253     RtlInitUnicodeString(&KeyName, L"FormatMask");
00254     ntStatus = SettingsKey->QueryValueKey(&KeyName, KeyValuePartialInformation, KeyInfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD), &ResultLength);
00255     if (NT_SUCCESS (ntStatus)) {
00256         PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyInfo;
00257         if (PartialInfo->DataLength == sizeof(DWORD)) {
00258             cm->formatMask = (*(PLONG)PartialInfo->Data);
00259         }
00260     } else {
00261         cm->formatMask = 0xFFFFFFFF;
00262     }
00263 
00264     ExFreePoolWithTag (KeyInfo,'dbrt');
00265 
00266     SettingsKey->Release();
00267     DriverKey->Release();
00268 
00269     settingsLoaded = TRUE;
00270 
00271     return STATUS_SUCCESS;
00272 }
00273 
00274 STDMETHODIMP CCMITopology::storeMixerSettingsToRegistry()
00275 {
00276     //PAGED_CODE();
00277     DBGPRINT(("CCMITopology::storeMixerSettingsToRegistry"));
00278 
00279     PREGISTRYKEY       DriverKey;
00280     PREGISTRYKEY       SettingsKey;
00281     UNICODE_STRING     KeyName;
00282     PCPROPERTY_REQUEST PropertyRequest;
00283     PCPROPERTY_ITEM    PropertyItem;
00284     DWORD              Value,Channel;
00285     WCHAR              buffer[128];
00286 
00287     if ((!CMIAdapter) || (!(CMIAdapter->getDeviceObject()))) {
00288         return STATUS_UNSUCCESSFUL;
00289     }
00290 
00291     NTSTATUS ntStatus = PcNewRegistryKey(&DriverKey, NULL, DriverRegistryKey, KEY_ALL_ACCESS, CMIAdapter->getDeviceObject(), NULL, NULL, 0, NULL);
00292 
00293     if(!NT_SUCCESS(ntStatus)) {
00294         DBGPRINT(("PcNewRegistryKey() failed"));
00295         return STATUS_UNSUCCESSFUL;
00296     }
00297 
00298     RtlInitUnicodeString(&KeyName, L"Settings");
00299 
00300     ntStatus = DriverKey->NewSubKey(&SettingsKey, NULL, KEY_ALL_ACCESS, &KeyName, REG_OPTION_NON_VOLATILE, NULL);
00301 
00302     if(!NT_SUCCESS(ntStatus)) {
00303         DBGPRINT(("DriverKey->NewSubKey() failed"));
00304         return STATUS_UNSUCCESSFUL;
00305     }
00306 
00307     PropertyRequest.MajorTarget  = this;
00308     PropertyRequest.Verb         = KSPROPERTY_TYPE_GET;
00309     PropertyRequest.Instance     = &Channel;
00310     PropertyRequest.InstanceSize = sizeof(DWORD);
00311     PropertyRequest.Value        = &Value;
00312     PropertyRequest.ValueSize    = sizeof(DWORD);
00313     PropertyRequest.PropertyItem = &PropertyItem;
00314 
00315     for ( UINT i=0; i < SIZEOF_ARRAY(TopologyNodes); i++ ) {
00316         PropertyRequest.Node = i;
00317         if (IsEqualGUIDAligned(*(TopologyNodes[i].Type), KSNODETYPE_VOLUME)) {
00318             PropertyRequest.Node = i;
00319             PropertyItem.Id = KSPROPERTY_AUDIO_VOLUMELEVEL;
00320 
00321             ntStatus = RtlStringCbPrintfW(buffer, sizeof(buffer), L"Node%dLeft", i);
00322             if (!NT_SUCCESS(ntStatus)) {
00323                 DBGPRINT(("RtlStringCbPrintfW() failed"));
00324             }
00325             RtlInitUnicodeString(&KeyName, buffer);
00326             Channel = CHAN_LEFT;
00327             ntStatus = PropertyHandler_Level(&PropertyRequest);
00328             if (NT_SUCCESS(ntStatus)) {
00329                 ntStatus = SettingsKey->SetValueKey(&KeyName, REG_DWORD, PVOID(&Value), sizeof(DWORD));
00330                 if(!NT_SUCCESS(ntStatus)) {
00331                     DBGPRINT(("SetValueKey() failed"));
00332                     break;
00333                 }
00334             }
00335 
00336             ntStatus = RtlStringCbPrintfW(buffer, sizeof(buffer), L"Node%dRight", i);
00337             if (!NT_SUCCESS(ntStatus)) {
00338                 DBGPRINT(("RtlStringCbPrintfW() failed"));
00339             }
00340             RtlInitUnicodeString(&KeyName, buffer);
00341             Channel = CHAN_RIGHT;
00342             ntStatus = PropertyHandler_Level(&PropertyRequest);
00343             if (NT_SUCCESS(ntStatus)) {
00344                 ntStatus = SettingsKey->SetValueKey(&KeyName, REG_DWORD, PVOID(&Value), sizeof(DWORD));
00345                 if(!NT_SUCCESS(ntStatus)) {
00346                     DBGPRINT(("SetValueKey() failed"));
00347                     break;
00348                 }
00349             }
00350 
00351         }
00352         if (IsEqualGUIDAligned(*(TopologyNodes[i].Type), KSNODETYPE_MUTE)) {
00353             PropertyItem.Id = KSPROPERTY_AUDIO_MUTE;
00354             PropertyHandler_OnOff(&PropertyRequest);
00355 
00356             ntStatus = RtlStringCbPrintfW(buffer, sizeof(buffer), L"Node%dLeft", i);
00357             if (!NT_SUCCESS(ntStatus)) {
00358                 DBGPRINT(("RtlStringCbPrintfW() failed"));
00359             }
00360             RtlInitUnicodeString(&KeyName, buffer);
00361             Channel = CHAN_LEFT;
00362             ntStatus = PropertyHandler_OnOff(&PropertyRequest);
00363             if (NT_SUCCESS(ntStatus)) {
00364                 ntStatus = SettingsKey->SetValueKey(&KeyName, REG_DWORD, PVOID(&Value), sizeof(DWORD));
00365                 if(!NT_SUCCESS(ntStatus)) {
00366                     DBGPRINT(("SetValueKey() failed"));
00367                     break;
00368                 }
00369             }
00370 
00371             ntStatus = RtlStringCbPrintfW(buffer, sizeof(buffer), L"Node%dRight", i);
00372             if (!NT_SUCCESS(ntStatus)) {
00373                 DBGPRINT(("RtlStringCbPrintfW() failed"));
00374             }
00375             RtlInitUnicodeString(&KeyName, buffer);
00376             Channel = CHAN_RIGHT;
00377             ntStatus = PropertyHandler_OnOff(&PropertyRequest);
00378             if (NT_SUCCESS(ntStatus)) {
00379                 ntStatus = SettingsKey->SetValueKey(&KeyName, REG_DWORD, PVOID(&Value), sizeof(DWORD));
00380                 if(!NT_SUCCESS(ntStatus)) {
00381                     DBGPRINT(("SetValueKey() failed"));
00382                     break;
00383                 }
00384             }
00385         }
00386         if (IsEqualGUIDAligned(*(TopologyNodes[i].Type), KSNODETYPE_LOUDNESS)) {
00387             PropertyItem.Id = KSPROPERTY_AUDIO_LOUDNESS;
00388             PropertyHandler_OnOff(&PropertyRequest);
00389 
00390             ntStatus = RtlStringCbPrintfW(buffer, sizeof(buffer), L"Node%dLeft", i);
00391             if (!NT_SUCCESS(ntStatus)) {
00392                 DBGPRINT(("RtlStringCbPrintfW() failed"));
00393             }
00394             RtlInitUnicodeString(&KeyName, buffer);
00395             Channel = CHAN_LEFT;
00396             ntStatus = PropertyHandler_OnOff(&PropertyRequest);
00397             if (NT_SUCCESS(ntStatus)) {
00398                 ntStatus = SettingsKey->SetValueKey(&KeyName, REG_DWORD, PVOID(&Value), sizeof(DWORD));
00399                 if(!NT_SUCCESS(ntStatus)) {
00400                     DBGPRINT(("SetValueKey() failed"));
00401                     break;
00402                 }
00403             }
00404 
00405             ntStatus = RtlStringCbPrintfW(buffer, sizeof(buffer), L"Node%dRight", i);
00406             if (!NT_SUCCESS(ntStatus)) {
00407                 DBGPRINT(("RtlStringCbPrintfW() failed"));
00408             }
00409             RtlInitUnicodeString(&KeyName, buffer);
00410             Channel = CHAN_RIGHT;
00411             ntStatus = PropertyHandler_OnOff(&PropertyRequest);
00412             if (NT_SUCCESS(ntStatus)) {
00413                 ntStatus = SettingsKey->SetValueKey(&KeyName, REG_DWORD, PVOID(&Value), sizeof(DWORD));
00414                 if(!NT_SUCCESS(ntStatus)) {
00415                     DBGPRINT(("SetValueKey() failed"));
00416                     break;
00417                 }
00418             }
00419         }
00420     }
00421     Value = cm->formatMask;
00422     RtlInitUnicodeString(&KeyName, L"FormatMask");
00423     ntStatus = SettingsKey->SetValueKey(&KeyName, REG_DWORD, PVOID(&Value), sizeof(DWORD));
00424     if (!NT_SUCCESS(ntStatus)) {
00425         DBGPRINT(("SetValueKey() failed"));
00426     }
00427 
00428     SettingsKey->Release();
00429     DriverKey->Release();
00430 
00431     return STATUS_SUCCESS;
00432 }
00433 
00434 STDMETHODIMP CCMITopology::loadMixerSettingsFromMemory()
00435 {
00436     //PAGED_CODE();
00437     DBGPRINT(("CCMITopology::loadMixerSettingsFromMemory"));
00438 
00439     CMIAdapter->resetMixer();
00440     CMIAdapter->loadSBMixerFromMemory();
00441     CMIAdapter->writeUInt8(REG_MIXER1, mixer1Register);
00442     CMIAdapter->writeUInt8(REG_MIXER2, auxVolumeRegister);
00443     CMIAdapter->writeUInt8(REG_MIXER3, micVolumeRegister);
00444     CMIAdapter->writeUInt8(REG_MIXER4, mixer4Register);
00445 
00446     CMIAdapter->setUInt32Bit(REG_FUNCTRL1, functrl1Register);
00447     CMIAdapter->setUInt32Bit(REG_CHFORMAT, chformatRegister);
00448     CMIAdapter->setUInt32Bit(REG_LEGACY,   legacyRegister);
00449     CMIAdapter->setUInt32Bit(REG_MISCCTRL, miscctrlRegister);
00450 
00451     return STATUS_SUCCESS;
00452 }
00453 
00454 STDMETHODIMP CCMITopology::storeMixerSettingsToMemory()
00455 {
00456     //PAGED_CODE();
00457     DBGPRINT(("CCMITopology::storeMixerSettingsToMemory"));
00458 
00459     mixer1Register   = CMIAdapter->readUInt8(REG_MIXER1);
00460     mixer4Register   = CMIAdapter->readUInt8(REG_MIXER4);
00461     functrl1Register = CMIAdapter->readUInt32(REG_FUNCTRL1) & LOOP_SPDF ;
00462     chformatRegister = CMIAdapter->readUInt32(REG_CHFORMAT) & (INV_SPDIFI1 | SEL_SPDIFI1 | POLVALID);
00463     legacyRegister   = CMIAdapter->readUInt32(REG_LEGACY) & (BASS2LINE | CENTER2LINE | EN_SPDCOPYRHT);
00464     miscctrlRegister = CMIAdapter->readUInt32(REG_MISCCTRL) & (EN_SPDO5V | SEL_SPDIFI2);
00465 
00466     return STATUS_SUCCESS;
00467 }
00468 
00469 NTSTATUS NTAPI PropertyHandler_OnOff(PPCPROPERTY_REQUEST PropertyRequest)
00470 {
00471     //PAGED_CODE();
00472     //ASSERT(PropertyRequest);
00473     DBGPRINT(("[PropertyHandler_OnOff]"));
00474 
00475     CCMITopology *that = (CCMITopology *) ((PMINIPORTTOPOLOGY) PropertyRequest->MajorTarget);
00476 
00477     NTSTATUS  ntStatus = STATUS_INVALID_PARAMETER;
00478     //UInt8     data, mask, reg;
00479     UInt8     mask, reg;
00480     LONG      channel;
00481 
00482     if (PropertyRequest->Node == ULONG(-1)) {
00483         return ntStatus;
00484     }
00485 
00486     if ( ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) || (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)) && (PropertyRequest->InstanceSize >= sizeof(LONG)) ) {
00487         channel = *(PLONG(PropertyRequest->Instance));
00488         if (PropertyRequest->ValueSize >= sizeof(BOOL)) {
00489 
00490             if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MUTE) {
00491                 PBOOL Muted = PBOOL(PropertyRequest->Value);
00492                 switch (PropertyRequest->Node) {
00493 
00494                     case KSNODE_TOPO_WAVEOUT_MUTE:
00495                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00496                             *Muted = (that->CMIAdapter->readUInt8(REG_MIXER1) & MUTE_WAVE);
00497                         }
00498                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00499                             if (*Muted) {
00500                                 that->CMIAdapter->setUInt8Bit(REG_MIXER1, MUTE_WAVE);
00501                             } else {
00502                                 that->CMIAdapter->clearUInt8Bit(REG_MIXER1, MUTE_WAVE);
00503                             }
00504                         }
00505                         ntStatus = STATUS_SUCCESS;
00506                         break;
00507 
00508                     case KSNODE_TOPO_AUX_MUTE:
00509                         switch (channel) {
00510                             case CHAN_LEFT:  mask = MUTE_AUX_L; break;
00511                             case CHAN_RIGHT: mask = MUTE_AUX_R; break;
00512                             default: return ntStatus;
00513                         }
00514 
00515                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00516                             *Muted = !(that->micVolumeRegister & mask);
00517                         }
00518                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00519                             if (*Muted) {
00520                                 that->micVolumeRegister &= ~mask;
00521                             } else {
00522                                 that->micVolumeRegister |= mask;
00523                             }
00524                             that->CMIAdapter->writeUInt8(REG_MIXER2, that->micVolumeRegister);
00525                         }
00526                         ntStatus = STATUS_SUCCESS;
00527                         break;
00528 
00529                     case KSNODE_TOPO_MICOUT_MUTE:
00530                         if (channel != CHAN_LEFT) {
00531                             return ntStatus;
00532                         }
00533 
00534                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00535                             *Muted = !(that->CMIAdapter->readMixer(SBREG_OUTPUTCTRL) & EN_MIC);
00536                         }
00537                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00538                             if (*Muted) {
00539                                 that->CMIAdapter->clearMixerBit(SBREG_OUTPUTCTRL, EN_MIC);
00540                             } else {
00541                                 that->CMIAdapter->setMixerBit(SBREG_OUTPUTCTRL, EN_MIC);
00542                             }
00543                         }
00544                         ntStatus = STATUS_SUCCESS;
00545                         break;
00546 
00547                     case KSNODE_TOPO_CD_MUTE:
00548                         switch (channel) {
00549                             case CHAN_LEFT:  mask = EN_CD_L; break;
00550                             case CHAN_RIGHT: mask = EN_CD_R; break;
00551                             default: return ntStatus;
00552                         }
00553                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00554                             *Muted = !(that->CMIAdapter->readMixer(SBREG_OUTPUTCTRL) & mask);
00555                         }
00556                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00557                             if (*Muted) {
00558                                 that->CMIAdapter->clearMixerBit(SBREG_OUTPUTCTRL, mask);
00559                             } else {
00560                                 that->CMIAdapter->setMixerBit(SBREG_OUTPUTCTRL, mask);
00561                             }
00562                         }
00563                         ntStatus = STATUS_SUCCESS;
00564                         break;
00565 
00566                     case KSNODE_TOPO_LINEIN_MUTE:
00567                         switch (channel) {
00568                             case CHAN_LEFT:  mask = EN_LINEIN_L; break;
00569                             case CHAN_RIGHT: mask = EN_LINEIN_R; break;
00570                             default: return ntStatus;
00571                         }
00572                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00573                             *Muted = !(that->CMIAdapter->readMixer(SBREG_OUTPUTCTRL) & mask);
00574                         }
00575                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00576                             if (*Muted) {
00577                                 that->CMIAdapter->clearMixerBit(SBREG_OUTPUTCTRL, mask);
00578                             } else {
00579                                 that->CMIAdapter->setMixerBit(SBREG_OUTPUTCTRL, mask);
00580                             }
00581                         }
00582                         ntStatus = STATUS_SUCCESS;
00583                         break;
00584 
00585                     case KSNODE_TOPO_MIC_MUTE_IN:
00586                         if (channel != CHAN_LEFT) {
00587                             return ntStatus;
00588                         }
00589                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00590                             *Muted = !(that->CMIAdapter->readMixer(SBREG_IN_CTRL_L) & EN_MIC);
00591                         }
00592                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00593                             if (*Muted) {
00594                                 that->CMIAdapter->clearMixerBit(SBREG_IN_CTRL_L, EN_MIC);
00595                                 that->CMIAdapter->clearMixerBit(SBREG_IN_CTRL_R, EN_MIC);
00596                             } else {
00597                                 that->CMIAdapter->setMixerBit(SBREG_IN_CTRL_L, EN_MIC);
00598                                 that->CMIAdapter->setMixerBit(SBREG_IN_CTRL_R, EN_MIC);
00599                             }
00600                         }
00601                         ntStatus = STATUS_SUCCESS;
00602                         break;
00603 
00604                     case KSNODE_TOPO_CD_MUTE_IN:
00605                         switch (channel) {
00606                             case CHAN_LEFT:  mask = EN_LINEIN_L; reg = EN_CD_L; break;
00607                             case CHAN_RIGHT: mask = EN_LINEIN_R; reg = EN_CD_R; break;
00608                             default: return ntStatus;
00609                         }
00610                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00611                             *Muted = !(that->CMIAdapter->readMixer(reg) & mask);
00612                         }
00613                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00614                             if (*Muted) {
00615                                 that->CMIAdapter->clearMixerBit(reg, mask);
00616                             } else {
00617                                 that->CMIAdapter->setMixerBit(reg, mask);
00618                             }
00619                         }
00620                         ntStatus = STATUS_SUCCESS;
00621                         break;
00622 
00623                     case KSNODE_TOPO_LINEIN_MUTE_IN:
00624                         switch (channel) {
00625                             case CHAN_LEFT:  mask = EN_LINEIN_L; reg = SBREG_IN_CTRL_L; break;
00626                             case CHAN_RIGHT: mask = EN_LINEIN_R; reg = SBREG_IN_CTRL_R; break;
00627                             default: return ntStatus;
00628                         }
00629                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00630                             *Muted = !(that->CMIAdapter->readMixer(reg) & mask);
00631                         }
00632                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00633                             if (*Muted) {
00634                                 that->CMIAdapter->clearMixerBit(reg, mask);
00635                             } else {
00636                                 that->CMIAdapter->setMixerBit(reg, mask);
00637                             }
00638                         }
00639                         ntStatus = STATUS_SUCCESS;
00640                         break;
00641 
00642 
00643                     case KSNODE_TOPO_AUX_MUTE_IN:
00644                         switch (channel) {
00645                             case CHAN_LEFT:  mask = MUTE_RAUX_L; break;
00646                             case CHAN_RIGHT: mask = MUTE_RAUX_R; break;
00647                             default: return ntStatus;
00648                         }
00649                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00650                             *Muted = (that->micVolumeRegister & mask) ;
00651                         }
00652                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00653                             if (*Muted) {
00654                                 that->micVolumeRegister |= mask;
00655                             } else {
00656                                 that->micVolumeRegister &= ~mask;
00657                             }
00658                             that->CMIAdapter->writeUInt8(REG_MIXER2, that->micVolumeRegister);
00659                         }
00660                         ntStatus = STATUS_SUCCESS;
00661                         break;
00662 
00663                     case KSNODE_TOPO_WAVEOUT_MUTE_IN:
00664                         switch (channel) {
00665                             case CHAN_LEFT:  mask = EN_WAVEIN_L; break;
00666                             case CHAN_RIGHT: mask = EN_WAVEIN_R; break;
00667                             default: return ntStatus;
00668                         }
00669                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00670 //                          *Muted = !(that->CMIAdapter->readUInt8(REG_MIXER1) & mask);
00671                             *Muted = !(that->cm->enableSPDIFIn);
00672                             ntStatus = STATUS_SUCCESS;
00673                         }
00674                         if ((PropertyRequest->Verb & KSPROPERTY_TYPE_SET) && !(that->settingsLoaded)) {
00675                             if (*Muted) {
00676                                 that->cm->enableSPDIFIn = FALSE;
00677                                 that->CMIAdapter->clearUInt8Bit(REG_MIXER1, mask);
00678                             } else {
00679                                 that->cm->enableSPDIFIn = TRUE;
00680                                 that->CMIAdapter->setUInt8Bit(REG_MIXER1, mask);
00681                             }
00682                             ntStatus = STATUS_SUCCESS;
00683                         }
00684                         break;
00685 
00686                     case KSNODE_TOPO_MASTER_MUTE_DUMMY:
00687                         channel = (1 << channel);
00688                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00689                             *Muted = that->masterMuteDummy & channel;
00690                         }
00691                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00692                             if (*Muted) {
00693                                 that->masterMuteDummy |= channel;
00694                             } else {
00695                                 that->masterMuteDummy &= ~channel;
00696                             }
00697                         }
00698                         ntStatus = STATUS_SUCCESS;
00699                         break;
00700                 }
00701             }
00702 
00703             if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_LOUDNESS) {
00704                 PBOOL LoudnessOn = PBOOL(PropertyRequest->Value);
00705                 switch  (PropertyRequest->Node) {
00706                     case KSNODE_TOPO_MICIN_LOUDNESS:
00707                         if (channel == CHAN_LEFT) {
00708                             if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00709                                 *LoudnessOn = (that->CMIAdapter->readMixer(SBREG_EXTENSION) & EN_MICBOOST);
00710                             }
00711                             if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00712 //                              DBGPRINT(("setting mic boost: previous state %d, new state %d", (that->CMIAdapter->readMixer(SBREG_EXTENSION) & EN_MICBOOST), (*LoudnessOn)));
00713                                 if (*LoudnessOn) {
00714                                     that->CMIAdapter->setMixerBit(SBREG_EXTENSION, EN_MICBOOST);
00715                                 } else {
00716                                     that->CMIAdapter->clearMixerBit(SBREG_EXTENSION, EN_MICBOOST);
00717                                 }
00718                             }
00719                             ntStatus = STATUS_SUCCESS;
00720                         }
00721                         break;
00722                     case KSNODE_TOPO_MICOUT_LOUDNESS:
00723                         if (channel == CHAN_LEFT) {
00724                             if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00725                                 *LoudnessOn = !(that->CMIAdapter->readUInt8(REG_MIXER2) & DIS_MICGAIN);
00726                             }
00727                             if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00728                                 if (*LoudnessOn) {
00729                                     that->CMIAdapter->clearUInt8Bit(REG_MIXER2, DIS_MICGAIN);
00730                                 } else {
00731                                     that->CMIAdapter->setUInt8Bit(REG_MIXER2, DIS_MICGAIN);
00732                                 }
00733                             }
00734                             ntStatus = STATUS_SUCCESS;
00735                         }
00736                         break;
00737                     case KSNODE_TOPO_IEC_5V:
00738                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00739                             *LoudnessOn = (that->CMIAdapter->readUInt32(REG_MISCCTRL) & EN_SPDO5V);
00740                         }
00741                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00742                             if (*LoudnessOn) {
00743                                 that->CMIAdapter->setUInt32Bit(REG_MISCCTRL, EN_SPDO5V);
00744                             } else {
00745                                 that->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, EN_SPDO5V);
00746                             }
00747                         }
00748                         ntStatus = STATUS_SUCCESS;
00749                         break;
00750                     case KSNODE_TOPO_IEC_OUT:
00751                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00752                             if (that->cm) {
00753                                 *LoudnessOn = that->cm->enableSPDIFOut;
00754                             }
00755                         }
00756                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00757                             if (that->cm) {
00758                                 that->cm->enableSPDIFOut = (*LoudnessOn);
00759                             }
00760                         }
00761                         ntStatus = STATUS_SUCCESS;
00762                         break;
00763 
00764                     case KSNODE_TOPO_IEC_INVERSE:
00765                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00766                             if (that->cm->chipVersion <= 37) {
00767                                 *LoudnessOn = (that->CMIAdapter->readUInt8(REG_MIXER4) & INV_SPDIFI1);
00768                             } else {
00769                                 *LoudnessOn = (that->CMIAdapter->readUInt32(REG_CHFORMAT) & INV_SPDIFI2);
00770                             }
00771                         }
00772                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00773                             if (*LoudnessOn) {
00774                                 if (that->cm->chipVersion <= 37) {
00775                                     that->CMIAdapter->setUInt8Bit(REG_MIXER4, INV_SPDIFI1);
00776                                 } else {
00777                                     that->CMIAdapter->setUInt32Bit(REG_CHFORMAT, INV_SPDIFI2);
00778                                 }
00779                             } else {
00780                                 if (that->cm->chipVersion <= 37) {
00781                                     that->CMIAdapter->clearUInt8Bit(REG_MIXER4, INV_SPDIFI1);
00782                                 } else {
00783                                     that->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, INV_SPDIFI2);
00784                                 }
00785                             }
00786                         }
00787                         ntStatus = STATUS_SUCCESS;
00788                         break;
00789 
00790                     case KSNODE_TOPO_IEC_MONITOR:
00791                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00792                             *LoudnessOn = (that->CMIAdapter->readUInt8(REG_MIXER1) & EN_SPDI2DAC);
00793                         }
00794                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00795                             if (*LoudnessOn) {
00796                                 that->CMIAdapter->setUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
00797                             } else {
00798                                 that->CMIAdapter->clearUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
00799                             }
00800                         }
00801                         ntStatus = STATUS_SUCCESS;
00802                         break;
00803 
00804                     case KSNODE_TOPO_IEC_SELECT:
00805                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00806                             if (that->cm->chipVersion <= 37) {
00807                                 *LoudnessOn = (that->CMIAdapter->readUInt32(REG_CHFORMAT) & SEL_SPDIFI1);
00808                             } else {
00809                                 *LoudnessOn = (that->CMIAdapter->readUInt32(REG_MISCCTRL) & SEL_SPDIFI2);
00810                             }
00811                         }
00812                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
00813                             if (*LoudnessOn) {
00814                                 if (that->cm->chipVersion <= 37) {
00815                                     that->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SEL_SPDIFI1);
00816                                 } else {
00817                                     that->CMIAdapter->setUInt32Bit(REG_MISCCTRL, SEL_SPDIFI2);
00818                                 }
00819                             } else {
00820                                 if (that->cm->chipVersion <= 37) {
00821                                     that->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SEL_SPDIFI1);
00822                                 } else {
00823                                     that->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, SEL_SPDIFI2);
00824                                 }
00825                             }
00826                         }
00827                         ntStatus = STATUS_SUCCESS;
00828                         break;
00829 
00830                     case KSNODE_TOPO_XCHG_FB:
00831                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00832                             *LoudnessOn = (that->CMIAdapter->readUInt8(REG_MIXER1) & REAR2FRONT);
00833                         }
00834                         if ((PropertyRequest->Verb & KSPROPERTY_TYPE_SET) && !(that->settingsLoaded)) {
00835                             if (*LoudnessOn) {
00836                                 that->CMIAdapter->setUInt8Bit(REG_MIXER1, REAR2FRONT);
00837                             } else {
00838                                 that->CMIAdapter->clearUInt8Bit(REG_MIXER1, REAR2FRONT);
00839                             }
00840                         }
00841                         ntStatus = STATUS_SUCCESS;
00842                         break;
00843 
00844                     case KSNODE_TOPO_BASS2LINE:
00845                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00846                             *LoudnessOn = (that->CMIAdapter->readUInt32(REG_LEGACY) & BASS2LINE);
00847                         }
00848                         if ((PropertyRequest->Verb & KSPROPERTY_TYPE_SET) && !(that->settingsLoaded)) {
00849                             if (*LoudnessOn) {
00850                                 that->CMIAdapter->setUInt32Bit(REG_LEGACY, BASS2LINE);
00851                             } else {
00852                                 that->CMIAdapter->clearUInt32Bit(REG_LEGACY, BASS2LINE);
00853                             }
00854                         }
00855                         ntStatus = STATUS_SUCCESS;
00856                         break;
00857 
00858                     case KSNODE_TOPO_CENTER2LINE:
00859                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00860                             *LoudnessOn = (that->CMIAdapter->readUInt32(REG_LEGACY) & CENTER2LINE);
00861                         }
00862                         if ((PropertyRequest->Verb & KSPROPERTY_TYPE_SET) && !(that->settingsLoaded)) {
00863                             if (*LoudnessOn) {
00864                                 that->CMIAdapter->setUInt32Bit(REG_LEGACY, CENTER2LINE);
00865                             } else {
00866                                 that->CMIAdapter->clearUInt32Bit(REG_LEGACY, CENTER2LINE);
00867                             }
00868                         }
00869                         ntStatus = STATUS_SUCCESS;
00870                         break;
00871 
00872                     case KSNODE_TOPO_IEC_COPYRIGHT:
00873                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00874                             *LoudnessOn = (that->CMIAdapter->readUInt32(REG_LEGACY) & EN_SPDCOPYRHT);
00875                         }
00876                         if ((PropertyRequest->Verb & KSPROPERTY_TYPE_SET) && !(that->settingsLoaded)) {
00877                             if (*LoudnessOn) {
00878                                 that->CMIAdapter->setUInt32Bit(REG_LEGACY, EN_SPDCOPYRHT);
00879                             } else {
00880                                 that->CMIAdapter->clearUInt32Bit(REG_LEGACY, EN_SPDCOPYRHT);
00881                             }
00882                         }
00883                         ntStatus = STATUS_SUCCESS;
00884                         break;
00885 
00886                     case KSNODE_TOPO_IEC_POLVALID:
00887                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00888                             *LoudnessOn = (that->CMIAdapter->readUInt32(REG_CHFORMAT) & POLVALID);
00889                         }
00890                         if ((PropertyRequest->Verb & KSPROPERTY_TYPE_SET) && !(that->settingsLoaded)) {
00891                             if (*LoudnessOn) {
00892                                 that->CMIAdapter->setUInt32Bit(REG_CHFORMAT, POLVALID);
00893                             } else {
00894                                 that->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, POLVALID);
00895                             }
00896                         }
00897                         ntStatus = STATUS_SUCCESS;
00898                         break;
00899 
00900                     case KSNODE_TOPO_IEC_LOOP:
00901                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00902                             *LoudnessOn = (that->CMIAdapter->readUInt32(REG_FUNCTRL1) & LOOP_SPDF);
00903                         }
00904                         if ((PropertyRequest->Verb & KSPROPERTY_TYPE_SET) && !(that->settingsLoaded)) {
00905                             if (*LoudnessOn) {
00906                                 that->CMIAdapter->setUInt32Bit(REG_FUNCTRL1, LOOP_SPDF);
00907                             } else {
00908                                 that->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, LOOP_SPDF);
00909                             }
00910                         }
00911                         ntStatus = STATUS_SUCCESS;
00912                         break;
00913 
00914                     case KSNODE_TOPO_REAR2LINE:
00915                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00916                             *LoudnessOn = (that->CMIAdapter->readUInt8(REG_MIXER1) & REAR2LINE);
00917                         }
00918                         if ((PropertyRequest->Verb & KSPROPERTY_TYPE_SET) && !(that->settingsLoaded)) {
00919                             if (*LoudnessOn) {
00920                                 that->CMIAdapter->setUInt8Bit(REG_MIXER1, REAR2LINE);
00921                             } else {
00922                                 that->CMIAdapter->clearUInt8Bit(REG_MIXER1, REAR2LINE);
00923                             }
00924                         }
00925                         ntStatus = STATUS_SUCCESS;
00926                         break;
00927 
00928                     case KSNODE_TOPO_CENTER2MIC:
00929                         if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
00930                             *LoudnessOn = (that->CMIAdapter->readUInt8(REG_MIXER4) & CENTER2MIC) && (that->cm->chipVersion > 37);
00931                         }
00932                         if ((PropertyRequest->Verb & KSPROPERTY_TYPE_SET) && !(that->settingsLoaded) && (that->cm->chipVersion > 37)) {
00933                             if (*LoudnessOn) {
00934                                 that->CMIAdapter->setUInt8Bit(REG_MIXER4, CENTER2MIC);
00935                             } else {
00936                                 that->CMIAdapter->clearUInt8Bit(REG_MIXER4, CENTER2MIC);
00937                             }
00938                         }
00939                         ntStatus = STATUS_SUCCESS;
00940                         break;
00941                 }
00942             }
00943 
00944             if ((NT_SUCCESS(ntStatus)) && (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)) {
00945                 PropertyRequest->ValueSize = sizeof(BOOL);
00946             }
00947 
00948         }
00949     } else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) {
00950         bool supported = false;
00951         if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MUTE) {
00952             switch (PropertyRequest->Node) {
00953                 case KSNODE_TOPO_CD_MUTE:
00954                 case KSNODE_TOPO_LINEIN_MUTE:
00955                 case KSNODE_TOPO_MICOUT_MUTE:
00956                 case KSNODE_TOPO_AUX_MUTE:
00957                 case KSNODE_TOPO_WAVEOUT_MUTE:
00958                 case KSNODE_TOPO_LINEIN_MUTE_IN:
00959                 case KSNODE_TOPO_MIC_MUTE_IN:
00960                 case KSNODE_TOPO_CD_MUTE_IN:
00961                 case KSNODE_TOPO_AUX_MUTE_IN:
00962                 case KSNODE_TOPO_WAVEOUT_MUTE_IN:
00963                 case KSNODE_TOPO_MASTER_MUTE_DUMMY:
00964                     supported = true;
00965             }
00966         }
00967 
00968         if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_LOUDNESS) {
00969             switch (PropertyRequest->Node) {
00970                 case KSNODE_TOPO_MICIN_LOUDNESS:
00971                 case KSNODE_TOPO_MICOUT_LOUDNESS:
00972                 case KSNODE_TOPO_IEC_5V:
00973                 case KSNODE_TOPO_IEC_OUT:
00974                 case KSNODE_TOPO_IEC_INVERSE:
00975                 case KSNODE_TOPO_IEC_MONITOR:
00976                 case KSNODE_TOPO_IEC_SELECT:
00977                 case KSNODE_TOPO_XCHG_FB:
00978                 case KSNODE_TOPO_BASS2LINE:
00979                 case KSNODE_TOPO_CENTER2LINE:
00980                 case KSNODE_TOPO_IEC_COPYRIGHT:
00981                 case KSNODE_TOPO_IEC_POLVALID:
00982                 case KSNODE_TOPO_IEC_LOOP:
00983                 case KSNODE_TOPO_REAR2LINE:
00984                     supported = true;
00985             }
00986             if ((PropertyRequest->Node == KSNODE_TOPO_CENTER2MIC) && (that->cm->chipVersion > 37)) {
00987                 supported = true;
00988             }
00989         }
00990 
00991         if (supported) {
00992             if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION))) {
00993                 PKSPROPERTY_DESCRIPTION PropDesc = PKSPROPERTY_DESCRIPTION(PropertyRequest->Value);
00994 
00995                 PropDesc->AccessFlags      = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT;
00996                 PropDesc->DescriptionSize   = sizeof(KSPROPERTY_DESCRIPTION);
00997                 PropDesc->PropTypeSet.Set   = KSPROPTYPESETID_General;
00998                 PropDesc->PropTypeSet.Id    = VT_BOOL;
00999                 PropDesc->PropTypeSet.Flags = 0;
01000                 PropDesc->MembersListCount  = 0;
01001                 PropDesc->Reserved        = 0;
01002 
01003                 PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION);
01004                 ntStatus = STATUS_SUCCESS;
01005             } else if (PropertyRequest->ValueSize >= sizeof(ULONG)) {
01006                 PULONG AccessFlags = PULONG(PropertyRequest->Value);
01007 
01008                 *AccessFlags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT;
01009 
01010                 PropertyRequest->ValueSize = sizeof(ULONG);
01011                 ntStatus = STATUS_SUCCESS;
01012             }
01013         }
01014     }
01015 
01016     return ntStatus;
01017 }
01018 
01019 static NTSTATUS BasicSupportHandler(PPCPROPERTY_REQUEST PropertyRequest)
01020 {
01021     //PAGED_CODE();
01022     //ASSERT(PropertyRequest);
01023     DBGPRINT(("[BasicSupportHandler]"));
01024 
01025     NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
01026 
01027     if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION))) {
01028         PKSPROPERTY_DESCRIPTION PropDesc = PKSPROPERTY_DESCRIPTION(PropertyRequest->Value);
01029 
01030         PropDesc->AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET;
01031         PropDesc->DescriptionSize   = sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_STEPPING_LONG);
01032         PropDesc->PropTypeSet.Set   = KSPROPTYPESETID_General;
01033         PropDesc->PropTypeSet.Id    = VT_I4;
01034         PropDesc->PropTypeSet.Flags = 0;
01035         PropDesc->MembersListCount  = 1;
01036         PropDesc->Reserved        = 0;
01037 
01038         if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_STEPPING_LONG))) {
01039             PKSPROPERTY_MEMBERSHEADER Members = PKSPROPERTY_MEMBERSHEADER(PropDesc + 1);
01040 
01041             Members->MembersFlags = KSPROPERTY_MEMBER_STEPPEDRANGES;
01042             Members->MembersSize  = sizeof(KSPROPERTY_STEPPING_LONG);
01043             Members->MembersCount = 1;
01044             Members->Flags        = 0;
01045 
01046             PKSPROPERTY_STEPPING_LONG Range = PKSPROPERTY_STEPPING_LONG(Members + 1);
01047 
01048             for ( UINT i=0; i < SIZEOF_ARRAY(VolTable); i++ ) {
01049                 if (VolTable[i].node == PropertyRequest->Node) {
01050                     Range->Bounds.SignedMaximum = (VolTable[i].max << 16);
01051                     Range->Bounds.SignedMinimum = (VolTable[i].min << 16);
01052                     Range->SteppingDelta        = (VolTable[i].step << 16);
01053                     ntStatus = STATUS_SUCCESS;
01054                 }
01055             }
01056             if (!NT_SUCCESS(ntStatus)) {
01057                 switch (PropertyRequest->Node) {
01058                     case KSNODE_TOPO_AUX_VOLUME:
01059                         Range->Bounds.SignedMaximum = 0;
01060                         Range->Bounds.SignedMinimum = (-60 << 16);
01061                         Range->SteppingDelta        = (4 << 16);
01062                         ntStatus = STATUS_SUCCESS;
01063                         break;
01064                     case KSNODE_TOPO_MICIN_VOLUME:
01065                         Range->Bounds.SignedMaximum = 0;
01066                         Range->Bounds.SignedMinimum = (-56 << 16);
01067                         Range->SteppingDelta        = (8 << 16);
01068                         ntStatus = STATUS_SUCCESS;
01069                         break;
01070                 }
01071             }
01072             Range->Reserved = 0;
01073 
01074             PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_STEPPING_LONG);
01075         } else {
01076             PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION);
01077             ntStatus = STATUS_SUCCESS;
01078         }
01079     } else if (PropertyRequest->ValueSize >= sizeof(ULONG)) {
01080         PULONG AccessFlags = PULONG(PropertyRequest->Value);
01081         *AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET;
01082         PropertyRequest->ValueSize = sizeof(ULONG);
01083         ntStatus = STATUS_SUCCESS;
01084     }
01085 
01086     return ntStatus;
01087 }
01088 
01089 NTSTATUS NTAPI PropertyHandler_Level(PPCPROPERTY_REQUEST PropertyRequest)
01090 {
01091     //PAGED_CODE();
01092     //ASSERT(PropertyRequest);
01093     DBGPRINT(("[PropertyHandler_Level]"));
01094 
01095     CCMITopology *that = (CCMITopology *) ((PMINIPORTTOPOLOGY) PropertyRequest->MajorTarget);
01096     NTSTATUS     ntStatus = STATUS_INVALID_PARAMETER;
01097     UInt32       channel;
01098     UInt8        mixerValue;
01099 
01100     if ((PropertyRequest->Node == ULONG(-1)) || (PropertyRequest->Node >= KSNODE_TOPO_INVALID) || (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_VOLUMELEVEL)) {
01101         return ntStatus;
01102     }
01103 
01104     if ( ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) || (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)) && (PropertyRequest->InstanceSize >= sizeof(LONG)) ) {
01105 
01106         channel = *(PLONG(PropertyRequest->Instance));
01107 
01108         if ((PropertyRequest->Node == KSNODE_TOPO_MICOUT_VOLUME) && (channel != CHAN_LEFT)) {
01109             return STATUS_INVALID_PARAMETER;
01110         }
01111 
01112         if ( ( (channel == CHAN_LEFT) || (channel == CHAN_RIGHT) ) && (PropertyRequest->ValueSize >= sizeof(LONG))) {
01113 
01114             PLONG Level = (PLONG)PropertyRequest->Value;
01115 
01116             for ( UINT i=0; i <SIZEOF_ARRAY(VolTable); i++ )
01117             {
01118                 if (VolTable[i].node == PropertyRequest->Node) {
01119                     if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
01120 
01121                         mixerValue = (that->CMIAdapter->readMixer(VolTable[i].reg+channel) >> VolTable[i].shift) & VolTable[i].mask;
01122                         *Level     = that->NodeCache[(2*PropertyRequest->Node)+channel];
01123 
01124                         if (mixerValue != ((*Level >> (VolTable[i].dbshift+16))+VolTable[i].mask)) {
01125                             *Level = (mixerValue - VolTable[i].mask) << (16+VolTable[i].dbshift);
01126                             that->NodeCache[(2*PropertyRequest->Node)+channel] = *Level;
01127                         }
01128                     } else
01129                     if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
01130                         if (*Level <= (VolTable[i].min << 16)) {
01131                             mixerValue = 0;
01132                             that->NodeCache[(2*PropertyRequest->Node)+channel] = VolTable[i].min << 16;
01133                         } else
01134                         if (*Level >= (VolTable[i].max << 16)) {
01135                             mixerValue = VolTable[i].mask;
01136                             that->NodeCache[(2*PropertyRequest->Node)+channel] = VolTable[i].max << 16;
01137                         } else {
01138                             mixerValue = ((*Level >> (VolTable[i].dbshift+16)) + VolTable[i].mask) & VolTable[i].mask;
01139                             that->NodeCache[(2*PropertyRequest->Node)+channel] = *Level;
01140                         }
01141                         that->CMIAdapter->writeMixer(VolTable[i].reg+channel, mixerValue << VolTable[i].shift);
01142                     }
01143                     ntStatus = STATUS_SUCCESS;
01144                 }
01145             }
01146             if (PropertyRequest->Node == KSNODE_TOPO_AUX_VOLUME) {
01147                 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
01148                     mixerValue = that->auxVolumeRegister;
01149                     *Level     = that->NodeCache[(2*PropertyRequest->Node)+channel];
01150                     if (channel == CHAN_LEFT) {
01151                         mixerValue >>= 4;
01152                     }
01153                     mixerValue &= 0x0F;
01154                     if (mixerValue != ((*Level >> 18)+0x0F)) {
01155                         *Level = (mixerValue - 0x0F) << 18;
01156                         that->NodeCache[(2*PropertyRequest->Node)+channel] = *Level;
01157                     }
01158                 } else
01159                 if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
01160                     if (*Level <= (-30 << 16)) {
01161                         mixerValue = 0;
01162                         that->NodeCache[(2*PropertyRequest->Node)+channel] = -30 << 16;
01163                     } else
01164                     if (*Level >= 0) {
01165                         mixerValue = 0x0F;
01166                         that->NodeCache[(2*PropertyRequest->Node)+channel] = 0;
01167                     } else  {
01168                         mixerValue = ((*Level >> 18) + 0x0F) & 0x0F;
01169                         that->NodeCache[(2*PropertyRequest->Node)+channel] = *Level;
01170                     }
01171 
01172                     if (channel == CHAN_RIGHT) {
01173                         that->auxVolumeRegister = (that->auxVolumeRegister & 0xF0) | mixerValue;
01174                     } else if (channel == CHAN_LEFT) {
01175                         that->auxVolumeRegister = (that->auxVolumeRegister & 0x0F) | (mixerValue << 4);
01176                     }
01177                     that->CMIAdapter->writeUInt8(REG_MIXER3, that->auxVolumeRegister);
01178                 }
01179                 ntStatus = STATUS_SUCCESS;
01180             }
01181             if ((PropertyRequest->Node == KSNODE_TOPO_MICIN_VOLUME) && (channel == CHAN_LEFT)) {
01182                 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
01183                     *Level     = that->NodeCache[(2*PropertyRequest->Node)];
01184                     mixerValue = that->micVolumeRegister >> 1 & 0x7;
01185                     if (mixerValue != ((*Level >> 19)+0x07)) {
01186                         *Level = (mixerValue - 0x07) << 19;
01187                         that->NodeCache[(2*PropertyRequest->Node)] = *Level;
01188                     }
01189                 } else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
01190                     if (*Level <= (-56 << 16)) {
01191                         mixerValue = 0;
01192                         that->NodeCache[(2*PropertyRequest->Node)] = -56 << 16;
01193                     } else if (*Level >= 0) {
01194                         mixerValue = 0x07;
01195                         that->NodeCache[(2*PropertyRequest->Node)] = 0;
01196                     } else {
01197                         mixerValue = ((*Level >> 19) + 0x07) & 0x07;
01198                         that->NodeCache[(2*PropertyRequest->Node)] = *Level;
01199                     }
01200                     that->micVolumeRegister &= ~(0x07 << 1);
01201                     that->micVolumeRegister |= mixerValue << 1;
01202                     that->CMIAdapter->writeUInt8(REG_MIXER2, that->micVolumeRegister);
01203                 }
01204                 ntStatus = STATUS_SUCCESS;
01205             }
01206             if ((NT_SUCCESS(ntStatus)) && (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)) {
01207                 PropertyRequest->ValueSize = sizeof(LONG);
01208             }
01209         }
01210     } else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) {
01211         switch(PropertyRequest->Node) {
01212             case KSNODE_TOPO_LINEOUT_VOLUME:
01213             case KSNODE_TOPO_WAVEOUT_VOLUME:
01214             case KSNODE_TOPO_CD_VOLUME:
01215             case KSNODE_TOPO_LINEIN_VOLUME:
01216             case KSNODE_TOPO_MICOUT_VOLUME:
01217             case KSNODE_TOPO_MICIN_VOLUME:
01218             case KSNODE_TOPO_AUX_VOLUME:
01219                 ntStatus = BasicSupportHandler(PropertyRequest);
01220                 break;
01221         }
01222     }
01223 
01224     return ntStatus;
01225 }
01226 NTSTATUS NTAPI PropertyHandler_CpuResources(PPCPROPERTY_REQUEST PropertyRequest)
01227 {
01228     //PAGED_CODE();
01229     //ASSERT(PropertyRequest);
01230     DBGPRINT(("[PropertyHandler_CpuResources]"));
01231 
01232     NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
01233 
01234     if (PropertyRequest->Node == MAXULONG) {
01235         return ntStatus;
01236     }
01237     if (PropertyRequest->Node >= KSNODE_TOPO_INVALID) {
01238         return ntStatus;
01239     }
01240 
01241     if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
01242         if (PropertyRequest->ValueSize >= sizeof(LONG)) {
01243             *((PLONG)PropertyRequest->Value) = KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU;
01244 
01245             PropertyRequest->ValueSize = sizeof(LONG);
01246             ntStatus = STATUS_SUCCESS;
01247         } else  {
01248             ntStatus = STATUS_BUFFER_TOO_SMALL;
01249         }
01250     } else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) {
01251         if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION))) {
01252             PKSPROPERTY_DESCRIPTION PropDesc = PKSPROPERTY_DESCRIPTION(PropertyRequest->Value);
01253 
01254             PropDesc->AccessFlags       = KSPROPERTY_TYPE_BASICSUPPORT |
01255                                           KSPROPERTY_TYPE_GET;
01256             PropDesc->DescriptionSize   = sizeof(KSPROPERTY_DESCRIPTION);
01257             PropDesc->PropTypeSet.Set   = KSPROPTYPESETID_General;
01258             PropDesc->PropTypeSet.Id    = VT_I4;
01259             PropDesc->PropTypeSet.Flags = 0;
01260             PropDesc->MembersListCount  = 0;
01261             PropDesc->Reserved          = 0;
01262 
01263             PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION);
01264             ntStatus = STATUS_SUCCESS;
01265         } else if (PropertyRequest->ValueSize >= sizeof(ULONG)) {
01266             PULONG AccessFlags = PULONG(PropertyRequest->Value);
01267 
01268             *AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET;
01269 
01270             PropertyRequest->ValueSize = sizeof(ULONG);
01271             ntStatus = STATUS_SUCCESS;
01272         }
01273     }
01274 
01275     return ntStatus;
01276 }
01277 
01278 NTSTATUS NTAPI PropertyHandler_ComponentId(PPCPROPERTY_REQUEST PropertyRequest)
01279 {
01280     //PAGED_CODE();
01281     //ASSERT(PropertyRequest);
01282     DBGPRINT(("[PropertyHandler_ComponentId]"));
01283 
01284     NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
01285     CCMITopology *that = (CCMITopology *) ((PMINIPORTTOPOLOGY) PropertyRequest->MajorTarget);
01286 
01287     if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
01288         if (PropertyRequest->ValueSize >= sizeof(KSCOMPONENTID)) {
01289             PKSCOMPONENTID pComponentId = (PKSCOMPONENTID)PropertyRequest->Value;
01290 
01291             pComponentId->Manufacturer = MANUFACTURER_CM8738;
01292             pComponentId->Product      = PRODUCT_CM8738;
01293             pComponentId->Component    = COMPONENT_CM8738;
01294             pComponentId->Name         = GUID_NULL;
01295             pComponentId->Version      = CMIPCI_VERSION;
01296             pComponentId->Revision     = that->cm->chipVersion;
01297 
01298             PropertyRequest->ValueSize = sizeof(KSCOMPONENTID);
01299             ntStatus = STATUS_SUCCESS;
01300         } else if (PropertyRequest->ValueSize == 0) {
01301             PropertyRequest->ValueSize = sizeof(KSCOMPONENTID);
01302             ntStatus = STATUS_BUFFER_OVERFLOW;
01303         } else {
01304             PropertyRequest->ValueSize = 0;
01305             ntStatus = STATUS_BUFFER_TOO_SMALL;
01306         }
01307     } else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) {
01308         if (PropertyRequest->ValueSize >= sizeof(ULONG)) {
01309             PULONG AccessFlags = PULONG(PropertyRequest->Value);
01310 
01311             *AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET;
01312 
01313             PropertyRequest->ValueSize = sizeof(ULONG);
01314             ntStatus = STATUS_SUCCESS;
01315         } else {
01316             PropertyRequest->ValueSize = 0;
01317             ntStatus = STATUS_BUFFER_TOO_SMALL;
01318         }
01319     }
01320 
01321     return ntStatus;
01322 }
01323 
01324 NTSTATUS NTAPI PropertyHandler_Private(PPCPROPERTY_REQUEST PropertyRequest)
01325 {
01326     //PAGED_CODE();
01327     //ASSERT(PropertyRequest);
01328     DBGPRINT(("[PropertyHandler_Private]"));
01329 
01330     NTSTATUS     ntStatus = STATUS_INVALID_DEVICE_REQUEST;
01331     CCMITopology *that = (CCMITopology *) ((PMINIPORTTOPOLOGY) PropertyRequest->MajorTarget);
01332 
01333     if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
01334         if (PropertyRequest->PropertyItem->Id != KSPROPERTY_CMI_GET) {
01335             return STATUS_INVALID_DEVICE_REQUEST;
01336         }
01337 
01338         if (PropertyRequest->ValueSize == 0) {
01339             PropertyRequest->ValueSize = sizeof(CMIDATA);
01340             return STATUS_BUFFER_OVERFLOW;
01341         } else if (PropertyRequest->ValueSize < sizeof (CMIDATA)) {
01342             PropertyRequest->ValueSize = 0;
01343             return STATUS_BUFFER_TOO_SMALL;
01344         }
01345 
01346         CMIDATA* cmiData = (CMIDATA*)PropertyRequest->Value;
01347 #ifdef WAVERT
01348         RtlStringCbPrintfA(cmiData->driverVersion, sizeof(cmiData->driverVersion), CMIVERSION "-WaveRT");
01349 #else
01350         RtlStringCbPrintfA(cmiData->driverVersion, sizeof(cmiData->driverVersion), CMIVERSION);
01351 #endif
01352         cmiData->hardwareRevision    = that->cm->chipVersion;
01353         cmiData->maxChannels         = that->cm->maxChannels;
01354         cmiData->IOBase              = (USHORT)(ULONG_PTR)that->cm->IOBase;
01355         cmiData->MPUBase             = (USHORT)(ULONG_PTR)that->cm->MPUBase;
01356         cmiData->enableSPDO          = that->cm->enableSPDIFOut;
01357         cmiData->enableSPDI          = that->cm->enableSPDIFIn;
01358         cmiData->formatMask          = that->cm->formatMask;
01359         cmiData->exchangeFrontBack   = (that->CMIAdapter->readUInt8(REG_MIXER1) & REAR2FRONT);
01360         cmiData->enableSPDO5V        = (that->CMIAdapter->readUInt32(REG_MISCCTRL) & EN_SPDO5V);
01361         cmiData->enablePCMDAC        = (that->CMIAdapter->readUInt8(REG_MIXER1) & EN_SPDI2DAC);
01362         cmiData->enableBass2Line     = (that->CMIAdapter->readUInt32(REG_LEGACY) & BASS2LINE);
01363         cmiData->enableCenter2Line   = (that->CMIAdapter->readUInt32(REG_LEGACY) & CENTER2LINE);
01364         cmiData->enableRear2Line     = (that->CMIAdapter->readUInt8(REG_MIXER1) & REAR2LINE);
01365         cmiData->enableCenter2Mic    = (that->CMIAdapter->readUInt8(REG_MIXER4) & CENTER2MIC) && (that->cm->chipVersion > 37);
01366         cmiData->enableSPDOCopyright = (that->CMIAdapter->readUInt32(REG_LEGACY) & EN_SPDCOPYRHT);
01367         cmiData->invertValidBitSPDI  = (that->CMIAdapter->readUInt32(REG_CHFORMAT) & POLVALID);
01368         cmiData->loopSPDI            = (that->CMIAdapter->readUInt32(REG_FUNCTRL1) & LOOP_SPDF);
01369         if (that->cm->chipVersion <= 37) {
01370             cmiData->select2ndSPDI   = (that->CMIAdapter->readUInt32(REG_CHFORMAT) & SEL_SPDIFI1);
01371             cmiData->invertPhaseSPDI = (that->CMIAdapter->readUInt8(REG_MIXER4) & INV_SPDIFI1);
01372         } else {
01373             cmiData->select2ndSPDI   = (that->CMIAdapter->readUInt32(REG_MISCCTRL) & SEL_SPDIFI2);
01374             cmiData->invertPhaseSPDI = (that->CMIAdapter->readUInt32(REG_CHFORMAT) & INV_SPDIFI2);
01375         }
01376 
01377         PropertyRequest->ValueSize = sizeof(CMIDATA);
01378         ntStatus = STATUS_SUCCESS;
01379     } else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
01380         if (PropertyRequest->PropertyItem->Id != KSPROPERTY_CMI_SET) {
01381             return STATUS_INVALID_DEVICE_REQUEST;
01382         }
01383 
01384         if (PropertyRequest->ValueSize == 0) {
01385             PropertyRequest->ValueSize = sizeof(CMIDATA);
01386             return STATUS_BUFFER_OVERFLOW;
01387         } else if (PropertyRequest->ValueSize < sizeof (CMIDATA)) {
01388             PropertyRequest->ValueSize = 0;
01389             return STATUS_BUFFER_TOO_SMALL;
01390         }
01391         CMIDATA* cmiData = (CMIDATA*)PropertyRequest->Value;
01392         that->cm->enableSPDIFIn         = cmiData->enableSPDI;
01393         that->cm->enableSPDIFOut        = cmiData->enableSPDO;
01394         that->cm->formatMask            = cmiData->formatMask;
01395 
01396         if (cmiData->enableSPDI) {
01397             that->CMIAdapter->setUInt8Bit(REG_MIXER1, EN_WAVEIN_L | EN_WAVEIN_R);
01398         } else {
01399             that->CMIAdapter->clearUInt8Bit(REG_MIXER1, EN_WAVEIN_L | EN_WAVEIN_R);
01400         }
01401 
01402         if (cmiData->exchangeFrontBack) {
01403             that->CMIAdapter->setUInt8Bit(REG_MIXER1, REAR2FRONT);
01404         } else {
01405             that->CMIAdapter->clearUInt8Bit(REG_MIXER1, REAR2FRONT);
01406         }
01407         if (cmiData->enableSPDO5V) {
01408             that->CMIAdapter->setUInt32Bit(REG_MISCCTRL, EN_SPDO5V);
01409         } else {
01410             that->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, EN_SPDO5V);
01411         }
01412         if (cmiData->enablePCMDAC) {
01413             that->CMIAdapter->setUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
01414         } else {
01415             that->CMIAdapter->clearUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
01416         }
01417         if (cmiData->enableBass2Line) {
01418             that->CMIAdapter->setUInt32Bit(REG_LEGACY, BASS2LINE);
01419         } else {
01420             that->CMIAdapter->clearUInt32Bit(REG_LEGACY, BASS2LINE);
01421         }
01422         if (cmiData->enableCenter2Line) {
01423             that->CMIAdapter->setUInt32Bit(REG_LEGACY, CENTER2LINE);
01424         } else {
01425             that->CMIAdapter->clearUInt32Bit(REG_LEGACY, CENTER2LINE);
01426         }
01427         if (cmiData->enableRear2Line) {
01428             that->CMIAdapter->setUInt8Bit(REG_MIXER1, REAR2LINE);
01429         } else {
01430             that->CMIAdapter->clearUInt8Bit(REG_MIXER1, REAR2LINE);
01431         }
01432         if (that->cm->chipVersion > 37) {
01433             if (cmiData->enableCenter2Mic) {
01434                 that->CMIAdapter->setUInt8Bit(REG_MIXER4, CENTER2MIC);
01435             } else {
01436                 that->CMIAdapter->clearUInt8Bit(REG_MIXER4, CENTER2MIC);
01437             }
01438         }
01439         if (cmiData->enableSPDOCopyright) {
01440             that->CMIAdapter->setUInt32Bit(REG_LEGACY, EN_SPDCOPYRHT);
01441         } else {
01442             that->CMIAdapter->clearUInt32Bit(REG_LEGACY, EN_SPDCOPYRHT);
01443         }
01444         if (cmiData->invertValidBitSPDI) {
01445             that->CMIAdapter->setUInt32Bit(REG_CHFORMAT, POLVALID);
01446         } else {
01447             that->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, POLVALID);
01448         }
01449         if (cmiData->loopSPDI) {
01450             that->CMIAdapter->setUInt32Bit(REG_FUNCTRL1, LOOP_SPDF);
01451         } else {
01452             that->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, LOOP_SPDF);
01453         }
01454         if (cmiData->select2ndSPDI) {
01455             if (that->cm->chipVersion <= 37) {
01456                 that->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SEL_SPDIFI1);
01457             } else {
01458                 that->CMIAdapter->setUInt32Bit(REG_MISCCTRL, SEL_SPDIFI2);
01459             }
01460         } else {
01461             if (that->cm->chipVersion <= 37) {
01462                 that->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SEL_SPDIFI1);
01463             } else {
01464                 that->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, SEL_SPDIFI2);
01465             }
01466         }
01467         if (cmiData->invertPhaseSPDI) {
01468             if (that->cm->chipVersion <= 37) {
01469                 that->CMIAdapter->setUInt8Bit(REG_MIXER4, INV_SPDIFI1);
01470             } else {
01471                 that->CMIAdapter->setUInt32Bit(REG_CHFORMAT, INV_SPDIFI2);
01472             }
01473         } else {
01474             if (that->cm->chipVersion <= 37) {
01475                 that->CMIAdapter->clearUInt8Bit(REG_MIXER4, INV_SPDIFI1);
01476             } else {
01477                 that->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, INV_SPDIFI2);
01478             }
01479         }
01480 
01481         that->storeMixerSettingsToRegistry();
01482 
01483         ntStatus = STATUS_SUCCESS;
01484     } else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) {
01485         if (PropertyRequest->ValueSize >= sizeof(ULONG)) {
01486             PULONG AccessFlags = PULONG(PropertyRequest->Value);
01487 
01488             *AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET;
01489 
01490             PropertyRequest->ValueSize = sizeof(ULONG);
01491             ntStatus = STATUS_SUCCESS;
01492         } else {
01493             PropertyRequest->ValueSize = 0;
01494             ntStatus = STATUS_BUFFER_TOO_SMALL;
01495         }
01496     }
01497 
01498     return ntStatus;
01499 }

Generated on Sat May 26 2012 04:27:13 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.