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