xref: /haiku/src/add-ons/kernel/drivers/audio/echo/generic/CMona.cpp (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 // ****************************************************************************
2 //
3 //		CMona.cpp
4 //
5 //		Implementation file for the CMona 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 "CMona.h"
32 
33 #define MONA_ANALOG_OUTPUT_LATENCY		59
34 #define MONA_ANALOG_INPUT_LATENCY		71
35 #define MONA_DIGITAL_OUTPUT_LATENCY		32
36 #define MONA_DIGITAL_INPUT_LATENCY		32
37 
38 
39 
40 /****************************************************************************
41 
42 	Construction and destruction
43 
44  ****************************************************************************/
45 
46 //===========================================================================
47 //
48 // Overload new & delete so memory for this object is allocated
49 //	from non-paged memory.
50 //
51 //===========================================================================
52 
53 PVOID CMona::operator new( size_t Size )
54 {
55 	PVOID 		pMemory;
56 	ECHOSTATUS 	Status;
57 
58 	Status = OsAllocateNonPaged(Size,&pMemory);
59 
60 	if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory ))
61 	{
62 		ECHO_DEBUGPRINTF(("CMona::operator new - memory allocation failed\n"));
63 
64 		pMemory = NULL;
65 	}
66 	else
67 	{
68 		memset( pMemory, 0, Size );
69 	}
70 
71 	return pMemory;
72 
73 }	// PVOID CMona::operator new( size_t Size )
74 
75 
76 VOID  CMona::operator delete( PVOID pVoid )
77 {
78 	if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) )
79 	{
80 		ECHO_DEBUGPRINTF(("CMona::operator delete memory free failed\n"));
81 	}
82 }	// VOID CMona::operator delete( PVOID pVoid )
83 
84 
85 //===========================================================================
86 //
87 // Constructor and destructor
88 //
89 //===========================================================================
90 
91 CMona::CMona( PCOsSupport pOsSupport )
92 		: CEchoGals( pOsSupport )
93 {
94 	ECHO_DEBUGPRINTF( ( "CMona::CMona() is born!\n" ) );
95 
96 	m_wAnalogOutputLatency = MONA_ANALOG_OUTPUT_LATENCY;
97 	m_wAnalogInputLatency = MONA_ANALOG_INPUT_LATENCY;
98 	m_wDigitalOutputLatency = MONA_DIGITAL_OUTPUT_LATENCY;
99 	m_wDigitalInputLatency = MONA_DIGITAL_INPUT_LATENCY;
100 }
101 
102 CMona::~CMona()
103 {
104 	ECHO_DEBUGPRINTF( ( "CMona::~CMona() is toast!\n" ) );
105 }
106 
107 
108 
109 
110 /****************************************************************************
111 
112 	Setup and hardware initialization
113 
114  ****************************************************************************/
115 
116 //===========================================================================
117 //
118 // Every card has an InitHw method
119 //
120 //===========================================================================
121 
122 ECHOSTATUS CMona::InitHw()
123 {
124 	ECHOSTATUS	Status;
125 
126 	//
127 	// Call the base method
128 	//
129 	if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) )
130 		return Status;
131 
132 	//
133 	// Create the DSP comm object
134 	//
135 	ECHO_ASSERT(NULL == m_pDspCommObject );
136 	m_pDspCommObject = new CMonaDspCommObject( (PDWORD) m_pvSharedMemory,
137 															 m_pOsSupport );
138 	if (NULL == m_pDspCommObject)
139 	{
140 		ECHO_DEBUGPRINTF(("CMona::InitHw - could not create DSP comm object\n"));
141 		return ECHOSTATUS_NO_MEM;
142 	}
143 
144 	//
145 	// Load the DSP, the PCI card ASIC, and the external box ASIC
146 	//
147 	GetDspCommObject()->LoadFirmware();
148 	if ( GetDspCommObject()->IsBoardBad() )
149 		return ECHOSTATUS_DSP_DEAD;
150 
151 	//
152 	// Clear the "bad board" flag; set the flags to indicate that
153 	// Mona can handle super-interleave and supports the digital
154 	// input auto-mute.
155 	//
156 	m_wFlags &= ~ECHOGALS_FLAG_BADBOARD;
157 	m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK |
158 				ECHOGALS_ROFLAG_DIGITAL_IN_AUTOMUTE;
159 
160 	//
161 	//	Must call this here after DSP is init to
162 	//	init gains and mutes
163 	//
164 	Status = InitLineLevels();
165 	if ( ECHOSTATUS_OK != Status )
166 		return Status;
167 
168 	//
169 	// Set the digital mode to S/PDIF RCA
170 	//
171 	SetDigitalMode( DIGITAL_MODE_SPDIF_RCA );
172 
173 	//
174 	// Set the S/PDIF output format to "professional"
175 	//
176 	SetProfessionalSpdif( TRUE );
177 
178 	//
179 	//	Get default sample rate from DSP
180 	//
181 	m_dwSampleRate = GetDspCommObject()->GetSampleRate();
182 
183 	ECHO_DEBUGPRINTF( ( "CMona::InitHw()\n" ) );
184 	return Status;
185 
186 }	// ECHOSTATUS CMona::InitHw()
187 
188 
189 
190 
191 /****************************************************************************
192 
193 	Informational methods
194 
195  ****************************************************************************/
196 
197 //===========================================================================
198 //
199 // Override GetCapabilities to enumerate unique capabilties for this card
200 //
201 //===========================================================================
202 
203 ECHOSTATUS CMona::GetCapabilities
204 (
205 	PECHOGALS_CAPS	pCapabilities
206 )
207 {
208 	ECHOSTATUS	Status;
209 
210 	Status = GetBaseCapabilities(pCapabilities);
211 	if ( ECHOSTATUS_OK != Status )
212 		return Status;
213 
214 	pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_WORD		|
215 												ECHO_CLOCK_BIT_SPDIF		|
216 												ECHO_CLOCK_BIT_ADAT;
217 
218 	return Status;
219 
220 }	// ECHOSTATUS CMona::GetCapabilities
221 
222 
223 //===========================================================================
224 //
225 // QueryAudioSampleRate is used to find out if this card can handle a
226 // given sample rate.
227 //
228 //===========================================================================
229 
230 ECHOSTATUS CMona::QueryAudioSampleRate
231 (
232 	DWORD		dwSampleRate
233 )
234 {
235 	if ( dwSampleRate !=  8000 &&
236 		  dwSampleRate != 11025 &&
237 		  dwSampleRate != 16000 &&
238 		  dwSampleRate != 22050 &&
239 		  dwSampleRate != 32000 &&
240 		  dwSampleRate != 44100 &&
241 		  dwSampleRate != 48000 &&
242 		  dwSampleRate != 88200 &&
243 		  dwSampleRate != 96000 )
244 	{
245 		ECHO_DEBUGPRINTF(
246 			("CMona::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate) );
247 		return ECHOSTATUS_BAD_FORMAT;
248 	}
249 	if ( dwSampleRate >= 88200 && DIGITAL_MODE_ADAT == GetDigitalMode() )
250 	{
251 		ECHO_DEBUGPRINTF(
252 			("CMona::QueryAudioSampleRate() Sample rate cannot be "
253 			 "set to 88,200 Hz or 96,000 Hz in ADAT mode\n") );
254 		return ECHOSTATUS_BAD_FORMAT;
255 	}
256 
257 	ECHO_DEBUGPRINTF( ( "CMona::QueryAudioSampleRate()\n" ) );
258 	return ECHOSTATUS_OK;
259 }	// ECHOSTATUS CMona::QueryAudioSampleRate
260 
261 
262 void CMona::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate)
263 {
264 	dwMinRate = 8000;
265 	dwMaxRate = 96000;
266 }
267 
268 
269 //===========================================================================
270 //
271 // GetInputClockDetect returns a bitmask consisting of all the input
272 // clocks currently connected to the hardware; this changes as the user
273 // connects and disconnects clock inputs.
274 //
275 // You should use this information to determine which clocks the user is
276 // allowed to select.
277 //
278 // Mona supports S/PDIF, word, and ADAT input clocks.
279 //
280 //===========================================================================
281 
282 ECHOSTATUS CMona::GetInputClockDetect(DWORD &dwClockDetectBits)
283 {
284 	//ECHO_DEBUGPRINTF(("CMona::GetInputClockDetect\n"));
285 
286 	if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
287 	{
288 		ECHO_DEBUGPRINTF( ("CMona::GetInputClockDetect: DSP Dead!\n") );
289 		return ECHOSTATUS_DSP_DEAD;
290 	}
291 
292 	//
293 	// Map the DSP clock detect bits to the generic driver clock detect bits
294 	//
295 	DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect();
296 
297 	dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL;
298 
299 	if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_SPDIF))
300 		dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF;
301 
302 	if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ADAT))
303 		dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT;
304 
305 	if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_WORD))
306 		dwClockDetectBits |= ECHO_CLOCK_BIT_WORD;
307 
308 	return ECHOSTATUS_OK;
309 
310 }	// GetInputClockDetect
311 
312 
313 // *** CMona.cpp ***
314