source: svn/trunk/zas_dstar/devices/Audio/STV83x8/STV83xy.c @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
File size: 115.9 KB
Line 
1/*
2   STV 83xy
3
4   Audio Driver API (DV_AUD)
5
6   STMicroelectronics Confidential      Version 1.12    Author: HDP Appli Lab 11/2006
7*/
8
9// ******************************************************************
10// CHIP SUPPORT
11
12// put in comment to remove corresponding patch for S/W space saving
13//#define INCLUDE_83x7
14#define INCLUDE_83x8
15
16#ifndef INCLUDE_83x7
17  #ifndef INCLUDE_83x8
18  ...           // error: choose AT LEAST ONE patch!
19  #endif
20#endif
21
22// ******************************************************************
23// ******************************************************************
24//#include "typedef.h"
25#include "dsthalcommon.h"
26typedef unsigned char   U8;
27typedef unsigned short  U16;
28typedef unsigned long   U32;
29
30#include "STV83xy.h"
31#include "STV83xyPatch.h"
32#include "test_patch1.h"
33#include "dsthalsys.h"
34
35
36//#include "debug.h"
37U8 RegAddr = 0;
38U8 SAVED_I2CAddr = 0;
39int ST_SRS_COMP = SRS_DEFAULT_COMP;
40int ST_AVL_COMP = AVL_DEFAULT_COMP;
41// ******************************************************************
42// ******************************************************************
43
44// external I2C routines (low level H/W I2C access)
45// int DHL_SYS_I2cRead(unsigned char addr, int isSubAddress, int subAddress, unsigned char *buf, int len)
46U8 I2C_Read(U8 I2cAddr, U8 RegIndex){
47        int result;
48//      U8 *SubAddr = (U8 *)((int)RegIndex);
49        U8 DataBuf = 0;
50        result = DHL_SYS_I2cReadEx(0,I2cAddr, 1, RegIndex,&DataBuf,1);
51       
52        if ( result < 0 )
53                printf("Audio I2C Read Error\n");
54       
55        return DataBuf;
56}
57// #define I2C_Read(x,y)        DHL_SYS_I2cRead(x,1,y,RegIndex,1)
58// int DHL_SYS_I2cWrite(unsigned char addr, int isSubAddress, int subAddress, unsigned char *buf, int len)
59U8 I2C_Write(U8 I2cAddr, U8 RegIndex, U8 RegValue){     // returns 0 if no error
60        int result;
61        U8 RegVal = RegValue;
62       
63        result = DHL_SYS_I2cWriteEx(0,I2cAddr,1,RegIndex,&RegVal,1);
64       
65        if( result < 0){
66                printf("Audio I2C Write Error\n");
67                return 1;
68        }
69        return 0;
70}
71//
72U8 I2C_WriteAddrIndex(U8 I2cAddr, U8 RegIndex){         // returns 0 if no error
73       
74        RegAddr = RegIndex;
75        SAVED_I2CAddr = I2cAddr;
76        return 0;
77}
78
79//
80U8 I2C_WriteData(U8 RegValue){                          // returns 0 if no error
81        U8 result;
82        result = I2C_Write(SAVED_I2CAddr,RegAddr++,RegValue);   
83        if(result){
84                printf("WriteDataFail\n");
85                return 1;
86        }
87        return 0;
88//      return I2C_Write(SAVED_I2CAddr,RegAddr++,RegValue);             // writeÈÄ regAddrÀÌ Áõ°¡µÇ¸é¼­ writing
89}
90//
91U8 I2C_Stop(void){
92        return 0;                                       // returns 0 if no error
93}
94
95int stv_r(U8 addr)
96{
97        int c;
98        c = I2C_Read(0x80,addr);
99        printf("0x%x\n",c);
100        return c;
101}
102
103int stv_w(U8 addr, U8 data)
104{
105        stv_r(addr);
106        I2C_Write(0x80,addr,data);
107        stv_r(addr);
108        return 1;
109}
110
111// external timer routine
112#define WAIT_Inms(x) OS_mDelay(x)
113
114// ******************************************************************
115// ******************************************************************
116
117// higher level I2C routines used by 83xy routines
118static void DVAUD_I2cClrBit(U16 Field);
119static void DVAUD_I2cSetBit(U16 Field);
120static void DVAUD_I2cWriteReg(U8 Reg, U8 RegValue);
121static void DVAUD_I2cWriteField(U16 Field, U8 Value);
122static U8 DVAUD_I2cReadReg(U8 Reg);
123static U8 DVAUD_I2cReadField(U16 Field);
124
125// ******************************************************************
126// ******************************************************************
127         
128// NOTE: ALL variables below are local and MUST be "static"
129// "static" may be removed for test purposes only
130
131static DVAUD_DeviceType_t       Dev_ID = DVAUD_kUnknown;        // set by DVAUD_DeviceStart(), tested by every routine
132static DVAUD_Status_t           I2C_Status;                     // updated by I2C routines
133static U8                       I2cAddr83xy = 0x80;             // by default, if ADR_SEL pin = 0
134static DVAUD_DeviceCapability_t Dev_Capability;                 // for DVAUD_DeviceStart() and DVAUD_LowPowerExit()
135
136// ******************************************************************
137// ******************************************************************
138
139
140// ******************************************************************
141// ******************************************************************
142
143DVAUD_Status_t DVAUD_DACMuteSet (
144                const DVAUD_Output_t            eOutput,
145                const DVAUD_Enabled_t           eNewStatus)
146{
147  U16 Bit;
148 
149  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
150     return DVAUD_kDeviceNotReady;
151     
152  switch (eOutput)
153    {
154    case DVAUD_kOutputSpeaker:
155      Bit = F_MUTE_DAC_LR;
156      break;
157    case DVAUD_kOutputCenter:
158    case DVAUD_kOutputSubwoofer:
159      Bit = F_MUTE_DAC_CSUB;
160      break;
161    case DVAUD_kOutputHeadphone:
162    case DVAUD_kOutputSurround:
163      Bit = F_MUTE_DAC_SHP;
164      break;
165    case DVAUD_kOutputSCART1:
166    case DVAUD_kOutputSCART2:
167    case DVAUD_kOutputSCART3:
168      Bit = F_MUTE_DAC_SCART;
169      break;
170    default:                            // parameter config not in list
171      return DVAUD_kBadParameter;
172    }
173   
174  switch (eNewStatus)
175    {
176    case DVAUD_kDisabled:
177      DVAUD_I2cClrBit(Bit);             // R_MUTE_DAC
178      break;
179    case DVAUD_kEnabled:
180      DVAUD_I2cSetBit(Bit);             // R_MUTE_DAC
181      break;
182    default:                            // parameter not in list
183      return DVAUD_kBadParameter;
184    }
185
186  return I2C_Status;
187}
188
189// ******************************************************************
190
191DVAUD_Status_t DVAUD_SoftMuteSet (
192                const DVAUD_Output_t            eOutput,
193                const DVAUD_Enabled_t           eNewStatus)
194{
195  U16 Bit;
196 
197  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
198     return DVAUD_kDeviceNotReady;
199     
200  switch (eOutput)
201    {
202    case DVAUD_kOutputHeadphone:
203      Bit = F_MUTE_DIG_HP;
204      break;
205    case DVAUD_kOutputSPDIF:
206      Bit = F_MUTE_DIG_SPDIF;
207      break;
208    case DVAUD_kOutputSCART1:
209    case DVAUD_kOutputSCART2:
210    case DVAUD_kOutputSCART3:
211      Bit = F_MUTE_DIG_SCART;
212      break;
213    case DVAUD_kOutputSurround:
214      Bit = F_MUTE_DIG_SRND;
215      break;
216    case DVAUD_kOutputSubwoofer:
217      Bit = F_MUTE_DIG_SUB;
218      break;
219    case DVAUD_kOutputCenter:
220      Bit = F_MUTE_DIG_C;
221      break;
222    case DVAUD_kOutputSpeaker:
223      Bit = F_MUTE_DIG_LS;
224      break;
225    default:                            // parameter config not in list
226      return DVAUD_kBadParameter;
227    }
228   
229  switch (eNewStatus)
230    {
231    case DVAUD_kDisabled:
232      DVAUD_I2cClrBit(Bit);             // R_MUTE_DIGITAL
233      break;
234    case DVAUD_kEnabled:
235      DVAUD_I2cSetBit(Bit);             // R_MUTE_DIGITAL
236      break;
237    default:                            // parameter not in list
238      return DVAUD_kBadParameter;
239    }
240
241  return I2C_Status;
242}
243
244// ******************************************************************
245
246static U16 DVAUD_VolumeConvertLR (S32 ValueInmdB)
247{
248  // convert from [-108000(-108); +19875(+19.875db)] to [0; 1023] by steps of 125 (0.125dB)
249  return (U16)((ValueInmdB+108000L)/125L);
250}
251
252static U8 DVAUD_VolumeConvertScart (S32 ValueInmdB)
253{
254  // convert from [-108000(-108); +19500(+19.5)] to [0; 255] by steps of 500 (0.5dB)
255  return (U8)((ValueInmdB+108000L)/500L);
256}
257
258static S8 DVAUD_VolumeConvertCenterSub (S16 ValueInmdB)
259{
260  // convert from [-16000(-16); +15875(+15.875)] to [-128; +127] by steps of 125 (0.125dB)
261  return (S8)(ValueInmdB/125L);
262}
263
264DVAUD_Status_t DVAUD_VolumeSet (
265                const DVAUD_Output_t    eOutput,
266                const S32               lValueInmdB)
267{
268  U8 Val;
269  U16 ValW;
270 
271  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
272     return DVAUD_kDeviceNotReady;
273 
274        printf("%d 0x%x\n",__LINE__,(int)lValueInmdB);     
275       
276  switch (eOutput)
277    {
278    case DVAUD_kOutputSpeaker:
279   
280      if (lValueInmdB<(-108000L) || lValueInmdB>19875L)
281        return DVAUD_kBadParameter;     // value out of range
282      ValW = DVAUD_VolumeConvertLR(lValueInmdB);
283      printf("%d 0x%x\n",__LINE__,(int)ValW);
284      // volume in LS_L always
285      DVAUD_I2cSetBit(F_VOLUME_MODE_LS);                                // volume/balance
286      DVAUD_I2cWriteReg(R_VOLUME_LS_L_COARSE, (ValW>>2) & 0xFF);        // whole register coarse = bits 9..2
287      DVAUD_I2cWriteField(F_VOLUME_LS_L_FINE, ValW & 0x03);             // R_VOLUME_LS_L_FINE fine = bits 1..0
288      break;
289
290    case DVAUD_kOutputCenter:
291      if (lValueInmdB<(-16000L) || lValueInmdB>15875L)
292        return DVAUD_kBadParameter;     // value out of range
293      DVAUD_I2cWriteReg(R_VOLUME_LS_C, DVAUD_VolumeConvertCenterSub(lValueInmdB));
294      break;
295
296    case DVAUD_kOutputSubwoofer:
297      if (lValueInmdB<(-16000L) || lValueInmdB>15875L)
298        return DVAUD_kBadParameter;     // value out of range
299      DVAUD_I2cWriteReg(R_VOLUME_LS_SUB, DVAUD_VolumeConvertCenterSub(lValueInmdB));
300      break;
301
302    case DVAUD_kOutputSurround:
303      if (lValueInmdB<(-16000L) || lValueInmdB>15875L)
304        return DVAUD_kBadParameter;     // value out of range
305      Val = DVAUD_VolumeConvertCenterSub(lValueInmdB);
306      DVAUD_I2cWriteReg(R_VOLUME_LS_SL, Val);
307      DVAUD_I2cWriteReg(R_VOLUME_LS_SR, Val);                           // treat Srnd L and R alike
308      break;
309
310    case DVAUD_kOutputHeadphone:
311      if (lValueInmdB<(-108000L) || lValueInmdB>19875L)
312        return DVAUD_kBadParameter;     // value out of range
313      ValW = DVAUD_VolumeConvertLR(lValueInmdB);
314      // volume in HP_L always
315      DVAUD_I2cSetBit(F_VOLUME_MODE_HP);                                // volume/balance
316      DVAUD_I2cWriteReg(R_VOLUME_HP_L_COARSE, (ValW>>2) & 0xFF);        // whole register coarse = bits 9..2
317      DVAUD_I2cWriteField(F_VOLUME_HP_L_FINE, ValW & 0x03);             // R_VOLUME_HP_L_FINE fine = bits 1..0
318      break;
319
320    case DVAUD_kOutputSCART1:
321    case DVAUD_kOutputSCART2:
322    case DVAUD_kOutputSCART3:
323      if (lValueInmdB<(-108000L) || lValueInmdB>19500L)
324        return DVAUD_kBadParameter;     // value out of range
325      DVAUD_I2cWriteReg(R_VOLUME_SCART, DVAUD_VolumeConvertScart(lValueInmdB));
326      break;
327
328    default:                            // parameter config not in list
329      return DVAUD_kBadParameter;
330    }
331
332  return I2C_Status;
333}
334
335// ******************************************************************
336
337DVAUD_Status_t DVAUD_BalanceSet (
338                const DVAUD_Output_t            eOutput,
339                const DVAUD_Side_t              eSide,
340                const U8                        ucValueInPercent)
341{
342  S32 sCoeff;
343  S32 slVal;
344 
345  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
346    return DVAUD_kDeviceNotReady;
347
348  if (ucValueInPercent>100)
349    return DVAUD_kBadParameter;         // value out of range
350 
351  // check if side parameter is correct
352  switch (eSide)
353    {
354    case DVAUD_kLeft:
355      sCoeff = (-511L);                 // -100% = full to the left
356      break;
357    case DVAUD_kRight:
358      sCoeff = 511L;                    // 100% = full to the right
359      break;
360    default: 
361      return DVAUD_kBadParameter;               // value out of range
362    }
363
364  slVal = ((S8)ucValueInPercent * sCoeff) / 100L;       // full precision conversion to -511..+511 range (to avoid floats)
365
366  // coarse = MSB = bits 9..2
367  // fine = LSB = bits 1..0
368  // sign bit 9 = 1 if negative
369 
370  switch (eOutput)
371    {
372    case DVAUD_kOutputSpeaker:
373      // balance in LS_R always
374      DVAUD_I2cWriteReg(R_VOLUME_LS_R_COARSE, (slVal >> 2) & 0xFF);     // whole register = MSB
375      DVAUD_I2cWriteField(F_VOLUME_LS_R_FINE, slVal & 0x03);            // R_VOLUME_LS_R_FINE = LSB
376      break;
377    case DVAUD_kOutputHeadphone:
378      // balance in HP_R always
379      DVAUD_I2cWriteReg(R_VOLUME_HP_R_COARSE, (slVal >> 2) & 0xFF);     // whole register
380      DVAUD_I2cWriteField(F_VOLUME_HP_R_FINE, slVal & 0x03);            // R_VOLUME_HP_R_FINE
381      break;
382    default:                            // parameter config not in list
383      return DVAUD_kBadParameter;
384    }
385
386  return I2C_Status;
387}
388
389// ******************************************************************
390DVAUD_Status_t DVAUD_PrologicSetConfig (
391                const DVAUD_PrologicConfig_t*           const pstConfig,
392                const DVAUD_PrologicDownMixMode_t       eNewMode)
393{
394  U8 Val;
395  S8 ValS;
396  S32 ValLS;
397
398  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)                 // chip not initialized or in standby
399     return DVAUD_kDeviceNotReady;
400
401  if ((Dev_Capability.ePrologicI  != DVAUD_kImplemented) &&
402      (Dev_Capability.ePrologicII != DVAUD_kImplemented))
403    return DVAUD_kFeatureNotSupported;          // neither Prologic I nor II supported
404
405  // Mode
406  Val = pstConfig->eMode;
407  if (Val >= DVAUD_kNbOfPrologicMode)
408    return DVAUD_kBadParameter;                 // value out of range
409  if ((Val != DVAUD_kModePrologic1Emulation) &&
410      (Dev_Capability.ePrologicI == DVAUD_kImplemented))
411    return DVAUD_kFeatureNotSupported;          // in Dolby Prologic 1, only Prologic 1 emulation supported
412  DVAUD_I2cWriteField(F_PL2_MODES,Val);         // R_PROLOGIC2_CONF1
413 
414  // Autobalance
415  switch (pstConfig->eAutoBalance)
416    {
417    case DVAUD_kFalse:
418      DVAUD_I2cClrBit(F_PL2_AUTOBALANCE);       // R_PROLOGIC2_CONF2
419      break;
420    case DVAUD_kTrue:
421      DVAUD_I2cSetBit(F_PL2_AUTOBALANCE);
422      break;
423    default:                                    // parameter not in list
424      return DVAUD_kBadParameter;
425    }
426
427  // Panorama
428  switch (pstConfig->ePanorama)
429    {
430    case DVAUD_kFalse:
431      DVAUD_I2cClrBit(F_PL2_PANORAMA);          // R_PROLOGIC2_CONF2
432      break;
433    case DVAUD_kTrue:
434      DVAUD_I2cSetBit(F_PL2_PANORAMA);
435      break;
436    default:                                    // parameter not in list
437      return DVAUD_kBadParameter;
438    }
439
440  // RS Polarity
441  switch (pstConfig->eRSPolarity)
442    {
443    case DVAUD_kFalse:
444      DVAUD_I2cClrBit(F_PL2_SRND_COHERENCE);    // R_PROLOGIC2_CONF2
445      break;
446    case DVAUD_kTrue:
447      DVAUD_I2cSetBit(F_PL2_SRND_COHERENCE);
448      break;
449    default:                                    // parameter not in list
450      return DVAUD_kBadParameter;
451    }
452
453  // LFE Bypass
454  switch (pstConfig->eLFEBypass)
455    {
456    case DVAUD_kFalse:
457      DVAUD_I2cClrBit(F_PL2_LFE_BYPASS);        // R_PROLOGIC2_CONF1
458      break;
459    case DVAUD_kTrue:
460      DVAUD_I2cSetBit(F_PL2_LFE_BYPASS);
461      break;
462    default:                                    // parameter not in list
463      return DVAUD_kBadParameter;
464    }
465
466  // Surround Filter
467  Val = pstConfig->eFilter;
468  if (Val >= DVAUD_kNbOfPrologicSrndFilter)
469    return DVAUD_kBadParameter;                 // value out of range
470  DVAUD_I2cWriteField(F_PL2_SRND_FILTER, Val);  // R_PROLOGIC2_CONF2
471
472  // C Dimension
473  ValS = pstConfig->cDimension;
474  if (ValS<(-3) || ValS>3)
475    return DVAUD_kBadParameter;                 // value out of range
476  DVAUD_I2cWriteField(F_PL2_DIMENSION, ValS+3); // R_PROLOGIC2_CONF3
477
478  // Center Width
479  Val = pstConfig->eWidth;
480  if (Val >= DVAUD_kNbOfPrologicCenterWidth)
481    return DVAUD_kBadParameter;                 // value out of range
482  DVAUD_I2cWriteField(F_PL2_C_WIDTH, Val);      // R_PROLOGIC2_CONF3
483
484  // Attenuation -127.5dB -> 0dB
485  ValLS = pstConfig->lAttenuationInmdB;
486  if (ValLS>0 || ValLS<(-127500))
487    return DVAUD_kBadParameter;                 // value out of range
488  DVAUD_I2cWriteReg(R_PROLOGIC2_LEVEL, (-ValLS)/500);
489
490  // DownMix Mode
491  if (eNewMode >= DVAUD_kNbOfPrologicDownMixMode)
492    return DVAUD_kBadParameter;                                 // value out of range
493  DVAUD_I2cWriteField(F_PL2_OUTPUT_DOWNMIX, eNewMode +3 );      // R_PROLOGIC2_CONF1
494
495  return I2C_Status;
496}
497
498// ******************************************************************
499
500DVAUD_Status_t DVAUD_PrologicSet (
501                const DVAUD_Enabled_t           eNewStatus)
502{
503  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
504     return DVAUD_kDeviceNotReady;
505
506  switch (eNewStatus)
507    {
508    case DVAUD_kDisabled:
509      DVAUD_I2cClrBit(F_PL2_ON);        // R_PROLOGIC2_CONF1
510      break;
511    case DVAUD_kEnabled:
512      if ((Dev_Capability.ePrologicI  != DVAUD_kImplemented) &&
513          (Dev_Capability.ePrologicII != DVAUD_kImplemented))
514        return DVAUD_kFeatureNotSupported;              // neither Prologic I nor II supported
515      else
516        DVAUD_I2cSetBit(F_PL2_ON);
517      break;
518    default:                            // parameter not in list
519      return DVAUD_kBadParameter;
520    }
521
522  return I2C_Status;
523}
524
525// ******************************************************************
526
527DVAUD_Status_t DVAUD_BassManagementSetConfig  (
528                const DVAUD_BassManagementConfig_t*             const pstConfig)
529{
530  U8 Val;
531
532  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
533     return DVAUD_kDeviceNotReady;
534
535  // LFE
536  switch (pstConfig->eLFEAdd)
537    {
538    case DVAUD_kDisabled:
539      DVAUD_I2cClrBit(F_LFE_ADD);       // R_BASS_MNGT_CONF2
540      break;
541    case DVAUD_kEnabled:
542      DVAUD_I2cSetBit(F_LFE_ADD);
543      break;
544    default:                            // parameter not in list
545      return DVAUD_kBadParameter;
546    }
547
548  // level adjustment
549  switch (pstConfig->eLevelAdjust)
550    {
551    case DVAUD_kDisabled:
552      DVAUD_I2cClrBit(F_LEVEL_ADJUST);  // R_BASS_MNGT_CONF2
553      break;
554    case DVAUD_kEnabled:
555      DVAUD_I2cSetBit(F_LEVEL_ADJUST);
556      break;
557    default:                            // parameter not in list
558      return DVAUD_kBadParameter;
559    }
560
561  // subwoofer out
562  switch (pstConfig->eSubwooferOut)
563    {
564    case DVAUD_kDisabled:
565      DVAUD_I2cClrBit(F_SUBWOOFER_ON);  // R_BASS_MNGT_CONF2
566      break;
567    case DVAUD_kEnabled:
568      DVAUD_I2cSetBit(F_SUBWOOFER_ON);
569      break;
570    default:                            // parameter not in list
571      return DVAUD_kBadParameter;
572    }
573
574  // prologic surround
575  switch (pstConfig->ePrologicSrnd)
576    {
577    case DVAUD_kDisabled:
578      DVAUD_I2cClrBit(F_PROLOGIC_MODE); // R_BASS_MNGT_CONF2
579      break;
580    case DVAUD_kEnabled:
581      DVAUD_I2cSetBit(F_PROLOGIC_MODE);
582      break;
583    default:                            // parameter not in list
584      return DVAUD_kBadParameter;
585    }
586
587  // bass config mode
588  Val = pstConfig->eMode;
589  if (Val >= DVAUD_kNbOfBassConfigMode)
590    return DVAUD_kBadParameter;                 // value out of range
591  DVAUD_I2cWriteField(F_BASS_MNGT_CONF, Val);   // R_BASS_MNGT_CONF2
592
593  // sub corner freq
594  Val = pstConfig->eFreq;
595  if (Val >= DVAUD_kNbOfSubCornerFreq)
596    return DVAUD_kBadParameter;                         // value out of range
597  DVAUD_I2cWriteField(F_BASS_MNGT_CORNER_FREQ, Val);    // R_BASS_MNGT_CONF1
598
599  return I2C_Status;
600}
601
602// ******************************************************************
603
604DVAUD_Status_t DVAUD_BassManagementSet (
605                const DVAUD_Enabled_t           eNewStatus)
606{
607  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
608     return DVAUD_kDeviceNotReady;
609
610  switch (eNewStatus)
611    {
612    case DVAUD_kDisabled:
613      DVAUD_I2cClrBit(F_BASS_MNGT_ON);  // R_BASS_MNGT_CONF1
614      break;
615    case DVAUD_kEnabled:
616      DVAUD_I2cSetBit(F_BASS_MNGT_ON);
617      break;
618    default:                            // parameter not in list
619      return DVAUD_kBadParameter;
620    }
621
622  return I2C_Status;
623}
624
625// ******************************************************************
626
627DVAUD_Status_t DVAUD_PinkNoiseSetConfig  (
628                const DVAUD_PinkNoiseConfig_t*  const pstConfig)
629{
630  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
631     return DVAUD_kDeviceNotReady;
632
633  // left
634  switch (pstConfig->eLeft)
635    {
636    case DVAUD_kDisabled:
637      DVAUD_I2cClrBit(F_LEFT_NOISE);    // R_NOISE_GENERATOR
638      break;
639    case DVAUD_kEnabled:
640      DVAUD_I2cSetBit(F_LEFT_NOISE);
641      break;
642    default:                            // parameter not in list
643      return DVAUD_kBadParameter;
644    }
645
646  // center
647  switch (pstConfig->eCenter)
648    {
649    case DVAUD_kDisabled:
650      DVAUD_I2cClrBit(F_CENTER_NOISE);  // R_NOISE_GENERATOR
651      break;
652    case DVAUD_kEnabled:
653      DVAUD_I2cSetBit(F_CENTER_NOISE);
654      break;
655    default:                            // parameter not in list
656      return DVAUD_kBadParameter;
657    }
658
659  // right
660  switch (pstConfig->eRight)
661    {
662    case DVAUD_kDisabled:
663      DVAUD_I2cClrBit(F_RIGHT_NOISE);   // R_NOISE_GENERATOR
664      break;
665    case DVAUD_kEnabled:
666      DVAUD_I2cSetBit(F_RIGHT_NOISE);
667      break;
668    default:                            // parameter not in list
669      return DVAUD_kBadParameter;
670    }
671
672  // surround left
673  switch (pstConfig->eSrndLeft)
674    {
675    case DVAUD_kDisabled:
676      DVAUD_I2cClrBit(F_SLEFT_NOISE);   // R_NOISE_GENERATOR
677      break;
678    case DVAUD_kEnabled:
679      DVAUD_I2cSetBit(F_SLEFT_NOISE);
680      break;
681    default:                            // parameter not in list
682      return DVAUD_kBadParameter;
683    }
684   
685  // surround right
686  switch (pstConfig->eSrndRight)
687    {
688    case DVAUD_kDisabled:
689      DVAUD_I2cClrBit(F_SRIGHT_NOISE);  // R_NOISE_GENERATOR
690      break;
691    case DVAUD_kEnabled:
692      DVAUD_I2cSetBit(F_SRIGHT_NOISE);
693      break;
694    default:                            // parameter not in list
695      return DVAUD_kBadParameter;
696    }
697
698  // subwoofer
699  switch (pstConfig->eSubwoofer)
700    {
701    case DVAUD_kDisabled:
702      DVAUD_I2cClrBit(F_SUB_NOISE);     // R_NOISE_GENERATOR
703      break;
704    case DVAUD_kEnabled:
705      DVAUD_I2cSetBit(F_SUB_NOISE);
706      break;
707    default:                            // parameter not in list
708      return DVAUD_kBadParameter;
709    }
710
711  return I2C_Status;
712}
713
714// ******************************************************************
715
716DVAUD_Status_t DVAUD_PinkNoiseSet (
717                const DVAUD_Enabled_t           eNewStatus)
718{
719  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
720     return DVAUD_kDeviceNotReady;
721
722  switch (eNewStatus)
723    {
724    case DVAUD_kDisabled:
725      DVAUD_I2cClrBit(F_NOISE_ON);      // R_NOISE_GENERATOR
726      break;
727    case DVAUD_kEnabled:
728      DVAUD_I2cSetBit(F_NOISE_ON);
729      break;
730    default:                            // parameter not in list
731      return DVAUD_kBadParameter;
732    }
733
734  return I2C_Status;
735}
736
737// ******************************************************************
738
739DVAUD_Status_t DVAUD_AVDelaySetConfig  (
740                const DVAUD_Output_t            eOutput,
741                const U8                        ucValueInStep)
742{
743  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
744     return DVAUD_kDeviceNotReady;
745
746  if (ucValueInStep > 0x98)             // greater than 100.32ms
747    return DVAUD_kBadParameter;         // value out of range
748
749  switch (eOutput)
750    {
751    case DVAUD_kOutputSpeaker:
752      DVAUD_I2cWriteReg(R_AV_DELAY_TIME_LS, ucValueInStep);
753      break;
754    case DVAUD_kOutputHeadphone:
755      DVAUD_I2cWriteReg(R_AV_DELAY_TIME_HP, ucValueInStep);
756      break;
757    default:                            // parameter config not in list
758      return DVAUD_kBadParameter;
759    }
760   
761  return I2C_Status;
762}
763
764// ******************************************************************
765
766DVAUD_Status_t DVAUD_AVDelaySet (
767                const DVAUD_Enabled_t           eNewStatus)
768{
769  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
770     return DVAUD_kDeviceNotReady;
771
772  switch (eNewStatus)
773    {
774    case DVAUD_kDisabled:
775      DVAUD_I2cClrBit(F_AV_DELAY_ON);   // R_AV_DELAY_CONF
776      break;
777    case DVAUD_kEnabled:
778      DVAUD_I2cSetBit(F_AV_DELAY_ON);
779      break;
780    default:                            // parameter not in list
781      return DVAUD_kBadParameter;
782    }
783
784  return I2C_Status;
785}
786
787// ******************************************************************
788
789DVAUD_Status_t DVAUD_DolbyDelaySetConfig  (
790                const U8                        ucValueInStep)
791{
792  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
793     return DVAUD_kDeviceNotReady;
794
795  if (ucValueInStep > 25)
796    return DVAUD_kBadParameter;
797
798  DVAUD_I2cWriteField(F_SRND_DELAY_TIME, ucValueInStep);        // R_SRND_DELAY
799   
800  return I2C_Status;
801}
802
803// ******************************************************************
804
805DVAUD_Status_t DVAUD_DolbyDelaySet (
806                const DVAUD_Enabled_t           eNewStatus)
807{
808  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
809     return DVAUD_kDeviceNotReady;
810
811  switch (eNewStatus)
812    {
813    case DVAUD_kDisabled:
814      DVAUD_I2cClrBit(F_SRND_DELAY_ON); // R_SRND_DELAY
815      break;
816    case DVAUD_kEnabled:
817      DVAUD_I2cSetBit(F_SRND_DELAY_ON);
818      break;
819    default:                            // parameter not in list
820      return DVAUD_kBadParameter;
821    }
822
823  return I2C_Status;
824}
825
826// ******************************************************************
827
828DVAUD_Status_t DVAUD_DownMixSetConfig (
829                const DVAUD_DownMixConfig_t*    const pstConfig)
830{
831  U8 Val;
832 
833  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
834     return DVAUD_kDeviceNotReady;
835
836  // downmix mode
837  switch (pstConfig->eDownMixModeAAC)
838    {
839    case DVAUD_kDisabled:
840      DVAUD_I2cClrBit(F_DOWNMIX_MODE);  // R_DOWNMIX_CONF
841      break;
842    case DVAUD_kEnabled:
843      DVAUD_I2cSetBit(F_DOWNMIX_MODE);
844      break;
845    default:                            // parameter not in list
846      return DVAUD_kBadParameter;
847    }
848
849  // surround factor
850  Val = pstConfig->eSurroundFactor;
851  if (Val >= DVAUD_kNbOfDownMixFactor)
852    return DVAUD_kBadParameter;                 // value out of range
853  DVAUD_I2cWriteField(F_SRND_FACTOR, Val);      // R_DOWNMIX_CONF
854
855  // center factor
856  Val = pstConfig->eCenterFactor;
857  if (Val >= DVAUD_kNbOfDownMixFactor)
858    return DVAUD_kBadParameter;                 // value out of range
859  DVAUD_I2cWriteField(F_CENTER_FACTOR, Val);    // R_DOWNMIX_CONF
860
861  return I2C_Status;
862}
863
864// ******************************************************************
865
866DVAUD_Status_t DVAUD_DownmixSet (
867                const DVAUD_Enabled_t           eNewStatus)
868{
869  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
870     return DVAUD_kDeviceNotReady;
871
872  switch (eNewStatus)
873    {
874    case DVAUD_kDisabled:
875      DVAUD_I2cClrBit(F_DOWNMIX_ON);    // R_DOWNMIX_CONF
876      break;
877    case DVAUD_kEnabled:
878      DVAUD_I2cSetBit(F_DOWNMIX_ON);
879      break;
880    default:                            // parameter not in list
881      return DVAUD_kBadParameter;
882    }
883
884  return I2C_Status;
885}
886
887// ******************************************************************
888
889static U8 DVAUD_GetMainAudioMatrixInput (
890                const DVAUD_Input_t             eInput)
891{
892  switch (eInput)
893    {
894    case DVAUD_kInputMute:
895      return 0;
896    case DVAUD_kInputSIF1_FMAMAB:
897    case DVAUD_kInputSIF2_FMAMAB:
898      return 1;
899    case DVAUD_kInputSIF1_StereoAB:
900    case DVAUD_kInputSIF2_StereoAB:
901      return 2;
902    case DVAUD_kInputSIF1_StereoA:
903    case DVAUD_kInputSIF2_StereoA:
904      return 3;
905    case DVAUD_kInputSIF1_StereoB:
906    case DVAUD_kInputSIF2_StereoB:
907      return 4;
908    case DVAUD_kInputI2S0:
909      return 5;
910    case DVAUD_kInputI2S1:
911      return 6;
912    case DVAUD_kInputI2S2:
913      return 7;
914    case DVAUD_kInputI2S3:
915      return 8;
916    case DVAUD_kInputMono:
917    case DVAUD_kInputSCART1:
918    case DVAUD_kInputSCART2:
919    case DVAUD_kInputSCART3:
920    case DVAUD_kInputSCART4:
921    case DVAUD_kInputSCART5:
922      return 9;
923    default:
924      return 0xFF;                              // bad value, including DirectMono and DirectScart
925    }
926}
927
928static DVAUD_Status_t DVAUD_SetMainAudioMatrixOutput (
929                const DVAUD_Output_t            eOutput,
930                const U8                        Matrix,
931                const DVAUD_Input_t             eInput)
932{
933  U8 ScartInSelect;
934  U16 FieldOut = 0;
935  U16 FieldMute = 0;
936
937  ScartInSelect = 0;
938 
939  // manage SIF1 or SIF2
940 
941  switch (eInput)
942    {
943    case DVAUD_kInputSIF1_FMAMAB:
944    case DVAUD_kInputSIF1_StereoAB:
945    case DVAUD_kInputSIF1_StereoA:
946    case DVAUD_kInputSIF1_StereoB:
947      DVAUD_I2cClrBit(F_IF_SELECT);             // SIF1
948      break;
949    case DVAUD_kInputSIF2_FMAMAB:
950    case DVAUD_kInputSIF2_StereoAB:
951    case DVAUD_kInputSIF2_StereoA:
952    case DVAUD_kInputSIF2_StereoB:
953      DVAUD_I2cSetBit(F_IF_SELECT);             // SIF2
954      break;
955    case DVAUD_kInputMono:
956      ScartInSelect = 5;                        // value to write + 1
957      break;
958    case DVAUD_kInputSCART1:
959      ScartInSelect = 1;                        // value to write + 1
960      break;
961    case DVAUD_kInputSCART2:
962      ScartInSelect = 2;                        // value to write + 1
963      break;
964    case DVAUD_kInputSCART3:
965      ScartInSelect = 3;                        // value to write + 1
966      break;
967    case DVAUD_kInputSCART4:
968      ScartInSelect = 4;                        // value to write + 1
969      break;
970    case DVAUD_kInputSCART5:
971      ScartInSelect = 7;                        // value to write + 1
972      break;
973    default:
974      break;
975    }
976
977   if (ScartInSelect)                                           // if input from scart in select block
978     DVAUD_I2cWriteField(F_ADC_INPUT_SEL, ScartInSelect-1);     // preset this block first
979
980  switch (eOutput)
981    {
982    case DVAUD_kOutputSpeaker:
983      FieldOut = F_OUTPUT_LS_LR;
984      break;
985    case DVAUD_kOutputCenter:
986    case DVAUD_kOutputSubwoofer:        // same
987      FieldOut = F_OUTPUT_LS_CSUB;
988      break;
989    case DVAUD_kOutputSurround:
990      FieldOut = F_OUTPUT_LS_SRND;
991      break;
992    case DVAUD_kOutputHeadphone:
993      FieldOut = F_OUTPUT_HP_LR;
994      break;
995    case DVAUD_kOutputI2SDelay:
996      FieldOut = F_OUTPUT_DELAY_LR;
997      break;
998    case DVAUD_kOutputSPDIF:
999      FieldOut = F_OUTPUT_SPDIF_LR;
1000      break;
1001    case DVAUD_kOutputSCART1:
1002    case DVAUD_kOutputSCART2:
1003    case DVAUD_kOutputSCART3:
1004      if (Matrix == 0)                  // DVAUD_kInputMute
1005        FieldOut = 0;                   // don't set "mute" in main audio matrix block for SCART
1006      else
1007        FieldOut = F_OUTPUT_SCART_LR;
1008      break;
1009    default:
1010      break;
1011    }
1012
1013  // enable audio matrix config except if "mute" for SCART (done later)
1014  if (FieldOut)
1015    DVAUD_I2cWriteField(FieldOut, Matrix); 
1016
1017  // if out is SPDIF: deselect SPDIF bypass
1018  if (eOutput == DVAUD_kOutputSPDIF)
1019    DVAUD_I2cClrBit(F_SPDIF_BYPASS);
1020
1021  FieldMute = 0;
1022
1023  // if out = Scart1/2/3
1024  // manage "mute" directly in scart out select block 
1025
1026  // need to set scart out select module too
1027  if (eOutput == DVAUD_kOutputSCART1)
1028    {
1029    FieldOut  = F_SC1_OUTPUT_SEL;
1030    FieldMute = F_SC1_MUTE;
1031    }
1032  else if (eOutput == DVAUD_kOutputSCART2)
1033    {
1034    FieldOut  = F_SC2_OUTPUT_SEL;
1035    FieldMute = F_SC2_MUTE;
1036    }
1037  else if (eOutput == DVAUD_kOutputSCART3)
1038    {
1039    FieldOut  = F_SC3_OUTPUT_SEL;
1040    FieldMute = F_SC3_MUTE;
1041    }
1042
1043  // mute or unmute corresponding output
1044  if (FieldMute)
1045    {
1046    if (Matrix == 0)                    // mute on SCARTn
1047      DVAUD_I2cSetBit(FieldMute);       // mute output scart n
1048    else
1049      {
1050      DVAUD_I2cWriteField(FieldOut, 0); // select DAC SCART n
1051      DVAUD_I2cClrBit(FieldMute);       // unmute output scart n
1052      }
1053    }
1054     
1055  return I2C_Status;
1056}
1057
1058static DVAUD_Status_t DVAUD_ManageMainAudioMatrix(
1059                const DVAUD_Output_t            eOutput,
1060                const DVAUD_Input_t             eInput)
1061{
1062  U8 AudioMatrix;
1063
1064  // if IN = external SPDIF pin and OUT = SPDIF: enable bypass
1065  if (eInput == DVAUD_kInputExternalSPDIF)
1066    {
1067    if (eOutput == DVAUD_kOutputSPDIF)
1068      DVAUD_I2cSetBit(F_SPDIF_BYPASS);
1069    else                                // external SPDIF not allowed to any other output
1070      I2C_Status = DVAUD_kBadParameter;
1071    }   
1072  else
1073    {
1074    // select proper input parameter for main audio matrix
1075    AudioMatrix = DVAUD_GetMainAudioMatrixInput(eInput);
1076    if (AudioMatrix == 0xFF)                                    // wrong input parameter
1077      I2C_Status = DVAUD_kBadParameter;
1078    else
1079      DVAUD_SetMainAudioMatrixOutput(eOutput, AudioMatrix, eInput);     // program output matrix including SIF1/2 switch
1080    }
1081
1082  return I2C_Status;
1083}
1084
1085static U8 DVAUD_CheckIfDirectScanIn(
1086                const DVAUD_Input_t             eInput)
1087{
1088  switch (eInput)
1089    {
1090    case DVAUD_kDirectMono:
1091    case DVAUD_kDirectSCART1:
1092    case DVAUD_kDirectSCART2:
1093    case DVAUD_kDirectSCART3:
1094    case DVAUD_kDirectSCART4:
1095    case DVAUD_kDirectSCART5:
1096      return 1;
1097    default:
1098      return 0;
1099    }
1100}
1101
1102static DVAUD_Status_t DVAUD_ManageDirectScartOut (
1103                const DVAUD_Output_t            eOutput,
1104                const DVAUD_Input_t             eInput)
1105{
1106  U8 ScartOutSelect;
1107  U16 FieldOut, FieldMute;
1108
1109  // select field to program input select & field to unmute depending on scart output
1110
1111  if (eOutput == DVAUD_kOutputSCART1)
1112    {
1113    FieldOut  = F_SC1_OUTPUT_SEL;
1114    FieldMute = F_SC1_MUTE;
1115    }
1116  else if (eOutput == DVAUD_kOutputSCART2)
1117    {
1118    FieldOut  = F_SC2_OUTPUT_SEL;
1119    FieldMute = F_SC2_MUTE;
1120    }
1121  else // DVAUD_kOutputSCART3
1122    {
1123    FieldOut  = F_SC3_OUTPUT_SEL;
1124    FieldMute = F_SC3_MUTE;
1125    }
1126 
1127  // select input select value to program
1128 
1129  switch (eInput)
1130    {
1131    case DVAUD_kDirectMono:
1132      ScartOutSelect = 1;
1133      break;
1134    case DVAUD_kDirectSCART1:
1135      ScartOutSelect = 2;
1136      break;
1137    case DVAUD_kDirectSCART2:
1138      ScartOutSelect = 3;
1139      break;
1140    case DVAUD_kDirectSCART3:
1141      ScartOutSelect = 4;
1142      break;
1143    case DVAUD_kDirectSCART4:
1144      ScartOutSelect = 5;
1145      break;
1146    case DVAUD_kDirectSCART5:
1147      ScartOutSelect = 7;
1148      break;
1149    default:
1150      return DVAUD_kBadParameter;       // should never occur thanks to DVAUD_CheckIfDirectScanIn()
1151    }
1152
1153  DVAUD_I2cWriteField(FieldOut, ScartOutSelect);        // R_SCART1_2_OUTPUT_CTRL or R_SCART3_OUT_SCAUX_CTRL
1154  DVAUD_I2cClrBit(FieldMute);                           // then unmute scart out
1155 
1156  return I2C_Status;
1157}
1158
1159// everything except I2S
1160
1161DVAUD_Status_t DVAUD_SwitchConnect (
1162                const DVAUD_Output_t            eOutput,
1163                const DVAUD_Input_t             eInput)
1164{                           
1165  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1166     return DVAUD_kDeviceNotReady;
1167
1168  switch (eOutput)
1169    {
1170    case DVAUD_kOutputSpeaker:
1171    case DVAUD_kOutputCenter:
1172    case DVAUD_kOutputSubwoofer:
1173    case DVAUD_kOutputSurround:
1174    case DVAUD_kOutputHeadphone:
1175    case DVAUD_kOutputI2SDelay:
1176    case DVAUD_kOutputSPDIF:
1177      return DVAUD_ManageMainAudioMatrix(eOutput, eInput);      // manage main audio matrix select block
1178
1179    case DVAUD_kOutputSCART1:
1180    case DVAUD_kOutputSCART2:
1181    case DVAUD_kOutputSCART3:
1182      if (DVAUD_CheckIfDirectScanIn(eInput))                    // check if direct scart input select
1183        return DVAUD_ManageDirectScartOut(eOutput, eInput);     // manage scart out select block (direct)
1184      else
1185        return DVAUD_ManageMainAudioMatrix(eOutput, eInput);    // manage main audio matrix select block
1186    default:
1187      return DVAUD_kBadParameter;
1188    }
1189}
1190
1191// ******************************************************************
1192
1193// I2S only
1194
1195DVAUD_Status_t DVAUD_I2SSwitchConnect (
1196                const DVAUD_I2SOutput_t         eI2SOutput,
1197                const DVAUD_Output_t            eOutput)
1198{
1199  U8 I2SOutSelect;
1200  U16 FieldOut, FieldDir;
1201
1202  FieldDir = 0;
1203 
1204  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1205     return DVAUD_kDeviceNotReady;
1206 
1207  switch(eI2SOutput)
1208    {
1209    case DVAUD_kOutputI2SData0:
1210       FieldOut = F_I2S_DATA0_CTRL;
1211       FieldDir = F_I2S_DATA0_DIR;
1212       break;
1213    case DVAUD_kOutputI2SData1:
1214       FieldOut = F_I2S_DATA1_CTRL;
1215       FieldDir = F_I2S_DATA1_DIR;
1216       break;
1217    case DVAUD_kOutputI2SData2:
1218       FieldOut = F_I2S_DATA2_CTRL;
1219       FieldDir = F_I2S_DATA2_DIR;
1220       break;
1221    case DVAUD_kOutputI2SData3:
1222       FieldOut = F_I2S_DATA3_CTRL;
1223       FieldDir = F_I2S_DATA3_DIR;
1224       break;
1225    case DVAUD_kOutputI2SAData:
1226       FieldOut = F_I2SA_DATA_CTRL;
1227       FieldDir = F_I2SA_DATA_DIR;
1228       break;
1229    case DVAUD_kOutputI2SOData0:        // TQFP100 only
1230       FieldOut = F_I2SO_DATA0_CTRL;    // no direction bit
1231       break;
1232    case DVAUD_kOutputI2SOData1:        // TQFP100 only
1233       FieldOut = F_I2SO_DATA1_CTRL;    // no direction bit
1234       break;
1235    default:                            // parameter not in list
1236      return DVAUD_kBadParameter;
1237    }
1238
1239  switch (eOutput)
1240    {
1241    case DVAUD_kOutputMuted:            // specific parameter to mute I2Sx output (and also revert it to "in")
1242      I2SOutSelect = 0;
1243      break;
1244    case DVAUD_kOutputSpeaker:
1245      I2SOutSelect = 1;
1246      break;
1247    case DVAUD_kOutputSurround:
1248    case DVAUD_kOutputHeadphone:
1249      I2SOutSelect = 2;
1250      break;
1251    case DVAUD_kOutputCenter:
1252    case DVAUD_kOutputSubwoofer:
1253      I2SOutSelect = 3;
1254      break;
1255    case DVAUD_kOutputSCART1:
1256    case DVAUD_kOutputSCART2:
1257    case DVAUD_kOutputSCART3:
1258      I2SOutSelect = 4;
1259      break;
1260    case DVAUD_kOutputSPDIF:
1261      I2SOutSelect = 5;
1262      break;
1263    case DVAUD_kOutputI2SDelay:
1264      I2SOutSelect = 6;
1265      break;
1266    case DVAUD_kOutputPCMCLK:           // only for I2S3
1267      if (eI2SOutput == DVAUD_kOutputI2SData3)
1268        I2SOutSelect = 7;
1269      else
1270        return DVAUD_kFeatureNotSupported;
1271      break;
1272    default:                            // parameter not in list
1273      return DVAUD_kBadParameter;
1274    }
1275
1276  // write I2S config
1277  DVAUD_I2cWriteField(FieldOut, I2SOutSelect);
1278
1279  // if muted: also set direction to "in", otherwise to "out"
1280  if (FieldDir)                         // only for I2S 0 1 2 3 A
1281    {
1282    if (eOutput ==  DVAUD_kOutputMuted)
1283      DVAUD_I2cClrBit(FieldDir);
1284    else
1285      DVAUD_I2cSetBit(FieldDir);
1286    }
1287   
1288  return I2C_Status;
1289}
1290
1291// ******************************************************************
1292
1293DVAUD_Status_t DVAUD_IRQSetConfig  (
1294                const DVAUD_IRQConfig_t*        const pstConfig)
1295{
1296  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1297     return DVAUD_kDeviceNotReady;
1298
1299  // IRQ0 new standard always enabled
1300 
1301  // IRQ1 sync lost
1302  switch (pstConfig->eIRQ1I2SSyncLost)
1303    {
1304    case DVAUD_kDisabled:
1305      DVAUD_I2cClrBit(F_IRQ1_ENABLE);   // R_I2S_IN_CONF
1306      break;
1307    case DVAUD_kEnabled:
1308      DVAUD_I2cSetBit(F_IRQ1_ENABLE);
1309      break;
1310    default:                            // parameter not in list
1311      return DVAUD_kBadParameter;
1312    }
1313
1314  // IRQ2 sync found
1315  switch (pstConfig->eIRQ2I2SSyncFound)
1316    {
1317    case DVAUD_kDisabled:
1318      DVAUD_I2cClrBit(F_IRQ2_ENABLE);   // R_I2S_IN_CONF
1319      break;
1320    case DVAUD_kEnabled:
1321      DVAUD_I2cSetBit(F_IRQ2_ENABLE);
1322      break;
1323    default:                            // parameter not in list
1324      return DVAUD_kBadParameter;
1325    }
1326
1327  // IRQ3 freq change
1328  switch (pstConfig->eIRQ3I2SFreqChange)
1329    {
1330    case DVAUD_kDisabled:
1331      DVAUD_I2cClrBit(F_IRQ3_ENABLE);   // R_I2S_IN_CONF
1332      break;
1333    case DVAUD_kEnabled:
1334      DVAUD_I2cSetBit(F_IRQ3_ENABLE);
1335      break;
1336    default:                            // parameter not in list
1337      return DVAUD_kBadParameter;
1338    }
1339
1340  // IRQ4 HP status change always enabled
1341  // IRQ5 HP unmute ready always enabled
1342
1343  return I2C_Status;
1344}
1345               
1346// ******************************************************************
1347
1348DVAUD_Status_t DVAUD_IRQReset (
1349                const DVAUD_IRQConfig_t*        const pstConfig)
1350{
1351  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1352     return DVAUD_kDeviceNotReady;
1353
1354  // IRQ0 new standard
1355  switch (pstConfig->eIRQ0NewStandard)
1356    {
1357    case DVAUD_kDisabled:               // do nothing
1358      break;
1359    case DVAUD_kEnabled:                // reset H/W flag
1360      DVAUD_I2cClrBit(F_IRQ0);          // R_IRQ_STATUS
1361      break;
1362    default:                            // parameter not in list
1363      return DVAUD_kBadParameter;
1364    }
1365 
1366  // IRQ1 sync lost
1367  switch (pstConfig->eIRQ1I2SSyncLost)
1368    {
1369    case DVAUD_kDisabled:               // do nothing
1370      break;
1371    case DVAUD_kEnabled:                // reset H/W flag
1372      DVAUD_I2cClrBit(F_IRQ1);          // R_IRQ_STATUS
1373      break;
1374    default:                            // parameter not in list
1375      return DVAUD_kBadParameter;
1376    }
1377
1378  // IRQ2 sync found
1379  switch (pstConfig->eIRQ2I2SSyncFound)
1380    {
1381    case DVAUD_kDisabled:               // do nothing
1382      break;
1383    case DVAUD_kEnabled:                // reset H/W flag
1384      DVAUD_I2cClrBit(F_IRQ2);          // R_IRQ_STATUS
1385      break;
1386    default:                            // parameter not in list
1387      return DVAUD_kBadParameter;
1388    }
1389
1390  // IRQ3 freq change
1391  switch (pstConfig->eIRQ3I2SFreqChange)
1392    {
1393    case DVAUD_kDisabled:               // do nothing
1394      break;
1395    case DVAUD_kEnabled:                // reset H/W flag
1396      DVAUD_I2cClrBit(F_IRQ3);          // R_IRQ_STATUS
1397      break;
1398    default:                            // parameter not in list
1399      return DVAUD_kBadParameter;
1400    }
1401
1402  // IRQ4 HP status change
1403  switch (pstConfig->eIRQ4HPStatusChange)
1404    {
1405    case DVAUD_kDisabled:               // do nothing
1406      break;
1407    case DVAUD_kEnabled:                // reset H/W flag
1408      DVAUD_I2cClrBit(F_IRQ4);          // R_IRQ_STATUS
1409      break;
1410    default:                            // parameter not in list
1411      return DVAUD_kBadParameter;
1412    }
1413
1414  // IRQ5 HP unmute ready
1415  switch (pstConfig->eIRQ5HPUnmuteReady)
1416    {
1417    case DVAUD_kDisabled:               // do nothing
1418      break;
1419    case DVAUD_kEnabled:                // reset H/W flag
1420      DVAUD_I2cClrBit(F_IRQ5);          // R_IRQ_STATUS
1421      break;
1422    default:                            // parameter not in list
1423      return DVAUD_kBadParameter;
1424    }
1425
1426  return I2C_Status;
1427}
1428
1429// ******************************************************************
1430
1431DVAUD_Status_t DVAUD_IRQGet (
1432                DVAUD_Bool_t*           const peOneIRQIsSet,
1433                DVAUD_IRQConfig_t*      const pstConfig)
1434{
1435  U8 IrqStatus;
1436 
1437  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1438     return DVAUD_kDeviceNotReady;
1439 
1440  IrqStatus = DVAUD_I2cReadReg(R_IRQ_STATUS) & 0x3F;
1441
1442  // return true if at least 1 IRQ is found set 
1443  *peOneIRQIsSet = (IrqStatus) ? DVAUD_kTrue : DVAUD_kFalse; 
1444
1445  // IRQ0 new standard set?
1446  pstConfig->eIRQ0NewStandard = (IrqStatus & 0x01) ? DVAUD_kEnabled : DVAUD_kDisabled;
1447 
1448  // IRQ1 sync lost set?
1449  pstConfig->eIRQ1I2SSyncLost = (IrqStatus & 0x02) ? DVAUD_kEnabled : DVAUD_kDisabled;
1450
1451  // IRQ2 sync found set?
1452  pstConfig->eIRQ2I2SSyncFound = (IrqStatus & 0x04) ? DVAUD_kEnabled : DVAUD_kDisabled;
1453
1454  // IRQ3 freq change set?
1455  pstConfig->eIRQ3I2SFreqChange = (IrqStatus & 0x08) ? DVAUD_kEnabled : DVAUD_kDisabled;
1456
1457  // IRQ4 HP status change set?
1458  pstConfig->eIRQ4HPStatusChange = (IrqStatus & 0x10) ? DVAUD_kEnabled : DVAUD_kDisabled;
1459
1460  // IRQ5 HP unmute ready set?
1461  pstConfig->eIRQ5HPUnmuteReady = (IrqStatus & 0x20) ? DVAUD_kEnabled : DVAUD_kDisabled;
1462
1463  return I2C_Status;
1464}
1465
1466// ******************************************************************
1467
1468#define NBOFI2SCONFIGREG 5
1469
1470static const U8 I2SPinConfigReg[NBOFI2SCONFIGREG] =
1471  {
1472  R_I2S_MATRIX_CTRL0,           // 0x53
1473  R_I2S_MATRIX_CTRL1,           // 0x54
1474  R_I2S_MATRIX_CTRL2,           // 0x55
1475  R_I2SO_DATA_CTRL,             // 0x59
1476  R_I2S_MATRIX_INPUT_CTRL       // 0x5E
1477  };
1478
1479static const U8 I2SPinConfig[DVAUD_kNbOfI2PinConfigPreset][NBOFI2SCONFIGREG] =
1480  {
1481  { 0x00, 0x00, 0x0A, 0x31, 0x00 },     // TQFP100 Conf 1: 4 * I2S in (@48kHz) + 3 * I2S out
1482  { 0xE0, 0xF0, 0x0A, 0x31, 0x01 },     // TQFP100 Conf 2: I2S SRC in + I2S delay loop (@48kHz) + 3 * I2S out
1483  { 0xE0, 0xF0, 0x10, 0x31, 0x53 },     // TQFP100 Conf 3: I2Saux SRC in + I2S delay loop (@48kHz) + 2 * I2S out
1484  { 0xE0, 0xF0, 0x1A, 0x31, 0x00 },     // TQFP100 Conf 4: I2S delay loop (@48kHz) + 3 * I2S out
1485  { 0x00, 0x00, 0xC0, 0x00, 0x00 },     // TQFP80  Conf 1: 4 * I2S in (@48kHz) + 0 * I2S out
1486  { 0x00, 0x09, 0x50, 0x01, 0xA0 }      // TQFP80  Conf 2: I2S SRC in + 1 * I2S out
1487  };
1488 
1489DVAUD_Status_t DVAUD_I2SPinSetConfig  (
1490                const DVAUD_I2SPinConfig_t*     const pstConfig)
1491{
1492  U8 Index, Reg, Input_Conf, WaitLoop, FW_Version;
1493
1494  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1495     return DVAUD_kDeviceNotReady;
1496
1497  if (pstConfig->eI2SPinConfigPreset >= DVAUD_kNbOfI2PinConfigPreset)
1498     return DVAUD_kBadParameter;
1499
1500  Index = pstConfig->eI2SPinConfigPreset;       // index in registers table and registers values table
1501
1502  for (Reg=0; Reg < NBOFI2SCONFIGREG; Reg++)
1503    DVAUD_I2cWriteReg(I2SPinConfigReg[Reg], I2SPinConfig[Index][Reg]);
1504   
1505  // Restart device if needed
1506  Input_Conf = DVAUD_I2cReadField(F_INPUT_CONFIG);
1507  if ((pstConfig->eI2SPinConfigPreset == DVAUD_kTQFP100Conf1) || (pstConfig->eI2SPinConfigPreset == DVAUD_kTQFP80Conf1))
1508  {
1509    // Multi 48 mode needed
1510    if (Input_Conf == 0) // SRC mode -> Restart needed
1511    {
1512      // Stop DSP F/W
1513      DVAUD_I2cClrBit(F_DSP_FW_RUN);                    // R_DSP_FW_CONF
1514     
1515      // wait until DSP ready
1516      WaitLoop = 10;
1517      while(WaitLoop)
1518      {
1519      // delay 1ms
1520      WAIT_Inms(1);
1521      if (DVAUD_I2cReadField(F_DSP_FW_READY))   // STAT_DSP_INIT if DSP ready
1522        break;                                  // exit loop
1523      WaitLoop--;
1524       }
1525      if (!WaitLoop)                            // end of loop, DSP never ready
1526        return DVAUD_kUnknownError;
1527
1528      // run DSP 
1529      DVAUD_I2cWriteReg(R_DSP_FW_CONF, 0x05);
1530
1531      // delay 2ms
1532      WAIT_Inms(2);
1533
1534      // check STAT F/W version number (in IC ROM) specific to IC type
1535      // this is a data from design, specific to IC type
1536      switch (Dev_ID)
1537        {
1538        case DVAUD_k83x7:
1539          FW_Version = 0x15;
1540          break;
1541        case DVAUD_k83x8:
1542          FW_Version = 0x2F;                           
1543          break;
1544        default:                                                // should never occur...
1545          FW_Version = 0x00;
1546          break;
1547        }
1548      if (DVAUD_I2cReadField(F_FW_VERSION) != FW_Version)       // STAT_FW_VERSION
1549        return DVAUD_kUnknownError;
1550    }
1551  }
1552  else // pstConfig->eI2SPinConfigPreset == DVAUD_kTQFP100Conf2/3/4 DVAUD_kTQFP80Conf2
1553  {
1554    // SRC mode needed
1555    if (Input_Conf == 1) // Mutli 48 mode -> Restart needed
1556    {
1557      // Stop DSP F/W
1558      DVAUD_I2cClrBit(F_DSP_FW_RUN);                    // R_DSP_FW_CONF
1559     
1560      // wait until DSP ready
1561      WaitLoop = 10;
1562      while(WaitLoop)
1563      {
1564      // delay 1ms
1565      WAIT_Inms(1);
1566      if (DVAUD_I2cReadField(F_DSP_FW_READY))   // STAT_DSP_INIT if DSP ready
1567        break;                                  // exit loop
1568      WaitLoop--;
1569       }
1570      if (!WaitLoop)                            // end of loop, DSP never ready
1571        return DVAUD_kUnknownError;
1572
1573      // run DSP 
1574      DVAUD_I2cWriteReg(R_DSP_FW_CONF, 0x01);
1575
1576      // delay 2ms
1577      WAIT_Inms(2);
1578
1579      // check STAT F/W version number (in IC ROM) specific to IC type
1580      // this is a data from design, specific to IC type
1581      switch (Dev_ID)
1582        {
1583        case DVAUD_k83x8:
1584          FW_Version = 0x2F;                           
1585          break;
1586        case DVAUD_k83x7:
1587          FW_Version = 0x15;
1588          break;
1589        default:                                                // should never occur...
1590          FW_Version = 0x00;
1591          break;
1592        }
1593      if (DVAUD_I2cReadField(F_FW_VERSION) != FW_Version)       // STAT_FW_VERSION
1594        return DVAUD_kUnknownError;
1595    }
1596  }
1597         
1598  return I2C_Status;
1599}
1600
1601// ******************************************************************
1602
1603DVAUD_Status_t DVAUD_I2SHWSetConfig  (
1604                const DVAUD_I2SHWConfig_t*      const pstConfig)
1605{
1606  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1607     return DVAUD_kDeviceNotReady;
1608
1609  switch (pstConfig->eSyncSignIsPositive)
1610    {
1611    case DVAUD_kTrue:
1612      DVAUD_I2cSetBit(F_SYNC_SIGN);     // R_I2S_CTRL
1613      break;
1614    case DVAUD_kFalse:
1615      DVAUD_I2cClrBit(F_SYNC_SIGN);
1616      break;
1617    default:                            // parameter not in list
1618      return DVAUD_kBadParameter;
1619    }
1620
1621  if ((pstConfig->eLockThreshold) >= DVAUD_kNbOfI2SLockThreshold)
1622    return DVAUD_kBadParameter;
1623  DVAUD_I2cWriteField(F_LOCK_TH, pstConfig->eLockThreshold);    // R_I2S_CTRL
1624
1625  if ((pstConfig->eSyncConstant) >= DVAUD_kNbOfI2SSyncConstant)
1626    return DVAUD_kBadParameter;
1627  DVAUD_I2cWriteField(F_SYNC_CST, pstConfig->eSyncConstant);    // R_I2S_CTRL
1628 
1629  return I2C_Status;
1630}
1631
1632// ******************************************************************
1633
1634DVAUD_Status_t DVAUD_I2SSWSetConfig  (
1635                const DVAUD_I2SSWConfig_t*      const pstConfig,
1636                const DVAUD_I2SSWConfig_t*      const pstDelayConfig,
1637                const U8                        ucShiftRight,
1638                const U8                        ucWordMask)
1639{
1640  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1641     return DVAUD_kDeviceNotReady;
1642
1643  // main I2S configuration
1644 
1645  switch (pstConfig->eLRCLKStartIsRight)
1646    {
1647    case DVAUD_kTrue:
1648      DVAUD_I2cSetBit(F_LRCLK_START);   // R_I2S_IN_CONF
1649      break;
1650    case DVAUD_kFalse:
1651      DVAUD_I2cClrBit(F_LRCLK_START);
1652      break;
1653    default:                            // parameter not in list
1654      return DVAUD_kBadParameter;
1655    }
1656
1657  switch (pstConfig->eLRCLKPolarityIsHigh)
1658    {
1659    case DVAUD_kTrue:
1660      DVAUD_I2cSetBit(F_LRCLK_POLARITY);// R_I2S_IN_CONF
1661      break;
1662    case DVAUD_kFalse:
1663      DVAUD_I2cClrBit(F_LRCLK_POLARITY);
1664      break;
1665    default:                            // parameter not in list
1666      return DVAUD_kBadParameter;
1667    }
1668
1669  switch (pstConfig->eSCLKPolarityIsRise)
1670    {
1671    case DVAUD_kTrue:
1672      DVAUD_I2cSetBit(F_SCLK_POLARITY); // R_I2S_IN_CONF
1673      break;
1674    case DVAUD_kFalse:
1675      DVAUD_I2cClrBit(F_SCLK_POLARITY);
1676      break;
1677    default:                            // parameter not in list
1678      return DVAUD_kBadParameter;
1679    }
1680
1681  switch (pstConfig->eMSBIsFirst)
1682    {
1683    case DVAUD_kTrue:
1684      DVAUD_I2cSetBit(F_DATA_CFG);      // R_I2S_IN_CONF
1685      break;
1686    case DVAUD_kFalse:
1687      DVAUD_I2cClrBit(F_DATA_CFG);
1688      break;
1689    default:                            // parameter not in list
1690      return DVAUD_kBadParameter;
1691    }
1692
1693  switch (pstConfig->eUModeIsStandard)
1694    {
1695    case DVAUD_kTrue:
1696      DVAUD_I2cSetBit(F_I2S_MODE);      // R_I2S_IN_CONF
1697      break;
1698    case DVAUD_kFalse:
1699      DVAUD_I2cClrBit(F_I2S_MODE);
1700      break;
1701    default:                            // parameter not in list
1702      return DVAUD_kBadParameter;
1703    }
1704
1705  // I2S delay configuration
1706 
1707  switch (pstDelayConfig->eLRCLKStartIsRight)
1708    {
1709    case DVAUD_kTrue:
1710      DVAUD_I2cSetBit(F_DELAY_LRCLK_START);     // R_I2S_IN_DELAY_CONF
1711      break;
1712    case DVAUD_kFalse:
1713      DVAUD_I2cClrBit(F_DELAY_LRCLK_START);
1714      break;
1715    default:                                    // parameter not in list
1716      return DVAUD_kBadParameter;
1717    }
1718
1719  switch (pstDelayConfig->eLRCLKPolarityIsHigh)
1720    {
1721    case DVAUD_kTrue:
1722      DVAUD_I2cSetBit(F_DELAY_LRCLK_POLARITY);  // R_I2S_IN_DELAY_CONF
1723      break;
1724    case DVAUD_kFalse:
1725      DVAUD_I2cClrBit(F_DELAY_LRCLK_POLARITY);
1726      break;
1727    default:                            // parameter not in list
1728      return DVAUD_kBadParameter;
1729    }
1730
1731  switch (pstDelayConfig->eSCLKPolarityIsRise)
1732    {
1733    case DVAUD_kTrue:
1734      DVAUD_I2cSetBit(F_DELAY_SCLK_POLARITY);   // R_I2S_IN_DELAY_CONF
1735      break;
1736    case DVAUD_kFalse:
1737      DVAUD_I2cClrBit(F_DELAY_SCLK_POLARITY);
1738      break;
1739    default:                                    // parameter not in list
1740      return DVAUD_kBadParameter;
1741    }
1742
1743  switch (pstDelayConfig->eMSBIsFirst)
1744    {
1745    case DVAUD_kTrue:
1746      DVAUD_I2cSetBit(F_DELAY_DATA_CFG);        // R_I2S_IN_DELAY_CONF
1747      break;
1748    case DVAUD_kFalse:
1749      DVAUD_I2cClrBit(F_DELAY_DATA_CFG);
1750      break;
1751    default:                                    // parameter not in list
1752      return DVAUD_kBadParameter;
1753    }
1754
1755  switch (pstDelayConfig->eUModeIsStandard)
1756    {
1757    case DVAUD_kTrue:
1758      DVAUD_I2cSetBit(F_DELAY_I2S_MODE);        // R_I2S_IN_DELAY_CONF
1759      break;
1760    case DVAUD_kFalse:
1761      DVAUD_I2cClrBit(F_DELAY_I2S_MODE);
1762      break;
1763    default:                                    // parameter not in list
1764      return DVAUD_kBadParameter;
1765    }
1766 
1767  if (ucShiftRight > 31)
1768    return DVAUD_kBadParameter;                                 // value out of range
1769  DVAUD_I2cWriteField(F_SHIFT_RIGHT_RANGE, ucShiftRight);       // R_I2S_IN_SHIFT_RIGHT
1770
1771  if (ucWordMask > 31)
1772    return DVAUD_kBadParameter;                 // value out of range
1773  DVAUD_I2cWriteField(F_WORD_MASK, ucWordMask); // R_I2S_IN_MASK
1774 
1775  return I2C_Status;
1776}
1777
1778// ******************************************************************
1779
1780DVAUD_Status_t DVAUD_I2SInputFrequencyGet (
1781                DVAUD_I2SFrequency_t*           const peI2SFreq)
1782{
1783  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1784     return DVAUD_kDeviceNotReady;
1785
1786  *peI2SFreq = (DVAUD_I2SFrequency_t) DVAUD_I2cReadField(F_I2S_INPUT_FREQ);     // R_STAT_STD_HP_I2S_IN
1787 
1788  return I2C_Status;
1789}
1790
1791// ******************************************************************
1792
1793DVAUD_Status_t DVAUD_SPDIFOutSetConfig  (
1794                const DVAUD_SPDIFConfig_t*      const pstConfig)
1795{
1796  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1797     return DVAUD_kDeviceNotReady;
1798
1799  switch (pstConfig->eNoCopyright)
1800    {
1801    case DVAUD_kTrue:
1802      DVAUD_I2cSetBit(F_SPDIF_NO_COPYRIGHT);    // R_SPDIF_CONF
1803      break;
1804    case DVAUD_kFalse:
1805      DVAUD_I2cClrBit(F_SPDIF_NO_COPYRIGHT);
1806      break;
1807    default:                                    // parameter not in list
1808      return DVAUD_kBadParameter;
1809    }
1810
1811  switch (pstConfig->eNoPCM)
1812    {
1813    case DVAUD_kTrue:
1814      DVAUD_I2cSetBit(F_SPDIF_NO_PCM);  // R_SPDIF_CONF
1815      break;
1816    case DVAUD_kFalse:
1817      DVAUD_I2cClrBit(F_SPDIF_NO_PCM);
1818      break;
1819    default:                            // parameter not in list
1820      return DVAUD_kBadParameter;
1821    }
1822
1823  return I2C_Status;
1824}
1825
1826// ******************************************************************
1827
1828DVAUD_Status_t DVAUD_ParametricEqSetConfig  (
1829                const DVAUD_ParametricEqConfig_t*       const pstConfig)
1830{ 
1831  U16 Freq;
1832  U32 ulVal;
1833
1834  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1835     return DVAUD_kDeviceNotReady;
1836 
1837  Freq =  pstConfig->ucFrequencyInHz;
1838 
1839  switch (pstConfig->ucBandNumber)
1840    {
1841    case 1:
1842      if (Freq<40 || Freq>400)
1843        return DVAUD_kBadParameter;
1844      ulVal = ((Freq-40)*255L)/360L;
1845      break;
1846    case 2:
1847      if (Freq<400 || Freq>2000)
1848        return DVAUD_kBadParameter;
1849      ulVal = ((Freq-400)*255L)/1600L;
1850      break;
1851    case 3:
1852      if (Freq<2000 || Freq>10000)
1853        return DVAUD_kBadParameter;
1854      ulVal = ((Freq-2000)*255L)/8000L;
1855      break;
1856    default:     
1857      return DVAUD_kBadParameter;
1858    }
1859   
1860  DVAUD_I2cWriteReg(R_PARAM_EQ_CONF2, (U8)ulVal);               // previous computation already scaled value down to 8 bits
1861
1862  if ((pstConfig->ucQ) > 31)
1863    return DVAUD_kBadParameter;                         // value out of range
1864  DVAUD_I2cWriteField(F_PARAM_EQ_Q, pstConfig->ucQ);    // R_PARAM_EQ_CONF3
1865
1866  // valid range is -12dB to +3dB
1867  if ((pstConfig->sGainInmdB)<(-12000) || (pstConfig->sGainInmdB)>3000)
1868    return DVAUD_kBadParameter;                         // value out of range
1869  ulVal = (pstConfig->sGainInmdB)/500;                  // range -24..+6 = -12..+3dB (step 0.5dB)
1870  DVAUD_I2cWriteField(F_PARAM_EQ_GAIN, (U8)ulVal);      // R_PARAM_EQ_CONF1
1871
1872  // enable band only at the very end to write new set of parameters
1873
1874  switch (pstConfig->ucBandNumber)
1875    {
1876    case 1:
1877      DVAUD_I2cSetBit(F_BAND1_VALID);   // R_PARAM_EQ_CONF3
1878      break;
1879    case 2:
1880      DVAUD_I2cSetBit(F_BAND2_VALID);   // R_PARAM_EQ_CONF3
1881      break;
1882    case 3:
1883      DVAUD_I2cSetBit(F_BAND3_VALID);   // R_PARAM_EQ_CONF3
1884      break;
1885    // no default, parameter was already checked before
1886    }
1887 
1888  return I2C_Status;
1889}
1890
1891// ******************************************************************
1892
1893DVAUD_Status_t DVAUD_ParametricEqSet (
1894                const DVAUD_Enabled_t           eNewStatus)
1895{
1896  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1897     return DVAUD_kDeviceNotReady;
1898
1899  switch (eNewStatus)
1900    {
1901    case DVAUD_kDisabled:
1902      DVAUD_I2cClrBit(F_PARAM_EQ_ON);   // R_PARAM_EQ_CONF1
1903      break;
1904    case DVAUD_kEnabled:
1905      DVAUD_I2cSetBit(F_PARAM_EQ_ON);
1906      break;
1907    default:                            // parameter not in list
1908      return DVAUD_kBadParameter;
1909    }
1910
1911  return I2C_Status;
1912}
1913
1914// ******************************************************************
1915
1916DVAUD_Status_t DVAUD_AnticlippingSetConfig  (
1917                const DVAUD_AnticlippingMode_t  eLSNewStatus, 
1918                const DVAUD_AnticlippingMode_t  eHPNewStatus,
1919                const DVAUD_AnticlippingMode_t  eSCARTNewStatus,
1920                const DVAUD_AnticlippingMode_t  eSPDIFNewStatus)
1921{
1922
1923  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1924     return DVAUD_kDeviceNotReady;
1925
1926  if (eLSNewStatus >= DVAUD_kNbOfAnticlippingMode)
1927    return DVAUD_kBadParameter;
1928  DVAUD_I2cWriteField(F_CLAMP_LS, eLSNewStatus);        // R_ANTICLIPPING
1929
1930  if (eHPNewStatus >= DVAUD_kNbOfAnticlippingMode)
1931    return DVAUD_kBadParameter;
1932  DVAUD_I2cWriteField(F_CLAMP_HP, eHPNewStatus);        // R_ANTICLIPPING
1933
1934  if (eSCARTNewStatus >= DVAUD_kNbOfAnticlippingMode)
1935    return DVAUD_kBadParameter;
1936  DVAUD_I2cWriteField(F_CLAMP_SCART, eSCARTNewStatus);  // R_ANTICLIPPING
1937
1938  if (eSPDIFNewStatus >= DVAUD_kNbOfAnticlippingMode)
1939    return DVAUD_kBadParameter;
1940  DVAUD_I2cWriteField(F_CLAMP_SPDIF, eSPDIFNewStatus);  // R_ANTICLIPPING
1941 
1942  return I2C_Status;
1943}
1944
1945// ******************************************************************
1946
1947DVAUD_Status_t DVAUD_HPDetectSetConfig  (
1948                const DVAUD_HPDetectMode_t      eNewStatus,
1949                const DVAUD_Enabled_t           eLSAutoMute)
1950{
1951  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1952     return DVAUD_kDeviceNotReady;
1953
1954  if (eNewStatus >= DVAUD_kNbOfHPDetectMode)
1955    return DVAUD_kBadParameter;
1956  DVAUD_I2cWriteField(F_HP_MODE, eNewStatus);   // R_HP_SCARTAUX_CONF
1957
1958  switch (eLSAutoMute)
1959    {
1960    case DVAUD_kDisabled:
1961      DVAUD_I2cClrBit(F_LS_AUTO_MUTE);  // R_HP_SCARTAUX_CONF
1962      break;
1963    case DVAUD_kEnabled:
1964      DVAUD_I2cSetBit(F_LS_AUTO_MUTE);
1965      break;
1966    default:                            // parameter not in list
1967      return DVAUD_kBadParameter;
1968    }
1969
1970  return I2C_Status;
1971}
1972
1973// ******************************************************************
1974
1975DVAUD_Status_t DVAUD_HPDetectGet (
1976                DVAUD_Enabled_t*                const peNewState)
1977{
1978  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1979     return DVAUD_kDeviceNotReady;
1980
1981  *peNewState = DVAUD_I2cReadField(F_HP_DETECTED) ? DVAUD_kEnabled : DVAUD_kDisabled;   // R_STAT_STD_HP_I2S_IN
1982 
1983  return I2C_Status;
1984}
1985
1986// ******************************************************************
1987
1988DVAUD_Status_t DVAUD_BeeperSetConfig (
1989                const DVAUD_BeeperConfig_t*     const pstConfig)
1990{
1991  U8 BeepPath;
1992 
1993  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
1994     return DVAUD_kDeviceNotReady;
1995
1996  if ((pstConfig->eBeeperSound) >= DVAUD_kNbOfBeeperSound)
1997    return DVAUD_kBadParameter;
1998  DVAUD_I2cWriteField(F_SOUND_SELECT, pstConfig->eBeeperSound);         // R_BEEPER_CONF1
1999
2000  if ((pstConfig->eBeeperNote) >= DVAUD_kNbOfBeeperNote)
2001    return DVAUD_kBadParameter;
2002  DVAUD_I2cWriteField(F_BEEP_NOTE, pstConfig->eBeeperNote);             // R_BEEPER_CONF3
2003
2004  if ((pstConfig->ucBeeperOctave)==0 || (pstConfig->ucBeeperOctave)>6)  // octave from 1 to 6
2005    return DVAUD_kBadParameter;
2006  DVAUD_I2cWriteField(F_BEEP_OCTAVE, (pstConfig->ucBeeperOctave)-1);    // R_BEEPER_CONF3 real value from 0 to 5
2007
2008  if ((pstConfig->eBeeperRelease) >= DVAUD_kNbOfBeeperRelease)
2009    return DVAUD_kBadParameter;
2010  DVAUD_I2cWriteField(F_BEEP_RELEASE, pstConfig->eBeeperRelease);       // R_BEEPER_CONF4
2011
2012  BeepPath = 0;
2013 
2014  switch (pstConfig->eBeeperOnLS)
2015    {
2016    case DVAUD_kDisabled:
2017      break;
2018    case DVAUD_kEnabled:
2019      BeepPath |=1;
2020      break;
2021    default:                            // parameter not in list
2022      return DVAUD_kBadParameter;
2023    }
2024
2025  switch (pstConfig->eBeeperOnHP)
2026    {
2027    case DVAUD_kDisabled:
2028      break;
2029    case DVAUD_kEnabled:
2030      BeepPath |=2;
2031      break;
2032    default:                            // parameter not in list
2033      return DVAUD_kBadParameter;
2034    }
2035
2036  DVAUD_I2cWriteField(F_BEEP_PATH, BeepPath);   // R_BEEPER_CONF2
2037 
2038  switch (pstConfig->eBeeperContinuous)
2039    {
2040    case DVAUD_kTrue:
2041      DVAUD_I2cSetBit(F_CONTINUOUS_MODE);       // R_BEEPER_CONF4
2042      break;
2043    case DVAUD_kFalse:
2044      DVAUD_I2cClrBit(F_CONTINUOUS_MODE);
2045      break;
2046    default:                                    // parameter not in list
2047      return DVAUD_kBadParameter;
2048    }
2049
2050  if ((pstConfig->eBeeperDuration) >= DVAUD_kNbOfBeeperDuration)
2051    return DVAUD_kBadParameter;
2052  DVAUD_I2cWriteField(F_BEEP_DURATION, pstConfig->eBeeperDuration);     // R_BEEPER_CONF4
2053
2054  if ((pstConfig->cBeeperVolumeIndB)<(-93) || (pstConfig->cBeeperVolumeIndB)>0)
2055    return DVAUD_kBadParameter;                                                 // value out of range
2056  DVAUD_I2cWriteField(F_BEEP_VOLUME, ((pstConfig->cBeeperVolumeIndB)+93)/3);    // R_BEEPER_CONF2,0x1F [-93;0] converts to [0;31]
2057
2058  return I2C_Status;
2059}
2060
2061// ******************************************************************
2062
2063DVAUD_Status_t DVAUD_BeeperSet (
2064                const DVAUD_Enabled_t           eNewStatus)
2065{
2066  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2067     return DVAUD_kDeviceNotReady;
2068
2069  switch (eNewStatus)
2070    {
2071    case DVAUD_kDisabled:
2072      DVAUD_I2cClrBit(F_BEEP_ON);       // R_BEEPER_CONF1
2073      break;
2074    case DVAUD_kEnabled:
2075      DVAUD_I2cSetBit(F_BEEP_ON);
2076      break;
2077    default:                            // parameter not in list
2078      return DVAUD_kBadParameter;
2079    }
2080
2081  return I2C_Status;
2082}
2083
2084// ******************************************************************
2085
2086DVAUD_Status_t DVAUD_STOmniSurroundSetConfig  (
2087                const DVAUD_STOmniSurroundConfig_t*     const pstConfig) // -> LS only
2088{
2089  U16 Percent;
2090
2091  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2092     return DVAUD_kDeviceNotReady;
2093
2094  if ((pstConfig->eSurroundMode) >= DVAUD_kNbOfOmniSurroundMode)
2095    return DVAUD_kBadParameter;
2096  DVAUD_I2cWriteField(F_OMNISRND_INPUT_MODE, pstConfig->eSurroundMode); // R_OMNISRND_CONF1
2097
2098  if ((pstConfig->eWideMode) >= DVAUD_kNbOfWideMode)
2099    return DVAUD_kBadParameter;
2100  DVAUD_I2cWriteField(F_WIDE_MODE, pstConfig->eWideMode);       // R_OMNISRND_CONF2
2101
2102  if ((pstConfig->ucWideLevelInPercent) > 100)
2103    return DVAUD_kBadParameter;
2104  Percent = ((U16)(pstConfig->ucWideLevelInPercent)*(U16)63)/100;       // range [0;100%] converts to [0;63]
2105  DVAUD_I2cWriteField(F_WIDE_LEVEL, (U8)Percent);                       // R_OMNISRND_CONF2
2106
2107  if ((pstConfig->eVoiceMode) >= DVAUD_kNbOfVoiceMode)
2108    return DVAUD_kBadParameter;
2109  DVAUD_I2cWriteField(F_ST_VOICE, pstConfig->eVoiceMode);       // R_OMNISRND_CONF1
2110 
2111  return I2C_Status;
2112}
2113
2114// ******************************************************************
2115
2116DVAUD_Status_t DVAUD_STOmniSurroundSet (
2117                const DVAUD_Enabled_t           eNewStatus) // -> LS only
2118{
2119  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2120     return DVAUD_kDeviceNotReady;
2121
2122  switch (eNewStatus)
2123    {
2124    case DVAUD_kDisabled:
2125      DVAUD_I2cClrBit(F_OMNISRND_ON);   // R_OMNISRND_CONF1
2126      break;
2127    case DVAUD_kEnabled:
2128      DVAUD_I2cSetBit(F_OMNISRND_ON);
2129      break;
2130    default:                            // parameter not in list
2131      return DVAUD_kBadParameter;
2132    }
2133
2134  return I2C_Status;
2135}
2136
2137// ******************************************************************
2138
2139DVAUD_Status_t DVAUD_STDynamicBassSetConfig  (
2140                const DVAUD_Output_t                    eOutput,
2141                const DVAUD_STDynamicBassConfig_t*      const pstConfig) // -> LS & HP
2142{
2143  U8 Reg;
2144
2145  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2146     return DVAUD_kDeviceNotReady;
2147
2148  switch (eOutput)
2149    {
2150    case DVAUD_kOutputSpeaker:          // LS
2151      Reg = 1;                          // 1=LS
2152      break;
2153    case DVAUD_kOutputHeadphone:        // HP
2154      Reg = 0;                          // 0=HP
2155      break;
2156    default:                            // parameter config not in list
2157      return DVAUD_kBadParameter;
2158    }
2159
2160  if ((pstConfig->eFrequency) >= DVAUD_kNbOfDynamicBassFrequency)
2161    return DVAUD_kBadParameter;
2162   // R_DYNAMIC_BASS_LS or R_DYNAMIC_BASS_HP
2163  DVAUD_I2cWriteField((Reg)? F_DYN_BASS_LS_FREQ : F_DYN_BASS_HP_FREQ, pstConfig->eFrequency);
2164
2165  if ((pstConfig->usGainInmdB)>15500)
2166    return DVAUD_kBadParameter;         // value out of range
2167  // range 0..31 = 0..+15.5dB (step 0.5dB)
2168  // R_DYNAMIC_BASS_LS or R_DYNAMIC_BASS_HP
2169  DVAUD_I2cWriteField((Reg)? F_DYN_BASS_LS_LEVEL : F_DYN_BASS_HP_LEVEL, (pstConfig->usGainInmdB)/500);
2170
2171  return I2C_Status;
2172}
2173
2174// ******************************************************************
2175
2176DVAUD_Status_t DVAUD_STBynamicBassSet (
2177                const DVAUD_Output_t            eOutput,
2178                const DVAUD_Enabled_t           eNewStatus) // -> LS & HP
2179{
2180  U16 Field;
2181 
2182  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2183     return DVAUD_kDeviceNotReady;
2184
2185  switch (eOutput)
2186    {
2187    case DVAUD_kOutputSpeaker:          // LS
2188      Field = F_DYN_BASS_LS_ON;         // R_DYNAMIC_BASS_LS
2189      break;
2190    case DVAUD_kOutputHeadphone:        // HP
2191      Field = F_DYN_BASS_HP_ON;         // R_DYNAMIC_BASS_HP
2192      break;
2193    default:                            // parameter config not in list
2194      return DVAUD_kBadParameter;
2195    }
2196
2197  switch (eNewStatus)
2198    {
2199    case DVAUD_kDisabled:
2200      DVAUD_I2cClrBit(Field);
2201      break;
2202    case DVAUD_kEnabled:
2203      DVAUD_I2cSetBit(Field);
2204      break;
2205    default:                            // parameter not in list
2206      return DVAUD_kBadParameter;
2207    }
2208
2209  return I2C_Status;
2210}
2211
2212// ******************************************************************
2213
2214DVAUD_Status_t DVAUD_SRSTruSurroundXTSetConfig  (
2215                const DVAUD_SRSTruSurroundXTConfig_t*   const pstConfig) // -> LS only
2216{
2217  S32 ValLS;
2218
2219  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2220     return DVAUD_kDeviceNotReady;
2221
2222  if ((Dev_Capability.eSRSTruSurroundXT  != DVAUD_kImplemented) &&
2223      (Dev_Capability.eSRSWOW            != DVAUD_kImplemented))
2224    return DVAUD_kFeatureNotSupported;          // no SRS supported
2225
2226  if (((pstConfig->eSurroundMode) != DVAUD_kTruSurroundMono) &&
2227      ((pstConfig->eSurroundMode) != DVAUD_kTruSurroundStereo) &&
2228       (Dev_Capability.eSRSWOW    == DVAUD_kImplemented))
2229    return DVAUD_kFeatureNotSupported;          // only Mono and Stereo modes supported in SRS Wow (SRS=1)
2230 
2231  if ((pstConfig->eSurroundMode) >= DVAUD_kNbOfTruSurroundXTMode)
2232    return DVAUD_kBadParameter;
2233  DVAUD_I2cWriteField(F_TRUSRND_INPUT_MODE, pstConfig->eSurroundMode);  // R_TRUSRND_CONF
2234
2235  switch (pstConfig->eTruSurroundXTIsBypassed)
2236    {
2237    case DVAUD_kTrue:
2238      DVAUD_I2cSetBit(F_TRUSRND_BYPASS);        // R_TRUSRND_CONF
2239      break;
2240    case DVAUD_kFalse:
2241      DVAUD_I2cClrBit(F_TRUSRND_BYPASS);
2242      break;
2243    default:                            // parameter not in list
2244      return DVAUD_kBadParameter;
2245    }
2246
2247  // Attenuation -127.5dB -> 0dB
2248  ValLS = pstConfig->lTSXTAttenuationInmdB;
2249  if (ValLS>0 || ValLS<(-127500))
2250    return DVAUD_kBadParameter;                 // value out of range
2251  // range -127.5dB..0 = 0..255 (step 0.5)
2252  DVAUD_I2cWriteReg(R_TRUSRND_LEVEL, (-ValLS)/500);
2253
2254  switch (pstConfig->eDialogClarity)
2255    {
2256    case DVAUD_kDisabled:
2257      DVAUD_I2cClrBit(F_DC_ON);         // R_TRUSRND_CONF
2258      break;
2259    case DVAUD_kEnabled:
2260      DVAUD_I2cSetBit(F_DC_ON);
2261      break;
2262    default:                            // parameter not in list
2263      return DVAUD_kBadParameter;
2264    }
2265
2266  // Attenuation -127.5dB -> 0dB
2267  ValLS = pstConfig->lDCAttenuationInmdB;
2268  if (ValLS>0 || ValLS<(-127500))
2269    return DVAUD_kBadParameter;                 // value out of range
2270  // range -127.5dB..0 = 0..255 (step 0.5)
2271  DVAUD_I2cWriteReg(R_TRUSRND_DC_LEVEL, (-ValLS)/500);
2272
2273  return I2C_Status;
2274}
2275
2276// ******************************************************************
2277
2278DVAUD_Status_t DVAUD_SRSTruSurroundXTSet (
2279                const DVAUD_Enabled_t           eNewStatus) // -> LS only
2280{
2281  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2282     return DVAUD_kDeviceNotReady;
2283
2284  if ((Dev_Capability.eSRSTruSurroundXT  != DVAUD_kImplemented) &&
2285      (Dev_Capability.eSRSWOW            != DVAUD_kImplemented))
2286    return DVAUD_kFeatureNotSupported;          // no SRS supported
2287
2288  switch (eNewStatus)
2289    {
2290    case DVAUD_kDisabled:
2291      DVAUD_I2cClrBit(F_TRUSRND_ON);    // R_TRUSRND_CONF
2292      break;
2293    case DVAUD_kEnabled:
2294      DVAUD_I2cSetBit(F_TRUSRND_ON);
2295      break;
2296    default:                            // parameter not in list
2297      return DVAUD_kBadParameter;
2298    }
2299
2300  return I2C_Status;
2301}
2302
2303// ******************************************************************
2304
2305DVAUD_Status_t DVAUD_SRSTruBassSetConfig  (
2306                const DVAUD_Output_t            eOutput,
2307                const DVAUD_SRSTruBassConfig_t* const pstConfig) // -> LS & HP
2308{
2309  U8 Reg;
2310
2311  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2312     return DVAUD_kDeviceNotReady;
2313  if ((Dev_Capability.eSRSTruSurroundXT  != DVAUD_kImplemented) &&
2314      (Dev_Capability.eSRSWOW            != DVAUD_kImplemented))
2315    return DVAUD_kFeatureNotSupported;          // no SRS supported
2316  switch (eOutput)
2317    {
2318    case DVAUD_kOutputSpeaker:          // LS
2319      Reg = 1;                          // 1=LS
2320      break;
2321    case DVAUD_kOutputHeadphone:        // HP
2322      Reg = 0;                          // 0=HP
2323      break;
2324    default:                            // parameter config not in list
2325      return DVAUD_kBadParameter;
2326    }
2327  if ((pstConfig->eFrequency) >= DVAUD_kNbOfTruBassFrequency)
2328    return DVAUD_kBadParameter;
2329  // R_TRUBASS_LS_CONF or R_TRUBASS_HP_CONF
2330  DVAUD_I2cWriteField((Reg)? F_TRUBASS_LS_SIZE : F_TRUBASS_HP_SIZE, pstConfig->eFrequency);
2331  if ((pstConfig->lAttenuationInmdB)<(-127500) || (pstConfig->lAttenuationInmdB)>0)
2332    return DVAUD_kBadParameter;         // value out of range
2333  // range -127.5dB..0 = 0..255 (step 0.5)
2334  DVAUD_I2cWriteReg((Reg)? R_TRUBASS_LS_LEVEL : R_TRUBASS_HP_LEVEL, ((pstConfig->lAttenuationInmdB)/(-500)));
2335  return I2C_Status;
2336}
2337
2338// ******************************************************************
2339
2340DVAUD_Status_t DVAUD_SRSTruBassSet (
2341                const DVAUD_Output_t            eOutput,
2342                const DVAUD_Enabled_t           eNewStatus) // -> LS & HP
2343{
2344  U16 Field;
2345
2346  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2347     return DVAUD_kDeviceNotReady;
2348
2349  if ((Dev_Capability.eSRSTruSurroundXT  != DVAUD_kImplemented) &&
2350      (Dev_Capability.eSRSWOW            != DVAUD_kImplemented))
2351    return DVAUD_kFeatureNotSupported;          // no SRS supported
2352
2353  switch (eOutput)
2354    {
2355    case DVAUD_kOutputSpeaker:          // LS
2356      Field = F_TRUBASS_LS_ON;          // R_TRUBASS_LS_CONF
2357      break;
2358    case DVAUD_kOutputHeadphone:        // HP
2359      Field = F_TRUBASS_HP_ON;          // R_TRUBASS_HP_CONF
2360      break;
2361    default:                            // parameter config not in list
2362      return DVAUD_kBadParameter;
2363    }
2364
2365  switch (eNewStatus)
2366    {
2367    case DVAUD_kDisabled:
2368      DVAUD_I2cClrBit(Field);
2369      break;
2370    case DVAUD_kEnabled:
2371      DVAUD_I2cSetBit(Field);
2372      break;
2373    default:                            // parameter not in list
2374      return DVAUD_kBadParameter;
2375    }
2376
2377  return I2C_Status;
2378}
2379
2380// ******************************************************************
2381
2382DVAUD_Status_t DVAUD_SmartVolumeSetConfig  (
2383                const DVAUD_Output_t                    eOutput,
2384                const DVAUD_SmartVolumeConfig_t*        const pstConfig) // -> LS & HP
2385{
2386  U8 Reg;
2387 
2388  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2389     return DVAUD_kDeviceNotReady;
2390
2391  switch (eOutput)
2392    {
2393    case DVAUD_kOutputSpeaker:          // LS
2394      Reg = 1;                          // 1=LS
2395      break;
2396    case DVAUD_kOutputHeadphone:        // HP
2397      Reg = 0;                          // 0=HP
2398      break;
2399    default:                            // parameter config not in list
2400      return DVAUD_kBadParameter;
2401    }
2402
2403  if (Reg == 1)         // LS only
2404    {
2405    if ((pstConfig->ePeakDetection) >= DVAUD_kNbOfLSPeakDetectionMode)
2406      return DVAUD_kBadParameter;
2407    DVAUD_I2cWriteField(F_SVC_LS_INPUT, pstConfig->ePeakDetection);     // R_SVC_CONF
2408    }
2409
2410  if ((pstConfig->eReleaseTime) >= DVAUD_kNbOfReleaseTime)
2411    return DVAUD_kBadParameter;
2412  // R_SVC_LS_CONF or R_SVC_HP_CONF
2413  DVAUD_I2cWriteField((Reg) ? F_SVC_LS_TIME : F_SVC_HP_TIME, pstConfig->eReleaseTime);
2414
2415  if (((pstConfig->cThresholdIndB) < (-31)) || ((pstConfig->cThresholdIndB) > 0))
2416    return DVAUD_kBadParameter;
2417  // R_SVC_LS_CONF or R_SVC_HP_CONF
2418  DVAUD_I2cWriteField((Reg) ? F_SVC_LS_THRESHOLD : F_SVC_HP_THRESHOLD, -(pstConfig->cThresholdIndB));
2419 
2420  if ((pstConfig->usMakeUpGainInmdB) > 24000)
2421    return DVAUD_kBadParameter;
2422  // R_SVC_LS_GAIN or R_SVC_HP_GAIN
2423  DVAUD_I2cWriteField((Reg) ? F_SVC_LS_MAKE_UP_GAIN : F_SVC_HP_MAKE_UP_GAIN, (pstConfig->usMakeUpGainInmdB)/500);
2424 
2425  return I2C_Status;
2426}
2427
2428// ******************************************************************
2429
2430DVAUD_Status_t DVAUD_SmartVolumeSet (
2431                const DVAUD_Output_t            eOutput,
2432                const DVAUD_Enabled_t           eNewStatus) // -> LS & HP
2433{
2434  U16 Field;
2435 
2436  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2437     return DVAUD_kDeviceNotReady;
2438
2439  switch (eOutput)
2440    {
2441    case DVAUD_kOutputSpeaker:          // LS
2442      Field = F_SVC_LS_ON;
2443      break;
2444    case DVAUD_kOutputHeadphone:        // HP
2445      Field = F_SVC_HP_ON;
2446      break;
2447    default:                            // parameter config not in list
2448      return DVAUD_kBadParameter;
2449    }
2450
2451  switch (eNewStatus)
2452    {
2453    case DVAUD_kDisabled:
2454      DVAUD_I2cClrBit(Field);           // R_SVC_CONF
2455      break;
2456    case DVAUD_kEnabled:
2457      DVAUD_I2cSetBit(Field);
2458      break;
2459    default:                            // parameter not in list
2460      return DVAUD_kBadParameter;
2461    }
2462
2463  return I2C_Status;
2464}
2465
2466// ******************************************************************
2467
2468DVAUD_Status_t DVAUD_EqualizerBassTrebleSetConfig  (
2469                const DVAUD_Output_t            eOutput,
2470                const DVAUD_EQMode_t            eEQMode,
2471                const S16*                      const psGainInmdB) // -> LS & HP
2472// WARNING no out of boundary test is made on *psGainInmdB
2473// it is up to the user to make sure that the pointer points onto an array of 2 or 5 "S16", depending on eEQMode value
2474{
2475  U8 OutType;
2476  U8 EqType;
2477  const S16* GainArray;
2478 
2479  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2480     return DVAUD_kDeviceNotReady;
2481
2482  switch (eOutput)
2483    {
2484    case DVAUD_kOutputSpeaker:          // LS
2485      OutType = 1;
2486      break;
2487    case DVAUD_kOutputHeadphone:        // HP
2488      OutType = 0;
2489      break;
2490    default:                            // parameter config not in list
2491      return DVAUD_kBadParameter;
2492    }
2493
2494  GainArray = psGainInmdB;              // copy to temporary pointer
2495 
2496  if (OutType)                          // LS
2497    {
2498    switch (eEQMode)
2499      {
2500      case DVAUD_kModeEQ:               // 5 band equalizer (LS only, HP is always bass/treble)
2501        EqType = 1;
2502        DVAUD_I2cClrBit(F_EQ_BT_LS_MODE);       // R_EQ_BT_CONF
2503        break;
2504      case DVAUD_kModeBT:               // 2 band bass/treble (LS only, HP is always like this)
2505        EqType = 0;
2506        DVAUD_I2cSetBit(F_EQ_BT_LS_MODE);
2507        break;
2508      default:                          // parameter config not in list
2509        return DVAUD_kBadParameter;
2510      }
2511
2512    if ((*GainArray < (-12000)) || (*GainArray > 12000))
2513      return DVAUD_kBadParameter;
2514    DVAUD_I2cWriteReg(R_EQ_BT_LS_BAND1, (*GainArray)/125);      // LS Band 1 (=bass)
2515    GainArray++;                                                // next data in array
2516
2517    if (EqType)                                         // 5 band mode
2518      {
2519      if ((*GainArray < (-12000)) || (*GainArray > 12000))
2520        return DVAUD_kBadParameter;
2521      DVAUD_I2cWriteReg(R_EQ_BT_LS_BAND2, (*GainArray)/125);    // LS Band 2
2522      GainArray++;                                              // next data in array
2523
2524      if ((*GainArray < (-12000)) || (*GainArray > 12000))
2525        return DVAUD_kBadParameter;
2526      DVAUD_I2cWriteReg(R_EQ_BT_LS_BAND3, (*GainArray)/125);    // LS Band 3
2527      GainArray++;                                              // next data in array
2528
2529      if ((*GainArray < (-12000)) || (*GainArray > 12000))
2530        return DVAUD_kBadParameter;
2531      DVAUD_I2cWriteReg(R_EQ_BT_LS_BAND4, (*GainArray)/125);    // LS Band 4
2532      GainArray++;                                              // next data in array
2533      }
2534
2535    if ((*GainArray < (-12000)) || (*GainArray > 12000))
2536      return DVAUD_kBadParameter;
2537    DVAUD_I2cWriteReg(R_EQ_BT_LS_BAND5, (*GainArray)/125);      // LS Band 5 (=treble)
2538    }
2539  else                                                          // HP
2540    {
2541    switch (eEQMode)
2542      {
2543      case DVAUD_kModeBT:               // 2 band bass/treble (LS only, HP is always like this)
2544        break;
2545      case DVAUD_kModeEQ:               // 5 band equalizer (does not exist for HP)
2546      default:                          // parameter config not in list
2547        return DVAUD_kBadParameter;
2548      }
2549
2550
2551    if ((*GainArray < (-12000)) || (*GainArray > 12000))
2552      return DVAUD_kBadParameter;
2553    DVAUD_I2cWriteReg(R_BT_HP_BASS, (*GainArray)/125);          // HP Bass
2554    GainArray++;                                                // next data in array
2555         
2556    if ((*GainArray < (-12000)) || (*GainArray > 12000))
2557      return DVAUD_kBadParameter;
2558    DVAUD_I2cWriteReg(R_BT_HP_TREBLE, (*GainArray)/125);        // HP Treble
2559    } 
2560     
2561  return I2C_Status;
2562}
2563
2564// ******************************************************************
2565
2566DVAUD_Status_t DVAUD_EqualizerBassTrebleSet (
2567                const DVAUD_Output_t            eOutput,
2568                const DVAUD_Enabled_t           eNewStatus) // -> LS & HP
2569{
2570  U16 Field;
2571 
2572  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2573     return DVAUD_kDeviceNotReady;
2574
2575  switch (eOutput)
2576    {
2577    case DVAUD_kOutputSpeaker:          // LS
2578      Field = F_EQ_BT_LS_ON;
2579      break;
2580    case DVAUD_kOutputHeadphone:        // HP
2581      Field = F_BT_HP_ON;
2582      break;
2583    default:                            // parameter config not in list
2584      return DVAUD_kBadParameter;
2585    }
2586
2587  switch (eNewStatus)
2588    {
2589    case DVAUD_kDisabled:
2590      DVAUD_I2cClrBit(Field);           // R_EQ_BT_CONF
2591      break;
2592    case DVAUD_kEnabled:
2593      DVAUD_I2cSetBit(Field);
2594      break;
2595    default:                            // parameter not in list
2596      return DVAUD_kBadParameter;
2597    }
2598
2599  return I2C_Status;
2600}
2601
2602// ******************************************************************
2603
2604DVAUD_Status_t DVAUD_LoudnessSetConfig  (
2605                const DVAUD_Output_t            eOutput,
2606                const DVAUD_LoudnessConfig_t*   const pstConfig) // -> LS & HP
2607{
2608  U8 Reg;
2609
2610  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2611     return DVAUD_kDeviceNotReady;
2612
2613  switch (eOutput)
2614    {
2615    case DVAUD_kOutputSpeaker:          // LS
2616      Reg = 1;
2617      break;
2618    case DVAUD_kOutputHeadphone:        // HP
2619      Reg = 0;
2620      break;
2621    default:                            // parameter config not in list
2622      return DVAUD_kBadParameter;
2623    }
2624
2625  if (((pstConfig->cThresholdIndB) < (-42)) || ((pstConfig->cThresholdIndB) > 0))
2626    return DVAUD_kBadParameter;
2627  DVAUD_I2cWriteField((Reg) ? F_LOUD_LS_THRESHOLD : F_LOUD_HP_THRESHOLD, (pstConfig->cThresholdIndB)/(-6));
2628
2629  if ((pstConfig->ucTrebleGainIndB) > 18)
2630    return DVAUD_kBadParameter;
2631  DVAUD_I2cWriteField((Reg) ? F_LOUD_LS_TREBLE : F_LOUD_HP_TREBLE, (pstConfig->ucTrebleGainIndB)/3);
2632
2633  return I2C_Status;
2634}
2635
2636// ******************************************************************
2637
2638DVAUD_Status_t DVAUD_LoudnessSet (
2639                const DVAUD_Output_t            eOutput,
2640                const DVAUD_Enabled_t           eNewStatus) // -> LS & HP
2641{
2642  U16 Field;
2643
2644  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2645     return DVAUD_kDeviceNotReady;
2646
2647  switch (eOutput)
2648    {
2649    case DVAUD_kOutputSpeaker:          // LS
2650      Field = F_LOUD_LS_ON;             // R_LOUDNESS_LS
2651      break;
2652    case DVAUD_kOutputHeadphone:        // HP
2653      Field = F_LOUD_HP_ON;             // R_LOUDNESS_HP
2654      break;
2655    default:                            // parameter config not in list
2656      return DVAUD_kBadParameter;
2657    }
2658
2659  switch (eNewStatus)
2660    {
2661    case DVAUD_kDisabled:
2662      DVAUD_I2cClrBit(Field);
2663      break;
2664    case DVAUD_kEnabled:
2665      DVAUD_I2cSetBit(Field);
2666      break;
2667    default:                            // parameter not in list
2668      return DVAUD_kBadParameter;
2669    }
2670
2671  return I2C_Status;
2672}
2673
2674// ******************************************************************
2675
2676DVAUD_Status_t DVAUD_PrescalerSetConfig  (
2677                const DVAUD_Prescaler_t         ePrescaler,
2678                const S16                       iValueInmdB)
2679{
2680  U16 Field;
2681
2682  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2683     return DVAUD_kDeviceNotReady;
2684
2685  switch (ePrescaler)
2686    {
2687    case DVAUD_kPrescalerAMEIAJMono:
2688      if ((Dev_Capability.eEIAJ != DVAUD_kImplemented) &&
2689          (Dev_Capability.eDeviceType != DVAUD_k83x7))
2690        return DVAUD_kFeatureNotSupported;
2691      Field = F_PRESCALE_AM_EIAJ;       // R_PRESCALE_AM_EIAJ
2692      break;
2693    case DVAUD_kPrescalerFMBTSCMono:
2694      Field = F_PRESCALE_FM_BTSC;       // R_PRESCALE_FM_BTSC
2695      break;
2696    case DVAUD_kPrescalerNICAM:
2697      if (Dev_Capability.eNICAM != DVAUD_kImplemented)
2698        return DVAUD_kFeatureNotSupported;
2699      Field = F_PRESCALE_NICAM;         // R_PRESCALE_NICAM
2700      break;
2701    case DVAUD_kPrescalerBTSCStereo:
2702      Field = F_PRESCALE_BTSC_ST;       // R_PRESCALE_BTSC_ST
2703      break;
2704    case DVAUD_kPrescalerBTSCSAP:
2705      Field = F_PRESCALE_BTSC_SAP;      // R_PRESCALE_BTSC_SAP
2706      break;
2707    case DVAUD_kPrescalerEIAJStereo:
2708      if (Dev_Capability.eEIAJ != DVAUD_kImplemented)
2709        return DVAUD_kFeatureNotSupported;
2710      Field = F_PRESCALE_EIAJ_ST;       // R_PRESCALE_EIAJ_ST
2711      break;
2712    case DVAUD_kPrescalerSCART:
2713      Field = F_PRESCALE_SCART;         // R_PRESCALE_SCART
2714      break;
2715    case DVAUD_kPrescalerI2S0:
2716      Field = F_PRESCALE_I2S0;          // R_PRESCALE_I2S0
2717      break;
2718    case DVAUD_kPrescalerI2S1:
2719      Field = F_PRESCALE_I2S1;          // R_PRESCALE_I2S1
2720      break;
2721    case DVAUD_kPrescalerI2S2:
2722      Field = F_PRESCALE_I2S2;          // R_PRESCALE_I2S2
2723      break;
2724    case DVAUD_kPrescalerI2S3:
2725      Field = F_PRESCALE_I2S3;          // R_PRESCALE_I2S3
2726      break;
2727    default:                            // parameter config not in list
2728      return DVAUD_kBadParameter;
2729    }
2730
2731  if (iValueInmdB<(-12000) || iValueInmdB>24000)
2732    return DVAUD_kBadParameter;         // value out of range
2733  DVAUD_I2cWriteField(Field, (U8)(iValueInmdB/500));
2734
2735  return I2C_Status;
2736}
2737
2738// ******************************************************************
2739
2740DVAUD_Status_t DVAUD_PeakDetectorSetConfig  (
2741                const DVAUD_PeakDetectorConfig_t*       const pstConfig, 
2742                DVAUD_Bool_t                            const eLeftOverloadSet,         // PJ
2743                DVAUD_Bool_t                            const eRightOverloadSet,        // PJ
2744                DVAUD_Bool_t                            const eLROverloadSet)           // PJ
2745{
2746  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2747     return DVAUD_kDeviceNotReady;
2748
2749  if ((pstConfig->eSource) >= DVAUD_kNbOfPeakDetectorSource)
2750    return DVAUD_kBadParameter;         // value out of range
2751  DVAUD_I2cWriteField(F_PEAK_INPUT, pstConfig->eSource);        // R_PEAK_DETECTOR
2752
2753  if ((pstConfig->eLRRange) >= DVAUD_kNbOfPeakDetectorLRRange)
2754    return DVAUD_kBadParameter;         // value out of range
2755  DVAUD_I2cWriteField(F_PEAK_L_R_RANGE, pstConfig->eLRRange);   // R_PEAK_DETECTOR
2756
2757  switch (eLeftOverloadSet)
2758    {
2759    case DVAUD_kFalse:
2760      DVAUD_I2cClrBit(F_OVERLOAD_L);    // R_STAT_PEAK_L
2761      break;
2762    case DVAUD_kTrue:
2763      DVAUD_I2cSetBit(F_OVERLOAD_L);
2764      break;
2765    default:                            // parameter not in list
2766      return DVAUD_kBadParameter;
2767    }
2768
2769  switch (eRightOverloadSet)
2770    {
2771    case DVAUD_kFalse:
2772      DVAUD_I2cClrBit(F_OVERLOAD_R);    // R_STAT_PEAK_R
2773      break;
2774    case DVAUD_kTrue:
2775      DVAUD_I2cSetBit(F_OVERLOAD_R);
2776      break;
2777    default:                            // parameter not in list
2778      return DVAUD_kBadParameter;
2779    }
2780
2781  switch (eLROverloadSet)
2782    {
2783    case DVAUD_kFalse:
2784      DVAUD_I2cClrBit(F_OVERLOAD_L_R);  // R_STAT_PEAK_L_R
2785      break;
2786    case DVAUD_kTrue:
2787      DVAUD_I2cSetBit(F_OVERLOAD_L_R);
2788      break;
2789    default:                            // parameter not in list
2790      return DVAUD_kBadParameter;
2791    }
2792 
2793  return I2C_Status;
2794}
2795
2796// ******************************************************************
2797
2798DVAUD_Status_t DVAUD_PeakDetectorSet (
2799                const DVAUD_Enabled_t           eNewStatus)
2800{
2801  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2802     return DVAUD_kDeviceNotReady;
2803
2804  switch (eNewStatus)
2805    {
2806    case DVAUD_kDisabled:
2807      DVAUD_I2cClrBit(F_PEAK_ON);       // R_PEAK_DETECTOR
2808      break;
2809    case DVAUD_kEnabled:
2810      DVAUD_I2cSetBit(F_PEAK_ON);
2811      break;
2812    default:                            // parameter not in list
2813      return DVAUD_kBadParameter;
2814    }
2815
2816  return I2C_Status;
2817}
2818
2819// ******************************************************************
2820
2821DVAUD_Status_t DVAUD_PeakDetectorGet (
2822                U8*                             const pucLeftLevelInDiv,
2823                U8*                             const pucRightLevelInDiv,
2824                U8*                             const pucLRLevelInDiv,
2825                DVAUD_Bool_t*                   peLeftOverload, 
2826                DVAUD_Bool_t*                   peRightOverload, 
2827                DVAUD_Bool_t*                   peLROverload)
2828{
2829  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2830     return DVAUD_kDeviceNotReady;
2831
2832  // levels over 7 bits
2833 
2834  *pucLeftLevelInDiv  = DVAUD_I2cReadField(F_PEAK_L);   // R_STAT_PEAK_L
2835  *pucRightLevelInDiv = DVAUD_I2cReadField(F_PEAK_R);   // R_STAT_PEAK_R
2836  *pucLRLevelInDiv    = DVAUD_I2cReadField(F_PEAK_L_R); // R_STAT_PEAK_L_R
2837
2838  // test 8th bit (MSB)
2839 
2840  // R_STAT_PEAK_L
2841  *peLeftOverload = (DVAUD_I2cReadField(F_OVERLOAD_L)) ? DVAUD_kTrue : DVAUD_kFalse; 
2842
2843  // R_STAT_PEAK_R
2844  *peRightOverload = (DVAUD_I2cReadField(F_OVERLOAD_R)) ? DVAUD_kTrue : DVAUD_kFalse; 
2845
2846  // R_STAT_PEAK_L_R
2847  *peLROverload = (DVAUD_I2cReadField(F_OVERLOAD_L_R)) ? DVAUD_kTrue : DVAUD_kFalse; 
2848 
2849  return I2C_Status;
2850}
2851
2852// ******************************************************************
2853
2854DVAUD_Status_t DVAUD_AGCSetConfig  (
2855                const DVAUD_AGCConfig_t*        const pstConfig)
2856{
2857  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2858     return DVAUD_kDeviceNotReady;
2859
2860  if ((pstConfig->usAGCGainAMInmdB) > 30000)
2861    return DVAUD_kBadParameter;         // value out of range
2862  DVAUD_I2cWriteField(F_AGC_ERR, (U8)((pstConfig->usAGCGainAMInmdB)/1500));     // R_AGC_GAIN
2863 
2864  return I2C_Status;
2865}
2866
2867// ******************************************************************
2868
2869DVAUD_Status_t DVAUD_DemodSetConfig  (
2870                const DVAUD_DemodConfig_t*      const pstConfig)
2871{
2872  U16 ZwtData;
2873 
2874  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2875     return DVAUD_kDeviceNotReady;
2876
2877  DVAUD_I2cWriteReg(R_SQTH1_MONO, pstConfig->ucFM1SquelchThMONO);
2878
2879  DVAUD_I2cWriteReg(R_CETH1, pstConfig->ucFM1CarrierTh);
2880
2881  DVAUD_I2cWriteReg(R_SQTH1, pstConfig->ucFM1SquelchTh);
2882
2883  DVAUD_I2cWriteReg(R_CETH2, pstConfig->ucFM2CarrierTh);
2884
2885  DVAUD_I2cWriteReg(R_SQTH2, pstConfig->ucFM2SquelchTh);
2886
2887  switch (pstConfig->eNICAMErrorCounterIs64msec)
2888    {
2889    case DVAUD_kFalse:
2890      DVAUD_I2cClrBit(F_ECT);   // R_NICAM_CTRL
2891      break;
2892    case DVAUD_kTrue:
2893      DVAUD_I2cSetBit(F_ECT);
2894      break;
2895    default:                    // parameter not in list
2896      return DVAUD_kBadParameter;
2897    }
2898
2899  if ((pstConfig->eNICAMMaxError) >= DVAUD_kNbOfNICAMMaxError)
2900    return DVAUD_kBadParameter;                                 // value out of range
2901  DVAUD_I2cWriteField(F_MAE, pstConfig->eNICAMMaxError);        // R_NICAM_CTRL
2902
2903  if ((pstConfig->ucZweitonPilotThresoldInPercent) > 100)
2904    return DVAUD_kBadParameter;                                         // value out of range
2905  if (pstConfig->ucZweitonPilotThresoldInPercent == 100)
2906    ZwtData = 15;                                                       // max value
2907  else
2908    ZwtData = (pstConfig->ucZweitonPilotThresoldInPercent)*4/25;        // <-> /6.25
2909  DVAUD_I2cWriteField(F_THRESH_PILOT, (U8)ZwtData);                     // R_ZWT_TH
2910
2911  if ((pstConfig->ucZweitonToneThresoldInPercent) > 100)
2912    return DVAUD_kBadParameter;                                         // value out of range
2913  if (pstConfig->ucZweitonToneThresoldInPercent == 100)
2914    ZwtData = 15;                                                       // max value
2915  else
2916    ZwtData = (pstConfig->ucZweitonToneThresoldInPercent)*4/25;         // <-> /6.25
2917  DVAUD_I2cWriteField(F_THRESH_TONE, (U8)ZwtData);                              // R_ZWT_TH
2918
2919  if ((pstConfig->eZweitonErrorProbability) >= DVAUD_kNbOfZweitonErrorProbability)
2920    return DVAUD_kBadParameter;                                         // value out of range
2921  DVAUD_I2cWriteField(F_TSCTRL, pstConfig->eZweitonErrorProbability);   // R_ZWT_CTRL
2922
2923  DVAUD_I2cWriteReg(R_STEREO_LEVEL_H, pstConfig->ucBTSCStereoHighTh);
2924
2925  DVAUD_I2cWriteReg(R_STEREO_LEVEL_L, pstConfig->ucBTSCStereoLowTh);
2926
2927  DVAUD_I2cWriteReg(R_SAP_LEVEL_H, pstConfig->ucBTSCSAPHighTh);
2928
2929  DVAUD_I2cWriteReg(R_SAP_LEVEL_L, pstConfig->ucBTSCSAPLowTh);
2930
2931  DVAUD_I2cWriteReg(R_SAP_SQ_TH, pstConfig->ucBTSCSAPSquelchTh);
2932
2933  return I2C_Status;
2934}
2935
2936// ******************************************************************
2937
2938DVAUD_Status_t DVAUD_AutostandardSetConfig  (
2939                const DVAUD_AutostandardConfig_t*       const pstConfig)
2940{
2941  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
2942     return DVAUD_kDeviceNotReady;
2943
2944  switch (pstConfig->eAutoMute)
2945    {
2946    case DVAUD_kDisabled:
2947      DVAUD_I2cClrBit(F_AUTO_MUTE);     // R_AUTOSTD_CONF
2948      break;
2949    case DVAUD_kEnabled:
2950      DVAUD_I2cSetBit(F_AUTO_MUTE);
2951      break;
2952    default:                            // parameter not in list
2953      return DVAUD_kBadParameter;
2954    }
2955
2956  switch (pstConfig->eNICAMBackupForce)
2957    {
2958    case DVAUD_kDisabled:
2959      DVAUD_I2cClrBit(F_NICAM_BACKUP_FORCE);    // R_AUTOSTD_CONF
2960      break;
2961    case DVAUD_kEnabled:
2962      DVAUD_I2cSetBit(F_NICAM_BACKUP_FORCE);
2963      break;
2964    default:                                    // parameter not in list
2965      return DVAUD_kBadParameter;
2966    }
2967
2968  switch (pstConfig->eNICAMMonoIn)
2969    {
2970    case DVAUD_kDisabled:
2971      DVAUD_I2cClrBit(F_NICAM_MONO_IN); // R_AUTOSTD_CONF
2972      break;
2973    case DVAUD_kEnabled:
2974      DVAUD_I2cSetBit(F_NICAM_MONO_IN);
2975      break;
2976    default:                            // parameter not in list
2977      return DVAUD_kBadParameter;
2978    }
2979
2980  if ((pstConfig->eFMTime) >= DVAUD_kNbOfFMTime)
2981    return DVAUD_kBadParameter;                         // value out of range
2982  DVAUD_I2cWriteField(F_FM_TIME, pstConfig->eFMTime);   // R_AUTOSTD_TIMES
2983
2984  if ((pstConfig->eNICAMTime) >= DVAUD_kNbOfNICAMTime)
2985    return DVAUD_kBadParameter;                                 // value out of range
2986  DVAUD_I2cWriteField(F_NICAM_TIME, pstConfig->eNICAMTime);     // R_AUTOSTD_TIMES
2987
2988  if ((pstConfig->eZweitonTime) >= DVAUD_kNbOfZweitonTime)
2989    return DVAUD_kBadParameter;                                 // value out of range
2990  DVAUD_I2cWriteField(F_ZWEITON_TIME, pstConfig->eZweitonTime); // R_AUTOSTD_TIMES
2991
2992  switch (pstConfig->eWideMode)
2993    {
2994    case DVAUD_kDisabled:
2995      DVAUD_I2cClrBit(F_FM_WIDE_ENABLE);        // R_AUTOSTD_CONF
2996      break;
2997    case DVAUD_kEnabled:
2998      DVAUD_I2cSetBit(F_FM_WIDE_ENABLE);
2999      break;
3000    default:                                    // parameter not in list
3001      return DVAUD_kBadParameter;
3002    }
3003
3004  return I2C_Status;
3005}
3006
3007// ******************************************************************
3008
3009DVAUD_Status_t DVAUD_AutostandardSetList (
3010                const DVAUD_AutostandardList_t* const pstList)
3011{
3012  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
3013     return DVAUD_kDeviceNotReady;
3014
3015  switch (pstList->eLLpStandardIsEnabled)
3016    {
3017    case DVAUD_kFalse:
3018      DVAUD_I2cClrBit(F_LDK_SW);        // R_AMFM_MONO_STD_DET
3019      break;
3020    case DVAUD_kTrue:
3021      DVAUD_I2cSetBit(F_LDK_SW);
3022      break;
3023    default:                            // parameter not in list
3024      return DVAUD_kBadParameter;
3025    }
3026
3027  switch (pstList->eLDKMono)
3028    {
3029    case DVAUD_kDisabled:
3030      DVAUD_I2cClrBit(F_LDK);           // R_AMFM_MONO_STD_DET
3031      break;
3032    case DVAUD_kEnabled:
3033      if (Dev_Capability.eDeviceType != DVAUD_k83x7)
3034        return DVAUD_kFeatureNotSupported;      // only on 83x7
3035      DVAUD_I2cSetBit(F_LDK);
3036      break;
3037    default:                            // parameter not in list
3038      return DVAUD_kBadParameter;
3039    }
3040
3041  switch (pstList->eDK1Zweiton)
3042    {
3043    case DVAUD_kDisabled:
3044      DVAUD_I2cClrBit(F_LDK_ZWT1);      // R_NICAMZWT_ST_STD_DET
3045      break;
3046    case DVAUD_kEnabled:
3047      if (Dev_Capability.eDeviceType != DVAUD_k83x7)
3048        return DVAUD_kFeatureNotSupported;      // only on 83x7
3049      DVAUD_I2cSetBit(F_LDK_ZWT1);
3050      break;
3051    default:                            // parameter not in list
3052      return DVAUD_kBadParameter;
3053    }
3054
3055  switch (pstList->eDK2Zweiton)
3056    {
3057    case DVAUD_kDisabled:
3058      DVAUD_I2cClrBit(F_LDK_ZWT2);      // R_NICAMZWT_ST_STD_DET
3059      break;
3060    case DVAUD_kEnabled:
3061      if (Dev_Capability.eDeviceType != DVAUD_k83x7)
3062        return DVAUD_kFeatureNotSupported;      // only on 83x7
3063      DVAUD_I2cSetBit(F_LDK_ZWT2);
3064      break;
3065    default:                            // parameter not in list
3066      return DVAUD_kBadParameter;
3067    }
3068
3069  switch (pstList->eDK3Zweiton)
3070    {
3071    case DVAUD_kDisabled:
3072      DVAUD_I2cClrBit(F_LDK_ZWT3);      // R_NICAMZWT_ST_STD_DET
3073      break;
3074    case DVAUD_kEnabled:
3075      if (Dev_Capability.eDeviceType != DVAUD_k83x7)
3076        return DVAUD_kFeatureNotSupported;      // only on 83x7
3077      DVAUD_I2cSetBit(F_LDK_ZWT3);
3078      break;
3079    default:                            // parameter not in list
3080      return DVAUD_kBadParameter;
3081    }
3082
3083  switch (pstList->eLDKNICAM)
3084    {
3085    case DVAUD_kDisabled:
3086      DVAUD_I2cClrBit(F_LDK_NICAM);     // R_NICAMZWT_ST_STD_DET
3087      break;
3088    case DVAUD_kEnabled:
3089      if (Dev_Capability.eNICAM != DVAUD_kImplemented)
3090        return DVAUD_kFeatureNotSupported;
3091      else
3092        DVAUD_I2cSetBit(F_LDK_NICAM);
3093      break;
3094    default:                            // parameter not in list
3095      return DVAUD_kBadParameter;
3096    }
3097
3098  switch (pstList->eIMono)
3099    {
3100    case DVAUD_kFalse:
3101      DVAUD_I2cClrBit(F_I);     // R_AMFM_MONO_STD_DET
3102      break;
3103    case DVAUD_kTrue:
3104      if (Dev_Capability.eDeviceType != DVAUD_k83x7)
3105        return DVAUD_kFeatureNotSupported;      // only on 83x7
3106      DVAUD_I2cSetBit(F_I);
3107      break;
3108    default:                    // parameter not in list
3109      return DVAUD_kBadParameter;
3110    }
3111
3112  switch (pstList->eINICAM)
3113    {
3114    case DVAUD_kDisabled:
3115      DVAUD_I2cClrBit(F_I_NICAM);       // R_NICAMZWT_ST_STD_DET
3116      break;
3117    case DVAUD_kEnabled:
3118      if (Dev_Capability.eNICAM != DVAUD_kImplemented)
3119        return DVAUD_kFeatureNotSupported;
3120      DVAUD_I2cSetBit(F_I_NICAM);
3121      break;
3122    default:                            // parameter not in list
3123      return DVAUD_kBadParameter;
3124    }
3125
3126  switch (pstList->eBGMono)
3127    {
3128    case DVAUD_kFalse:
3129      DVAUD_I2cClrBit(F_BG);            // R_AMFM_MONO_STD_DET
3130      break;
3131    case DVAUD_kTrue:
3132      if (Dev_Capability.eDeviceType != DVAUD_k83x7)
3133        return DVAUD_kFeatureNotSupported;      // only on 83x7
3134      DVAUD_I2cSetBit(F_BG);
3135      break;
3136    default:                            // parameter not in list
3137      return DVAUD_kBadParameter;
3138    }
3139
3140  switch (pstList->eBGZweiton)
3141    {
3142    case DVAUD_kDisabled:
3143      DVAUD_I2cClrBit(F_BG_ZWT);        // R_NICAMZWT_ST_STD_DET
3144      break;
3145    case DVAUD_kEnabled:
3146      if (Dev_Capability.eDeviceType != DVAUD_k83x7)
3147        return DVAUD_kFeatureNotSupported;      // only on 83x7
3148      DVAUD_I2cSetBit(F_BG_ZWT);
3149      break;
3150    default:                            // parameter not in list
3151      return DVAUD_kBadParameter;
3152    }
3153
3154  switch (pstList->eBGNICAM)
3155    {
3156    case DVAUD_kDisabled:
3157      DVAUD_I2cClrBit(F_BG_NICAM);      // R_NICAMZWT_ST_STD_DET
3158      break;
3159    case DVAUD_kEnabled:
3160      if (Dev_Capability.eNICAM != DVAUD_kImplemented)
3161        return DVAUD_kFeatureNotSupported;
3162      else
3163        DVAUD_I2cSetBit(F_BG_NICAM);
3164      break;
3165    default:                            // parameter not in list
3166      return DVAUD_kBadParameter;
3167    }
3168
3169  switch (pstList->eMNMono)
3170    {
3171    case DVAUD_kDisabled:
3172      DVAUD_I2cClrBit(F_MN);    // R_AMFM_MONO_STD_DET
3173      break;
3174    case DVAUD_kEnabled:
3175      if (Dev_Capability.eDeviceType != DVAUD_k83x7)
3176        return DVAUD_kFeatureNotSupported;      // only on 83x7
3177      DVAUD_I2cSetBit(F_MN);
3178      break;
3179    default:                    // parameter not in list
3180      return DVAUD_kBadParameter;
3181    }
3182
3183  switch (pstList->eMNZweiton)
3184    {
3185    case DVAUD_kDisabled:
3186      DVAUD_I2cClrBit(F_MN_ZWT);        // R_NICAMZWT_ST_STD_DET
3187      break;
3188    case DVAUD_kEnabled:
3189      if (Dev_Capability.eDeviceType != DVAUD_k83x7)
3190        return DVAUD_kFeatureNotSupported;      // only on 83x7
3191      DVAUD_I2cSetBit(F_MN_ZWT);
3192      break;
3193    default:                            // parameter not in list
3194      return DVAUD_kBadParameter;
3195    }
3196
3197  switch (pstList->eMNBTSCMono)
3198    {
3199    case DVAUD_kDisabled:
3200      DVAUD_I2cClrBit(F_BTSC_MONO);     // R_BTSCEIAJ_STD_DET
3201      break;
3202    case DVAUD_kEnabled:
3203      if (Dev_Capability.eDeviceType != DVAUD_k83x8)
3204        return DVAUD_kFeatureNotSupported;      // only on 83x8
3205      DVAUD_I2cSetBit(F_BTSC_MONO);
3206      break;
3207    default:                            // parameter not in list
3208      return DVAUD_kBadParameter;
3209    }
3210
3211  switch (pstList->eMNBTSCStereo)
3212    {
3213    case DVAUD_kDisabled:
3214      DVAUD_I2cClrBit(F_BTSC_STEREO);   // R_BTSCEIAJ_STD_DET
3215      break;
3216    case DVAUD_kEnabled:
3217      if (Dev_Capability.eDeviceType != DVAUD_k83x8)
3218        return DVAUD_kFeatureNotSupported;      // only on 83x8
3219      DVAUD_I2cSetBit(F_BTSC_STEREO);
3220      break;
3221    default:                            // parameter not in list
3222      return DVAUD_kBadParameter;
3223    }
3224
3225  switch (pstList->eMNBTSCSAP)
3226    {
3227    case DVAUD_kDisabled:
3228      DVAUD_I2cClrBit(F_BTSC_SAP);      // R_BTSCEIAJ_STD_DET
3229      break;
3230    case DVAUD_kEnabled:
3231      if (Dev_Capability.eDeviceType != DVAUD_k83x8)
3232        return DVAUD_kFeatureNotSupported;      // only on 83x8
3233      DVAUD_I2cSetBit(F_BTSC_SAP);
3234      break;
3235    default:                            // parameter not in list
3236      return DVAUD_kBadParameter;
3237    }
3238
3239  switch (pstList->eMNEIAJMono)
3240    {
3241    case DVAUD_kDisabled:
3242      DVAUD_I2cClrBit(F_EIAJ_MONO);     // R_BTSCEIAJ_STD_DET
3243      break;
3244    case DVAUD_kEnabled:
3245      if (Dev_Capability.eEIAJ != DVAUD_kImplemented)
3246        return DVAUD_kFeatureNotSupported;
3247      else
3248        DVAUD_I2cSetBit(F_EIAJ_MONO);
3249      break;
3250    default:                            // parameter not in list
3251      return DVAUD_kBadParameter;
3252    }
3253
3254  switch (pstList->eMNEIAJStereo)
3255    {
3256    case DVAUD_kDisabled:
3257      DVAUD_I2cClrBit(F_EIAJ_STEREO);   // R_BTSCEIAJ_STD_DET
3258      break;
3259    case DVAUD_kEnabled:
3260      if (Dev_Capability.eEIAJ != DVAUD_kImplemented)
3261        return DVAUD_kFeatureNotSupported;
3262      else
3263        DVAUD_I2cSetBit(F_EIAJ_STEREO);
3264      break;
3265    default:                            // parameter not in list
3266      return DVAUD_kBadParameter;
3267    }
3268
3269  return I2C_Status;
3270}
3271
3272// ******************************************************************
3273
3274DVAUD_Status_t DVAUD_AutostandardGet (
3275                DVAUD_Bool_t*                   const peMonoSquelchIsOK,
3276                DVAUD_Bool_t*                   const peMonoIsAvailable, 
3277                DVAUD_Bool_t*                   const peStereoDualIsAvailable, 
3278                DVAUD_Bool_t*                   const peSAPIsAvailable,
3279                DVAUD_StandardDetected_t*       const pstCurrentStandard,
3280                DVAUD_StandardTypeDetected_t*   const pstCurrentStandardType)
3281{
3282  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
3283     return DVAUD_kDeviceNotReady;
3284
3285  // R_DEMOD_STAT
3286  *peMonoSquelchIsOK = (DVAUD_I2cReadField(F_FM1_SQ_MONO)) ? DVAUD_kTrue : DVAUD_kFalse; 
3287
3288  // R_STAT_AUTOSTD
3289  *peMonoIsAvailable       = (DVAUD_I2cReadField(F_MONO_DET))        ? DVAUD_kTrue : DVAUD_kFalse; 
3290  *peStereoDualIsAvailable = (DVAUD_I2cReadField(F_STEREO_DUAL_DET)) ? DVAUD_kTrue : DVAUD_kFalse; 
3291  *peSAPIsAvailable        = (DVAUD_I2cReadField(F_BTSC_SAP_DET))    ? DVAUD_kTrue : DVAUD_kFalse; 
3292
3293  // spread over 2 fields
3294  *pstCurrentStandard      = (DVAUD_StandardDetected_t) (DVAUD_I2cReadReg(R_STAT_AUTOSTD) & 0x1F);
3295  *pstCurrentStandardType  = (DVAUD_StandardTypeDetected_t) DVAUD_I2cReadField(F_CURRENT_STANDARD);     // R_STAT_STD_HP_I2S_IN
3296 
3297  return I2C_Status;
3298}
3299
3300// ******************************************************************
3301
3302DVAUD_Status_t DVAUD_DeviceCapabilityGet (
3303                DVAUD_DeviceCapability_t*       const pstDeviceCapability)
3304{
3305// chip not yet initialized: don't check Dev_ID!
3306//  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)       // chip not initialized or in standby
3307//     return DVAUD_kDeviceNotReady;
3308
3309  Dev_ID = (DVAUD_DeviceType_t) DVAUD_I2cReadField(F_CHIP_VERSION);     // R_CUT_ID
3310  pstDeviceCapability->eDeviceType = Dev_ID;
3311 
3312  switch (Dev_ID)
3313    {
3314    case DVAUD_k83x8:
3315      // do something specific to 83x8 here
3316      printf("DEVICE 83x8\n");
3317      break;
3318    case DVAUD_k83x7:
3319        printf("DEVICE 83x7\n");
3320      // do something specific to 83x7 here
3321      break;
3322    default:
3323      Dev_ID = DVAUD_kUnknown;
3324      pstDeviceCapability->eDeviceType = DVAUD_kUnknown;
3325      return DVAUD_kDeviceNotReady;
3326    }
3327
3328  // R_STAT_ONCHIP_ALGOS
3329  // 10xxxxxx or 11xxxxxx OK
3330  pstDeviceCapability->eSRSTruSurroundXT = (DVAUD_I2cReadField(F_SRS) & 0x02)       ? DVAUD_kImplemented : DVAUD_kNotImplemented;
3331  // 01xxxxxx OK
3332  pstDeviceCapability->eSRSWOW           = (DVAUD_I2cReadField(F_SRS) == 0x01)      ? DVAUD_kImplemented : DVAUD_kNotImplemented;
3333  // xx10xxxx or xx11xxxx OK
3334  pstDeviceCapability->ePrologicII       = (DVAUD_I2cReadField(F_DOLBY) & 0x02)     ? DVAUD_kImplemented : DVAUD_kNotImplemented;
3335  // xx01xxxx OK
3336  pstDeviceCapability->ePrologicI        = (DVAUD_I2cReadField(F_DOLBY) == 0x01)    ? DVAUD_kImplemented : DVAUD_kNotImplemented;
3337  pstDeviceCapability->eEIAJ             = (DVAUD_I2cReadField(F_EIAJ))             ? DVAUD_kImplemented : DVAUD_kNotImplemented;
3338  pstDeviceCapability->eNICAM            = (DVAUD_I2cReadField(F_NICAM))            ? DVAUD_kImplemented : DVAUD_kNotImplemented;
3339  pstDeviceCapability->eMultichannelOut  = (DVAUD_I2cReadField(F_MULTICHANNEL_OUT)) ? DVAUD_kImplemented : DVAUD_kNotImplemented;
3340  pstDeviceCapability->eMultiI2SIn       = (DVAUD_I2cReadField(F_MULTI_I2S_IN))     ? DVAUD_kImplemented : DVAUD_kNotImplemented;
3341
3342  return I2C_Status;
3343}
3344
3345// ******************************************************************
3346
3347#define MAX_NB_OF_PATCH_RETRIES 3
3348
3349static const U8 PatchConversion[15] =   // 0..E, F = no access
3350  {
3351  0x60,
3352  0x61,
3353  0x62,
3354  0x63,
3355  0x64,
3356  0x65,
3357  0x66,
3358  0x67,
3359  0x68,
3360  0x69,
3361  0x6A,
3362  0x6B,
3363  0x00,
3364  0x75,
3365  0x80
3366};
3367#if 0
3368static DVAUD_Status_t DVAUD_LoadPatch(U8 ChipID)
3369{
3370        U32   uiPatchSize, uiCount = 0;
3371        U8 PatchVersion = 0;
3372#if 0
3373        DHL_SYS_SetGPIO(11,0);
3374        WAIT_Inms(1);
3375        DHL_SYS_SetGPIO(11,1);
3376        WAIT_Inms(1);
3377#endif
3378
3379  switch(ChipID)
3380  {
3381#ifdef INCLUDE_83x7
3382      case DVAUD_k83x7:
3383                                for( uiPatchSize = 0; uiPatchSize < ( sizeof(ttucPatchV18h1) / 2 );  uiPatchSize++ )
3384                          {
3385                                I2C_Write( I2cAddr83xy, ttucPatchV18h1[uiCount][0], ttucPatchV18h1[uiCount][1] );
3386                                uiCount += 1;
3387                          }           
3388        PatchVersion = PATCH_VERSION_83x7;
3389        return DVAUD_kNoError;
3390        break;
3391#endif
3392#ifdef INCLUDE_83x8
3393      case DVAUD_k83x8:
3394                                for( uiPatchSize = 0; uiPatchSize < ( sizeof(ttucPatchV18h1) / 2 );  uiPatchSize++ )
3395                          {
3396                                I2C_Write( I2cAddr83xy, ttucPatchV18h1[uiCount][0], ttucPatchV18h1[uiCount][1] );
3397                                uiCount += 1;
3398                          }           
3399        PatchVersion = PATCH_VERSION_83x8;
3400        return DVAUD_kNoError;
3401        break;
3402#endif
3403      default:
3404        return DVAUD_kUnknownError;
3405  }
3406#if 0 
3407  if (DVAUD_I2cReadField(F_PATCH_FLAG) &&                       // R_STATUS correct patch load
3408       (DVAUD_I2cReadField(F_PATCH_VERSION) == PatchVersion))   // R_STAT_PATCH_VERSION same patch version
3409      return DVAUD_kNoError;                                    // OK no error during patch load
3410#endif
3411                                                // load patch again until max # of reloads is reached
3412       
3413  return DVAUD_kUnknownError;                   // if patch could not be loaded
3414}
3415#else
3416static DVAUD_Status_t DVAUD_LoadPatch(U8 ChipID)
3417{
3418  U8 Retries;
3419  U16 PatchIndex;
3420  const U8 * Patch;
3421  U8 PatchReg = 0;
3422  U8 PatchRegSave = 0;
3423  U8 PatchVal = 0;
3424  U8 PatchVersion = 0;
3425  U8 PrevPatchReg = 0;
3426  U8 FirstTime = 0;
3427  U8 HalfPointer = 0;
3428
3429  for (Retries = 0; Retries < MAX_NB_OF_PATCH_RETRIES; Retries++)
3430    {
3431    switch(ChipID)
3432      {
3433#ifdef INCLUDE_83x7
3434      case DVAUD_k83x7:
3435        Patch        = &ttucPatch83x7V03h[0][0];        // point to beginning of 83x7 patch array
3436        PatchVersion = PATCH_VERSION_83x7;
3437        PatchIndex   = kPatch83x7V03hSize;
3438        break;
3439#endif
3440#ifdef INCLUDE_83x8
3441      case DVAUD_k83x8:
3442        Patch        = &ttucPatch83x8V0Ah[0][0];        // point to beginning of 83x8 patch array
3443        PatchVersion = PATCH_VERSION_83x8;
3444        PatchIndex   = kPatch83x8V0AhSize;
3445        break;
3446#endif
3447      default:
3448      printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__);
3449        return DVAUD_kUnknownError;
3450      }
3451
3452    if (PatchIndex == 0){                       // null size patch
3453        printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__);
3454      return DVAUD_kBadParameter;
3455    }
3456
3457    FirstTime = 1;                              // for smart patch loading
3458    HalfPointer = 0;                            // first data = MSB address nibble
3459   
3460    while (PatchIndex)                          // scan the whole list
3461      {
3462      if (!HalfPointer)                         // MSB address nibble to load
3463        {
3464        HalfPointer = 1;                        // next = LSB address nibble
3465        PatchRegSave = *Patch++;
3466        PatchReg = PatchRegSave >> 4;
3467        }
3468      else                                      // LSB address nibble to load
3469        {
3470        HalfPointer = 0;                        // next = next MSB address nibble
3471        PatchReg = PatchRegSave & 0x0F;
3472        PatchIndex--;                           // next entry
3473        }
3474
3475      PatchVal = *Patch++;                      // read data associated to current register address
3476       
3477      if (PatchReg >= 0x0F)
3478        continue;                               // 0x0F: skip data
3479
3480      PatchReg = PatchConversion[PatchReg];     // 0x00..0x0E: convert from chart
3481
3482      if (FirstTime)                            // very first loop
3483        {
3484        FirstTime = 0;
3485        PrevPatchReg = PatchReg;
3486        I2C_WriteAddrIndex(I2cAddr83xy, PatchReg);      // send start + I2C addr + reg addr
3487//                              I2C_Write(I2cAddr83xy,PatchReg,PatchVal);                       // send data
3488        }
3489      if (PatchReg != PrevPatchReg)             // if new register address != old one + 1 (not consecutive addrs)
3490        {
3491        PrevPatchReg = PatchReg;                // store new value
3492        I2C_Stop();                             // stop bit
3493        I2C_WriteAddrIndex(I2cAddr83xy, PatchReg);      // send start + I2C addr + reg addr
3494        }
3495      I2C_WriteData(PatchVal); 
3496      PrevPatchReg++;                           // for successive register address comparison
3497      }
3498    I2C_Stop();
3499
3500    if (DVAUD_I2cReadField(F_PATCH_FLAG) &&                     // R_STATUS correct patch load
3501       (DVAUD_I2cReadField(F_PATCH_VERSION) == PatchVersion))   // R_STAT_PATCH_VERSION same patch version
3502      return DVAUD_kNoError;                                    // OK no error during patch load
3503
3504    }                                           // load patch again until max # of reloads is reached
3505
3506  return DVAUD_kUnknownError;                   // if patch could not be loaded
3507}
3508#endif
3509// ******************************************************************
3510
3511DVAUD_Status_t DVAUD_DeviceStart(void)
3512{
3513  U8 WaitLoop;
3514  U8 FW_Version;
3515  U8 test = 0;
3516 
3517  // ****
3518  // **** USER ACTION
3519  // ****
3520  //
3521  // hardware reset pin low
3522  // *** do it here ***
3523  //
3524
3525        DHL_SYS_SetGPIO( 11, 0 );
3526
3527  // delay 100us or more
3528  WAIT_Inms(1);
3529 
3530  // hardware reset pin high
3531  // *** do it here ***
3532  //
3533        DHL_SYS_SetGPIO( 11, 1 );
3534  // delay 2ms
3535  WAIT_Inms(2);
3536
3537  // check if IC is here and responds to requests
3538  if (DVAUD_DeviceCapabilityGet(&Dev_Capability) != DVAUD_kNoError){
3539        printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__);
3540    return DVAUD_kUnknownError;
3541        }
3542  // load DSP F/W patch
3543  if(!test){
3544         if (DVAUD_LoadPatch(Dev_Capability.eDeviceType) != DVAUD_kNoError){    // exit in error if any problem occured during patch load
3545                printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__);       
3546           return DVAUD_kUnknownError;
3547                }
3548        }
3549  // start DSP H/W
3550  DVAUD_I2cSetBit(F_DSP_HW_RUN);                        // R_DSP_HW_CONF
3551
3552  // wait until DSP ready
3553  WaitLoop = 10;
3554  while(WaitLoop)
3555    {
3556    // delay 1ms
3557    WAIT_Inms(1);
3558    if (DVAUD_I2cReadField(F_DSP_FW_READY))     // STAT_DSP_INIT if DSP ready
3559       break;                                   // exit loop
3560    WaitLoop--;
3561    }
3562  if (!WaitLoop){                               // end of loop, DSP never ready
3563        printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__);
3564    return DVAUD_kUnknownError;
3565  }
3566   
3567  // check F/W version
3568  if (DVAUD_I2cReadField(F_FW_VERSION) != 0xFF){        // STAT_FW_VERSION
3569        printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__);
3570    return DVAUD_kUnknownError;
3571  }
3572
3573  // run DSP 
3574  DVAUD_I2cWriteReg(R_DSP_FW_CONF, 0x01);
3575
3576  // delay 2ms
3577  WAIT_Inms(2);
3578
3579  // get capability again to have the accurate registers values now that DSP is running
3580  if (DVAUD_DeviceCapabilityGet(&Dev_Capability) != DVAUD_kNoError){
3581        printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__);
3582    return DVAUD_kUnknownError;
3583        }
3584  // check STAT F/W version number (in IC ROM) specific to IC type
3585  // this is a data from design, specific to IC type
3586  switch (Dev_Capability.eDeviceType)
3587    {
3588#ifdef INCLUDE_83x7
3589    case DVAUD_k83x7:
3590      FW_Version = 0x15;
3591      break;
3592#endif
3593#ifdef INCLUDE_83x8
3594    case DVAUD_k83x8:
3595      FW_Version = 0x2F;                               
3596      break;
3597#endif
3598    default:                                            // should never occur...
3599      FW_Version = 0x00;      break;
3600    }
3601  if (DVAUD_I2cReadField(F_FW_VERSION) != FW_Version){  // STAT_FW_VERSION
3602        printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__);
3603    return DVAUD_kUnknownError;
3604  }
3605
3606  return DVAUD_kNoError;                                // everything OK 
3607}
3608
3609// ******************************************************************
3610
3611DVAUD_Status_t DVAUD_LowPowerEnter ()
3612{
3613  if (Dev_ID==DVAUD_kUnknown  || Dev_ID==DVAUD_kDeviceNotReady)         // chip not initialized or in standby
3614     return DVAUD_kDeviceNotReady;
3615
3616  // mute all outputs except SCART OUT (SCART path is kept)
3617 
3618  I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSpeaker,   DVAUD_kEnabled);
3619  if (I2C_Status != DVAUD_kNoError)
3620    return I2C_Status;
3621   
3622  I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputCenter,    DVAUD_kEnabled);
3623  if (I2C_Status != DVAUD_kNoError)
3624    return I2C_Status;
3625
3626  I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSubwoofer, DVAUD_kEnabled);
3627  if (I2C_Status != DVAUD_kNoError)
3628    return I2C_Status;
3629
3630  I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSurround,  DVAUD_kEnabled);
3631  if (I2C_Status != DVAUD_kNoError)
3632    return I2C_Status;
3633
3634  I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputHeadphone, DVAUD_kEnabled);
3635  if (I2C_Status != DVAUD_kNoError)
3636    return I2C_Status;
3637
3638  // delay 25ms
3639  WAIT_Inms(25);
3640
3641  // enable SCART IN standby
3642  DVAUD_I2cSetBit(F_EN_STBY);           // R_RESET
3643  if (I2C_Status != DVAUD_kNoError)
3644    return I2C_Status;
3645
3646  // device in low power mode: no response from routines
3647  Dev_ID = (DVAUD_DeviceType_t) DVAUD_kDeviceNotReady;
3648
3649  // ****
3650  // **** USER ACTION
3651  // all unneeded power supplies can now be switched off
3652  // ****
3653  // ****
3654
3655  return I2C_Status;
3656}
3657
3658// ******************************************************************
3659
3660DVAUD_Status_t DVAUD_LowPowerExit(void)
3661{
3662  if (Dev_ID==DVAUD_kUnknown)           // chip not initialized
3663     return DVAUD_kDeviceNotReady;
3664
3665  // same sequence as LowPowerEnter() but in reverse order
3666
3667  // ****
3668  // **** USER ACTION
3669  // all power supplies MUST now be switched on
3670  // ****
3671  // ****
3672
3673  // delay 25ms
3674  WAIT_Inms(25);
3675
3676  // re-check if IC is here and responds to requests
3677  if (DVAUD_DeviceCapabilityGet(&Dev_Capability) != DVAUD_kNoError)
3678    return DVAUD_kUnknownError;
3679 
3680  // disable SCART IN standby
3681  DVAUD_I2cClrBit(F_EN_STBY);           // R_RESET
3682  if (I2C_Status != DVAUD_kNoError)
3683    return I2C_Status;
3684
3685  // delay 25ms
3686  WAIT_Inms(25);
3687
3688  // un-mute all outputs except SCART OUT
3689 
3690  I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSpeaker,   DVAUD_kDisabled);
3691  if (I2C_Status != DVAUD_kNoError)
3692    return I2C_Status;
3693   
3694  I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputCenter,    DVAUD_kDisabled);
3695  if (I2C_Status != DVAUD_kNoError)
3696    return I2C_Status;
3697
3698  I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSubwoofer, DVAUD_kDisabled);
3699  if (I2C_Status != DVAUD_kNoError)
3700    return I2C_Status;
3701
3702  I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSurround,  DVAUD_kDisabled);
3703  if (I2C_Status != DVAUD_kNoError)
3704    return I2C_Status;
3705
3706  I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputHeadphone, DVAUD_kDisabled);
3707
3708  return I2C_Status;
3709}
3710
3711// ******************************************************************
3712
3713DVAUD_Status_t DVAUD_DeviceI2CAddressSet (
3714                const U8 ucChipAddr)
3715{
3716  if ((ucChipAddr == 0x80) || (ucChipAddr == 0x84))
3717    {
3718    I2cAddr83xy = ucChipAddr;   // & 0xFE
3719    return DVAUD_kNoError;
3720    }
3721  else
3722    return DVAUD_kBadParameter;
3723}
3724
3725// ******************************************************************
3726
3727//
3728// ******************************************************************
3729// ******************************************************************
3730// ******************************************************************
3731// ******************************************************************
3732//
3733// I2C ROUTINES
3734//
3735// ******************************************************************
3736// ******************************************************************
3737// ******************************************************************
3738// ******************************************************************
3739//
3740
3741// FIELD LENGTH
3742const unsigned char Field_Length[NBREG][8] =
3743{
3744        {1,3,4,0,0,0,0,0},      /*Reg 0x00*/
3745        {1,1,1,1,1,1,1,1},
3746        {1,1,1,1,1,3,0,0},
3747        {8,0,0,0,0,0,0,0},
3748        {1,1,1,2,1,2,0,0},
3749        {1,1,1,1,1,1,1,1},
3750        {8,0,0,0,0,0,0,0},
3751        {1,1,4,1,1,0,0,0},
3752        {1,1,2,1,3,0,0,0},
3753        {1,1,1,5,0,0,0,0},
3754        {8,0,0,0,0,0,0,0},
3755        {8,0,0,0,0,0,0,0},
3756        {1,1,1,1,1,3,0,0},
3757        {1,1,1,1,1,1,1,1},
3758        {1,1,1,3,2,0,0,0},
3759        {1,5,1,1,0,0,0,0},
3760        {8,0,0,0,0,0,0,0},      /*Reg 0x10*/
3761        {8,0,0,0,0,0,0,0},
3762        {8,0,0,0,0,0,0,0},
3763        {8,0,0,0,0,0,0,0},
3764        {8,0,0,0,0,0,0,0},
3765        {8,0,0,0,0,0,0,0},
3766        {8,0,0,0,0,0,0,0},
3767        {8,0,0,0,0,0,0,0},
3768        {8,0,0,0,0,0,0,0},
3769        {8,0,0,0,0,0,0,0},
3770        {8,0,0,0,0,0,0,0},
3771        {8,0,0,0,0,0,0,0},
3772        {8,0,0,0,0,0,0,0},
3773        {8,0,0,0,0,0,0,0},
3774        {8,0,0,0,0,0,0,0},
3775        {8,0,0,0,0,0,0,0},
3776        {8,0,0,0,0,0,0,0},      /*Reg 0x20*/
3777        {8,0,0,0,0,0,0,0},
3778        {8,0,0,0,0,0,0,0},
3779        {1,3,1,1,2,0,0,0},
3780        {8,0,0,0,0,0,0,0},
3781        {8,0,0,0,0,0,0,0},
3782        {1,1,1,1,1,3,0,0},
3783        {8,0,0,0,0,0,0,0},
3784        {8,0,0,0,0,0,0,0},
3785        {8,0,0,0,0,0,0,0},
3786        {8,0,0,0,0,0,0,0},
3787        {8,0,0,0,0,0,0,0},
3788        {8,0,0,0,0,0,0,0},
3789        {8,0,0,0,0,0,0,0},
3790        {8,0,0,0,0,0,0,0},
3791        {8,0,0,0,0,0,0,0},
3792        {8,0,0,0,0,0,0,0},      /*Reg 0x30*/
3793        {8,0,0,0,0,0,0,0},
3794        {8,0,0,0,0,0,0,0},
3795        {8,0,0,0,0,0,0,0},
3796        {8,0,0,0,0,0,0,0},
3797        {8,0,0,0,0,0,0,0},
3798        {8,0,0,0,0,0,0,0},
3799        {8,0,0,0,0,0,0,0},
3800        {8,0,0,0,0,0,0,0},
3801        {8,0,0,0,0,0,0,0},
3802        {8,0,0,0,0,0,0,0},
3803        {1,1,1,1,1,3,0,0},
3804        {2,2,1,1,2,0,0,0},
3805        {1,1,1,1,1,3,0,0},
3806        {8,0,0,0,0,0,0,0},
3807        {1,1,1,4,1,0,0,0},
3808        {1,1,1,3,2,0,0,0},      /*Reg 0x40*/
3809        {4,4,0,0,0,0,0,0},
3810        {1,1,1,1,1,1,1,1},
3811        {4,2,1,1,0,0,0,0},
3812        {1,1,1,1,3,1,0,0},
3813        {8,0,0,0,0,0,0,0},
3814        {8,0,0,0,0,0,0,0},
3815        {1,1,1,1,1,1,1,1},
3816        {8,0,0,0,0,0,0,0},
3817        {8,0,0,0,0,0,0,0},
3818        {8,0,0,0,0,0,0,0},
3819        {1,1,3,1,1,1,0,0},
3820        {1,1,1,1,1,1,1,1},
3821        {8,0,0,0,0,0,0,0},
3822        {1,1,1,1,4,0,0,0},
3823        {8,0,0,0,0,0,0,0},
3824        {8,0,0,0,0,0,0,0},      /*Reg 0x50*/
3825        {8,0,0,0,0,0,0,0},
3826        {8,0,0,0,0,0,0,0},
3827        {1,3,1,3,0,0,0,0},
3828        {1,3,1,3,0,0,0,0},
3829        {1,1,1,1,1,3,0,0},
3830        {4,1,3,0,0,0,0,0},
3831        {1,3,1,3,0,0,0,0},
3832        {1,3,1,3,0,0,0,0},
3833        {1,3,1,3,0,0,0,0},
3834        {1,3,1,3,0,0,0,0},
3835        {1,1,1,5,0,0,0,0},
3836        {8,0,0,0,0,0,0,0},
3837        {8,0,0,0,0,0,0,0},
3838        {2,2,3,1,0,0,0,0},
3839        {8,0,0,0,0,0,0,0}, 
3840        {8,0,0,0,0,0,0,0},      /*Reg 0x60*/
3841        {8,0,0,0,0,0,0,0},
3842        {8,0,0,0,0,0,0,0},
3843        {8,0,0,0,0,0,0,0},
3844        {8,0,0,0,0,0,0,0},
3845        {8,0,0,0,0,0,0,0},
3846        {8,0,0,0,0,0,0,0},
3847        {8,0,0,0,0,0,0,0},
3848        {8,0,0,0,0,0,0,0},
3849        {8,0,0,0,0,0,0,0},
3850        {8,0,0,0,0,0,0,0},
3851        {8,0,0,0,0,0,0,0},
3852        {8,0,0,0,0,0,0,0},
3853        {8,0,0,0,0,0,0,0},
3854        {8,0,0,0,0,0,0,0},
3855        {8,0,0,0,0,0,0,0}, 
3856        {8,0,0,0,0,0,0,0},      /*Reg 0x70*/
3857        {8,0,0,0,0,0,0,0},
3858        {8,0,0,0,0,0,0,0},
3859        {8,0,0,0,0,0,0,0},
3860        {8,0,0,0,0,0,0,0},
3861        {8,0,0,0,0,0,0,0},
3862        {8,0,0,0,0,0,0,0},
3863        {8,0,0,0,0,0,0,0},
3864        {8,0,0,0,0,0,0,0},
3865        {8,0,0,0,0,0,0,0},
3866        {8,0,0,0,0,0,0,0},
3867        {8,0,0,0,0,0,0,0},
3868        {8,0,0,0,0,0,0,0},
3869        {8,0,0,0,0,0,0,0},
3870        {8,0,0,0,0,0,0,0},
3871        {8,0,0,0,0,0,0,0},
3872        {1,1,1,1,1,1,1,1},      /*Reg 0x80*/
3873        {1,1,1,1,1,1,1,1},
3874        {1,1,1,1,1,1,1,1},
3875        {8,0,0,0,0,0,0,0},
3876        {8,0,0,0,0,0,0,0},
3877        {2,2,1,1,1,1,0,0},
3878        {1,1,1,1,1,1,1,1},
3879        {1,1,1,1,1,1,1,1},
3880        {1,1,1,5,0,0,0,0},
3881        {1,1,1,5,0,0,0,0},
3882        {1,1,2,1,1,2,0,0},
3883        {1,1,1,1,1,1,1,1},
3884        {1,1,2,1,1,1,1,0},
3885        {1,1,1,1,1,1,1,1},
3886        {1,1,1,1,1,1,1,1},
3887        {1,1,1,1,1,1,1,1},
3888        {1,1,1,1,1,1,1,1},      /*Reg 0x90*/
3889        {3,3,2,0,0,0,0,0},
3890        {8,0,0,0,0,0,0,0},
3891        {1,1,1,1,1,1,2,0},
3892        {1,1,1,1,1,3,0,0},
3893        {8,0,0,0,0,0,0,0},
3894        {8,0,0,0,0,0,0,0},
3895        {1,1,1,1,1,1,1,1},
3896        {1,1,1,1,2,1,1,0},
3897        {8,0,0,0,0,0,0,0},
3898        {8,0,0,0,0,0,0,0},
3899        {1,2,1,2,2,0,0,0},
3900        {8,0,0,0,0,0,0,0},
3901        {1,1,1,1,1,2,1,0},
3902        {1,7,0,0,0,0,0,0},
3903        {1,7,0,0,0,0,0,0},
3904        {1,7,0,0,0,0,0,0},      /*Reg 0xA0*/
3905        {1,7,0,0,0,0,0,0},
3906        {1,7,0,0,0,0,0,0},
3907        {1,7,0,0,0,0,0,0},
3908        {1,7,0,0,0,0,0,0},
3909        {1,7,0,0,0,0,0,0},
3910        {1,7,0,0,0,0,0,0},
3911        {1,7,0,0,0,0,0,0},
3912        {1,7,0,0,0,0,0,0},
3913        {1,3,3,1,0,0,0,0},
3914        {3,3,1,1,0,0,0,0},
3915        {1,1,1,1,4,0,0,0},
3916        {4,4,0,0,0,0,0,0},
3917        {4,4,0,0,0,0,0,0},
3918        {4,4,0,0,0,0,0,0},
3919        {4,4,0,0,0,0,0,0},
3920        {1,1,1,1,1,3,0,0},      /*Reg 0xB0*/
3921        {1,1,1,2,3,0,0,0},
3922        {1,2,2,3,0,0,0,0},
3923        {1,2,2,3,0,0,0,0},
3924        {3,2,3,0,0,0,0,0},
3925        {1,1,1,1,1,1,1,1},
3926        {8,0,0,0,0,0,0,0},
3927        {8,0,0,0,0,0,0,0},
3928        {1,3,3,1,0,0,0,0},
3929        {1,1,1,2,1,1,1,0},
3930        {1,1,3,3,0,0,0,0},
3931        {8,0,0,0,0,0,0,0},
3932        {1,1,1,1,1,1,1,1},
3933        {1,2,5,0,0,0,0,0},
3934        {4,1,1,1,1,0,0,0},
3935        {8,0,0,0,0,0,0,0},
3936        {8,0,0,0,0,0,0,0},      /*Reg 0xC0*/
3937        {1,1,1,1,3,1,0,0},
3938        {8,0,0,0,0,0,0,0},
3939        {1,1,1,1,3,1,0,0},
3940        {8,0,0,0,0,0,0,0},
3941        {2,5,1,0,0,0,0,0},
3942        {6,2,0,0,0,0,0,0},
3943        {1,1,2,2,2,0,0,0},
3944        {5,2,1,0,0,0,0,0},
3945        {5,2,1,0,0,0,0,0},
3946        {1,1,3,1,1,1,0,0},
3947        {1,1,1,1,1,2,1,0},
3948        {3,5,0,0,0,0,0,0},
3949        {1,1,6,0,0,0,0,0},
3950        {3,5,0,0,0,0,0,0},
3951        {1,1,6,0,0,0,0,0},
3952        {1,1,1,1,1,1,1,1},      /*Reg 0xD0*/
3953        {8,0,0,0,0,0,0,0},
3954        {8,0,0,0,0,0,0,0},
3955        {8,0,0,0,0,0,0,0},
3956        {8,0,0,0,0,0,0,0},
3957        {8,0,0,0,0,0,0,0},
3958        {8,0,0,0,0,0,0,0},
3959        {8,0,0,0,0,0,0,0},
3960        {1,3,3,1,0,0,0,0},
3961        {1,3,3,1,0,0,0,0},
3962        {1,1,1,1,1,2,1,0},
3963        {1,2,5,0,0,0,0,0},
3964        {1,3,4,0,0,0,0,0},
3965        {1,1,3,3,0,0,0,0},
3966        {1,1,1,1,3,1,0,0},
3967        {1,1,1,1,1,3,0,0},
3968        {2,2,2,2,0,0,0,0},      /*Reg 0xE0*/
3969        {1,1,1,1,1,1,1,1},
3970        {1,1,1,1,1,1,1,1},
3971        {1,1,1,1,1,1,1,1},
3972        {8,0,0,0,0,0,0,0},
3973        {1,1,1,1,1,1,2,0},
3974        {8,0,0,0,0,0,0,0},
3975        {1,1,1,1,1,1,2,0},
3976        {8,0,0,0,0,0,0,0},
3977        {8,0,0,0,0,0,0,0},
3978        {8,0,0,0,0,0,0,0},
3979        {8,0,0,0,0,0,0,0},
3980        {8,0,0,0,0,0,0,0},
3981        {1,1,1,1,1,1,2,0},
3982        {8,0,0,0,0,0,0,0},
3983        {1,1,1,1,1,1,2,0},
3984        {8,0,0,0,0,0,0,0},      /*Reg 0xF0*/
3985        {8,0,0,0,0,0,0,0},
3986        {1,1,6,0,0,0,0,0},
3987        {8,0,0,0,0,0,0,0},
3988        {1,1,1,5,0,0,0,0},
3989        {8,0,0,0,0,0,0,0},
3990        {8,0,0,0,0,0,0,0},
3991        {1,1,1,1,1,1,1,1},
3992        {1,1,1,5,0,0,0,0},
3993        {8,0,0,0,0,0,0,0},
3994        {8,0,0,0,0,0,0,0},
3995        {3,1,1,3,0,0,0,0},
3996        {1,1,1,1,4,0,0,0},
3997        {1,7,0,0,0,0,0,0},
3998        {1,7,0,0,0,0,0,0},
3999        {1,7,0,0,0,0,0,0}       /*Reg 0xff*/
4000};
4001
4002// Data to write in field at register [RegIndex] = (Data & Mask) << Shift;
4003static U16 RegIndex;    // I2C register address
4004static U8 Mask;         // Mask for data
4005static U8 Shift;        // nb of left shifts to reach field pos in register
4006
4007DVAUD_Status_t ComputeRegMaskShift(U16 Field)
4008{
4009  unsigned char pos;
4010  unsigned char index;
4011  unsigned char length;
4012 
4013  Mask = 0;
4014
4015  for (RegIndex = 0; RegIndex < NBREG; RegIndex++)
4016    {
4017    pos = 0;
4018    index = 0;
4019    while (pos < 8)
4020      {
4021      length = Field_Length[RegIndex][index];           // field lenght in register at (7-pos)
4022      if (length==0)                                    // null length: end of register
4023        break;                                          // go to next one in list
4024      if (Field == 0)                                   // found field
4025        {
4026        // example: 1,3,4,0,0,0,0
4027        // 1st field: pos=0, length=1 gives Shift=7 and Mask=0x01(<<7=0x80)  1xxxxxxx
4028        // 2nd field: pos=1, length=3 gives Shift=4 and Mask=0x07(<<4=0x70)  x111xxxx
4029        // 3rd field: pos=4, length=4 gives Shift=0 and Mask=0x0F(<<0=0x0F)  xxxx1111
4030        Shift = 8-pos-length;                           // compute nb of shifts to reach field from LSB
4031        while (length)                                  // compute mask to AND data with
4032          {
4033          Mask<<=1;
4034          Mask+=1;
4035          length--;
4036          }
4037        return DVAUD_kNoError;                          // everything OK
4038        }
4039      index++;                                          // next pos in array
4040      pos += length;                                    // next field pos in register
4041      Field--;                                          // go to next field in list
4042      }
4043    }
4044
4045  return DVAUD_kBadParameter;                           // could not find field
4046}                                                         
4047
4048//static void DVAUD_I2cClrBit(U8 Reg, U8 Bit)           // Reg = register subaddress, Bit = bit # (0..7)
4049static void DVAUD_I2cClrBit(U16 Field)                  // Field = field name in enum Field_List
4050{
4051  // !! if Field is not a single bit, only the rightmost bit of the field will be written
4052  DVAUD_I2cWriteField(Field, 0);
4053}
4054
4055//static void DVAUD_I2cSetBit(U8 Reg, U8 Bit)           // Reg = register subaddress, Bit = bit # (0..7)
4056static void DVAUD_I2cSetBit(U16 Field)                  // Field = field name in enum Field_List
4057{
4058  // !! if Field is not a single bit, only the rightmost bit of the field will be written
4059  DVAUD_I2cWriteField(Field, 1);
4060}
4061
4062static void DVAUD_I2cWriteReg(U8 Reg, U8 RegValue)      // Reg = register subaddress, RegValue = 0..255
4063{
4064  if (I2C_Write(I2cAddr83xy, Reg, RegValue))            // low level H/W I2C access
4065    I2C_Status = DVAUD_kI2CProblem;
4066  else
4067    I2C_Status = DVAUD_kNoError;
4068}
4069
4070//static void DVAUD_I2cWriteField(U8 Reg, U8 Field, U8 Value)   // Reg = register subaddress, Field = bits to write, Value = 0..255
4071static void DVAUD_I2cWriteField(U16 Field, U8 Value)    // Field = field name in enum Field_List, Value = 0..255
4072{
4073  U8 RegValue;
4074
4075  I2C_Status = ComputeRegMaskShift(Field);              // compute register address, mask and n# of left shifts
4076  if (I2C_Status != DVAUD_kNoError)                     // if bad register
4077    return;                                             // quit in error
4078
4079  Value  &= Mask;                                       // mask bits in data to write
4080  Value <<= Shift;                                      // prepare data at proper position in register
4081  Mask  <<= Shift;                                      // shift mask to mask existing data in register
4082 
4083  RegValue = I2C_Read(I2cAddr83xy, RegIndex);           // low level H/W I2C access
4084  RegValue &= ~Mask;                                    // mask bits outside field
4085  RegValue |= Value;                                    // fill bit(s) in
4086
4087  if (I2C_Write(I2cAddr83xy, RegIndex, RegValue))       // low level H/W I2C access
4088    I2C_Status = DVAUD_kI2CProblem;
4089  else
4090    I2C_Status = DVAUD_kNoError;
4091}
4092
4093static U8 DVAUD_I2cReadReg(U8 Reg)                      // Reg = register subaddress
4094{
4095  return(I2C_Read(I2cAddr83xy, Reg));                   // low level H/W I2C access
4096}
4097
4098//static void DVAUD_I2cWriteField(U8 Reg, U8 Field, U8 Value)   // Reg = register subaddress, Field = bits to write, Value = 0..255
4099static U8 DVAUD_I2cReadField(U16 Field)                 // Field = field name in enum Field_List, Value = 0..255
4100{
4101  U8 RegValue = 0;
4102
4103  I2C_Status = ComputeRegMaskShift(Field);              // compute register address, mask and n# of left shifts
4104  if (I2C_Status == DVAUD_kNoError)                     // if good register
4105    {
4106    RegValue = I2C_Read(I2cAddr83xy, RegIndex);         // low level H/W I2C access
4107    RegValue >>= Shift;                                 // shift data back from position in register
4108    RegValue &= Mask;                                   // mask bits in data just read
4109    }
4110
4111  return RegValue; 
4112}
4113
4114// added by bg.noh
4115U8 DVAUD_I2cWriteReg_Mask(U8 RegIndex, U8 Data, U8 Mask)
4116{
4117        U8 ucRegValue;
4118        U8 ucResult = 0;
4119
4120        ucRegValue = I2C_Read( I2cAddr83xy, RegIndex );
4121
4122        ucRegValue &= ~Mask;
4123        ucRegValue |= Data;
4124
4125        ucResult |= I2C_Write( I2cAddr83xy, RegIndex, ucRegValue );
4126
4127        return ( ucResult );
4128}
4129
Note: See TracBrowser for help on using the repository browser.