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.
20 #if !defined(__AROS__)
22 #include <proto/expansion.h>
24 #include <libraries/ahi_sub.h>
25 #include <proto/exec.h>
29 #include "interrupt.h"
30 #include "pci_wrapper.h"
33 #include <aros/debug.h>
34 #define DebugPrintF bug
37 #define min(a,b) ((a)<(b)?(a):(b))
40 /******************************************************************************
41 ** Hardware interrupt handler *************************************************
42 ******************************************************************************/
46 CardInterrupt( struct SB128_DATA
* card
)
48 struct AHIAudioCtrlDrv
* AudioCtrl
= card
->audioctrl
;
49 struct DriverBase
* AHIsubBase
= (struct DriverBase
*) card
->ahisubbase
;
50 struct PCIDevice
*dev
= (struct PCIDevice
* ) card
->pci_dev
;
55 bug("[CMI8738]: %s(card @ 0x%p)\n", __PRETTY_FUNCTION__
, card
);
57 while (((intreq
= (pci_inl(SB128_STATUS
, card
))) & SB128_INT_PENDING
) != 0)
59 if( intreq
& SB128_INT_DAC2
&& AudioCtrl
!= NULL
)
61 /* Clear interrupt pending bit(s) and re-enable playback interrupts */
62 pci_outl((pci_inl(SB128_SCON
, card
) & ~SB128_DAC2_INTEN
), SB128_SCON
, card
);
63 pci_outl((pci_inl(SB128_SCON
, card
) | SB128_DAC2_INTEN
), SB128_SCON
, card
);
65 if (card
->flip
== 0) /* just played buf 1 */
68 card
->current_buffer
= card
->playback_buffer
;
70 else /* just played buf 2 */
73 card
->current_buffer
= (APTR
) ((unsigned long) card
->playback_buffer
+ card
->current_bytesize
);
76 card
->playback_interrupt_enabled
= FALSE
;
77 Cause( &card
->playback_interrupt
);
80 if( intreq
& SB128_INT_ADC
&& AudioCtrl
!= NULL
)
82 /* Clear interrupt pending bit(s) and re-enable record interrupts */
83 pci_outl((pci_inl(SB128_SCON
, card
) & ~SB128_ADC_INTEN
), SB128_SCON
, card
);
84 pci_outl((pci_inl(SB128_SCON
, card
) | SB128_ADC_INTEN
), SB128_SCON
, card
);
86 if( card
->record_interrupt_enabled
)
88 /* Invoke softint to convert and feed AHI with the new sample data */
90 if (card
->recflip
== 0) /* just filled buf 1 */
93 card
->current_record_buffer
= card
->record_buffer
;
95 else /* just filled buf 2 */
98 card
->current_record_buffer
= (APTR
) ((unsigned long) card
->record_buffer
+ card
->current_record_bytesize
);
100 card
->record_interrupt_enabled
= FALSE
;
101 Cause( &card
->record_interrupt
);
113 /******************************************************************************
114 ** Playback interrupt handler *************************************************
115 ******************************************************************************/
118 PlaybackInterrupt( struct SB128_DATA
* card
)
120 struct AHIAudioCtrlDrv
* AudioCtrl
= card
->audioctrl
;
121 struct DriverBase
* AHIsubBase
= (struct DriverBase
*) card
->ahisubbase
;
122 struct PCIDevice
*dev
= (struct PCIDevice
* ) card
->pci_dev
;
124 if( card
->mix_buffer
!= NULL
&& card
->current_buffer
!= NULL
)
134 skip_mix
= CallHookPkt( AudioCtrl
->ahiac_PreTimerFunc
, (Object
*) AudioCtrl
, 0 );
135 CallHookPkt( AudioCtrl
->ahiac_PlayerFunc
, (Object
*) AudioCtrl
, NULL
);
139 CallHookPkt( AudioCtrl
->ahiac_MixerFunc
, (Object
*) AudioCtrl
, card
->mix_buffer
);
142 /* Now translate and transfer to the DMA buffer */
144 skip
= ( AudioCtrl
->ahiac_Flags
& AHIACF_HIFI
) ? 2 : 1;
145 samples
= card
->current_bytesize
>> 1;
147 src
= card
->mix_buffer
;
148 dst
= card
->current_buffer
;
154 *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
;
180 struct PCIDevice
*dev
= (struct PCIDevice
* ) card
->pci_dev
;
182 struct AHIRecordMessage rm
=
185 card
->current_record_buffer
,
186 RECORD_BUFFER_SAMPLES
189 int i
= 0, shorts
= card
->current_record_bytesize
/ 2;
190 WORD
* ptr
= card
->current_record_buffer
;
192 //Invalidate cache so that data read from DMA buffer is correct - Articia hack
193 CacheClearE(card
->current_record_buffer
, card
->current_record_bytesize
, CACRF_InvalidateD
);
197 *ptr
= ( ( *ptr
& 0xff ) << 8 ) | ( ( *ptr
& 0xff00 ) >> 8 );
203 CallHookPkt( AudioCtrl
->ahiac_SamplerFunc
, (Object
*) AudioCtrl
, &rm
);
205 //Invalidate cache so that data read from DMA buffer is correct - Articia hack
206 CacheClearE(card
->current_record_buffer
, card
->current_record_bytesize
, CACRF_InvalidateD
);
208 card
->record_interrupt_enabled
= TRUE
;