2 Copyright (c) 2006-2007 dogbert <dogber1@gmail.com>
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14 derived from this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "mintopo.hpp"
30 #include "mintopotables.hpp"
31 #define NTSTRSAFE_LIB //for Windows 2000 compatibility
32 #include "NtStrsafe.h"
34 #pragma code_seg("PAGE")
36 const GUID KSPROPSETID_CMI
= {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFF}};
38 HRESULT NTAPI
CreateMiniportTopologyCMI(PUNKNOWN
* Unknown
, REFCLSID
, PUNKNOWN UnknownOuter
, POOL_TYPE PoolType
)
42 STD_CREATE_BODY_(CCMITopology
,Unknown
,UnknownOuter
,PoolType
,PMINIPORTTOPOLOGY
);
45 STDMETHODIMP
CCMITopology::QueryInterface(REFIID Interface
, PVOID
* Object
)
49 DBGPRINT(("CCMITopology::NonDelegatingQueryInterface"));
51 if (IsEqualGUIDAligned(Interface
, IID_IUnknown
)) {
52 *Object
= PVOID(PUNKNOWN(PMINIPORTTOPOLOGY(this)));
53 } else if (IsEqualGUIDAligned(Interface
,IID_IMiniport
)) {
54 *Object
= PVOID(PMINIPORT(this));
55 } else if (IsEqualGUIDAligned(Interface
,IID_IMiniportTopology
)) {
56 *Object
= PVOID(PMINIPORTTOPOLOGY(this));
57 } else if (IsEqualGUIDAligned (Interface
, IID_ICMITopolgy
)) {
58 *Object
= (PVOID
)(PMINIPORTTOPOLOGY
)this;
64 PUNKNOWN(*Object
)->AddRef();
65 return STATUS_SUCCESS
;
68 return STATUS_INVALID_PARAMETER
;
71 CCMITopology::~CCMITopology()
75 DBGPRINT(("CCMITopology::~CCMITopology"));
77 storeMixerSettingsToRegistry(); //or not. during system shutdown, this doesn't seem to work.
78 cm
->TopoMiniport
= NULL
;
81 CMIAdapter
->Release();
85 STDMETHODIMP
CCMITopology::Init(PUNKNOWN UnknownAdapter
, PRESOURCELIST ResourceList
, PPORTTOPOLOGY Port
)
88 //ASSERT(UnknownAdapter);
90 DBGPRINT(("CCMITopology::Init"));
92 NTSTATUS ntStatus
= UnknownAdapter
->QueryInterface(IID_ICMIAdapter
, (PVOID
*)&CMIAdapter
);
94 if (!NT_SUCCESS(ntStatus
)) {
95 DBGPRINT(("UnknownAdapter->QueryInterface() failed"));
96 return STATUS_INVALID_PARAMETER
;
99 CMIAdapter
->resetMixer();
100 auxVolumeRegister
= CMIAdapter
->readUInt8(REG_MIXER3
);
101 micVolumeRegister
= CMIAdapter
->readUInt8(REG_MIXER2
);
102 functrl1Register
= 0;
103 chformatRegister
= 0;
105 miscctrlRegister
= 0;
107 cm
= CMIAdapter
->getCMI8738Info();
108 cm
->TopoMiniport
= this; //this is not really nice
109 loadMixerSettingsFromRegistry();
111 return STATUS_SUCCESS
;
114 STDMETHODIMP
CCMITopology::GetDescription(PPCFILTER_DESCRIPTOR
* OutFilterDescriptor
)
117 //ASSERT(OutFilterDescriptor);
118 DBGPRINT(("CCMITopology::GetDescription"));
120 *OutFilterDescriptor
= &MiniportFilterDescriptor
;
122 return STATUS_SUCCESS
;
125 STDMETHODIMP
CCMITopology::loadMixerSettingsFromRegistry()
128 DBGPRINT(("CCMITopology::loadMixerSettingsFromRegistry"));
130 PREGISTRYKEY DriverKey
;
131 PREGISTRYKEY SettingsKey
;
132 UNICODE_STRING KeyName
;
133 PCPROPERTY_REQUEST PropertyRequest
;
134 PCPROPERTY_ITEM PropertyItem
;
140 if ((!CMIAdapter
) || (!(CMIAdapter
->getDeviceObject()))) {
141 DBGPRINT(("CMIAdapter->getDeviceObject() failed"));
142 return STATUS_UNSUCCESSFUL
;
145 settingsLoaded
= FALSE
;
147 NTSTATUS ntStatus
= PcNewRegistryKey(&DriverKey
, NULL
, DriverRegistryKey
, KEY_ALL_ACCESS
, CMIAdapter
->getDeviceObject(), NULL
, NULL
, 0, NULL
);
149 if(!NT_SUCCESS(ntStatus
)) {
150 DBGPRINT(("PcNewRegistryKey() failed"));
151 return STATUS_UNSUCCESSFUL
;
154 RtlInitUnicodeString(&KeyName
, L
"Settings");
156 ntStatus
= DriverKey
->NewSubKey(&SettingsKey
, NULL
, KEY_ALL_ACCESS
, &KeyName
, REG_OPTION_NON_VOLATILE
, NULL
);
157 if(!NT_SUCCESS(ntStatus
)) {
158 DBGPRINT(("DriverKey->NewSubKey() failed"));
159 return STATUS_UNSUCCESSFUL
;
162 KeyInfo
= ExAllocatePoolWithTag(PagedPool
, sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(DWORD
), 'dbrt');
163 if(KeyInfo
== NULL
) {
164 DBGPRINT(("ExAllocatePoolWithTag() failed"));
165 return STATUS_UNSUCCESSFUL
;
168 PropertyRequest
.MajorTarget
= this;
169 PropertyRequest
.Verb
= KSPROPERTY_TYPE_SET
;
170 PropertyRequest
.Instance
= &Channel
;
171 PropertyRequest
.InstanceSize
= sizeof(DWORD
);
172 PropertyRequest
.Value
= &(PKEY_VALUE_PARTIAL_INFORMATION(KeyInfo
)->Data
);
173 PropertyRequest
.ValueSize
= sizeof(DWORD
);
174 PropertyRequest
.PropertyItem
= &PropertyItem
;
176 for (int i
=0;i
< SIZEOF_ARRAY(TopologyNodes
); i
++) {
177 PropertyRequest
.Node
= i
;
180 ntStatus
= RtlStringCbPrintfW(buffer
, sizeof(buffer
), L
"Node%dLeft", i
);
181 if (!NT_SUCCESS(ntStatus
)) {
182 DBGPRINT(("RtlStringCbPrintfW() failed"));
184 RtlInitUnicodeString(&KeyName
, buffer
);
185 ntStatus
= SettingsKey
->QueryValueKey(&KeyName
, KeyValuePartialInformation
, KeyInfo
, sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(DWORD
), &ResultLength
);
186 if (NT_SUCCESS(ntStatus
)) {
187 if(PKEY_VALUE_PARTIAL_INFORMATION(KeyInfo
)->DataLength
== sizeof(DWORD
)) {
188 if (IsEqualGUIDAligned(*(TopologyNodes
[i
].Type
), KSNODETYPE_VOLUME
)) {
189 PropertyItem
.Id
= KSPROPERTY_AUDIO_VOLUMELEVEL
;
190 PropertyHandler_Level(&PropertyRequest
);
192 if (IsEqualGUIDAligned(*(TopologyNodes
[i
].Type
), KSNODETYPE_MUTE
)) {
193 PropertyItem
.Id
= KSPROPERTY_AUDIO_MUTE
;
194 PropertyHandler_OnOff(&PropertyRequest
);
196 if (IsEqualGUIDAligned(*(TopologyNodes
[i
].Type
), KSNODETYPE_LOUDNESS
)) {
197 PropertyItem
.Id
= KSPROPERTY_AUDIO_LOUDNESS
;
198 PropertyHandler_OnOff(&PropertyRequest
);
203 if (i
== KSNODE_TOPO_IEC_OUT
) {
204 PropertyItem
.Id
= KSPROPERTY_AUDIO_LOUDNESS
;
205 *(PBOOL(PropertyRequest
.Value
)) = true;
206 PropertyHandler_OnOff(&PropertyRequest
);
208 if (i
== KSNODE_TOPO_WAVEOUT_MUTE_IN
) {
209 PropertyItem
.Id
= KSPROPERTY_AUDIO_MUTE
;
210 *(PBOOL(PropertyRequest
.Value
)) = true;
211 PropertyHandler_OnOff(&PropertyRequest
);
213 if (i
== KSNODE_TOPO_CENTER2MIC
) {
214 PropertyItem
.Id
= KSPROPERTY_AUDIO_LOUDNESS
;
215 *(PBOOL(PropertyRequest
.Value
)) = false;
216 PropertyHandler_OnOff(&PropertyRequest
);
220 Channel
= CHAN_RIGHT
;
221 ntStatus
= RtlStringCbPrintfW(buffer
, sizeof(buffer
), L
"Node%dRight", i
);
222 if (!NT_SUCCESS(ntStatus
)) {
223 DBGPRINT(("RtlStringCbPrintfW() failed"));
225 RtlInitUnicodeString(&KeyName
, buffer
);
226 ntStatus
= SettingsKey
->QueryValueKey(&KeyName
, KeyValuePartialInformation
, KeyInfo
, sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(DWORD
), &ResultLength
);
227 if (NT_SUCCESS(ntStatus
)) {
228 if(PKEY_VALUE_PARTIAL_INFORMATION(KeyInfo
)->DataLength
== sizeof(DWORD
)) {
229 if (IsEqualGUIDAligned(*(TopologyNodes
[i
].Type
), KSNODETYPE_VOLUME
)) {
230 PropertyItem
.Id
= KSPROPERTY_AUDIO_VOLUMELEVEL
;
231 PropertyHandler_Level(&PropertyRequest
);
233 if (IsEqualGUIDAligned(*(TopologyNodes
[i
].Type
), KSNODETYPE_MUTE
)) {
234 PropertyItem
.Id
= KSPROPERTY_AUDIO_MUTE
;
235 PropertyHandler_OnOff(&PropertyRequest
);
237 if (IsEqualGUIDAligned(*(TopologyNodes
[i
].Type
), KSNODETYPE_LOUDNESS
)) {
238 PropertyItem
.Id
= KSPROPERTY_AUDIO_LOUDNESS
;
239 PropertyHandler_OnOff(&PropertyRequest
);
243 if (i
== KSNODE_TOPO_WAVEOUT_MUTE_IN
) {
244 PropertyItem
.Id
= KSPROPERTY_AUDIO_MUTE
;
245 *(PBOOL(PropertyRequest
.Value
)) = true;
246 PropertyHandler_OnOff(&PropertyRequest
);
251 RtlInitUnicodeString(&KeyName
, L
"FormatMask");
252 ntStatus
= SettingsKey
->QueryValueKey(&KeyName
, KeyValuePartialInformation
, KeyInfo
, sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(DWORD
), &ResultLength
);
253 if (NT_SUCCESS (ntStatus
)) {
254 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)KeyInfo
;
255 if (PartialInfo
->DataLength
== sizeof(DWORD
)) {
256 cm
->formatMask
= (*(PLONG
)PartialInfo
->Data
);
259 cm
->formatMask
= 0xFFFFFFFF;
262 ExFreePoolWithTag (KeyInfo
,'dbrt');
264 SettingsKey
->Release();
265 DriverKey
->Release();
267 settingsLoaded
= TRUE
;
269 return STATUS_SUCCESS
;
272 STDMETHODIMP
CCMITopology::storeMixerSettingsToRegistry()
275 DBGPRINT(("CCMITopology::storeMixerSettingsToRegistry"));
277 PREGISTRYKEY DriverKey
;
278 PREGISTRYKEY SettingsKey
;
279 UNICODE_STRING KeyName
;
280 PCPROPERTY_REQUEST PropertyRequest
;
281 PCPROPERTY_ITEM PropertyItem
;
285 if ((!CMIAdapter
) || (!(CMIAdapter
->getDeviceObject()))) {
286 return STATUS_UNSUCCESSFUL
;
289 NTSTATUS ntStatus
= PcNewRegistryKey(&DriverKey
, NULL
, DriverRegistryKey
, KEY_ALL_ACCESS
, CMIAdapter
->getDeviceObject(), NULL
, NULL
, 0, NULL
);
291 if(!NT_SUCCESS(ntStatus
)) {
292 DBGPRINT(("PcNewRegistryKey() failed"));
293 return STATUS_UNSUCCESSFUL
;
296 RtlInitUnicodeString(&KeyName
, L
"Settings");
298 ntStatus
= DriverKey
->NewSubKey(&SettingsKey
, NULL
, KEY_ALL_ACCESS
, &KeyName
, REG_OPTION_NON_VOLATILE
, NULL
);
300 if(!NT_SUCCESS(ntStatus
)) {
301 DBGPRINT(("DriverKey->NewSubKey() failed"));
302 return STATUS_UNSUCCESSFUL
;
305 PropertyRequest
.MajorTarget
= this;
306 PropertyRequest
.Verb
= KSPROPERTY_TYPE_GET
;
307 PropertyRequest
.Instance
= &Channel
;
308 PropertyRequest
.InstanceSize
= sizeof(DWORD
);
309 PropertyRequest
.Value
= &Value
;
310 PropertyRequest
.ValueSize
= sizeof(DWORD
);
311 PropertyRequest
.PropertyItem
= &PropertyItem
;
313 for (int i
=0;i
< SIZEOF_ARRAY(TopologyNodes
); i
++) {
314 PropertyRequest
.Node
= i
;
315 if (IsEqualGUIDAligned(*(TopologyNodes
[i
].Type
), KSNODETYPE_VOLUME
)) {
316 PropertyRequest
.Node
= i
;
317 PropertyItem
.Id
= KSPROPERTY_AUDIO_VOLUMELEVEL
;
319 ntStatus
= RtlStringCbPrintfW(buffer
, sizeof(buffer
), L
"Node%dLeft", i
);
320 if (!NT_SUCCESS(ntStatus
)) {
321 DBGPRINT(("RtlStringCbPrintfW() failed"));
323 RtlInitUnicodeString(&KeyName
, buffer
);
325 ntStatus
= PropertyHandler_Level(&PropertyRequest
);
326 if (NT_SUCCESS(ntStatus
)) {
327 ntStatus
= SettingsKey
->SetValueKey(&KeyName
, REG_DWORD
, PVOID(&Value
), sizeof(DWORD
));
328 if(!NT_SUCCESS(ntStatus
)) {
329 DBGPRINT(("SetValueKey() failed"));
334 ntStatus
= RtlStringCbPrintfW(buffer
, sizeof(buffer
), L
"Node%dRight", i
);
335 if (!NT_SUCCESS(ntStatus
)) {
336 DBGPRINT(("RtlStringCbPrintfW() failed"));
338 RtlInitUnicodeString(&KeyName
, buffer
);
339 Channel
= CHAN_RIGHT
;
340 ntStatus
= PropertyHandler_Level(&PropertyRequest
);
341 if (NT_SUCCESS(ntStatus
)) {
342 ntStatus
= SettingsKey
->SetValueKey(&KeyName
, REG_DWORD
, PVOID(&Value
), sizeof(DWORD
));
343 if(!NT_SUCCESS(ntStatus
)) {
344 DBGPRINT(("SetValueKey() failed"));
350 if (IsEqualGUIDAligned(*(TopologyNodes
[i
].Type
), KSNODETYPE_MUTE
)) {
351 PropertyItem
.Id
= KSPROPERTY_AUDIO_MUTE
;
352 PropertyHandler_OnOff(&PropertyRequest
);
354 ntStatus
= RtlStringCbPrintfW(buffer
, sizeof(buffer
), L
"Node%dLeft", i
);
355 if (!NT_SUCCESS(ntStatus
)) {
356 DBGPRINT(("RtlStringCbPrintfW() failed"));
358 RtlInitUnicodeString(&KeyName
, buffer
);
360 ntStatus
= PropertyHandler_OnOff(&PropertyRequest
);
361 if (NT_SUCCESS(ntStatus
)) {
362 ntStatus
= SettingsKey
->SetValueKey(&KeyName
, REG_DWORD
, PVOID(&Value
), sizeof(DWORD
));
363 if(!NT_SUCCESS(ntStatus
)) {
364 DBGPRINT(("SetValueKey() failed"));
369 ntStatus
= RtlStringCbPrintfW(buffer
, sizeof(buffer
), L
"Node%dRight", i
);
370 if (!NT_SUCCESS(ntStatus
)) {
371 DBGPRINT(("RtlStringCbPrintfW() failed"));
373 RtlInitUnicodeString(&KeyName
, buffer
);
374 Channel
= CHAN_RIGHT
;
375 ntStatus
= PropertyHandler_OnOff(&PropertyRequest
);
376 if (NT_SUCCESS(ntStatus
)) {
377 ntStatus
= SettingsKey
->SetValueKey(&KeyName
, REG_DWORD
, PVOID(&Value
), sizeof(DWORD
));
378 if(!NT_SUCCESS(ntStatus
)) {
379 DBGPRINT(("SetValueKey() failed"));
384 if (IsEqualGUIDAligned(*(TopologyNodes
[i
].Type
), KSNODETYPE_LOUDNESS
)) {
385 PropertyItem
.Id
= KSPROPERTY_AUDIO_LOUDNESS
;
386 PropertyHandler_OnOff(&PropertyRequest
);
388 ntStatus
= RtlStringCbPrintfW(buffer
, sizeof(buffer
), L
"Node%dLeft", i
);
389 if (!NT_SUCCESS(ntStatus
)) {
390 DBGPRINT(("RtlStringCbPrintfW() failed"));
392 RtlInitUnicodeString(&KeyName
, buffer
);
394 ntStatus
= PropertyHandler_OnOff(&PropertyRequest
);
395 if (NT_SUCCESS(ntStatus
)) {
396 ntStatus
= SettingsKey
->SetValueKey(&KeyName
, REG_DWORD
, PVOID(&Value
), sizeof(DWORD
));
397 if(!NT_SUCCESS(ntStatus
)) {
398 DBGPRINT(("SetValueKey() failed"));
403 ntStatus
= RtlStringCbPrintfW(buffer
, sizeof(buffer
), L
"Node%dRight", i
);
404 if (!NT_SUCCESS(ntStatus
)) {
405 DBGPRINT(("RtlStringCbPrintfW() failed"));
407 RtlInitUnicodeString(&KeyName
, buffer
);
408 Channel
= CHAN_RIGHT
;
409 ntStatus
= PropertyHandler_OnOff(&PropertyRequest
);
410 if (NT_SUCCESS(ntStatus
)) {
411 ntStatus
= SettingsKey
->SetValueKey(&KeyName
, REG_DWORD
, PVOID(&Value
), sizeof(DWORD
));
412 if(!NT_SUCCESS(ntStatus
)) {
413 DBGPRINT(("SetValueKey() failed"));
419 Value
= cm
->formatMask
;
420 RtlInitUnicodeString(&KeyName
, L
"FormatMask");
421 ntStatus
= SettingsKey
->SetValueKey(&KeyName
, REG_DWORD
, PVOID(&Value
), sizeof(DWORD
));
422 if (!NT_SUCCESS(ntStatus
)) {
423 DBGPRINT(("SetValueKey() failed"));
426 SettingsKey
->Release();
427 DriverKey
->Release();
429 return STATUS_SUCCESS
;
432 STDMETHODIMP
CCMITopology::loadMixerSettingsFromMemory()
435 DBGPRINT(("CCMITopology::loadMixerSettingsFromMemory"));
437 CMIAdapter
->resetMixer();
438 CMIAdapter
->loadSBMixerFromMemory();
439 CMIAdapter
->writeUInt8(REG_MIXER1
, mixer1Register
);
440 CMIAdapter
->writeUInt8(REG_MIXER2
, auxVolumeRegister
);
441 CMIAdapter
->writeUInt8(REG_MIXER3
, micVolumeRegister
);
442 CMIAdapter
->writeUInt8(REG_MIXER4
, mixer4Register
);
444 CMIAdapter
->setUInt32Bit(REG_FUNCTRL1
, functrl1Register
);
445 CMIAdapter
->setUInt32Bit(REG_CHFORMAT
, chformatRegister
);
446 CMIAdapter
->setUInt32Bit(REG_LEGACY
, legacyRegister
);
447 CMIAdapter
->setUInt32Bit(REG_MISCCTRL
, miscctrlRegister
);
449 return STATUS_SUCCESS
;
452 STDMETHODIMP
CCMITopology::storeMixerSettingsToMemory()
455 DBGPRINT(("CCMITopology::storeMixerSettingsToMemory"));
457 mixer1Register
= CMIAdapter
->readUInt8(REG_MIXER1
);
458 mixer4Register
= CMIAdapter
->readUInt8(REG_MIXER4
);
459 functrl1Register
= CMIAdapter
->readUInt32(REG_FUNCTRL1
) & LOOP_SPDF
;
460 chformatRegister
= CMIAdapter
->readUInt32(REG_CHFORMAT
) & (INV_SPDIFI1
| SEL_SPDIFI1
| POLVALID
);
461 legacyRegister
= CMIAdapter
->readUInt32(REG_LEGACY
) & (BASS2LINE
| CENTER2LINE
| EN_SPDCOPYRHT
);
462 miscctrlRegister
= CMIAdapter
->readUInt32(REG_MISCCTRL
) & (EN_SPDO5V
| SEL_SPDIFI2
);
464 return STATUS_SUCCESS
;
467 NTSTATUS NTAPI
PropertyHandler_OnOff(PPCPROPERTY_REQUEST PropertyRequest
)
470 //ASSERT(PropertyRequest);
471 DBGPRINT(("[PropertyHandler_OnOff]"));
473 CCMITopology
*that
= (CCMITopology
*) ((PMINIPORTTOPOLOGY
) PropertyRequest
->MajorTarget
);
475 NTSTATUS ntStatus
= STATUS_INVALID_PARAMETER
;
476 UInt8 data
, mask
, reg
;
479 if (PropertyRequest
->Node
== ULONG(-1)) {
483 if ( ((PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) || (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
)) && (PropertyRequest
->InstanceSize
>= sizeof(LONG
)) ) {
484 channel
= *(PLONG(PropertyRequest
->Instance
));
485 if (PropertyRequest
->ValueSize
>= sizeof(BOOL
)) {
487 if (PropertyRequest
->PropertyItem
->Id
== KSPROPERTY_AUDIO_MUTE
) {
488 PBOOL Muted
= PBOOL(PropertyRequest
->Value
);
489 switch (PropertyRequest
->Node
) {
491 case KSNODE_TOPO_WAVEOUT_MUTE
:
492 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
493 *Muted
= (that
->CMIAdapter
->readUInt8(REG_MIXER1
) & MUTE_WAVE
);
495 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
497 that
->CMIAdapter
->setUInt8Bit(REG_MIXER1
, MUTE_WAVE
);
499 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER1
, MUTE_WAVE
);
502 ntStatus
= STATUS_SUCCESS
;
505 case KSNODE_TOPO_AUX_MUTE
:
507 case CHAN_LEFT
: mask
= MUTE_AUX_L
; break;
508 case CHAN_RIGHT
: mask
= MUTE_AUX_R
; break;
509 default: return ntStatus
;
512 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
513 *Muted
= !(that
->micVolumeRegister
& mask
);
515 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
517 that
->micVolumeRegister
&= ~mask
;
519 that
->micVolumeRegister
|= mask
;
521 that
->CMIAdapter
->writeUInt8(REG_MIXER2
, that
->micVolumeRegister
);
523 ntStatus
= STATUS_SUCCESS
;
526 case KSNODE_TOPO_MICOUT_MUTE
:
527 if (channel
!= CHAN_LEFT
) {
531 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
532 *Muted
= !(that
->CMIAdapter
->readMixer(SBREG_OUTPUTCTRL
) & EN_MIC
);
534 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
536 that
->CMIAdapter
->clearMixerBit(SBREG_OUTPUTCTRL
, EN_MIC
);
538 that
->CMIAdapter
->setMixerBit(SBREG_OUTPUTCTRL
, EN_MIC
);
541 ntStatus
= STATUS_SUCCESS
;
544 case KSNODE_TOPO_CD_MUTE
:
546 case CHAN_LEFT
: mask
= EN_CD_L
; break;
547 case CHAN_RIGHT
: mask
= EN_CD_R
; break;
548 default: return ntStatus
;
550 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
551 *Muted
= !(that
->CMIAdapter
->readMixer(SBREG_OUTPUTCTRL
) & mask
);
553 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
555 that
->CMIAdapter
->clearMixerBit(SBREG_OUTPUTCTRL
, mask
);
557 that
->CMIAdapter
->setMixerBit(SBREG_OUTPUTCTRL
, mask
);
560 ntStatus
= STATUS_SUCCESS
;
563 case KSNODE_TOPO_LINEIN_MUTE
:
565 case CHAN_LEFT
: mask
= EN_LINEIN_L
; break;
566 case CHAN_RIGHT
: mask
= EN_LINEIN_R
; break;
567 default: return ntStatus
;
569 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
570 *Muted
= !(that
->CMIAdapter
->readMixer(SBREG_OUTPUTCTRL
) & mask
);
572 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
574 that
->CMIAdapter
->clearMixerBit(SBREG_OUTPUTCTRL
, mask
);
576 that
->CMIAdapter
->setMixerBit(SBREG_OUTPUTCTRL
, mask
);
579 ntStatus
= STATUS_SUCCESS
;
582 case KSNODE_TOPO_MIC_MUTE_IN
:
583 if (channel
!= CHAN_LEFT
) {
586 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
587 *Muted
= !(that
->CMIAdapter
->readMixer(SBREG_IN_CTRL_L
) & EN_MIC
);
589 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
591 that
->CMIAdapter
->clearMixerBit(SBREG_IN_CTRL_L
, EN_MIC
);
592 that
->CMIAdapter
->clearMixerBit(SBREG_IN_CTRL_R
, EN_MIC
);
594 that
->CMIAdapter
->setMixerBit(SBREG_IN_CTRL_L
, EN_MIC
);
595 that
->CMIAdapter
->setMixerBit(SBREG_IN_CTRL_R
, EN_MIC
);
598 ntStatus
= STATUS_SUCCESS
;
601 case KSNODE_TOPO_CD_MUTE_IN
:
603 case CHAN_LEFT
: mask
= EN_LINEIN_L
; reg
= EN_CD_L
; break;
604 case CHAN_RIGHT
: mask
= EN_LINEIN_R
; reg
= EN_CD_R
; break;
605 default: return ntStatus
;
607 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
608 *Muted
= !(that
->CMIAdapter
->readMixer(reg
) & mask
);
610 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
612 that
->CMIAdapter
->clearMixerBit(reg
, mask
);
614 that
->CMIAdapter
->setMixerBit(reg
, mask
);
617 ntStatus
= STATUS_SUCCESS
;
620 case KSNODE_TOPO_LINEIN_MUTE_IN
:
622 case CHAN_LEFT
: mask
= EN_LINEIN_L
; reg
= SBREG_IN_CTRL_L
; break;
623 case CHAN_RIGHT
: mask
= EN_LINEIN_R
; reg
= SBREG_IN_CTRL_R
; break;
624 default: return ntStatus
;
626 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
627 *Muted
= !(that
->CMIAdapter
->readMixer(reg
) & mask
);
629 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
631 that
->CMIAdapter
->clearMixerBit(reg
, mask
);
633 that
->CMIAdapter
->setMixerBit(reg
, mask
);
636 ntStatus
= STATUS_SUCCESS
;
640 case KSNODE_TOPO_AUX_MUTE_IN
:
642 case CHAN_LEFT
: mask
= MUTE_RAUX_L
; break;
643 case CHAN_RIGHT
: mask
= MUTE_RAUX_R
; break;
644 default: return ntStatus
;
646 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
647 *Muted
= (that
->micVolumeRegister
& mask
) ;
649 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
651 that
->micVolumeRegister
|= mask
;
653 that
->micVolumeRegister
&= ~mask
;
655 that
->CMIAdapter
->writeUInt8(REG_MIXER2
, that
->micVolumeRegister
);
657 ntStatus
= STATUS_SUCCESS
;
660 case KSNODE_TOPO_WAVEOUT_MUTE_IN
:
662 case CHAN_LEFT
: mask
= EN_WAVEIN_L
; break;
663 case CHAN_RIGHT
: mask
= EN_WAVEIN_R
; break;
664 default: return ntStatus
;
666 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
667 // *Muted = !(that->CMIAdapter->readUInt8(REG_MIXER1) & mask);
668 *Muted
= !(that
->cm
->enableSPDIFIn
);
669 ntStatus
= STATUS_SUCCESS
;
671 if ((PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) && !(that
->settingsLoaded
)) {
673 that
->cm
->enableSPDIFIn
= FALSE
;
674 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER1
, mask
);
676 that
->cm
->enableSPDIFIn
= TRUE
;
677 that
->CMIAdapter
->setUInt8Bit(REG_MIXER1
, mask
);
679 ntStatus
= STATUS_SUCCESS
;
683 case KSNODE_TOPO_MASTER_MUTE_DUMMY
:
684 channel
= (1 << channel
);
685 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
686 *Muted
= that
->masterMuteDummy
& channel
;
688 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
690 that
->masterMuteDummy
|= channel
;
692 that
->masterMuteDummy
&= ~channel
;
695 ntStatus
= STATUS_SUCCESS
;
700 if (PropertyRequest
->PropertyItem
->Id
== KSPROPERTY_AUDIO_LOUDNESS
) {
701 PBOOL LoudnessOn
= PBOOL(PropertyRequest
->Value
);
702 switch (PropertyRequest
->Node
) {
703 case KSNODE_TOPO_MICIN_LOUDNESS
:
704 if (channel
== CHAN_LEFT
) {
705 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
706 *LoudnessOn
= (that
->CMIAdapter
->readMixer(SBREG_EXTENSION
) & EN_MICBOOST
);
708 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
709 // DBGPRINT(("setting mic boost: previous state %d, new state %d", (that->CMIAdapter->readMixer(SBREG_EXTENSION) & EN_MICBOOST), (*LoudnessOn)));
711 that
->CMIAdapter
->setMixerBit(SBREG_EXTENSION
, EN_MICBOOST
);
713 that
->CMIAdapter
->clearMixerBit(SBREG_EXTENSION
, EN_MICBOOST
);
716 ntStatus
= STATUS_SUCCESS
;
719 case KSNODE_TOPO_MICOUT_LOUDNESS
:
720 if (channel
== CHAN_LEFT
) {
721 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
722 *LoudnessOn
= !(that
->CMIAdapter
->readUInt8(REG_MIXER2
) & DIS_MICGAIN
);
724 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
726 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER2
, DIS_MICGAIN
);
728 that
->CMIAdapter
->setUInt8Bit(REG_MIXER2
, DIS_MICGAIN
);
731 ntStatus
= STATUS_SUCCESS
;
734 case KSNODE_TOPO_IEC_5V
:
735 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
736 *LoudnessOn
= (that
->CMIAdapter
->readUInt32(REG_MISCCTRL
) & EN_SPDO5V
);
738 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
740 that
->CMIAdapter
->setUInt32Bit(REG_MISCCTRL
, EN_SPDO5V
);
742 that
->CMIAdapter
->clearUInt32Bit(REG_MISCCTRL
, EN_SPDO5V
);
745 ntStatus
= STATUS_SUCCESS
;
747 case KSNODE_TOPO_IEC_OUT
:
748 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
750 *LoudnessOn
= that
->cm
->enableSPDIFOut
;
753 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
755 that
->cm
->enableSPDIFOut
= (*LoudnessOn
);
758 ntStatus
= STATUS_SUCCESS
;
761 case KSNODE_TOPO_IEC_INVERSE
:
762 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
763 if (that
->cm
->chipVersion
<= 37) {
764 *LoudnessOn
= (that
->CMIAdapter
->readUInt8(REG_MIXER4
) & INV_SPDIFI1
);
766 *LoudnessOn
= (that
->CMIAdapter
->readUInt32(REG_CHFORMAT
) & INV_SPDIFI2
);
769 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
771 if (that
->cm
->chipVersion
<= 37) {
772 that
->CMIAdapter
->setUInt8Bit(REG_MIXER4
, INV_SPDIFI1
);
774 that
->CMIAdapter
->setUInt32Bit(REG_CHFORMAT
, INV_SPDIFI2
);
777 if (that
->cm
->chipVersion
<= 37) {
778 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER4
, INV_SPDIFI1
);
780 that
->CMIAdapter
->clearUInt32Bit(REG_CHFORMAT
, INV_SPDIFI2
);
784 ntStatus
= STATUS_SUCCESS
;
787 case KSNODE_TOPO_IEC_MONITOR
:
788 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
789 *LoudnessOn
= (that
->CMIAdapter
->readUInt8(REG_MIXER1
) & EN_SPDI2DAC
);
791 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
793 that
->CMIAdapter
->setUInt8Bit(REG_MIXER1
, EN_SPDI2DAC
);
795 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER1
, EN_SPDI2DAC
);
798 ntStatus
= STATUS_SUCCESS
;
801 case KSNODE_TOPO_IEC_SELECT
:
802 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
803 if (that
->cm
->chipVersion
<= 37) {
804 *LoudnessOn
= (that
->CMIAdapter
->readUInt32(REG_CHFORMAT
) & SEL_SPDIFI1
);
806 *LoudnessOn
= (that
->CMIAdapter
->readUInt32(REG_MISCCTRL
) & SEL_SPDIFI2
);
809 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
811 if (that
->cm
->chipVersion
<= 37) {
812 that
->CMIAdapter
->setUInt32Bit(REG_CHFORMAT
, SEL_SPDIFI1
);
814 that
->CMIAdapter
->setUInt32Bit(REG_MISCCTRL
, SEL_SPDIFI2
);
817 if (that
->cm
->chipVersion
<= 37) {
818 that
->CMIAdapter
->clearUInt32Bit(REG_CHFORMAT
, SEL_SPDIFI1
);
820 that
->CMIAdapter
->clearUInt32Bit(REG_MISCCTRL
, SEL_SPDIFI2
);
824 ntStatus
= STATUS_SUCCESS
;
827 case KSNODE_TOPO_XCHG_FB
:
828 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
829 *LoudnessOn
= (that
->CMIAdapter
->readUInt8(REG_MIXER1
) & REAR2FRONT
);
831 if ((PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) && !(that
->settingsLoaded
)) {
833 that
->CMIAdapter
->setUInt8Bit(REG_MIXER1
, REAR2FRONT
);
835 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER1
, REAR2FRONT
);
838 ntStatus
= STATUS_SUCCESS
;
841 case KSNODE_TOPO_BASS2LINE
:
842 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
843 *LoudnessOn
= (that
->CMIAdapter
->readUInt32(REG_LEGACY
) & BASS2LINE
);
845 if ((PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) && !(that
->settingsLoaded
)) {
847 that
->CMIAdapter
->setUInt32Bit(REG_LEGACY
, BASS2LINE
);
849 that
->CMIAdapter
->clearUInt32Bit(REG_LEGACY
, BASS2LINE
);
852 ntStatus
= STATUS_SUCCESS
;
855 case KSNODE_TOPO_CENTER2LINE
:
856 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
857 *LoudnessOn
= (that
->CMIAdapter
->readUInt32(REG_LEGACY
) & CENTER2LINE
);
859 if ((PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) && !(that
->settingsLoaded
)) {
861 that
->CMIAdapter
->setUInt32Bit(REG_LEGACY
, CENTER2LINE
);
863 that
->CMIAdapter
->clearUInt32Bit(REG_LEGACY
, CENTER2LINE
);
866 ntStatus
= STATUS_SUCCESS
;
869 case KSNODE_TOPO_IEC_COPYRIGHT
:
870 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
871 *LoudnessOn
= (that
->CMIAdapter
->readUInt32(REG_LEGACY
) & EN_SPDCOPYRHT
);
873 if ((PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) && !(that
->settingsLoaded
)) {
875 that
->CMIAdapter
->setUInt32Bit(REG_LEGACY
, EN_SPDCOPYRHT
);
877 that
->CMIAdapter
->clearUInt32Bit(REG_LEGACY
, EN_SPDCOPYRHT
);
880 ntStatus
= STATUS_SUCCESS
;
883 case KSNODE_TOPO_IEC_POLVALID
:
884 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
885 *LoudnessOn
= (that
->CMIAdapter
->readUInt32(REG_CHFORMAT
) & POLVALID
);
887 if ((PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) && !(that
->settingsLoaded
)) {
889 that
->CMIAdapter
->setUInt32Bit(REG_CHFORMAT
, POLVALID
);
891 that
->CMIAdapter
->clearUInt32Bit(REG_CHFORMAT
, POLVALID
);
894 ntStatus
= STATUS_SUCCESS
;
897 case KSNODE_TOPO_IEC_LOOP
:
898 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
899 *LoudnessOn
= (that
->CMIAdapter
->readUInt32(REG_FUNCTRL1
) & LOOP_SPDF
);
901 if ((PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) && !(that
->settingsLoaded
)) {
903 that
->CMIAdapter
->setUInt32Bit(REG_FUNCTRL1
, LOOP_SPDF
);
905 that
->CMIAdapter
->clearUInt32Bit(REG_FUNCTRL1
, LOOP_SPDF
);
908 ntStatus
= STATUS_SUCCESS
;
911 case KSNODE_TOPO_REAR2LINE
:
912 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
913 *LoudnessOn
= (that
->CMIAdapter
->readUInt8(REG_MIXER1
) & REAR2LINE
);
915 if ((PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) && !(that
->settingsLoaded
)) {
917 that
->CMIAdapter
->setUInt8Bit(REG_MIXER1
, REAR2LINE
);
919 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER1
, REAR2LINE
);
922 ntStatus
= STATUS_SUCCESS
;
925 case KSNODE_TOPO_CENTER2MIC
:
926 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
927 *LoudnessOn
= (that
->CMIAdapter
->readUInt8(REG_MIXER4
) & CENTER2MIC
) && (that
->cm
->chipVersion
> 37);
929 if ((PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) && !(that
->settingsLoaded
) && (that
->cm
->chipVersion
> 37)) {
931 that
->CMIAdapter
->setUInt8Bit(REG_MIXER4
, CENTER2MIC
);
933 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER4
, CENTER2MIC
);
936 ntStatus
= STATUS_SUCCESS
;
941 if ((NT_SUCCESS(ntStatus
)) && (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
)) {
942 PropertyRequest
->ValueSize
= sizeof(BOOL
);
946 } else if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_BASICSUPPORT
) {
947 bool supported
= false;
948 if (PropertyRequest
->PropertyItem
->Id
== KSPROPERTY_AUDIO_MUTE
) {
949 switch (PropertyRequest
->Node
) {
950 case KSNODE_TOPO_CD_MUTE
:
951 case KSNODE_TOPO_LINEIN_MUTE
:
952 case KSNODE_TOPO_MICOUT_MUTE
:
953 case KSNODE_TOPO_AUX_MUTE
:
954 case KSNODE_TOPO_WAVEOUT_MUTE
:
955 case KSNODE_TOPO_LINEIN_MUTE_IN
:
956 case KSNODE_TOPO_MIC_MUTE_IN
:
957 case KSNODE_TOPO_CD_MUTE_IN
:
958 case KSNODE_TOPO_AUX_MUTE_IN
:
959 case KSNODE_TOPO_WAVEOUT_MUTE_IN
:
960 case KSNODE_TOPO_MASTER_MUTE_DUMMY
:
965 if (PropertyRequest
->PropertyItem
->Id
== KSPROPERTY_AUDIO_LOUDNESS
) {
966 switch (PropertyRequest
->Node
) {
967 case KSNODE_TOPO_MICIN_LOUDNESS
:
968 case KSNODE_TOPO_MICOUT_LOUDNESS
:
969 case KSNODE_TOPO_IEC_5V
:
970 case KSNODE_TOPO_IEC_OUT
:
971 case KSNODE_TOPO_IEC_INVERSE
:
972 case KSNODE_TOPO_IEC_MONITOR
:
973 case KSNODE_TOPO_IEC_SELECT
:
974 case KSNODE_TOPO_XCHG_FB
:
975 case KSNODE_TOPO_BASS2LINE
:
976 case KSNODE_TOPO_CENTER2LINE
:
977 case KSNODE_TOPO_IEC_COPYRIGHT
:
978 case KSNODE_TOPO_IEC_POLVALID
:
979 case KSNODE_TOPO_IEC_LOOP
:
980 case KSNODE_TOPO_REAR2LINE
:
983 if ((PropertyRequest
->Node
== KSNODE_TOPO_CENTER2MIC
) && (that
->cm
->chipVersion
> 37)) {
989 if (PropertyRequest
->ValueSize
>= (sizeof(KSPROPERTY_DESCRIPTION
))) {
990 PKSPROPERTY_DESCRIPTION PropDesc
= PKSPROPERTY_DESCRIPTION(PropertyRequest
->Value
);
992 PropDesc
->AccessFlags
= KSPROPERTY_TYPE_GET
| KSPROPERTY_TYPE_SET
| KSPROPERTY_TYPE_BASICSUPPORT
;
993 PropDesc
->DescriptionSize
= sizeof(KSPROPERTY_DESCRIPTION
);
994 PropDesc
->PropTypeSet
.Set
= KSPROPTYPESETID_General
;
995 PropDesc
->PropTypeSet
.Id
= VT_BOOL
;
996 PropDesc
->PropTypeSet
.Flags
= 0;
997 PropDesc
->MembersListCount
= 0;
998 PropDesc
->Reserved
= 0;
1000 PropertyRequest
->ValueSize
= sizeof(KSPROPERTY_DESCRIPTION
);
1001 ntStatus
= STATUS_SUCCESS
;
1002 } else if (PropertyRequest
->ValueSize
>= sizeof(ULONG
)) {
1003 PULONG AccessFlags
= PULONG(PropertyRequest
->Value
);
1005 *AccessFlags
= KSPROPERTY_TYPE_GET
| KSPROPERTY_TYPE_SET
| KSPROPERTY_TYPE_BASICSUPPORT
;
1007 PropertyRequest
->ValueSize
= sizeof(ULONG
);
1008 ntStatus
= STATUS_SUCCESS
;
1016 static NTSTATUS
BasicSupportHandler(PPCPROPERTY_REQUEST PropertyRequest
)
1019 //ASSERT(PropertyRequest);
1020 DBGPRINT(("[BasicSupportHandler]"));
1022 NTSTATUS ntStatus
= STATUS_INVALID_DEVICE_REQUEST
;
1024 if (PropertyRequest
->ValueSize
>= (sizeof(KSPROPERTY_DESCRIPTION
))) {
1025 PKSPROPERTY_DESCRIPTION PropDesc
= PKSPROPERTY_DESCRIPTION(PropertyRequest
->Value
);
1027 PropDesc
->AccessFlags
= KSPROPERTY_TYPE_BASICSUPPORT
| KSPROPERTY_TYPE_GET
| KSPROPERTY_TYPE_SET
;
1028 PropDesc
->DescriptionSize
= sizeof(KSPROPERTY_DESCRIPTION
) + sizeof(KSPROPERTY_MEMBERSHEADER
) + sizeof(KSPROPERTY_STEPPING_LONG
);
1029 PropDesc
->PropTypeSet
.Set
= KSPROPTYPESETID_General
;
1030 PropDesc
->PropTypeSet
.Id
= VT_I4
;
1031 PropDesc
->PropTypeSet
.Flags
= 0;
1032 PropDesc
->MembersListCount
= 1;
1033 PropDesc
->Reserved
= 0;
1035 if (PropertyRequest
->ValueSize
>= (sizeof(KSPROPERTY_DESCRIPTION
) + sizeof(KSPROPERTY_MEMBERSHEADER
) + sizeof(KSPROPERTY_STEPPING_LONG
))) {
1036 PKSPROPERTY_MEMBERSHEADER Members
= PKSPROPERTY_MEMBERSHEADER(PropDesc
+ 1);
1038 Members
->MembersFlags
= KSPROPERTY_MEMBER_STEPPEDRANGES
;
1039 Members
->MembersSize
= sizeof(KSPROPERTY_STEPPING_LONG
);
1040 Members
->MembersCount
= 1;
1043 PKSPROPERTY_STEPPING_LONG Range
= PKSPROPERTY_STEPPING_LONG(Members
+ 1);
1045 for (int i
=0;i
<SIZEOF_ARRAY(VolTable
);i
++) {
1046 if (VolTable
[i
].node
== PropertyRequest
->Node
) {
1047 Range
->Bounds
.SignedMaximum
= (VolTable
[i
].max
<< 16);
1048 Range
->Bounds
.SignedMinimum
= (VolTable
[i
].min
<< 16);
1049 Range
->SteppingDelta
= (VolTable
[i
].step
<< 16);
1050 ntStatus
= STATUS_SUCCESS
;
1053 if (!NT_SUCCESS(ntStatus
)) {
1054 switch (PropertyRequest
->Node
) {
1055 case KSNODE_TOPO_AUX_VOLUME
:
1056 Range
->Bounds
.SignedMaximum
= 0;
1057 Range
->Bounds
.SignedMinimum
= (-60 << 16);
1058 Range
->SteppingDelta
= (4 << 16);
1059 ntStatus
= STATUS_SUCCESS
;
1061 case KSNODE_TOPO_MICIN_VOLUME
:
1062 Range
->Bounds
.SignedMaximum
= 0;
1063 Range
->Bounds
.SignedMinimum
= (-56 << 16);
1064 Range
->SteppingDelta
= (8 << 16);
1065 ntStatus
= STATUS_SUCCESS
;
1069 Range
->Reserved
= 0;
1071 PropertyRequest
->ValueSize
= sizeof(KSPROPERTY_DESCRIPTION
) + sizeof(KSPROPERTY_MEMBERSHEADER
) + sizeof(KSPROPERTY_STEPPING_LONG
);
1073 PropertyRequest
->ValueSize
= sizeof(KSPROPERTY_DESCRIPTION
);
1074 ntStatus
= STATUS_SUCCESS
;
1076 } else if (PropertyRequest
->ValueSize
>= sizeof(ULONG
)) {
1077 PULONG AccessFlags
= PULONG(PropertyRequest
->Value
);
1078 *AccessFlags
= KSPROPERTY_TYPE_BASICSUPPORT
| KSPROPERTY_TYPE_GET
| KSPROPERTY_TYPE_SET
;
1079 PropertyRequest
->ValueSize
= sizeof(ULONG
);
1080 ntStatus
= STATUS_SUCCESS
;
1086 NTSTATUS NTAPI
PropertyHandler_Level(PPCPROPERTY_REQUEST PropertyRequest
)
1089 //ASSERT(PropertyRequest);
1090 DBGPRINT(("[PropertyHandler_Level]"));
1092 CCMITopology
*that
= (CCMITopology
*) ((PMINIPORTTOPOLOGY
) PropertyRequest
->MajorTarget
);
1093 NTSTATUS ntStatus
= STATUS_INVALID_PARAMETER
;
1097 if ((PropertyRequest
->Node
== ULONG(-1)) || (PropertyRequest
->Node
>= KSNODE_TOPO_INVALID
) || (PropertyRequest
->PropertyItem
->Id
!= KSPROPERTY_AUDIO_VOLUMELEVEL
)) {
1101 if ( ((PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) || (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
)) && (PropertyRequest
->InstanceSize
>= sizeof(LONG
)) ) {
1103 channel
= *(PLONG(PropertyRequest
->Instance
));
1105 if ((PropertyRequest
->Node
== KSNODE_TOPO_MICOUT_VOLUME
) && (channel
!= CHAN_LEFT
)) {
1106 return STATUS_INVALID_PARAMETER
;
1109 if ( ( (channel
== CHAN_LEFT
) || (channel
== CHAN_RIGHT
) ) && (PropertyRequest
->ValueSize
>= sizeof(LONG
))) {
1111 PLONG Level
= (PLONG
)PropertyRequest
->Value
;
1113 for (int i
=0;i
<SIZEOF_ARRAY(VolTable
);i
++)
1115 if (VolTable
[i
].node
== PropertyRequest
->Node
) {
1116 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
1118 mixerValue
= (that
->CMIAdapter
->readMixer(VolTable
[i
].reg
+channel
) >> VolTable
[i
].shift
) & VolTable
[i
].mask
;
1119 *Level
= that
->NodeCache
[(2*PropertyRequest
->Node
)+channel
];
1121 if (mixerValue
!= ((*Level
>> (VolTable
[i
].dbshift
+16))+VolTable
[i
].mask
)) {
1122 *Level
= (mixerValue
- VolTable
[i
].mask
) << (16+VolTable
[i
].dbshift
);
1123 that
->NodeCache
[(2*PropertyRequest
->Node
)+channel
] = *Level
;
1126 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
1127 if (*Level
<= (VolTable
[i
].min
<< 16)) {
1129 that
->NodeCache
[(2*PropertyRequest
->Node
)+channel
] = VolTable
[i
].min
<< 16;
1131 if (*Level
>= (VolTable
[i
].max
<< 16)) {
1132 mixerValue
= VolTable
[i
].mask
;
1133 that
->NodeCache
[(2*PropertyRequest
->Node
)+channel
] = VolTable
[i
].max
<< 16;
1135 mixerValue
= ((*Level
>> (VolTable
[i
].dbshift
+16)) + VolTable
[i
].mask
) & VolTable
[i
].mask
;
1136 that
->NodeCache
[(2*PropertyRequest
->Node
)+channel
] = *Level
;
1138 that
->CMIAdapter
->writeMixer(VolTable
[i
].reg
+channel
, mixerValue
<< VolTable
[i
].shift
);
1140 ntStatus
= STATUS_SUCCESS
;
1143 if (PropertyRequest
->Node
== KSNODE_TOPO_AUX_VOLUME
) {
1144 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
1145 mixerValue
= that
->auxVolumeRegister
;
1146 *Level
= that
->NodeCache
[(2*PropertyRequest
->Node
)+channel
];
1147 if (channel
== CHAN_LEFT
) {
1151 if (mixerValue
!= ((*Level
>> 18)+0x0F)) {
1152 *Level
= (mixerValue
- 0x0F) << 18;
1153 that
->NodeCache
[(2*PropertyRequest
->Node
)+channel
] = *Level
;
1156 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
1157 if (*Level
<= (-30 << 16)) {
1159 that
->NodeCache
[(2*PropertyRequest
->Node
)+channel
] = -30 << 16;
1163 that
->NodeCache
[(2*PropertyRequest
->Node
)+channel
] = 0;
1165 mixerValue
= ((*Level
>> 18) + 0x0F) & 0x0F;
1166 that
->NodeCache
[(2*PropertyRequest
->Node
)+channel
] = *Level
;
1169 if (channel
== CHAN_RIGHT
) {
1170 that
->auxVolumeRegister
= (that
->auxVolumeRegister
& 0xF0) | mixerValue
;
1171 } else if (channel
== CHAN_LEFT
) {
1172 that
->auxVolumeRegister
= (that
->auxVolumeRegister
& 0x0F) | (mixerValue
<< 4);
1174 that
->CMIAdapter
->writeUInt8(REG_MIXER3
, that
->auxVolumeRegister
);
1176 ntStatus
= STATUS_SUCCESS
;
1178 if ((PropertyRequest
->Node
== KSNODE_TOPO_MICIN_VOLUME
) && (channel
== CHAN_LEFT
)) {
1179 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
1180 *Level
= that
->NodeCache
[(2*PropertyRequest
->Node
)];
1181 mixerValue
= that
->micVolumeRegister
>> 1 & 0x7;
1182 if (mixerValue
!= ((*Level
>> 19)+0x07)) {
1183 *Level
= (mixerValue
- 0x07) << 19;
1184 that
->NodeCache
[(2*PropertyRequest
->Node
)] = *Level
;
1186 } else if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
1187 if (*Level
<= (-56 << 16)) {
1189 that
->NodeCache
[(2*PropertyRequest
->Node
)] = -56 << 16;
1190 } else if (*Level
>= 0) {
1192 that
->NodeCache
[(2*PropertyRequest
->Node
)] = 0;
1194 mixerValue
= ((*Level
>> 19) + 0x07) & 0x07;
1195 that
->NodeCache
[(2*PropertyRequest
->Node
)] = *Level
;
1197 that
->micVolumeRegister
&= ~(0x07 << 1);
1198 that
->micVolumeRegister
|= mixerValue
<< 1;
1199 that
->CMIAdapter
->writeUInt8(REG_MIXER2
, that
->micVolumeRegister
);
1201 ntStatus
= STATUS_SUCCESS
;
1203 if ((NT_SUCCESS(ntStatus
)) && (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
)) {
1204 PropertyRequest
->ValueSize
= sizeof(LONG
);
1207 } else if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_BASICSUPPORT
) {
1208 switch(PropertyRequest
->Node
) {
1209 case KSNODE_TOPO_LINEOUT_VOLUME
:
1210 case KSNODE_TOPO_WAVEOUT_VOLUME
:
1211 case KSNODE_TOPO_CD_VOLUME
:
1212 case KSNODE_TOPO_LINEIN_VOLUME
:
1213 case KSNODE_TOPO_MICOUT_VOLUME
:
1214 case KSNODE_TOPO_MICIN_VOLUME
:
1215 case KSNODE_TOPO_AUX_VOLUME
:
1216 ntStatus
= BasicSupportHandler(PropertyRequest
);
1223 NTSTATUS NTAPI
PropertyHandler_CpuResources(PPCPROPERTY_REQUEST PropertyRequest
)
1226 //ASSERT(PropertyRequest);
1227 DBGPRINT(("[PropertyHandler_CpuResources]"));
1229 NTSTATUS ntStatus
= STATUS_INVALID_DEVICE_REQUEST
;
1231 if (PropertyRequest
->Node
== MAXULONG
) {
1234 if (PropertyRequest
->Node
>= KSNODE_TOPO_INVALID
) {
1238 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
1239 if (PropertyRequest
->ValueSize
>= sizeof(LONG
)) {
1240 *((PLONG
)PropertyRequest
->Value
) = KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU
;
1242 PropertyRequest
->ValueSize
= sizeof(LONG
);
1243 ntStatus
= STATUS_SUCCESS
;
1245 ntStatus
= STATUS_BUFFER_TOO_SMALL
;
1247 } else if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_BASICSUPPORT
) {
1248 if (PropertyRequest
->ValueSize
>= (sizeof(KSPROPERTY_DESCRIPTION
))) {
1249 PKSPROPERTY_DESCRIPTION PropDesc
= PKSPROPERTY_DESCRIPTION(PropertyRequest
->Value
);
1251 PropDesc
->AccessFlags
= KSPROPERTY_TYPE_BASICSUPPORT
|
1252 KSPROPERTY_TYPE_GET
;
1253 PropDesc
->DescriptionSize
= sizeof(KSPROPERTY_DESCRIPTION
);
1254 PropDesc
->PropTypeSet
.Set
= KSPROPTYPESETID_General
;
1255 PropDesc
->PropTypeSet
.Id
= VT_I4
;
1256 PropDesc
->PropTypeSet
.Flags
= 0;
1257 PropDesc
->MembersListCount
= 0;
1258 PropDesc
->Reserved
= 0;
1260 PropertyRequest
->ValueSize
= sizeof(KSPROPERTY_DESCRIPTION
);
1261 ntStatus
= STATUS_SUCCESS
;
1262 } else if (PropertyRequest
->ValueSize
>= sizeof(ULONG
)) {
1263 PULONG AccessFlags
= PULONG(PropertyRequest
->Value
);
1265 *AccessFlags
= KSPROPERTY_TYPE_BASICSUPPORT
| KSPROPERTY_TYPE_GET
;
1267 PropertyRequest
->ValueSize
= sizeof(ULONG
);
1268 ntStatus
= STATUS_SUCCESS
;
1275 NTSTATUS NTAPI
PropertyHandler_ComponentId(PPCPROPERTY_REQUEST PropertyRequest
)
1278 //ASSERT(PropertyRequest);
1279 DBGPRINT(("[PropertyHandler_ComponentId]"));
1281 NTSTATUS ntStatus
= STATUS_INVALID_DEVICE_REQUEST
;
1282 CCMITopology
*that
= (CCMITopology
*) ((PMINIPORTTOPOLOGY
) PropertyRequest
->MajorTarget
);
1284 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
1285 if (PropertyRequest
->ValueSize
>= sizeof(KSCOMPONENTID
)) {
1286 PKSCOMPONENTID pComponentId
= (PKSCOMPONENTID
)PropertyRequest
->Value
;
1288 pComponentId
->Manufacturer
= MANUFACTURER_CM8738
;
1289 pComponentId
->Product
= PRODUCT_CM8738
;
1290 pComponentId
->Component
= COMPONENT_CM8738
;
1291 pComponentId
->Name
= GUID_NULL
;
1292 pComponentId
->Version
= CMIPCI_VERSION
;
1293 pComponentId
->Revision
= that
->cm
->chipVersion
;
1295 PropertyRequest
->ValueSize
= sizeof(KSCOMPONENTID
);
1296 ntStatus
= STATUS_SUCCESS
;
1297 } else if (PropertyRequest
->ValueSize
== 0) {
1298 PropertyRequest
->ValueSize
= sizeof(KSCOMPONENTID
);
1299 ntStatus
= STATUS_BUFFER_OVERFLOW
;
1301 PropertyRequest
->ValueSize
= 0;
1302 ntStatus
= STATUS_BUFFER_TOO_SMALL
;
1304 } else if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_BASICSUPPORT
) {
1305 if (PropertyRequest
->ValueSize
>= sizeof(ULONG
)) {
1306 PULONG AccessFlags
= PULONG(PropertyRequest
->Value
);
1308 *AccessFlags
= KSPROPERTY_TYPE_BASICSUPPORT
| KSPROPERTY_TYPE_GET
;
1310 PropertyRequest
->ValueSize
= sizeof(ULONG
);
1311 ntStatus
= STATUS_SUCCESS
;
1313 PropertyRequest
->ValueSize
= 0;
1314 ntStatus
= STATUS_BUFFER_TOO_SMALL
;
1321 NTSTATUS NTAPI
PropertyHandler_Private(PPCPROPERTY_REQUEST PropertyRequest
)
1324 //ASSERT(PropertyRequest);
1325 DBGPRINT(("[PropertyHandler_Private]"));
1327 NTSTATUS ntStatus
= STATUS_INVALID_DEVICE_REQUEST
;
1328 CCMITopology
*that
= (CCMITopology
*) ((PMINIPORTTOPOLOGY
) PropertyRequest
->MajorTarget
);
1330 if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_GET
) {
1331 if (PropertyRequest
->PropertyItem
->Id
!= KSPROPERTY_CMI_GET
) {
1332 return STATUS_INVALID_DEVICE_REQUEST
;
1335 if (PropertyRequest
->ValueSize
== 0) {
1336 PropertyRequest
->ValueSize
= sizeof(CMIDATA
);
1337 return STATUS_BUFFER_OVERFLOW
;
1338 } else if (PropertyRequest
->ValueSize
< sizeof (CMIDATA
)) {
1339 PropertyRequest
->ValueSize
= 0;
1340 return STATUS_BUFFER_TOO_SMALL
;
1343 CMIDATA
* cmiData
= (CMIDATA
*)PropertyRequest
->Value
;
1345 RtlStringCbPrintfA(cmiData
->driverVersion
, sizeof(cmiData
->driverVersion
), CMIVERSION
"-WaveRT");
1347 RtlStringCbPrintfA(cmiData
->driverVersion
, sizeof(cmiData
->driverVersion
), CMIVERSION
);
1349 cmiData
->hardwareRevision
= that
->cm
->chipVersion
;
1350 cmiData
->maxChannels
= that
->cm
->maxChannels
;
1351 cmiData
->IOBase
= (USHORT
)(ULONG_PTR
)that
->cm
->IOBase
;
1352 cmiData
->MPUBase
= (USHORT
)(ULONG_PTR
)that
->cm
->MPUBase
;
1353 cmiData
->enableSPDO
= that
->cm
->enableSPDIFOut
;
1354 cmiData
->enableSPDI
= that
->cm
->enableSPDIFIn
;
1355 cmiData
->formatMask
= that
->cm
->formatMask
;
1356 cmiData
->exchangeFrontBack
= (that
->CMIAdapter
->readUInt8(REG_MIXER1
) & REAR2FRONT
);
1357 cmiData
->enableSPDO5V
= (that
->CMIAdapter
->readUInt32(REG_MISCCTRL
) & EN_SPDO5V
);
1358 cmiData
->enablePCMDAC
= (that
->CMIAdapter
->readUInt8(REG_MIXER1
) & EN_SPDI2DAC
);
1359 cmiData
->enableBass2Line
= (that
->CMIAdapter
->readUInt32(REG_LEGACY
) & BASS2LINE
);
1360 cmiData
->enableCenter2Line
= (that
->CMIAdapter
->readUInt32(REG_LEGACY
) & CENTER2LINE
);
1361 cmiData
->enableRear2Line
= (that
->CMIAdapter
->readUInt8(REG_MIXER1
) & REAR2LINE
);
1362 cmiData
->enableCenter2Mic
= (that
->CMIAdapter
->readUInt8(REG_MIXER4
) & CENTER2MIC
) && (that
->cm
->chipVersion
> 37);
1363 cmiData
->enableSPDOCopyright
= (that
->CMIAdapter
->readUInt32(REG_LEGACY
) & EN_SPDCOPYRHT
);
1364 cmiData
->invertValidBitSPDI
= (that
->CMIAdapter
->readUInt32(REG_CHFORMAT
) & POLVALID
);
1365 cmiData
->loopSPDI
= (that
->CMIAdapter
->readUInt32(REG_FUNCTRL1
) & LOOP_SPDF
);
1366 if (that
->cm
->chipVersion
<= 37) {
1367 cmiData
->select2ndSPDI
= (that
->CMIAdapter
->readUInt32(REG_CHFORMAT
) & SEL_SPDIFI1
);
1368 cmiData
->invertPhaseSPDI
= (that
->CMIAdapter
->readUInt8(REG_MIXER4
) & INV_SPDIFI1
);
1370 cmiData
->select2ndSPDI
= (that
->CMIAdapter
->readUInt32(REG_MISCCTRL
) & SEL_SPDIFI2
);
1371 cmiData
->invertPhaseSPDI
= (that
->CMIAdapter
->readUInt32(REG_CHFORMAT
) & INV_SPDIFI2
);
1374 PropertyRequest
->ValueSize
= sizeof(CMIDATA
);
1375 ntStatus
= STATUS_SUCCESS
;
1376 } else if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_SET
) {
1377 if (PropertyRequest
->PropertyItem
->Id
!= KSPROPERTY_CMI_SET
) {
1378 return STATUS_INVALID_DEVICE_REQUEST
;
1381 if (PropertyRequest
->ValueSize
== 0) {
1382 PropertyRequest
->ValueSize
= sizeof(CMIDATA
);
1383 return STATUS_BUFFER_OVERFLOW
;
1384 } else if (PropertyRequest
->ValueSize
< sizeof (CMIDATA
)) {
1385 PropertyRequest
->ValueSize
= 0;
1386 return STATUS_BUFFER_TOO_SMALL
;
1388 CMIDATA
* cmiData
= (CMIDATA
*)PropertyRequest
->Value
;
1389 that
->cm
->enableSPDIFIn
= cmiData
->enableSPDI
;
1390 that
->cm
->enableSPDIFOut
= cmiData
->enableSPDO
;
1391 that
->cm
->formatMask
= cmiData
->formatMask
;
1393 if (cmiData
->enableSPDI
) {
1394 that
->CMIAdapter
->setUInt8Bit(REG_MIXER1
, EN_WAVEIN_L
| EN_WAVEIN_R
);
1396 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER1
, EN_WAVEIN_L
| EN_WAVEIN_R
);
1399 if (cmiData
->exchangeFrontBack
) {
1400 that
->CMIAdapter
->setUInt8Bit(REG_MIXER1
, REAR2FRONT
);
1402 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER1
, REAR2FRONT
);
1404 if (cmiData
->enableSPDO5V
) {
1405 that
->CMIAdapter
->setUInt32Bit(REG_MISCCTRL
, EN_SPDO5V
);
1407 that
->CMIAdapter
->clearUInt32Bit(REG_MISCCTRL
, EN_SPDO5V
);
1409 if (cmiData
->enablePCMDAC
) {
1410 that
->CMIAdapter
->setUInt8Bit(REG_MIXER1
, EN_SPDI2DAC
);
1412 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER1
, EN_SPDI2DAC
);
1414 if (cmiData
->enableBass2Line
) {
1415 that
->CMIAdapter
->setUInt32Bit(REG_LEGACY
, BASS2LINE
);
1417 that
->CMIAdapter
->clearUInt32Bit(REG_LEGACY
, BASS2LINE
);
1419 if (cmiData
->enableCenter2Line
) {
1420 that
->CMIAdapter
->setUInt32Bit(REG_LEGACY
, CENTER2LINE
);
1422 that
->CMIAdapter
->clearUInt32Bit(REG_LEGACY
, CENTER2LINE
);
1424 if (cmiData
->enableRear2Line
) {
1425 that
->CMIAdapter
->setUInt8Bit(REG_MIXER1
, REAR2LINE
);
1427 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER1
, REAR2LINE
);
1429 if (that
->cm
->chipVersion
> 37) {
1430 if (cmiData
->enableCenter2Mic
) {
1431 that
->CMIAdapter
->setUInt8Bit(REG_MIXER4
, CENTER2MIC
);
1433 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER4
, CENTER2MIC
);
1436 if (cmiData
->enableSPDOCopyright
) {
1437 that
->CMIAdapter
->setUInt32Bit(REG_LEGACY
, EN_SPDCOPYRHT
);
1439 that
->CMIAdapter
->clearUInt32Bit(REG_LEGACY
, EN_SPDCOPYRHT
);
1441 if (cmiData
->invertValidBitSPDI
) {
1442 that
->CMIAdapter
->setUInt32Bit(REG_CHFORMAT
, POLVALID
);
1444 that
->CMIAdapter
->clearUInt32Bit(REG_CHFORMAT
, POLVALID
);
1446 if (cmiData
->loopSPDI
) {
1447 that
->CMIAdapter
->setUInt32Bit(REG_FUNCTRL1
, LOOP_SPDF
);
1449 that
->CMIAdapter
->clearUInt32Bit(REG_FUNCTRL1
, LOOP_SPDF
);
1451 if (cmiData
->select2ndSPDI
) {
1452 if (that
->cm
->chipVersion
<= 37) {
1453 that
->CMIAdapter
->setUInt32Bit(REG_CHFORMAT
, SEL_SPDIFI1
);
1455 that
->CMIAdapter
->setUInt32Bit(REG_MISCCTRL
, SEL_SPDIFI2
);
1458 if (that
->cm
->chipVersion
<= 37) {
1459 that
->CMIAdapter
->clearUInt32Bit(REG_CHFORMAT
, SEL_SPDIFI1
);
1461 that
->CMIAdapter
->clearUInt32Bit(REG_MISCCTRL
, SEL_SPDIFI2
);
1464 if (cmiData
->invertPhaseSPDI
) {
1465 if (that
->cm
->chipVersion
<= 37) {
1466 that
->CMIAdapter
->setUInt8Bit(REG_MIXER4
, INV_SPDIFI1
);
1468 that
->CMIAdapter
->setUInt32Bit(REG_CHFORMAT
, INV_SPDIFI2
);
1471 if (that
->cm
->chipVersion
<= 37) {
1472 that
->CMIAdapter
->clearUInt8Bit(REG_MIXER4
, INV_SPDIFI1
);
1474 that
->CMIAdapter
->clearUInt32Bit(REG_CHFORMAT
, INV_SPDIFI2
);
1478 that
->storeMixerSettingsToRegistry();
1480 ntStatus
= STATUS_SUCCESS
;
1481 } else if (PropertyRequest
->Verb
& KSPROPERTY_TYPE_BASICSUPPORT
) {
1482 if (PropertyRequest
->ValueSize
>= sizeof(ULONG
)) {
1483 PULONG AccessFlags
= PULONG(PropertyRequest
->Value
);
1485 *AccessFlags
= KSPROPERTY_TYPE_BASICSUPPORT
| KSPROPERTY_TYPE_GET
| KSPROPERTY_TYPE_SET
;
1487 PropertyRequest
->ValueSize
= sizeof(ULONG
);
1488 ntStatus
= STATUS_SUCCESS
;
1490 PropertyRequest
->ValueSize
= 0;
1491 ntStatus
= STATUS_BUFFER_TOO_SMALL
;