xref: /haiku/src/add-ons/kernel/drivers/audio/echo/generic/CEchoGals.cpp (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
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 	INT32	i;
91 
92 	ASSERT( pOsSupport );
93 
94 	m_pOsSupport = pOsSupport;		// Ptr to OS Support methods & data
95 
96 	m_wFlags = ECHOGALS_FLAG_BADBOARD;
97 
98 	for ( i = 0; i < ECHO_MAXAUDIOPIPES; i++ )
99 	{
100 		m_wBytesPerSample[ i ] = 1;
101 	}
102 
103 	m_dwLockedSampleRate	= 44100;
104 
105 }	// CEchoGals::CEchoGals()
106 
107 
108 //===========================================================================
109 //
110 // Destructor
111 //
112 //===========================================================================
113 
114 CEchoGals::~CEchoGals()
115 {
116 	//
117 	// Free stuff
118 	//
119 	delete m_pDspCommObject;	// This powers down the DSP
120 
121 	//
122 	// Clean up the ducks
123 	//
124 	WORD i;
125 
126 	for (i = 0; i < ECHO_MAXAUDIOPIPES; i++)
127 	{
128 		if (NULL != m_DaffyDucks[i])
129 			delete m_DaffyDucks[i];
130 	}
131 
132 	//
133 	//	Clean up the mixer client list
134 	//
135 	while (NULL != m_pMixerClients)
136 	{
137 		ECHO_MIXER_CLIENT *pDeadClient;
138 
139 		pDeadClient = m_pMixerClients;
140 		m_pMixerClients = pDeadClient->pNext;
141 		OsFreeNonPaged(pDeadClient);
142 	}
143 
144 	ECHO_DEBUGPRINTF( ( "CEchoGals::~CEchoGals() is toast!\n" ) );
145 
146 }	// CEchoGals::~CEchoGals()
147 
148 
149 
150 
151 /****************************************************************************
152 
153 	CEchoGals setup and hardware initialization
154 
155  ****************************************************************************/
156 
157 //===========================================================================
158 //
159 // AssignResources does just what you'd expect.
160 //
161 // Note that pvSharedMemory is a logical pointer - that is, the driver
162 // will dereference this pointer to access the memory-mapped regisers on
163 // the DSP.  The caller needs to take the physical address from the PCI
164 // config space and map it.
165 //
166 //===========================================================================
167 
168 ECHOSTATUS CEchoGals::AssignResources
169 (
170 	PVOID		pvSharedMemory,		// Ptr to DSP registers
171 	PCHAR		pszCardName				// Caller gets from registry
172 )
173 {
174 	//
175 	//	Use ASSERT to be sure this isn't called twice!
176 	//
177 	ASSERT( NULL == m_pvSharedMemory );
178 
179 	//
180 	//	Check and store the parameters
181 	//
182 	ASSERT( pvSharedMemory );
183 	if ( NULL == pszCardName )
184 	{
185 		return( ECHOSTATUS_BAD_CARD_NAME );
186 	}
187 	m_pvSharedMemory = pvSharedMemory;	// Shared memory addr assigned by PNP
188 
189 	//
190 	//	Copy card name & make sure we don't overflow our buffer
191 	//
192 	strncpy( m_szCardInstallName, pszCardName, ECHO_MAXNAMELEN-1 );
193 	m_szCardInstallName[ ECHO_MAXNAMELEN-1 ] = 0;
194 
195 	return ECHOSTATUS_OK;
196 
197 }	// ECHOSTATUS CEchoGals::AssignResources
198 
199 
200 //===========================================================================
201 //
202 // InitHw is device-specific and so does nothing here; it is overridden
203 // in the derived classes.
204 //
205 //	The correct sequence is:
206 //
207 //	Construct the appropriate CEchoGals-derived object for the card
208 // Call AssignResources
209 // Call InitHw
210 //
211 //===========================================================================
212 
213 ECHOSTATUS CEchoGals::InitHw()
214 {
215 	//
216 	//	Use ASSERT to be sure AssignResources was called!
217 	//
218 	ASSERT( m_pvSharedMemory );
219 
220 	return ECHOSTATUS_OK;
221 
222 } // ECHOSTATUS CEchoGals::InitHw()
223 
224 
225 //===========================================================================
226 //
227 // This method initializes classes to control the mixer controls for
228 // the busses and pipes.  This is a protected method; it is called
229 // from each of the CEchoGals derived classes once the DSP is up
230 // and running.
231 //
232 //===========================================================================
233 
234 ECHOSTATUS CEchoGals::InitLineLevels()
235 {
236 	ECHOSTATUS	Status = ECHOSTATUS_OK;
237 	WORD			i;
238 
239 	m_fMixerDisabled = TRUE;
240 
241 	if ( 	(NULL == GetDspCommObject()) ||
242 			(GetDspCommObject()->IsBoardBad() ) )
243 	{
244 		return ECHOSTATUS_DSP_DEAD;
245 	}
246 
247 	//
248 	// Do output busses first since output pipes & monitors
249 	// depend on output bus values
250 	//
251 	for ( i = 0; i < GetNumBussesOut(); i++ )
252 	{
253 		m_BusOutLineLevels[ i ].Init( i, this );
254 	}
255 
256 	Status = m_PipeOutCtrl.Init(this);
257 	if (ECHOSTATUS_OK != Status)
258 		return Status;
259 
260 	Status = m_MonitorCtrl.Init(this);
261 	if (ECHOSTATUS_OK != Status)
262 		return Status;
263 
264 	for ( i = 0; i < GetNumBussesIn(); i++ )
265 	{
266 		m_BusInLineLevels[ i ].Init(	i,	this );
267 	}
268 
269 	m_fMixerDisabled = FALSE;
270 
271 	return Status;
272 
273 }	// ECHOSTATUS CEchoGals::InitLineLevels()
274 
275 
276 
277 
278 /******************************************************************************
279 
280  CEchoGals interrupt handler functions
281 
282  ******************************************************************************/
283 
284 //===========================================================================
285 //
286 // This isn't the interrupt handler itself; rather, the OS-specific layer
287 // of the driver has an interrupt handler that calls this function.
288 //
289 //===========================================================================
290 
291 ECHOSTATUS CEchoGals::ServiceIrq(BOOL &fMidiReceived)
292 {
293 	CDspCommObject *pDCO;
294 
295 	//
296 	// Read the DSP status register and see if this DSP
297 	// generated this interrupt
298 	//
299 	fMidiReceived = FALSE;
300 
301 	pDCO = GetDspCommObject();
302 	if ( pDCO->GetStatusReg() & CHI32_STATUS_IRQ )
303 	{
304 
305 #ifdef MIDI_SUPPORT
306 
307 		//
308 		// If this was a MIDI input interrupt, get the MIDI input data
309 		//
310 		DWORD dwMidiInCount;
311 
312 		pDCO->ReadMidi( 0, dwMidiInCount );	  // The count is at index 0
313 		if ( 0 != dwMidiInCount )
314 		{
315 			m_MidiIn.ServiceIrq();
316 			fMidiReceived = TRUE;
317 		}
318 
319 #endif // MIDI_SUPPORT
320 
321 		//
322 		//	Clear the hardware interrupt
323 		//
324 		pDCO->AckInt();
325 
326 		return ECHOSTATUS_OK;
327 	}
328 
329 	//
330 	// This interrupt line must be shared
331 	//
332 	/*
333 	ECHO_DEBUGPRINTF( ("CEchoGals::ServiceIrq() %s\tInterrupt not ours!\n",
334 							 GetDeviceName()) );
335 	*/
336 
337 	return ECHOSTATUS_IRQ_NOT_OURS;
338 
339 }	// ECHOSTATUS CEchoGals::ServiceIrq()
340 
341 
342 
343 
344 /****************************************************************************
345 
346 	Character strings for the ECHOSTATUS return values -
347 	useful for debugging.
348 
349  ****************************************************************************/
350 
351 //
352 // pStatusStrs is used if you want to print out a friendlier version of
353 // the various ECHOSTATUS codes.
354 //
355 char *	pStatusStrs[ECHOSTATUS_LAST] =
356 {
357 	"ECHOSTATUS_OK",
358 	"ECHOSTATUS_BAD_FORMAT",
359 	"ECHOSTATUS_BAD_BUFFER_SIZE",
360 	"ECHOSTATUS_CANT_OPEN",
361 	"ECHOSTATUS_CANT_CLOSE",
362 	"ECHOSTATUS_CHANNEL_NOT_OPEN",
363 	"ECHOSTATUS_BUSY",
364 	"ECHOSTATUS_BAD_LEVEL",
365 	"ECHOSTATUS_NO_MIDI",
366 	"ECHOSTATUS_CLOCK_NOT_SUPPORTED",
367 	"ECHOSTATUS_CLOCK_NOT_AVAILABLE",
368 	"ECHOSTATUS_BAD_CARDID",
369 	"ECHOSTATUS_NOT_SUPPORTED",
370 	"ECHOSTATUS_BAD_NOTIFY_SIZE",
371 	"ECHOSTATUS_INVALID_PARAM",
372 	"ECHOSTATUS_NO_MEM",
373 	"ECHOSTATUS_NOT_SHAREABLE",
374 	"ECHOSTATUS_FIRMWARE_LOADED",
375 	"ECHOSTATUS_DSP_DEAD",
376 	"ECHOSTATUS_DSP_TIMEOUT",
377 	"ECHOSTATUS_INVALID_CHANNEL",
378 	"ECHOSTATUS_CHANNEL_ALREADY_OPEN",
379 	"ECHOSTATUS_DUCK_FULL",
380 	"ECHOSTATUS_INVALID_INDEX",
381 	"ECHOSTATUS_BAD_CARD_NAME",
382 	"ECHOSTATUS_IRQ_NOT_OURS",
383 	"",
384 	"",
385 	"",
386 	"",
387 	"",
388 	"ECHOSTATUS_BUFFER_OVERFLOW",
389 	"ECHOSTATUS_OPERATION_CANCELED",
390 	"ECHOSTATUS_EVENT_NOT_OPEN",
391 	"ECHOSTATUS_ASIC_NOT_LOADED"
392 	"ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED",
393 	"ECHOSTATUS_RESERVED",
394 	"ECHOSTATUS_BAD_COOKIE",
395 	"ECHOSTATUS_MIXER_DISABLED",
396 	"ECHOSTATUS_NO_SUPER_INTERLEAVE",
397 	"ECHOSTATUS_DUCK_NOT_WRAPPED"
398 };
399 
400 
401 
402 // *** CEchoGals.cpp ***
403 
404 
405 
406 
407 
408