2 The contents of this file are subject to the AROS Public License Version 1.1 (the "License");
3 you may not use this file except in compliance with the License. You may obtain a copy of the License at
4 http://www.aros.org/license.html
5 Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
6 ANY KIND, either express or implied. See the License for the specific language governing rights and
7 limitations under the License.
9 The Original Code is written by Davy Wentzler.
14 #if !defined(__AROS__)
16 #include <proto/expansion.h>
19 #include <devices/ahi.h>
20 #include <exec/memory.h>
21 #include <libraries/ahi_sub.h>
23 #include <proto/ahi_sub.h>
24 #include <proto/exec.h>
25 #include <proto/dos.h>
26 #include <proto/utility.h>
30 #include <aros/debug.h>
31 #define DebugPrintF bug
39 #include "pci_wrapper.h"
43 /******************************************************************************
44 ** Globals ********************************************************************
45 ******************************************************************************/
49 static const ULONG Frequencies
[ FREQUENCIES
] =
52 8000, // ยต- and A-Law
61 static const ULONG FrequencyBits
[ FREQUENCIES
] =
75 static const STRPTR Inputs
[ INPUTS
] =
85 /* Not static since it's used in misc.c too */
86 const UWORD InputBits
[ INPUTS
] =
93 AC97_RECMUX_STEREO_MIX
,
101 static const STRPTR Outputs
[ OUTPUTS
] =
107 /******************************************************************************
108 ** AHIsub_AllocAudio **********************************************************
109 ******************************************************************************/
112 _AHIsub_AllocAudio( struct TagItem
* taglist
,
113 struct AHIAudioCtrlDrv
* AudioCtrl
,
114 struct DriverBase
* AHIsubBase
)
116 struct CMI8738Base
* CMI8738Base
= (struct CMI8738Base
*) AHIsubBase
;
122 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__
);
124 card_num
= ( GetTagData( AHIDB_AudioID
, 0, taglist
) & 0x0000f000 ) >> 12;
126 if( card_num
>= CMI8738Base
->cards_found
||
127 CMI8738Base
->driverdatas
[ card_num
] == NULL
)
129 DebugPrintF("no date for card = %ld\n", card_num
);
130 Req( "No CMI8738_DATA for card %ld.", card_num
);
135 struct CMI8738_DATA
* card
;
137 struct PCIDevice
*dev
;
139 card
= CMI8738Base
->driverdatas
[ card_num
];
140 AudioCtrl
->ahiac_DriverData
= card
;
142 ObtainSemaphore( &CMI8738Base
->semaphore
);
143 in_use
= ( card
->audioctrl
!= NULL
);
146 card
->audioctrl
= AudioCtrl
;
148 ReleaseSemaphore( &CMI8738Base
->semaphore
);
156 card
->playback_interrupt_enabled
= FALSE
;
157 card
->record_interrupt_enabled
= FALSE
;
159 for( i
= 1; i
< FREQUENCIES
; i
++ )
161 if( (ULONG
) Frequencies
[ i
] > AudioCtrl
->ahiac_MixFreq
)
163 if ( ( AudioCtrl
->ahiac_MixFreq
- (LONG
) Frequencies
[ i
- 1 ] ) < ( (LONG
) Frequencies
[ i
] - AudioCtrl
->ahiac_MixFreq
) )
177 ret
= AHISF_KNOWHIFI
| AHISF_KNOWSTEREO
| AHISF_MIXING
| AHISF_TIMING
;
179 for( i
= 0; i
< FREQUENCIES
; ++i
)
181 if( AudioCtrl
->ahiac_MixFreq
== Frequencies
[ i
] )
183 ret
|= AHISF_CANRECORD
;
193 /******************************************************************************
194 ** AHIsub_FreeAudio ***********************************************************
195 ******************************************************************************/
198 _AHIsub_FreeAudio( struct AHIAudioCtrlDrv
* AudioCtrl
,
199 struct DriverBase
* AHIsubBase
)
201 struct CMI8738Base
* CMI8738Base
= (struct CMI8738Base
*) AHIsubBase
;
202 struct CMI8738_DATA
* card
= (struct CMI8738_DATA
*) AudioCtrl
->ahiac_DriverData
;
204 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__
);
208 ObtainSemaphore( &CMI8738Base
->semaphore
);
209 if( card
->audioctrl
== AudioCtrl
)
211 // Release it if we own it.
212 card
->audioctrl
= NULL
;
214 ReleaseSemaphore( &CMI8738Base
->semaphore
);
216 AudioCtrl
->ahiac_DriverData
= NULL
;
221 /******************************************************************************
222 ** AHIsub_Disable *************************************************************
223 ******************************************************************************/
226 _AHIsub_Disable( struct AHIAudioCtrlDrv
* AudioCtrl
,
227 struct DriverBase
* AHIsubBase
)
229 struct CMI8738Base
* CMI8738Base
= (struct CMI8738Base
*) AHIsubBase
;
231 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__
);
233 // V6 drivers do not have to preserve all registers
239 /******************************************************************************
240 ** AHIsub_Enable **************************************************************
241 ******************************************************************************/
244 _AHIsub_Enable( struct AHIAudioCtrlDrv
* AudioCtrl
,
245 struct DriverBase
* AHIsubBase
)
247 struct CMI8738Base
* CMI8738Base
= (struct CMI8738Base
*) AHIsubBase
;
249 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__
);
251 // V6 drivers do not have to preserve all registers
257 /******************************************************************************
258 ** AHIsub_Start ***************************************************************
259 ******************************************************************************/
262 _AHIsub_Start( ULONG flags
,
263 struct AHIAudioCtrlDrv
* AudioCtrl
,
264 struct DriverBase
* AHIsubBase
)
266 struct CMI8738Base
* CMI8738Base
= (struct CMI8738Base
*) AHIsubBase
;
267 struct CMI8738_DATA
* card
= (struct CMI8738_DATA
*) AudioCtrl
->ahiac_DriverData
;
268 struct PCIDevice
*dev
= card
->pci_dev
;
269 UWORD PlayCtrlFlags
= 0, RecCtrlFlags
= 0;
270 ULONG dma_buffer_size
= 0;
272 unsigned long phys_addr
;
275 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__
);
277 /* Stop playback/recording, free old buffers (if any) */
278 //IAHIsub->AHIsub_Stop( flags, AudioCtrl );
280 for( i
= 0; i
< FREQUENCIES
; ++i
)
282 if( AudioCtrl
->ahiac_MixFreq
== Frequencies
[ i
] )
289 card
->mixerstate
= cmimix_rd(dev
, card
, CMPCI_SB16_MIXER_OUTMIX
);
291 if( flags
& AHISF_PLAY
)
293 ULONG dma_sample_frame_size
;
296 unsigned short cod
, ChannelsFlag
= CMPCI_REG_FORMAT_16BIT
;
298 //WriteMask(dev, card, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET | CMPCI_REG_CH1_RESET);
299 //ClearMask(dev, card, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET | CMPCI_REG_CH1_RESET);
301 /* Allocate a new mixing buffer. Note: The buffer must be cleared, since
302 it might not be filled by the mixer software interrupt because of
303 pretimer/posttimer! */
305 card
->mix_buffer
= AllocVec( AudioCtrl
->ahiac_BuffSize
, MEMF_PUBLIC
| MEMF_CLEAR
);
307 if( card
->mix_buffer
== NULL
)
309 Req( "Unable to allocate %ld bytes for mixing buffer.", AudioCtrl
->ahiac_BuffSize
);
313 /* Allocate a buffer large enough for 16-bit double-buffered
314 playback (mono or stereo) */
316 if( AudioCtrl
->ahiac_Flags
& AHIACF_STEREO
)
318 dma_sample_frame_size
= 4;
319 dma_buffer_size
= AudioCtrl
->ahiac_MaxBuffSamples
* dma_sample_frame_size
;
320 ChannelsFlag
|= CMPCI_REG_FORMAT_STEREO
;
324 dma_sample_frame_size
= 2;
325 dma_buffer_size
= AudioCtrl
->ahiac_MaxBuffSamples
* dma_sample_frame_size
;
328 //DebugPrintF("dma_buffer_size = %ld, AudioCtrl->ahiac_BuffSize = %ld, AudioCtrl->ahiac_MaxBuffSamples = %ld\nAudioCtrl->ahiac_BuffSamples = %ld", dma_buffer_size, AudioCtrl->ahiac_BuffSize, AudioCtrl->ahiac_MaxBuffSamples, AudioCtrl->ahiac_BuffSamples);
330 card
->playback_buffer
= pci_alloc_consistent(dma_buffer_size
* 2, &card
->playback_buffer_nonaligned
, 128);
332 if (!card
->playback_buffer
)
334 Req( "Unable to allocate playback buffer." );
338 card
->current_bytesize
= dma_buffer_size
;
339 card
->current_frames
= AudioCtrl
->ahiac_MaxBuffSamples
;
340 card
->current_buffer
= card
->playback_buffer
+ card
->current_bytesize
;
341 card
->playback_interrupt_enabled
= TRUE
;
346 WritePartialMask(dev
, card
, CMPCI_REG_FUNC_1
, CMPCI_REG_DAC_FS_SHIFT
, CMPCI_REG_DAC_FS_MASK
, FrequencyBits
[freqbit
]);
347 WritePartialMask(dev
, card
, CMPCI_REG_CHANNEL_FORMAT
, CMPCI_REG_CH0_FORMAT_SHIFT
, CMPCI_REG_CH0_FORMAT_MASK
, ChannelsFlag
);
348 WriteMask(dev
, card
, CMPCI_REG_CHANNEL_FORMAT
, (13 << 1));
350 #if !defined(__AROS__)
351 if (IFakeDMA
== NULL
)
353 stack
= SuperState();
354 card
->playback_buffer_phys
= IMMU
->GetPhysicalAddress(card
->playback_buffer
);
359 card
->playback_buffer_phys
= card
->playback_buffer
;
361 bug("[CMI8738] %s: Playback buffer @ 0x%p\n", __PRETTY_FUNCTION__
, card
->playback_buffer
);
363 pci_outl(card
->playback_buffer_phys
, CMPCI_REG_DMA0_BASE
, card
);
364 pci_outw((dma_buffer_size
/ dma_sample_frame_size
) * 2 - 1, CMPCI_REG_DMA0_LENGTH
, card
);
365 pci_outw((dma_buffer_size
/ dma_sample_frame_size
) - 1, CMPCI_REG_DMA0_INTLEN
, card
);
367 card
->is_playing
= TRUE
;
370 if( flags
& AHISF_RECORD
)
373 ULONG ChannelsFlag
= CMPCI_REG_FORMAT_16BIT
;
376 card
->current_record_bytesize
= RECORD_BUFFER_SAMPLES
* 4;
378 /* Allocate a new recording buffer (page aligned!) */
379 card
->record_buffer
= pci_alloc_consistent(card
->current_record_bytesize
* 2, &card
->record_buffer_nonaligned
, 128);
381 if( card
->record_buffer
== NULL
)
383 Req( "Unable to allocate %ld bytes for the recording buffer.", card
->current_record_bytesize
, 128);
387 SaveMixerState( card
);
388 UpdateMonitorMixer( card
);
393 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_OUTMIX
, card
->mixerstate
| CMPCI_SB16_SW_LINE
);
397 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_OUTMIX
, card
->mixerstate
| CMPCI_SB16_SW_MIC
);
401 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_OUTMIX
, card
->mixerstate
| CMPCI_SB16_SW_CD
);
405 byte
= pci_inb(CMPCI_REG_MIXER25
, card
);
407 pci_outb(byte
, CMPCI_REG_MIXER25
, card
); // unmute Aux
414 card
->record_interrupt_enabled
= TRUE
;
418 WritePartialMask(dev
, card
, CMPCI_REG_FUNC_1
, CMPCI_REG_ADC_FS_SHIFT
, CMPCI_REG_ADC_FS_MASK
, FrequencyBits
[freqbit
]);
419 WritePartialMask(dev
, card
, CMPCI_REG_CHANNEL_FORMAT
, CMPCI_REG_CH1_FORMAT_SHIFT
, CMPCI_REG_CH1_FORMAT_MASK
, CMPCI_REG_FORMAT_16BIT
| CMPCI_REG_FORMAT_STEREO
);
421 #if !defined(__AROS__)
422 if (IFakeDMA
== NULL
)
424 stack
= SuperState();
425 card
->record_buffer_phys
= IMMU
->GetPhysicalAddress(card
->record_buffer
);
430 card
->record_buffer_phys
= card
->record_buffer
;
432 pci_outl(card
->record_buffer_phys
, CMPCI_REG_DMA1_BASE
, card
);
434 pci_outw((card
->current_record_bytesize
/ 4) * 2 - 1, CMPCI_REG_DMA1_LENGTH
, card
);
436 pci_outw((card
->current_record_bytesize
/ 4) - 1, CMPCI_REG_DMA1_INTLEN
, card
);
438 card
->current_record_buffer
= card
->record_buffer
+ card
->current_record_bytesize
;
439 card
->is_recording
= TRUE
;
442 if( flags
& AHISF_PLAY
)
445 WriteMask(dev
, card
, CMPCI_REG_FUNC_0
, CMPCI_REG_CH0_ENABLE
);
446 WriteMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH0_INTR_ENABLE
);
449 if( flags
& AHISF_RECORD
)
451 WriteMask(dev
, card
, CMPCI_REG_FUNC_0
, CMPCI_REG_CH1_ENABLE
);
452 WriteMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH1_INTR_ENABLE
);
459 /******************************************************************************
460 ** AHIsub_Update **************************************************************
461 ******************************************************************************/
464 _AHIsub_Update( ULONG flags
,
465 struct AHIAudioCtrlDrv
* AudioCtrl
,
466 struct DriverBase
* AHIsubBase
)
468 struct CMI8738Base
* CMI8738Base
= (struct CMI8738Base
*) AHIsubBase
;
469 struct CMI8738_DATA
* card
= (struct CMI8738_DATA
*) AudioCtrl
->ahiac_DriverData
;
471 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__
);
474 card
->current_frames
= AudioCtrl
->ahiac_BuffSamples
;
476 if( AudioCtrl
->ahiac_Flags
& AHIACF_STEREO
)
478 card
->current_bytesize
= card
->current_frames
* 4;
482 card
->current_bytesize
= card
->current_frames
* 2;
488 /******************************************************************************
489 ** AHIsub_Stop ****************************************************************
490 ******************************************************************************/
493 _AHIsub_Stop( ULONG flags
,
494 struct AHIAudioCtrlDrv
* AudioCtrl
,
495 struct DriverBase
* AHIsubBase
)
497 struct CMI8738Base
* CMI8738Base
= (struct CMI8738Base
*) AHIsubBase
;
498 struct CMI8738_DATA
* card
= (struct CMI8738_DATA
*) AudioCtrl
->ahiac_DriverData
;
499 struct PCIDevice
*dev
= card
->pci_dev
;
501 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__
);
503 if( flags
& AHISF_PLAY
)
505 unsigned short play_ctl
;
507 card
->is_playing
= FALSE
;
509 ClearMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH0_INTR_ENABLE
);
510 ClearMask(dev
, card
, CMPCI_REG_FUNC_0
, CMPCI_REG_CH0_ENABLE
);
512 if (card
->current_bytesize
> 0)
513 pci_free_consistent(card
->playback_buffer_nonaligned
);
515 card
->current_bytesize
= 0;
516 card
->current_frames
= 0;
517 card
->current_buffer
= NULL
;
519 if ( card
->mix_buffer
)
520 FreeVec( card
->mix_buffer
);
522 card
->mix_buffer
= NULL
;
523 card
->playback_interrupt_enabled
= FALSE
;
524 card
->current_bytesize
= 0;
525 //DebugPrintF("#IRQ's = %ld\n", z);
528 if( flags
& AHISF_RECORD
&& card
->is_recording
)
530 unsigned short rec_ctl
, val
;
533 ClearMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH1_INTR_ENABLE
);
534 ClearMask(dev
, card
, CMPCI_REG_FUNC_0
, CMPCI_REG_CH1_ENABLE
);
539 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_OUTMIX
, card
->mixerstate
);
543 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_OUTMIX
, card
->mixerstate
);
547 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_OUTMIX
, card
->mixerstate
);
551 byte
= pci_inb(CMPCI_REG_MIXER25
, card
);
552 pci_outb(byte
& ~0x30, CMPCI_REG_MIXER25
, card
); // mute Aux
559 if( card
->record_buffer
!= NULL
)
561 pci_free_consistent( card
->record_buffer_nonaligned
);
564 card
->record_buffer
= NULL
;
565 card
->current_record_bytesize
= 0;
567 card
->is_recording
= FALSE
;
568 card
->record_interrupt_enabled
= FALSE
;
573 /******************************************************************************
574 ** AHIsub_GetAttr *************************************************************
575 ******************************************************************************/
578 _AHIsub_GetAttr( ULONG attribute
,
581 struct TagItem
* taglist
,
582 struct AHIAudioCtrlDrv
* AudioCtrl
,
583 struct DriverBase
* AHIsubBase
)
585 struct CMI8738Base
* CMI8738Base
= (struct CMI8738Base
*) AHIsubBase
;
588 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__
);
590 struct CMI8738_DATA
* card
= (struct CMI8738_DATA
*) AudioCtrl
->ahiac_DriverData
;
593 int card_num
= ( GetTagData( AHIDB_AudioID
, 0, taglist
) & 0x0000f000 ) >> 12;
595 if( card_num
<= CMI8738Base
->cards_found
||
596 CMI8738Base
->driverdatas
[ card_num
] != NULL
)
597 card
= CMI8738Base
->driverdatas
[ card_num
];
599 bug("[CMI8738] %s: card data @ 0x%p\n", __PRETTY_FUNCTION__
, card
);
606 case AHIDB_MaxChannels
:
608 return card
->channels
;
611 case AHIDB_Frequencies
:
614 case AHIDB_Frequency
: // Index->Frequency
615 return (LONG
) Frequencies
[ argument
];
617 case AHIDB_Index
: // Frequency->Index
618 if( argument
<= (LONG
) Frequencies
[ 0 ] )
623 if( argument
>= (LONG
) Frequencies
[ FREQUENCIES
- 1 ] )
625 return FREQUENCIES
-1;
628 for( i
= 1; i
< FREQUENCIES
; i
++ )
630 if( (LONG
) Frequencies
[ i
] > argument
)
632 if( ( argument
- (LONG
) Frequencies
[ i
- 1 ] ) < ( (LONG
) Frequencies
[ i
] - argument
) )
643 return 0; // Will not happen
646 return (LONG
) "Davy Wentzler";
648 case AHIDB_Copyright
:
649 return (LONG
) "(C) 2011 The AROS Dev Team";
652 return (LONG
) LibIDString
;
654 case AHIDB_Annotation
:
655 return (LONG
) "AROS CMI8738 Audio driver";
660 case AHIDB_FullDuplex
:
666 case AHIDB_MaxRecordSamples
:
667 return RECORD_BUFFER_SAMPLES
;
672 unsigned long res = (unsigned long) (0x10000 * pow (10.0, dB / 20.0));
673 double dB = 20.0 * log10(0xVALUE / 65536.0);
675 printf("dB = %f, res = %lx\n", dB, res);*/
677 case AHIDB_MinMonitorVolume
:
680 case AHIDB_MaxMonitorVolume
:
683 case AHIDB_MinInputGain
:
684 return 0x10000; // 0.0 dB gain
686 case AHIDB_MaxInputGain
:
687 return 0x10000; // 0 dB gain
689 case AHIDB_MinOutputVolume
:
690 return 0x34; // -62 dB
692 case AHIDB_MaxOutputVolume
:
693 return 0x10000; // 0 dB
699 return (LONG
) Inputs
[ argument
];
705 return (LONG
) Outputs
[ argument
];
713 /******************************************************************************
714 ** AHIsub_HardwareControl *****************************************************
715 ******************************************************************************/
718 _AHIsub_HardwareControl( ULONG attribute
,
720 struct AHIAudioCtrlDrv
* AudioCtrl
,
721 struct DriverBase
* AHIsubBase
)
723 struct CMI8738Base
* CMI8738Base
= (struct CMI8738Base
*) AHIsubBase
;
724 struct CMI8738_DATA
* card
= (struct CMI8738_DATA
*) AudioCtrl
->ahiac_DriverData
;
725 struct PCIDevice
*dev
= card
->pci_dev
;
728 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__
);
732 case AHIC_MonitorVolume
:
733 card
->monitor_volume
= Linear2MixerGain( (Fixed
) argument
, &card
->monitor_volume_bits
);
734 //DebugPrintF("card->monitor_volume = %lu, %lx\n", card->monitor_volume, card->monitor_volume);
735 if( card
->is_recording
)
737 UpdateMonitorMixer( card
);
741 case AHIC_MonitorVolume_Query
:
742 return card
->monitor_volume
;
745 card
->input_gain
= Linear2RecordGain( (Fixed
) argument
, &card
->input_gain_bits
);
746 //codec_write(card, AC97_RECORD_GAIN, card->input_gain_bits );
749 case AHIC_InputGain_Query
:
750 return card
->input_gain
;
752 case AHIC_OutputVolume
:
754 double dB
= 20.0 * log10((Fixed
) argument
/ 65536.0);
755 unsigned int val
= 0xFF - ( ((unsigned int)(-dB
/2)) << 3);
756 cmimix_wr(dev
, card
, 0x30, val
);
757 cmimix_wr(dev
, card
, 0x31, val
);
760 case AHIC_OutputVolume_Query
:
761 return card
->output_volume
;
764 card
->input
= argument
;
769 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_ADCMIX_L
, (CMPCI_SB16_MIXER_LINE_SRC_R
<< 1) );
770 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_ADCMIX_R
, CMPCI_SB16_MIXER_LINE_SRC_R
);
774 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_ADCMIX_L
, CMPCI_SB16_MIXER_MIC_SRC
);
775 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_ADCMIX_R
, CMPCI_SB16_MIXER_MIC_SRC
);
779 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_ADCMIX_L
, (CMPCI_SB16_MIXER_CD_SRC_R
<< 1) );
780 cmimix_wr(dev
, card
, CMPCI_SB16_MIXER_ADCMIX_R
, CMPCI_SB16_MIXER_CD_SRC_R
);
784 byte
= pci_inb(CMPCI_REG_MIXER25
, card
);
785 pci_outb(byte
| 0xC0, CMPCI_REG_MIXER25
, card
); // rec source Aux
796 if( card
->is_recording
)
798 UpdateMonitorMixer( card
);
803 case AHIC_Input_Query
:
807 card
->output
= argument
;
809 if( card
->output
== 0 )
811 ClearMask(dev
, card
, CMPCI_REG_FUNC_1
, CMPCI_REG_SPDIFOUT_DAC
| CMPCI_REG_SPDIF0_ENABLE
);
812 ClearMask(dev
, card
, CMPCI_REG_LEGACY_CTRL
, CMPCI_REG_XSPDIF_ENABLE
);
816 WriteMask(dev
, card
, CMPCI_REG_FUNC_1
, CMPCI_REG_SPDIFOUT_DAC
| CMPCI_REG_SPDIF0_ENABLE
);
817 WriteMask(dev
, card
, CMPCI_REG_LEGACY_CTRL
, CMPCI_REG_XSPDIF_ENABLE
);
821 case AHIC_Output_Query
: