ReactOS 0.4.15-dev-7842-g558ab78
common.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 common.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 Common: "
12
13#include "common.h"
14
15
16/*****************************************************************************
17 * Static Members
18 *****************************************************************************
19 */
20
21//
22// This is the register cache including registry names and default values. The
23// first WORD contains the register value and the second WORD contains a flag.
24// Currently, we only set SHREG_INVALID if we have to read the register at
25// startup (that's true when there is no constant default value for the
26// register). Note that we cache the registers only to prevent read access to
27// the AC97 CoDec during runtime, because this is slow (40us).
28// We only set SHREG_INIT if we want to set the register to default at driver
29// startup. If needed, the third field contains the registry name and the
30// forth field contains a default value that is used when there is no registry
31// entry.
32// The flag SHREG_NOCACHE is used when we don't want to cache the register
33// at all. This is neccessary for status registers and sample rate registers.
34//
36{
37{0x0000, SHREG_INVALID, NULL, 0}, // AC97REG_RESET
38{0x8000, SHREG_INIT, L"MasterVolume", 0x0000}, // AC97REG_MASTER_VOLUME
39{0x8000, SHREG_INIT, L"HeadphoneVolume", 0x0000}, // AC97REG_HPHONE_VOLUME
40{0x8000, SHREG_INIT, L"MonooutVolume", 0x0000}, // AC97REG_MMONO_VOLUME
41{0x0F0F, SHREG_INIT, L"ToneControls", 0x0F0F}, // AC97REG_MASTER_TONE
42{0x0000, SHREG_INVALID |
43 SHREG_INIT, L"BeepVolume", 0x0000}, // AC97REG_BEEP_VOLUME
44{0x8008, SHREG_INIT, L"PhoneVolume", 0x8008}, // AC97REG_PHONE_VOLUME
45{0x8008, SHREG_INIT, L"MicVolume", 0x8008}, // AC97REG_MIC_VOLUME
46{0x8808, SHREG_INIT, L"LineInVolume", 0x0808}, // AC97REG_LINE_IN_VOLUME
47{0x8808, SHREG_INIT, L"CDVolume", 0x0808}, // AC97REG_CD_VOLUME
48{0x8808, SHREG_INIT, L"VideoVolume", 0x0808}, // AC97REG_VIDEO_VOLUME
49{0x8808, SHREG_INIT, L"AUXVolume", 0x0808}, // AC97REG_AUX_VOLUME
50{0x8808, SHREG_INIT, L"WaveOutVolume", 0x0808}, // AC97REG_PCM_OUT_VOLUME
51{0x0000, SHREG_INIT, L"RecordSelect", 0x0404}, // AC97REG_RECORD_SELECT
52{0x8000, SHREG_INIT, L"RecordGain", 0x0000}, // AC97REG_RECORD_GAIN
53{0x8000, SHREG_INIT, L"RecordGainMic", 0x0000}, // AC97REG_RECORD_GAIN_MIC
54{0x0000, SHREG_INIT, L"GeneralPurpose", 0x0000}, // AC97REG_GENERAL
55{0x0000, SHREG_INIT, L"3DControl", 0x0000}, // AC97REG_3D_CONTROL
56{0x0000, SHREG_NOCACHE, NULL, 0}, // AC97REG_RESERVED
57{0x0000, SHREG_NOCACHE |
58 SHREG_INIT, L"PowerDown", 0}, // AC97REG_POWERDOWN
59// AC97-2.0 registers
60{0x0000, SHREG_INVALID, NULL, 0}, // AC97REG_EXT_AUDIO_ID
61{0x0000, SHREG_NOCACHE |
62 SHREG_INIT, L"ExtAudioCtrl", 0x4001}, // AC97REG_EXT_AUDIO_CTRL
63{0xBB80, SHREG_NOCACHE, NULL, 0}, // AC97REG_FRONT_SAMPLERATE
64{0xBB80, SHREG_NOCACHE, NULL, 0}, // AC97REG_SURROUND_SAMPLERATE
65{0xBB80, SHREG_NOCACHE, NULL, 0}, // AC97REG_LFE_SAMPLERATE
66{0xBB80, SHREG_NOCACHE, NULL, 0}, // AC97REG_RECORD_SAMPLERATE
67{0xBB80, SHREG_NOCACHE, NULL, 0}, // AC97REG_MIC_SAMPLERATE
68{0x8080, SHREG_INIT, L"CenterLFEVolume", 0x0000}, // AC97REG_CENTER_LFE_VOLUME
69{0x8080, SHREG_INIT, L"SurroundVolume", 0x0000}, // AC97REG_SURROUND_VOLUME
70{0x0000, SHREG_NOCACHE, NULL, 0} // AC97REG_RESERVED2
71
72// We leave the other values blank. There would be a huge gap with 31
73// elements that are currently unused, and then there would be 2 other
74// (used) values, the vendor IDs. We just force a read from the vendor
75// IDs in the end of ProbeHWConfig to fill the cache.
76};
77
78
79//
80// This is the hardware configuration information. The first struct is for
81// nodes, which we default to FALSE. The second struct is for Pins, which
82// contains the configuration (FALSE) and the registry string which is the
83// reason for making a static struct so we can just fill in the name.
84//
86{
87 // Nodes
88 {{FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE},
89 {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE},
90 {FALSE}},
91 // Pins
92 {{FALSE, L"DisablePCBeep"}, // PINC_PCBEEP_PRESENT
93 {FALSE, L"DisablePhone"}, // PINC_PHONE_PRESENT
94 {FALSE, L"DisableMic2"}, // PINC_MIC2_PRESENT
95 {FALSE, L"DisableVideo"}, // PINC_VIDEO_PRESENT
96 {FALSE, L"DisableAUX"}, // PINC_AUX_PRESENT
97 {FALSE, L"DisableHeadphone"}, // PINC_HPOUT_PRESENT
98 {FALSE, L"DisableMonoOut"}, // PINC_MONOOUT_PRESENT
99 {FALSE, L"DisableMicIn"}, // PINC_MICIN_PRESENT
100 {FALSE, L"DisableMic"}, // PINC_MIC_PRESENT
101 {FALSE, L"DisableLineIn"}, // PINC_LINEIN_PRESENT
102 {FALSE, L"DisableCD"}, // PINC_CD_PRESENT
103 {FALSE, L"DisableSurround"}, // PINC_SURROUND_PRESENT
104 {FALSE, L"DisableCenterLFE"}} // PINC_CENTER_LFE_PRESENT
105};
106
107
108#ifdef _MSC_VER
109#pragma code_seg("PAGE")
110#endif
111/*****************************************************************************
112 * NewAdapterCommon
113 *****************************************************************************
114 * Create a new adapter common object.
115 */
117(
119 IN REFCLSID,
120 IN PUNKNOWN UnknownOuter OPTIONAL,
122 __drv_reportError("Must succeed pool allocations are forbidden. "
123 "Allocation failures cause a system crash"))
125)
126{
127 PAGED_CODE ();
128
129 ASSERT (Unknown);
130
131 DOUT (DBG_PRINT, ("[NewAdapterCommon]"));
132
133 STD_CREATE_BODY_WITH_TAG_(CAC97AdapterCommon,Unknown,UnknownOuter,PoolType,
135}
136
137
138/*****************************************************************************
139 * CAC97AdapterCommon::Init
140 *****************************************************************************
141 * Initialize the adapter common object -> initialize and probe HW.
142 * Pass only checked resources.
143 */
144STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::Init
145(
148)
149{
150 PAGED_CODE ();
151
154
155 NTSTATUS ntStatus = STATUS_SUCCESS;
156
157 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::Init]"));
158
159 //
160 // Set the topology pointer to NULL.
161 //
163
164 //
165 // Save the device object
166 //
168
169 //
170 // Get the base address for the AC97 codec and bus master.
171 //
172 ASSERT (ResourceList->FindTranslatedPort (0));
173 m_pCodecBase = (PUSHORT)ResourceList->FindTranslatedPort (0)->
174 u.Port.Start.QuadPart;
175
176 ASSERT (ResourceList->FindTranslatedPort (1));
177 m_pBusMasterBase = (PUCHAR)ResourceList->FindTranslatedPort (1)->
178 u.Port.Start.QuadPart;
179
180 DOUT (DBG_SYSINFO, ("Configuration:\n"
181 " Bus Master = 0x%p\n"
182 " Codec = 0x%p",
184
185 //
186 // Set m_bDirectRead to TRUE so that all AC97 register read and
187 // writes are going directly to the HW
188 //
190
191 //
192 // Initialize the hardware.
193 //
194 ntStatus = InitAC97 ();
195 if (!NT_SUCCESS (ntStatus))
196 return ntStatus;
197
198 //
199 // Probe hardware configuration
200 //
201 ntStatus = ProbeHWConfig ();
202 if (!NT_SUCCESS (ntStatus))
203 {
204 DOUT (DBG_ERROR, ("Probing of hardware configuration failed!"));
205 return ntStatus;
206 }
207
208 //
209 // Now, every AC97 read access goes to the cache.
210 //
212
213 //
214 // Restore the AC97 registers now.
215 //
216#if (DBG)
217 DumpConfig ();
218#endif
219 ntStatus = SetAC97Default ();
220
221 //
222 // Initialize the device state.
223 //
225
226 return ntStatus;
227}
228
229
230/*****************************************************************************
231 * CAC97AdapterCommon::~CAC97AdapterCommon
232 *****************************************************************************
233 * Destructor.
234 */
236{
237 PAGED_CODE ();
238
239 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::~CAC97AdapterCommon]"));
240}
241
242
243#if (DBG)
244/*****************************************************************************
245 * CAC97AdapterCommon::DumpConfig
246 *****************************************************************************
247 * Dumps the HW configuration for the AC97 codec.
248 */
249void CAC97AdapterCommon::DumpConfig (void)
250{
251 PAGED_CODE ();
252
253 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::DumpConfig]"));
254
255 //
256 // Print debug output for MICIN.
257 //
258 if (GetPinConfig (PINC_MICIN_PRESENT))
259 {
260 DOUT (DBG_PROBE, ("MICIN found"));
261 }
262 else
263 {
264 DOUT (DBG_PROBE, ("No MICIN found"));
265 }
266
267 //
268 // Print debug output for tone controls.
269 //
270 if (GetNodeConfig (NODEC_TONE_PRESENT))
271 {
272 DOUT (DBG_PROBE, ("Tone controls found"));
273 }
274 else
275 {
276 DOUT (DBG_PROBE, ("No tone controls found"));
277 }
278
279 //
280 // Print debug output for mono out.
281 //
282 if (!GetPinConfig (PINC_MONOOUT_PRESENT))
283 {
284 DOUT (DBG_PROBE, ("No mono out found"));
285 }
286
287 //
288 // Print debug output for headphones.
289 //
290 if (!GetPinConfig (PINC_HPOUT_PRESENT))
291 {
292 DOUT (DBG_PROBE, ("No headphone out found"));
293 }
294
295 //
296 // Print debug output for loudness.
297 //
298 if (GetNodeConfig (NODEC_LOUDNESS_PRESENT))
299 {
300 DOUT (DBG_PROBE, ("Loudness found"));
301 }
302 else
303 {
304 DOUT (DBG_PROBE, ("No Loudness found"));
305 }
306
307 //
308 // Print debug output for 3D.
309 //
310 if (GetNodeConfig (NODEC_3D_PRESENT))
311 {
312 DOUT (DBG_PROBE, ("3D controls found"));
313 }
314 else
315 {
316 DOUT (DBG_PROBE, ("No 3D controls found"));
317 }
318
319 //
320 // Print debug output for pc beep.
321 //
322 if (GetPinConfig (PINC_PCBEEP_PRESENT))
323 {
324 DOUT (DBG_PROBE, ("PC beep found"));
325 }
326 else
327 {
328 DOUT (DBG_PROBE, ("No PC beep found"));
329 }
330
331 //
332 // Print debug output for phone line (or mono line input).
333 //
334 if (GetPinConfig (PINC_PHONE_PRESENT))
335 {
336 DOUT (DBG_PROBE, ("Phone found"));
337 }
338 else
339 {
340 DOUT (DBG_PROBE, ("No Phone found"));
341 }
342
343 //
344 // Print debug output for video.
345 //
346 if (GetPinConfig (PINC_VIDEO_PRESENT))
347 {
348 DOUT (DBG_PROBE, ("Video in found"));
349 }
350 else
351 {
352 DOUT (DBG_PROBE, ("No Video in found"));
353 }
354
355 //
356 // Print debug output for AUX.
357 //
358 if (GetPinConfig (PINC_AUX_PRESENT))
359 {
360 DOUT (DBG_PROBE, ("AUX in found"));
361 }
362 else
363 {
364 DOUT (DBG_PROBE, ("No AUX in found"));
365 }
366
367 //
368 // Print debug output for second miorophone.
369 //
370 if (GetPinConfig (PINC_MIC2_PRESENT))
371 {
372 DOUT (DBG_PROBE, ("MIC2 found"));
373 }
374 else
375 {
376 DOUT (DBG_PROBE, ("No MIC2 found"));
377 }
378
379 //
380 // Print debug output for 3D stuff.
381 //
382 if (GetNodeConfig (NODEC_3D_PRESENT))
383 {
384 if (GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE))
385 {
386 DOUT (DBG_PROBE, ("Adjustable 3D center control found"));
387 }
388 if (GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE))
389 {
390 DOUT (DBG_PROBE, ("Nonadjustable 3D depth control found"));
391 }
392 }
393
394 //
395 // Print debug output for quality of master volume.
396 //
397 if (GetNodeConfig (NODEC_6BIT_MASTER_VOLUME))
398 {
399 DOUT (DBG_PROBE, ("6bit master out found"));
400 }
401 else
402 {
403 DOUT (DBG_PROBE, ("5bit master out found"));
404 }
405
406 //
407 // Print debug output for quality of headphones volume.
408 //
409 if (GetPinConfig (PINC_HPOUT_PRESENT))
410 {
411 if (GetNodeConfig (NODEC_6BIT_HPOUT_VOLUME))
412 {
413 DOUT (DBG_PROBE, ("6bit headphone out found"));
414 }
415 else
416 {
417 DOUT (DBG_PROBE, ("5bit headphone out found"));
418 }
419 }
420
421 //
422 // Print debug output for quality of mono out volume.
423 //
424 if (GetPinConfig (PINC_MONOOUT_PRESENT))
425 {
426 if (GetNodeConfig (NODEC_6BIT_MONOOUT_VOLUME))
427 {
428 DOUT (DBG_PROBE, ("6bit mono out found"));
429 }
430 else
431 {
432 DOUT (DBG_PROBE, ("5bit mono out found"));
433 }
434 }
435
436 //
437 // Print sample rate information.
438 //
439 if (GetNodeConfig (NODEC_PCM_VARIABLERATE_SUPPORTED))
440 {
441 DOUT (DBG_PROBE, ("PCM variable sample rate supported"));
442 }
443 else
444 {
445 DOUT (DBG_PROBE, ("only 48KHz PCM supported"));
446 }
447
448 //
449 // Print double rate information.
450 //
451 if (GetNodeConfig (NODEC_PCM_DOUBLERATE_SUPPORTED))
452 {
453 DOUT (DBG_PROBE, ("PCM double sample rate supported"));
454 }
455
456 //
457 // Print mic rate information.
458 //
459 if (GetNodeConfig (NODEC_MIC_VARIABLERATE_SUPPORTED))
460 {
461 DOUT (DBG_PROBE, ("MIC variable sample rate supported"));
462 }
463 else
464 {
465 DOUT (DBG_PROBE, ("only 48KHz MIC supported"));
466 }
467
468 // print DAC information
469 if (GetNodeConfig (NODEC_CENTER_DAC_PRESENT))
470 {
471 DOUT (DBG_PROBE, ("center DAC found"));
472 }
473 if (GetNodeConfig (NODEC_SURROUND_DAC_PRESENT))
474 {
475 DOUT (DBG_PROBE, ("surround DAC found"));
476 }
477 if (GetNodeConfig (NODEC_LFE_DAC_PRESENT))
478 {
479 DOUT (DBG_PROBE, ("LFE DAC found"));
480 }
481}
482#endif
483
484/*****************************************************************************
485 * CAC97AdapterCommon::NonDelegatingQueryInterface
486 *****************************************************************************
487 * Obtains an interface. This function works just like a COM QueryInterface
488 * call and is used if the object is not being aggregated.
489 * We basically just check any GUID we know and return this object in case we
490 * know it.
491 */
492STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::NonDelegatingQueryInterface
493(
496)
497{
498 PAGED_CODE ();
499
500 ASSERT (Object);
501
502 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::NonDelegatingQueryInterface]"));
503
504 // Is it IID_IUnknown?
506 {
508 }
509 else
510 // or IID_IAC97AdapterCommon ...
511 if (IsEqualGUIDAligned (Interface, IID_IAC97AdapterCommon))
512 {
513 *Object = (PVOID)(PADAPTERCOMMON)this;
514 }
515 else
516 // or IID_IAdapterPowerManagement ...
517 if (IsEqualGUIDAligned (Interface, IID_IAdapterPowerManagement))
518 {
520 }
521 else
522 {
523 // nothing found, must be an unknown interface.
524 *Object = NULL;
526 }
527
528 //
529 // We reference the interface for the caller.
530 //
531 ((PUNKNOWN)*Object)->AddRef ();
532 return STATUS_SUCCESS;
533}
534
535/*****************************************************************************
536 * CAC97AdapterCommon::InitAC97
537 *****************************************************************************
538 * Initialize the AC97 (without hosing the modem if it got installed first).
539 */
541{
542 PAGED_CODE ();
543
544 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::InitAC97]"));
545
546 //
547 // First check if there is an AC link to the primary CoDec.
548 //
549 NTSTATUS ntStatus = PrimaryCodecReady ();
550 if (NT_SUCCESS (ntStatus))
551 {
552 //
553 // Second, reset this primary CoDec; If this is a AMC97 CoDec, only
554 // the audio registers are reset. If this is a MC97 CoDec, the CoDec
555 // should ignore the reset (according to the spec).
556 //
557 WriteCodecRegister (AC97REG_RESET, 0x00, 0xFFFF);
558
559 ntStatus = PowerUpCodec ();
560 }
561 else
562 {
563 DOUT (DBG_ERROR, ("Initialization of AC97 CoDec failed."));
564 }
565
566 return ntStatus;
567}
568
569/*****************************************************************************
570 * CAC97AdapterCommon::Check6thBitSupport
571 *****************************************************************************
572 * Probes for 6th bit volume control support.
573 * The passed parameters are the AC97 register that has the volume control and
574 * the node config that should be set in this case.
575 */
577(
578 IN AC97Register AC97Reg,
580)
581{
582 PAGED_CODE();
583
584 NTSTATUS ntStatus;
585 WORD wCodecReg;
586 WORD wOriginal;
587
588 // Read the current value.
589 ntStatus = ReadCodecRegister (AC97Reg, &wOriginal);
590 if (!NT_SUCCESS (ntStatus))
591 return ntStatus;
592
593 // Write the 6th bit; for mono controls we write 0x20, for stereo
594 // controls 0x2020.
595 ntStatus = WriteCodecRegister (AC97Reg,
596 (AC97Reg == AC97REG_MMONO_VOLUME) ? 0x0020 : 0x2020, 0xFFFF);
597 if (!NT_SUCCESS (ntStatus))
598 return ntStatus;
599
600 // And read back.
601 ntStatus = ReadCodecRegister (AC97Reg, &wCodecReg);
602 if (!NT_SUCCESS (ntStatus))
603 return ntStatus;
604
605 // Check return. For mono 0x20 and for stereo 0x2020.
606 if (((wCodecReg & 0x0020) && (AC97Reg == AC97REG_MMONO_VOLUME)) ||
607 (wCodecReg & 0x2020))
608 {
609 SetNodeConfig (Config, TRUE);
610 }
611 else
612 {
613 SetNodeConfig (Config, FALSE);
614 }
615
616 // Restore original value.
617 WriteCodecRegister (AC97Reg, wOriginal, 0xFFFF);
618
619 return ntStatus;
620}
621
622/*****************************************************************************
623 * CAC97AdapterCommon::ProbeHWConfig
624 *****************************************************************************
625 * Probes the hardware configuration.
626 * If this function returns with an error, then the configuration is not
627 * complete! Probing the registers is done by reading them (and comparing with
628 * the HW default value) or when the default is unknown, writing to them and
629 * reading back + restoring.
630 * Additionally, we read the registry so that a HW vendor can overwrite (means
631 * disable) found registers in case the adapter (e.g. video) is not visible to
632 * the user (he can't plug in a video audio there).
633 *
634 * This is a very long function with all of the error checking!
635 */
637{
638 PAGED_CODE ();
639
640 NTSTATUS ntStatus = STATUS_SUCCESS;
641 DWORD dwGlobalStatus;
642 WORD wCodecID;
643 WORD wCodecReg;
644
645 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ProbeHWConfig]"));
646
647 //
648 // Wait for the whatever 97 to complete reset and establish a link.
649 //
650 ntStatus = PrimaryCodecReady ();
651 if (!NT_SUCCESS (ntStatus))
652 return ntStatus;
653
654 //
655 // Master volume is one of the supported registers on an AC97
656 //
657 ntStatus = ReadCodecRegister (AC97REG_MASTER_VOLUME, &wCodecReg);
658 if (!NT_SUCCESS (ntStatus))
659 return ntStatus;
660
661 // Default is x8000.
662 if (wCodecReg != 0x8000)
664
665 //
666 // This gives us information about the AC97 CoDec
667 //
668 ntStatus = ReadCodecRegister (AC97REG_RESET, &wCodecID);
669 if (!NT_SUCCESS (ntStatus))
670 return ntStatus;
671
672 //
673 // Fill out the configuration stuff.
674 //
675
676 SetPinConfig (PINC_MICIN_PRESENT, wCodecID & 0x0001);
677
678 // Check if OEM wants to disable MIC record line.
680 SetPinConfig (PINC_MICIN_PRESENT, FALSE);
681
682 // If we still have MIC record line, enable the DAC in ext. audio register.
683 if (GetPinConfig (PINC_MICIN_PRESENT))
684 // Enable ADC MIC.
685 WriteCodecRegister (AC97REG_EXT_AUDIO_CTRL, 0, 0x4000);
686 else
687 // Disable ADC MIC.
688 WriteCodecRegister (AC97REG_EXT_AUDIO_CTRL, 0x4000, 0x4000);
689
690 //
691 // Continue setting configuration information.
692 //
693
694 SetNodeConfig (NODEC_TONE_PRESENT, wCodecID & 0x0004);
695 SetNodeConfig (NODEC_SIMUL_STEREO_PRESENT, wCodecID & 0x0008);
696 SetPinConfig (PINC_HPOUT_PRESENT, wCodecID & 0x0010);
697
698 // Check if OEM wants to disable headphone output.
700 SetPinConfig (PINC_HPOUT_PRESENT, FALSE);
701
702 SetNodeConfig (NODEC_LOUDNESS_PRESENT, wCodecID & 0x0020);
703 SetNodeConfig (NODEC_3D_PRESENT, wCodecID & 0x7C00);
704
705 //
706 // Test for the input pins that are always there but could be disabled
707 // by the HW vender
708 //
709
710 // Check if OEM wants to disable mic input.
712
713 // Check if OEM wants to disable line input.
715
716 // Check if OEM wants to disable CD input.
718
719
720 //
721 // For the rest, we have to probe the registers.
722 //
723
724 //
725 // Test for Mono out.
726 //
727 ntStatus = ReadCodecRegister (AC97REG_MMONO_VOLUME, &wCodecReg);
728 if (!NT_SUCCESS (ntStatus))
729 return ntStatus;
730
731 // Default is x8000.
732 SetPinConfig (PINC_MONOOUT_PRESENT, (wCodecReg == 0x8000));
733
734 // Check if OEM wants to disable mono output.
736 SetPinConfig (PINC_MONOOUT_PRESENT, FALSE);
737
738 //
739 // Test for PC beeper support.
740 //
741 ntStatus = ReadCodecRegister (AC97REG_BEEP_VOLUME, &wCodecReg);
742 if (!NT_SUCCESS (ntStatus))
743 return ntStatus;
744
745 // default is x0 or x8000. If it's 0x8000 then we know for sure that the
746 // CoDec has a PcBeep, otherwise we have to check the register
747 if (wCodecReg == 0x8000)
748 SetPinConfig (PINC_PCBEEP_PRESENT, TRUE);
749 else if (!wCodecReg)
750 {
751 // mute the pc beeper.
752 ntStatus = WriteCodecRegister (AC97REG_BEEP_VOLUME, 0x8000, 0xFFFF);
753 if (!NT_SUCCESS (ntStatus))
754 return ntStatus;
755
756 // read back
757 ntStatus = ReadCodecRegister (AC97REG_BEEP_VOLUME, &wCodecReg);
758 if (!NT_SUCCESS (ntStatus))
759 return ntStatus;
760
761 if (wCodecReg == 0x8000)
762 {
763 // yep, we have support.
764 SetPinConfig (PINC_PCBEEP_PRESENT, TRUE);
765 // reset to default value.
766 WriteCodecRegister (AC97REG_BEEP_VOLUME, 0x0, 0xFFFF);
767 }
768 else
769 // nope, not present
770 SetPinConfig (PINC_PCBEEP_PRESENT, FALSE);
771 }
772 else
773 // any other value then 0x0 and 0x8000.
774 SetPinConfig (PINC_PCBEEP_PRESENT, FALSE);
775
776 // Check if OEM wants to disable beeper support.
778 SetPinConfig (PINC_PCBEEP_PRESENT, FALSE);
779
780 //
781 // Test for phone support.
782 //
783 ntStatus = ReadCodecRegister (AC97REG_PHONE_VOLUME, &wCodecReg);
784 if (!NT_SUCCESS (ntStatus))
785 return ntStatus;
786
787 // Default is x8008.
788 SetPinConfig (PINC_PHONE_PRESENT, (wCodecReg == 0x8008));
789
790 // Check if OEM wants to disable phone input.
792 SetPinConfig (PINC_PHONE_PRESENT, FALSE);
793
794 //
795 // Test for video support.
796 //
797 ntStatus = ReadCodecRegister (AC97REG_VIDEO_VOLUME, &wCodecReg);
798 if (!NT_SUCCESS (ntStatus))
799 return ntStatus;
800
801 // Default is x8808.
802 SetPinConfig (PINC_VIDEO_PRESENT, (wCodecReg == 0x8808));
803
804 // Check if OEM wants to disable video input.
806 SetPinConfig (PINC_VIDEO_PRESENT, FALSE);
807
808 //
809 // Test for Aux support.
810 //
811 ntStatus = ReadCodecRegister (AC97REG_AUX_VOLUME, &wCodecReg);
812 if (!NT_SUCCESS (ntStatus))
813 return ntStatus;
814
815 // Default is 0x8808.
816 SetPinConfig (PINC_AUX_PRESENT, (wCodecReg == 0x8808));
817
818 // Check if OEM wants to disable aux input.
820 SetPinConfig (PINC_AUX_PRESENT, FALSE);
821
822 //
823 // Test for Mic2 source.
824 //
825 ntStatus = ReadCodecRegister (AC97REG_GENERAL, &wCodecReg);
826 if (!NT_SUCCESS (ntStatus))
827 return ntStatus;
828
829 // Test for Mic2 select bit.
830 if (wCodecReg & 0x0100)
831 SetPinConfig (PINC_MIC2_PRESENT, TRUE);
832 else
833 {
834 // Select Mic2 as source.
835 ntStatus = WriteCodecRegister (AC97REG_GENERAL, 0x0100, 0x0100);
836 if (!NT_SUCCESS (ntStatus))
837 return ntStatus;
838
839 // Read back.
840 ntStatus = ReadCodecRegister (AC97REG_GENERAL, &wCodecReg);
841 if (!NT_SUCCESS (ntStatus))
842 return ntStatus;
843
844 if (wCodecReg & 0x0100)
845 {
846 // Yep, we have support so set it to the default value.
847 SetPinConfig (PINC_MIC2_PRESENT, TRUE);
848 // reset to default value.
849 WriteCodecRegister (AC97REG_GENERAL, 0, 0x0100);
850 }
851 else
852 SetPinConfig (PINC_MIC2_PRESENT, FALSE);
853 }
854
855 // Check if OEM wants to disable mic2 input.
857 SetPinConfig (PINC_MIC2_PRESENT, FALSE);
858
859 //
860 // Test the 3D controls.
861 //
862 if (GetNodeConfig (NODEC_3D_PRESENT))
863 {
864 //
865 // First test for fixed 3D controls. Write default value ...
866 //
867 ntStatus = WriteCodecRegister (AC97REG_3D_CONTROL, 0, 0xFFFF);
868 if (!NT_SUCCESS (ntStatus))
869 return ntStatus;
870
871 // Read 3D register. Default is 0 when adjustable, otherwise it is
872 // a fixed value.
873 ntStatus = ReadCodecRegister (AC97REG_3D_CONTROL, &wCodecReg);
874 if (!NT_SUCCESS (ntStatus))
875 return ntStatus;
876
877 //
878 // Check center and depth separately.
879 //
880
881 // For center
882 SetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE, !(wCodecReg & 0x0F00));
883
884 // For depth
885 SetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE, !(wCodecReg & 0x000F));
886
887 //
888 // Test for adjustable controls.
889 //
890 WriteCodecRegister (AC97REG_3D_CONTROL, 0x0A0A, 0xFFFF);
891
892 // Read 3D register. Now it should be 0x0A0A for adjustable controls,
893 // otherwise it is a fixed control or simply not there.
894 ReadCodecRegister (AC97REG_3D_CONTROL, &wCodecReg);
895
896 // Restore the default value
897 WriteCodecRegister (AC97REG_3D_CONTROL, 0, 0xFFFF);
898
899 // Check the center control for beeing adjustable
900 if (GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE) &&
901 (wCodecReg & 0x0F00) != 0x0A00)
902 {
903 SetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE, FALSE);
904 }
905
906 // Check the depth control for beeing adjustable
907 if (GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE) &&
908 (wCodecReg & 0x000F) != 0x000A)
909 {
910 SetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE, FALSE);
911 }
912 }
913
914 //
915 // Check for 6th bit support in volume controls. To check the 6th bit,
916 // we first have to write a value (with 6th bit set) and then read it
917 // back. After that, we should restore the register to its default value.
918 //
919
920 //
921 // Start with the master volume.
922 //
924
925 //
926 // Check for a headphone volume control.
927 //
928 if (GetPinConfig (PINC_HPOUT_PRESENT))
929 {
931 }
932
933 //
934 // Mono out there?
935 //
936 if (GetPinConfig (PINC_MONOOUT_PRESENT))
937 {
939 }
940
941 //
942 // Get extended AC97 V2.0 information
943 //
944 ntStatus = ReadCodecRegister (AC97REG_EXT_AUDIO_ID, &wCodecReg);
945 if (!NT_SUCCESS (ntStatus))
946 return ntStatus;
947
948 //
949 // Store the information
950 //
951 SetNodeConfig (NODEC_PCM_VARIABLERATE_SUPPORTED, wCodecReg & 0x0001);
952 SetNodeConfig (NODEC_PCM_DOUBLERATE_SUPPORTED, wCodecReg & 0x0002);
953 SetNodeConfig (NODEC_MIC_VARIABLERATE_SUPPORTED, wCodecReg & 0x0008);
954 SetNodeConfig (NODEC_CENTER_DAC_PRESENT, wCodecReg & 0x0040);
955 SetNodeConfig (NODEC_SURROUND_DAC_PRESENT, wCodecReg & 0x0080);
956 SetNodeConfig (NODEC_LFE_DAC_PRESENT, wCodecReg & 0x0100);
957
958 //
959 // In case we have some features get some more information and program
960 // the codec.
961 //
962 if (wCodecReg)
963 {
964 //
965 // Enable variable sample rate in the control register and disable
966 // double rate. Also enable all DACs.
967 //
968 WriteCodecRegister (AC97REG_EXT_AUDIO_CTRL, wCodecReg & 0x0009, 0x380B);
969
970 //
971 // Check for codecs that have only one sample rate converter. These
972 // codecs will stick registers AC97REG_FRONT_SAMPLERATE and
973 // AC97REG_RECORD_SAMPLERATE together.
974 //
975 if (GetNodeConfig (NODEC_PCM_VARIABLERATE_SUPPORTED))
976 {
977 // The default of the sample rate registers should be 0xBB80.
978 WriteCodecRegister (AC97REG_FRONT_SAMPLERATE, 0xBB80, 0xFFFF);
979
980 // Write 44.1KHz into record VSR, then check playback again.
981 WriteCodecRegister (AC97REG_RECORD_SAMPLERATE, 0xAC44, 0xFFFF);
982 ntStatus = ReadCodecRegister (AC97REG_FRONT_SAMPLERATE, &wCodecReg);
983 WriteCodecRegister (AC97REG_RECORD_SAMPLERATE, 0xBB80, 0xFFFF);
984 if (!NT_SUCCESS (ntStatus))
985 return ntStatus;
986
987 //
988 // Set the flag accordingly
989 //
990 SetNodeConfig (NODEC_PCM_VSR_INDEPENDENT_RATES, (wCodecReg == 0xBB80));
991 }
992
993 //
994 // Check multichanel support on the AC97.
995 //
996 if (GetNodeConfig (NODEC_SURROUND_DAC_PRESENT))
997 {
998 dwGlobalStatus = ReadBMControlRegister32 (GLOB_STA);
999
1000 //
1001 // Codec supports >2 chanel, does AC97 too?
1002 //
1003 if ((GetNodeConfig (NODEC_CENTER_DAC_PRESENT) ||
1004 GetNodeConfig (NODEC_LFE_DAC_PRESENT)) &&
1005 (dwGlobalStatus & GLOB_STA_MC6))
1006 {
1007 SetPinConfig (PINC_CENTER_LFE_PRESENT, TRUE);
1008 }
1009 else
1010 {
1011 SetPinConfig (PINC_CENTER_LFE_PRESENT, FALSE);
1012 }
1013
1014 //
1015 // Do we support at least 4 channels?
1016 //
1017 SetPinConfig (PINC_SURROUND_PRESENT, (dwGlobalStatus & GLOB_STA_MC4));
1018 }
1019 else
1020 {
1021 //
1022 // Only 2 channel (stereo) support.
1023 //
1024 SetPinConfig (PINC_CENTER_LFE_PRESENT, FALSE);
1025 SetPinConfig (PINC_SURROUND_PRESENT, FALSE);
1026 }
1027 }
1028
1029 // Check if OEM wants to disable surround output.
1031 SetPinConfig (PINC_SURROUND_PRESENT, FALSE);
1032
1033 // Check if OEM wants to disable center and LFE output.
1035 SetPinConfig (PINC_CENTER_LFE_PRESENT, FALSE);
1036
1037 //
1038 // Check the 6th bit support for the additional channels.
1039 //
1040 if (GetPinConfig (PINC_SURROUND_PRESENT))
1042
1043 if (GetPinConfig (PINC_CENTER_LFE_PRESENT))
1045
1046 //
1047 // We read these registers because they are dependent on the codec.
1048 //
1049 ReadCodecRegister (AC97REG_VENDOR_ID1, &wCodecReg);
1050 ReadCodecRegister (AC97REG_VENDOR_ID2, &wCodecReg);
1051
1052 return STATUS_SUCCESS;
1053}
1054
1055
1056/*****************************************************************************
1057 * CAC97AdapterCommon::AcquireCodecSemiphore
1058 *****************************************************************************
1059 * Acquires the AC97 semiphore. This can not be called at dispatch level
1060 * because it can timeout if a lower IRQL thread has the semaphore.
1061 */
1063{
1064 PAGED_CODE ();
1065
1066 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::AcquireCodecSemiphore]"));
1067
1068 ULONG ulCount = 0;
1070 {
1071 //
1072 // Do we want to give up??
1073 //
1074 if (ulCount++ > 100)
1075 {
1076 DOUT (DBG_ERROR, ("Cannot acquire semaphore."));
1077 return STATUS_IO_TIMEOUT;
1078 }
1079
1080 //
1081 // Let's wait a little, 40us and then try again.
1082 //
1084 }
1085
1086 return STATUS_SUCCESS;
1087}
1088
1089
1090/*****************************************************************************
1091 * CAC97AdapterCommon::ReadCodecRegister
1092 *****************************************************************************
1093 * Reads a AC97 register. Don't call at PASSIVE_LEVEL.
1094 */
1095STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::ReadCodecRegister
1096(
1098 _Out_ PWORD wData
1099)
1100{
1101 PAGED_CODE ();
1102
1103 ASSERT (wData);
1104 ASSERT (reg < AC97REG_INVALID); // audio can only be in the primary codec
1106
1107 NTSTATUS ntStatus;
1108 ULONG Status;
1109
1110 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ReadCodecRegister]"));
1111
1112 //
1113 // Check if we have to access the HW directly.
1114 //
1117 {
1118 //
1119 // Grab the codec access semiphore.
1120 //
1121 ntStatus = AcquireCodecSemiphore ();
1122 if (!NT_SUCCESS (ntStatus))
1123 {
1124 DOUT (DBG_ERROR, ("ReadCodecRegister couldn't acquire the semiphore"
1125 " for reg. %s", reg <= AC97REG_RESERVED2 ? RegStrings[reg] :
1126 reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" :
1127 reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" :
1128 "REG_INVALID"));
1129 return ntStatus;
1130 }
1131
1132 //
1133 // Read the data.
1134 //
1136
1137 //
1138 // Check to see if the read was successful.
1139 //
1141 if (Status & GLOB_STA_RCS)
1142 {
1143 //
1144 // clear the timeout bit
1145 //
1147 *wData = 0;
1148 DOUT (DBG_ERROR, ("ReadCodecRegister timed out for register %s",
1149 reg <= AC97REG_RESERVED2 ? RegStrings[reg] :
1150 reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" :
1151 reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" :
1152 "REG_INVALID"));
1153 return STATUS_IO_TIMEOUT;
1154 }
1155
1156 //
1157 // Clear invalid flag
1158 //
1160 m_stAC97Registers[reg].wFlags &= ~SHREG_INVALID;
1161
1162 DOUT (DBG_REGS, ("AC97READ: %s = 0x%04x (HW)",
1163 reg <= AC97REG_RESERVED2 ? RegStrings[reg] :
1164 reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" :
1165 reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" :
1166 "REG_INVALID", *wData));
1167 }
1168 else
1169 {
1170 //
1171 // Otherwise, use the value in the cache.
1172 //
1174 DOUT (DBG_REGS, ("AC97READ: %s = 0x%04x (C)",
1175 reg <= AC97REG_RESERVED2 ? RegStrings[reg] :
1176 reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" :
1177 reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" :
1178 "REG_INVALID", *wData));
1179 }
1180
1181 return STATUS_SUCCESS;
1182}
1183
1184
1185/*****************************************************************************
1186 * CAC97AdapterCommon::WriteCodecRegister
1187 *****************************************************************************
1188 * Writes to a AC97 register. This can only be done at passive level because
1189 * the AcquireCodecSemiphore call could fail!
1190 */
1191STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::WriteCodecRegister
1192(
1194 _In_ WORD wData,
1195 _In_ WORD wMask
1196)
1197{
1198 PAGED_CODE ();
1199
1200 ASSERT (reg < AC97REG_INVALID); // audio can only be in the primary codec
1201
1202 WORD TempData = 0;
1203 NTSTATUS ntStatus = STATUS_SUCCESS;
1204
1205 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::WriteCodecRegister]"));
1206
1207 //
1208 // No mask? Could happen when you try to prg. left channel of a
1209 // mono volume.
1210 //
1211 if (!wMask)
1212 return STATUS_SUCCESS;
1213
1214 //
1215 // Check to see if we are only writing specific bits. If so, we want
1216 // to leave some bits in the register alone.
1217 //
1218 if (wMask != 0xffff)
1219 {
1220 //
1221 // Read the current register contents.
1222 //
1223 ntStatus = ReadCodecRegister (reg, &TempData);
1224 if (!NT_SUCCESS (ntStatus))
1225 {
1226 DOUT (DBG_ERROR, ("WriteCodecRegiser read for mask failed"));
1227 return ntStatus;
1228 }
1229
1230 //
1231 // Do the masking.
1232 //
1233 TempData &= ~wMask;
1234 TempData |= (wMask & wData);
1235 }
1236 else
1237 {
1238 TempData = wData;
1239 }
1240
1241
1242 //
1243 // Grab the codec access semiphore.
1244 //
1245 ntStatus = AcquireCodecSemiphore ();
1246 if (!NT_SUCCESS (ntStatus))
1247 {
1248 DOUT (DBG_ERROR, ("WriteCodecRegister failed for register %s",
1249 reg <= AC97REG_RESERVED2 ? RegStrings[reg] :
1250 reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" :
1251 reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" : "REG_INVALID"));
1252 return ntStatus;
1253 }
1254
1255 //
1256 // Write the data.
1257 //
1258 WRITE_PORT_USHORT (m_pCodecBase + reg, TempData);
1259
1260 //
1261 // Update cache.
1262 //
1264 m_stAC97Registers[reg].wCache = TempData;
1265
1266 DOUT (DBG_REGS, ("AC97WRITE: %s -> 0x%04x",
1267 reg <= AC97REG_RESERVED2 ? RegStrings[reg] :
1268 reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" :
1269 reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" :
1270 "REG_INVALID", TempData));
1271
1272
1273 return STATUS_SUCCESS;
1274}
1275
1276
1277/*****************************************************************************
1278 * CAC97AdapterCommon::PrimaryCodecReady
1279 *****************************************************************************
1280 * Checks whether the primary codec is present and ready. This may take
1281 * awhile if we are bringing it up from a cold reset so give it a second
1282 * before giving up.
1283 */
1285{
1286 PAGED_CODE ();
1287
1288 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::PrimaryCodecReady]"));
1289
1290
1291 //
1292 // Enable the AC link and raise the reset line.
1293 //
1294 DWORD dwRegValue = ReadBMControlRegister32 (GLOB_CNT);
1295
1296 // If someone enabled GPI Interrupt Enable, then he hopefully handles that
1297 // too.
1298 dwRegValue = (dwRegValue | GLOB_CNT_COLD) & ~(GLOB_CNT_ACLOFF | GLOB_CNT_PRIE);
1299 WriteBMControlRegister (GLOB_CNT, dwRegValue);
1300
1301 //
1302 // Wait for the Codec to be ready.
1303 //
1304 ULONG WaitCycles = 200;
1305 LARGE_INTEGER WaitTime;
1306
1307 WaitTime.QuadPart = (-50000); // wait 5000us (5ms) relative
1308
1309 do
1310 {
1313 {
1314 return STATUS_SUCCESS;
1315 }
1316
1318 } while (WaitCycles--);
1319
1320 DOUT (DBG_ERROR, ("PrimaryCodecReady timed out!"));
1321 return STATUS_IO_TIMEOUT;
1322}
1323
1324
1325/*****************************************************************************
1326 * CAC97AdapterCommon::PowerUpCodec
1327 *****************************************************************************
1328 * Sets the Codec to the highest power state and waits until the Codec reports
1329 * that the power state is reached.
1330 */
1332{
1333 PAGED_CODE ();
1334
1335 WORD wCodecReg;
1336 NTSTATUS ntStatus;
1337
1338 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::PowerUpCodec]"));
1339
1340 //
1341 // Power up the Codec.
1342 //
1343 WriteCodecRegister (AC97REG_POWERDOWN, 0x00, 0xFFFF);
1344
1345 //
1346 // Wait for the Codec to be powered up.
1347 //
1348 ULONG WaitCycles = 200;
1349 LARGE_INTEGER WaitTime;
1350
1351 WaitTime.QuadPart = (-50000); // wait 5000us (5ms) relative
1352
1353 do
1354 {
1355 //
1356 // Read the power management register.
1357 //
1358 ntStatus = ReadCodecRegister (AC97REG_POWERDOWN, &wCodecReg);
1359 if (!NT_SUCCESS (ntStatus))
1360 {
1361 wCodecReg = 0; // Will cause an error.
1362 break;
1363 }
1364
1365 //
1366 // Check the power state. Should be ready.
1367 //
1368 if ((wCodecReg & 0x0f) == 0x0f)
1369 break;
1370
1371 //
1372 // Let's wait a little, 5ms and then try again.
1373 //
1375 } while (WaitCycles--);
1376
1377 // Check if we timed out.
1378 if ((wCodecReg & 0x0f) != 0x0f)
1379 {
1380 DOUT (DBG_ERROR, ("PowerUpCodec timed out. CoDec not powered up."));
1381 ntStatus = STATUS_DEVICE_NOT_READY;
1382 }
1383
1384 return ntStatus;
1385}
1386
1387
1388/*****************************************************************************
1389 * CAC97AdapterCommon::ProgramSampleRate
1390 *****************************************************************************
1391 * Programs the sample rate. If the rate cannot be programmed, the routine
1392 * restores the register and returns STATUS_UNSUCCESSFUL.
1393 * We don't handle double rate sample rates here, because the Intel AC97 con-
1394 * troller cannot serve CoDecs with double rate or surround sound. If you want
1395 * to modify this driver for another AC97 controller, then you might want to
1396 * change this function too.
1397 */
1398STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::ProgramSampleRate
1399(
1401 IN DWORD dwSampleRate
1402)
1403{
1404 PAGED_CODE ();
1405
1406 WORD wOldRateReg, wCodecReg;
1407 NTSTATUS ntStatus;
1408
1409 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ProgramSampleRate]"));
1410
1411 //
1412 // Check if we support variable sample rate.
1413 //
1414 switch(Register)
1415 {
1417 //
1418 // Variable sample rate supported?
1419 //
1420 if (GetNodeConfig (NODEC_MIC_VARIABLERATE_SUPPORTED))
1421 {
1422 // Range supported?
1423 if (dwSampleRate > 48000ul)
1424 {
1425 // Not possible.
1426 DOUT (DBG_VSR, ("Samplerate %d not supported", dwSampleRate));
1427 return STATUS_NOT_SUPPORTED;
1428 }
1429 }
1430 else
1431 {
1432 // Only 48000KHz possible.
1433 if (dwSampleRate != 48000ul)
1434 {
1435 DOUT (DBG_VSR, ("Samplerate %d not supported", dwSampleRate));
1436 return STATUS_NOT_SUPPORTED;
1437 }
1438
1439 return STATUS_SUCCESS;
1440 }
1441 break;
1442
1447 //
1448 // Variable sample rate supported?
1449 //
1450 if (GetNodeConfig (NODEC_PCM_VARIABLERATE_SUPPORTED))
1451 {
1452 //
1453 // Check range supported
1454 //
1455 if (dwSampleRate > 48000ul)
1456 {
1457 DOUT (DBG_VSR, ("Samplerate %d not supported", dwSampleRate));
1458 return STATUS_NOT_SUPPORTED;
1459 }
1460 }
1461 else
1462 {
1463 // Only 48KHz possible.
1464 if (dwSampleRate != 48000ul)
1465 {
1466 DOUT (DBG_VSR, ("Samplerate %d not supported", dwSampleRate));
1467 return STATUS_NOT_SUPPORTED;
1468 }
1469
1470 return STATUS_SUCCESS;
1471 }
1472 break;
1473
1474 default:
1475 DOUT (DBG_ERROR, ("Invalid sample rate register!"));
1476 return STATUS_UNSUCCESSFUL;
1477 }
1478
1479
1480 //
1481 // Save the old sample rate register.
1482 //
1483 ntStatus = ReadCodecRegister (Register, &wOldRateReg);
1484 if (!NT_SUCCESS (ntStatus))
1485 return ntStatus;
1486
1487 //
1488 // program the rate.
1489 //
1490 ntStatus = WriteCodecRegister (Register, (WORD)dwSampleRate, 0xFFFF);
1491 if (!NT_SUCCESS (ntStatus))
1492 {
1493 DOUT (DBG_ERROR, ("Cannot program sample rate."));
1494 return ntStatus;
1495 }
1496
1497 //
1498 // Read it back.
1499 //
1500 ntStatus = ReadCodecRegister (Register, &wCodecReg);
1501 if (!NT_SUCCESS (ntStatus))
1502 {
1503 DOUT (DBG_ERROR, ("Cannot read sample rate."));
1504 return ntStatus;
1505 }
1506
1507 //
1508 // Validate.
1509 //
1510 if (wCodecReg != dwSampleRate)
1511 {
1512 //
1513 // restore sample rate and ctrl register.
1514 //
1515 WriteCodecRegister (Register, wOldRateReg, 0xFFFF);
1516
1517 DOUT (DBG_VSR, ("Samplerate %d not supported", dwSampleRate));
1518 return STATUS_NOT_SUPPORTED;
1519 }
1520
1521 DOUT (DBG_VSR, ("Samplerate changed to %d.", dwSampleRate));
1522 return STATUS_SUCCESS;
1523}
1524
1525
1526/*****************************************************************************
1527 * CAC97AdapterCommon::PowerChangeState
1528 *****************************************************************************
1529 * Change power state for the device. We handle the codec, PowerChangeNotify
1530 * in the wave miniport handles the DMA registers.
1531 */
1532STDMETHODIMP_(void) CAC97AdapterCommon::PowerChangeState
1533(
1534 _In_ POWER_STATE NewState
1535)
1536{
1537 PAGED_CODE ();
1538
1539 NTSTATUS ntStatus = STATUS_SUCCESS;
1540
1541 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::PowerChangeNotify]"));
1542
1543 //
1544 // Check to see if this is the current power state.
1545 //
1546 if (NewState.DeviceState == m_PowerState)
1547 {
1548 DOUT (DBG_POWER, ("New device state equals old state."));
1549 return;
1550 }
1551
1552 //
1553 // Check the new device state.
1554 //
1555 if ((NewState.DeviceState < PowerDeviceD0) ||
1556 (NewState.DeviceState > PowerDeviceD3))
1557 {
1558 DOUT (DBG_ERROR, ("Unknown device state: D%d.",
1559 (ULONG)NewState.DeviceState - (ULONG)PowerDeviceD0));
1560 return;
1561 }
1562
1563 DOUT (DBG_POWER, ("Changing state to D%d.", (ULONG)NewState.DeviceState -
1565
1566 //
1567 // Switch on new state.
1568 //
1569 switch (NewState.DeviceState)
1570 {
1571 case PowerDeviceD0:
1572 //
1573 // If we are coming from D2 or D3 we have to restore the registers cause
1574 // there might have been a power loss.
1575 //
1577 {
1578 //
1579 // Reset AD3 to indicate that we are now awake.
1580 // Because the system has only one power irp at a time, we are sure
1581 // that the modem driver doesn't get called while we are restoring
1582 // power.
1583 //
1584 WriteBMControlRegister (GLOB_STA,
1585 ReadBMControlRegister32 (GLOB_STA) & ~GLOB_STA_AD3);
1586
1587 //
1588 // Restore codec registers.
1589 //
1590 ntStatus = RestoreCodecRegisters ();
1591 }
1592 else // We are coming from power state D1
1593 {
1594 ntStatus = PowerUpCodec ();
1595 }
1596
1597 // Print error code.
1598 if (!NT_SUCCESS (ntStatus))
1599 {
1600 DOUT (DBG_ERROR, ("PowerChangeState failed to restore the codec."));
1601 }
1602 break;
1603
1604 case PowerDeviceD1:
1605 //
1606 // This sleep state is the lowest latency sleep state with respect
1607 // to the latency time required to return to D0. If the
1608 // driver is not being used an inactivity timer in portcls will
1609 // place the driver in this state after a timeout period
1610 // controllable via the registry.
1611 //
1612
1613 // Let's power down the DAC/ADC's and analog mixer.
1614 WriteCodecRegister (AC97REG_POWERDOWN, 0x0700, 0xFFFF);
1615 break;
1616
1617 case PowerDeviceD2:
1618 case PowerDeviceD3:
1619 //
1620 // This is a full hibernation state and is the longest latency sleep
1621 // state. In this modes the power could be removed or reduced that
1622 // much that the AC97 controller looses information, so we save
1623 // whatever we have to save.
1624 //
1625
1626 //
1627 // Powerdown ADC, DAC, Mixer, Vref, HP amp, and Exernal Amp but not
1628 // AC-link and Clk
1629 //
1630 WriteCodecRegister (AC97REG_POWERDOWN, 0xCF00, 0xFFFF);
1631
1632 //
1633 // Only in D3 mode we set the AD3 bit and evtl. shut off the AC link.
1634 //
1635 if (NewState.DeviceState == PowerDeviceD3)
1636 {
1637 //
1638 // Set the AD3 bit.
1639 //
1640 ULONG ulReg = ReadBMControlRegister32 (GLOB_STA);
1641 WriteBMControlRegister (GLOB_STA, ulReg | GLOB_STA_AD3);
1642
1643 //
1644 // We check if the modem is sleeping. If it is, we can shut off the
1645 // AC link also. We shut off the AC link also if the modem is not
1646 // there.
1647 //
1648 if ((ulReg & GLOB_STA_MD3) || !(ulReg & GLOB_STA_SCR))
1649 {
1650 // Set Codec to super sleep
1651 WriteCodecRegister (AC97REG_POWERDOWN, 0xFF00, 0xFFFF);
1652
1653 // Disable the AC-link signals
1654 ulReg = ReadBMControlRegister32 (GLOB_CNT);
1655 WriteBMControlRegister (GLOB_CNT, (ulReg | GLOB_CNT_ACLOFF) & ~GLOB_CNT_COLD);
1656 }
1657 }
1658 break;
1659 }
1660
1661 //
1662 // Save the new state. This local value is used to determine when to
1663 // cache property accesses and when to permit the driver from accessing
1664 // the hardware.
1665 //
1666 m_PowerState = NewState.DeviceState;
1667 DOUT (DBG_POWER, ("Entering D%d", (ULONG)m_PowerState -
1669}
1670
1671
1672/*****************************************************************************
1673 * CAC97AdapterCommon::QueryPowerChangeState
1674 *****************************************************************************
1675 * Query to see if the device can change to this power state
1676 */
1677STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::QueryPowerChangeState
1678(
1679 _In_ POWER_STATE NewState
1680)
1681{
1682 PAGED_CODE ();
1683
1684 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::QueryPowerChangeState]"));
1685
1686 // Check here to see of a legitimate state is being requested
1687 // based on the device state and fail the call if the device/driver
1688 // cannot support the change requested. Otherwise, return STATUS_SUCCESS.
1689 // Note: A QueryPowerChangeState() call is not guaranteed to always preceed
1690 // a PowerChangeState() call.
1691
1692 // check the new state being requested
1693 switch (NewState.DeviceState)
1694 {
1695 case PowerDeviceD0:
1696 case PowerDeviceD1:
1697 case PowerDeviceD2:
1698 case PowerDeviceD3:
1699 return STATUS_SUCCESS;
1700
1701 default:
1702 DOUT (DBG_ERROR, ("Unknown device state: D%d.",
1703 (ULONG)NewState.DeviceState - (ULONG)PowerDeviceD0));
1705 }
1706}
1707
1708
1709/*****************************************************************************
1710 * CAC97AdapterCommon::QueryDeviceCapabilities
1711 *****************************************************************************
1712 * Called at startup to get the caps for the device. This structure provides
1713 * the system with the mappings between system power state and device power
1714 * state. This typically will not need modification by the driver.
1715 * If the driver modifies these mappings then the driver is not allowed to
1716 * change the mapping to a weaker power state (e.g. from S1->D3 to S1->D1).
1717 *
1718 */
1720STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::QueryDeviceCapabilities
1721(
1722 PDEVICE_CAPABILITIES PowerDeviceCaps
1723)
1724{
1725 PAGED_CODE ();
1726
1727 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::QueryDeviceCapabilities]"));
1728
1729 UNREFERENCED_PARAMETER(PowerDeviceCaps);
1730
1731 return STATUS_SUCCESS;
1732}
1733
1734
1735/*****************************************************************************
1736 * CAC97AdapterCommon::RestoreAC97Registers
1737 *****************************************************************************
1738 * Preset the AC97 registers with default values. The routine first checks if
1739 * There are registry entries for the default values. If not, we have hard
1740 * coded values too ;)
1741 */
1743{
1744 PAGED_CODE ();
1745
1746 PREGISTRYKEY DriverKey;
1747 PREGISTRYKEY SettingsKey;
1748 UNICODE_STRING sKeyName;
1749 ULONG ulDisposition;
1750 ULONG ulResultLength;
1751 PVOID KeyInfo = NULL;
1752
1753 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::SetAC97Default]"));
1754
1755 // open the driver registry key
1756 NTSTATUS ntStatus = PcNewRegistryKey (&DriverKey, // IRegistryKey
1757 NULL, // OuterUnknown
1758 DriverRegistryKey, // Registry key type
1759 KEY_READ, // Access flags
1760 m_pDeviceObject, // Device object
1761 NULL, // Subdevice
1762 NULL, // ObjectAttributes
1763 0, // Create options
1764 NULL); // Disposition
1765 if (NT_SUCCESS (ntStatus))
1766 {
1767 // make a unicode string for the subkey name
1768 RtlInitUnicodeString (&sKeyName, L"Settings");
1769
1770 // open the settings subkey
1771 ntStatus = DriverKey->NewSubKey (&SettingsKey, // Subkey
1772 NULL, // OuterUnknown
1773 KEY_READ, // Access flags
1774 &sKeyName, // Subkey name
1775 REG_OPTION_NON_VOLATILE, // Create options
1776 &ulDisposition);
1777
1778 if (NT_SUCCESS (ntStatus))
1779 {
1780 // allocate data to hold key info
1783 sizeof(WORD), PoolTag);
1784 if (NULL != KeyInfo)
1785 {
1786 // loop through all mixer settings
1788 i = (AC97Register)(i + 1))
1789 {
1791 {
1792 // init key name
1793 RtlInitUnicodeString (&sKeyName,
1794 m_stAC97Registers[i].sRegistryName);
1795
1796 // query the value key
1797 ntStatus = SettingsKey->QueryValueKey (&sKeyName,
1799 KeyInfo,
1801 sizeof(WORD),
1802 &ulResultLength);
1803 if (NT_SUCCESS (ntStatus))
1804 {
1805 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo =
1807
1808 if (PartialInfo->DataLength == sizeof(WORD))
1809 {
1810 // set mixer register to registry value
1811 WriteCodecRegister
1812 (i, *(PWORD)PartialInfo->Data, 0xFFFF);
1813 }
1814 else // write the hard coded default
1815 {
1816 // if key access failed, set to default
1817 WriteCodecRegister
1818 (i, m_stAC97Registers[i].wWantedDefault, 0xFFFF);
1819 }
1820 }
1821 else // write the hard coded default
1822 {
1823 // if key access failed, set to default
1824 WriteCodecRegister
1825 (i, m_stAC97Registers[i].wWantedDefault, 0xFFFF);
1826 }
1827 }
1828 }
1829
1830 // we want to return status success even if the last QueryValueKey
1831 // failed.
1832 ntStatus = STATUS_SUCCESS;
1833
1834 // free the key info
1835 ExFreePoolWithTag (KeyInfo,PoolTag);
1836 }
1837 else
1838 {
1840 }
1841
1842 // release the settings key
1843 SettingsKey->Release ();
1844 }
1845
1846 // release the driver key
1847 DriverKey->Release ();
1848 }
1849
1850
1851 // in case we did not query the registry (cause of lack of resources)
1852 // restore default values and return insufficient resources.
1853 if (!NT_SUCCESS (ntStatus))
1854 {
1855 // copy hard coded default settings
1857 i = (AC97Register)(i + 1))
1858 {
1860 {
1861 WriteCodecRegister (i, m_stAC97Registers[i].wWantedDefault, 0xFFFF);
1862 }
1863 }
1864 }
1865
1866 return ntStatus;
1867}
1868
1869
1870/*****************************************************************************
1871 * CAC97AdapterCommon::DisableAC97Pin
1872 *****************************************************************************
1873 * Returns TRUE when the HW vendor wants to disable the pin. A disabled pin is
1874 * not shown to the user (means it is not included in the topology). The
1875 * reason for doing this could be that some of the input lines like Aux or
1876 * Video are not available to the user (to plug in something) but the codec
1877 * can handle those lines.
1878 */
1880(
1882)
1883{
1884 PAGED_CODE ();
1885
1886 PREGISTRYKEY DriverKey;
1887 PREGISTRYKEY SettingsKey;
1888 UNICODE_STRING sKeyName;
1889 ULONG ulDisposition;
1890 ULONG ulResultLength;
1891 PVOID KeyInfo = NULL;
1892 BOOL bDisable = FALSE;
1893
1894 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::DisableAC97Pin]"));
1895
1896 // open the driver registry key
1897 NTSTATUS ntStatus = PcNewRegistryKey (&DriverKey, // IRegistryKey
1898 NULL, // OuterUnknown
1899 DriverRegistryKey, // Registry key type
1900 KEY_READ, // Access flags
1901 m_pDeviceObject, // Device object
1902 NULL, // Subdevice
1903 NULL, // ObjectAttributes
1904 0, // Create options
1905 NULL); // Disposition
1906 if (NT_SUCCESS (ntStatus))
1907 {
1908 // make a unicode string for the subkey name
1909 RtlInitUnicodeString (&sKeyName, L"Settings");
1910
1911 // open the settings subkey
1912 ntStatus = DriverKey->NewSubKey (&SettingsKey, // Subkey
1913 NULL, // OuterUnknown
1914 KEY_READ, // Access flags
1915 &sKeyName, // Subkey name
1916 REG_OPTION_NON_VOLATILE, // Create options
1917 &ulDisposition);
1918
1919 if (NT_SUCCESS (ntStatus))
1920 {
1921 // allocate data to hold key info
1924 sizeof(BYTE), PoolTag);
1925 if (NULL != KeyInfo)
1926 {
1927 // init key name
1929 Pins[pin].sRegistryName);
1930
1931 // query the value key
1932 ntStatus = SettingsKey->QueryValueKey (&sKeyName,
1934 KeyInfo,
1936 sizeof(BYTE),
1937 &ulResultLength );
1938 if (NT_SUCCESS (ntStatus))
1939 {
1940 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo =
1942
1943 if (PartialInfo->DataLength == sizeof(BYTE))
1944 {
1945 // store the value
1946 if (*(PBYTE)PartialInfo->Data)
1947 bDisable = TRUE;
1948 else
1949 bDisable = FALSE;
1950 }
1951 }
1952
1953 // free the key info
1954 ExFreePoolWithTag (KeyInfo,PoolTag);
1955 }
1956
1957 // release the settings key
1958 SettingsKey->Release ();
1959 }
1960
1961 // release the driver key
1962 DriverKey->Release ();
1963 }
1964
1965 // if one of the stuff above fails we return the default, which is FALSE.
1966 return bDisable;
1967}
1968
1969
1970/*****************************************************************************
1971 * CAC97AdapterCommon::RestoreCodecRegisters
1972 *****************************************************************************
1973 * write back cached mixer values to codec registers
1974 */
1975NTSTATUS CAC97AdapterCommon::RestoreCodecRegisters (void)
1976{
1977 PAGED_CODE ();
1978
1979 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::RestoreCodecRegisters]"));
1980
1981 //
1982 // Initialize the AC97 codec.
1983 //
1984 NTSTATUS ntStatus = InitAC97 ();
1985 if (!NT_SUCCESS (ntStatus))
1986 return ntStatus;
1987
1988 //
1989 // Restore all codec registers. Failure is not critical.
1990 //
1992 i = (AC97Register)(i + 1))
1993 {
1994 WriteCodecRegister (i, m_stAC97Registers[i].wCache, 0xFFFF);
1995 }
1996
1997 return STATUS_SUCCESS;
1998}
1999
2000/*****************************************************************************
2001 * CAC97AdapterCommon::ReadChannelConfigDefault
2002 *****************************************************************************
2003 * This function reads the default channel config from the registry. The
2004 * registry entry "ChannelConfig" is set every every time we get a
2005 * KSPROPERTY_AUDIO_CHANNEL_CONFIG for the DAC node.
2006 * In case the key doesn't exist we assume a channel config of stereo speakers,
2007 * cause that is the default of DSOUND.
2008 */
2009STDMETHODIMP_(void) CAC97AdapterCommon::ReadChannelConfigDefault
2010(
2011 PDWORD pdwChannelConfig,
2012 PWORD pwChannels
2013)
2014{
2015 PAGED_CODE ();
2016
2017 PREGISTRYKEY DriverKey;
2018 PREGISTRYKEY SettingsKey;
2019 UNICODE_STRING sKeyName;
2020 ULONG ulDisposition;
2021 ULONG ulResultLength;
2022 PVOID KeyInfo = NULL;
2023
2024 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ReadChannelConfigDefault]"));
2025
2026 // This is the default: 2 speakers, stereo.
2027 *pdwChannelConfig = KSAUDIO_SPEAKER_STEREO;
2028 *pwChannels = 2;
2029
2030 // open the driver registry key
2031 NTSTATUS ntStatus = PcNewRegistryKey (&DriverKey, // IRegistryKey
2032 NULL, // OuterUnknown
2033 DriverRegistryKey, // Registry key type
2034 KEY_READ, // Access flags
2035 m_pDeviceObject, // Device object
2036 NULL, // Subdevice
2037 NULL, // ObjectAttributes
2038 0, // Create options
2039 NULL); // Disposition
2040 if (NT_SUCCESS (ntStatus))
2041 {
2042 // make a unicode string for the subkey name
2043 RtlInitUnicodeString (&sKeyName, L"Settings");
2044
2045 // open the settings subkey
2046 ntStatus = DriverKey->NewSubKey (&SettingsKey, // Subkey
2047 NULL, // OuterUnknown
2048 KEY_READ, // Access flags
2049 &sKeyName, // Subkey name
2050 REG_OPTION_NON_VOLATILE, // Create options
2051 &ulDisposition);
2052
2053 if (NT_SUCCESS (ntStatus))
2054 {
2055 // allocate data to hold key info
2058 sizeof(DWORD), PoolTag);
2059 if (NULL != KeyInfo)
2060 {
2061 // init key name
2062 RtlInitUnicodeString (&sKeyName, L"ChannelConfig");
2063
2064 // query the value key
2065 ntStatus = SettingsKey->QueryValueKey (&sKeyName,
2067 KeyInfo,
2069 sizeof(DWORD),
2070 &ulResultLength );
2071 if (NT_SUCCESS (ntStatus))
2072 {
2073 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo =
2075
2076 if (PartialInfo->DataLength == sizeof(DWORD))
2077 {
2078 switch (*(PLONG)PartialInfo->Data)
2079 {
2082 if (GetPinConfig (PINC_SURROUND_PRESENT))
2083 {
2084 *pdwChannelConfig = *(PDWORD)PartialInfo->Data;
2085 *pwChannels = 4;
2086 }
2087 break;
2088
2090 if (GetPinConfig (PINC_SURROUND_PRESENT) &&
2091 GetPinConfig (PINC_CENTER_LFE_PRESENT))
2092 {
2093 *pdwChannelConfig = *(PDWORD)PartialInfo->Data;
2094 *pwChannels = 6;
2095 }
2096 break;
2097 }
2098 }
2099 }
2100
2101 // free the key info
2102 ExFreePoolWithTag (KeyInfo,PoolTag);
2103 }
2104
2105 // release the settings key
2106 SettingsKey->Release ();
2107 }
2108
2109 // release the driver key
2110 DriverKey->Release ();
2111 }
2112}
2113
2114/*****************************************************************************
2115 * CAC97AdapterCommon::WriteChannelConfigDefault
2116 *****************************************************************************
2117 * This function writes the default channel config to the registry. The
2118 * registry entry "ChannelConfig" is set every every time we get a
2119 * KSPROPERTY_AUDIO_CHANNEL_CONFIG for the DAC node.
2120 */
2121STDMETHODIMP_(void) CAC97AdapterCommon::WriteChannelConfigDefault (DWORD dwChannelConfig)
2122{
2123 PAGED_CODE ();
2124
2125 PREGISTRYKEY DriverKey;
2126 PREGISTRYKEY SettingsKey;
2127 UNICODE_STRING sKeyName;
2128 ULONG ulDisposition;
2129
2130 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::WriteChannelConfigDefault]"));
2131
2132 // open the driver registry key
2133 NTSTATUS ntStatus = PcNewRegistryKey (&DriverKey, // IRegistryKey
2134 NULL, // OuterUnknown
2135 DriverRegistryKey, // Registry key type
2136 KEY_WRITE, // Access flags
2137 m_pDeviceObject, // Device object
2138 NULL, // Subdevice
2139 NULL, // ObjectAttributes
2140 0, // Create options
2141 NULL); // Disposition
2142 if (NT_SUCCESS (ntStatus))
2143 {
2144 // make a unicode string for the subkey name
2145 RtlInitUnicodeString (&sKeyName, L"Settings");
2146
2147 // open the settings subkey
2148 ntStatus = DriverKey->NewSubKey (&SettingsKey, // Subkey
2149 NULL, // OuterUnknown
2150 KEY_WRITE, // Access flags
2151 &sKeyName, // Subkey name
2152 REG_OPTION_NON_VOLATILE, // Create options
2153 &ulDisposition);
2154
2155 if (NT_SUCCESS (ntStatus))
2156 {
2157 // init key name
2158 RtlInitUnicodeString (&sKeyName, L"ChannelConfig");
2159
2160 // query the value key
2161 ntStatus = SettingsKey->SetValueKey (&sKeyName,
2162 REG_DWORD,
2163 &dwChannelConfig,
2164 sizeof (DWORD));
2165 if (!NT_SUCCESS (ntStatus))
2166 {
2167 DOUT (DBG_ERROR, ("Could not write the ChannelConfig to registry."));
2168 }
2169
2170 // release the settings key
2171 SettingsKey->Release ();
2172 }
2173
2174 // release the driver key
2175 DriverKey->Release ();
2176 }
2177}
2178
2179/*****************************************************************************
2180 * Non paged code begins here
2181 *****************************************************************************
2182 */
2183
2184#ifdef _MSC_VER
2185#pragma code_seg()
2186#endif
2187/*****************************************************************************
2188 * CAC97AdapterCommon::WriteBMControlRegister
2189 *****************************************************************************
2190 * Writes a byte (UCHAR) to BusMaster Control register.
2191 */
2192STDMETHODIMP_(void) CAC97AdapterCommon::WriteBMControlRegister
2193(
2194 IN ULONG ulOffset,
2195 IN UCHAR ucValue
2196)
2197{
2198 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::WriteBMControlRegister] (UCHAR)"));
2199
2200 WRITE_PORT_UCHAR ((PUCHAR)(m_pBusMasterBase + ulOffset), ucValue);
2201
2202 DOUT (DBG_REGS, ("WriteBMControlRegister wrote 0x%2x to 0x%4p.",
2203 ucValue, m_pBusMasterBase + ulOffset));
2204}
2205
2206/*****************************************************************************
2207 * CAC97AdapterCommon::WriteBMControlRegister
2208 *****************************************************************************
2209 * Writes a word (USHORT) to BusMaster Control register.
2210 */
2211STDMETHODIMP_(void) CAC97AdapterCommon::WriteBMControlRegister
2212(
2213 IN ULONG ulOffset,
2214 IN USHORT usValue
2215)
2216{
2217 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::WriteBMControlRegister (USHORT)]"));
2218
2219 WRITE_PORT_USHORT ((PUSHORT)(m_pBusMasterBase + ulOffset), usValue);
2220
2221 DOUT (DBG_REGS, ("WriteBMControlRegister wrote 0x%4x to 0x%4p",
2222 usValue, m_pBusMasterBase + ulOffset));
2223}
2224
2225/*****************************************************************************
2226 * CAC97AdapterCommon::WriteBMControlRegister
2227 *****************************************************************************
2228 * Writes a DWORD (ULONG) to BusMaster Control register.
2229 */
2230STDMETHODIMP_(void) CAC97AdapterCommon::WriteBMControlRegister
2231(
2232 IN ULONG ulOffset,
2233 IN ULONG ulValue
2234)
2235{
2236 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::WriteBMControlRegister (ULONG)]"));
2237
2238 WRITE_PORT_ULONG ((PULONG)(m_pBusMasterBase + ulOffset), ulValue);
2239
2240 DOUT (DBG_REGS, ("WriteBMControlRegister wrote 0x%8x to 0x%4p.",
2241 ulValue, m_pBusMasterBase + ulOffset));
2242}
2243
2244/*****************************************************************************
2245 * CAC97AdapterCommon::ReadBMControlRegister8
2246 *****************************************************************************
2247 * Read a byte (UCHAR) from BusMaster Control register.
2248 */
2249STDMETHODIMP_(UCHAR) CAC97AdapterCommon::ReadBMControlRegister8
2250(
2251 IN ULONG ulOffset
2252)
2253{
2254 UCHAR ucValue = UCHAR(-1);
2255
2256 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ReadBMControlRegister8]"));
2257
2258 ucValue = READ_PORT_UCHAR ((PUCHAR)(m_pBusMasterBase + ulOffset));
2259
2260 DOUT (DBG_REGS, ("ReadBMControlRegister read 0x%2x from 0x%4p.", ucValue,
2261 m_pBusMasterBase + ulOffset));
2262
2263 return ucValue;
2264}
2265
2266/*****************************************************************************
2267 * CAC97AdapterCommon::ReadBMControlRegister16
2268 *****************************************************************************
2269 * Read a word (USHORT) from BusMaster Control register.
2270 */
2271STDMETHODIMP_(USHORT) CAC97AdapterCommon::ReadBMControlRegister16
2272(
2273 IN ULONG ulOffset
2274)
2275{
2276 USHORT usValue = USHORT(-1);
2277
2278 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ReadBMControlRegister16]"));
2279
2280 usValue = READ_PORT_USHORT ((PUSHORT)(m_pBusMasterBase + ulOffset));
2281
2282 DOUT (DBG_REGS, ("ReadBMControlRegister read 0x%4x = 0x%4p", usValue,
2283 m_pBusMasterBase + ulOffset));
2284
2285 return usValue;
2286}
2287
2288/*****************************************************************************
2289 * CAC97AdapterCommon::ReadBMControlRegister32
2290 *****************************************************************************
2291 * Read a dword (ULONG) from BusMaster Control register.
2292 */
2293STDMETHODIMP_(ULONG) CAC97AdapterCommon::ReadBMControlRegister32
2294(
2295 IN ULONG ulOffset
2296)
2297{
2298 ULONG ulValue = ULONG(-1);
2299
2300 DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ReadBMControlRegister32]"));
2301
2302 ulValue = READ_PORT_ULONG ((PULONG)(m_pBusMasterBase + ulOffset));
2303
2304 DOUT (DBG_REGS, ("ReadBMControlRegister read 0x%8x = 0x%4p", ulValue,
2305 m_pBusMasterBase + ulOffset));
2306
2307 return ulValue;
2308}
2309
#define PAGED_CODE()
STDMETHODIMP_(void) CAC97AdapterCommon
Definition: common.cpp:1532
NTSTATUS NewAdapterCommon(OUT PUNKNOWN *Unknown, IN REFCLSID, IN PUNKNOWN UnknownOuter OPTIONAL, _When_((PoolType &NonPagedPoolMustSucceed) !=0, __drv_reportError("Must succeed pool allocations are forbidden. " "Allocation failures cause a system crash")) IN POOL_TYPE PoolType)
Definition: common.cpp:117
AC97Register
Definition: ac97reg.h:17
@ AC97REG_EXT_AUDIO_CTRL
Definition: ac97reg.h:41
@ AC97REG_AUX_VOLUME
Definition: ac97reg.h:29
@ AC97REG_MASTER_VOLUME
Definition: ac97reg.h:19
@ AC97REG_SURROUND_VOLUME
Definition: ac97reg.h:48
@ AC97REG_RESET
Definition: ac97reg.h:18
@ AC97REG_POWERDOWN
Definition: ac97reg.h:37
@ AC97REG_INVALID
Definition: ac97reg.h:60
@ AC97REG_VIDEO_VOLUME
Definition: ac97reg.h:28
@ AC97REG_HPHONE_VOLUME
Definition: ac97reg.h:20
@ AC97REG_EXT_AUDIO_ID
Definition: ac97reg.h:40
@ AC97REG_VENDOR_ID1
Definition: ac97reg.h:55
@ AC97REG_GENERAL
Definition: ac97reg.h:34
@ AC97REG_PHONE_VOLUME
Definition: ac97reg.h:24
@ AC97REG_LFE_SAMPLERATE
Definition: ac97reg.h:44
@ AC97REG_3D_CONTROL
Definition: ac97reg.h:35
@ AC97REG_MIC_SAMPLERATE
Definition: ac97reg.h:46
@ AC97REG_RESERVED2
Definition: ac97reg.h:49
@ AC97REG_RECORD_SAMPLERATE
Definition: ac97reg.h:45
@ AC97REG_MMONO_VOLUME
Definition: ac97reg.h:21
@ AC97REG_CENTER_LFE_VOLUME
Definition: ac97reg.h:47
@ AC97REG_BEEP_VOLUME
Definition: ac97reg.h:23
@ AC97REG_SURROUND_SAMPLERATE
Definition: ac97reg.h:43
@ AC97REG_VENDOR_ID2
Definition: ac97reg.h:56
@ AC97REG_FRONT_SAMPLERATE
Definition: ac97reg.h:42
LONG NTSTATUS
Definition: precomp.h:26
const GUID IID_IUnknown
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:81
AC97REG_INVALID AC97Register _Out_ PWORD wData
Definition: common.h:265
NTSTATUS SetAC97Default(void)
Definition: common.cpp:1742
PWORD pwChannels
Definition: common.h:364
NTSTATUS PrimaryCodecReady(void)
Definition: common.cpp:1284
NTSTATUS InitAC97(void)
Definition: common.cpp:540
DEVICE_POWER_STATE m_PowerState
Definition: common.h:98
BOOL m_bDirectRead
Definition: common.h:97
static tHardwareConfig m_stHardwareConfig
Definition: common.h:93
NTSTATUS PowerUpCodec(void)
Definition: common.cpp:1331
static tAC97Registers m_stAC97Registers[64]
Definition: common.h:92
PUCHAR m_pBusMasterBase
Definition: common.h:96
PAC97MINIPORTTOPOLOGY m_Topology
Definition: common.h:99
PDEVICE_OBJECT m_pDeviceObject
Definition: common.h:94
IN PDEVICE_OBJECT DeviceObject
Definition: common.h:189
NTSTATUS AcquireCodecSemiphore(void)
Definition: common.cpp:1062
AC97REG_INVALID AC97Register Register
Definition: common.h:263
AC97REG_INVALID AC97Register _In_ WORD _In_ WORD wMask
Definition: common.h:275
PWORD m_pCodecBase
Definition: common.h:95
IN DWORD dwSampleRate
Definition: common.h:338
NTSTATUS Check6thBitSupport(IN AC97Register, IN TopoNodeConfig)
Definition: common.cpp:577
NTSTATUS ProbeHWConfig(void)
Definition: common.cpp:636
BOOL DisableAC97Pin(IN TopoPinConfig)
Definition: common.cpp:1880
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI PcNewRegistryKey(OUT PREGISTRYKEY *OutRegistryKey, IN PUNKNOWN OuterUnknown OPTIONAL, IN ULONG RegistryKeyType, IN ACCESS_MASK DesiredAccess, IN PVOID DeviceObject OPTIONAL, IN PVOID SubDevice OPTIONAL, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN ULONG CreateOptions OPTIONAL, OUT PULONG Disposition OPTIONAL)
Definition: registry.cpp:264
const WORD SHREG_NOCACHE
Definition: common.h:73
const WORD SHREG_INIT
Definition: common.h:68
const WORD SHREG_INVALID
Definition: common.h:62
const int DBG_REGS
Definition: debug.h:25
const int DBG_PROBE
Definition: debug.h:26
const int DBG_POWER
Definition: debug.h:23
#define DOUT(lvl, strings)
Definition: debug.h:82
const int DBG_VSR
Definition: debug.h:28
const int DBG_SYSINFO
Definition: debug.h:27
TopoPinConfig
Definition: shared.h:62
@ PINC_LINEIN_PRESENT
Definition: shared.h:72
@ PINC_MONOOUT_PRESENT
Definition: shared.h:69
@ PINC_VIDEO_PRESENT
Definition: shared.h:66
@ PINC_MIC2_PRESENT
Definition: shared.h:65
@ PINC_PCBEEP_PRESENT
Definition: shared.h:63
@ PINC_PHONE_PRESENT
Definition: shared.h:64
@ PINC_AUX_PRESENT
Definition: shared.h:67
@ PINC_SURROUND_PRESENT
Definition: shared.h:74
@ PINC_CENTER_LFE_PRESENT
Definition: shared.h:75
@ PINC_HPOUT_PRESENT
Definition: shared.h:68
@ PINC_CD_PRESENT
Definition: shared.h:73
@ PINC_MICIN_PRESENT
Definition: shared.h:70
@ PINC_MIC_PRESENT
Definition: shared.h:71
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_TONE_PRESENT
Definition: shared.h:86
@ 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_LOUDNESS_PRESENT
Definition: shared.h:87
@ NODEC_6BIT_SURROUND_VOLUME
Definition: shared.h:92
@ NODEC_3D_PRESENT
Definition: shared.h:85
@ NODEC_SIMUL_STEREO_PRESENT
Definition: shared.h:88
@ NODEC_6BIT_MONOOUT_VOLUME
Definition: shared.h:91
@ NODEC_6BIT_MASTER_VOLUME
Definition: shared.h:89
@ NODEC_PCM_VSR_INDEPENDENT_RATES
Definition: shared.h:97
IAC97AdapterCommon * PADAPTERCOMMON
Definition: shared.h:488
#define __drv_reportError(why)
Definition: driverspecs.h:320
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
#define PagedPool
Definition: env_spec_w32.h:308
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
VOID NTAPI WRITE_PORT_USHORT(IN PUSHORT Port, IN USHORT Value)
Definition: portio.c:115
ULONG NTAPI READ_PORT_ULONG(IN PULONG Port)
Definition: portio.c:70
VOID NTAPI WRITE_PORT_ULONG(IN PULONG Port, IN ULONG Value)
Definition: portio.c:123
USHORT NTAPI READ_PORT_USHORT(IN PUSHORT Port)
Definition: portio.c:63
static int reg
Definition: i386-dis.c:1290
@ Unknown
Definition: i8042prt.h:114
const ULONG GLOB_STA_SCR
Definition: ichreg.h:85
const ULONG GLOB_STA_MC4
Definition: ichreg.h:76
const ULONG GLOB_STA_PCR
Definition: ichreg.h:86
const ULONG GLOB_CNT_PRIE
Definition: ichreg.h:68
const ULONG GLOB_CNT
Definition: ichreg.h:42
const ULONG GLOB_CNT_ACLOFF
Definition: ichreg.h:69
const UCHAR CAS_CAS
Definition: ichreg.h:93
const ULONG GLOB_CNT_COLD
Definition: ichreg.h:71
const ULONG GLOB_STA_MD3
Definition: ichreg.h:77
const ULONG GLOB_STA_AD3
Definition: ichreg.h:78
const ULONG GLOB_STA_RCS
Definition: ichreg.h:79
const ULONG GLOB_STA_MC6
Definition: ichreg.h:75
const ULONG GLOB_STA
Definition: ichreg.h:43
const ULONG CAS
Definition: ichreg.h:44
#define KSAUDIO_SPEAKER_SURROUND
Definition: ksmedia.h:1457
#define KSAUDIO_SPEAKER_5POINT1
Definition: ksmedia.h:1459
#define KSAUDIO_SPEAKER_QUAD
Definition: ksmedia.h:1455
#define KSAUDIO_SPEAKER_STEREO
Definition: ksmedia.h:1454
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define _Use_decl_annotations_
Definition: ms_sal.h:275
#define _Out_
Definition: ms_sal.h:345
#define _When_(expr, annos)
Definition: ms_sal.h:254
#define _COM_Outptr_
Definition: ms_sal.h:449
#define _In_
Definition: ms_sal.h:308
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
#define _In_range_(lb, ub)
Definition: ms_sal.h:571
#define KernelMode
Definition: asm.h:34
#define DBG_ERROR
Definition: nfs41_debug.h:78
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define KEY_WRITE
Definition: nt_native.h:1031
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
@ PowerDeviceD1
Definition: ntpoapi.h:50
@ PowerDeviceD0
Definition: ntpoapi.h:49
@ PowerDeviceD2
Definition: ntpoapi.h:51
@ PowerDeviceD3
Definition: ntpoapi.h:52
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
WORD * PWORD
Definition: pedump.c:67
BYTE * PBYTE
Definition: pedump.c:66
DWORD * PDWORD
Definition: pedump.c:68
unsigned short USHORT
Definition: pedump.c:61
IRegistryKey * PREGISTRYKEY
Definition: portcls.h:1009
IResourceList * PRESOURCELIST
Definition: portcls.h:442
IAdapterPowerManagement * PADAPTERPOWERMANAGEMENT
Definition: portcls.h:2039
@ DriverRegistryKey
Definition: portcls.h:902
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define REG_DWORD
Definition: sdbapi.c:596
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define STATUS_SUCCESS
Definition: shellext.h:65
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
Definition: regsvr.c:104
WORD wFlags
Definition: common.h:48
WORD wCache
Definition: common.h:47
PWCHAR sRegistryName
Definition: common.h:35
uint32_t * PULONG
Definition: typedefs.h:59
INT POOL_TYPE
Definition: typedefs.h:78
void * PVOID
Definition: typedefs.h:50
uint16_t * PUSHORT
Definition: typedefs.h:56
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG PoolTag
Definition: wdfmemory.h:164
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:309
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
#define DBG_PRINT(ppi, ch, level)
Definition: win32kdebug.h:168
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
* PDEVICE_CAPABILITIES
Definition: iotypes.h:965
@ NonPagedPoolMustSucceed
Definition: ketypes.h:880
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char BYTE
Definition: xxhash.c:193