ReactOS 0.4.16-dev-257-g6aa11ac
prophnd.cpp
Go to the documentation of this file.
1/********************************************************************************
2** Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved.
3**
4** Portions Copyright (c) 1998-1999 Intel Corporation
5**
6********************************************************************************/
7
8/* The file prophnd.cpp was reviewed by LCA in June 2011 and is acceptable for use by Microsoft. */
9
10// Every debug output has "Modulname text".
11#define STR_MODULENAME "AC97 Property handler: "
12
13#include "mintopo.h"
14
15// These are the values passed to the property handler in the instance
16// parameter that normally represents the channel.
17const LONG CHAN_LEFT = 0;
18const LONG CHAN_RIGHT = 1;
19const LONG CHAN_MASTER = -1;
20
21
22// paged code goes here.
23#ifdef _MSC_VER
24#pragma code_seg("PAGE")
25#endif
26
27
28/*****************************************************************************
29 * CAC97MiniportTopology::SetMultichannelMute
30 *****************************************************************************
31 * This function is used to set one of the multichannel mutes.
32 * It takes the master mono into account when calculating the mute.
33 * Make sure that you updated the stNodeCache before calling this function.
34 */
36(
38 IN TopoNodes Mute
39)
40{
41 PAGED_CODE();
42
43 NTSTATUS ntStatus = STATUS_SUCCESS;
44 BOOL bMute;
45
46 // The first calls to SetMultichannelMute could be without valid
47 // cache information because WDMAUD might currently query the nodes
48 // (this is at system startup). When WDMAUD queried all nodes then
49 // all cache information will be valid.
50 if (that->stNodeCache[NODE_VIRT_MASTERMONO_MUTE].bLeftValid &&
51 that->stNodeCache[Mute].bLeftValid)
52 {
53 // We get the master mono mute and the mute that is to change.
54 // Then we "or" them and write the value to the register.
55 bMute = that->stNodeCache[NODE_VIRT_MASTERMONO_MUTE].lLeft ||
56 that->stNodeCache[Mute].lLeft;
57
58 ntStatus = that->AdapterCommon->WriteCodecRegister (
59 that->AdapterCommon->GetNodeReg (Mute),
60 bMute ? -1 : 0,
61 that->AdapterCommon->GetNodeMask (Mute));
62
63 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x", NodeStrings[Mute], (int)bMute));
64 }
65
66 return ntStatus;
67}
68
69/*****************************************************************************
70 * CAC97MiniportTopology::SetMultichannelVolume
71 *****************************************************************************
72 * This function is used to set one of the multichannel volumes.
73 * It takes the master mono into account when calculating the volume.
74 * Make sure that you updated the stNodeCache before calling this function.
75 */
77(
80)
81{
82 PAGED_CODE();
83
84 NTSTATUS ntStatus = STATUS_SUCCESS;
86 ULONG uStep;
87 LONG lLevel;
88 WORD wRegister;
89
90 // The first calls to SetMultichannelMute could be without valid
91 // cache information because WDMAUD might currently query the nodes
92 // (this is at system startup). When WDMAUD queried all nodes then
93 // all cache information will be valid.
94 if (that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].bLeftValid &&
95 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].bRightValid &&
96 that->stNodeCache[Volume].bLeftValid &&
97 that->stNodeCache[Volume].bRightValid)
98 {
99 // We get the master mono volume and the volume that is to change.
100 // Then we substract master mono from it and write the value to the
101 // register.
102 lLevel = that->stNodeCache[Volume].lLeft +
103 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].lLeft;
104
105 // Translate the dB value into a register value.
106
107 // Get the registered DB values
108 ntStatus = GetDBValues (that->AdapterCommon, Volume,
109 &lMinimum, &lMaximum, &uStep);
110 if (!NT_SUCCESS(ntStatus))
111 return ntStatus;
112
113 // Check borders.
114 if (lLevel < lMinimum) lLevel = lMinimum;
115 if (lLevel > lMaximum) lLevel = lMaximum;
116
117 // Calculate the register value
118 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep) << 8;
119
120 // Get the right value too.
121 lLevel = that->stNodeCache[Volume].lRight +
122 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].lRight;
123
124 // Check borders.
125 if (lLevel < lMinimum) lLevel = lMinimum;
126 if (lLevel > lMaximum) lLevel = lMaximum;
127
128 // Add it to the register value.
129 wRegister += (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
130
131 // Write it.
132 ntStatus = that->AdapterCommon->WriteCodecRegister (
133 that->AdapterCommon->GetNodeReg (Volume),
134 wRegister,
135 that->AdapterCommon->GetNodeMask (Volume));
136
137 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x/0x%x", NodeStrings[Volume],
138 that->stNodeCache[Volume].lLeft +
139 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].lLeft,
140 lLevel));
141 }
142
143 return ntStatus;
144}
145
146/*****************************************************************************
147 * CAC97MiniportTopology::GetDBValues
148 *****************************************************************************
149 * This function is used internally and does no parameter checking. The only
150 * parameter that could be invalid is the node.
151 * It returns the dB values (means minimum, maximum, step) of the node control,
152 * mainly for the property call "basic support". Sure, the node must be a
153 * volume or tone control node, not a mute or mux node.
154 */
156(
157 IN PADAPTERCOMMON AdapterCommon,
159 OUT LONG *plMinimum,
160 OUT LONG *plMaximum,
161 OUT ULONG *puStep
162)
163{
164 PAGED_CODE();
165
166 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::GetDBValues]"));
167
168 // This is going to be simple. Check the node and return the parameters.
169 switch (Node)
170 {
171 // These nodes could have 5bit or 6bit controls, so we first
172 // have to check this.
173#ifndef __REACTOS__
175#endif
180 case NODE_LFE_VOLUME:
183 // needed for the config query
185
186 // which node to query?
190 if (Node == NODE_HPOUT_VOLUME)
196
197 // check if we have 6th bit support.
198 if (AdapterCommon->GetNodeConfig (config))
199 {
200 // 6bit control
201 *plMaximum = 0; // 0 dB
202 *plMinimum = 0xFFA18000; // -94.5 dB
203 *puStep = 0x00018000; // 1.5 dB
204 }
205 else
206 {
207 // 5bit control
208 *plMaximum = 0; // 0 dB
209 *plMinimum = 0xFFD18000; // -46.5 dB
210 *puStep = 0x00018000; // 1.5 dB
211 }
212 break;
213
215 // This virtual control gets added to the speaker volumes.
216 // We assume 5-bit volumes.
217 *plMaximum = 0; // 0 dB
218 *plMinimum = 0xFFD18000; // -46.5 dB
219 *puStep = 0x00018000; // 1.5 dB
220 break;
221
223 *plMaximum = 0; // 0 dB
224 *plMinimum = 0xFFD30000; // -45 dB
225 *puStep = 0x00030000; // 3 dB
226 break;
227
231 case NODE_CD_VOLUME:
233 case NODE_AUX_VOLUME:
235#ifdef __REACTOS__
236 // ReactOS change: use the same Decibel range as for WaveOut,
237 // to fix incorrect volume level change scaling. CORE-14780
239#endif
240 *plMaximum = 0x000C0000; // 12 dB
241 *plMinimum = 0xFFDD8000; // -34.5 dB
242 *puStep = 0x00018000; // 1.5 dB
243 break;
244
245
254 case NODE_MIC_VOLUME:
255 *plMaximum = 0x00168000; // 22.5 dB
256 *plMinimum = 0; // 0 dB
257 *puStep = 0x00018000; // 1.5 dB
258 break;
259
260 case NODE_BASS:
261 case NODE_TREBLE:
262 *plMaximum = 0x000A8000; // 10.5 dB
263 *plMinimum = 0xFFF58000; // -10.5 dB
264 *puStep = 0x00018000; // 1.5 dB
265 break;
266
267 // These nodes can be fixed or variable.
268 // Normally we won't display a fixed volume slider, but if 3D is
269 // supported and both sliders are fixed, we have to display one fixed
270 // slider for the advanced control panel.
273 if (AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE) &&
275 {
276 *plMaximum = 0x000F0000; // +15 dB
277 *plMinimum = 0x00000000; // 0 dB
278 *puStep = 0x00010000; // 1 dB
279 }
280 else
281 if (AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE) &&
283 {
284 *plMaximum = 0x000F0000; // +15 dB
285 *plMinimum = 0x00000000; // 0 dB
286 *puStep = 0x00010000; // 1 dB
287 }
288 else
289 {
290 // In case it is fixed, read the value and return it.
291 WORD wRegister;
292
293 // read the register
294 if (!NT_SUCCESS (AdapterCommon->ReadCodecRegister (
295 AdapterCommon->GetNodeReg (Node), &wRegister)))
296 wRegister = 0; // in case we fail.
297
298 // mask out the control
299 wRegister &= AdapterCommon->GetNodeMask (Node);
301 {
302 wRegister >>= 8;
303 }
304 // calculate the dB value.
305 *plMaximum = (DWORD)(-wRegister) << 16; // fixed value
306 *plMinimum = (DWORD)(-wRegister) << 16; // fixed value
307 *puStep = 0x00010000; // 1 dB
308 }
309 break;
310
311 case NODE_INVALID:
312 default:
313 // poeser pupe, tu.
314 DOUT (DBG_ERROR, ("GetDBValues: Invalid node requested."));
316 }
317
318 return STATUS_SUCCESS;
319}
320
321/*****************************************************************************
322 * CAC97MiniportTopology::PropertyHandler_OnOff
323 *****************************************************************************
324 * Accesses a KSAUDIO_ONOFF value property.
325 * This function (property handler) is called by portcls every time there is a
326 * get or a set request for the node. The connection between the node type and
327 * the property handler is made in the automation table which is referenced
328 * when you register the node.
329 * We use this property handler for all nodes that have a checkbox, means mute
330 * controls and the special checkbox controls under advanced properties, which
331 * are AGC and LOUDNESS.
332 */
334(
335 IN PPCPROPERTY_REQUEST PropertyRequest
336)
337{
338 PAGED_CODE ();
339
340 ASSERT (PropertyRequest);
341
343 LONG channel;
344 TopoNodes NodeDef;
345 // The major target is the object pointer to the topology miniport.
347 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
348
349 ASSERT (that);
350
351 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_OnOff]"));
352
353 // validate node
354 if (PropertyRequest->Node == (ULONG)-1)
355 return ntStatus;
356
357 // do the appropriate action for the request.
358
359 // we should do a get or a set?
360 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
361 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
362 {
363 // validate parameters
364 if ((PropertyRequest->InstanceSize < sizeof(LONG)) ||
365 (PropertyRequest->ValueSize < sizeof(BOOL)))
366 return ntStatus;
367
368 // get channel
369 channel = *(PLONG)PropertyRequest->Instance;
370
371 // check channel types, return when unknown
372 // as you can see, we have no multichannel support.
373 if ((channel != CHAN_LEFT) &&
374 (channel != CHAN_RIGHT) &&
375 (channel != CHAN_MASTER))
376 return ntStatus;
377
378 // We have only mono mutes or On/Off checkboxes although they might control
379 // a stereo path. For example, we have a 1-bit mute for CD Volume. This
380 // mute controls both CD Volume channels.
381 if (channel == CHAN_RIGHT)
382 return ntStatus;
383
384 // get the buffer
385 PBOOL OnOff = (PBOOL)PropertyRequest->Value;
386
387 // Switch on the node id. This is just for parameter checking.
388 // If something goes wrong, we will immediately return with
389 // ntStatus, which is STATUS_INVALID_PARAMETER.
390 switch (NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
391 {
392 // These are mutes for mono volumes.
393 case NODE_PCBEEP_MUTE:
394 case NODE_PHONE_MUTE:
395 case NODE_MIC_MUTE:
396 case NODE_MICIN_MUTE:
397 case NODE_CENTER_MUTE:
398 case NODE_LFE_MUTE:
400 // check type
401 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_MUTE)
402 return ntStatus;
403 break;
404
405 // Well, this one is a AGC, although there is no _automatic_ gain
406 // control, but we have a mic boost (which is some kind of manual
407 // gain control).
408 // The 3D Bypass is a real fake, but that's how you get check boxes
409 // on the advanced control panel.
410 // Both controls are in a mono path.
412 case NODE_MIC_BOOST:
413 // check type
414 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_AGC)
415 return ntStatus;
416 break;
417
418 // Simulated Stereo is a AGC control in a stereo path.
420 // check type
421 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_AGC)
422 return ntStatus;
423 break;
424
425 // This is a loudness control in a stereo path. We have to check the
426 // type.
427 case NODE_LOUDNESS:
428 // check type
429 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_LOUDNESS)
430 return ntStatus;
431 break;
432
433 // For 3D Enable and Mic are exposed as loudness in a mono path.
435 case NODE_MIC_SELECT:
436 // check type
437 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_LOUDNESS)
438 return ntStatus;
439 break;
440
441 // These are mutes in a stereo path.
442 // Because the HW has only one mute-bit for the stereo channel, we
443 // expose the mute as mono. this works in current OS and hopefully
444 // will work in future OS.
446 case NODE_LINEIN_MUTE:
447 case NODE_CD_MUTE:
448 case NODE_VIDEO_MUTE:
449 case NODE_AUX_MUTE:
451 case NODE_FRONT_MUTE:
453 case NODE_HPOUT_MUTE:
454 // just check the type.
455 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_MUTE)
456 return ntStatus;
457 break;
458
459 case NODE_INVALID:
460 default:
461 // Ooops.
462 DOUT (DBG_ERROR, ("PropertyHandler_OnOff: Invalid node requested."));
463 return ntStatus;
464 }
465
466 // Now, do some action!
467
468 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
469 {
470 WORD wRegister;
471
472 // Read the HW register for the node except NODE_VIRT_MASTERMONO_MUTE,
473 // since this is pure virtual.
474 if (NodeDef != NODE_VIRT_MASTERMONO_MUTE)
475 {
476 // get the register and read it.
477 ntStatus = that->AdapterCommon->ReadCodecRegister (
478 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
479 if (!NT_SUCCESS (ntStatus))
480 return ntStatus;
481 // Mask out every unused bit.
482 wRegister &= that->AdapterCommon->GetNodeMask (NodeDef);
483 // Store the value.
484 *OnOff = wRegister ? TRUE : FALSE;
485 }
486 else
487 {
488 // Assume no mute for master mono.
489 *OnOff = FALSE;
490 }
491
492 // When we have cache information then return this instead of the
493 // calculated value. If we don't, store the calculated value.
494 if (that->stNodeCache[NodeDef].bLeftValid)
495 *OnOff = that->stNodeCache[NodeDef].lLeft;
496 else
497 {
498 that->stNodeCache[NodeDef].lLeft = *OnOff;
499 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
500 }
501
502 PropertyRequest->ValueSize = sizeof(BOOL);
503 DOUT (DBG_PROPERTY, ("GET: %s = 0x%x", NodeStrings[NodeDef], *OnOff));
504
505 // Set the return code here.
506 ntStatus = STATUS_SUCCESS;
507 }
508 else // this must be a set.
509 {
510 // First update the node cache.
511 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
512 that->stNodeCache[NodeDef].lLeft = (*OnOff) ? TRUE : FALSE;
513
514 //
515 // If we have a master mono, then we have to program the speaker
516 // mutes a little different.
517 // Check for master mono (surround or headphone present) and
518 // if one of the speaker mutes is requested.
519 //
520 if ((that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
521 that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT)) &&
522 ((NodeDef == NODE_VIRT_MASTERMONO_MUTE) || (NodeDef == NODE_LFE_MUTE) ||
523 (NodeDef == NODE_CENTER_MUTE) || (NodeDef == NODE_FRONT_MUTE) ||
524 (NodeDef == NODE_SURROUND_MUTE) || (NodeDef == NODE_HPOUT_MUTE)))
525 {
526 //
527 // For master mono we have to update all speakers.
528 //
529 if (NodeDef == NODE_VIRT_MASTERMONO_MUTE)
530 {
531 // Update all speaker mutes.
532 ntStatus = SetMultichannelMute (that, NODE_FRONT_MUTE);
533 if (that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
534 ntStatus = SetMultichannelMute (that, NODE_HPOUT_MUTE);
535 if (that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
536 ntStatus = SetMultichannelMute (that, NODE_SURROUND_MUTE);
537 if (that->AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
538 {
539 ntStatus = SetMultichannelMute (that, NODE_CENTER_MUTE);
540 ntStatus = SetMultichannelMute (that, NODE_LFE_MUTE);
541 }
542 }
543 else // Update the individual speaker mute.
544 {
545 ntStatus = SetMultichannelMute (that, NodeDef);
546 }
547 }
548 else
549 {
550 //
551 // For all other mutes/checkboxes just write the value to the HW.
552 //
553 ntStatus = that->AdapterCommon->WriteCodecRegister (
554 that->AdapterCommon->GetNodeReg (NodeDef),
555 (*OnOff) ? -1 : 0,
556 that->AdapterCommon->GetNodeMask (NodeDef));
557 }
558
559 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x", NodeStrings[NodeDef], *OnOff));
560
561 // ntStatus was set with the write call! whatever this is, return it.
562 }
563 }
564
565 return ntStatus;
566}
567
568/*****************************************************************************
569 * CAC97MiniportTopology::BasicSupportHandler
570 *****************************************************************************
571 * Assists in BASICSUPPORT accesses on level properties.
572 * This function is called internally every time there is a "basic support"
573 * request on a volume or tone control. The basic support is used to retrieve
574 * some information about the range of the control (from - to dB, steps) and
575 * which type of control (tone, volume).
576 * Basically, this function just calls GetDBValues to get the range information
577 * and fills the rest of the structure with some constants.
578 */
580(
581 IN PPCPROPERTY_REQUEST PropertyRequest
582)
583{
584 PAGED_CODE ();
585
586 ASSERT (PropertyRequest);
587
588 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::BasicSupportHandler]"));
589
591 // The major target is the object pointer to the topology miniport.
593 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
594
595 ASSERT (that);
596
597
598 // if there is enough space for a KSPROPERTY_DESCRIPTION information
599 if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION)))
600 {
601 // we return a KSPROPERTY_DESCRIPTION structure.
602 PKSPROPERTY_DESCRIPTION PropDesc = (PKSPROPERTY_DESCRIPTION)PropertyRequest->Value;
603
607 PropDesc->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION) +
611 PropDesc->PropTypeSet.Id = VT_I4;
612 PropDesc->PropTypeSet.Flags = 0;
613 PropDesc->MembersListCount = 1;
614 PropDesc->Reserved = 0;
615
616 // if return buffer can also hold a range description, return it too
617 if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION) +
619 {
620 // fill in the members header
622
624 Members->MembersSize = sizeof(KSPROPERTY_STEPPING_LONG);
625 Members->MembersCount = 1;
626 Members->Flags = 0;
627
628 // fill in the stepped range
630
631 ntStatus = GetDBValues (that->AdapterCommon,
632 that->TransNodeNrToNodeDef (PropertyRequest->Node),
633 &Range->Bounds.SignedMinimum,
634 &Range->Bounds.SignedMaximum,
635 &Range->SteppingDelta);
636
637 Range->Reserved = 0;
638
639 // set the return value size
640 PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) +
643
644 DOUT (DBG_PROPERTY, ("BASIC_SUPPORT: %s max=0x%x min=0x%x step=0x%x",
645 NodeStrings[that->TransNodeNrToNodeDef (PropertyRequest->Node)],
646 Range->Bounds.SignedMaximum, Range->Bounds.SignedMinimum,
647 Range->SteppingDelta));
648 } else
649 {
650 // we hadn't enough space for the range information;
651 // set the return value size
652 PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION);
653 }
654
655 ntStatus = STATUS_SUCCESS;
656 }
657 else if (PropertyRequest->ValueSize >= sizeof(ULONG))
658 {
659 // if return buffer can hold a ULONG, return the access flags
660 PULONG AccessFlags = (PULONG)PropertyRequest->Value;
661
662 *AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT |
665
666 // set the return value size
667 PropertyRequest->ValueSize = sizeof(ULONG);
668 ntStatus = STATUS_SUCCESS;
669 }
670
671 // In case there was not even enough space for a ULONG in the return buffer,
672 // we fail this request with STATUS_INVALID_DEVICE_REQUEST.
673 // Any other case will return STATUS_SUCCESS.
674 return ntStatus;
675}
676
677/*****************************************************************************
678 * CAC97MiniportTopology::PropertyHandler_Level
679 *****************************************************************************
680 * Accesses a KSAUDIO_LEVEL property.
681 * This function (property handler) is called by portcls every time there is a
682 * get, set or basic support request for the node. The connection between the
683 * node type and the property handler is made in the automation table which is
684 * referenced when you register the node.
685 * We use this property handler for all volume controls (and virtual volume
686 * controls for recording).
687 */
689(
690 IN PPCPROPERTY_REQUEST PropertyRequest
691)
692{
693 PAGED_CODE ();
694
695 ASSERT (PropertyRequest);
696
697 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_Level]"));
698
700 TopoNodes NodeDef;
701 LONG channel;
703 ULONG uStep;
704 // The major target is the object pointer to the topology miniport.
706 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
707
708 ASSERT (that);
709
710 // validate node
711 if (PropertyRequest->Node == (ULONG)-1)
712 return ntStatus;
713
714 // do the appropriate action for the request.
715
716 // we should do a get or a set?
717 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
718 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
719 {
720 // validate parameters
721 if ((PropertyRequest->InstanceSize < sizeof(LONG)) ||
722 (PropertyRequest->ValueSize < sizeof(LONG)))
723 return ntStatus;
724
725 // get channel information
726 channel = *((PLONG)PropertyRequest->Instance);
727
728 // check channel types, return when unknown
729 // as you can see, we have no multichannel support.
730 if ((channel != CHAN_LEFT) &&
731 (channel != CHAN_RIGHT) &&
732 (channel != CHAN_MASTER))
733 return ntStatus;
734
735 // get the buffer
736 PLONG Level = (PLONG)PropertyRequest->Value;
737
738 // Switch on the node id. This is just for parameter checking.
739 // If something goes wrong, we will immideately return with
740 // ntStatus, which is STATUS_INVALID_PARAMETER.
741 switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
742 {
743 // these are mono channels, don't respond to a right channel
744 // request.
747 case NODE_MIC_VOLUME:
756 case NODE_LFE_VOLUME:
757 // check type
758 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_VOLUMELEVEL)
759 return ntStatus;
760 // check channel
761 if (channel == CHAN_RIGHT)
762 return ntStatus;
763 // Well, this is a fake for the routine below that should work
764 // for all nodes ... On AC97 the right channel are the LSBs and
765 // mono channels have only LSBs used. Windows however thinks that
766 // mono channels are left channels (only). So we could say here
767 // we have a right channel request (to prg. the LSBs) instead of
768 // a left channel request. But we have some controls that are HW-
769 // stereo, but exposed to the system as mono. These are the virtual
770 // volume controls in front of the wave-in muxer for the MIC, PHONE
771 // and MONO MIX signals (see to the switch:
772 // NODE_VIRT_MASTER_INPUT_VOLUME1, 7 and 8). Saying we have a MASTER
773 // request makes sure the value is prg. for left and right channel,
774 // but on HW-mono controls the right channel is prg. only, cause the
775 // mask in ac97reg.h leads to a 0-mask for left channel prg. which
776 // just does nothing ;)
777 channel = CHAN_MASTER;
778 break;
779
780 // These are stereo channels.
786 case NODE_CD_VOLUME:
788 case NODE_AUX_VOLUME:
795 // check type
796 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_VOLUMELEVEL)
797 return ntStatus;
798 // check channel; we don't support a get with master
799 if ((channel == CHAN_MASTER) &&
800 (PropertyRequest->Verb & KSPROPERTY_TYPE_GET))
801 return ntStatus;
802 break;
803
804 case NODE_INVALID:
805 default:
806 // Ooops
807 DOUT (DBG_ERROR, ("PropertyHandler_Level: Invalid node requested."));
808 return ntStatus;
809 }
810
811 // Now, do some action!
812
813 // get the registered dB values.
814 ntStatus = GetDBValues (that->AdapterCommon, NodeDef, &lMinimum,
815 &lMaximum, &uStep);
816 if (!NT_SUCCESS (ntStatus))
817 return ntStatus;
818
819 // do a get
820 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
821 {
822 WORD wRegister;
823
824 // Read the HW register for the node except NODE_VIRT_MASTERMONO_VOLUME
825 // since this is pure virtual.
826 if (NodeDef != NODE_VIRT_MASTERMONO_VOLUME)
827 {
828 // Get the register and read it.
829 ntStatus = that->AdapterCommon->ReadCodecRegister (
830 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
831 if (!NT_SUCCESS (ntStatus))
832 return ntStatus;
833
834 // mask out every unused bit and rotate.
835 if (channel == CHAN_LEFT)
836 {
837 wRegister = (wRegister & (that->AdapterCommon->GetNodeMask (NodeDef)
838 & AC97REG_MASK_LEFT)) >> 8;
839 }
840 else // here goes mono or stereo-right
841 {
842 wRegister &= (that->AdapterCommon->GetNodeMask (NodeDef) &
844 }
845
846 // Oops - NODE_PCBEEP_VOLUME doesn't use bit0. We have to adjust.
847 if (NodeDef == NODE_PCBEEP_VOLUME)
848 wRegister >>= 1;
849
850 // we have to translate the reg to dB.dB value.
851
852 switch (NodeDef)
853 {
854 // for record, we calculate it reverse.
864 *Level = lMinimum + uStep * wRegister;
865 break;
866 default:
867 *Level = lMaximum - uStep * wRegister;
868 break;
869 }
870
871 // For the virtual controls, which are in front of a muxer, there
872 // is no mute control displayed. But we have a HW mute control, so
873 // what we do is enabling this mute when the user moves the slider
874 // down to the bottom and disabling it on every other position.
875 // We will return a PROP_MOST_NEGATIVE value in case the slider
876 // is moved to the bottom.
877 // We do this only for the "mono muxer" since the volume there ranges
878 // from 0 to -46.5dB. The record volumes only have a range from
879 // 0 to +22.5dB and we cannot mute them when the slider is down.
880 if ((NodeDef == NODE_VIRT_MONOOUT_VOLUME1) ||
881 (NodeDef == NODE_VIRT_MONOOUT_VOLUME2))
882 {
883 // read the register again.
884 ntStatus = that->AdapterCommon->ReadCodecRegister (
885 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
886 if (!NT_SUCCESS (ntStatus))
887 return ntStatus;
888 // return most negative value in case it is checked.
889 if (wRegister & AC97REG_MASK_MUTE)
891 }
892 }
893 else // This is master mono volume.
894 {
895 // Assume 0dB for master mono volume.
896 *Level = 0;
897 }
898
899 // when we have cache information then return this instead
900 // of the calculated value. if we don't, store the calculated
901 // value.
902 // We do that twice for master because in case we didn't set
903 // the NodeCache yet it will be set then.
904 if ((channel == CHAN_LEFT) || (channel == CHAN_MASTER))
905 {
906 if (that->stNodeCache[NodeDef].bLeftValid)
907 *Level = that->stNodeCache[NodeDef].lLeft;
908 else
909 {
910 that->stNodeCache[NodeDef].lLeft = *Level;
911 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
912 }
913 }
914
915 if ((channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
916 {
917 if (that->stNodeCache[NodeDef].bRightValid)
918 *Level = that->stNodeCache[NodeDef].lRight;
919 else
920 {
921 that->stNodeCache[NodeDef].lRight = *Level;
922 that->stNodeCache[NodeDef].bRightValid = (BYTE)-1;
923 }
924 }
925
926 // thats all, good bye.
927 PropertyRequest->ValueSize = sizeof(LONG);
928 DOUT (DBG_PROPERTY, ("GET: %s(%s) = 0x%x",NodeStrings[NodeDef],
929 channel==CHAN_LEFT ? "L" : "R", *Level));
930
931 // ntStatus was set with the read call! whatever this is, return it.
932 }
933 else // this must be a set
934 {
935 WORD wRegister;
936 LONG lLevel = *Level;
937
938 //
939 // Check borders.
940 //
941 // These 2 lines will have a special effect on sndvol32.
942 // Whenever you move the balance slider on a volume, one channel
943 // keeps the same and the other volume channel gets descreased.
944 // With ac97 on recording controls, the default slider position
945 // is at 0dB and the range of the volume is 0dB till +22.5dB.
946 // That means that panning (moving the balance slider) is simply
947 // impossible. If you would store the volume like sndvol gives it
948 // to you and you return it on a get, then the balance slider
949 // moves and stays at the position the user wanted it. However,
950 // if you return the actual volume the balance slider will jump
951 // back to the position that the HW can do (play with it to see
952 // how it works).
953 //
954 if (lLevel > lMaximum) lLevel = lMaximum;
955 if (lLevel < lMinimum) lLevel = lMinimum;
956
957 // First update the node cache.
958 if ((channel == CHAN_LEFT) || (channel == CHAN_MASTER))
959 {
960 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
961 that->stNodeCache[NodeDef].lLeft = lLevel;
962 }
963 if ((channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
964 {
965 that->stNodeCache[NodeDef].bRightValid = (BYTE)-1;
966 that->stNodeCache[NodeDef].lRight = lLevel;
967 }
968
969 //
970 // If we have a master mono, then we have to program the speaker
971 // volumes a little different.
972 // Check for master mono (surround or headphone present) and
973 // if one of the speaker volumes is requested.
974 //
975 if ((that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
976 that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT)) &&
977 ((NodeDef == NODE_VIRT_MASTERMONO_VOLUME) || (NodeDef == NODE_LFE_VOLUME) ||
978 (NodeDef == NODE_CENTER_VOLUME) || (NodeDef == NODE_FRONT_VOLUME) ||
979 (NodeDef == NODE_SURROUND_VOLUME) || (NodeDef == NODE_HPOUT_VOLUME)))
980 {
981 //
982 // For master mono we have to update all speaker volumes.
983 //
984 if (NodeDef == NODE_VIRT_MASTERMONO_VOLUME)
985 {
986 // Update all speaker volumes.
987 ntStatus = SetMultichannelVolume (that, NODE_FRONT_VOLUME);
988 if (that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
989 ntStatus = SetMultichannelVolume (that, NODE_HPOUT_VOLUME);
990 if (that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
992 if (that->AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
993 {
994 ntStatus = SetMultichannelVolume (that, NODE_CENTER_VOLUME);
995 ntStatus = SetMultichannelVolume (that, NODE_LFE_VOLUME);
996 }
997 }
998 else // update the individual speaker volume only.
999 {
1000 ntStatus = SetMultichannelVolume (that, NodeDef);
1001 }
1002 }
1003 else // This is for all other volumes (or no master mono present).
1004 {
1005 // calculate the dB.dB value.
1006
1007 // The nodes are calculated differently.
1008 switch (NodeDef)
1009 {
1010 // for record controls we calculate it 'reverse'.
1019 // read the wavein selector.
1020 ntStatus = that->AdapterCommon->ReadCodecRegister (
1021 that->AdapterCommon->GetNodeReg (NODE_WAVEIN_SELECT),
1022 &wRegister);
1023 if (!NT_SUCCESS (ntStatus))
1024 return ntStatus;
1025
1026 // mask out every unused bit.
1027 wRegister &= (that->AdapterCommon->GetNodeMask (
1029
1030 // check if the volume that we change belongs to the active
1031 // (selected) virtual channel.
1032 // Tricky: If the virtual nodes are not defined consecutively
1033 // this comparision will fail.
1034 if ((NodeDef - NODE_VIRT_MASTER_INPUT_VOLUME1) != wRegister)
1035 return ntStatus;
1036
1037 // fall through for calculation.
1038
1039 case NODE_MICIN_VOLUME:
1040 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1041 break;
1042
1045 // read the monoout selector.
1046 ntStatus = that->AdapterCommon->ReadCodecRegister (
1047 that->AdapterCommon->GetNodeReg (NODE_MONOOUT_SELECT),
1048 &wRegister);
1049 if (!NT_SUCCESS (ntStatus))
1050 return ntStatus;
1051
1052 // mask out every unused bit.
1053 wRegister &= that->AdapterCommon->GetNodeMask (NODE_MONOOUT_SELECT);
1054
1055 // check if the volume that we change belongs to the active
1056 // (selected) virtual channel.
1057 // Note: Monout select is set if we want to prg. MIC (Volume2).
1058 if ((!wRegister && (NodeDef == NODE_VIRT_MONOOUT_VOLUME2)) ||
1059 (wRegister && (NodeDef == NODE_VIRT_MONOOUT_VOLUME1)))
1060 return ntStatus;
1061
1062 // fall through for calculation.
1063 default:
1064 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1065 break;
1066 }
1067
1068 // Oops - NODE_PCBEEP_VOLUME doesn't use bit0. We have to adjust.
1069 if (NodeDef == NODE_PCBEEP_VOLUME)
1070 wRegister <<= 1;
1071
1072 // write the stuff (with mask!).
1073 // Note: mono channels are 'master' here (see fake above).
1074 // this makes sure that left and right channel is prg. for the virt.
1075 // controls. On controls that only have the right channel, the left
1076 // channel programming does nothing cause the mask will be zero.
1077 if ((channel == CHAN_LEFT) || (channel == CHAN_MASTER))
1078 {
1079 // write only left.
1080 ntStatus = that->AdapterCommon->WriteCodecRegister (
1081 that->AdapterCommon->GetNodeReg (NodeDef),
1082 wRegister << 8,
1083 that->AdapterCommon->GetNodeMask (NodeDef) & AC97REG_MASK_LEFT);
1084 // immediately return on error
1085 if (!NT_SUCCESS (ntStatus))
1086 return ntStatus;
1087 }
1088
1089 if ((channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
1090 {
1091 // write only right.
1092 ntStatus = that->AdapterCommon->WriteCodecRegister (
1093 that->AdapterCommon->GetNodeReg (NodeDef),
1094 wRegister,
1095 that->AdapterCommon->GetNodeMask (NodeDef) & AC97REG_MASK_RIGHT);
1096 // immediately return on error
1097 if (!NT_SUCCESS (ntStatus))
1098 return ntStatus;
1099 }
1100
1101 // For the virtual controls, which are in front of a muxer, there
1102 // is no mute control displayed. But we have a HW mute control, so
1103 // what we do is enabling this mute when the user moves the slider
1104 // down to the bottom and disabling it on every other position.
1105 // We do this only for the "mono muxer", the recording mutes will
1106 // never be muted.
1107 // Tricky: Master input virtual controls must be defined consecutively.
1108 if ((NodeDef >= NODE_VIRT_MASTER_INPUT_VOLUME1) &&
1109 (NodeDef <= NODE_VIRT_MASTER_INPUT_VOLUME8))
1110 {
1111 // disable the mute; this only works because the mute and volume
1112 // share the same register.
1113 ntStatus = that->AdapterCommon->WriteCodecRegister (
1114 that->AdapterCommon->GetNodeReg (NodeDef),
1116
1117 // Just in case.
1118 that->UpdateRecordMute ();
1119 }
1120
1121 if ((NodeDef == NODE_VIRT_MONOOUT_VOLUME1) ||
1122 (NodeDef == NODE_VIRT_MONOOUT_VOLUME2))
1123 {
1124 // these are only mono controls so checking one entry is enough.
1125 if ( that->stNodeCache[NodeDef].bLeftValid &&
1126 (that->stNodeCache[NodeDef].lLeft <= lMinimum))
1127 {
1128 // set the mute; this only works because the mute and volume
1129 // share the same register.
1130 ntStatus = that->AdapterCommon->WriteCodecRegister (
1131 that->AdapterCommon->GetNodeReg (NodeDef),
1133 }
1134 else
1135 {
1136 // clear the mute; this only works because the mute and volume
1137 // share the same register.
1138 ntStatus = that->AdapterCommon->WriteCodecRegister (
1139 that->AdapterCommon->GetNodeReg (NodeDef),
1141 }
1142 }
1143 }
1144
1145 DOUT (DBG_PROPERTY, ("SET: %s(%s) -> 0x%x", NodeStrings[NodeDef],
1146 channel==CHAN_LEFT ? "L" : channel==CHAN_RIGHT ? "R" : "M",
1147 *Level));
1148
1149 // ntStatus was set with the read call! whatever this is, return it.
1150 }
1151 }
1152 else
1153 {
1154 if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
1155 {
1156 ntStatus = BasicSupportHandler (PropertyRequest);
1157 }
1158 }
1159
1160 return ntStatus;
1161}
1162
1163/*****************************************************************************
1164 * CAC97MiniportTopology::PropertyHandler_Tone
1165 *****************************************************************************
1166 * Accesses a KSAUDIO_TONE property.
1167 * This function (property handler) is called by portcls every time there is a
1168 * get, set or basic support request for the node. The connection between the
1169 * node type and the property handler is made in the automation table which is
1170 * referenced when you register the node.
1171 * We use this property handler for all tone controls displayed at the advanced
1172 * property dialog in sndvol32 and the 3D controls displayed and exposed as
1173 * normal volume controls.
1174 */
1176(
1177 IN PPCPROPERTY_REQUEST PropertyRequest
1178)
1179{
1180 PAGED_CODE ();
1181
1182 ASSERT (PropertyRequest);
1183
1184 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_Tone]"));
1185
1187 TopoNodes NodeDef;
1189 ULONG uStep;
1190 // The major target is the object pointer to the topology miniport.
1191 CAC97MiniportTopology *that =
1192 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
1193
1194 ASSERT (that);
1195
1196 // validate node
1197 if (PropertyRequest->Node == (ULONG)-1)
1198 return ntStatus;
1199
1200 // do the appropriate action for the request.
1201
1202 // we should do a get or a set?
1203 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
1204 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
1205 {
1206 // validate parameters
1207 if ((PropertyRequest->InstanceSize < sizeof(LONG)) ||
1208 (PropertyRequest->ValueSize < sizeof(LONG)))
1209 return ntStatus;
1210
1211 // get the buffer
1212 PLONG Level = (PLONG)PropertyRequest->Value;
1213
1214 // Switch on the node id. This is just for parameter checking.
1215 // If something goes wrong, we will immideately return with
1216 // ntStatus, which is STATUS_INVALID_PARAMETER.
1217 switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
1218 {
1219 case NODE_BASS:
1220 // check type.
1221 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_BASS)
1222 return ntStatus;
1223 break;
1224
1225 case NODE_TREBLE:
1226 // check type.
1227 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_TREBLE)
1228 return ntStatus;
1229 break;
1230
1232 case NODE_VIRT_3D_DEPTH:
1233 // check 3D control
1234 if (!that->AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE)
1235 && (NodeDef == NODE_VIRT_3D_CENTER))
1236 return ntStatus;
1237 if (!that->AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE)
1238 && (NodeDef == NODE_VIRT_3D_DEPTH))
1239 return ntStatus;
1240 // check type
1241 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_VOLUMELEVEL)
1242 return ntStatus;
1243 // check channel
1244 if (*(PLONG(PropertyRequest->Instance)) == CHAN_RIGHT)
1245 return ntStatus;
1246 break;
1247
1248 case NODE_INVALID:
1249 default:
1250 // Ooops
1251 DOUT (DBG_ERROR, ("PropertyHandler_Tone: Invalid node requested."));
1252 return ntStatus;
1253 }
1254
1255 // Now, do some action!
1256
1257 // get the registered DB values
1258 ntStatus = GetDBValues (that->AdapterCommon, NodeDef, &lMinimum,
1259 &lMaximum, &uStep);
1260 if (!NT_SUCCESS (ntStatus))
1261 return ntStatus;
1262
1263 // do a get
1264 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
1265 {
1266 WORD wRegister;
1267
1268 // first get the stuff.
1269 ntStatus = that->AdapterCommon->ReadCodecRegister (
1270 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
1271 if (!NT_SUCCESS (ntStatus))
1272 return ntStatus;
1273
1274 // mask out every unused bit.
1275 wRegister &= that->AdapterCommon->GetNodeMask (NodeDef);
1276
1277 // rotate if bass tone control or 3D center control
1278 if ((NodeDef == NODE_BASS) || (NodeDef == NODE_VIRT_3D_CENTER))
1279 wRegister >>= 8;
1280
1281 // convert from reg to dB.dB value.
1282 if ((NodeDef == NODE_VIRT_3D_CENTER) ||
1283 (NodeDef == NODE_VIRT_3D_DEPTH))
1284 {
1285 // That's for the 3D controls
1286 *Level = lMinimum + uStep * wRegister;
1287 }
1288 else
1289 {
1290 if (wRegister == 0x000F)
1291 *Level = 0; // bypass
1292 else
1293 // And that's for the tone controls
1294 *Level = lMaximum - uStep * wRegister;
1295 }
1296
1297 // when we have cache information then return this instead
1298 // of the calculated value. if we don't, store the calculated
1299 // value.
1300 if (that->stNodeCache[NodeDef].bLeftValid)
1301 *Level = that->stNodeCache[NodeDef].lLeft;
1302 else
1303 {
1304 that->stNodeCache[NodeDef].lLeft = *Level;
1305 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
1306 }
1307
1308 // we return a LONG
1309 PropertyRequest->ValueSize = sizeof(LONG);
1310 DOUT (DBG_PROPERTY, ("GET: %s = 0x%x", NodeStrings[NodeDef], *Level));
1311 // ntStatus was set with the read call! whatever this is, return it.
1312 }
1313 else // that must be a set
1314 {
1315 WORD wRegister;
1316 LONG lLevel = *Level;
1317
1318 // calculate the dB.dB value.
1319 // check borders.
1320 if (lLevel > lMaximum) lLevel = lMaximum;
1321 if (lLevel < lMinimum) lLevel = lMinimum;
1322
1323 // write the value to the node cache.
1324 that->stNodeCache[NodeDef].lLeft = *Level;
1325 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
1326
1327 // convert from dB.dB value to reg.
1328 if ((NodeDef == NODE_VIRT_3D_CENTER) ||
1329 (NodeDef == NODE_VIRT_3D_DEPTH))
1330 {
1331 // For 3D controls
1332 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1333 }
1334 else
1335 {
1336 // For tone controls
1337 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1338 // We don't prg. 0dB Bass or 0dB Treble, instead we smartly prg.
1339 // a bypass which is reg. value 0x0F.
1340 if (wRegister == 7) // 0 dB
1341 wRegister = 0x000F; // bypass
1342 }
1343
1344 // rotate if bass tone control or 3D center control
1345 if ((NodeDef == NODE_BASS) || (NodeDef == NODE_VIRT_3D_CENTER))
1346 wRegister <<= 8;
1347
1348 // write the stuff.
1349 ntStatus = that->AdapterCommon->WriteCodecRegister (
1350 that->AdapterCommon->GetNodeReg (NodeDef),
1351 wRegister,
1352 that->AdapterCommon->GetNodeMask (NodeDef));
1353
1354 DOUT (DBG_PROPERTY,("SET: %s -> 0x%x", NodeStrings[NodeDef], *Level));
1355 // ntStatus was set with the write call! whatever this is, return in.
1356 }
1357 }
1358 else
1359 {
1360 if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
1361 {
1362 ntStatus = BasicSupportHandler (PropertyRequest);
1363 }
1364 }
1365
1366 return ntStatus;
1367}
1368
1369/*****************************************************************************
1370 * CAC97MiniportTopology::PropertyHandler_Ulong
1371 *****************************************************************************
1372 * Accesses a ULONG value property. For MUX and DEMUX.
1373 * This function (property handler) is called by portcls every time there is a
1374 * get, set or basic support request for the node. The connection between the
1375 * node type and the property handler is made in the automation table which is
1376 * referenced when you register the node.
1377 * We use this property handler for all muxer controls.
1378 */
1380(
1381 IN PPCPROPERTY_REQUEST PropertyRequest
1382)
1383{
1384 PAGED_CODE ();
1385
1386 ASSERT (PropertyRequest);
1387
1388 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_Ulong]"));
1389
1391 TopoNodes NodeDef;
1393 ULONG uStep;
1394 // The major target is the object pointer to the topology miniport.
1395 CAC97MiniportTopology *that =
1396 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
1397
1398 ASSERT (that);
1399
1400
1401 // validate node instance
1402 if (PropertyRequest->Node == (ULONG)-1)
1403 return ntStatus;
1404
1405 // if we should do a get or set.
1406 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
1407 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
1408 {
1409 // validate buffer size.
1410 if (PropertyRequest->ValueSize < sizeof(ULONG))
1411 return ntStatus;
1412
1413 // get the pointer to the buffer.
1414 PULONG PropValue = (PULONG)PropertyRequest->Value;
1415
1416 // Switch on the node id. This is just for parameter checking.
1417 // If something goes wrong, we will immideately return with
1418 // ntStatus, which is STATUS_INVALID_PARAMETER.
1419 switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
1420 {
1422 case NODE_WAVEIN_SELECT:
1423 // check the type
1424 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_MUX_SOURCE)
1425 return ntStatus;
1426 break;
1427
1428 case NODE_INVALID:
1429 default:
1430 // Ooops
1431 DOUT (DBG_ERROR, ("PropertyHandler_Tone: Invalid node requested."));
1432 return ntStatus;
1433 }
1434
1435 // Now do some action!
1436
1437 // should we return the value?
1438 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
1439 {
1440 WORD wRegister;
1441
1442 // first get the stuff.
1443 ntStatus = that->AdapterCommon->ReadCodecRegister (
1444 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
1445 if (!NT_SUCCESS (ntStatus))
1446 return ntStatus;
1447
1448 // mask out every unused bit.
1449 wRegister &= that->AdapterCommon->GetNodeMask (NodeDef);
1450
1451 // calculate the selected pin
1452 if (NodeDef == NODE_MONOOUT_SELECT)
1453 {
1454 // for mono out we have just one bit
1455 if (wRegister)
1456 *PropValue = 2;
1457 else
1458 *PropValue = 1;
1459 }
1460 else
1461 {
1462 // the wave in muxer is a stereo muxer, so just return the
1463 // right channel (gives values 0-7) and adjust it by adding 1.
1464 *PropValue = (wRegister & AC97REG_MASK_RIGHT) + 1;
1465 }
1466
1467 // we return a LONG
1468 PropertyRequest->ValueSize = sizeof(LONG);
1469 DOUT (DBG_PROPERTY, ("GET: %s = 0x%x", NodeStrings[NodeDef],
1470 *PropValue));
1471 // ntStatus was set with the read call! whatever this is, return it.
1472 }
1473 else // that must be a set
1474 {
1475 TopoNodes VirtNode;
1476 WORD wRegister;
1477 ULONG ulSelect = *PropValue;
1478 LONG lLevel;
1479
1480 // Check the selection first.
1481 if (NodeDef == NODE_MONOOUT_SELECT)
1482 {
1483 if ((ulSelect < 1) || (ulSelect > 2))
1484 return ntStatus; // STATUS_INVALID_PARAMETER
1485 }
1486 else
1487 {
1488 if ((ulSelect < 1) || (ulSelect > 8))
1489 return ntStatus; // STATUS_INVALID_PARAMETER
1490 }
1491
1492 // calculate the register value for programming.
1493 if (NodeDef == NODE_MONOOUT_SELECT)
1494 {
1495 // for mono out we have just one bit
1496 if (ulSelect == 2)
1497 // the mask will make sure we only prg. one bit.
1498 wRegister = 0xFFFF;
1499 else
1500 // ulSelect == 1
1501 wRegister = 0;
1502 }
1503 else
1504 {
1505 // *257 is the same as: (ulSelect << 8) + ulSelect
1506 wRegister = (WORD)(ulSelect - 1) * 257;
1507 }
1508
1509 // write the stuff.
1510 ntStatus = that->AdapterCommon->WriteCodecRegister (
1511 that->AdapterCommon->GetNodeReg (NodeDef),
1512 wRegister,
1513 that->AdapterCommon->GetNodeMask (NodeDef));
1514
1515 // Store the virt. node for later use.
1516 // Tricky: Master input virtual controls must be defined consecutively.
1517 if (NodeDef == NODE_MONOOUT_SELECT)
1518 VirtNode = (TopoNodes)(NODE_VIRT_MONOOUT_VOLUME1 + (ulSelect - 1));
1519 else
1520 VirtNode = (TopoNodes)(NODE_VIRT_MASTER_INPUT_VOLUME1 + (ulSelect - 1));
1521
1522 // Virtual controls make our life more complicated. When the user
1523 // changes the input source say from CD to LiniIn, then the system just
1524 // sends a message to the input muxer that the selection changed.
1525 // Cause we have only one HW register for the input muxer, all volumes
1526 // displayed for the user are "virtualized", means they are not there,
1527 // and when the selection changes, we have to prg. the volume of the
1528 // selected input to the HW register. That's what we do now.
1529
1530 // get the registered DB values
1531 ntStatus = GetDBValues (that->AdapterCommon, VirtNode,
1532 &lMinimum, &lMaximum, &uStep);
1533 if (!NT_SUCCESS (ntStatus))
1534 return ntStatus;
1535
1536 // We can be lazy here and don't check for mono controls. Reason
1537 // is that the level handler writes the volume value for mono
1538 // controls into both the left and right node cache ;))
1539
1540 if (that->stNodeCache[VirtNode].bLeftValid &&
1541 that->stNodeCache[VirtNode].bRightValid)
1542 {
1543 // prg. left channel
1544 lLevel = that->stNodeCache[VirtNode].lLeft;
1545
1546 // calculate the dB.dB value.
1547 if (NodeDef == NODE_MONOOUT_SELECT)
1548 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1549 else
1550 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1551
1552 // write left channel.
1553 ntStatus = that->AdapterCommon->WriteCodecRegister (
1554 that->AdapterCommon->GetNodeReg (VirtNode),
1555 wRegister << 8,
1556 that->AdapterCommon->GetNodeMask (VirtNode) & AC97REG_MASK_LEFT);
1557
1558 // prg. right channel
1559 lLevel = that->stNodeCache[VirtNode].lRight;
1560
1561 // calculate the dB.dB value.
1562 if (NodeDef == NODE_MONOOUT_SELECT)
1563 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1564 else
1565 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1566
1567 // write right channel.
1568 ntStatus = that->AdapterCommon->WriteCodecRegister (
1569 that->AdapterCommon->GetNodeReg (VirtNode),
1570 wRegister,
1571 that->AdapterCommon->GetNodeMask (VirtNode) & AC97REG_MASK_RIGHT);
1572
1573 // For the virtual controls, which are in front of a muxer, there
1574 // is no mute control displayed. But we have a HW mute control, so
1575 // what we do is enabling this mute when the user moves the slider
1576 // down to the bottom and disabling it on every other position.
1577 // We do this only for the "mono muxer", the recording mutes will
1578 // never be muted.
1579 if (NodeDef == NODE_WAVEIN_SELECT)
1580 {
1581 // disable the mute; this only works because the mute and volume
1582 // share the same register.
1583 ntStatus = that->AdapterCommon->WriteCodecRegister (
1584 that->AdapterCommon->GetNodeReg (VirtNode),
1586
1587 that->UpdateRecordMute ();
1588 }
1589
1590 if (NodeDef == NODE_MONOOUT_SELECT)
1591 {
1592 // these are only mono controls so checking one entry is enough.
1593 if ( that->stNodeCache[VirtNode].bLeftValid &&
1594 (that->stNodeCache[VirtNode].lLeft <= lMinimum))
1595 {
1596 // set the mute; this only works because the mute and volume
1597 // share the same register.
1598 ntStatus = that->AdapterCommon->WriteCodecRegister (
1599 that->AdapterCommon->GetNodeReg (VirtNode),
1601 }
1602 else
1603 {
1604 // clear the mute; this only works because the mute and volume
1605 // share the same register.
1606 ntStatus = that->AdapterCommon->WriteCodecRegister (
1607 that->AdapterCommon->GetNodeReg (VirtNode),
1609 }
1610 }
1611 }
1612
1613 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x", NodeStrings[NodeDef],
1614 *PropValue));
1615 // ntStatus was set with the write call! whatever this is, return it.
1616 }
1617 }
1618
1619 return ntStatus;
1620}
1621
1622/*****************************************************************************
1623 * CAC97MiniportTopology::PropertyHandler_CpuResources
1624 *****************************************************************************
1625 * Propcesses a KSPROPERTY_AUDIO_CPU_RESOURCES request
1626 * This property handler is called by the system for every node and every node
1627 * must support this property. Basically, this property is for performance
1628 * monitoring and we just say here that every function we claim to have has HW
1629 * support (which by the way is true).
1630 */
1632(
1633 IN PPCPROPERTY_REQUEST PropertyRequest
1634)
1635{
1636 PAGED_CODE ();
1637
1638 ASSERT (PropertyRequest);
1639
1640 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_CpuResources]"));
1641
1642 CAC97MiniportTopology *that =
1643 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
1645
1646 ASSERT (that);
1647
1648 // validate node
1649 if (PropertyRequest->Node == (ULONG)-1)
1650 return ntStatus;
1651
1652 // validate the node def.
1653 if (that->TransNodeNrToNodeDef (PropertyRequest->Node) == NODE_INVALID)
1654 return ntStatus;
1655
1656 // we should do a get
1657 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
1658 {
1659 // just return the flag.
1660 if (PropertyRequest->ValueSize >= sizeof(LONG))
1661 {
1662 *((PLONG)PropertyRequest->Value) = KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU;
1663 PropertyRequest->ValueSize = sizeof(LONG);
1664 ntStatus = STATUS_SUCCESS;
1665 }
1666 else // not enough buffer.
1667 {
1668 ntStatus = STATUS_BUFFER_TOO_SMALL;
1669 }
1670 }
1671
1672 return ntStatus;
1673}
1674
1675#ifdef INCLUDE_PRIVATE_PROPERTY
1676/*****************************************************************************
1677 * CAC97MiniportTopology::PropertyHandler_Private
1678 *****************************************************************************
1679 * This is a private property that returns some AC97 codec features.
1680 * This routine gets called whenever the topology filter gets a property
1681 * request with KSPROSETPID_Private and KSPROPERTY_AC97_FEATURES set. It is not
1682 * a node property but a filter property (you don't have to specify a node).
1683 */
1684NTSTATUS CAC97MiniportTopology::PropertyHandler_Private
1685(
1686 IN PPCPROPERTY_REQUEST PropertyRequest
1687)
1688{
1689 PAGED_CODE ();
1690
1691 ASSERT (PropertyRequest);
1692
1693 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_Private]"));
1694
1696 // The major target is the object pointer to the topology miniport.
1697 CAC97MiniportTopology *that =
1698 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
1699
1700
1701 ASSERT (that);
1702
1703
1704 // We only have a get defined.
1705 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
1706 {
1707 // Check the ID ("function" in "group").
1708 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AC97_FEATURES)
1709 return ntStatus;
1710
1711 // validate buffer size.
1712 if (PropertyRequest->ValueSize < sizeof (tAC97Features))
1713 return ntStatus;
1714
1715 // The "Value" is the out buffer that you pass in DeviceIoControl call.
1716 tAC97Features *pAC97Features = (tAC97Features *) PropertyRequest->Value;
1717
1718 // Check the buffer.
1719 if (!pAC97Features)
1720 return ntStatus;
1721
1722 //
1723 // Fill the AC97Features structure.
1724 //
1725
1726 // Set the volumes.
1727 pAC97Features->MasterVolume = Volume5bit;
1728 if (that->AdapterCommon->GetNodeConfig (NODEC_6BIT_MASTER_VOLUME))
1729 pAC97Features->MasterVolume = Volume6bit;
1730
1731 pAC97Features->HeadphoneVolume = Volume5bit;
1732 if (!that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
1733 pAC97Features->HeadphoneVolume = VolumeDisabled;
1734 else if (that->AdapterCommon->GetNodeConfig (NODEC_6BIT_HPOUT_VOLUME))
1735 pAC97Features->HeadphoneVolume = Volume6bit;
1736
1737 pAC97Features->MonoOutVolume = Volume5bit;
1738 if (!that->AdapterCommon->GetPinConfig (PINC_MONOOUT_PRESENT))
1739 pAC97Features->MonoOutVolume = VolumeDisabled;
1740 else if (that->AdapterCommon->GetNodeConfig (NODEC_6BIT_MONOOUT_VOLUME))
1741 pAC97Features->MonoOutVolume = Volume6bit;
1742
1743 // The 18/20bit Resolution information.
1744 WORD wCodecID;
1745
1746 // Read the reset register.
1747 ntStatus = that->AdapterCommon->ReadCodecRegister (AC97REG_RESET, &wCodecID);
1748 if (!NT_SUCCESS (ntStatus))
1749 return ntStatus;
1750
1751 //
1752 // Now check the DAC and ADC resolution.
1753 //
1754
1755 // First the DAC.
1756 pAC97Features->DAC = Resolution16bit;
1757 if (wCodecID & 0x0040)
1758 pAC97Features->DAC = Resolution18bit;
1759 if (wCodecID & 0x0080)
1760 pAC97Features->DAC = Resolution20bit;
1761
1762 // Then the ADC.
1763 pAC97Features->ADC = Resolution16bit;
1764 if (wCodecID & 0x0100)
1765 pAC97Features->ADC = Resolution18bit;
1766 if (wCodecID & 0x0200)
1767 pAC97Features->ADC = Resolution20bit;
1768
1769 // 3D technique
1770 pAC97Features->n3DTechnique = ((wCodecID & 0x7C00) >> 10);
1771
1772 // Set the flag for MicIn.
1773 pAC97Features->bMicInPresent = that->AdapterCommon->
1774 GetPinConfig (PINC_MICIN_PRESENT) ? TRUE : FALSE;
1775
1776 // Variable sample rate info.
1777 pAC97Features->bVSRPCM = that->AdapterCommon->
1778 GetNodeConfig (NODEC_PCM_VARIABLERATE_SUPPORTED) ? TRUE : FALSE;
1779 pAC97Features->bDSRPCM = that->AdapterCommon->
1780 GetNodeConfig (NODEC_PCM_DOUBLERATE_SUPPORTED) ? TRUE : FALSE;
1781 pAC97Features->bVSRMIC = that->AdapterCommon->
1782 GetNodeConfig (NODEC_MIC_VARIABLERATE_SUPPORTED) ? TRUE : FALSE;
1783
1784 // Additional DAC's
1785 pAC97Features->bCenterDAC = that->AdapterCommon->
1786 GetNodeConfig (NODEC_CENTER_DAC_PRESENT) ? TRUE : FALSE;
1787 pAC97Features->bSurroundDAC = that->AdapterCommon->
1788 GetNodeConfig (NODEC_SURROUND_DAC_PRESENT) ? TRUE : FALSE;
1789 pAC97Features->bLFEDAC = that->AdapterCommon->
1790 GetNodeConfig (NODEC_LFE_DAC_PRESENT) ? TRUE : FALSE;
1791
1792
1793 // We filled out the structure.
1794 PropertyRequest->ValueSize = sizeof (tAC97Features);
1795 DOUT (DBG_PROPERTY, ("Get AC97Features succeeded."));
1796
1797 // ntStatus was set with the read call! whatever this is, return it.
1798 }
1799#ifdef PROPERTY_SHOW_SET
1800 else
1801 {
1802 // Just to show, we have a SET also.
1803 if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET)
1804 {
1805 // This is the only property for a SET.
1806 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AC97_SAMPLE_SET)
1807 return ntStatus;
1808
1809 // validate buffer size.
1810 if (PropertyRequest->ValueSize < sizeof (DWORD))
1811 return ntStatus;
1812
1813 // Get the pointer to the DWORD.
1814 DWORD *pTimerTick = (DWORD *)PropertyRequest->Value;
1815
1816 // Check the buffer.
1817 if (!pTimerTick)
1818 return ntStatus;
1819
1820 // Print the message.
1821 DOUT (DBG_ALL, ("This computer is already %d ms running Windows!", *pTimerTick));
1822 ntStatus = STATUS_SUCCESS;
1823 }
1824 }
1825#endif
1826
1827 return ntStatus;
1828}
1829#endif
1830
1831
#define PAGED_CODE()
@ AC97REG_RESET
Definition: ac97reg.h:18
LONG NTSTATUS
Definition: precomp.h:26
tNodeCache stNodeCache[NODE_TOP_ELEMENT]
Definition: mintopo.h:106
static NTSTATUS GetDBValues(IN PADAPTERCOMMON, IN TopoNodes Node, OUT LONG *plMinimum, OUT LONG *plMaximum, OUT ULONG *puStep)
Definition: prophnd.cpp:156
TopoNodes TransNodeNrToNodeDef(IN int Node)
Definition: mintopo.h:135
static NTSTATUS SetMultichannelMute(IN CAC97MiniportTopology *that, IN TopoNodes Mute)
Definition: prophnd.cpp:36
PADAPTERCOMMON AdapterCommon
Definition: mintopo.h:98
static NTSTATUS NTAPI PropertyHandler_Ulong(IN PPCPROPERTY_REQUEST PropertyRequest)
Definition: prophnd.cpp:1380
static NTSTATUS BasicSupportHandler(IN PPCPROPERTY_REQUEST PropertyRequest)
Definition: prophnd.cpp:580
static NTSTATUS NTAPI PropertyHandler_Level(IN PPCPROPERTY_REQUEST PropertyRequest)
Definition: prophnd.cpp:689
static NTSTATUS SetMultichannelVolume(IN CAC97MiniportTopology *that, IN TopoNodes Volume)
Definition: prophnd.cpp:77
void UpdateRecordMute(void)
Definition: mintopo.cpp:2053
static NTSTATUS NTAPI PropertyHandler_Tone(IN PPCPROPERTY_REQUEST PropertyRequest)
Definition: prophnd.cpp:1176
static NTSTATUS NTAPI PropertyHandler_OnOff(IN PPCPROPERTY_REQUEST PropertyRequest)
Definition: prophnd.cpp:334
static NTSTATUS NTAPI PropertyHandler_CpuResources(IN PPCPROPERTY_REQUEST PropertyRequest)
Definition: prophnd.cpp:1632
struct config_s config
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
@ VT_I4
Definition: compat.h:2298
#define CHAN_MASTER
Definition: interfaces.hpp:68
#define CHAN_RIGHT
Definition: interfaces.hpp:67
#define CHAN_LEFT
Definition: interfaces.hpp:66
switch(r->id)
Definition: btrfs.c:3046
const int DBG_ALL
Definition: debug.h:35
#define DOUT(lvl, strings)
Definition: debug.h:82
const int DBG_PROPERTY
Definition: debug.h:29
@ PINC_MONOOUT_PRESENT
Definition: shared.h:69
@ PINC_SURROUND_PRESENT
Definition: shared.h:74
@ PINC_CENTER_LFE_PRESENT
Definition: shared.h:75
@ PINC_HPOUT_PRESENT
Definition: shared.h:68
@ PINC_MICIN_PRESENT
Definition: shared.h:70
TopoNodes
Definition: shared.h:186
@ NODE_MASTEROUT_VOLUME
Definition: shared.h:215
@ NODE_HPOUT_MUTE
Definition: shared.h:218
@ NODE_TREBLE
Definition: shared.h:212
@ NODE_WAVEOUT_MUTE
Definition: shared.h:188
@ NODE_PHONE_VOLUME
Definition: shared.h:192
@ NODE_VIRT_MASTER_INPUT_VOLUME1
Definition: shared.h:223
@ NODE_MICIN_MUTE
Definition: shared.h:232
@ NODE_LFE_MUTE
Definition: shared.h:238
@ NODE_VIRT_MONOOUT_VOLUME1
Definition: shared.h:220
@ NODE_PHONE_MUTE
Definition: shared.h:193
@ NODE_MIC_BOOST
Definition: shared.h:195
@ NODE_WAVEIN_SELECT
Definition: shared.h:222
@ NODE_HPOUT_VOLUME
Definition: shared.h:217
@ NODE_VIRT_MONOOUT_VOLUME2
Definition: shared.h:221
@ NODE_CENTER_MUTE
Definition: shared.h:236
@ NODE_LFE_VOLUME
Definition: shared.h:237
@ NODE_VIRT_MASTER_INPUT_VOLUME3
Definition: shared.h:225
@ NODE_VIRT_MASTER_INPUT_VOLUME8
Definition: shared.h:230
@ NODE_SIMUL_STEREO
Definition: shared.h:214
@ NODE_VIRT_MASTERMONO_MUTE
Definition: shared.h:242
@ NODE_AUX_VOLUME
Definition: shared.h:204
@ NODE_PCBEEP_MUTE
Definition: shared.h:191
@ NODE_VIRT_3D_CENTER
Definition: shared.h:207
@ NODE_LINEIN_VOLUME
Definition: shared.h:198
@ NODE_MIC_MUTE
Definition: shared.h:197
@ NODE_VIRT_WAVEOUT_3D_BYPASS
Definition: shared.h:189
@ NODE_VIRT_3D_ENABLE
Definition: shared.h:209
@ NODE_VIRT_MASTER_INPUT_VOLUME2
Definition: shared.h:224
@ NODE_CD_VOLUME
Definition: shared.h:200
@ NODE_FRONT_VOLUME
Definition: shared.h:239
@ NODE_MIC_VOLUME
Definition: shared.h:196
@ NODE_BASS
Definition: shared.h:211
@ NODE_LINEIN_MUTE
Definition: shared.h:199
@ NODE_VIRT_MASTER_INPUT_VOLUME6
Definition: shared.h:228
@ NODE_PCBEEP_VOLUME
Definition: shared.h:190
@ NODE_VIRT_MASTER_INPUT_VOLUME5
Definition: shared.h:227
@ NODE_LOUDNESS
Definition: shared.h:213
@ NODE_VIDEO_MUTE
Definition: shared.h:203
@ NODE_CENTER_VOLUME
Definition: shared.h:235
@ NODE_CD_MUTE
Definition: shared.h:201
@ NODE_VIRT_MASTER_INPUT_VOLUME7
Definition: shared.h:229
@ NODE_WAVEOUT_VOLUME
Definition: shared.h:187
@ NODE_FRONT_MUTE
Definition: shared.h:240
@ NODE_INVALID
Definition: shared.h:244
@ NODE_VIRT_MASTERMONO_VOLUME
Definition: shared.h:241
@ NODE_VIRT_3D_DEPTH
Definition: shared.h:208
@ NODE_SURROUND_VOLUME
Definition: shared.h:233
@ NODE_MASTEROUT_MUTE
Definition: shared.h:216
@ NODE_SURROUND_MUTE
Definition: shared.h:234
@ NODE_VIDEO_VOLUME
Definition: shared.h:202
@ NODE_MONOOUT_SELECT
Definition: shared.h:219
@ NODE_AUX_MUTE
Definition: shared.h:205
@ NODE_MICIN_VOLUME
Definition: shared.h:231
@ NODE_VIRT_MASTER_INPUT_VOLUME4
Definition: shared.h:226
@ NODE_MIC_SELECT
Definition: shared.h:194
TopoNodeConfig
Definition: shared.h:84
@ NODEC_6BIT_CENTER_LFE_VOLUME
Definition: shared.h:93
@ NODEC_3D_DEPTH_ADJUSTABLE
Definition: shared.h:95
@ NODEC_PCM_DOUBLERATE_SUPPORTED
Definition: shared.h:98
@ NODEC_MIC_VARIABLERATE_SUPPORTED
Definition: shared.h:99
@ NODEC_6BIT_HPOUT_VOLUME
Definition: shared.h:90
@ NODEC_SURROUND_DAC_PRESENT
Definition: shared.h:101
@ NODEC_CENTER_DAC_PRESENT
Definition: shared.h:100
@ NODEC_PCM_VARIABLERATE_SUPPORTED
Definition: shared.h:96
@ NODEC_3D_CENTER_ADJUSTABLE
Definition: shared.h:94
@ NODEC_LFE_DAC_PRESENT
Definition: shared.h:102
@ NODEC_6BIT_SURROUND_VOLUME
Definition: shared.h:92
@ NODEC_6BIT_MONOOUT_VOLUME
Definition: shared.h:91
@ NODEC_6BIT_MASTER_VOLUME
Definition: shared.h:89
IAC97AdapterCommon * PADAPTERCOMMON
Definition: shared.h:488
#define KSPROPERTY_TYPE_SET
Definition: dmksctrl.h:43
#define KSPROPERTY_TYPE_BASICSUPPORT
Definition: dmksctrl.h:45
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
#define KSPROPERTY_MEMBER_STEPPEDRANGES
Definition: ks.h:1559
#define KSPROPTYPESETID_General
Definition: ks.h:858
struct KSPROPERTY_STEPPING_LONG * PKSPROPERTY_STEPPING_LONG
struct KSPROPERTY_DESCRIPTION * PKSPROPERTY_DESCRIPTION
struct KSPROPERTY_MEMBERSHEADER * PKSPROPERTY_MEMBERSHEADER
@ KSPROPERTY_AUDIO_BASS
Definition: ksmedia.h:1067
@ KSPROPERTY_AUDIO_VOLUMELEVEL
Definition: ksmedia.h:1057
@ KSPROPERTY_AUDIO_MUTE
Definition: ksmedia.h:1066
@ KSPROPERTY_AUDIO_TREBLE
Definition: ksmedia.h:1069
@ KSPROPERTY_AUDIO_AGC
Definition: ksmedia.h:1074
@ KSPROPERTY_AUDIO_LOUDNESS
Definition: ksmedia.h:1076
@ KSPROPERTY_AUDIO_MUX_SOURCE
Definition: ksmedia.h:1065
#define KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU
Definition: ksmedia.h:1198
if(dx< 0)
Definition: linetemp.h:194
const WORD AC97REG_MASK_RIGHT
Definition: mintopo.h:49
const WORD AC97REG_MASK_MUTE
Definition: mintopo.h:50
const WORD AC97REG_MASK_LEFT
Definition: mintopo.h:48
const long PROP_MOST_NEGATIVE
Definition: mintopo.h:56
LONG lMinimum
Definition: mmsystem.h:0
LONG lMaximum
Definition: mmsystem.h:1
UNICODE_STRING Volume
Definition: fltkernel.h:1172
#define ASSERT(a)
Definition: mode.c:44
#define DBG_ERROR
Definition: nfs41_debug.h:78
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
long LONG
Definition: pedump.c:60
const LONG CHAN_LEFT
Definition: prophnd.cpp:17
const LONG CHAN_MASTER
Definition: prophnd.cpp:19
const LONG CHAN_RIGHT
Definition: prophnd.cpp:18
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
ULONG Id
Definition: dmksctrl.h:77
ULONG Flags
Definition: dmksctrl.h:78
GUID Set
Definition: dmksctrl.h:76
ULONG DescriptionSize
Definition: ks.h:1540
KSIDENTIFIER PropTypeSet
Definition: ks.h:1541
ULONG MembersListCount
Definition: ks.h:1542
BYTE bLeftValid
Definition: mintopo.h:77
BYTE bRightValid
Definition: mintopo.h:78
long lLeft
Definition: mintopo.h:75
long lRight
Definition: mintopo.h:76
Definition: range.c:39
uint32_t * PULONG
Definition: typedefs.h:59
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: dlist.c:348
#define DBG_PRINT(ppi, ch, level)
Definition: win32kdebug.h:169
BOOL * PBOOL
Definition: windef.h:161
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
unsigned char BYTE
Definition: xxhash.c:193