2 /*
3 Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 /**
37 * \file audio_dc_config.c
38 *
39 * \brief Configures Audio daughter card HW modules
40 *
41 */
43 #include "audio_dc_cfg.h"
44 #include "vproccmds_a.h"
45 #include <stdarg.h>
46 #include "string.h"
48 Platform_STATUS audioHDMIConfig(void);
50 #define HSR4_I2C_ADDR 0x5D
51 #define HSR4_I2C_PORT_NUM I2C_PORT_1
53 /* ------------------------------------------------------------------------ *
54 * Prototypes *
55 * ------------------------------------------------------------------------ */
57 /**
58 * \brief Initializes ADC module
59 *
60 * This function initializes and configures the ADC modules
61 * on audio daughter card
62 *
63 * \param devId [IN] ADC Device Id
64 * \param config [IN] ADC configuration parameters
65 *
66 * \return Platform_EOK on Success or error code
67 */
68 Platform_STATUS audioAdcConfig(AdcDevId devId, AdcConfig *config)
69 {
70 Platform_STATUS status;
72 if(config == NULL)
73 {
74 IFPRINT(platform_write("Invalid Inputs\n"));
75 return (Platform_EINVALID);
76 }
78 /* Initialize all the HW instances of ADC */
79 status = platformAudioAdcInit(devId);
80 if(status != Platform_EOK)
81 {
82 IFPRINT(platform_write("audioAdcConfig : platformaudioAdcConfig Failed\n"));
83 return (status);
84 }
86 /* Set ADC channel gain */
87 status = platformAudioAdcSetGain(devId, ADC_CH_ALL, config->gain);
88 if(status != Platform_EOK)
89 {
90 IFPRINT(platform_write("audioAdcConfig : platformAudioAdcSetGain Failed\n"));
91 return (status);
92 }
94 /* Configure Left input mux for ADC1L */
95 status = platformAudioAdcSetLeftInputMux(devId, ADC_CH1_LEFT,
96 config->adc1LMux);
97 if(status != Platform_EOK)
98 {
99 IFPRINT(platform_write("audioAdcConfig : platformAudioAdcSetLeftInputMux Failed\n"));
100 return (status);
101 }
103 /* Configure Left input mux for ADC2L*/
104 status = platformAudioAdcSetLeftInputMux(devId, ADC_CH2_LEFT,
105 config->adc2LMux);
106 if(status != Platform_EOK)
107 {
108 IFPRINT(platform_write("audioAdcConfig : platformAudioAdcSetLeftInputMux Failed\n"));
109 return (status);
110 }
112 /* Configure Right input mux for ADC1R */
113 status = platformAudioAdcSetRightInputMux(devId, ADC_CH1_RIGHT,
114 config->adc1RMux);
115 if(status != Platform_EOK)
116 {
117 IFPRINT(platform_write("audioAdcConfig : platformAudioAdcSetRightInputMux Failed\n"));
118 return (status);
119 }
121 /* Configure Right input mux for ADC2R */
122 status = platformAudioAdcSetRightInputMux(devId, ADC_CH2_RIGHT,
123 config->adc2RMux);
124 if(status != Platform_EOK)
125 {
126 IFPRINT(platform_write("audioAdcConfig : platformAudioAdcSetRightInputMux Failed\n"));
127 return (status);
128 }
130 /* Configure audio data format */
131 status = platformAudioAdcDataConfig(devId, config->wlen, config->format);
132 if(status != Platform_EOK)
133 {
134 IFPRINT(platform_write("audioAdcConfig : platformAudioAdcDataConfig Failed\n"));
135 return (status);
136 }
138 /* Configure all the interrupts */
139 status = platformAudioAdcConfigIntr(devId, ADC_INTR_ALL,
140 config->intEnable);
141 if(status != Platform_EOK)
142 {
143 IFPRINT(platform_write("audioAdcConfig : platformAudioAdcConfigIntr Failed\n"));
144 return (status);
145 }
147 return (status);
148 }
150 /**
151 * \brief Initializes DAC module
152 *
153 * This function initializes and configures the DAC modules
154 * on audio daughter card
155 *
156 * \param devId [IN] DAC Device Id
157 * \param config [IN] DAC configuration parameters
158 *
159 * \return Platform_EOK on Success or error code
160 */
161 Platform_STATUS audioDacConfig(DacDevId devId, DacConfig *config)
162 {
163 Platform_STATUS status;
165 if(config == NULL)
166 {
167 IFPRINT(platform_write("Invalid Inputs\n"));
168 return (Platform_EINVALID);
169 }
171 /* Initialize Audio DAC */
172 status = platformAudioDacInit(devId);
173 if(status != Platform_EOK)
174 {
175 IFPRINT(platform_write("audioDacConfig : platformaudioDacConfig Failed\n"));
176 return (status);
177 }
179 /* Configure AMUTE control event */
180 status = platformAudioDacAmuteCtrl(devId, config->amuteCtrl,
181 config->amuteEnable);
182 if(status != Platform_EOK)
183 {
184 IFPRINT(platform_write("audioDacConfig : platformAudioDacAmuteCtrl Failed\n"));
185 return (status);
186 }
188 /* Set sampling mode */
189 status = platformAudioDacSetSamplingMode(devId, config->samplingMode);
190 if(status != Platform_EOK)
191 {
192 IFPRINT(platform_write("audioDacConfig : platformAudioDacSetSamplingMode Failed\n"));
193 return (status);
194 }
196 /* Set data format */
197 status = platformAudioDacSetDataFormat(devId, config->dataFormat);
198 if(status != Platform_EOK)
199 {
200 IFPRINT(platform_write("audioDacConfig : platformAudioDacSetDataFormat Failed\n"));
201 return (status);
202 }
204 /* Enable soft mute control */
205 status = platformAudioDacSoftMuteCtrl(devId, DAC_CHAN_ALL,
206 config->softMuteEnable);
207 if(status != Platform_EOK)
208 {
209 IFPRINT(platform_write("audioDacConfig : platformAudioDacSoftMuteCtrl Failed\n"));
210 return (status);
211 }
213 /* Set attenuation mode */
214 status = platformAudioDacSetAttnMode(devId, config->attnMode);
215 if(status != Platform_EOK)
216 {
217 IFPRINT(platform_write("audioDacConfig : platformAudioDacSetAttnMode Failed\n"));
218 return (status);
219 }
221 /* Set De-emphasis control */
222 status = platformAudioDacDeempCtrl(devId, config->deempCtrl);
223 if(status != Platform_EOK)
224 {
225 IFPRINT(platform_write("audioDacConfig : platformAudioDacDeempCtrl Failed\n"));
226 return (status);
227 }
229 /* Set DAC volume */
230 status = platformAudioDacSetVolume(devId, DAC_CHAN_ALL, config->volume);
231 if(status != Platform_EOK)
232 {
233 IFPRINT(platform_write("audioDacConfig : platformAudioDacSetVolume Failed\n"));
234 return (status);
235 }
237 return (status);
238 }
240 /**
241 * \brief Initializes DIR module
242 *
243 * This function initializes and configures the DIR modules
244 * on audio daughter card
245 *
246 * \return Platform_EOK on Success or error code
247 */
248 Platform_STATUS audioDirConfig(void)
249 {
250 Platform_STATUS status;
251 int8_t fsout;
252 #ifdef CHECK_ERROR_STATUS
253 uint32_t timeout;
254 #endif
256 status = platformAudioDirInit();
257 if(status != Platform_EOK)
258 {
259 IFPRINT(platform_write("audioDirConfig : Audio DIR Configuration Failed!\n"));
260 return (status);
261 }
263 #ifdef CHECK_ERROR_STATUS
264 /* DIR should be in PLL mode.
265 Wait for ERROR signal to be low as DIR is configured for
266 AUTO mode */
267 timeout = ERROR_STATUS_WAIT_TIMEOUT;
268 while (timeout)
269 {
270 if(!platformAudioDirGetErrStatus())
271 {
272 IFPRINT(platform_write("audioDirConfig : DIR in PLL Mode\n"));
273 break;
274 }
276 IFPRINT(platform_write("audioDirConfig : Waiting for DIR to Enter PLL Mode...\n"));
277 platform_delay(1000);
278 timeout--;
279 }
281 if(!timeout)
282 {
283 IFPRINT(platform_write("audioDirConfig : DIR is not in PLL Mode!!\n"));
284 return (Platform_EFAIL);
285 }
286 #endif
288 fsout = platformAudioDirGetFsOut();
289 if(fsout == 2)
290 {
291 IFPRINT(platform_write("audioDirConfig : Out of Range Sampling Frequency\n"));
292 }
293 else if(fsout == 0)
294 {
295 IFPRINT(platform_write("audioDirConfig : Calculated Sampling Frequency Output is 43 kHz\9645.2 kHz\n"));
296 }
297 else if(fsout == 1)
298 {
299 IFPRINT(platform_write("audioDirConfig : Calculated Sampling Frequency Output is 46.8 kHz\9649.2 kHz\n"));
300 }
301 else if(fsout == 3)
302 {
303 IFPRINT(platform_write("audioDirConfig : Calculated Sampling Frequency Output is 31.2 kHz\9632.8 kHz\n"));
304 }
305 else
306 {
307 IFPRINT(platform_write("audioDirConfig : Error in Reading FSOUT status \n"));
308 status = Platform_EFAIL;
309 }
311 return (status);
312 }
314 int alpha_i2c_write(unsigned short, ...);
315 void set_audio_desc(unsigned char ,unsigned char ,unsigned char ,unsigned char ,unsigned char );
316 void hrptredid();
317 void hdmi128();
320 int gret_val=0;
321 int alpha_i2c_write(unsigned short var1, ...)
322 {
323 unsigned short alpha_type,length,temp_var;
324 int i,offset,ret_val;
325 unsigned char cmd[50];
326 char *s;
327 va_list argp;
328 va_start(argp, var1);
330 alpha_type = var1>> 8;
331 switch(alpha_type)
332 {
333 case 0xca:
334 case 0xc2:
335 case 0xc3:
336 case 0xc4:
337 length = 4;
338 break;
339 case 0xcb:
340 length = 6;
341 break;
342 case 0xcc:
343 length = 8;
344 break;
345 case 0xcd:
346 case 0xc5:
347 length= 8; // temporary - data starts after 8 bytes
348 break;
349 }
351 cmd[0]=length;
352 temp_var=var1;
353 for(i=0;i<length-2;i+=2) // convert to bytes as per protocol
354 {
355 cmd[i+1]= temp_var & 0xff;
356 cmd[i+2]= temp_var >> 8;
357 temp_var=va_arg(argp, short);
358 }
359 cmd[i+1]= temp_var & 0xff;
360 cmd[i+2]= temp_var >> 8;
363 if(alpha_type == 0xcd) // special processing for variable length
364 {
365 offset=9;
366 s = va_arg(argp, char *); // remaining data is in form of string
367 length = temp_var; // last short indicates data length
368 cmd[0]+=length;
369 for(i=offset;i<offset+length;i++)
370 cmd[i]=s[i-offset];
371 }
372 va_end(argp);
375 ret_val = i2cWrite(HSR4_I2C_PORT_NUM, HSR4_I2C_ADDR, cmd, cmd[0]+1, I2C_RELEASE_BUS);
376 if(ret_val !=I2C_RET_OK)
377 gret_val++;
380 return ret_val;
381 }
383 void set_audio_desc(unsigned char var1,unsigned char var2,unsigned char var3,unsigned char var4,unsigned char var5)
384 {
385 int ret_val=I2C_RET_OK;
386 do{ret_val=alpha_i2c_write(HSDIO_EDID_AUDIO_DESC_FORMAT(var1, var2));}while (ret_val !=I2C_RET_OK);
387 platform_delay(1000);
388 do{ret_val=alpha_i2c_write(HSDIO_EDID_AUDIO_DESC_NUM_CHANNELS(var1, var3));}while (ret_val !=I2C_RET_OK);
389 platform_delay(1000);
390 do{ret_val=alpha_i2c_write(HSDIO_EDID_AUDIO_DESC_SAMPLE_RATES(var1, var4));}while (ret_val !=I2C_RET_OK);
391 platform_delay(1000);
392 do{ret_val=alpha_i2c_write(HSDIO_EDID_AUDIO_DESC_MISC(var1, var5));}while (ret_val !=I2C_RET_OK);
393 platform_delay(1000);
394 do{ret_val=alpha_i2c_write(HSDIO_ALERT(HSDIO_ALERT_INPUT_AUDIO_CHANGE_msk));}while (ret_val !=I2C_RET_OK);
395 platform_delay(1000);
396 do{ret_val=alpha_i2c_write(HSDIO_ALERT(HSDIO_ALERT_INPUT_AUDIO_MUTE_msk));}while (ret_val !=I2C_RET_OK);
397 platform_delay(1000);
398 }
400 void hrptredid()
401 {
402 int ret_val=I2C_RET_OK;
404 do{
405 platform_delay(1000);
406 ret_val=alpha_i2c_write(HSDIO_EDID_SPEAKER_ALLOCATION_BLOCK(0xFF));
407 if (ret_val !=I2C_RET_OK)
408 i2cConfig(HSR4_I2C_PORT_NUM);
410 }while (ret_val !=I2C_RET_OK);
412 platform_delay(1000);
413 do{ret_val=alpha_i2c_write(HSDIO_EDID_SPEAKER_ALLOCATION_BLOCK_2(0x7));}while (ret_val !=I2C_RET_OK);
415 set_audio_desc(0,1,2,0x7f,7); // Stero PCM
416 set_audio_desc(1,1,8,0x7f,7); // Multi Ch PCM
417 set_audio_desc(2,2,6,0x7,80); //AC3
418 //set_audio_desc(2,0,0,0,0); //AC3; (GJ) currently not supported
419 set_audio_desc(3,10,8,0x07,1); // EAC3 //DTS (3,7,6,0x1e,192)
420 set_audio_desc(4,12,8,0x7F,1); // MLP (THD) //DTS (4,7,8,0x6,192)
421 //set_audio_desc(4,0,0,0,0); // MLP (THD) //DTS (4,7,8,0x6,192) ; (GJ) currently not supported
422 // Empty descriptors to be programmed to 0s
423 set_audio_desc(5,0,0,0,0); //AAC LC (5,6,6,0x1f,192);
424 set_audio_desc(6,0,0,0,0);
425 set_audio_desc(7,0,0,0,0);
426 set_audio_desc(8,0,0,0,0); // DTS-HD (8,11,8,0x7F,1)
427 set_audio_desc(9,0,0,0,0);
428 set_audio_desc(10,0,0,0,0);
429 set_audio_desc(11,0,0,0,0);
430 set_audio_desc(12,0,0,0,0);
431 set_audio_desc(13,0,0,0,0);
432 set_audio_desc(14,0,0,0,0);
433 set_audio_desc(15,0,0,0,0);
434 set_audio_desc(16,0,0,0,0);
435 set_audio_desc(17,0,0,0,0);
436 set_audio_desc(18,0,0,0,0);
437 set_audio_desc(19,0,0,0,0);
438 platform_delay(1000);
439 do{ret_val=alpha_i2c_write(HSDIO_EDID_GO);}while (ret_val !=0);
440 //fclose(fp1);
441 }
443 void hdmi128()
444 {
445 int ret_val=0;
446 platform_delay(1000);
447 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_MCLK_TO_HOST(HSDIO_AudioMClk_128X));}while (ret_val !=0);
448 platform_delay(1000);
449 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_FORMAT_TO_HOST(HSDIO_AudioFmt_I2S));}while (ret_val !=0);
450 platform_delay(1000);
451 do{ret_val=alpha_i2c_write(HSDIO_IMPLEMENT_AUDIO_TO_HOST_CMDS);}while (ret_val !=0);
452 platform_delay(1000);
453 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_PRESENT(HSDIO_AudioPresent_HAS_NO_AUDIO));}while (ret_val !=0);
454 platform_delay(1000);
455 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_FORMAT(HSDIO_AudioFmt_I2S));}while (ret_val !=0);
456 platform_delay(1000);
457 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_SAMPLE_SIZE(HSDIO_AudioSampleSize_32));}while (ret_val !=0);
458 platform_delay(1000);
459 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_FREQ(HSDIO_AudioFreq_48K));}while (ret_val !=0);
460 platform_delay(1000);
461 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_LAYOUT(HSDIO_AudioLayout_2));}while (ret_val !=0);
462 platform_delay(1000);
463 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_MCLK(HSDIO_AudioMClk_AUTO));}while (ret_val !=0);
464 platform_delay(1000);
465 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_AUX_CHANNEL_CNT(1));}while (ret_val !=0);
466 platform_delay(1000);
467 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_AUX_SPEAKER_MAPPING(0));}while (ret_val !=0);
468 platform_delay(1000);
469 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_CHSTS_PCM_PREEMPHASIS(HSDIO_CSFormatInfo_PCM_NO_PRE));}while (ret_val !=0);
470 platform_delay(1000);
471 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_CHSTS_COPYRIGHT(HSDIO_CSCopyright_PROTECTED));}while (ret_val !=0);
472 platform_delay(1000);
473 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_CHSTS_WORD_LENGTH(HSDIO_CSWordLength_24));}while (ret_val !=0);
474 platform_delay(1000);
475 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_OUTPUT_GO);}while (ret_val !=0);
476 platform_delay(1000);
477 do{ret_val=alpha_i2c_write(HSDIO_AUDIO_ROUTING(HSDIO_AudioRouting_HSDIOIN_HOSTOUT));}while (ret_val !=0);
478 platform_delay(1000);
479 do{ret_val=alpha_i2c_write(HSDIO_SYS_CFG_GO);}while (ret_val !=0);
480 }
482 Platform_STATUS audioHDMIConfig(void)
483 {
484 Platform_STATUS status = 0;
486 hrptredid();
488 hdmi128();
490 return (status);
491 }
493 unsigned int read_hdmi_samprate()
494 {
495 unsigned char data[50];
496 Uint8 length;
497 int ret_val=7;
498 //int ret_val2=0;
499 int clear_to_read=5;
501 clear_to_read=alpha_i2c_write(HSDIO_ALERT_STS); //clear the interrupt on ~HMINT by reading the Alert Status register
503 ret_val=alpha_i2c_write(HSDIO_AUDIO_INPUT_FREQ_STS);
505 if(!ret_val) i2cRead(HSR4_I2C_PORT_NUM, HSR4_I2C_ADDR,&length,0,1,1);
506 if(!ret_val) i2cRead(HSR4_I2C_PORT_NUM, HSR4_I2C_ADDR,&data[0],0,1,length);
507 if(!ret_val) ret_val= data[3]; // indicates sample rate
508 else
509 ret_val = 0;
511 return ret_val;
512 }
514 /* Nothing past this point */