STM32746G-Discovery board drivers V1.0.0

Dependents:   F746_SD_GraphicEqualizer_ren0620

Fork of BSP_DISCO_F746NG by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers wm8994.c Source File

wm8994.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    wm8994.c
00004   * @author  MCD Application Team
00005   * @version V2.0.0
00006   * @date    24-June-2015
00007   * @brief   This file provides the WM8994 Audio Codec driver.   
00008   ******************************************************************************
00009   * @attention
00010   *
00011   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
00012   *
00013   * Redistribution and use in source and binary forms, with or without modification,
00014   * are permitted provided that the following conditions are met:
00015   *   1. Redistributions of source code must retain the above copyright notice,
00016   *      this list of conditions and the following disclaimer.
00017   *   2. Redistributions in binary form must reproduce the above copyright notice,
00018   *      this list of conditions and the following disclaimer in the documentation
00019   *      and/or other materials provided with the distribution.
00020   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00021   *      may be used to endorse or promote products derived from this software
00022   *      without specific prior written permission.
00023   *
00024   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00025   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00028   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00030   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00032   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034   *
00035   ******************************************************************************
00036   */
00037 
00038 /* Includes ------------------------------------------------------------------*/
00039 #include "wm8994.h"
00040 
00041 /** @addtogroup BSP
00042   * @{
00043   */
00044   
00045 /** @addtogroup Components
00046   * @{
00047   */ 
00048 
00049 /** @addtogroup wm8994
00050   * @brief     This file provides a set of functions needed to drive the 
00051   *            WM8994 audio codec.
00052   * @{
00053   */
00054 
00055 /** @defgroup WM8994_Private_Types
00056   * @{
00057   */
00058 
00059 /**
00060   * @}
00061   */ 
00062   
00063 /** @defgroup WM8994_Private_Defines
00064   * @{
00065   */
00066 /* Uncomment this line to enable verifying data sent to codec after each write 
00067    operation (for debug purpose) */
00068 #if !defined (VERIFY_WRITTENDATA)  
00069 /* #define VERIFY_WRITTENDATA */
00070 #endif /* VERIFY_WRITTENDATA */
00071 /**
00072   * @}
00073   */ 
00074 
00075 /** @defgroup WM8994_Private_Macros
00076   * @{
00077   */
00078 
00079 /**
00080   * @}
00081   */ 
00082   
00083 /** @defgroup WM8994_Private_Variables
00084   * @{
00085   */
00086 
00087 /* Audio codec driver structure initialization */  
00088 AUDIO_DrvTypeDef wm8994_drv = 
00089 {
00090   wm8994_Init,
00091   wm8994_DeInit,
00092   wm8994_ReadID,
00093 
00094   wm8994_Play,
00095   wm8994_Pause,
00096   wm8994_Resume,
00097   wm8994_Stop,  
00098 
00099   wm8994_SetFrequency,
00100   wm8994_SetVolume,
00101   wm8994_SetMute,  
00102   wm8994_SetOutputMode,
00103 
00104   wm8994_Reset
00105 };
00106 
00107 static uint32_t outputEnabled = 0;
00108 static uint32_t inputEnabled = 0;
00109 /**
00110   * @}
00111   */ 
00112 
00113 /** @defgroup WM8994_Function_Prototypes
00114   * @{
00115   */
00116 static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value);
00117 /**
00118   * @}
00119   */ 
00120 
00121 /** @defgroup WM8994_Private_Functions
00122   * @{
00123   */ 
00124 
00125 /**
00126   * @brief Initializes the audio codec and the control interface.
00127   * @param DeviceAddr: Device address on communication Bus.   
00128   * @param OutputInputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
00129   *  OUTPUT_DEVICE_BOTH, OUTPUT_DEVICE_AUTO, INPUT_DEVICE_DIGITAL_MICROPHONE_1,
00130   *  INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_INPUT_LINE_1 or INPUT_DEVICE_INPUT_LINE_2.
00131   * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
00132   * @param AudioFreq: Audio Frequency 
00133   * @retval 0 if correct communication, else wrong communication
00134   */
00135 uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq)
00136 {
00137   uint32_t counter = 0;
00138   uint16_t output_device = OutputInputDevice & 0xFF;
00139   uint16_t input_device = OutputInputDevice & 0xFF00;
00140   uint16_t power_mgnt_reg_1 = 0;
00141   
00142   /* Initialize the Control interface of the Audio Codec */
00143   AUDIO_IO_Init();
00144   /* wm8994 Errata Work-Arounds */
00145   counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0003);
00146   counter += CODEC_IO_Write(DeviceAddr, 0x817, 0x0000);
00147   counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0000);
00148   
00149   /* Enable VMID soft start (fast), Start-up Bias Current Enabled */
00150   counter += CODEC_IO_Write(DeviceAddr, 0x39, 0x006C);
00151   
00152   /* Enable bias generator, Enable VMID */
00153   counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x0003);
00154   
00155   /* Add Delay */
00156   AUDIO_IO_Delay(50);
00157 
00158   /* Path Configurations for output */
00159   if (output_device > 0)
00160   {
00161     outputEnabled = 1;
00162     switch (output_device)
00163     {
00164     case OUTPUT_DEVICE_SPEAKER:
00165       /* Enable DAC1 (Left), Enable DAC1 (Right),
00166       Disable DAC2 (Left), Disable DAC2 (Right)*/
00167       counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);
00168 
00169       /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
00170       counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);
00171 
00172       /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
00173       counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);
00174 
00175       /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
00176       counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
00177 
00178       /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
00179       counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
00180       break;
00181 
00182     case OUTPUT_DEVICE_HEADPHONE:
00183       /* Disable DAC1 (Left), Disable DAC1 (Right),
00184       Enable DAC2 (Left), Enable DAC2 (Right)*/
00185       counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
00186 
00187       /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
00188       counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
00189 
00190       /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
00191       counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
00192 
00193       /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
00194       counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
00195 
00196       /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
00197       counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
00198       break;
00199 
00200     case OUTPUT_DEVICE_BOTH:
00201       /* Enable DAC1 (Left), Enable DAC1 (Right),
00202       also Enable DAC2 (Left), Enable DAC2 (Right)*/
00203       counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
00204 
00205       /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
00206       counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
00207 
00208       /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
00209       counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
00210 
00211       /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
00212       counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
00213 
00214       /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
00215       counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
00216       break;
00217 
00218     case OUTPUT_DEVICE_AUTO :
00219     default:
00220       /* Disable DAC1 (Left), Disable DAC1 (Right),
00221       Enable DAC2 (Left), Enable DAC2 (Right)*/
00222       counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
00223 
00224       /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
00225       counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
00226 
00227       /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
00228       counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
00229 
00230       /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
00231       counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
00232 
00233       /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
00234       counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
00235       break;
00236     }
00237   }
00238   else
00239   {
00240     outputEnabled = 0;
00241   }
00242 
00243   /* Path Configurations for input */
00244   if (input_device > 0)
00245   {
00246     inputEnabled = 1;
00247     switch (input_device)
00248     {
00249     case INPUT_DEVICE_DIGITAL_MICROPHONE_2 :
00250       /* Enable AIF1ADC2 (Left), Enable AIF1ADC2 (Right)
00251        * Enable DMICDAT2 (Left), Enable DMICDAT2 (Right)
00252        * Enable Left ADC, Enable Right ADC */
00253       counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0C30);
00254 
00255       /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
00256       counter += CODEC_IO_Write(DeviceAddr, 0x450, 0x00DB);
00257 
00258       /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
00259       counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6000);
00260 
00261       /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
00262       counter += CODEC_IO_Write(DeviceAddr, 0x608, 0x0002);
00263 
00264       /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
00265       counter += CODEC_IO_Write(DeviceAddr, 0x609, 0x0002);
00266 
00267       /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC2 signal detect */
00268       counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000E);
00269       break;
00270 
00271     case INPUT_DEVICE_INPUT_LINE_1 :
00272       /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
00273        * Enable Left ADC, Enable Right ADC */
00274       counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0303);
00275 
00276       /* Enable AIF1 DRC1 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
00277       counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);
00278 
00279       /* Enable IN1L and IN1R, Disable IN2L and IN2R, Enable Thermal sensor & shutdown */
00280       counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6350);
00281 
00282       /* Enable the ADCL(Left) to AIF1 Timeslot 0 (Left) mixer path */
00283       counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);
00284 
00285       /* Enable the ADCR(Right) to AIF1 Timeslot 0 (Right) mixer path */
00286       counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);
00287 
00288       /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
00289       counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
00290       break;
00291 
00292     case INPUT_DEVICE_DIGITAL_MICROPHONE_1 :
00293     case INPUT_DEVICE_INPUT_LINE_2 :
00294     default:
00295       /* Actually, no other input devices supported */
00296       counter++;
00297       break;
00298     }
00299   }
00300   else
00301   {
00302     inputEnabled = 0;
00303   }
00304   
00305   /*  Clock Configurations */
00306   switch (AudioFreq)
00307   {
00308   case  AUDIO_FREQUENCY_8K:
00309     /* AIF1 Sample Rate = 8 (KHz), ratio=256 */ 
00310     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
00311     break;
00312     
00313   case  AUDIO_FREQUENCY_16K:
00314     /* AIF1 Sample Rate = 16 (KHz), ratio=256 */ 
00315     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
00316     break;
00317     
00318   case  AUDIO_FREQUENCY_48K:
00319     /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
00320     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
00321     break;
00322     
00323   case  AUDIO_FREQUENCY_96K:
00324     /* AIF1 Sample Rate = 96 (KHz), ratio=256 */ 
00325     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
00326     break;
00327     
00328   case  AUDIO_FREQUENCY_11K:
00329     /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */ 
00330     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
00331     break;
00332     
00333   case  AUDIO_FREQUENCY_22K:
00334     /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */ 
00335     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
00336     break;
00337     
00338   case  AUDIO_FREQUENCY_44K:
00339     /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */ 
00340     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
00341     break; 
00342     
00343   default:
00344     /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
00345     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
00346     break; 
00347   }
00348   /* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */
00349   counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4010);
00350   
00351   /* slave mode */
00352   counter += CODEC_IO_Write(DeviceAddr, 0x302, 0x0000);
00353   
00354   /* Enable the DSP processing clock for AIF1, Enable the core clock */
00355   counter += CODEC_IO_Write(DeviceAddr, 0x208, 0x000A);
00356   
00357   /* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */
00358   counter += CODEC_IO_Write(DeviceAddr, 0x200, 0x0001);
00359 
00360   if (output_device > 0)  /* Audio output selected */
00361   {
00362     /* Analog Output Configuration */
00363 
00364     /* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */
00365     counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0300);
00366 
00367     /* Left Speaker Mixer Volume = 0dB */
00368     counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x0000);
00369 
00370     /* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/
00371     counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x0000);
00372 
00373     /* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path,
00374     Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */
00375     counter += CODEC_IO_Write(DeviceAddr, 0x36, 0x0300);
00376 
00377     /* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */
00378     counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x3003);
00379 
00380     /* Headphone/Speaker Enable */
00381 
00382     /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */
00383     counter += CODEC_IO_Write(DeviceAddr, 0x51, 0x0005);
00384 
00385     /* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */
00386     /* idem for Speaker */
00387     power_mgnt_reg_1 |= 0x0303 | 0x3003;
00388     counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
00389 
00390     /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */
00391     counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x0022);
00392 
00393     /* Enable Charge Pump */
00394     counter += CODEC_IO_Write(DeviceAddr, 0x4C, 0x9F25);
00395 
00396     /* Add Delay */
00397     AUDIO_IO_Delay(15);
00398 
00399     /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
00400     counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0001);
00401 
00402     /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
00403     counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0001);
00404 
00405     /* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */
00406     /* idem for SPKOUTL and SPKOUTR */
00407     counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0030 | 0x0300);
00408 
00409     /* Enable DC Servo and trigger start-up mode on left and right channels */
00410     counter += CODEC_IO_Write(DeviceAddr, 0x54, 0x0033);
00411 
00412     /* Add Delay */
00413     AUDIO_IO_Delay(250);
00414 
00415     /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */
00416     counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x00EE);
00417 
00418     /* Unmutes */
00419 
00420     /* Unmute DAC 1 (Left) */
00421     counter += CODEC_IO_Write(DeviceAddr, 0x610, 0x00C0);
00422 
00423     /* Unmute DAC 1 (Right) */
00424     counter += CODEC_IO_Write(DeviceAddr, 0x611, 0x00C0);
00425 
00426     /* Unmute the AIF1 Timeslot 0 DAC path */
00427     counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);
00428 
00429     /* Unmute DAC 2 (Left) */
00430     counter += CODEC_IO_Write(DeviceAddr, 0x612, 0x00C0);
00431 
00432     /* Unmute DAC 2 (Right) */
00433     counter += CODEC_IO_Write(DeviceAddr, 0x613, 0x00C0);
00434 
00435     /* Unmute the AIF1 Timeslot 1 DAC2 path */
00436     counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);
00437     
00438     /* Volume Control */
00439     wm8994_SetVolume(DeviceAddr, Volume);
00440   }
00441 
00442   if (input_device > 0) /* Audio input selected */
00443   {
00444     if ((input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_1) || (input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_2))
00445     {
00446       /* Enable Microphone bias 1 generator, Enable VMID */
00447       power_mgnt_reg_1 |= 0x0013;
00448       counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
00449 
00450       /* ADC oversample enable */
00451       counter += CODEC_IO_Write(DeviceAddr, 0x620, 0x0002);
00452 
00453       /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
00454       counter += CODEC_IO_Write(DeviceAddr, 0x411, 0x3800);
00455     }
00456     else if ((input_device == INPUT_DEVICE_INPUT_LINE_1) || (input_device == INPUT_DEVICE_INPUT_LINE_2))
00457     {
00458       /* Enable normal bias generator, Enable VMID */
00459       power_mgnt_reg_1 |= 0x0003;
00460       counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
00461 
00462       /* Disable mute on IN1L, IN1L Volume = +0dB */
00463       counter += CODEC_IO_Write(DeviceAddr, 0x18, 0x000B);
00464 
00465       /* Disable mute on IN1R, IN1R Volume = +0dB */
00466       counter += CODEC_IO_Write(DeviceAddr, 0x1A, 0x000B);
00467 
00468       /* Disable mute on IN1L_TO_MIXINL, Gain = +0dB */
00469       counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0025);
00470 
00471       /* Disable mute on IN1R_TO_MIXINL, Gain = +0dB */
00472       counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0025);
00473 
00474       /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
00475       counter += CODEC_IO_Write(DeviceAddr, 0x28, 0x0011);
00476 
00477       /* AIF ADC1 HPF enable, HPF cut = hifi mode fc=4Hz at fs=48kHz */
00478       counter += CODEC_IO_Write(DeviceAddr, 0x410, 0x1800);
00479     }
00480     /* Volume Control */
00481     wm8994_SetVolume(DeviceAddr, Volume);
00482   }
00483   /* Return communication control value */
00484   return counter;  
00485 }
00486 
00487 /**
00488   * @brief  Deinitializes the audio codec.
00489   * @param  None
00490   * @retval  None
00491   */
00492 void wm8994_DeInit(void)
00493 {
00494   /* Deinitialize Audio Codec interface */
00495   AUDIO_IO_DeInit();
00496 }
00497 
00498 /**
00499   * @brief  Get the WM8994 ID.
00500   * @param DeviceAddr: Device address on communication Bus.
00501   * @retval The WM8994 ID 
00502   */
00503 uint32_t wm8994_ReadID(uint16_t DeviceAddr)
00504 {
00505   /* Initialize the Control interface of the Audio Codec */
00506   AUDIO_IO_Init();
00507 
00508   return ((uint32_t)AUDIO_IO_Read(DeviceAddr, WM8994_CHIPID_ADDR));
00509 }
00510 
00511 /**
00512   * @brief Start the audio Codec play feature.
00513   * @note For this codec no Play options are required.
00514   * @param DeviceAddr: Device address on communication Bus.   
00515   * @retval 0 if correct communication, else wrong communication
00516   */
00517 uint32_t wm8994_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size)
00518 {
00519   uint32_t counter = 0;
00520  
00521   /* Resumes the audio file playing */  
00522   /* Unmute the output first */
00523   counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
00524   
00525   return counter;
00526 }
00527 
00528 /**
00529   * @brief Pauses playing on the audio codec.
00530   * @param DeviceAddr: Device address on communication Bus. 
00531   * @retval 0 if correct communication, else wrong communication
00532   */
00533 uint32_t wm8994_Pause(uint16_t DeviceAddr)
00534 {  
00535   uint32_t counter = 0;
00536  
00537   /* Pause the audio file playing */
00538   /* Mute the output first */
00539   counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
00540   
00541   /* Put the Codec in Power save mode */
00542   counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x01);
00543  
00544   return counter;
00545 }
00546 
00547 /**
00548   * @brief Resumes playing on the audio codec.
00549   * @param DeviceAddr: Device address on communication Bus. 
00550   * @retval 0 if correct communication, else wrong communication
00551   */
00552 uint32_t wm8994_Resume(uint16_t DeviceAddr)
00553 {
00554   uint32_t counter = 0;
00555  
00556   /* Resumes the audio file playing */  
00557   /* Unmute the output first */
00558   counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
00559   
00560   return counter;
00561 }
00562 
00563 /**
00564   * @brief Stops audio Codec playing. It powers down the codec.
00565   * @param DeviceAddr: Device address on communication Bus. 
00566   * @param CodecPdwnMode: selects the  power down mode.
00567   *          - CODEC_PDWN_SW: only mutes the audio codec. When resuming from this 
00568   *                           mode the codec keeps the previous initialization
00569   *                           (no need to re-Initialize the codec registers).
00570   *          - CODEC_PDWN_HW: Physically power down the codec. When resuming from this
00571   *                           mode, the codec is set to default configuration 
00572   *                           (user should re-Initialize the codec in order to 
00573   *                            play again the audio stream).
00574   * @retval 0 if correct communication, else wrong communication
00575   */
00576 uint32_t wm8994_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode)
00577 {
00578   uint32_t counter = 0;
00579 
00580   if (outputEnabled != 0)
00581   {
00582     /* Mute the output first */
00583     counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
00584 
00585     if (CodecPdwnMode == CODEC_PDWN_SW)
00586     {
00587        /* Only output mute required*/
00588     }
00589     else /* CODEC_PDWN_HW */
00590     {
00591       /* Mute the AIF1 Timeslot 0 DAC1 path */
00592       counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200);
00593 
00594       /* Mute the AIF1 Timeslot 1 DAC2 path */
00595       counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200);
00596 
00597       /* Disable DAC1L_TO_HPOUT1L */
00598       counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0000);
00599 
00600       /* Disable DAC1R_TO_HPOUT1R */
00601       counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0000);
00602 
00603       /* Disable DAC1 and DAC2 */
00604       counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0000);
00605 
00606       /* Reset Codec by writing in 0x0000 address register */
00607       counter += CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000);
00608 
00609       outputEnabled = 0;
00610     }
00611   }
00612   return counter;
00613 }
00614 
00615 /**
00616   * @brief Sets higher or lower the codec volume level.
00617   * @param DeviceAddr: Device address on communication Bus.
00618   * @param Volume: a byte value from 0 to 255 (refer to codec registers 
00619   *         description for more details).
00620   * @retval 0 if correct communication, else wrong communication
00621   */
00622 uint32_t wm8994_SetVolume(uint16_t DeviceAddr, uint8_t Volume)
00623 {
00624   uint32_t counter = 0;
00625   uint8_t convertedvol = VOLUME_CONVERT(Volume);
00626 
00627   /* Output volume */
00628   if (outputEnabled != 0)
00629   {
00630     if(convertedvol > 0x3E)
00631     {
00632       /* Unmute audio codec */
00633       counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
00634 
00635       /* Left Headphone Volume */
00636       counter += CODEC_IO_Write(DeviceAddr, 0x1C, 0x3F | 0x140);
00637 
00638       /* Right Headphone Volume */
00639       counter += CODEC_IO_Write(DeviceAddr, 0x1D, 0x3F | 0x140);
00640 
00641       /* Left Speaker Volume */
00642       counter += CODEC_IO_Write(DeviceAddr, 0x26, 0x3F | 0x140);
00643 
00644       /* Right Speaker Volume */
00645       counter += CODEC_IO_Write(DeviceAddr, 0x27, 0x3F | 0x140);
00646     }
00647     else if (Volume == 0)
00648     {
00649       /* Mute audio codec */
00650       counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
00651     }
00652     else
00653     {
00654       /* Unmute audio codec */
00655       counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
00656 
00657       /* Left Headphone Volume */
00658       counter += CODEC_IO_Write(DeviceAddr, 0x1C, convertedvol | 0x140);
00659 
00660       /* Right Headphone Volume */
00661       counter += CODEC_IO_Write(DeviceAddr, 0x1D, convertedvol | 0x140);
00662 
00663       /* Left Speaker Volume */
00664       counter += CODEC_IO_Write(DeviceAddr, 0x26, convertedvol | 0x140);
00665 
00666       /* Right Speaker Volume */
00667       counter += CODEC_IO_Write(DeviceAddr, 0x27, convertedvol | 0x140);
00668     }
00669   }
00670 
00671   /* Input volume */
00672   if (inputEnabled != 0)
00673   {
00674     convertedvol = VOLUME_IN_CONVERT(Volume);
00675 
00676     /* Left AIF1 ADC1 volume */
00677     counter += CODEC_IO_Write(DeviceAddr, 0x400, convertedvol | 0x100);
00678 
00679     /* Right AIF1 ADC1 volume */
00680     counter += CODEC_IO_Write(DeviceAddr, 0x401, convertedvol | 0x100);
00681 
00682     /* Left AIF1 ADC2 volume */
00683     counter += CODEC_IO_Write(DeviceAddr, 0x404, convertedvol | 0x100);
00684 
00685     /* Right AIF1 ADC2 volume */
00686     counter += CODEC_IO_Write(DeviceAddr, 0x405, convertedvol | 0x100);
00687   }
00688   return counter;
00689 }
00690 
00691 /**
00692   * @brief Enables or disables the mute feature on the audio codec.
00693   * @param DeviceAddr: Device address on communication Bus.   
00694   * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the
00695   *             mute mode.
00696   * @retval 0 if correct communication, else wrong communication
00697   */
00698 uint32_t wm8994_SetMute(uint16_t DeviceAddr, uint32_t Cmd)
00699 {
00700   uint32_t counter = 0;
00701   
00702   if (outputEnabled != 0)
00703   {
00704     /* Set the Mute mode */
00705     if(Cmd == AUDIO_MUTE_ON)
00706     {
00707       /* Soft Mute the AIF1 Timeslot 0 DAC1 path L&R */
00708       counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200);
00709 
00710       /* Soft Mute the AIF1 Timeslot 1 DAC2 path L&R */
00711       counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200);
00712     }
00713     else /* AUDIO_MUTE_OFF Disable the Mute */
00714     {
00715       /* Unmute the AIF1 Timeslot 0 DAC1 path L&R */
00716       counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);
00717 
00718       /* Unmute the AIF1 Timeslot 1 DAC2 path L&R */
00719       counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);
00720     }
00721   }
00722   return counter;
00723 }
00724 
00725 /**
00726   * @brief Switch dynamically (while audio file is played) the output target 
00727   *         (speaker or headphone).
00728   * @param DeviceAddr: Device address on communication Bus.
00729   * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER,
00730   *         OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO 
00731   * @retval 0 if correct communication, else wrong communication
00732   */
00733 uint32_t wm8994_SetOutputMode(uint16_t DeviceAddr, uint8_t Output)
00734 {
00735   uint32_t counter = 0; 
00736   
00737   switch (Output) 
00738   {
00739   case OUTPUT_DEVICE_SPEAKER:
00740     /* Enable DAC1 (Left), Enable DAC1 (Right), 
00741     Disable DAC2 (Left), Disable DAC2 (Right)*/
00742     counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);
00743     
00744     /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
00745     counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);
00746     
00747     /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
00748     counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);
00749     
00750     /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
00751     counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
00752     
00753     /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
00754     counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
00755     break;
00756     
00757   case OUTPUT_DEVICE_HEADPHONE:
00758     /* Disable DAC1 (Left), Disable DAC1 (Right), 
00759     Enable DAC2 (Left), Enable DAC2 (Right)*/
00760     counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
00761     
00762     /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
00763     counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
00764     
00765     /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
00766     counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
00767     
00768     /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
00769     counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
00770     
00771     /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
00772     counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
00773     break;
00774     
00775   case OUTPUT_DEVICE_BOTH:
00776     /* Enable DAC1 (Left), Enable DAC1 (Right), 
00777     also Enable DAC2 (Left), Enable DAC2 (Right)*/
00778     counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
00779     
00780     /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
00781     counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
00782     
00783     /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
00784     counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
00785     
00786     /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
00787     counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
00788     
00789     /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
00790     counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
00791     break;
00792     
00793   default:
00794     /* Disable DAC1 (Left), Disable DAC1 (Right), 
00795     Enable DAC2 (Left), Enable DAC2 (Right)*/
00796     counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
00797     
00798     /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
00799     counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
00800     
00801     /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
00802     counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
00803     
00804     /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
00805     counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
00806     
00807     /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
00808     counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
00809     break;    
00810   }  
00811   return counter;
00812 }
00813 
00814 /**
00815   * @brief Sets new frequency.
00816   * @param DeviceAddr: Device address on communication Bus.
00817   * @param AudioFreq: Audio frequency used to play the audio stream.
00818   * @retval 0 if correct communication, else wrong communication
00819   */
00820 uint32_t wm8994_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq)
00821 {
00822   uint32_t counter = 0;
00823  
00824   /*  Clock Configurations */
00825   switch (AudioFreq)
00826   {
00827   case  AUDIO_FREQUENCY_8K:
00828     /* AIF1 Sample Rate = 8 (KHz), ratio=256 */ 
00829     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
00830     break;
00831     
00832   case  AUDIO_FREQUENCY_16K:
00833     /* AIF1 Sample Rate = 16 (KHz), ratio=256 */ 
00834     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
00835     break;
00836     
00837   case  AUDIO_FREQUENCY_48K:
00838     /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
00839     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
00840     break;
00841     
00842   case  AUDIO_FREQUENCY_96K:
00843     /* AIF1 Sample Rate = 96 (KHz), ratio=256 */ 
00844     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
00845     break;
00846     
00847   case  AUDIO_FREQUENCY_11K:
00848     /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */ 
00849     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
00850     break;
00851     
00852   case  AUDIO_FREQUENCY_22K:
00853     /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */ 
00854     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
00855     break;
00856     
00857   case  AUDIO_FREQUENCY_44K:
00858     /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */ 
00859     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
00860     break; 
00861     
00862   default:
00863     /* AIF1 Sample Rate = 48 (KHz), ratio=256 */ 
00864     counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
00865     break; 
00866   }
00867   return counter;
00868 }
00869 
00870 /**
00871   * @brief Resets wm8994 registers.
00872   * @param DeviceAddr: Device address on communication Bus. 
00873   * @retval 0 if correct communication, else wrong communication
00874   */
00875 uint32_t wm8994_Reset(uint16_t DeviceAddr)
00876 {
00877   uint32_t counter = 0;
00878   
00879   /* Reset Codec by writing in 0x0000 address register */
00880   counter = CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000);
00881   outputEnabled = 0;
00882   inputEnabled=0;
00883 
00884   return counter;
00885 }
00886 
00887 /**
00888   * @brief  Writes/Read a single data.
00889   * @param  Addr: I2C address
00890   * @param  Reg: Reg address 
00891   * @param  Value: Data to be written
00892   * @retval None
00893   */
00894 static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value)
00895 {
00896   uint32_t result = 0;
00897   
00898  AUDIO_IO_Write(Addr, Reg, Value);
00899   
00900 #ifdef VERIFY_WRITTENDATA
00901   /* Verify that the data has been correctly written */
00902   result = (AUDIO_IO_Read(Addr, Reg) == Value)? 0:1;
00903 #endif /* VERIFY_WRITTENDATA */
00904   
00905   return result;
00906 }
00907 
00908 /**
00909   * @}
00910   */
00911 
00912 /**
00913   * @}
00914   */
00915 
00916 /**
00917   * @}
00918   */
00919 
00920 /**
00921   * @}
00922   */
00923 
00924 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/