Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Drivers / CMI8738 / interrupt.c
blobab82d068b1624ea61e1e76739fe2fa89489e45dd
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
18 #include <libraries/ahi_sub.h>
19 #include <proto/exec.h>
20 #include <stddef.h>
21 #include "library.h"
22 #include "regs.h"
23 #include "interrupt.h"
24 #include "misc.h"
25 #include "pci_wrapper.h"
26 #ifdef __AROS__
27 #include <aros/debug.h>
28 #define DebugPrintF bug
29 #endif
31 #define min(a,b) ((a)<(b)?(a):(b))
33 int z = 0;
36 //struct tester t[10];
39 /******************************************************************************
40 ** Hardware interrupt handler *************************************************
41 ******************************************************************************/
44 LONG
45 CardInterrupt( struct CMI8738_DATA* card )
47 struct AHIAudioCtrlDrv* AudioCtrl = card->audioctrl;
48 struct PCIDevice *dev = (struct PCIDevice * ) card->pci_dev;
50 ULONG intreq;
51 LONG handled = 0;
53 bug("[CMI8738]: %s(card @ 0x%p)\n", __PRETTY_FUNCTION__, card);
54 bug("[CMI8738] %s: AHIAudioCtrlDrv @ 0x%p\n", __PRETTY_FUNCTION__, AudioCtrl);
56 for (;;)
57 // while (((intreq = pci_inl(CMPCI_REG_INTR_STATUS, card)) & CMPCI_REG_ANY_INTR) != 0)
59 intreq = pci_inl(CMPCI_REG_INTR_STATUS, card);
61 bug("[CMI8738] %s: INTR_STATUS = %08x\n", __PRETTY_FUNCTION__, intreq);
63 if (((intreq & CMPCI_REG_ANY_INTR) == 0) || (AudioCtrl == NULL))
64 break;
66 //DebugPrintF("INT %lx\n", intreq);
67 if( intreq & CMPCI_REG_CH0_INTR)
69 unsigned long diff = pci_inl(CMPCI_REG_DMA0_BASE, card) - (unsigned long) card->playback_buffer_phys;
71 ClearMask(dev, card, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE);
74 z++;
75 if (z < 10)
77 t[z].diff = diff;
78 t[z].flip = card->flip;
79 t[z].oldflip = card->oldflip;
80 }*/
82 /*if ((diff > 50 && diff < card->current_bytesize) ||
83 (diff > card->current_bytesize + 50 && diff < 2 * card->current_bytesize))
84 DebugPrintF("Delayed IRQ %lu %lu\n", diff % card->current_bytesize, card->current_bytesize);*/
87 if (diff >= card->current_bytesize) //card->flip == 0) // just played buf 1
89 if (card->flip == 1)
91 DebugPrintF("A:Missed IRQ! diff = %lu\n", diff);
94 card->flip = 1;
95 card->current_buffer = card->playback_buffer;
97 else // just played buf 2
99 if (card->flip == 0)
101 DebugPrintF("B:Missed IRQ! diff = %lu\n", diff);
104 card->flip = 0;
105 card->current_buffer = (APTR) ((long) card->playback_buffer + card->current_bytesize);
108 /*z++;
109 if (z == 25)
110 z = 0;*/
112 card->playback_interrupt_enabled = FALSE;
113 Cause( &card->playback_interrupt );
116 if( intreq & CMPCI_REG_CH1_INTR)
118 ClearMask(dev, card, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
120 /*if (z == 0)
121 DebugPrintF("rec\n");*/
122 z++;
123 /*if (z == 30)
124 z = 0;*/
126 if( card->record_interrupt_enabled )
128 /* Invoke softint to convert and feed AHI with the new sample data */
130 if (card->recflip == 0) // just played buf 1
132 card->recflip = 1;
133 card->current_record_buffer = card->record_buffer;
135 else // just played buf 2
137 card->recflip = 0;
138 card->current_record_buffer = (APTR) ((long) card->record_buffer + card->current_record_bytesize);
141 card->record_interrupt_enabled = FALSE;
142 Cause( &card->record_interrupt );
146 handled = 1;
150 return handled;
154 /******************************************************************************
155 ** Playback interrupt handler *************************************************
156 ******************************************************************************/
158 void
159 PlaybackInterrupt( struct CMI8738_DATA* card )
161 struct AHIAudioCtrlDrv* AudioCtrl = card->audioctrl;
162 struct DriverBase* AHIsubBase = (struct DriverBase*) card->ahisubbase;
163 struct PCIDevice *dev = (struct PCIDevice * ) card->pci_dev;
165 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__);
167 if( card->mix_buffer != NULL && card->current_buffer != NULL )
169 BOOL skip_mix;
171 WORD* src;
172 WORD* dst;
173 size_t skip;
174 size_t samples;
175 int i;
177 skip_mix = CallHookPkt( AudioCtrl->ahiac_PreTimerFunc, (Object*) AudioCtrl, 0 );
178 CallHookPkt( AudioCtrl->ahiac_PlayerFunc, (Object*) AudioCtrl, NULL );
180 //DebugPrintF("skip_mix = %d\n", skip_mix);
182 if( ! skip_mix )
184 CallHookPkt( AudioCtrl->ahiac_MixerFunc, (Object*) AudioCtrl, card->mix_buffer );
187 /* Now translate and transfer to the DMA buffer */
190 skip = ( AudioCtrl->ahiac_Flags & AHIACF_HIFI ) ? 2 : 1;
191 samples = card->current_bytesize >> 1;
193 src = card->mix_buffer;
194 #if !defined(__AMIGAOS4__) && !AROS_BIG_ENDIAN
195 if(skip == 2)
196 src++;
197 #endif
198 dst = card->current_buffer;
200 i = samples;
203 while( i > 0 )
205 #ifdef __AMIGAOS4__
206 *dst = ( ( *src & 0xff ) << 8 ) | ( ( *src & 0xff00 ) >> 8 );
207 #else
208 *dst = AROS_WORD2LE(*src);
209 #endif
211 src += skip;
212 dst += 1;
214 --i;
217 CacheClearE( card->current_buffer, (ULONG) dst - (ULONG) card->current_buffer, CACRF_ClearD );
219 CallHookPkt( AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0 );
222 WriteMask(dev, card, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE);
223 card->playback_interrupt_enabled = TRUE;
227 /******************************************************************************
228 ** Record interrupt handler ***************************************************
229 ******************************************************************************/
231 void
232 RecordInterrupt( struct CMI8738_DATA* card )
234 struct AHIAudioCtrlDrv* AudioCtrl = card->audioctrl;
235 struct DriverBase* AHIsubBase = (struct DriverBase*) card->ahisubbase;
236 struct PCIDevice *dev = (struct PCIDevice * ) card->pci_dev;
238 bug("[CMI8738]: %s()\n", __PRETTY_FUNCTION__);
240 struct AHIRecordMessage rm =
242 AHIST_S16S,
243 card->current_record_buffer,
244 RECORD_BUFFER_SAMPLES
247 int i = 0, shorts = card->current_record_bytesize / 2;
248 WORD* ptr = (WORD *) card->current_record_buffer;
251 CacheClearE( card->current_record_buffer, card->current_record_bytesize, CACRF_ClearD);
253 while( i < shorts )
255 #if defined(__AMIGAOS4__) || AROS_BIG_ENDIAN
256 *ptr = ( ( *ptr & 0xff ) << 8 ) | ( ( *ptr & 0xff00 ) >> 8 );
257 #endif
258 ++i;
259 ++ptr;
262 CallHookPkt( AudioCtrl->ahiac_SamplerFunc, (Object*) AudioCtrl, &rm );
264 CacheClearE( card->current_record_buffer, card->current_record_bytesize, CACRF_ClearD);
267 WriteMask(dev, card, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE);
268 card->record_interrupt_enabled = TRUE;