3 The contents of this file are subject to the AROS Public License Version 1.1 (the "License"); 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
6 Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
7 ANY KIND, either express or implied. See the License for the specific language governing rights and
8 limitations under the License.
10 The Original Code is (C) Copyright 2004-2011 Ross Vumbaca.
12 The Initial Developer of the Original Code is Ross Vumbaca.
18 #if !defined(__AROS__)
20 #include <proto/expansion.h>
22 #include <libraries/ahi_sub.h>
23 #include <proto/exec.h>
27 #include "interrupt.h"
28 #include "pci_wrapper.h"
30 #include <aros/debug.h>
33 #define min(a,b) ((a)<(b)?(a):(b))
36 /******************************************************************************
37 ** Hardware interrupt handler *************************************************
38 ******************************************************************************/
42 CardInterrupt( struct SB128_DATA
* card
)
44 struct AHIAudioCtrlDrv
* AudioCtrl
= card
->audioctrl
;
49 D(bug("[CMI8738]: %s(card @ 0x%p)\n", __PRETTY_FUNCTION__
, card
));
51 while (((intreq
= (pci_inl(SB128_STATUS
, card
))) & SB128_INT_PENDING
) != 0)
53 if( intreq
& SB128_INT_DAC2
&& AudioCtrl
!= NULL
)
55 /* Clear interrupt pending bit(s) and re-enable playback interrupts */
56 pci_outl((pci_inl(SB128_SCON
, card
) & ~SB128_DAC2_INTEN
), SB128_SCON
, card
);
57 pci_outl((pci_inl(SB128_SCON
, card
) | SB128_DAC2_INTEN
), SB128_SCON
, card
);
59 if (card
->flip
== 0) /* just played buf 1 */
62 card
->current_buffer
= card
->playback_buffer
;
64 else /* just played buf 2 */
67 card
->current_buffer
= (APTR
) ((unsigned long) card
->playback_buffer
+ card
->current_bytesize
);
70 card
->playback_interrupt_enabled
= FALSE
;
71 Cause( &card
->playback_interrupt
);
74 if( intreq
& SB128_INT_ADC
&& AudioCtrl
!= NULL
)
76 /* Clear interrupt pending bit(s) and re-enable record interrupts */
77 pci_outl((pci_inl(SB128_SCON
, card
) & ~SB128_ADC_INTEN
), SB128_SCON
, card
);
78 pci_outl((pci_inl(SB128_SCON
, card
) | SB128_ADC_INTEN
), SB128_SCON
, card
);
80 if( card
->record_interrupt_enabled
)
82 /* Invoke softint to convert and feed AHI with the new sample data */
84 if (card
->recflip
== 0) /* just filled buf 1 */
87 card
->current_record_buffer
= card
->record_buffer
;
89 else /* just filled buf 2 */
92 card
->current_record_buffer
= (APTR
) ((unsigned long) card
->record_buffer
+ card
->current_record_bytesize
);
94 card
->record_interrupt_enabled
= FALSE
;
95 Cause( &card
->record_interrupt
);
106 /******************************************************************************
107 ** Playback interrupt handler *************************************************
108 ******************************************************************************/
111 PlaybackInterrupt( struct SB128_DATA
* card
)
113 struct AHIAudioCtrlDrv
* AudioCtrl
= card
->audioctrl
;
114 struct DriverBase
* AHIsubBase
= (struct DriverBase
*) card
->ahisubbase
;
116 if( card
->mix_buffer
!= NULL
&& card
->current_buffer
!= NULL
)
126 skip_mix
= CallHookPkt( AudioCtrl
->ahiac_PreTimerFunc
, (Object
*) AudioCtrl
, 0 );
127 CallHookPkt( AudioCtrl
->ahiac_PlayerFunc
, (Object
*) AudioCtrl
, NULL
);
131 CallHookPkt( AudioCtrl
->ahiac_MixerFunc
, (Object
*) AudioCtrl
, card
->mix_buffer
);
134 /* Now translate and transfer to the DMA buffer */
136 skip
= ( AudioCtrl
->ahiac_Flags
& AHIACF_HIFI
) ? 2 : 1;
137 samples
= card
->current_bytesize
>> 1;
139 src
= card
->mix_buffer
;
144 dst
= card
->current_buffer
;
151 *dst
= ( ( *src
& 0xff ) << 8 ) | ( ( *src
& 0xff00 ) >> 8 );
162 //Flush cache so that data is completely written to the DMA buffer - Articia hack
163 CacheClearE(card
->current_buffer
, card
->current_bytesize
, CACRF_ClearD
);
165 CallHookPkt( AudioCtrl
->ahiac_PostTimerFunc
, (Object
*) AudioCtrl
, 0 );
167 card
->playback_interrupt_enabled
= TRUE
;
171 /******************************************************************************
172 ** Record interrupt handler ***************************************************
173 ******************************************************************************/
176 RecordInterrupt( struct SB128_DATA
* card
)
178 struct AHIAudioCtrlDrv
* AudioCtrl
= card
->audioctrl
;
179 struct DriverBase
* AHIsubBase
= (struct DriverBase
*) card
->ahisubbase
;
181 struct AHIRecordMessage rm
=
184 card
->current_record_buffer
,
185 RECORD_BUFFER_SAMPLES
189 int i
= 0, shorts
= card
->current_record_bytesize
/ 2;
190 WORD
* ptr
= card
->current_record_buffer
;
193 //Invalidate cache so that data read from DMA buffer is correct - Articia hack
194 CacheClearE(card
->current_record_buffer
, card
->current_record_bytesize
, CACRF_InvalidateD
);
199 *ptr
= ( ( *ptr
& 0xff ) << 8 ) | ( ( *ptr
& 0xff00 ) >> 8 );
206 CallHookPkt( AudioCtrl
->ahiac_SamplerFunc
, (Object
*) AudioCtrl
, &rm
);
208 //Invalidate cache so that data read from DMA buffer is correct - Articia hack
209 CacheClearE(card
->current_record_buffer
, card
->current_record_bytesize
, CACRF_InvalidateD
);
211 card
->record_interrupt_enabled
= TRUE
;