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.
14 #if !defined(__AROS__)
16 #include <proto/expansion.h>
18 #include <libraries/ahi_sub.h>
19 #include <proto/exec.h>
23 #include "interrupt.h"
25 #include "pci_wrapper.h"
28 #include <aros/debug.h>
29 #define DebugPrintF bug
32 #define min(a,b) ((a)<(b)?(a):(b))
37 //struct tester t[10];
40 /******************************************************************************
41 ** Hardware interrupt handler *************************************************
42 ******************************************************************************/
46 CardInterrupt( struct CMI8738_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
);
56 bug("[CMI8738] %s: AHIAudioCtrlDrv @ 0x%p\n", __PRETTY_FUNCTION__
, AudioCtrl
);
59 // while (((intreq = pci_inl(CMPCI_REG_INTR_STATUS, card)) & CMPCI_REG_ANY_INTR) != 0)
61 intreq
= pci_inl(CMPCI_REG_INTR_STATUS
, card
);
63 bug("[CMI8738] %s: INTR_STATUS = %08x\n", __PRETTY_FUNCTION__
, intreq
);
65 if (((intreq
& CMPCI_REG_ANY_INTR
) == 0) || (AudioCtrl
== NULL
))
68 //DebugPrintF("INT %lx\n", intreq);
69 if( intreq
& CMPCI_REG_CH0_INTR
)
71 unsigned long diff
= pci_inl(CMPCI_REG_DMA0_BASE
, card
) - (unsigned long) card
->playback_buffer_phys
;
73 ClearMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH0_INTR_ENABLE
);
80 t[z].flip = card->flip;
81 t[z].oldflip = card->oldflip;
84 /*if ((diff > 50 && diff < card->current_bytesize) ||
85 (diff > card->current_bytesize + 50 && diff < 2 * card->current_bytesize))
86 DebugPrintF("Delayed IRQ %lu %lu\n", diff % card->current_bytesize, card->current_bytesize);*/
89 if (diff
>= card
->current_bytesize
) //card->flip == 0) // just played buf 1
93 DebugPrintF("A:Missed IRQ! diff = %lu\n", diff
);
97 card
->current_buffer
= card
->playback_buffer
;
99 else // just played buf 2
103 DebugPrintF("B:Missed IRQ! diff = %lu\n", diff
);
107 card
->current_buffer
= (APTR
) ((long) card
->playback_buffer
+ card
->current_bytesize
);
114 card
->playback_interrupt_enabled
= FALSE
;
115 Cause( &card
->playback_interrupt
);
118 if( intreq
& CMPCI_REG_CH1_INTR
)
120 ClearMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH1_INTR_ENABLE
);
123 DebugPrintF("rec\n");*/
128 if( card
->record_interrupt_enabled
)
130 /* Invoke softint to convert and feed AHI with the new sample data */
132 if (card
->recflip
== 0) // just played buf 1
135 card
->current_record_buffer
= card
->record_buffer
;
137 else // just played buf 2
140 card
->current_record_buffer
= (APTR
) ((long) card
->record_buffer
+ card
->current_record_bytesize
);
143 card
->record_interrupt_enabled
= FALSE
;
144 Cause( &card
->record_interrupt
);
156 /******************************************************************************
157 ** Playback interrupt handler *************************************************
158 ******************************************************************************/
161 PlaybackInterrupt( struct CMI8738_DATA
* card
)
163 struct AHIAudioCtrlDrv
* AudioCtrl
= card
->audioctrl
;
164 struct DriverBase
* AHIsubBase
= (struct DriverBase
*) card
->ahisubbase
;
165 struct PCIDevice
*dev
= (struct PCIDevice
* ) card
->pci_dev
;
167 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__
);
169 if( card
->mix_buffer
!= NULL
&& card
->current_buffer
!= NULL
)
179 skip_mix
= CallHookPkt( AudioCtrl
->ahiac_PreTimerFunc
, (Object
*) AudioCtrl
, 0 );
180 CallHookPkt( AudioCtrl
->ahiac_PlayerFunc
, (Object
*) AudioCtrl
, NULL
);
182 //DebugPrintF("skip_mix = %d\n", skip_mix);
186 CallHookPkt( AudioCtrl
->ahiac_MixerFunc
, (Object
*) AudioCtrl
, card
->mix_buffer
);
189 /* Now translate and transfer to the DMA buffer */
192 skip
= ( AudioCtrl
->ahiac_Flags
& AHIACF_HIFI
) ? 2 : 1;
193 samples
= card
->current_bytesize
>> 1;
195 src
= card
->mix_buffer
;
196 dst
= card
->current_buffer
;
204 *dst
= ( ( *src
& 0xff ) << 8 ) | ( ( *src
& 0xff00 ) >> 8 );
215 CacheClearE( card
->current_buffer
, (ULONG
) dst
- (ULONG
) card
->current_buffer
, CACRF_ClearD
);
217 CallHookPkt( AudioCtrl
->ahiac_PostTimerFunc
, (Object
*) AudioCtrl
, 0 );
220 WriteMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH0_INTR_ENABLE
);
221 card
->playback_interrupt_enabled
= TRUE
;
225 /******************************************************************************
226 ** Record interrupt handler ***************************************************
227 ******************************************************************************/
230 RecordInterrupt( struct CMI8738_DATA
* card
)
232 struct AHIAudioCtrlDrv
* AudioCtrl
= card
->audioctrl
;
233 struct DriverBase
* AHIsubBase
= (struct DriverBase
*) card
->ahisubbase
;
234 struct PCIDevice
*dev
= (struct PCIDevice
* ) card
->pci_dev
;
236 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__
);
238 struct AHIRecordMessage rm
=
241 card
->current_record_buffer
,
242 RECORD_BUFFER_SAMPLES
245 int i
= 0, shorts
= card
->current_record_bytesize
/ 2;
246 WORD
* ptr
= (WORD
*) card
->current_record_buffer
;
249 CacheClearE( card
->current_record_buffer
, card
->current_record_bytesize
, CACRF_ClearD
);
253 *ptr
= ( ( *ptr
& 0xff ) << 8 ) | ( ( *ptr
& 0xff00 ) >> 8 );
259 CallHookPkt( AudioCtrl
->ahiac_SamplerFunc
, (Object
*) AudioCtrl
, &rm
);
261 CacheClearE( card
->current_record_buffer
, card
->current_record_bytesize
, CACRF_ClearD
);
264 WriteMask(dev
, card
, CMPCI_REG_INTR_CTRL
, CMPCI_REG_CH1_INTR_ENABLE
);
265 card
->record_interrupt_enabled
= TRUE
;