/**
  * @brief  Get the CS42L52 ID.
  * @param DeviceAddr: Device address on communication Bus.   
  * @retval The CS42L52 ID 
  */
uint32_t cs42l52_ReadID(uint16_t DeviceAddr)
{
  /* Initialize the Control interface of the Audio Codec */
  AUDIO_IO_Init(); 
  
  return ((uint32_t)AUDIO_IO_Read(DeviceAddr, CS42L52_CHIPID_ADDR));
}
Example #2
0
/**
  * @brief  Get the WM8994 ID.
  * @param DeviceAddr: Device address on communication Bus.
  * @retval The WM8994 ID 
  */
uint32_t wm8994_ReadID(uint16_t DeviceAddr)
{
  /* Initialize the Control interface of the Audio Codec */
  AUDIO_IO_Init();

  return ((uint32_t)AUDIO_IO_Read(DeviceAddr, WM8994_CHIPID_ADDR));
}
Example #3
0
/**
  * @brief  Get the CS43L22 ID.
  * @param DeviceAddr: Device address on communication Bus.   
  * @retval The CS43L22 ID 
  */
uint32_t cs43l22_ReadID(uint16_t DeviceAddr)
{
  uint8_t Value;
  /* Initialize the Control interface of the Audio Codec */
  AUDIO_IO_Init(); 
  
  Value = AUDIO_IO_Read(DeviceAddr, CS43L22_CHIPID_ADDR);
  Value = (Value & CS43L22_ID_MASK);
  
  return((uint32_t) Value);
}
Example #4
0
/**
  * @brief Initializes the audio codec and the control interface.
  * @param DeviceAddr: Device address on communication Bus.   
  * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
  *                       OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO .
  * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
  * @param AudioFreq: Audio Frequency 
  * @retval 0 if correct communication, else wrong communication
  */
uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
{
  uint32_t counter = 0;
  
  /* Initialize the Control interface of the Audio Codec */
  AUDIO_IO_Init();
  
  /* wm8994 Errata Work-Arounds */
  counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0003);
  counter += CODEC_IO_Write(DeviceAddr, 0x817, 0x0000);
  counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0000);
  
  /* Enable VMID soft start (fast), Start-up Bias Current Enabled */
  counter += CODEC_IO_Write(DeviceAddr, 0x39, 0x0064);
  
  /* Enable bias generator, Enable VMID */
  counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x0003);
  
  /* Add Delay */
  AUDIO_IO_Delay(50);
  
  /* Path Configurations */
  switch (OutputDevice)
  {
  case OUTPUT_DEVICE_SPEAKER:
    /* Enable DAC1 (Left), Enable DAC1 (Right), 
    Disable DAC2 (Left), Disable DAC2 (Right)*/
    counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);
    
    /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);
    
    /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);
    
    /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
    
    /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
    break;
    
  case OUTPUT_DEVICE_HEADPHONE:
    /* Disable DAC1 (Left), Disable DAC1 (Right), 
    Enable DAC2 (Left), Enable DAC2 (Right)*/
    counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
    
    /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
    
    /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
    
    /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
    
    /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
    break;
    
  case OUTPUT_DEVICE_BOTH:
    /* Enable DAC1 (Left), Enable DAC1 (Right), 
    also Enable DAC2 (Left), Enable DAC2 (Right)*/
    counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
    
    /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
    
    /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
    
    /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
    
    /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
    break;
    
  default:
    /* Disable DAC1 (Left), Disable DAC1 (Right), 
    Enable DAC2 (Left), Enable DAC2 (Right)*/
    counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
    
    /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
    
    /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
    
    /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
    
    /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
    counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
    break;    
  }
  
  /*  Clock Configurations */
  switch (AudioFreq)
  {
  case  AUDIO_FREQUENCY_8K:
    /* AIF1 Sample Rate = 8 (KHz), ratio=256 */ 
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
    break;
    
  case  AUDIO_FREQUENCY_16K:
    /* AIF1 Sample Rate = 16 (KHz), ratio=256 */ 
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
    break;
    
  case  AUDIO_FREQUENCY_48K:
    /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
    break;
    
  case  AUDIO_FREQUENCY_96K:
    /* AIF1 Sample Rate = 96 (KHz), ratio=256 */ 
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
    break;
    
  case  AUDIO_FREQUENCY_11K:
    /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */ 
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
    break;
    
  case  AUDIO_FREQUENCY_22K:
    /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */ 
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
    break;
    
  case  AUDIO_FREQUENCY_44K:
    /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */ 
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
    break; 
    
  default:
    /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
    break; 
  }
  
  /* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */
  counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4010);
  
  /* slave mode */
  counter += CODEC_IO_Write(DeviceAddr, 0x302, 0x0000);
  
  /* Enable the DSP processing clock for AIF1, Enable the core clock */
  counter += CODEC_IO_Write(DeviceAddr, 0x208, 0x000A);
  
  /* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */
  counter += CODEC_IO_Write(DeviceAddr, 0x200, 0x0001);
  
  /* Analogue Output Configuration */
  
  /* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */
  counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0300);
  
  /* Left Speaker Mixer Volume = 0dB */
  counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x0000);
  
  /* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/
  counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x0000);
  
  /* Volume Control */
  wm8994_SetVolume(DeviceAddr, Volume);
  
  /* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path, 
  Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */
  counter += CODEC_IO_Write(DeviceAddr, 0x36, 0x0300);
  
  /* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */
  counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x3003);
  
  /* Headphone/Speaker Enable */
  
  /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */
  counter += CODEC_IO_Write(DeviceAddr, 0x51, 0x0005);
  
  /* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */
  /* idem for Speaker */
  counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x0303 | 0x3003);
  
  /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */
  counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x0022);
  
  /* Enable Charge Pump */
  counter += CODEC_IO_Write(DeviceAddr, 0x4C, 0x9F25);
  
  /* Add Delay */
  AUDIO_IO_Delay(15);
  
  /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
  counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0001);
  
  /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
  counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0001);
  
  /* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */
  /* idem for SPKOUTL and SPKOUTR */
  counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0030 | 0x0300);
  
  /* Enable DC Servo and trigger start-up mode on left and right channels */
  counter += CODEC_IO_Write(DeviceAddr, 0x54, 0x0033);
  
  /* Add Delay */
  AUDIO_IO_Delay(250);
  
  /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */
  counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x00EE);
  
  /* Unmutes */
  
  /* Unmute DAC 1 (Left) */
  counter += CODEC_IO_Write(DeviceAddr, 0x610, 0x00C0);
  
  /* Unmute DAC 1 (Right) */
  counter += CODEC_IO_Write(DeviceAddr, 0x611, 0x00C0);
  
  /* Unmute the AIF1 Timeslot 0 DAC path */
  counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);
  
  /* Unmute DAC 2 (Left) */
  counter += CODEC_IO_Write(DeviceAddr, 0x612, 0x00C0);
  
  /* Unmute DAC 2 (Right) */
  counter += CODEC_IO_Write(DeviceAddr, 0x613, 0x00C0);
  
  /* Unmute the AIF1 Timeslot 1 DAC2 path */
  counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);
  
  /* Return communication control value */
  return counter;  
}
/**
  * @brief Initializes the audio codec and the control interface.
  * @param DeviceAddr: Device address on communication Bus.   
  * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
  *                       OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO .
  * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
  * @retval 0 if correct communication, else wrong communication
  */
uint32_t cs42l52_Init(uint16_t DeviceAddr, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
{
  uint32_t counter = 0;
  
  /* Initialize the Control interface of the Audio Codec */
  AUDIO_IO_Init();     
    
  /* Keep Codec powered OFF */
  counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x01);  
  
  /*Save Output device for mute ON/OFF procedure*/
  switch (OutputDevice)
  {
  case OUTPUT_DEVICE_SPEAKER:
    OutputDev = 0xFA;   /* SPK always ON & HP always OFF */
    break;
    
  case OUTPUT_DEVICE_HEADPHONE:
    OutputDev = 0xAF;   /* SPK always OFF & HP always ON */
    break;
    
  case OUTPUT_DEVICE_BOTH:
    OutputDev = 0xAA;   /* SPK always ON & HP always ON */
    break;
    
  case OUTPUT_DEVICE_AUTO:
    OutputDev = 0x05;   /* Detect the HP or the SPK automatically */
    break;    
    
  default:
    OutputDev = 0x05;   /* Detect the HP or the SPK automatically */
    break;    
  }
  
  counter += CODEC_IO_Write(DeviceAddr, 0x04, OutputDev);
  
  /* Clock configuration: Auto detection */  
  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x80);
  
  /* Set the Slave Mode and the audio Standard */  
  counter += CODEC_IO_Write(DeviceAddr, 0x06, CODEC_STANDARD);
  
  /* Interface Control 2: SCLK is Re-timed signal from MCLK*/
  counter +=CODEC_IO_Write(DeviceAddr, 0x07, 0x00); 
  
  /* ADCA and PGAA Select: no input selected*/
  counter +=CODEC_IO_Write(DeviceAddr, 0x08, 0x00);
  /* ADCB and PGAB Select: no input selected*/
  counter +=CODEC_IO_Write(DeviceAddr, 0x09, 0x00); 
  /*Play Back Control 1: headphone gain is 0.4, PCM not inverted, Master not mute*/
  counter +=CODEC_IO_Write(DeviceAddr, 0x0D, 0x10);/* CS42L52 has different config than CS42L52*/ 
  /* Miscellaneous Controls: Passthrough Analog & Passthrough Mute off, Soft Ramp on @0x0E*/
  counter +=CODEC_IO_Write(DeviceAddr, 0x0E, 0x02);  
  /* Play Back Control 2: Headphone Mute off, speaker mute off, mono enabled */
  counter +=CODEC_IO_Write(DeviceAddr, 0x0F, 0x32); 
  /* PCM A Volume: PCM Mute disabled, Volume is 0db(default) */
  counter +=CODEC_IO_Write(DeviceAddr, 0x1A, 0x00);
  /* PCM B Volume: PCM Mute disabled, Volume is 0db(default) */
  counter +=CODEC_IO_Write(DeviceAddr, 0x1B, 0x00); 
  /* Headphone A Volume: Headphone Volume is -6db */
  counter +=CODEC_IO_Write(DeviceAddr, 0x22, (uint8_t)(0-12));
  /* Headphone B Volume: Headphone Volume is -6db */
  counter +=CODEC_IO_Write(DeviceAddr, 0x23, (uint8_t)(0-12));    
  /* Speaker A Volume: Speaker Volume is 0db (default) */
  counter +=CODEC_IO_Write(DeviceAddr, 0x24, 0x00);
  /* Speaker B Volume: Speaker Volume is 0db (default) */
  counter +=CODEC_IO_Write(DeviceAddr, 0x25, 0x00);
  /* Charge Pump Frequency: 5 (default) */
  counter +=CODEC_IO_Write(DeviceAddr, 0x34, 5<<4);
  /* Power Control 1: power up */
  counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x00); 

  /* Set the Master volume */
  counter += cs42l52_SetVolume(DeviceAddr, Volume);
  
  /* Return communication control value */
  return counter;  
}
Example #6
0
/**
  * @brief Initializes the audio codec and the control interface.
  * @param DeviceAddr: Device address on communication Bus.   
  * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
  *                       OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO .
  * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
  * @retval 0 if correct communication, else wrong communication
  */
uint32_t cs43l22_Init(uint16_t DeviceAddr, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
{
  uint32_t counter = 0;
  
  /* Initialize the Control interface of the Audio Codec */
  AUDIO_IO_Init();     
    
  /* Keep Codec powered OFF */
  counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x01);  
  
  /*Save Output device for mute ON/OFF procedure*/
  switch (OutputDevice)
  {
  case OUTPUT_DEVICE_SPEAKER:
    OutputDev = 0xFA;
    break;
    
  case OUTPUT_DEVICE_HEADPHONE:
    OutputDev = 0xAF;
    break;
    
  case OUTPUT_DEVICE_BOTH:
    OutputDev = 0xAA;
    break;
    
  case OUTPUT_DEVICE_AUTO:
    OutputDev = 0x05;
    break;    
    
  default:
    OutputDev = 0x05;
    break;    
  }
  
  counter += CODEC_IO_Write(DeviceAddr, 0x04, OutputDev);
  
  /* Clock configuration: Auto detection */  
  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x81);
  
  /* Set the Slave Mode and the audio Standard */  
  counter += CODEC_IO_Write(DeviceAddr, 0x06, CODEC_STANDARD);
  
  /* Set the Master volume */
  counter += cs43l22_SetVolume(DeviceAddr, Volume);
  
  /* If the Speaker is enabled, set the Mono mode and volume attenuation level */
  if(OutputDevice != OUTPUT_DEVICE_HEADPHONE)
  {
    /* Set the Speaker Mono mode */  
    counter += CODEC_IO_Write(DeviceAddr, 0x0F , 0x06);
    
    /* Set the Speaker attenuation level */  
    counter += CODEC_IO_Write(DeviceAddr, 0x24, 0x00);
    counter += CODEC_IO_Write(DeviceAddr, 0x25, 0x00);
  }
  
  /* Additional configuration for the CODEC. These configurations are done to reduce
  the time needed for the Codec to power off. If these configurations are removed, 
  then a long delay should be added between powering off the Codec and switching 
  off the I2S peripheral MCLK clock (which is the operating clock for Codec).
  If this delay is not inserted, then the codec will not shut down properly and
  it results in high noise after shut down. */
  
  /* Disable the analog soft ramp */
  counter += CODEC_IO_Write(DeviceAddr, 0x0A, 0x00);
  /* Disable the digital soft ramp */
  counter += CODEC_IO_Write(DeviceAddr, 0x0E, 0x04);
  /* Disable the limiter attack level */
  counter += CODEC_IO_Write(DeviceAddr, 0x27, 0x00);
  /* Adjust Bass and Treble levels */
  counter += CODEC_IO_Write(DeviceAddr, 0x1F, 0x0F);
  /* Adjust PCM volume level */
  counter += CODEC_IO_Write(DeviceAddr, 0x1A, 0x0A);
  counter += CODEC_IO_Write(DeviceAddr, 0x1B, 0x0A);
  
  /* Return communication control value */
  return counter;  
}
Example #7
0
/**
  * @brief Initializes the audio codec and the control interface.
  * @param DeviceAddr: Device address on communication Bus.
  * @param OutputInputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
  *  OUTPUT_DEVICE_BOTH, OUTPUT_DEVICE_AUTO, INPUT_DEVICE_DIGITAL_MICROPHONE_1,
  *  INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_INPUT_LINE_1 or INPUT_DEVICE_INPUT_LINE_2.
  * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
  * @param AudioFreq: Audio Frequency
  * @retval 0 if correct communication, else wrong communication
  */
uint32_t wm8994_Init (uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq)
{
  uint32_t counter = 0;
  uint16_t output_device = OutputInputDevice & 0xFF;
  uint16_t input_device = OutputInputDevice & 0xFF00;
  uint16_t power_mgnt_reg_1 = 0;

  /* Initialize the Control interface of the Audio Codec */
  AUDIO_IO_Init();

  /* wm8994 Errata Work-Arounds */
  counter += CODEC_IO_Write (DeviceAddr, 0x102, 0x0003);
  counter += CODEC_IO_Write (DeviceAddr, 0x817, 0x0000);
  counter += CODEC_IO_Write (DeviceAddr, 0x102, 0x0000);

  /* Enable VMID soft start (fast), Start-up Bias Current Enabled */
  counter += CODEC_IO_Write (DeviceAddr, 0x39, 0x006C);

  /* Enable bias generator, Enable VMID */
  counter += CODEC_IO_Write (DeviceAddr, 0x01, 0x0003);

  /* Add Delay */
  AUDIO_IO_Delay(50);

  /* Path Configurations for output */
  if (output_device > 0)
  {
    outputEnabled = 1;
    switch (output_device)
    {
    case OUTPUT_DEVICE_SPEAKER:
      /* Enable DAC1 (Left), Enable DAC1 (Right),
      Disable DAC2 (Left), Disable DAC2 (Right)*/
      counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);

      /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);

      /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);

      /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);

      /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
      break;

    case OUTPUT_DEVICE_HEADPHONE:
      /* Disable DAC1 (Left), Disable DAC1 (Right),
      Enable DAC2 (Left), Enable DAC2 (Right)*/
      counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);

      /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);

      /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);

      /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);

      /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
      break;

    case OUTPUT_DEVICE_BOTH:
      /* Enable DAC1 (Left), Enable DAC1 (Right),
      also Enable DAC2 (Left), Enable DAC2 (Right)*/
      counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);

      /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);

      /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);

      /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);

      /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
      break;

    case OUTPUT_DEVICE_AUTO :
    default:
      /* Disable DAC1 (Left), Disable DAC1 (Right),
      Enable DAC2 (Left), Enable DAC2 (Right)*/
      counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);

      /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);

      /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);

      /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);

      /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
      break;
    }
  }
  else
  {
    outputEnabled = 0;
  }

  /* Path Configurations for input */
  if (input_device > 0)
  {
    inputEnabled = 1;
    switch (input_device)
    {
    case INPUT_DEVICE_DIGITAL_MICROPHONE_2 :
      /* Enable AIF1ADC2 (Left), Enable AIF1ADC2 (Right)
       * Enable DMICDAT2 (Left), Enable DMICDAT2 (Right)
       * Enable Left ADC, Enable Right ADC */
      counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0C30);

      /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
      counter += CODEC_IO_Write(DeviceAddr, 0x450, 0x00DB);

      /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
      counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6000);

      /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x608, 0x0002);

      /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x609, 0x0002);

      /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC2 signal detect */
      counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000E);
      break;

    case INPUT_DEVICE_INPUT_LINE_1 :
      /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
       * Enable Left ADC, Enable Right ADC */
      counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0303);

      /* Enable AIF1 DRC1 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
      counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);

      /* Enable IN1L and IN1R, Disable IN2L and IN2R, Enable Thermal sensor & shutdown */
      counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6350);

      /* Enable the ADCL(Left) to AIF1 Timeslot 0 (Left) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);

      /* Enable the ADCR(Right) to AIF1 Timeslot 0 (Right) mixer path */
      counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);

      /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
      counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
      break;

    case INPUT_DEVICE_DIGITAL_MICROPHONE_1 :
    case INPUT_DEVICE_INPUT_LINE_2 :
    default:
      /* Actually, no other input devices supported */
      counter++;
      break;
    }
  }
  else
  {
    inputEnabled = 0;
  }

  /*  Clock Configurations */
  switch (AudioFreq)
  {
  case  AUDIO_FREQUENCY_8K:
    /* AIF1 Sample Rate = 8 (KHz), ratio=256 */
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
    break;

  case  AUDIO_FREQUENCY_16K:
    /* AIF1 Sample Rate = 16 (KHz), ratio=256 */
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
    break;

  case  AUDIO_FREQUENCY_48K:
    /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
    break;

  case  AUDIO_FREQUENCY_96K:
    /* AIF1 Sample Rate = 96 (KHz), ratio=256 */
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
    break;

  case  AUDIO_FREQUENCY_11K:
    /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
    break;

  case  AUDIO_FREQUENCY_22K:
    /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
    break;

  case  AUDIO_FREQUENCY_44K:
    /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
    break;

  default:
    /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
    counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
    break;
  }
  /* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */
  counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4010);

  /* slave mode */
  counter += CODEC_IO_Write(DeviceAddr, 0x302, 0x0000);

  /* Enable the DSP processing clock for AIF1, Enable the core clock */
  counter += CODEC_IO_Write(DeviceAddr, 0x208, 0x000A);

  /* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */
  counter += CODEC_IO_Write(DeviceAddr, 0x200, 0x0001);

  if (output_device > 0)  /* Audio output selected */
  {
    /* Analog Output Configuration */

    /* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */
    counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0300);

    /* Left Speaker Mixer Volume = 0dB */
    counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x0000);

    /* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/
    counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x0000);

    /* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path,
    Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */
    counter += CODEC_IO_Write(DeviceAddr, 0x36, 0x0300);

    /* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */
    counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x3003);

    /* Headphone/Speaker Enable */

    /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */
    counter += CODEC_IO_Write(DeviceAddr, 0x51, 0x0005);

    /* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */
    /* idem for Speaker */
    power_mgnt_reg_1 |= 0x0303 | 0x3003;
    counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);

    /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */
    counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x0022);

    /* Enable Charge Pump */
    counter += CODEC_IO_Write(DeviceAddr, 0x4C, 0x9F25);

    /* Add Delay */
    AUDIO_IO_Delay(15);

    /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
    counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0001);

    /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
    counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0001);

    /* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */
    /* idem for SPKOUTL and SPKOUTR */
    counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0030 | 0x0300);

    /* Enable DC Servo and trigger start-up mode on left and right channels */
    counter += CODEC_IO_Write(DeviceAddr, 0x54, 0x0033);

    /* Add Delay */
    AUDIO_IO_Delay(250);

    /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */
    counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x00EE);

    /* Unmutes */

    /* Unmute DAC 1 (Left) */
    counter += CODEC_IO_Write(DeviceAddr, 0x610, 0x00C0);

    /* Unmute DAC 1 (Right) */
    counter += CODEC_IO_Write(DeviceAddr, 0x611, 0x00C0);

    /* Unmute the AIF1 Timeslot 0 DAC path */
    counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);

    /* Unmute DAC 2 (Left) */
    counter += CODEC_IO_Write(DeviceAddr, 0x612, 0x00C0);

    /* Unmute DAC 2 (Right) */
    counter += CODEC_IO_Write(DeviceAddr, 0x613, 0x00C0);

    /* Unmute the AIF1 Timeslot 1 DAC2 path */
    counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);

    /* Volume Control */
    wm8994_SetVolume(DeviceAddr, Volume);
  }

  if (input_device > 0) /* Audio input selected */
  {
    if ((input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_1) || (input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_2))
    {
      /* Enable Microphone bias 1 generator, Enable VMID */
      power_mgnt_reg_1 |= 0x0013;
      counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);

      /* ADC oversample enable */
      counter += CODEC_IO_Write(DeviceAddr, 0x620, 0x0002);

      /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
      counter += CODEC_IO_Write(DeviceAddr, 0x411, 0x3800);
    }
    else if ((input_device == INPUT_DEVICE_INPUT_LINE_1) || (input_device == INPUT_DEVICE_INPUT_LINE_2))
    {
      /* Enable normal bias generator, Enable VMID */
      power_mgnt_reg_1 |= 0x0003;
      counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);

      /* Disable mute on IN1L, IN1L Volume = +0dB */
      counter += CODEC_IO_Write(DeviceAddr, 0x18, 0x000B);

      /* Disable mute on IN1R, IN1R Volume = +0dB */
      counter += CODEC_IO_Write(DeviceAddr, 0x1A, 0x000B);

      /* Disable mute on IN1L_TO_MIXINL, Gain = +0dB */
      counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0025);

      /* Disable mute on IN1R_TO_MIXINL, Gain = +0dB */
      counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0025);

      /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
      counter += CODEC_IO_Write(DeviceAddr, 0x28, 0x0011);

      /* AIF ADC1 HPF enable, HPF cut = hifi mode fc=4Hz at fs=48kHz */
      counter += CODEC_IO_Write(DeviceAddr, 0x410, 0x1800);
    }
    /* Volume Control */
    wm8994_SetVolume(DeviceAddr, Volume);
  }
  /* Return communication control value */
  return counter;
}