1// ****************************************************************************
2//
3//		CEchoGals.cpp
4//
5//		Implementation file for the CEchoGals driver class.
6//		Set editor tabs to 3 for your viewing pleasure.
7//
8// ----------------------------------------------------------------------------
9//
10// This file is part of Echo Digital Audio's generic driver library.
11// Copyright Echo Digital Audio Corporation (c) 1998 - 2005
12// All rights reserved
13// www.echoaudio.com
14//
15// This library is free software; you can redistribute it and/or
16// modify it under the terms of the GNU Lesser General Public
17// License as published by the Free Software Foundation; either
18// version 2.1 of the License, or (at your option) any later version.
19//
20// This library is distributed in the hope that it will be useful,
21// but WITHOUT ANY WARRANTY; without even the implied warranty of
22// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23// Lesser General Public License for more details.
24//
25// You should have received a copy of the GNU Lesser General Public
26// License along with this library; if not, write to the Free Software
27// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28//
29// ****************************************************************************
30
31#include "CEchoGals.h"
32
33
34/****************************************************************************
35
36	CEchoGals construction and destruction
37
38 ****************************************************************************/
39
40//===========================================================================
41//
42// Overload new & delete so memory for this object is allocated
43//	from non-paged memory.
44//
45//===========================================================================
46
47PVOID CEchoGals::operator new( size_t Size )
48{
49	PVOID 		pMemory;
50	ECHOSTATUS 	Status;
51
52	Status = OsAllocateNonPaged(Size,&pMemory);
53
54	if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
55	{
56		ECHO_DEBUGPRINTF(("CEchoGals::operator new - memory allocation failed\n"));
57
58		pMemory = NULL;
59	}
60	else
61	{
62		memset( pMemory, 0, Size );
63	}
64
65	return pMemory;
66
67}	// PVOID CEchoGals::operator new( size_t Size )
68
69
70VOID  CEchoGals::operator delete( PVOID pVoid )
71{
72	if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
73	{
74		ECHO_DEBUGPRINTF(("CEchoGals::operator delete memory free failed\n"));
75	}
76}	// VOID  CEchoGals::operator delete( PVOID pVoid )
77
78
79//===========================================================================
80//
81// Constructor
82//
83//===========================================================================
84
85CEchoGals::CEchoGals
86(
87	PCOsSupport pOsSupport
88)
89{
90	ECHO_ASSERT(pOsSupport );
91
92	m_pOsSupport = pOsSupport;		// Ptr to OS Support methods & data
93
94	m_wFlags = ECHOGALS_FLAG_BADBOARD;
95
96	m_dwLockedSampleRate	= 44100;
97
98}	// CEchoGals::CEchoGals()
99
100
101//===========================================================================
102//
103// Destructor
104//
105//===========================================================================
106
107CEchoGals::~CEchoGals()
108{
109	//
110	// Free stuff
111	//
112	delete m_pDspCommObject;	// This powers down the DSP
113
114	//
115	// Clean up the ducks
116	//
117	WORD i;
118
119	for (i = 0; i < ECHO_MAXAUDIOPIPES; i++)
120	{
121		if (NULL != m_DaffyDucks[i])
122			delete m_DaffyDucks[i];
123	}
124
125	//
126	//	Clean up the mixer client list
127	//
128	while (NULL != m_pMixerClients)
129	{
130		ECHO_MIXER_CLIENT *pDeadClient;
131
132		pDeadClient = m_pMixerClients;
133		m_pMixerClients = pDeadClient->pNext;
134		OsFreeNonPaged(pDeadClient);
135	}
136
137	ECHO_DEBUGPRINTF( ( "CEchoGals::~CEchoGals() is toast!\n" ) );
138
139}	// CEchoGals::~CEchoGals()
140
141
142
143
144/****************************************************************************
145
146	CEchoGals setup and hardware initialization
147
148 ****************************************************************************/
149
150//===========================================================================
151//
152// AssignResources does just what you'd expect.
153//
154// Note that pvSharedMemory is a logical pointer - that is, the driver
155// will dereference this pointer to access the memory-mapped regisers on
156// the DSP.  The caller needs to take the physical address from the PCI
157// config space and map it.
158//
159//===========================================================================
160
161ECHOSTATUS CEchoGals::AssignResources
162(
163	PVOID		pvSharedMemory,		// Ptr to DSP registers
164	PCHAR		pszCardName				// Caller gets from registry
165)
166{
167	//
168	//	Use ECHO_ASSERT(to be sure this isn't called twice!
169	//
170	ECHO_ASSERT(NULL == m_pvSharedMemory );
171
172	//
173	//	Check and store the parameters
174	//
175	ECHO_ASSERT(pvSharedMemory );
176	if ( NULL == pszCardName )
177	{
178		return( ECHOSTATUS_BAD_CARD_NAME );
179	}
180	m_pvSharedMemory = pvSharedMemory;	// Shared memory addr assigned by PNP
181
182	//
183	//	Copy card name & make sure we don't overflow our buffer
184	//
185	strncpy( m_szCardInstallName, pszCardName, ECHO_MAXNAMELEN-1 );
186	m_szCardInstallName[ ECHO_MAXNAMELEN-1 ] = 0;
187
188	return ECHOSTATUS_OK;
189
190}	// ECHOSTATUS CEchoGals::AssignResources
191
192
193//===========================================================================
194//
195// InitHw is device-specific and so does nothing here; it is overridden
196// in the derived classes.
197//
198//	The correct sequence is:
199//
200//	Construct the appropriate CEchoGals-derived object for the card
201// Call AssignResources
202// Call InitHw
203//
204//===========================================================================
205
206ECHOSTATUS CEchoGals::InitHw()
207{
208	//
209	//	Use ECHO_ASSERT to be sure AssignResources was called!
210	//
211	ECHO_ASSERT(m_pvSharedMemory );
212
213	return ECHOSTATUS_OK;
214
215} // ECHOSTATUS CEchoGals::InitHw()
216
217
218//===========================================================================
219//
220// This method initializes classes to control the mixer controls for
221// the busses and pipes.  This is a protected method; it is called
222// from each of the CEchoGals derived classes once the DSP is up
223// and running.
224//
225//===========================================================================
226
227ECHOSTATUS CEchoGals::InitLineLevels()
228{
229	ECHOSTATUS	Status = ECHOSTATUS_OK;
230	WORD			i;
231
232	m_fMixerDisabled = TRUE;
233
234	if ( 	(NULL == GetDspCommObject()) ||
235			(GetDspCommObject()->IsBoardBad() ) )
236	{
237		return ECHOSTATUS_DSP_DEAD;
238	}
239
240	//
241	// Do output busses first since output pipes & monitors
242	// depend on output bus values
243	//
244	for ( i = 0; i < GetNumBussesOut(); i++ )
245	{
246		m_BusOutLineLevels[ i ].Init( i, this );
247	}
248
249	Status = m_PipeOutCtrl.Init(this);
250	if (ECHOSTATUS_OK != Status)
251		return Status;
252
253	Status = m_MonitorCtrl.Init(this);
254	if (ECHOSTATUS_OK != Status)
255		return Status;
256
257	for ( i = 0; i < GetNumBussesIn(); i++ )
258	{
259		m_BusInLineLevels[ i ].Init(	i,	this );
260	}
261
262	m_fMixerDisabled = FALSE;
263
264	return Status;
265
266}	// ECHOSTATUS CEchoGals::InitLineLevels()
267
268
269
270
271/******************************************************************************
272
273 CEchoGals interrupt handler functions
274
275 ******************************************************************************/
276
277//===========================================================================
278//
279// This isn't the interrupt handler itself; rather, the OS-specific layer
280// of the driver has an interrupt handler that calls this function.
281//
282//===========================================================================
283
284ECHOSTATUS CEchoGals::ServiceIrq(BOOL &fMidiReceived)
285{
286	CDspCommObject *pDCO;
287
288	//
289	// Read the DSP status register and see if this DSP
290	// generated this interrupt
291	//
292	fMidiReceived = FALSE;
293
294	pDCO = GetDspCommObject();
295	if ( pDCO->GetStatusReg() & CHI32_STATUS_IRQ )
296	{
297
298#ifdef MIDI_SUPPORT
299
300		//
301		// If this was a MIDI input interrupt, get the MIDI input data
302		//
303		DWORD dwMidiInCount;
304
305		pDCO->ReadMidi( 0, dwMidiInCount );	  // The count is at index 0
306		if ( 0 != dwMidiInCount )
307		{
308			m_MidiIn.ServiceIrq();
309			fMidiReceived = TRUE;
310		}
311
312#endif // MIDI_SUPPORT
313
314		//
315		//	Clear the hardware interrupt
316		//
317		pDCO->AckInt();
318
319		return ECHOSTATUS_OK;
320	}
321
322	//
323	// This interrupt line must be shared
324	//
325	/*
326	ECHO_DEBUGPRINTF( ("CEchoGals::ServiceIrq() %s\tInterrupt not ours!\n",
327							 GetDeviceName()) );
328	*/
329
330	return ECHOSTATUS_IRQ_NOT_OURS;
331
332}	// ECHOSTATUS CEchoGals::ServiceIrq()
333
334
335
336
337/****************************************************************************
338
339	Character strings for the ECHOSTATUS return values -
340	useful for debugging.
341
342 ****************************************************************************/
343
344//
345// pStatusStrs is used if you want to print out a friendlier version of
346// the various ECHOSTATUS codes.
347//
348char *	pStatusStrs[ECHOSTATUS_LAST] =
349{
350	"ECHOSTATUS_OK",
351	"ECHOSTATUS_BAD_FORMAT",
352	"ECHOSTATUS_BAD_BUFFER_SIZE",
353	"ECHOSTATUS_CANT_OPEN",
354	"ECHOSTATUS_CANT_CLOSE",
355	"ECHOSTATUS_CHANNEL_NOT_OPEN",
356	"ECHOSTATUS_BUSY",
357	"ECHOSTATUS_BAD_LEVEL",
358	"ECHOSTATUS_NO_MIDI",
359	"ECHOSTATUS_CLOCK_NOT_SUPPORTED",
360	"ECHOSTATUS_CLOCK_NOT_AVAILABLE",
361	"ECHOSTATUS_BAD_CARDID",
362	"ECHOSTATUS_NOT_SUPPORTED",
363	"ECHOSTATUS_BAD_NOTIFY_SIZE",
364	"ECHOSTATUS_INVALID_PARAM",
365	"ECHOSTATUS_NO_MEM",
366	"ECHOSTATUS_NOT_SHAREABLE",
367	"ECHOSTATUS_FIRMWARE_LOADED",
368	"ECHOSTATUS_DSP_DEAD",
369	"ECHOSTATUS_DSP_TIMEOUT",
370	"ECHOSTATUS_INVALID_CHANNEL",
371	"ECHOSTATUS_CHANNEL_ALREADY_OPEN",
372	"ECHOSTATUS_DUCK_FULL",
373	"ECHOSTATUS_INVALID_INDEX",
374	"ECHOSTATUS_BAD_CARD_NAME",
375	"ECHOSTATUS_IRQ_NOT_OURS",
376	"",
377	"",
378	"",
379	"",
380	"",
381	"ECHOSTATUS_BUFFER_OVERFLOW",
382	"ECHOSTATUS_OPERATION_CANCELED",
383	"ECHOSTATUS_EVENT_NOT_OPEN",
384	"ECHOSTATUS_ASIC_NOT_LOADED"
385	"ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED",
386	"ECHOSTATUS_RESERVED",
387	"ECHOSTATUS_BAD_COOKIE",
388	"ECHOSTATUS_MIXER_DISABLED",
389	"ECHOSTATUS_NO_SUPER_INTERLEAVE",
390	"ECHOSTATUS_DUCK_NOT_WRAPPED"
391};
392
393
394
395// *** CEchoGals.cpp ***
396
397
398
399
400
401