Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Drivers / CMI8738 / cmi8738.c
blob8bd919a6b8e74189b713c796b2eaa4f3eec208c8
1 /*
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.
12 //#include <config.h>
14 #if !defined(__AROS__)
15 #undef __USE_INLINE__
16 #include <proto/expansion.h>
17 #endif
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>
28 #ifdef __AROS__
29 #define DEBUG 1
30 #include <aros/debug.h>
31 #define DebugPrintF bug
32 #endif
33 #include <math.h>
34 #include <string.h>
36 #include "library.h"
37 #include "regs.h"
38 #include "misc.h"
39 #include "pci_wrapper.h"
41 extern int z;
43 /******************************************************************************
44 ** Globals ********************************************************************
45 ******************************************************************************/
47 #define FREQUENCIES 8
49 static const ULONG Frequencies[ FREQUENCIES ] =
51 5512,
52 8000, // ยต- and A-Law
53 11025, // CD/4
54 16000, // DAT/3
55 22050, // CD/2
56 32000, // DAT/1.5
57 44100, // CD
58 48000 // DAT
61 static const ULONG FrequencyBits[ FREQUENCIES ] =
73 #define INPUTS 5
75 static const STRPTR Inputs[ INPUTS ] =
77 "Line in",
78 "Mic",
79 "CD",
80 "Aux",
81 "S/PDIF"
84 #if 0
85 /* Not static since it's used in misc.c too */
86 const UWORD InputBits[ INPUTS ] =
88 AC97_RECMUX_LINE,
89 AC97_RECMUX_MIC,
90 AC97_RECMUX_CD,
91 AC97_RECMUX_VIDEO,
92 AC97_RECMUX_AUX,
93 AC97_RECMUX_STEREO_MIX,
94 AC97_RECMUX_MONO_MIX,
95 AC97_RECMUX_PHONE
97 #endif
99 #define OUTPUTS 2
101 static const STRPTR Outputs[ OUTPUTS ] =
103 "Line Out",
104 "Digital Out"
107 /******************************************************************************
108 ** AHIsub_AllocAudio **********************************************************
109 ******************************************************************************/
111 ULONG
112 _AHIsub_AllocAudio( struct TagItem* taglist,
113 struct AHIAudioCtrlDrv* AudioCtrl,
114 struct DriverBase* AHIsubBase )
116 struct CMI8738Base* CMI8738Base = (struct CMI8738Base*) AHIsubBase;
118 int card_num;
119 ULONG ret;
120 int i;
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 );
131 return AHISF_ERROR;
133 else
135 struct CMI8738_DATA* card;
136 BOOL in_use;
138 card = CMI8738Base->driverdatas[ card_num ];
139 AudioCtrl->ahiac_DriverData = card;
141 ObtainSemaphore( &CMI8738Base->semaphore );
142 in_use = ( card->audioctrl != NULL );
143 if( !in_use )
145 card->audioctrl = AudioCtrl;
147 ReleaseSemaphore( &CMI8738Base->semaphore );
149 if( in_use )
151 return AHISF_ERROR;
154 card->playback_interrupt_enabled = FALSE;
155 card->record_interrupt_enabled = FALSE;
158 ret = AHISF_KNOWHIFI | AHISF_KNOWSTEREO | AHISF_MIXING | AHISF_TIMING;
160 for( i = 0; i < FREQUENCIES; ++i )
162 if( AudioCtrl->ahiac_MixFreq == Frequencies[ i ] )
164 ret |= AHISF_CANRECORD;
165 break;
169 return ret;
174 /******************************************************************************
175 ** AHIsub_FreeAudio ***********************************************************
176 ******************************************************************************/
178 void
179 _AHIsub_FreeAudio( struct AHIAudioCtrlDrv* AudioCtrl,
180 struct DriverBase* AHIsubBase )
182 struct CMI8738Base* CMI8738Base = (struct CMI8738Base*) AHIsubBase;
183 struct CMI8738_DATA* card = (struct CMI8738_DATA*) AudioCtrl->ahiac_DriverData;
185 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__);
187 if( card != NULL )
189 ObtainSemaphore( &CMI8738Base->semaphore );
190 if( card->audioctrl == AudioCtrl )
192 // Release it if we own it.
193 card->audioctrl = NULL;
195 ReleaseSemaphore( &CMI8738Base->semaphore );
197 AudioCtrl->ahiac_DriverData = NULL;
202 /******************************************************************************
203 ** AHIsub_Disable *************************************************************
204 ******************************************************************************/
206 void
207 _AHIsub_Disable( struct AHIAudioCtrlDrv* AudioCtrl,
208 struct DriverBase* AHIsubBase )
210 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__);
212 // V6 drivers do not have to preserve all registers
214 Disable();
218 /******************************************************************************
219 ** AHIsub_Enable **************************************************************
220 ******************************************************************************/
222 void
223 _AHIsub_Enable( struct AHIAudioCtrlDrv* AudioCtrl,
224 struct DriverBase* AHIsubBase )
226 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__);
228 // V6 drivers do not have to preserve all registers
230 Enable();
234 /******************************************************************************
235 ** AHIsub_Start ***************************************************************
236 ******************************************************************************/
238 ULONG
239 _AHIsub_Start( ULONG flags,
240 struct AHIAudioCtrlDrv* AudioCtrl,
241 struct DriverBase* AHIsubBase )
243 #if !defined(__AROS__)
244 struct CMI8738Base* CMI8738Base = (struct CMI8738Base*) AHIsubBase;
245 APTR stack;
246 #endif
247 struct CMI8738_DATA* card = (struct CMI8738_DATA*) AudioCtrl->ahiac_DriverData;
248 struct PCIDevice *dev = card->pci_dev;
249 ULONG dma_buffer_size = 0;
250 int i, freqbit = 6;
252 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__);
254 /* Stop playback/recording, free old buffers (if any) */
255 //IAHIsub->AHIsub_Stop( flags, AudioCtrl );
257 for( i = 0; i < FREQUENCIES; ++i )
259 if( AudioCtrl->ahiac_MixFreq == Frequencies[ i ] )
261 freqbit = i;
262 break;
266 card->mixerstate = cmimix_rd(dev, card, CMPCI_SB16_MIXER_OUTMIX);
268 if( flags & AHISF_PLAY )
270 ULONG dma_sample_frame_size;
271 unsigned short ChannelsFlag = CMPCI_REG_FORMAT_16BIT;
273 //WriteMask(dev, card, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET | CMPCI_REG_CH1_RESET);
274 //ClearMask(dev, card, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET | CMPCI_REG_CH1_RESET);
276 /* Allocate a new mixing buffer. Note: The buffer must be cleared, since
277 it might not be filled by the mixer software interrupt because of
278 pretimer/posttimer! */
280 card->mix_buffer = AllocVec( AudioCtrl->ahiac_BuffSize, MEMF_PUBLIC | MEMF_CLEAR );
282 if( card->mix_buffer == NULL )
284 Req( "Unable to allocate %ld bytes for mixing buffer.", AudioCtrl->ahiac_BuffSize );
285 return AHIE_NOMEM;
288 /* Allocate a buffer large enough for 16-bit double-buffered
289 playback (mono or stereo) */
291 if( AudioCtrl->ahiac_Flags & AHIACF_STEREO )
293 dma_sample_frame_size = 4;
294 dma_buffer_size = AudioCtrl->ahiac_MaxBuffSamples * dma_sample_frame_size;
295 ChannelsFlag |= CMPCI_REG_FORMAT_STEREO;
297 else
299 dma_sample_frame_size = 2;
300 dma_buffer_size = AudioCtrl->ahiac_MaxBuffSamples * dma_sample_frame_size;
303 //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);
305 card->playback_buffer = pci_alloc_consistent(dma_buffer_size * 2, &card->playback_buffer_nonaligned, 128);
307 if (!card->playback_buffer)
309 Req( "Unable to allocate playback buffer." );
310 return AHIE_NOMEM;
313 card->current_bytesize = dma_buffer_size;
314 card->current_frames = AudioCtrl->ahiac_MaxBuffSamples;
315 card->current_buffer = card->playback_buffer + card->current_bytesize;
316 card->playback_interrupt_enabled = TRUE;
318 card->flip = 0;
319 card->oldflip = 0;
321 WritePartialMask(dev, card, CMPCI_REG_FUNC_1, CMPCI_REG_DAC_FS_SHIFT, CMPCI_REG_DAC_FS_MASK, FrequencyBits[freqbit]);
322 WritePartialMask(dev, card, CMPCI_REG_CHANNEL_FORMAT, CMPCI_REG_CH0_FORMAT_SHIFT, CMPCI_REG_CH0_FORMAT_MASK, ChannelsFlag);
323 WriteMask(dev, card, CMPCI_REG_CHANNEL_FORMAT, (13 << 1));
325 #if !defined(__AROS__)
326 if (IFakeDMA == NULL)
328 stack = SuperState();
329 card->playback_buffer_phys = IMMU->GetPhysicalAddress(card->playback_buffer);
330 UserState(stack);
332 else
333 #endif
334 card->playback_buffer_phys = card->playback_buffer;
336 bug("[CMI8738] %s: Playback buffer @ 0x%p\n", __PRETTY_FUNCTION__, card->playback_buffer);
338 pci_outl((ULONG)card->playback_buffer_phys, CMPCI_REG_DMA0_BASE, card);
339 pci_outw((dma_buffer_size / dma_sample_frame_size) * 2 - 1, CMPCI_REG_DMA0_LENGTH, card);
340 pci_outw((dma_buffer_size / dma_sample_frame_size) - 1, CMPCI_REG_DMA0_INTLEN, card);
342 card->is_playing = TRUE;
345 if( flags & AHISF_RECORD )
347 unsigned char byte;
349 card->current_record_bytesize = RECORD_BUFFER_SAMPLES * 4;
351 /* Allocate a new recording buffer (page aligned!) */
352 card->record_buffer = pci_alloc_consistent(card->current_record_bytesize * 2, &card->record_buffer_nonaligned, 128);
354 if( card->record_buffer == NULL )
356 Req( "Unable to allocate %ld bytes for the recording buffer.", card->current_record_bytesize, 128);
357 return AHIE_NOMEM;
360 SaveMixerState( card );
361 UpdateMonitorMixer( card );
363 switch (card->input)
365 case 0: // line
366 cmimix_wr(dev, card, CMPCI_SB16_MIXER_OUTMIX, card->mixerstate | CMPCI_SB16_SW_LINE);
367 break;
369 case 1: // mic
370 cmimix_wr(dev, card, CMPCI_SB16_MIXER_OUTMIX, card->mixerstate | CMPCI_SB16_SW_MIC);
371 break;
373 case 2: // CD
374 cmimix_wr(dev, card, CMPCI_SB16_MIXER_OUTMIX, card->mixerstate | CMPCI_SB16_SW_CD);
375 break;
377 case 3: // Aux
378 byte = pci_inb(CMPCI_REG_MIXER25, card);
379 byte |= 0x30;
380 pci_outb(byte, CMPCI_REG_MIXER25, card); // unmute Aux
381 break;
383 default:
384 break;
387 card->record_interrupt_enabled = TRUE;
389 card->recflip = 0;
391 WritePartialMask(dev, card, CMPCI_REG_FUNC_1, CMPCI_REG_ADC_FS_SHIFT, CMPCI_REG_ADC_FS_MASK, FrequencyBits[freqbit]);
392 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);
394 #if !defined(__AROS__)
395 if (IFakeDMA == NULL)
397 stack = SuperState();
398 card->record_buffer_phys = IMMU->GetPhysicalAddress(card->record_buffer);
399 UserState(stack);
401 else
402 #endif
403 card->record_buffer_phys = card->record_buffer;
405 pci_outl((ULONG)card->record_buffer_phys, CMPCI_REG_DMA1_BASE, card);
406 udelay(1);
407 pci_outw((card->current_record_bytesize / 4) * 2 - 1, CMPCI_REG_DMA1_LENGTH, card);
408 udelay(1);
409 pci_outw((card->current_record_bytesize / 4) - 1, CMPCI_REG_DMA1_INTLEN, card);
410 udelay(1);
411 card->current_record_buffer = card->record_buffer + card->current_record_bytesize;
412 card->is_recording = TRUE;
415 if( flags & AHISF_PLAY )
417 z = 0;
418 WriteMask(dev, card, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE);
419 WriteMask(dev, card, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE);
422 if( flags & AHISF_RECORD )
424 WriteMask(dev, card, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
425 WriteMask(dev, card, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
428 return AHIE_OK;
432 /******************************************************************************
433 ** AHIsub_Update **************************************************************
434 ******************************************************************************/
436 void
437 _AHIsub_Update( ULONG flags,
438 struct AHIAudioCtrlDrv* AudioCtrl,
439 struct DriverBase* AHIsubBase )
441 #if 0
442 struct CMI8738_DATA* card = (struct CMI8738_DATA*) AudioCtrl->ahiac_DriverData;
443 #endif
445 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__);
447 #if 0
448 card->current_frames = AudioCtrl->ahiac_BuffSamples;
450 if( AudioCtrl->ahiac_Flags & AHIACF_STEREO )
452 card->current_bytesize = card->current_frames * 4;
454 else
456 card->current_bytesize = card->current_frames * 2;
458 #endif
462 /******************************************************************************
463 ** AHIsub_Stop ****************************************************************
464 ******************************************************************************/
466 void
467 _AHIsub_Stop( ULONG flags,
468 struct AHIAudioCtrlDrv* AudioCtrl,
469 struct DriverBase* AHIsubBase )
471 struct CMI8738_DATA* card = (struct CMI8738_DATA*) AudioCtrl->ahiac_DriverData;
472 struct PCIDevice *dev = card->pci_dev;
474 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__);
476 if( flags & AHISF_PLAY )
478 card->is_playing= FALSE;
480 ClearMask(dev, card, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE);
481 ClearMask(dev, card, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE);
483 if (card->current_bytesize > 0)
484 pci_free_consistent(card->playback_buffer_nonaligned);
486 card->current_bytesize = 0;
487 card->current_frames = 0;
488 card->current_buffer = NULL;
490 if ( card->mix_buffer)
491 FreeVec( card->mix_buffer );
493 card->mix_buffer = NULL;
494 card->playback_interrupt_enabled = FALSE;
495 card->current_bytesize = 0;
496 //DebugPrintF("#IRQ's = %ld\n", z);
499 if( flags & AHISF_RECORD && card->is_recording)
501 unsigned char byte;
503 ClearMask(dev, card, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
504 ClearMask(dev, card, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE);
506 switch (card->input)
508 case 0: // line
509 cmimix_wr(dev, card, CMPCI_SB16_MIXER_OUTMIX, card->mixerstate);
510 break;
512 case 1: // mic
513 cmimix_wr(dev, card, CMPCI_SB16_MIXER_OUTMIX, card->mixerstate);
514 break;
516 case 2: // CD
517 cmimix_wr(dev, card, CMPCI_SB16_MIXER_OUTMIX, card->mixerstate);
518 break;
520 case 3: // Aux
521 byte = pci_inb(CMPCI_REG_MIXER25, card);
522 pci_outb(byte & ~0x30, CMPCI_REG_MIXER25, card); // mute Aux
523 break;
525 default:
526 break;
529 if( card->record_buffer != NULL )
531 pci_free_consistent( card->record_buffer_nonaligned);
534 card->record_buffer = NULL;
535 card->current_record_bytesize = 0;
537 card->is_recording = FALSE;
538 card->record_interrupt_enabled = FALSE;
543 /******************************************************************************
544 ** AHIsub_GetAttr *************************************************************
545 ******************************************************************************/
547 LONG
548 _AHIsub_GetAttr( ULONG attribute,
549 LONG argument,
550 LONG def,
551 struct TagItem* taglist,
552 struct AHIAudioCtrlDrv* AudioCtrl,
553 struct DriverBase* AHIsubBase )
555 struct CMI8738Base* CMI8738Base = (struct CMI8738Base*) AHIsubBase;
556 int i;
558 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__);
560 struct CMI8738_DATA* card = (struct CMI8738_DATA*) AudioCtrl->ahiac_DriverData;
561 if (card == NULL)
563 int card_num = ( GetTagData( AHIDB_AudioID, 0, taglist) & 0x0000f000 ) >> 12;
565 if( card_num <= CMI8738Base->cards_found ||
566 CMI8738Base->driverdatas[ card_num ] != NULL )
567 card = CMI8738Base->driverdatas[ card_num ];
569 bug("[CMI8738] %s: card data @ 0x%p\n", __PRETTY_FUNCTION__, card);
571 switch( attribute )
573 case AHIDB_Bits:
574 return 16;
576 case AHIDB_MaxChannels:
577 if (card)
578 return card->channels;
579 return 2;
581 case AHIDB_Frequencies:
582 return FREQUENCIES;
584 case AHIDB_Frequency: // Index->Frequency
585 return (LONG) Frequencies[ argument ];
587 case AHIDB_Index: // Frequency->Index
588 if( argument <= (LONG) Frequencies[ 0 ] )
590 return 0;
593 if( argument >= (LONG) Frequencies[ FREQUENCIES - 1 ] )
595 return FREQUENCIES-1;
598 for( i = 1; i < FREQUENCIES; i++ )
600 if( (LONG) Frequencies[ i ] > argument )
602 if( ( argument - (LONG) Frequencies[ i - 1 ] ) < ( (LONG) Frequencies[ i ] - argument ) )
604 return i-1;
606 else
608 return i;
613 return 0; // Will not happen
615 case AHIDB_Author:
616 return (LONG) "Davy Wentzler";
618 case AHIDB_Copyright:
619 return (LONG) "(C) 2011 The AROS Dev Team";
621 case AHIDB_Version:
622 return (LONG) LibIDString;
624 case AHIDB_Annotation:
625 return (LONG) "AROS CMI8738 Audio driver";
627 case AHIDB_Record:
628 return TRUE;
630 case AHIDB_FullDuplex:
631 return TRUE;
633 case AHIDB_Realtime:
634 return TRUE;
636 case AHIDB_MaxRecordSamples:
637 return RECORD_BUFFER_SAMPLES;
639 /* formula's:
640 #include <math.h>
642 unsigned long res = (unsigned long) (0x10000 * pow (10.0, dB / 20.0));
643 double dB = 20.0 * log10(0xVALUE / 65536.0);
645 printf("dB = %f, res = %lx\n", dB, res);*/
647 case AHIDB_MinMonitorVolume:
648 return 0x00000;
650 case AHIDB_MaxMonitorVolume:
651 return 0x00000;
653 case AHIDB_MinInputGain:
654 return 0x10000; // 0.0 dB gain
656 case AHIDB_MaxInputGain:
657 return 0x10000; // 0 dB gain
659 case AHIDB_MinOutputVolume:
660 return 0x34; // -62 dB
662 case AHIDB_MaxOutputVolume:
663 return 0x10000; // 0 dB
665 case AHIDB_Inputs:
666 return INPUTS;
668 case AHIDB_Input:
669 return (LONG) Inputs[ argument ];
671 case AHIDB_Outputs:
672 return OUTPUTS;
674 case AHIDB_Output:
675 return (LONG) Outputs[ argument ];
677 default:
678 return def;
683 /******************************************************************************
684 ** AHIsub_HardwareControl *****************************************************
685 ******************************************************************************/
687 ULONG
688 _AHIsub_HardwareControl( ULONG attribute,
689 LONG argument,
690 struct AHIAudioCtrlDrv* AudioCtrl,
691 struct DriverBase* AHIsubBase )
693 struct CMI8738_DATA* card = (struct CMI8738_DATA*) AudioCtrl->ahiac_DriverData;
694 struct PCIDevice *dev = card->pci_dev;
695 unsigned char byte;
697 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__);
699 switch( attribute )
701 case AHIC_MonitorVolume:
702 card->monitor_volume = Linear2MixerGain( (Fixed) argument, &card->monitor_volume_bits );
703 //DebugPrintF("card->monitor_volume = %lu, %lx\n", card->monitor_volume, card->monitor_volume);
704 if( card->is_recording )
706 UpdateMonitorMixer( card );
708 return TRUE;
710 case AHIC_MonitorVolume_Query:
711 return card->monitor_volume;
713 case AHIC_InputGain:
714 card->input_gain = Linear2RecordGain( (Fixed) argument, &card->input_gain_bits );
715 //codec_write(card, AC97_RECORD_GAIN, card->input_gain_bits );
716 return TRUE;
718 case AHIC_InputGain_Query:
719 return card->input_gain;
721 case AHIC_OutputVolume:
723 double dB = 20.0 * log10((Fixed) argument / 65536.0);
724 unsigned int val = 0xFF - ( ((unsigned int)(-dB/2)) << 3);
725 cmimix_wr(dev, card, 0x30, val);
726 cmimix_wr(dev, card, 0x31, val);
727 return TRUE;
729 case AHIC_OutputVolume_Query:
730 return card->output_volume;
732 case AHIC_Input:
733 card->input = argument;
735 switch (card->input)
737 case 0: // line
738 cmimix_wr(dev, card, CMPCI_SB16_MIXER_ADCMIX_L, (CMPCI_SB16_MIXER_LINE_SRC_R << 1) );
739 cmimix_wr(dev, card, CMPCI_SB16_MIXER_ADCMIX_R, CMPCI_SB16_MIXER_LINE_SRC_R );
740 break;
742 case 1: // mic
743 cmimix_wr(dev, card, CMPCI_SB16_MIXER_ADCMIX_L, CMPCI_SB16_MIXER_MIC_SRC);
744 cmimix_wr(dev, card, CMPCI_SB16_MIXER_ADCMIX_R, CMPCI_SB16_MIXER_MIC_SRC);
745 break;
747 case 2: // CD
748 cmimix_wr(dev, card, CMPCI_SB16_MIXER_ADCMIX_L, (CMPCI_SB16_MIXER_CD_SRC_R << 1) );
749 cmimix_wr(dev, card, CMPCI_SB16_MIXER_ADCMIX_R, CMPCI_SB16_MIXER_CD_SRC_R );
750 break;
752 case 3: // Aux
753 byte = pci_inb(CMPCI_REG_MIXER25, card);
754 pci_outb(byte | 0xC0, CMPCI_REG_MIXER25, card); // rec source Aux
755 break;
757 case 4: // SPDIF
759 break;
761 default:
762 break;
765 if( card->is_recording )
767 UpdateMonitorMixer( card );
770 return TRUE;
772 case AHIC_Input_Query:
773 return card->input;
775 case AHIC_Output:
776 card->output = argument;
778 if( card->output == 0 )
780 ClearMask(dev, card, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIFOUT_DAC | CMPCI_REG_SPDIF0_ENABLE);
781 ClearMask(dev, card, CMPCI_REG_LEGACY_CTRL, CMPCI_REG_XSPDIF_ENABLE);
783 else
785 WriteMask(dev, card, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIFOUT_DAC | CMPCI_REG_SPDIF0_ENABLE);
786 WriteMask(dev, card, CMPCI_REG_LEGACY_CTRL, CMPCI_REG_XSPDIF_ENABLE);
788 return TRUE;
790 case AHIC_Output_Query:
791 return card->output;
793 default:
794 return FALSE;