2 Copyright © 2005-2013, Davy Wentzler. All rights reserved.
7 #include "pci_wrapper.h"
11 #include <proto/expansion.h>
12 extern struct UtilityIFace
* IUtility
;
13 extern struct AHIsubIFace
* IAHIsub
;
14 extern struct MMUIFace
* IMMU
;
17 #include <devices/ahi.h>
18 #include <exec/memory.h>
19 #include <libraries/ahi_sub.h>
21 #include <proto/ahi_sub.h>
22 #include <proto/exec.h>
23 #include <proto/dos.h>
24 #include <proto/utility.h>
30 #include "library_card.h"
32 #include "library_mos.h"
38 #include "DriverData.h"
44 /******************************************************************************
45 ** Globals ********************************************************************
46 ******************************************************************************/
48 #define FREQUENCIES 15
50 static const ULONG Frequencies
[ FREQUENCIES
] =
69 static const ULONG FrequencyBits
[ FREQUENCIES
] =
85 14 // 176.4 KHz: only when CCS_SYSTEM_CONFIG:6 = 1 or (MT_I2S_FORMAT:MT_CLOCK_128x = 1 & CCS_SYSTEM_CONFIG:6 = 0)
89 #define SPDIF_FREQUENCIES 7
91 static const ULONG SPDIF_Frequencies
[ SPDIF_FREQUENCIES
] =
103 static const ULONG SPDIF_FrequencyBits
[ SPDIF_FREQUENCIES
] =
119 static const STRPTR Inputs
[ INPUTS
] __attribute__((used
)) =
131 "Digital in (16-bit)",
132 "Digital in (24-bit)"
135 #define INPUTS_PHASE28 4 // also for JULIA
136 static const STRPTR Inputs_Phase28
[ INPUTS_PHASE28
] __attribute__((used
)) =
140 "Digital in (16-bit)",
141 "Digital in (24-bit)"
145 #define INPUTS_REVO71 2
146 static const STRPTR Inputs_Revo71
[ INPUTS_REVO71
] __attribute__((used
)) =
152 #define INPUTS_REVO51 3
153 static const STRPTR Inputs_Revo51
[ INPUTS_REVO51
] __attribute__((used
)) =
163 static const STRPTR Outputs
[ OUTPUTS
] =
169 /******************************************************************************
170 ** AHIsub_AllocAudio **********************************************************
171 ******************************************************************************/
174 _AHIsub_AllocAudio( struct TagItem
* taglist
,
175 struct AHIAudioCtrlDrv
* AudioCtrl
,
176 struct DriverBase
* AHIsubBase
)
178 struct CardBase
* CardBase
= (struct CardBase
*) AHIsubBase
;
184 card_num
= ( GETTAGDATA( AHIDB_AudioID
, 0, taglist
) & 0x0000f000 ) >> 12;
186 if( card_num
>= CardBase
->cards_found
||
187 CardBase
->driverdatas
[ card_num
] == NULL
)
189 DEBUGPRINTF("no data for card = %ld\n", card_num
);
190 Req( "No CardData for card %ld.", card_num
);
195 struct CardData
* card
;
198 card
= CardBase
->driverdatas
[ card_num
];
199 AudioCtrl
->ahiac_DriverData
= card
;
201 OBTAINSEMAPHORE( &CardBase
->semaphore
);
202 in_use
= ( card
->audioctrl
!= NULL
);
205 card
->audioctrl
= AudioCtrl
;
207 RELEASESEMAPHORE( &CardBase
->semaphore
);
214 card
->playback_interrupt_enabled
= FALSE
;
215 card
->record_interrupt_enabled
= FALSE
;
218 ret
= AHISF_KNOWHIFI
| AHISF_KNOWSTEREO
| AHISF_MIXING
| AHISF_TIMING
;
221 for( i
= 0; i
< FREQUENCIES
; ++i
)
223 if( AudioCtrl
->ahiac_MixFreq
== Frequencies
[ i
] )
225 ret
|= AHISF_CANRECORD
;
235 /******************************************************************************
236 ** AHIsub_FreeAudio ***********************************************************
237 ******************************************************************************/
240 _AHIsub_FreeAudio( struct AHIAudioCtrlDrv
* AudioCtrl
,
241 struct DriverBase
* AHIsubBase
)
243 struct CardBase
* CardBase
= (struct CardBase
*) AHIsubBase
;
244 struct CardData
* card
= (struct CardData
*) AudioCtrl
->ahiac_DriverData
;
248 OBTAINSEMAPHORE( &CardBase
->semaphore
);
249 if( card
->audioctrl
== AudioCtrl
)
251 // Release it if we own it.
252 card
->audioctrl
= NULL
;
254 RELEASESEMAPHORE( &CardBase
->semaphore
);
256 AudioCtrl
->ahiac_DriverData
= NULL
;
261 /******************************************************************************
262 ** AHIsub_Disable *************************************************************
263 ******************************************************************************/
266 _AHIsub_Disable( struct AHIAudioCtrlDrv
* AudioCtrl
,
267 struct DriverBase
* AHIsubBase
)
269 // V6 drivers do not have to preserve all registers
279 /******************************************************************************
280 ** AHIsub_Enable **************************************************************
281 ******************************************************************************/
284 _AHIsub_Enable( struct AHIAudioCtrlDrv
* AudioCtrl
,
285 struct DriverBase
* AHIsubBase
)
287 // V6 drivers do not have to preserve all registers
298 /******************************************************************************
299 ** AHIsub_Start ***************************************************************
300 ******************************************************************************/
303 _AHIsub_Start( ULONG flags
,
304 struct AHIAudioCtrlDrv
* AudioCtrl
,
305 struct DriverBase
* AHIsubBase
)
307 struct CardData
* card
= (struct CardData
*) AudioCtrl
->ahiac_DriverData
;
308 ULONG dma_buffer_size
= 0;
311 unsigned char RMASK
= MT_RDMA0_MASK
;
316 /* Stop playback/recording, free old buffers (if any) */
317 //IAHIsub->AHIsub_Stop( flags, AudioCtrl );
319 for( i
= 0; i
< FREQUENCIES
; ++i
)
321 if( AudioCtrl
->ahiac_MixFreq
== Frequencies
[ i
] )
328 for( i
= 0; i
< SPDIF_FREQUENCIES
; ++i
)
330 if( AudioCtrl
->ahiac_MixFreq
== SPDIF_Frequencies
[ i
] )
337 OUTBYTE(card
->mtbase
+ MT_SAMPLERATE
, FrequencyBits
[freqbit
]);
338 OUTBYTE(card
->mtbase
+ MT_DMAI_BURSTSIZE
, 2); // set to stereo pair mode
341 if( flags
& AHISF_PLAY
)
344 ULONG dma_sample_frame_size
;
346 /* Allocate a new mixing buffer. Note: The buffer must be cleared, since
347 it might not be filled by the mixer software interrupt because of
348 pretimer/posttimer! */
350 card
->mix_buffer
= ALLOCVEC( AudioCtrl
->ahiac_BuffSize
, MEMF_PUBLIC
| MEMF_CLEAR
);
352 if( card
->mix_buffer
== NULL
)
354 Req( "Unable to allocate %ld bytes for mixing buffer.", AudioCtrl
->ahiac_BuffSize
);
358 /* Allocate a buffer large enough for 32-bit double-buffered playback (only stereo) */
360 dma_sample_frame_size
= 16; // we need 4-channel, otherwise the length can't be divided by 8
361 dma_buffer_size
= AudioCtrl
->ahiac_MaxBuffSamples
* dma_sample_frame_size
;
363 //DEBUGPRINTF("dma_buffer_size = %lu\n", dma_buffer_size);
365 /*if (dma_buffer_size != card->current_bytesize)
367 if (card->playback_buffer)
369 DEBUGPRINTF("Freeing prev buffer\n");
370 pci_free_consistent(card->playback_buffer_nonaligned);
373 card
->playback_buffer
= pci_alloc_consistent(dma_buffer_size
* 2, &card
->playback_buffer_nonaligned
, 4096);
374 card
->spdif_out_buffer
= pci_alloc_consistent(dma_buffer_size
, &card
->spdif_out_buffer_nonaligned
, 4096); // only stereo
376 if (!card
->playback_buffer
|| !card
->spdif_out_buffer
)
378 Req( "Unable to allocate playback buffer." );
382 ClearMask8(card
, card
->mtbase
, MT_DMA_CONTROL
, MT_PDMA0_START
| MT_PDMA4_START
); // stop
383 ClearMask8(card
, card
->mtbase
, MT_INTR_MASK
, MT_PDMA0_MASK
); // allow PDMA0 interrupts
385 card
->current_bytesize
= dma_buffer_size
;
386 card
->current_frames
= AudioCtrl
->ahiac_MaxBuffSamples
;
387 card
->current_buffer
= card
->playback_buffer
+ card
->current_bytesize
;
388 card
->spdif_out_current_buffer
= card
->spdif_out_buffer
+ card
->current_bytesize
/ 2;
389 card
->playback_interrupt_enabled
= TRUE
;
392 stack
= IExec
->SuperState();
393 card
->playback_buffer_phys
= IMMU
->GetPhysicalAddress(card
->playback_buffer
);
394 card
->spdif_out_buffer_phys
= IMMU
->GetPhysicalAddress(card
->spdif_out_buffer
);
395 IExec
->UserState(stack
);
397 card
->playback_buffer_phys
=
398 ahi_pci_logic_to_physic_addr(card
->playback_buffer
, card
->pci_dev
);
399 card
->spdif_out_buffer_phys
=
400 ahi_pci_logic_to_physic_addr(card
->spdif_out_buffer
, card
->pci_dev
);
402 card
->playback_buffer_phys
= card
->playback_buffer
;
403 card
->spdif_out_buffer_phys
= card
->spdif_out_buffer
; // if SPDIF were false, this pointer wouldn't get initialized, which might mean trouble in the IRQ
406 OUTLONG(card
->mtbase
+ MT_DMAI_PB_ADDRESS
,
407 (ULONG
)card
->playback_buffer_phys
);
409 //kprintf("card->playback_buffer_phys = %lx, virt = %lx\n", card->playback_buffer_phys, card->playback_buffer);
410 //DEBUGPRINTF("addr = %lx, %lx\n", card->playback_buffer_phys, INLONG(card->mtbase + MT_DMAI_PB_ADDRESS));
412 //DEBUGPRINTF("dmai length = %lu\n", (dma_buffer_size * 2) / 4 - 1);
413 OUTWORD(card
->mtbase
+ MT_DMAI_PB_LENGTH
, (dma_buffer_size
* 2) / 4 - 1);
414 OUTBYTE(card
->mtbase
+ MT_DMAI_PB_LENGTH
+ 2, 0);
415 OUTWORD(card
->mtbase
+ MT_DMAI_INTLEN
, (dma_buffer_size
* 1) / 4 - 1);
422 ClearMask8(card
, card
->iobase
, CCS_SPDIF_CONFIG
, CCS_SPDIF_INTEGRATED
); // disable: see doc: 4-27
424 OUTWORD(card
->mtbase
+ MT_SPDIF_TRANSMIT
, 0x04 | 1 << 5 | (FrequencyBits
[freqbit
] << 12)); // dig/dig converter
426 WriteMask8(card
, card
->iobase
, CCS_SPDIF_CONFIG
, CCS_SPDIF_INTEGRATED
); // enable
428 OUTLONG(card
->mtbase
+ MT_PDMA4_ADDRESS
,
429 (ULONG
)card
->spdif_out_buffer_phys
);
430 OUTWORD(card
->mtbase
+ MT_PDMA4_LENGTH
, (dma_buffer_size
) / 4 - 1);
431 OUTWORD(card
->mtbase
+ MT_PDMA4_INTLEN
, (dma_buffer_size
/ 2) / 4 - 1);
435 WriteMask8(card
, card
->mtbase
, MT_INTR_STATUS
, MT_DMA_FIFO
| MT_PDMA0
| MT_PDMA4
); // clear possibly pending interrupts
438 if( flags
& AHISF_RECORD
)
440 if ((card
->SubType
== PHASE28
&& card
->input
>= 2) ||
441 (card
->SubType
== JULIA
&& card
->input
>= 2) ||
442 (card
->SubType
== PHASE22
&& card
->input
>= 2) ||
443 (card
->SubType
!= AUREON_SKY
&& card
->input
>= 10)) { // digital in
444 //unsigned long GPIO;
446 RMASK
= MT_RDMA1_MASK
;
447 //GPIO = GetGPIOData(card, card->iobase);
448 //DEBUGPRINTF("%d %d %d\n", (GPIO & PHASE28_FREQ2) >> 16, (GPIO & PHASE28_FREQ1) >> 21, (GPIO & PHASE28_FREQ0) >> 22);
450 WriteMask8(card
, card
->mtbase
, MT_SAMPLERATE
, MT_SPDIF_MASTER
); // tbd!
453 card
->current_record_bytesize_32bit
= RECORD_BUFFER_SAMPLES
* 4 * 2; // 32-bit stereo
455 //DEBUGPRINTF("REC: current_record_bytesize = %ld\n", card->current_record_bytesize_32bit);
457 /* Allocate a new recording buffer (page aligned!) */
458 card
->record_buffer
= pci_alloc_consistent(card
->current_record_bytesize_32bit
, &card
->record_buffer_nonaligned
, 4096);
459 card
->record_buffer_32bit
= pci_alloc_consistent(card
->current_record_bytesize_32bit
* 2, &card
->record_buffer_nonaligned_32bit
, 4096);
461 if( card
->record_buffer
== NULL
|| card
->record_buffer_32bit
== NULL
)
463 Req( "Unable to allocate %ld bytes for the recording buffer.", card
->current_record_bytesize_32bit
);
467 SaveMixerState( card
);
468 UpdateMonitorMixer( card
);
471 ClearMask8(card
, card
->mtbase
, MT_DMA_CONTROL
, RMASK
); // stop
472 ClearMask8(card
, card
->mtbase
, MT_INTR_MASK
, RMASK
);
474 card
->current_record_buffer
= card
->record_buffer
+ card
->current_record_bytesize_32bit
/ 2;
475 card
->current_record_buffer_32bit
= card
->record_buffer_32bit
+ card
->current_record_bytesize_32bit
;
478 stack
= IExec
->SuperState();
479 card
->record_buffer_32bit_phys
= IMMU
->GetPhysicalAddress(card
->record_buffer_32bit
);
480 IExec
->UserState(stack
);
482 card
->record_buffer_32bit_phys
=
483 ahi_pci_logic_to_physic_addr(card
->record_buffer_32bit
, card
->pci_dev
);
485 card
->record_buffer_32bit_phys
= card
->record_buffer_32bit
;
488 if (RMASK
== MT_RDMA0_MASK
)
490 OUTLONG(card
->mtbase
+ MT_RDMA0_ADDRESS
, (long) card
->record_buffer_32bit_phys
);
491 OUTWORD(card
->mtbase
+ MT_RDMA0_LENGTH
, (card
->current_record_bytesize_32bit
* 2) / 4 - 1);
492 OUTWORD(card
->mtbase
+ MT_RDMA0_INTLEN
, (card
->current_record_bytesize_32bit
* 1) / 4 - 1);
497 OUTLONG(card
->mtbase
+ MT_RDMA1_ADDRESS
, (long) card
->record_buffer_32bit_phys
);
498 OUTWORD(card
->mtbase
+ MT_RDMA1_LENGTH
, (card
->current_record_bytesize_32bit
* 2) / 4 - 1);
499 OUTWORD(card
->mtbase
+ MT_RDMA1_INTLEN
, (card
->current_record_bytesize_32bit
* 1) / 4 - 1);
502 card
->record_interrupt_enabled
= TRUE
;
505 if (card
->SubType
== AUREON_SKY
|| card
->SubType
== AUREON_SPACE
|| card
->SubType
== PHASE28
)
506 wm_put(card
, card
->iobase
, 0x1C, 0x0D); // turn on zero-latency monitoring and PCM, disable AC97 mix
509 WriteMask8(card
, card
->mtbase
, MT_INTR_STATUS
, RMASK
);
512 if( flags
& AHISF_PLAY
)
514 unsigned char start
= MT_PDMA0_START
;
519 start
|= MT_PDMA4_START
;
522 card
->is_playing
= TRUE
;
524 //DEBUGPRINTF("START\n");
526 //DEBUGPRINTF("Config 4-5 = %x\n", READCONFIGWORD( PCI_COMMAND ));
527 // DEBUGPRINTF("BAR0 = %lx\n", dev->ReadConfigLong(0x10));
528 // DEBUGPRINTF("BAR1 = %lx\n", dev->ReadConfigLong(0x14));
530 /*for (i = 0; i <= 0x1F; i++)
532 DEBUGPRINTF("CCS %02d (%02x) = %x\n", i, i, INBYTE(card->iobase + i));
535 for (i = 0; i <= 0x76; i+=4)
537 DEBUGPRINTF("MT %02d (%02x) = %lx\n", i, i, INLONG(card->mtbase + i));
540 WriteMask8(card
, card
->mtbase
, MT_DMA_CONTROL
, start
);
543 if( flags
& AHISF_RECORD
)
545 card
->is_recording
= TRUE
;
546 WriteMask8(card
, card
->mtbase
, MT_DMA_CONTROL
, RMASK
);
553 /******************************************************************************
554 ** AHIsub_Update **************************************************************
555 ******************************************************************************/
558 _AHIsub_Update( ULONG flags
,
559 struct AHIAudioCtrlDrv
* AudioCtrl
,
560 struct DriverBase
* AHIsubBase
)
562 /*struct CardBase* CardBase = (struct CardBase*) AHIsubBase;
563 struct CardData* card = (struct CardData*) AudioCtrl->ahiac_DriverData;
565 card->current_frames = AudioCtrl->ahiac_BuffSamples;
567 if( AudioCtrl->ahiac_Flags & AHIACF_STEREO )
569 card->current_bytesize = card->current_frames * 4;
573 card->current_bytesize = card->current_frames * 2;
578 /******************************************************************************
579 ** AHIsub_Stop ****************************************************************
580 ******************************************************************************/
583 _AHIsub_Stop( ULONG flags
,
584 struct AHIAudioCtrlDrv
* AudioCtrl
,
585 struct DriverBase
* AHIsubBase
)
587 struct CardData
* card
= (struct CardData
*) AudioCtrl
->ahiac_DriverData
;
588 unsigned char RMASK
= MT_RDMA0_MASK
;
590 if( flags
& AHISF_PLAY
&& card
->is_playing
)
592 card
->is_playing
= FALSE
;
594 ClearMask8(card
, card
->mtbase
, MT_DMA_CONTROL
, MT_PDMA0_START
| MT_PDMA4_START
);
595 WriteMask8(card
, card
->mtbase
, MT_INTR_MASK
, MT_DMA_FIFO_MASK
| MT_PDMA0_MASK
);
597 if (card
->current_bytesize
> 0) {
598 pci_free_consistent(card
->playback_buffer_nonaligned
);
599 pci_free_consistent(card
->spdif_out_buffer_nonaligned
);
602 card
->current_bytesize
= 0;
603 card
->current_frames
= 0;
604 card
->current_buffer
= NULL
;
606 if (card
->mix_buffer
) {
607 FREEVEC( card
->mix_buffer
);
609 card
->mix_buffer
= NULL
;
610 card
->playback_interrupt_enabled
= FALSE
;
613 if( flags
& AHISF_RECORD
&& card
->is_recording
)
615 card
->is_recording
= FALSE
;
616 if ((card
->SubType
== PHASE28
&& card
->input
>= 2) ||
617 (card
->SubType
== JULIA
&& card
->input
>= 2) ||
618 (card
->SubType
!= PHASE28
&& card
->input
>= 10))
619 RMASK
= MT_RDMA1_MASK
;
621 ClearMask8(card
, card
->mtbase
, MT_DMA_CONTROL
, RMASK
);
622 WriteMask8(card
, card
->mtbase
, MT_INTR_MASK
, RMASK
);
624 if (card
->SubType
== AUREON_SKY
|| card
->SubType
== AUREON_SPACE
|| card
->SubType
== PHASE28
)
626 wm_put(card
, card
->iobase
, 0x1C, 0x0B); // turn off zero-latency monitoring: enable PCM and AC97 mix
631 if( card
->record_buffer
!= NULL
)
633 pci_free_consistent( card
->record_buffer_nonaligned
);
634 pci_free_consistent( card
->record_buffer_nonaligned_32bit
);
637 card
->record_buffer
= NULL
;
638 card
->current_record_bytesize_32bit
= 0;
639 card
->record_buffer_32bit
= NULL
;
640 card
->record_interrupt_enabled
= FALSE
;
646 /******************************************************************************
647 ** AHIsub_GetAttr *************************************************************
648 ******************************************************************************/
651 _AHIsub_GetAttr( ULONG attribute
,
654 struct TagItem
* taglist
,
655 struct AHIAudioCtrlDrv
* AudioCtrl
,
656 struct DriverBase
* AHIsubBase
)
658 struct CardBase
* CardBase
= (struct CardBase
*) AHIsubBase
;
659 struct CardData
* card
= CardBase
->driverdatas
[0]; // warning, don't take from AudioCtrl, since it is not always
660 // initialized before a call to GetAttr()!!!
668 case AHIDB_Frequencies
:
669 if (card
->SubType
== PHASE22
)
670 return FREQUENCIES
- 2;
674 case AHIDB_Frequency
: // Index->Frequency
675 return (LONG
) Frequencies
[ argument
];
677 case AHIDB_Index
: // Frequency->Index
678 if( argument
<= (LONG
) Frequencies
[ 0 ] )
683 if( argument
>= (LONG
) Frequencies
[ FREQUENCIES
- 1 ] )
685 return FREQUENCIES
-1;
688 for( i
= 1; i
< FREQUENCIES
; i
++ )
690 if( (LONG
) Frequencies
[ i
] > argument
)
692 if( ( argument
- (LONG
) Frequencies
[ i
- 1 ] ) < ( (LONG
) Frequencies
[ i
] - argument
) )
703 return 0; // Will not happen
706 return (LONG
) "Davy Wentzler";
708 case AHIDB_Copyright
:
709 return (LONG
) "(C) Davy Wentzler";
712 return (LONG
) LibIDString
;
714 case AHIDB_Annotation
:
716 "Terratec Aureon, Phase22/28, M-Audio Revolution 5.1/7.1 and ESI Juli@ driver";
721 case AHIDB_FullDuplex
:
727 case AHIDB_MaxRecordSamples
:
728 return RECORD_BUFFER_SAMPLES
;
733 unsigned long res = (unsigned long) (0x10000 * pow (10.0, dB / 20.0));
734 double dB = 20.0 * log10(0xVALUE / 65536.0);
736 printf("dB = %f, res = %lx\n", dB, res);*/
738 case AHIDB_MinMonitorVolume
:
739 if (card
->SubType
== REVO51
)
744 case AHIDB_MaxMonitorVolume
:
745 if (card
->SubType
== REVO51
)
750 case AHIDB_MinInputGain
:
751 if (card
->SubType
== REVO71
|| card
->SubType
== JULIA
|| card
->SubType
== PHASE22
)
753 else if (card
->SubType
== REVO51
)
756 return 0x404D; // -12 dB gain
758 case AHIDB_MaxInputGain
:
759 if (card
->SubType
== REVO71
|| card
->SubType
== JULIA
)
761 else if (card
->SubType
== REVO51
)
762 return 0x3FB27; // 12 dB
763 else if (card
->SubType
== PHASE22
)
766 return 0x8E99A; // 19 dB gain
768 case AHIDB_MinOutputVolume
:
769 if (card
->SubType
== PHASE22
)
772 return 0x00000; // -100 dB / mute
774 case AHIDB_MaxOutputVolume
:
775 return 0x10000; // 0 dB
778 if (card
->SubType
== PHASE28
|| card
->SubType
== JULIA
|| card
->SubType
== PHASE22
)
779 return INPUTS_PHASE28
;
780 else if (card
->SubType
== REVO71
)
781 return INPUTS_REVO71
;
782 else if (card
->SubType
== REVO51
)
783 return INPUTS_REVO51
;
788 if (card
->SubType
== PHASE28
|| card
->SubType
== JULIA
|| card
->SubType
== PHASE22
)
789 return (LONG
) Inputs_Phase28
[ argument
];
790 else if (card
->SubType
== REVO71
)
791 return (LONG
) Inputs_Revo71
[ argument
];
792 else if (card
->SubType
== REVO51
)
793 return (LONG
) Inputs_Revo51
[ argument
];
795 return (LONG
) Inputs
[ argument
];
801 return (LONG
) Outputs
[ argument
];
809 /******************************************************************************
810 ** AHIsub_HardwareControl *****************************************************
811 ******************************************************************************/
814 _AHIsub_HardwareControl( ULONG attribute
,
816 struct AHIAudioCtrlDrv
* AudioCtrl
,
817 struct DriverBase
* AHIsubBase
)
819 struct CardData
* card
= (struct CardData
*) AudioCtrl
->ahiac_DriverData
;
823 case AHIC_MonitorVolume
:
824 card
->monitor_volume
= 0;
826 if (card
->SubType
== REVO51
)
828 double dB
= 20.0 * log10((Fixed
) argument
/ 65536.0);
830 int offset
= card
->input
* 4; // left/right (10dB/1dB)
831 unsigned char bytes
[4];
833 int dB10
= -val
/ 10;
835 bytes
[0] = pt2258_db_codes
[offset
+ 0] | dB10
;
836 bytes
[1] = pt2258_db_codes
[offset
+ 1] | dB1
;
837 bytes
[2] = pt2258_db_codes
[offset
+ 2] | dB10
;
838 bytes
[3] = pt2258_db_codes
[offset
+ 3] | dB1
;
839 //DEBUGPRINTF("MON offset = %d, %x %x\n", offset, bytes[0], bytes[1]);
840 WriteBytesI2C(card
, card
->i2c
, bytes
, 4);
844 case AHIC_MonitorVolume_Query
:
845 return card
->monitor_volume
;
848 card
->input_gain
= Linear2RecordGain( (Fixed
) argument
, &card
->input_gain_bits
);
849 //DEBUGPRINTF("gain = %lx, bits = %x, argument = %lx\n", card->input_gain, card->input_gain_bits, argument);
851 if (card
->SubType
!= REVO71
&& card
->SubType
!= REVO51
&& card
->SubType
!= JULIA
&& card
->SubType
!= PHASE22
)
852 wm_put(card
, card
->iobase
, 0x19, card
->input_gain_bits
| 0x40); // | LRBOTH
854 else if (card
->SubType
== PHASE22
)
856 double dB
= 20.0 * log10((Fixed
) argument
/ 65536.0);
857 unsigned char val
= 128 + (int) (dB
* 2);
859 akm4xxx_write(card
, card
->RevoFrontCodec
, 0, 0x04, val
);
860 akm4xxx_write(card
, card
->RevoFrontCodec
, 0, 0x05, val
);
862 else if (card
->SubType
== REVO51
)
864 double dB
= 20.0 * log10((Fixed
) argument
/ 65536.0);
865 unsigned char val
= 0x80 + (int) (dB
* 2);
867 akm4xxx_write_new(card
, card
->RevoRecCodec
, 0, 0x04, val
);
868 akm4xxx_write_new(card
, card
->RevoRecCodec
, 0, 0x05, val
);
872 case AHIC_InputGain_Query
:
873 return card
->input_gain
;
875 case AHIC_OutputVolume
:
876 if (card
->SubType
!= REVO71
&& card
->SubType
!= REVO51
&& card
->SubType
!= JULIA
&& card
->SubType
!= PHASE22
) {
877 card
->output_volume
= Linear2MixerGain( (Fixed
) argument
, &card
->output_volume_bits
);
879 //DEBUGPRINTF("AHI: output %x\n", card->output_volume_bits);
881 wm_put(card
, card
->iobase
, 9, card
->output_volume_bits
| 0x100); // | update on all channels
882 wm_put(card
, card
->iobase
, 10, card
->output_volume_bits
| 0x100);
884 else if (card
->SubType
== REVO71
|| card
->SubType
== REVO51
) {
885 double dB
= 20.0 * log10((Fixed
) argument
/ 65536.0);
886 unsigned int val
= (unsigned int) (255.0 * pow(10.0, dB
/ 20.0));
888 card
->output_volume
= Linear2AKMGain( (Fixed
) argument
, &card
->output_volume_bits
);
890 if (card
->SubType
== REVO71
)
892 akm4xxx_write(card
, card
->RevoFrontCodec
, 0, 0x03, val
);
893 akm4xxx_write(card
, card
->RevoFrontCodec
, 0, 0x04, val
);
895 akm4xxx_write(card
, card
->RevoSurroundCodec
, 0, 0x04, card
->output_volume_bits
);
896 akm4xxx_write(card
, card
->RevoSurroundCodec
, 0, 0x05, card
->output_volume_bits
);
903 if (argument
== 0) // prevent overflow
905 dB
= -20.0 * log10((Fixed
) argument
/ 65536.0);
910 val
= 0x80 | (0x7F - (unsigned int)(dB
* 2));
912 //DEBUGPRINTF("arg = %ld, val = %lu, dB = %d\n", argument, val, (int) dB);
914 akm4xxx_write_new(card
, card
->RevoFrontCodec
, 0, 0x04, val
);
915 akm4xxx_write_new(card
, card
->RevoFrontCodec
, 0, 0x05, val
);
919 else if (card
->SubType
== JULIA
) {
920 double dB
= -20.0 * log10((Fixed
) argument
/ 65536.0);
921 unsigned int val
= 0x80 | (0x7F - (unsigned int)(dB
* 2));
923 //DEBUGPRINTF("val = %x, dB = %ld.%ld\n", val, (int)(dB), (int) ((dB - (int)(dB)) * 1000) );
925 WriteI2C(card
->pci_dev
, card
, AK4358_ADDR
, 0x08, val
); // dig out is conn. to the DAC as analogue out
926 WriteI2C(card
->pci_dev
, card
, AK4358_ADDR
, 0x09, val
);
928 /*WriteI2C(card->pci_dev, card, AK4358_ADDR, 0x06, val);
929 WriteI2C(card->pci_dev, card, AK4358_ADDR, 0x07, val);
931 WriteI2C(card->pci_dev, card, AK4358_ADDR, 0x08, val);
932 WriteI2C(card->pci_dev, card, AK4358_ADDR, 0x09, val);
934 WriteI2C(card->pci_dev, card, AK4358_ADDR, 0x0B, val);
935 WriteI2C(card->pci_dev, card, AK4358_ADDR, 0x0C, val);*/
937 else if (card
->SubType
== PHASE22
) {
940 //DEBUGPRINTF("card->output_volume = %lx, bits = %lx\n", card->output_volume, card->output_volume_bits);
943 case AHIC_OutputVolume_Query
:
944 return card
->output_volume
;
947 card
->input
= argument
;
949 if (card
->SubType
== REVO51
)
950 card
->input_is_24bits
= FALSE
;
953 if (card
->input
% 2 == 0)
954 card
->input_is_24bits
= FALSE
;
956 card
->input_is_24bits
= TRUE
;
959 if (card
->SubType
!= PHASE28
&& card
->input
< 10 && card
->SubType
!= REVO71
&& card
->SubType
!= REVO51
&& card
->SubType
!= JULIA
&& card
->SubType
!= PHASE22
) // analogue
960 wm_put(card
, card
->iobase
, 0x1B, (card
->input
/ 2) + 0x10 * (card
->input
/ 2) );
961 else if (card
->SubType
== REVO51
)
963 akm4xxx_write_new(card
, card
->RevoRecCodec
, 0, 0x01, card
->input
);
966 if( card
->is_recording
)
968 UpdateMonitorMixer( card
);
973 case AHIC_Input_Query
:
977 card
->output
= argument
;
979 if( card
->output
== 0 )
987 case AHIC_Output_Query
: