xref: /haiku/src/add-ons/kernel/drivers/audio/echo/generic/CEchoGals.cpp (revision b28ed9e04a771e5de38be68abd08148c0bbafc56)
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 
47 PVOID 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 
70 VOID  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 
85 CEchoGals::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 
107 CEchoGals::~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 
161 ECHOSTATUS CEchoGals::AssignResources
162 (
163 	PVOID		pvSharedMemory,		// Ptr to DSP registers
164 	const char*		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 
206 ECHOSTATUS 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 
227 ECHOSTATUS 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 
284 ECHOSTATUS 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 //
348 const char *	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 
402