BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / drivers / audio / echo / generic / CGina24DspCommObject.cpp
blob99282ada4f3d6f0bc41ab475ae7376b013f863ae
1 // ****************************************************************************
2 //
3 // CGina24DspCommObject.cpp
4 //
5 // Implementation file for Gina24 DSP interface class.
6 //
7 // ----------------------------------------------------------------------------
8 //
9 // This file is part of Echo Digital Audio's generic driver library.
10 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005
11 // All rights reserved
12 // www.echoaudio.com
14 // This library is free software; you can redistribute it and/or
15 // modify it under the terms of the GNU Lesser General Public
16 // License as published by the Free Software Foundation; either
17 // version 2.1 of the License, or (at your option) any later version.
19 // This library is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 // Lesser General Public License for more details.
24 // You should have received a copy of the GNU Lesser General Public
25 // License along with this library; if not, write to the Free Software
26 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 // ****************************************************************************
30 #include "CEchoGals.h"
31 #include "CGina24DspCommObject.h"
33 #include "Gina24DSP.c"
34 #include "Gina24_361DSP.c"
36 #include "Gina24ASIC.c"
37 #include "Gina24ASIC_361.c"
40 /****************************************************************************
42 Construction and destruction
44 ****************************************************************************/
46 //===========================================================================
48 // Constructor
50 //===========================================================================
52 CGina24DspCommObject::CGina24DspCommObject
54 PDWORD pdwRegBase, // Virtual ptr to DSP registers
55 PCOsSupport pOsSupport
56 ) : CGMLDspCommObject( pdwRegBase, pOsSupport )
58 strcpy( m_szCardName, "Gina24" );
59 m_pdwDspRegBase = pdwRegBase; // Virtual addr DSP's register base
61 m_wNumPipesOut = 16;
62 m_wNumPipesIn = 10;
63 m_wNumBussesOut = 16;
64 m_wNumBussesIn = 10;
65 m_wFirstDigitalBusOut = 8;
66 m_wFirstDigitalBusIn = 2;
68 m_fHasVmixer = FALSE;
70 m_wNumMidiOut = 0; // # MIDI out channels
71 m_wNumMidiIn = 0; // # MIDI in channels
72 m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 44100 );
73 // Need this in cse we start with ESYNC
74 m_bHasASIC = TRUE;
77 // Gina24 comes in both '301 and '361 flavors; pick the correct one.
78 //
79 if ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() )
80 m_pwDspCodeToLoad = pwGina24_361DSP;
81 else
82 m_pwDspCodeToLoad = pwGina24DSP;
84 m_byDigitalMode = DIGITAL_MODE_SPDIF_RCA;
85 m_bProfessionalSpdif = FALSE;
86 } // CGina24DspCommObject::CGina24DspCommObject( DWORD dwPhysRegBase )
89 //===========================================================================
91 // Destructor
93 //===========================================================================
95 CGina24DspCommObject::~CGina24DspCommObject()
97 ECHO_DEBUGPRINTF(("CGina24DspCommObject::~CGina24DspCommObject - "
98 "hasta la vista!\n"));
99 } // CGina24DspCommObject::~CGina24DspCommObject()
104 /****************************************************************************
106 Hardware setup and config
108 ****************************************************************************/
110 //===========================================================================
112 // Gina24 has an ASIC on the PCI card which must be loaded for anything
113 // interesting to happen.
115 //===========================================================================
117 BOOL CGina24DspCommObject::LoadASIC()
119 DWORD dwControlReg, dwSize;
120 PBYTE pbAsic;
122 if ( m_bASICLoaded )
123 return TRUE;
126 // Give the DSP a few milliseconds to settle down
128 m_pOsSupport->OsSnooze( 10000 );
131 // Pick the correct ASIC for '301 or '361 Gina24
133 if ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() )
135 pbAsic = pbGina24ASIC_361;
136 dwSize = sizeof( pbGina24ASIC_361 );
138 else
140 pbAsic = pbGina24ASIC;
141 dwSize = sizeof( pbGina24ASIC );
143 if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_GINA24_ASIC,
144 pbAsic,
145 dwSize ) )
146 return FALSE;
148 m_pbyAsic = pbAsic;
151 // Now give the new ASIC a little time to set up
153 m_pOsSupport->OsSnooze( 10000 );
156 // See if it worked
158 CheckAsicStatus();
161 // Set up the control register if the load succeeded -
163 // 48 kHz, internal clock, S/PDIF RCA mode
165 if ( m_bASICLoaded )
167 dwControlReg = GML_CONVERTER_ENABLE | GML_48KHZ;
168 WriteControlReg( dwControlReg, TRUE );
171 return m_bASICLoaded;
173 } // BOOL CGina24DspCommObject::LoadASIC()
176 //===========================================================================
178 // Set the input clock to internal, S/PDIF, ADAT
180 //===========================================================================
182 ECHOSTATUS CGina24DspCommObject::SetInputClock(WORD wClock)
184 BOOL bSetRate;
185 BOOL bWriteControlReg;
186 DWORD dwControlReg;
188 ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetInputClock:\n") );
190 dwControlReg = GetControlRegister();
193 // Mask off the clock select bits
195 dwControlReg &= GML_CLOCK_CLEAR_MASK;
197 bSetRate = FALSE;
198 bWriteControlReg = TRUE;
199 switch ( wClock )
201 case ECHO_CLOCK_INTERNAL :
203 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to INTERNAL\n" ) );
205 bSetRate = TRUE;
206 bWriteControlReg = FALSE;
207 break;
208 } // ECHO_CLOCK_INTERNAL
210 case ECHO_CLOCK_SPDIF :
212 if ( DIGITAL_MODE_ADAT == GetDigitalMode() )
214 return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
217 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to SPDIF\n" ) );
219 dwControlReg |= GML_SPDIF_CLOCK;
221 if ( GML_CLOCK_DETECT_BIT_SPDIF96 & GetInputClockDetect() )
223 dwControlReg |= GML_DOUBLE_SPEED_MODE;
225 else
227 dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
229 break;
230 } // ECHO_CLOCK_SPDIF
232 case ECHO_CLOCK_ADAT :
234 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ADAT\n" ) );
236 if ( DIGITAL_MODE_ADAT != GetDigitalMode() )
238 return ECHOSTATUS_CLOCK_NOT_AVAILABLE;
241 dwControlReg |= GML_ADAT_CLOCK;
242 dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
243 break;
244 } // ECHO_CLOCK_ADAT
246 case ECHO_CLOCK_ESYNC :
248 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ESYNC\n" ) );
250 dwControlReg |= GML_ESYNC_CLOCK;
251 dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
252 break;
253 } // ECHO_CLOCK_ESYNC
255 case ECHO_CLOCK_ESYNC96 :
257 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ESYNC96\n" ) );
259 dwControlReg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE;
260 break;
261 } // ECHO_CLOCK_ESYNC96
263 default :
264 ECHO_DEBUGPRINTF(("Input clock 0x%x not supported for Gina24\n",wClock));
265 ECHO_DEBUGBREAK();
266 return ECHOSTATUS_CLOCK_NOT_SUPPORTED;
267 } // switch (wInputClock)
271 // Winner! Save the new input clock.
273 m_wInputClock = wClock;
276 // Write the control reg if that's called for
278 if ( bWriteControlReg )
280 WriteControlReg( dwControlReg, TRUE );
283 // Set Gina24 sample rate to something sane if word or superword is
284 // being turned off
285 if ( bSetRate )
287 SetSampleRate( GetSampleRate() );
289 return ECHOSTATUS_OK;
291 } // ECHOSTATUS CGina24DspCommObject::SetInputClock
294 //===========================================================================
296 // SetSampleRate
298 // Set the audio sample rate for Gina24
300 //===========================================================================
302 DWORD CGina24DspCommObject::SetSampleRate( DWORD dwNewSampleRate )
304 DWORD dwControlReg, dwNewClock;
307 // Only set the clock for internal mode. If the clock is not set to
308 // internal, try and re-set the input clock; this more transparently
309 // handles switching between single and double-speed mode
311 if ( GetInputClock() != ECHO_CLOCK_INTERNAL )
313 ECHO_DEBUGPRINTF( ( "CGina24DspCommObject::SetSampleRate: Cannot set sample rate - "
314 "clock not set to CLK_CLOCKININTERNAL\n" ) );
317 // Save the rate anyhow
319 m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
322 // Set the input clock to the current value
324 SetInputClock( m_wInputClock );
326 return GetSampleRate();
330 // Set the sample rate
332 dwNewClock = 0;
334 dwControlReg = GetControlRegister();
335 dwControlReg &= GML_CLOCK_CLEAR_MASK;
336 dwControlReg &= GML_SPDIF_RATE_CLEAR_MASK;
338 switch ( dwNewSampleRate )
340 case 96000 :
341 dwNewClock = GML_96KHZ;
342 break;
344 case 88200 :
345 dwNewClock = GML_88KHZ;
346 break;
348 case 48000 :
349 dwNewClock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
350 break;
352 case 44100 :
353 dwNewClock = GML_44KHZ;
355 // Professional mode
357 if ( dwControlReg & GML_SPDIF_PRO_MODE )
359 dwNewClock |= GML_SPDIF_SAMPLE_RATE0;
361 break;
363 case 32000 :
364 dwNewClock = GML_32KHZ |
365 GML_SPDIF_SAMPLE_RATE0 |
366 GML_SPDIF_SAMPLE_RATE1;
367 break;
369 case 22050 :
370 dwNewClock = GML_22KHZ;
371 break;
373 case 16000 :
374 dwNewClock = GML_16KHZ;
375 break;
377 case 11025 :
378 dwNewClock = GML_11KHZ;
379 break;
381 case 8000 :
382 dwNewClock = GML_8KHZ;
383 break;
385 default :
386 ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetSampleRate: %ld "
387 "invalid!\n", dwNewSampleRate) );
388 ECHO_DEBUGBREAK();
389 return( GetSampleRate() );
392 dwControlReg |= dwNewClock;
395 // Send the new value to the DSP
397 if ( ECHOSTATUS_OK == WriteControlReg( dwControlReg ) )
399 m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate );
401 ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetSampleRate: %ld "
402 "clock %ld\n", dwNewSampleRate, dwNewClock) );
405 return GetSampleRate();
407 } // DWORD CGina24DspCommObject::SetSampleRate( DWORD dwNewSampleRate )
411 // **** CGina24DspCommObject.cpp ****