2 emu10kx.audio - AHI driver for SoundBlaster Live! series
3 Copyright (C) 2002-2005 Martin Blom <martin@blom.org>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <exec/memory.h>
23 #include <proto/exec.h>
24 #include <clib/alib_protos.h>
29 #include "emu10kx-misc.h"
30 #include "pci_wrapper.h"
32 /* We use global library bases instead of storing them in DriverBase, since
33 I don't want to modify the original sources more than necessary. */
35 struct DriverBase
* AHIsubBase
= NULL
;
36 struct ExecBase
* SysBase
= NULL
;
37 struct DosLibrary
* DOSBase
= NULL
;
40 struct DOSIFace
* IDOS
= NULL
;
41 struct ExecIFace
* IExec
= NULL
;
42 struct MMUIFace
* IMMU
= NULL
;
46 #include <proto/stdc.h>
48 struct StdCBase
*StdCBase
= NULL
;
57 /******************************************************************************
58 ** Custom driver init *********************************************************
59 ******************************************************************************/
62 DriverInit( struct DriverBase
* ahisubbase
)
64 struct EMU10kxBase
* EMU10kxBase
= (struct EMU10kxBase
*) ahisubbase
;
68 /*** Libraries etc. ********************************************************/
70 AHIsubBase
= ahisubbase
;
72 DOSBase
= (struct DosLibrary
*) OpenLibrary( DOSNAME
, 37 );
76 Req( "Unable to open 'dos.library' version 37.\n" );
81 if ((IDOS
= (struct DOSIFace
*) GetInterface((struct Library
*) DOSBase
, "main", 1, NULL
)) == NULL
)
83 Req("Couldn't open IDOS interface!\n");
87 /* if ((IAHIsub = (struct AHIsubIFace *) GetInterface((struct Library *) AHIsubBase, "main", 1, NULL)) == NULL) */
89 /* Req("Couldn't open IAHIsub interface!\n"); */
93 if ((IMMU
= (struct MMUIFace
*) GetInterface((struct Library
*) SysBase
, "mmu", 1, NULL
)) == NULL
)
95 Req("Couldn't open IMMU interface!\n");
99 /* if ((IUtility = (struct UtilityIFace *) GetInterface((struct Library *) UtilityBase, "main", 1, NULL)) == NULL) */
101 /* Req("Couldn't open IUtility interface!\n"); */
107 StdCBase
= (struct StdCBase
*) OpenLibrary( "stdc.library", 0 );
109 if( StdCBase
== NULL
)
111 Req( "Unable to open 'stdc.library'.\n" );
116 if (!ahi_pci_init(ahisubbase
))
121 InitSemaphore( &EMU10kxBase
->semaphore
);
124 /*** Count cards ***********************************************************/
126 EMU10kxBase
->cards_found
= 0;
129 // Search for Live! cards
130 while( ( dev
= ahi_pci_find_device( PCI_VENDOR_ID_CREATIVE
,
131 PCI_DEVICE_ID_CREATIVE_EMU10K1
,
134 ++EMU10kxBase
->cards_found
;
137 // Search for Audigy cards
138 while( ( dev
= ahi_pci_find_device( PCI_VENDOR_ID_CREATIVE
,
139 PCI_DEVICE_ID_CREATIVE_AUDIGY
,
142 ++EMU10kxBase
->cards_found
;
145 // Fail if no hardware (prevents the audio modes form being added to
146 // the database if the driver cannot be used).
148 if( EMU10kxBase
->cards_found
== 0 )
153 /*** CAMD ******************************************************************/
155 InitSemaphore( &EMU10kxBase
->camd
.Semaphore
);
156 EMU10kxBase
->camd
.Semaphore
.ss_Link
.ln_Pri
= 0;
157 EMU10kxBase
->camd
.Semaphore
.ss_Link
.ln_Name
= EMU10KX_CAMD_SEMAPHORE
;
159 EMU10kxBase
->camd
.Cards
= EMU10kxBase
->cards_found
;
160 EMU10kxBase
->camd
.Version
= VERSION
;
161 EMU10kxBase
->camd
.Revision
= REVISION
;
164 EMU10kxBase
->camd
.OpenPortFunc
.h_Entry
= OpenCAMDPort
;
165 EMU10kxBase
->camd
.OpenPortFunc
.h_SubEntry
= NULL
;
166 EMU10kxBase
->camd
.OpenPortFunc
.h_Data
= NULL
;
168 EMU10kxBase
->camd
.ClosePortFunc
.h_Entry
= (HOOKFUNC
) CloseCAMDPort
;
169 EMU10kxBase
->camd
.ClosePortFunc
.h_SubEntry
= NULL
;
170 EMU10kxBase
->camd
.ClosePortFunc
.h_Data
= NULL
;
172 EMU10kxBase
->camd
.ActivateXmitFunc
.h_Entry
= (HOOKFUNC
) ActivateCAMDXmit
;
173 EMU10kxBase
->camd
.ActivateXmitFunc
.h_SubEntry
= NULL
;
174 EMU10kxBase
->camd
.ActivateXmitFunc
.h_Data
= NULL
;
178 EMU10kxBase
->camd
.OpenPortFunc
.h_Entry
= HookEntry
;
179 EMU10kxBase
->camd
.OpenPortFunc
.h_SubEntry
= OpenCAMDPort
;
180 EMU10kxBase
->camd
.OpenPortFunc
.h_Data
= NULL
;
182 EMU10kxBase
->camd
.ClosePortFunc
.h_Entry
= HookEntry
;
183 EMU10kxBase
->camd
.ClosePortFunc
.h_SubEntry
= (HOOKFUNC
) CloseCAMDPort
;
184 EMU10kxBase
->camd
.ClosePortFunc
.h_Data
= NULL
;
186 EMU10kxBase
->camd
.ActivateXmitFunc
.h_Entry
= HookEntry
;
187 EMU10kxBase
->camd
.ActivateXmitFunc
.h_SubEntry
= (HOOKFUNC
) ActivateCAMDXmit
;
188 EMU10kxBase
->camd
.ActivateXmitFunc
.h_Data
= NULL
;
191 AddSemaphore( &EMU10kxBase
->camd
.Semaphore
);
193 /*** AC97 Mixer ************************************************************/
195 InitSemaphore( &EMU10kxBase
->ac97
.Semaphore
);
196 EMU10kxBase
->ac97
.Semaphore
.ss_Link
.ln_Pri
= 0;
197 EMU10kxBase
->ac97
.Semaphore
.ss_Link
.ln_Name
= EMU10KX_AC97_SEMAPHORE
;
199 EMU10kxBase
->ac97
.Cards
= EMU10kxBase
->cards_found
;
200 EMU10kxBase
->ac97
.Version
= VERSION
;
201 EMU10kxBase
->ac97
.Revision
= REVISION
;
204 EMU10kxBase
->ac97
.GetFunc
.h_Entry
= AC97GetFunc
;
205 EMU10kxBase
->ac97
.GetFunc
.h_SubEntry
= NULL
;
206 EMU10kxBase
->ac97
.GetFunc
.h_Data
= NULL
;
208 EMU10kxBase
->ac97
.SetFunc
.h_Entry
= (HOOKFUNC
) AC97SetFunc
;
209 EMU10kxBase
->ac97
.SetFunc
.h_SubEntry
= NULL
;
210 EMU10kxBase
->ac97
.SetFunc
.h_Data
= NULL
;
214 EMU10kxBase
->ac97
.GetFunc
.h_Entry
= HookEntry
;
215 EMU10kxBase
->ac97
.GetFunc
.h_SubEntry
= AC97GetFunc
;
216 EMU10kxBase
->ac97
.GetFunc
.h_Data
= NULL
;
218 EMU10kxBase
->ac97
.SetFunc
.h_Entry
= HookEntry
;
219 EMU10kxBase
->ac97
.SetFunc
.h_SubEntry
= (HOOKFUNC
) AC97SetFunc
;
220 EMU10kxBase
->ac97
.SetFunc
.h_Data
= NULL
;
223 AddSemaphore( &EMU10kxBase
->ac97
.Semaphore
);
225 /*** Allocate and init all cards *******************************************/
227 EMU10kxBase
->driverdatas
= AllocVec( sizeof( *EMU10kxBase
->driverdatas
) *
228 EMU10kxBase
->cards_found
,
231 if( EMU10kxBase
->driverdatas
== NULL
)
233 Req( "Out of memory." );
240 while( ( dev
= ahi_pci_find_device( PCI_VENDOR_ID_CREATIVE
,
241 PCI_DEVICE_ID_CREATIVE_EMU10K1
,
244 // AOS4: dev->Lock(PCI_LOCK_EXCLUSIVE); tbd
245 EMU10kxBase
->driverdatas
[ card_no
] = AllocDriverData( dev
, AHIsubBase
);
250 while( ( dev
= ahi_pci_find_device( PCI_VENDOR_ID_CREATIVE
,
251 PCI_DEVICE_ID_CREATIVE_AUDIGY
,
254 // AOS4: dev->Lock(PCI_LOCK_EXCLUSIVE); tbd
255 EMU10kxBase
->driverdatas
[ card_no
] = AllocDriverData( dev
, AHIsubBase
);
263 /******************************************************************************
264 ** Custom driver clean-up *****************************************************
265 ******************************************************************************/
268 DriverCleanup( struct DriverBase
* AHIsubBase
)
270 struct EMU10kxBase
* EMU10kxBase
= (struct EMU10kxBase
*) AHIsubBase
;
273 if( EMU10kxBase
->camd
.Semaphore
.ss_Link
.ln_Name
!= NULL
)
275 ObtainSemaphore( &EMU10kxBase
->camd
.Semaphore
);
276 RemSemaphore( &EMU10kxBase
->camd
.Semaphore
);
277 ReleaseSemaphore( &EMU10kxBase
->camd
.Semaphore
);
280 if( EMU10kxBase
->ac97
.Semaphore
.ss_Link
.ln_Name
!= NULL
)
282 ObtainSemaphore( &EMU10kxBase
->ac97
.Semaphore
);
283 RemSemaphore( &EMU10kxBase
->ac97
.Semaphore
);
284 ReleaseSemaphore( &EMU10kxBase
->ac97
.Semaphore
);
287 for( i
= 0; i
< EMU10kxBase
->cards_found
; ++i
)
290 emu10k1_irq_disable( &EMU10kxBase
->driverdatas
[ i
]->card
, ~0UL );
291 // INTE_MIDIRXENABLE | INTE_MIDITXENABLE);
293 FreeDriverData( EMU10kxBase
->driverdatas
[ i
], AHIsubBase
);
296 FreeVec( EMU10kxBase
->driverdatas
);
299 CloseLibrary( (struct Library
*) StdCBase
);
303 DropInterface((struct Interface
*) IDOS
);
304 DropInterface((struct Interface
*) IMMU
);
309 CloseLibrary( (struct Library
*) DOSBase
);