xref: /haiku/src/add-ons/kernel/drivers/audio/echo/generic/CGMLDspCommObject.cpp (revision 239222b2369c39dc52df52b0a7cdd6cc0a91bc92)
1 // ****************************************************************************
2 //
3 //  	CGMLDspCommObject.cpp
4 //
5 //		Implementation file for GML cards (Gina24, Mona, and Layla24).
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
13 //
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.
18 //
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.
23 //
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
27 //
28 // ****************************************************************************
29 
30 #include "CEchoGals.h"
31 #include "CGMLDspCommObject.h"
32 
33 //===========================================================================
34 //
35 // Set the S/PDIF output format
36 //
37 //===========================================================================
38 
39 void CGMLDspCommObject::SetProfessionalSpdif
40 (
41 	BOOL bNewStatus
42 )
43 {
44 	DWORD		dwControlReg;
45 
46 	dwControlReg = GetControlRegister();
47 
48 	//
49 	// Clear the current S/PDIF flags
50 	//
51 	dwControlReg &= GML_SPDIF_FORMAT_CLEAR_MASK;
52 
53 	//
54 	// Set the new S/PDIF flags depending on the mode
55 	//
56 	dwControlReg |= 	GML_SPDIF_TWO_CHANNEL |
57 							GML_SPDIF_24_BIT |
58 							GML_SPDIF_COPY_PERMIT;
59 	if ( bNewStatus )
60 	{
61 		//
62 		// Professional mode
63 		//
64 		dwControlReg |= GML_SPDIF_PRO_MODE;
65 
66 		switch ( GetSampleRate() )
67 		{
68 			case 32000 :
69 				dwControlReg |= GML_SPDIF_SAMPLE_RATE0 |
70 									 GML_SPDIF_SAMPLE_RATE1;
71 				break;
72 
73 			case 44100 :
74 				dwControlReg |= GML_SPDIF_SAMPLE_RATE0;
75 				break;
76 
77 			case 48000 :
78 				dwControlReg |= GML_SPDIF_SAMPLE_RATE1;
79 				break;
80 		}
81 	}
82 	else
83 	{
84 		//
85 		// Consumer mode
86 		//
87 		switch ( GetSampleRate() )
88 		{
89 			case 32000 :
90 				dwControlReg |= GML_SPDIF_SAMPLE_RATE0 |
91 									 GML_SPDIF_SAMPLE_RATE1;
92 				break;
93 
94 			case 48000 :
95 				dwControlReg |= GML_SPDIF_SAMPLE_RATE1;
96 				break;
97 		}
98 	}
99 
100 	//
101 	// Handle the non-audio bit
102 	//
103 	if (m_bNonAudio)
104 		dwControlReg |= GML_SPDIF_NOT_AUDIO;
105 
106 	//
107 	// Write the control reg
108 	//
109 	WriteControlReg( dwControlReg );
110 
111 	m_bProfessionalSpdif = bNewStatus;
112 
113 	ECHO_DEBUGPRINTF( ("CGMLDspCommObject::SetProfessionalSpdif to %s\n",
114 							( bNewStatus ) ? "Professional" : "Consumer") );
115 
116 }	// void CGMLDspCommObject::SetProfessionalSpdif( ... )
117 
118 
119 
120 
121 //===========================================================================
122 //
123 // SetSpdifOutNonAudio
124 //
125 // Set the state of the non-audio status bit in the S/PDIF out status bits
126 //
127 //===========================================================================
128 
129 void CGMLDspCommObject::SetSpdifOutNonAudio(BOOL bNonAudio)
130 {
131 	DWORD		dwControlReg;
132 
133 	dwControlReg = GetControlRegister();
134 	if (bNonAudio)
135 	{
136 		dwControlReg |= GML_SPDIF_NOT_AUDIO;
137 	}
138 	else
139 	{
140 		dwControlReg &= ~GML_SPDIF_NOT_AUDIO;
141 	}
142 
143 	m_bNonAudio = bNonAudio;
144 
145 	WriteControlReg( dwControlReg );
146 }
147 
148 
149 
150 //===========================================================================
151 //
152 // WriteControlReg
153 //
154 // Most configuration of Gina24, Layla24, or Mona is
155 // accomplished by writing the control register.  WriteControlReg
156 // sends the new control register value to the DSP.
157 //
158 //===========================================================================
159 
160 ECHOSTATUS CGMLDspCommObject::WriteControlReg
161 (
162 	DWORD dwControlReg,
163 	BOOL 	fForceWrite
164 )
165 {
166 	ECHO_DEBUGPRINTF(("CGMLDspCommObject::WriteControlReg 0x%lx\n",dwControlReg));
167 
168 	if ( !m_bASICLoaded )
169 	{
170 		ECHO_DEBUGPRINTF(("CGMLDspCommObject::WriteControlReg - ASIC not loaded\n"));
171 		return( ECHOSTATUS_ASIC_NOT_LOADED );
172 	}
173 
174 
175 	if ( !WaitForHandshake() )
176 	{
177 		ECHO_DEBUGPRINTF(("CGMLDspCommObject::WriteControlReg - no handshake\n"));
178 		return ECHOSTATUS_DSP_DEAD;
179 	}
180 
181 #ifdef DIGITAL_INPUT_AUTO_MUTE_SUPPORT
182 	//
183 	// Handle the digital input auto-mute
184 	//
185 	if (TRUE == m_fDigitalInAutoMute)
186 		dwControlReg |= GML_DIGITAL_IN_AUTO_MUTE;
187 	else
188 		dwControlReg &= ~GML_DIGITAL_IN_AUTO_MUTE;
189 #endif
190 
191 	//
192 	// Write the control register
193 	//
194 	if (fForceWrite || (dwControlReg != GetControlRegister()) )
195 	{
196 		SetControlRegister( dwControlReg );
197 
198 		ECHO_DEBUGPRINTF( ("CGMLDspCommObject::WriteControlReg: Setting 0x%lx\n",
199 								 dwControlReg) );
200 
201 		ClearHandshake();
202 		return SendVector( DSP_VC_WRITE_CONTROL_REG );
203 	}
204 	else
205 	{
206 		ECHO_DEBUGPRINTF( ("CGMLDspCommObject::WriteControlReg: control reg is already 0x%lx\n",
207 								 dwControlReg) );
208 	}
209 
210 	return ECHOSTATUS_OK;
211 
212 } // ECHOSTATUS CGMLDspCommObject::WriteControlReg( DWORD dwControlReg )
213 
214 //===========================================================================
215 //
216 // SetDigitalMode
217 //
218 //===========================================================================
219 
220 ECHOSTATUS CGMLDspCommObject::SetDigitalMode
221 (
222 	BYTE	byNewMode
223 )
224 {
225 	WORD		wInvalidClock;
226 
227 	//
228 	// See if the current input clock doesn't match the new digital mode
229 	//
230 	switch (byNewMode)
231 	{
232 		case DIGITAL_MODE_SPDIF_RCA :
233 		case DIGITAL_MODE_SPDIF_OPTICAL :
234 			wInvalidClock = ECHO_CLOCK_ADAT;
235 			break;
236 
237 		case DIGITAL_MODE_ADAT :
238 			wInvalidClock = ECHO_CLOCK_SPDIF;
239 			break;
240 
241 		default :
242 			wInvalidClock = 0xffff;
243 			break;
244 	}
245 
246 	if (wInvalidClock == GetInputClock())
247 	{
248 		SetInputClock( ECHO_CLOCK_INTERNAL );
249 		SetSampleRate( 48000 );
250 	}
251 
252 	//
253 	// Clear the current digital mode
254 	//
255 	DWORD dwControlReg;
256 
257 	dwControlReg = GetControlRegister();
258 	dwControlReg &= GML_DIGITAL_MODE_CLEAR_MASK;
259 
260 	//
261 	// Tweak the control reg
262 	//
263 	switch ( byNewMode )
264 	{
265 		case DIGITAL_MODE_SPDIF_RCA :
266 			break;
267 
268 		case DIGITAL_MODE_SPDIF_OPTICAL :
269 			dwControlReg |= GML_SPDIF_OPTICAL_MODE;
270 			break;
271 
272 		case DIGITAL_MODE_ADAT :
273 			dwControlReg |= GML_ADAT_MODE;
274 			dwControlReg &= ~GML_DOUBLE_SPEED_MODE;
275 			break;
276 
277 		default :
278 			return ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED;
279 	}
280 
281 	//
282 	// Write the control reg
283 	//
284 	WriteControlReg( dwControlReg );
285 
286 	m_byDigitalMode = byNewMode;
287 
288 	ECHO_DEBUGPRINTF( ("CGMLDspCommObject::SetDigitalMode to %ld\n",
289 							(DWORD) m_byDigitalMode) );
290 
291 	return ECHOSTATUS_OK;
292 
293 }	// ECHOSTATUS CGMLDspCommObject::SetDigitalMode
294 
295 
296 // **** CGMLDspCommObject.cpp ****
297