2 emu10kx.audio - AHI driver for SoundBlaster Live! series
3 Copyright (C) 2002-2005 Martin Blom <martin@blom.org>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 /******************************************************************************
21 ** WARNING *******************************************************************
22 *******************************************************************************
24 Note that you CANNOT base proprietary drivers on this particular
25 driver! Anything that is based on this driver has to be GPL:ed.
27 *******************************************************************************
28 ** WARNING *******************************************************************
29 ******************************************************************************/
34 #include <devices/ahi.h>
35 #include <exec/memory.h>
36 #include <libraries/ahi_sub.h>
38 #include <proto/ahi_sub.h>
39 #include <proto/exec.h>
40 #include <proto/utility.h>
46 #include "emu10kx-misc.h"
47 #include "pci_wrapper.h"
50 /******************************************************************************
51 ** Globals ********************************************************************
52 ******************************************************************************/
56 static const ULONG Frequencies
[ FREQUENCIES
] =
58 8000, // ยต- and A-Law
70 static const STRPTR Inputs
[ INPUTS
] =
82 /* Not static since it's used in emu10kx-misc.c too */
83 const UWORD InputBits
[ INPUTS
] =
85 AC97_RECMUX_STEREO_MIX
,
98 static const STRPTR Outputs
[ OUTPUTS
] =
105 /******************************************************************************
106 ** AHIsub_AllocAudio **********************************************************
107 ******************************************************************************/
110 _AHIsub_AllocAudio( struct TagItem
* taglist
,
111 struct AHIAudioCtrlDrv
* AudioCtrl
,
112 struct DriverBase
* AHIsubBase
)
114 struct EMU10kxBase
* EMU10kxBase
= (struct EMU10kxBase
*) AHIsubBase
;
120 card_num
= ( GetTagData( AHIDB_AudioID
, 0, taglist
) & 0x0000f000 ) >> 12;
122 if( card_num
>= EMU10kxBase
->cards_found
||
123 EMU10kxBase
->driverdatas
[ card_num
] == NULL
)
125 Req( "No EMU10kxData for card %ld.", card_num
);
130 struct EMU10kxData
* dd
= EMU10kxBase
->driverdatas
[ card_num
];
133 AudioCtrl
->ahiac_DriverData
= dd
;
135 ObtainSemaphore( &EMU10kxBase
->semaphore
);
136 in_use
= ( dd
->audioctrl
!= NULL
);
139 dd
->audioctrl
= AudioCtrl
;
141 ReleaseSemaphore( &EMU10kxBase
->semaphore
);
148 /* Since the EMU10kx chips can play a voice at any sample rate, we
149 do not have to examine/modify AudioCtrl->ahiac_MixFreq here.
151 Had this not been the case, AudioCtrl->ahiac_MixFreq should be
152 set to the frequency we will use.
154 However, recording can only be performed at the fixed sampling
159 ret
= AHISF_KNOWHIFI
| AHISF_KNOWSTEREO
| AHISF_KNOWMULTICHANNEL
| \
160 AHISF_MIXING
| AHISF_TIMING
;
162 for( i
= 0; i
< FREQUENCIES
; ++i
)
164 if( AudioCtrl
->ahiac_MixFreq
== Frequencies
[ i
] )
166 ret
|= AHISF_CANRECORD
;
176 /******************************************************************************
177 ** AHIsub_FreeAudio ***********************************************************
178 ******************************************************************************/
181 _AHIsub_FreeAudio( struct AHIAudioCtrlDrv
* AudioCtrl
,
182 struct DriverBase
* AHIsubBase
)
184 struct EMU10kxBase
* EMU10kxBase
= (struct EMU10kxBase
*) AHIsubBase
;
185 struct EMU10kxData
* dd
= (struct EMU10kxData
*) AudioCtrl
->ahiac_DriverData
;
189 ObtainSemaphore( &EMU10kxBase
->semaphore
);
190 if( dd
->audioctrl
== AudioCtrl
)
192 // Release it if we own it.
193 dd
->audioctrl
= NULL
;
195 ReleaseSemaphore( &EMU10kxBase
->semaphore
);
197 AudioCtrl
->ahiac_DriverData
= NULL
;
202 /******************************************************************************
203 ** AHIsub_Disable *************************************************************
204 ******************************************************************************/
207 _AHIsub_Disable( struct AHIAudioCtrlDrv
* AudioCtrl
,
208 struct DriverBase
* AHIsubBase
)
210 // V6 drivers do not have to preserve all registers
216 /******************************************************************************
217 ** AHIsub_Enable **************************************************************
218 ******************************************************************************/
221 _AHIsub_Enable( struct AHIAudioCtrlDrv
* AudioCtrl
,
222 struct DriverBase
* AHIsubBase
)
224 // V6 drivers do not have to preserve all registers
230 /******************************************************************************
231 ** AHIsub_Start ***************************************************************
232 ******************************************************************************/
235 _AHIsub_Start( ULONG flags
,
236 struct AHIAudioCtrlDrv
* AudioCtrl
,
237 struct DriverBase
* AHIsubBase
)
239 struct EMU10kxData
* dd
= (struct EMU10kxData
*) AudioCtrl
->ahiac_DriverData
;
241 /* Stop playback/recording, free old buffers (if any) */
242 AHIsub_Stop( flags
, AudioCtrl
);
244 if( flags
& AHISF_PLAY
)
248 ULONG dma_buffer_size
;
249 ULONG dma_sample_frame_size
;
251 /* Update cached/syncronized variables */
253 AHIsub_Update( AHISF_PLAY
, AudioCtrl
);
255 /* Allocate a new mixing buffer. Note: The buffer must be cleared, since
256 it might not be filled by the mixer software interrupt because of
257 pretimer/posttimer! */
259 dd
->mix_buffer
= AllocVec( AudioCtrl
->ahiac_BuffSize
,
260 MEMF_ANY
| MEMF_PUBLIC
| MEMF_CLEAR
);
262 if( dd
->mix_buffer
== NULL
)
264 Req( "Unable to allocate %ld bytes for mixing buffer.",
265 AudioCtrl
->ahiac_BuffSize
);
269 /* Allocate 1 or 4 voice buffers large enough for 16-bit double-buffered
270 playback (mono, stereo or 8 channels) */
272 if( AudioCtrl
->ahiac_Flags
& AHIACF_STEREO
||
273 AudioCtrl
->ahiac_Flags
& AHIACF_MULTICHANNEL
)
275 dma_sample_frame_size
= 4;
276 dma_buffer_size
= AudioCtrl
->ahiac_MaxBuffSamples
* dma_sample_frame_size
;
280 dma_sample_frame_size
= 2;
281 dma_buffer_size
= AudioCtrl
->ahiac_MaxBuffSamples
* dma_sample_frame_size
;
284 if( AudioCtrl
->ahiac_Flags
& AHIACF_MULTICHANNEL
)
288 // Disable front-to-center/LFE routing
289 emu10k1_set_volume_gpr( &dd
->card
, VOL_FRONT_CENTER
, 0, VOL_5BIT
);
290 emu10k1_set_volume_gpr( &dd
->card
, VOL_FRONT_LFE
, 0, VOL_5BIT
);
296 // Enable front-to-center/LFE routing
297 emu10k1_set_volume_gpr( &dd
->card
, VOL_FRONT_CENTER
, 100, VOL_5BIT
);
298 emu10k1_set_volume_gpr( &dd
->card
, VOL_FRONT_LFE
, 100, VOL_5BIT
);
301 for( i
= 0; i
< num_voices
; ++i
)
303 if( emu10k1_voice_alloc_buffer( &dd
->card
,
305 ( dma_buffer_size
* 2 + PAGE_SIZE
- 1 )
308 Req( "Unable to allocate voice buffer." );
312 memset( dd
->voices
[i
].mem
.addr
, 0, dma_buffer_size
* 2 );
314 dd
->voices
[i
].usage
= VOICE_USAGE_PLAYBACK
;
316 if( AudioCtrl
->ahiac_Flags
& AHIACF_STEREO
||
317 AudioCtrl
->ahiac_Flags
& AHIACF_MULTICHANNEL
)
319 dd
->voices
[i
].flags
= VOICE_FLAGS_STEREO
| VOICE_FLAGS_16BIT
;
323 dd
->voices
[i
].flags
= VOICE_FLAGS_16BIT
;
327 dd
->voice_buffers_allocated
= num_voices
;
329 for( i
= 0; i
< num_voices
; ++i
)
331 if( emu10k1_voice_alloc( &dd
->card
, &dd
->voices
[i
] ) < 0 )
333 Req( "Unable to allocate voice." );
338 dd
->voices_allocated
= num_voices
;
340 for( i
= 0; i
< num_voices
; ++i
)
342 dd
->voices
[i
].initial_pitch
= (u16
) ( srToPitch( AudioCtrl
->ahiac_MixFreq
) >> 8 );
343 dd
->voices
[i
].pitch_target
= SamplerateToLinearPitch( AudioCtrl
->ahiac_MixFreq
);
345 DPD(2, "Initial pitch --> %#x\n", dd
->voice
.initial_pitch
);
347 /* start, startloop and endloop is unit sample frames, not bytes */
349 dd
->voices
[i
].start
= ( ( dd
->voices
[i
].mem
.emupageindex
<< 12 )
350 / dma_sample_frame_size
);
351 dd
->voices
[i
].endloop
= dd
->voices
[i
].start
+ AudioCtrl
->ahiac_MaxBuffSamples
* 2;
352 dd
->voices
[i
].startloop
= dd
->voices
[i
].start
;
354 /* Make interrupt routine start at the correct location */
356 dd
->current_position
= dd
->current_length
;
357 dd
->current_buffers
[i
] = ( dd
->voices
[i
].mem
.addr
+
358 dd
->current_position
* dma_sample_frame_size
);
360 dd
->voices
[i
].params
[0].volume_target
= 0xffff;
361 dd
->voices
[i
].params
[0].initial_fc
= 0xff;
362 dd
->voices
[i
].params
[0].initial_attn
= 0x00;
363 dd
->voices
[i
].params
[0].byampl_env_sustain
= 0x7f;
364 dd
->voices
[i
].params
[0].byampl_env_decay
= 0x7f;
366 if( dd
->voices
[i
].flags
& VOICE_FLAGS_STEREO
)
368 if( dd
->card
.is_audigy
)
370 static int routes
[] = {
371 0x03020100, // Send FL/FR to ??/??, AHI_FRONT_L/MULTI_FRONT_R
372 0x03020504, // Send RL/RR to ??/??, AHI_REAR_L/AHI_REAR_R
373 0x03020706, // Send SL/SR to ??/??, AHI_SURROUND_L/AHI_SURROUND_R
374 0x03020908, // Send C/LFE to ??/??, AHI_CENTER,AHI_LFE
377 dd
->voices
[i
].params
[0].send_dcba
= 0x000000ff;
378 dd
->voices
[i
].params
[0].send_hgfe
= 0x00000000;
379 dd
->voices
[i
].params
[1].send_dcba
= 0x0000ff00;
380 dd
->voices
[i
].params
[1].send_hgfe
= 0x00000000;
382 dd
->voices
[i
].params
[0].send_routing
= dd
->voices
[i
].params
[1].send_routing
= routes
[i
];
383 dd
->voices
[i
].params
[0].send_routing2
= dd
->voices
[i
].params
[1].send_routing2
= 0x03020302;
385 /* dd->voices[i].params[0].send_dcba = 0x00ff00ff; */
386 /* dd->voices[i].params[0].send_hgfe = 0x00007f7f; */
387 /* dd->voices[i].params[1].send_dcba = 0xff00ff00; */
388 /* dd->voices[i].params[1].send_hgfe = 0x00007f7f; */
390 /* dd->voices[i].params[0].send_routing = dd->voices[i].params[1].send_routing = 0x03020100; */
391 /* dd->voices[i].params[0].send_routing2 = dd->voices[i].params[1].send_routing2 = 0x07060504; */
395 static int routes
[] = {
396 0x3210, // Send FL/FR to ??/??, AHI_FRONT_L/MULTI_FRONT_R
397 0x3254, // Send RL/RR to ??/??, AHI_REAR_L/AHI_REAR_R
398 0x3276, // Send SL/SR to ??/??, AHI_SURROUND_L/AHI_SURROUND_R
399 0x3298, // Send C/LFE to ??/??, AHI_CENTER,AHI_LFE
402 dd
->voices
[i
].params
[0].send_dcba
= 0x000000ff;
403 dd
->voices
[i
].params
[0].send_hgfe
= 0;
404 dd
->voices
[i
].params
[1].send_dcba
= 0x0000ff00;
405 dd
->voices
[i
].params
[1].send_hgfe
= 0;
407 dd
->voices
[i
].params
[0].send_routing
= dd
->voices
[i
].params
[1].send_routing
= routes
[i
];
408 dd
->voices
[i
].params
[0].send_routing2
= dd
->voices
[i
].params
[1].send_routing2
= 0;
411 dd
->voices
[i
].params
[1].volume_target
= 0xffff;
412 dd
->voices
[i
].params
[1].initial_fc
= 0xff;
413 dd
->voices
[i
].params
[1].initial_attn
= 0x00;
414 dd
->voices
[i
].params
[1].byampl_env_sustain
= 0x7f;
415 dd
->voices
[i
].params
[1].byampl_env_decay
= 0x7f;
419 if( dd
->card
.is_audigy
)
421 dd
->voices
[i
].params
[0].send_dcba
= 0xffffffff;
422 dd
->voices
[i
].params
[0].send_hgfe
= 0x0000ffff;
424 dd
->voices
[i
].params
[0].send_routing
= 0x03020100;
425 dd
->voices
[i
].params
[0].send_routing2
= 0x07060504;
429 dd
->voices
[i
].params
[0].send_dcba
= 0x000ffff;
430 dd
->voices
[i
].params
[0].send_hgfe
= 0;
432 dd
->voices
[i
].params
[0].send_routing
= 0x3210;
433 dd
->voices
[i
].params
[0].send_routing2
= 0;
437 DPD(2, "voice: startloop=%x, endloop=%x\n",
438 dd
->voice
.startloop
, dd
->voice
.endloop
);
440 emu10k1_voice_playback_setup( &dd
->voices
[i
] );
443 dd
->playback_interrupt_enabled
= TRUE
;
445 /* Enable timer interrupts (TIMER_INTERRUPT_FREQUENCY Hz) */
447 emu10k1_timer_set( &dd
->card
, 48000 / TIMER_INTERRUPT_FREQUENCY
);
448 emu10k1_irq_enable( &dd
->card
, INTE_INTERVALTIMERENB
);
450 emu10k1_voices_start( dd
->voices
, num_voices
, 0 );
452 dd
->voices_started
= num_voices
;
454 dd
->is_playing
= TRUE
;
457 if( flags
& AHISF_RECORD
)
460 /* Find out the recording frequency */
462 switch( AudioCtrl
->ahiac_MixFreq
)
465 adcctl
= ADCCR_SAMPLERATE_48
;
469 adcctl
= ADCCR_SAMPLERATE_44
;
473 adcctl
= ADCCR_SAMPLERATE_32
;
477 adcctl
= ADCCR_SAMPLERATE_24
;
481 adcctl
= ADCCR_SAMPLERATE_22
;
485 adcctl
= ADCCR_SAMPLERATE_16
;
489 adcctl
= ADCCR_SAMPLERATE_11
;
493 adcctl
= ADCCR_SAMPLERATE_8
;
500 if( dd
->card
.is_audigy
)
501 adcctl
|= A_ADCCR_LCHANENABLE
| A_ADCCR_RCHANENABLE
;
503 adcctl
|= ADCCR_LCHANENABLE
| ADCCR_RCHANENABLE
;
505 /* Allocate a new recording buffer (page aligned!) */
506 dd
->record_buffer
= pci_alloc_consistent( dd
->card
.pci_dev
,
507 RECORD_BUFFER_SAMPLES
* 4,
508 &dd
->record_dma_handle
);
510 if( dd
->record_buffer
== NULL
)
512 Req( "Unable to allocate %ld bytes for the recording buffer.",
513 RECORD_BUFFER_SAMPLES
* 4 );
517 SaveMixerState( dd
);
518 UpdateMonitorMixer( dd
);
521 // invalidate the whole record_buffer just to be on the safe side
522 CacheClearE( dd
->record_buffer
, RECORD_BUFFER_SAMPLES
* 4, CACRF_InvalidateD
);
525 sblive_writeptr( &dd
->card
, ADCBA
, 0, dd
->record_dma_handle
);
526 sblive_writeptr( &dd
->card
, ADCBS
, 0, RECORD_BUFFER_SIZE_VALUE
);
527 sblive_writeptr( &dd
->card
, ADCCR
, 0, adcctl
);
529 dd
->record_interrupt_enabled
= TRUE
;
531 /* Enable ADC interrupts */
533 emu10k1_irq_enable( &dd
->card
, INTE_ADCBUFENABLE
);
535 dd
->is_recording
= TRUE
;
542 /******************************************************************************
543 ** AHIsub_Update **************************************************************
544 ******************************************************************************/
547 _AHIsub_Update( ULONG flags
,
548 struct AHIAudioCtrlDrv
* AudioCtrl
,
549 struct DriverBase
* AHIsubBase
)
551 struct EMU10kxData
* dd
= (struct EMU10kxData
*) AudioCtrl
->ahiac_DriverData
;
553 dd
->current_length
= AudioCtrl
->ahiac_BuffSamples
;
555 if( AudioCtrl
->ahiac_Flags
& AHIACF_STEREO
)
557 dd
->current_size
= dd
->current_length
* 4;
561 dd
->current_size
= dd
->current_length
* 2;
566 /******************************************************************************
567 ** AHIsub_Stop ****************************************************************
568 ******************************************************************************/
571 _AHIsub_Stop( ULONG flags
,
572 struct AHIAudioCtrlDrv
* AudioCtrl
,
573 struct DriverBase
* AHIsubBase
)
575 struct EMU10kxData
* dd
= (struct EMU10kxData
*) AudioCtrl
->ahiac_DriverData
;
577 if( flags
& AHISF_PLAY
)
580 dd
->is_playing
= FALSE
;
582 if( dd
->voices_started
!= 0 )
584 emu10k1_irq_disable( &dd
->card
, INTE_INTERVALTIMERENB
);
586 // sblive_writeptr( &dd->card, CLIEL, dd->voice.num, 0 );
587 emu10k1_voices_stop( dd
->voices
, dd
->voices_started
);
588 dd
->voices_started
= 0;
591 for( i
= 0; i
< dd
->voices_allocated
; ++i
)
593 emu10k1_voice_free( &dd
->voices
[i
] );
596 dd
->voices_allocated
= 0;
598 for( i
= 0; i
< dd
->voice_buffers_allocated
; ++i
)
600 emu10k1_voice_free_buffer( &dd
->card
, &dd
->voices
[i
].mem
);
603 dd
->voice_buffers_allocated
= 0;
605 memset( &dd
->voices
, 0, sizeof( dd
->voices
) );
607 dd
->current_length
= 0;
608 dd
->current_size
= 0;
609 dd
->current_buffers
[0] = NULL
;
610 dd
->current_buffers
[1] = NULL
;
611 dd
->current_buffers
[2] = NULL
;
612 dd
->current_buffers
[3] = NULL
;
613 dd
->current_position
= 0;
615 FreeVec( dd
->mix_buffer
);
616 dd
->mix_buffer
= NULL
;
619 if( flags
& AHISF_RECORD
)
621 emu10k1_irq_disable( &dd
->card
, INTE_ADCBUFENABLE
);
623 sblive_writeptr( &dd
->card
, ADCCR
, 0, 0 );
624 sblive_writeptr( &dd
->card
, ADCBS
, 0, ADCBS_BUFSIZE_NONE
);
626 if( dd
->is_recording
)
628 // Do not restore mixer unless they have been saved
629 RestoreMixerState( dd
);
632 if( dd
->record_buffer
!= NULL
)
634 pci_free_consistent( dd
->card
.pci_dev
,
635 RECORD_BUFFER_SAMPLES
* 4,
637 dd
->record_dma_handle
);
640 dd
->record_buffer
= NULL
;
641 dd
->record_dma_handle
= 0;
643 dd
->is_recording
= FALSE
;
648 /******************************************************************************
649 ** AHIsub_GetAttr *************************************************************
650 ******************************************************************************/
653 _AHIsub_GetAttr( ULONG attribute
,
656 struct TagItem
* taglist
,
657 struct AHIAudioCtrlDrv
* AudioCtrl
,
658 struct DriverBase
* AHIsubBase
)
667 case AHIDB_Frequencies
:
670 case AHIDB_Frequency
: // Index->Frequency
671 return (LONG
) Frequencies
[ argument
];
673 case AHIDB_Index
: // Frequency->Index
674 if( argument
<= (LONG
) Frequencies
[ 0 ] )
679 if( argument
>= (LONG
) Frequencies
[ FREQUENCIES
- 1 ] )
681 return FREQUENCIES
-1;
684 for( i
= 1; i
< FREQUENCIES
; i
++ )
686 if( (LONG
) Frequencies
[ i
] > argument
)
688 if( ( argument
- (LONG
) Frequencies
[ i
- 1 ] )
689 < ( (LONG
) Frequencies
[ i
] - argument
) )
700 return 0; // Will not happen
703 return (IPTR
) "Martin 'Leviticus' Blom, Bertrand Lee et al.";
705 case AHIDB_Copyright
:
706 return (IPTR
) "GNU GPL";
709 return (IPTR
) LibIDString
;
711 case AHIDB_Annotation
:
713 "Funded by Hyperion Entertainment. Based on the Linux driver.";
718 case AHIDB_FullDuplex
:
724 case AHIDB_MaxRecordSamples
:
725 return RECORD_BUFFER_SAMPLES
/ 2;
727 case AHIDB_MinMonitorVolume
:
730 case AHIDB_MaxMonitorVolume
:
733 case AHIDB_MinInputGain
:
736 case AHIDB_MaxInputGain
:
739 case AHIDB_MinOutputVolume
:
742 case AHIDB_MaxOutputVolume
:
749 return (IPTR
) Inputs
[ argument
];
755 return (IPTR
) Outputs
[ argument
];
763 /******************************************************************************
764 ** AHIsub_HardwareControl *****************************************************
765 ******************************************************************************/
768 _AHIsub_HardwareControl( ULONG attribute
,
770 struct AHIAudioCtrlDrv
* AudioCtrl
,
771 struct DriverBase
* AHIsubBase
)
773 struct EMU10kxData
* dd
= (struct EMU10kxData
*) AudioCtrl
->ahiac_DriverData
;
777 case AHIC_MonitorVolume
:
778 dd
->monitor_volume
= Linear2MixerGain( (Fixed
) argument
,
779 &dd
->monitor_volume_bits
);
780 if( dd
->is_recording
)
782 UpdateMonitorMixer( dd
);
786 case AHIC_MonitorVolume_Query
:
787 return dd
->monitor_volume
;
790 dd
->input_gain
= Linear2RecordGain( (Fixed
) argument
,
791 &dd
->input_gain_bits
);
792 emu10k1_writeac97( &dd
->card
, AC97_RECORD_GAIN
, dd
->input_gain_bits
);
795 case AHIC_InputGain_Query
:
796 return dd
->input_gain
;
798 case AHIC_OutputVolume
:
799 dd
->output_volume
= Linear2MixerGain( (Fixed
) argument
,
800 &dd
->output_volume_bits
);
801 emu10k1_writeac97( &dd
->card
, AC97_PCMOUT_VOL
, dd
->output_volume_bits
);
804 case AHIC_OutputVolume_Query
:
805 return dd
->output_volume
;
808 dd
->input
= argument
;
809 emu10k1_writeac97( &dd
->card
, AC97_RECORD_SELECT
, InputBits
[ dd
->input
] );
811 if( dd
->is_recording
)
813 UpdateMonitorMixer( dd
);
818 case AHIC_Input_Query
:
822 dd
->output
= argument
;
824 if( dd
->output
== 0 )
826 emu10k1_set_volume_gpr( &dd
->card
, VOL_FRONT_REAR_L
, 0, VOL_5BIT
);
827 emu10k1_set_volume_gpr( &dd
->card
, VOL_FRONT_REAR_R
, 0, VOL_5BIT
);
831 emu10k1_set_volume_gpr( &dd
->card
, VOL_FRONT_REAR_L
, 100, VOL_5BIT
);
832 emu10k1_set_volume_gpr( &dd
->card
, VOL_FRONT_REAR_R
, 100, VOL_5BIT
);
836 case AHIC_Output_Query
: