xref: /btstack/port/stm32-f4discovery-usb/bsp/cs43l22.c (revision f763b8ceaf9411e1c5e999bc4423cdc8accb9a47)
1*f763b8ceSMatthias Ringwald /**
2*f763b8ceSMatthias Ringwald   ******************************************************************************
3*f763b8ceSMatthias Ringwald   * @file    cs43l22.c
4*f763b8ceSMatthias Ringwald   * @author  MCD Application Team
5*f763b8ceSMatthias Ringwald   * @version V2.0.2
6*f763b8ceSMatthias Ringwald   * @date    06-October-2015
7*f763b8ceSMatthias Ringwald   * @brief   This file provides the CS43L22 Audio Codec driver.
8*f763b8ceSMatthias Ringwald   ******************************************************************************
9*f763b8ceSMatthias Ringwald   * @attention
10*f763b8ceSMatthias Ringwald   *
11*f763b8ceSMatthias Ringwald   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
12*f763b8ceSMatthias Ringwald   *
13*f763b8ceSMatthias Ringwald   * Redistribution and use in source and binary forms, with or without modification,
14*f763b8ceSMatthias Ringwald   * are permitted provided that the following conditions are met:
15*f763b8ceSMatthias Ringwald   *   1. Redistributions of source code must retain the above copyright notice,
16*f763b8ceSMatthias Ringwald   *      this list of conditions and the following disclaimer.
17*f763b8ceSMatthias Ringwald   *   2. Redistributions in binary form must reproduce the above copyright notice,
18*f763b8ceSMatthias Ringwald   *      this list of conditions and the following disclaimer in the documentation
19*f763b8ceSMatthias Ringwald   *      and/or other materials provided with the distribution.
20*f763b8ceSMatthias Ringwald   *   3. Neither the name of STMicroelectronics nor the names of its contributors
21*f763b8ceSMatthias Ringwald   *      may be used to endorse or promote products derived from this software
22*f763b8ceSMatthias Ringwald   *      without specific prior written permission.
23*f763b8ceSMatthias Ringwald   *
24*f763b8ceSMatthias Ringwald   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25*f763b8ceSMatthias Ringwald   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*f763b8ceSMatthias Ringwald   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27*f763b8ceSMatthias Ringwald   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28*f763b8ceSMatthias Ringwald   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29*f763b8ceSMatthias Ringwald   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30*f763b8ceSMatthias Ringwald   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31*f763b8ceSMatthias Ringwald   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32*f763b8ceSMatthias Ringwald   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33*f763b8ceSMatthias Ringwald   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*f763b8ceSMatthias Ringwald   *
35*f763b8ceSMatthias Ringwald   ******************************************************************************
36*f763b8ceSMatthias Ringwald   */
37*f763b8ceSMatthias Ringwald 
38*f763b8ceSMatthias Ringwald /* Includes ------------------------------------------------------------------*/
39*f763b8ceSMatthias Ringwald #include "cs43l22.h"
40*f763b8ceSMatthias Ringwald 
41*f763b8ceSMatthias Ringwald /** @addtogroup BSP
42*f763b8ceSMatthias Ringwald   * @{
43*f763b8ceSMatthias Ringwald   */
44*f763b8ceSMatthias Ringwald 
45*f763b8ceSMatthias Ringwald /** @addtogroup Components
46*f763b8ceSMatthias Ringwald   * @{
47*f763b8ceSMatthias Ringwald   */
48*f763b8ceSMatthias Ringwald 
49*f763b8ceSMatthias Ringwald /** @addtogroup CS43L22
50*f763b8ceSMatthias Ringwald   * @brief     This file provides a set of functions needed to drive the
51*f763b8ceSMatthias Ringwald   *            CS43L22 audio codec.
52*f763b8ceSMatthias Ringwald   * @{
53*f763b8ceSMatthias Ringwald   */
54*f763b8ceSMatthias Ringwald 
55*f763b8ceSMatthias Ringwald /** @defgroup CS43L22_Private_Types
56*f763b8ceSMatthias Ringwald   * @{
57*f763b8ceSMatthias Ringwald   */
58*f763b8ceSMatthias Ringwald 
59*f763b8ceSMatthias Ringwald /**
60*f763b8ceSMatthias Ringwald   * @}
61*f763b8ceSMatthias Ringwald   */
62*f763b8ceSMatthias Ringwald 
63*f763b8ceSMatthias Ringwald /** @defgroup CS43L22_Private_Defines
64*f763b8ceSMatthias Ringwald   * @{
65*f763b8ceSMatthias Ringwald   */
66*f763b8ceSMatthias Ringwald #define VOLUME_CONVERT(Volume)    (((Volume) > 100)? 100:((uint8_t)(((Volume) * 255) / 100)))
67*f763b8ceSMatthias Ringwald /* Uncomment this line to enable verifying data sent to codec after each write
68*f763b8ceSMatthias Ringwald    operation (for debug purpose) */
69*f763b8ceSMatthias Ringwald #if !defined (VERIFY_WRITTENDATA)
70*f763b8ceSMatthias Ringwald /* #define VERIFY_WRITTENDATA */
71*f763b8ceSMatthias Ringwald #endif /* VERIFY_WRITTENDATA */
72*f763b8ceSMatthias Ringwald /**
73*f763b8ceSMatthias Ringwald   * @}
74*f763b8ceSMatthias Ringwald   */
75*f763b8ceSMatthias Ringwald 
76*f763b8ceSMatthias Ringwald /** @defgroup CS43L22_Private_Macros
77*f763b8ceSMatthias Ringwald   * @{
78*f763b8ceSMatthias Ringwald   */
79*f763b8ceSMatthias Ringwald 
80*f763b8ceSMatthias Ringwald /**
81*f763b8ceSMatthias Ringwald   * @}
82*f763b8ceSMatthias Ringwald   */
83*f763b8ceSMatthias Ringwald 
84*f763b8ceSMatthias Ringwald /** @defgroup CS43L22_Private_Variables
85*f763b8ceSMatthias Ringwald   * @{
86*f763b8ceSMatthias Ringwald   */
87*f763b8ceSMatthias Ringwald 
88*f763b8ceSMatthias Ringwald /* Audio codec driver structure initialization */
89*f763b8ceSMatthias Ringwald AUDIO_DrvTypeDef cs43l22_drv =
90*f763b8ceSMatthias Ringwald {
91*f763b8ceSMatthias Ringwald   cs43l22_Init,
92*f763b8ceSMatthias Ringwald   cs43l22_DeInit,
93*f763b8ceSMatthias Ringwald   cs43l22_ReadID,
94*f763b8ceSMatthias Ringwald 
95*f763b8ceSMatthias Ringwald   cs43l22_Play,
96*f763b8ceSMatthias Ringwald   cs43l22_Pause,
97*f763b8ceSMatthias Ringwald   cs43l22_Resume,
98*f763b8ceSMatthias Ringwald   cs43l22_Stop,
99*f763b8ceSMatthias Ringwald 
100*f763b8ceSMatthias Ringwald   cs43l22_SetFrequency,
101*f763b8ceSMatthias Ringwald   cs43l22_SetVolume,
102*f763b8ceSMatthias Ringwald   cs43l22_SetMute,
103*f763b8ceSMatthias Ringwald   cs43l22_SetOutputMode,
104*f763b8ceSMatthias Ringwald   cs43l22_Reset,
105*f763b8ceSMatthias Ringwald };
106*f763b8ceSMatthias Ringwald 
107*f763b8ceSMatthias Ringwald static uint8_t Is_cs43l22_Stop = 1;
108*f763b8ceSMatthias Ringwald 
109*f763b8ceSMatthias Ringwald volatile uint8_t OutputDev = 0;
110*f763b8ceSMatthias Ringwald 
111*f763b8ceSMatthias Ringwald /**
112*f763b8ceSMatthias Ringwald   * @}
113*f763b8ceSMatthias Ringwald   */
114*f763b8ceSMatthias Ringwald 
115*f763b8ceSMatthias Ringwald /** @defgroup CS43L22_Function_Prototypes
116*f763b8ceSMatthias Ringwald   * @{
117*f763b8ceSMatthias Ringwald   */
118*f763b8ceSMatthias Ringwald static uint8_t CODEC_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value);
119*f763b8ceSMatthias Ringwald /**
120*f763b8ceSMatthias Ringwald   * @}
121*f763b8ceSMatthias Ringwald   */
122*f763b8ceSMatthias Ringwald 
123*f763b8ceSMatthias Ringwald /** @defgroup CS43L22_Private_Functions
124*f763b8ceSMatthias Ringwald   * @{
125*f763b8ceSMatthias Ringwald   */
126*f763b8ceSMatthias Ringwald 
127*f763b8ceSMatthias Ringwald /**
128*f763b8ceSMatthias Ringwald   * @brief Initializes the audio codec and the control interface.
129*f763b8ceSMatthias Ringwald   * @param DeviceAddr: Device address on communication Bus.
130*f763b8ceSMatthias Ringwald   * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
131*f763b8ceSMatthias Ringwald   *                       OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO .
132*f763b8ceSMatthias Ringwald   * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
133*f763b8ceSMatthias Ringwald   * @retval 0 if correct communication, else wrong communication
134*f763b8ceSMatthias Ringwald   */
cs43l22_Init(uint16_t DeviceAddr,uint16_t OutputDevice,uint8_t Volume,uint32_t AudioFreq)135*f763b8ceSMatthias Ringwald uint32_t cs43l22_Init(uint16_t DeviceAddr, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
136*f763b8ceSMatthias Ringwald {
137*f763b8ceSMatthias Ringwald   uint32_t counter = 0;
138*f763b8ceSMatthias Ringwald 
139*f763b8ceSMatthias Ringwald   /* Initialize the Control interface of the Audio Codec */
140*f763b8ceSMatthias Ringwald   AUDIO_IO_Init();
141*f763b8ceSMatthias Ringwald 
142*f763b8ceSMatthias Ringwald   /* Keep Codec powered OFF */
143*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL1, 0x01);
144*f763b8ceSMatthias Ringwald 
145*f763b8ceSMatthias Ringwald   /*Save Output device for mute ON/OFF procedure*/
146*f763b8ceSMatthias Ringwald   switch (OutputDevice)
147*f763b8ceSMatthias Ringwald   {
148*f763b8ceSMatthias Ringwald   case OUTPUT_DEVICE_SPEAKER:
149*f763b8ceSMatthias Ringwald     OutputDev = 0xFA;
150*f763b8ceSMatthias Ringwald     break;
151*f763b8ceSMatthias Ringwald 
152*f763b8ceSMatthias Ringwald   case OUTPUT_DEVICE_HEADPHONE:
153*f763b8ceSMatthias Ringwald     OutputDev = 0xAF;
154*f763b8ceSMatthias Ringwald     break;
155*f763b8ceSMatthias Ringwald 
156*f763b8ceSMatthias Ringwald   case OUTPUT_DEVICE_BOTH:
157*f763b8ceSMatthias Ringwald     OutputDev = 0xAA;
158*f763b8ceSMatthias Ringwald     break;
159*f763b8ceSMatthias Ringwald 
160*f763b8ceSMatthias Ringwald   case OUTPUT_DEVICE_AUTO:
161*f763b8ceSMatthias Ringwald     OutputDev = 0x05;
162*f763b8ceSMatthias Ringwald     break;
163*f763b8ceSMatthias Ringwald 
164*f763b8ceSMatthias Ringwald   default:
165*f763b8ceSMatthias Ringwald     OutputDev = 0x05;
166*f763b8ceSMatthias Ringwald     break;
167*f763b8ceSMatthias Ringwald   }
168*f763b8ceSMatthias Ringwald 
169*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, OutputDev);
170*f763b8ceSMatthias Ringwald 
171*f763b8ceSMatthias Ringwald   /* Clock configuration: Auto detection */
172*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_CLOCKING_CTL, 0x81);
173*f763b8ceSMatthias Ringwald 
174*f763b8ceSMatthias Ringwald   /* Set the Slave Mode and the audio Standard */
175*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_INTERFACE_CTL1, CODEC_STANDARD);
176*f763b8ceSMatthias Ringwald 
177*f763b8ceSMatthias Ringwald   /* Set the Master volume */
178*f763b8ceSMatthias Ringwald   counter += cs43l22_SetVolume(DeviceAddr, Volume);
179*f763b8ceSMatthias Ringwald 
180*f763b8ceSMatthias Ringwald   /* If the Speaker is enabled, set the Mono mode and volume attenuation level */
181*f763b8ceSMatthias Ringwald   if(OutputDevice != OUTPUT_DEVICE_HEADPHONE)
182*f763b8ceSMatthias Ringwald   {
183*f763b8ceSMatthias Ringwald     /* Set the Speaker Mono mode */
184*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_PLAYBACK_CTL2, 0x06);
185*f763b8ceSMatthias Ringwald 
186*f763b8ceSMatthias Ringwald     /* Set the Speaker attenuation level */
187*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_SPEAKER_A_VOL, 0x00);
188*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_SPEAKER_B_VOL, 0x00);
189*f763b8ceSMatthias Ringwald   }
190*f763b8ceSMatthias Ringwald 
191*f763b8ceSMatthias Ringwald   /* Additional configuration for the CODEC. These configurations are done to reduce
192*f763b8ceSMatthias Ringwald   the time needed for the Codec to power off. If these configurations are removed,
193*f763b8ceSMatthias Ringwald   then a long delay should be added between powering off the Codec and switching
194*f763b8ceSMatthias Ringwald   off the I2S peripheral MCLK clock (which is the operating clock for Codec).
195*f763b8ceSMatthias Ringwald   If this delay is not inserted, then the codec will not shut down properly and
196*f763b8ceSMatthias Ringwald   it results in high noise after shut down. */
197*f763b8ceSMatthias Ringwald 
198*f763b8ceSMatthias Ringwald   /* Disable the analog soft ramp */
199*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_ANALOG_ZC_SR_SETT, 0x00);
200*f763b8ceSMatthias Ringwald   /* Disable the digital soft ramp */
201*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MISC_CTL, 0x04);
202*f763b8ceSMatthias Ringwald   /* Disable the limiter attack level */
203*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_LIMIT_CTL1, 0x00);
204*f763b8ceSMatthias Ringwald   /* Adjust Bass and Treble levels */
205*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_TONE_CTL, 0x0F);
206*f763b8ceSMatthias Ringwald   /* Adjust PCM volume level */
207*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_PCMA_VOL, 0x0A);
208*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_PCMB_VOL, 0x0A);
209*f763b8ceSMatthias Ringwald 
210*f763b8ceSMatthias Ringwald   /* Return communication control value */
211*f763b8ceSMatthias Ringwald   return counter;
212*f763b8ceSMatthias Ringwald }
213*f763b8ceSMatthias Ringwald 
214*f763b8ceSMatthias Ringwald /**
215*f763b8ceSMatthias Ringwald   * @brief  Deinitializes the audio codec.
216*f763b8ceSMatthias Ringwald   * @param  None
217*f763b8ceSMatthias Ringwald   * @retval  None
218*f763b8ceSMatthias Ringwald   */
cs43l22_DeInit(void)219*f763b8ceSMatthias Ringwald void cs43l22_DeInit(void)
220*f763b8ceSMatthias Ringwald {
221*f763b8ceSMatthias Ringwald   /* Deinitialize Audio Codec interface */
222*f763b8ceSMatthias Ringwald   AUDIO_IO_DeInit();
223*f763b8ceSMatthias Ringwald }
224*f763b8ceSMatthias Ringwald 
225*f763b8ceSMatthias Ringwald /**
226*f763b8ceSMatthias Ringwald   * @brief  Get the CS43L22 ID.
227*f763b8ceSMatthias Ringwald   * @param DeviceAddr: Device address on communication Bus.
228*f763b8ceSMatthias Ringwald   * @retval The CS43L22 ID
229*f763b8ceSMatthias Ringwald   */
cs43l22_ReadID(uint16_t DeviceAddr)230*f763b8ceSMatthias Ringwald uint32_t cs43l22_ReadID(uint16_t DeviceAddr)
231*f763b8ceSMatthias Ringwald {
232*f763b8ceSMatthias Ringwald   uint8_t Value;
233*f763b8ceSMatthias Ringwald   /* Initialize the Control interface of the Audio Codec */
234*f763b8ceSMatthias Ringwald   AUDIO_IO_Init();
235*f763b8ceSMatthias Ringwald 
236*f763b8ceSMatthias Ringwald   Value = AUDIO_IO_Read(DeviceAddr, CS43L22_CHIPID_ADDR);
237*f763b8ceSMatthias Ringwald   Value = (Value & CS43L22_ID_MASK);
238*f763b8ceSMatthias Ringwald 
239*f763b8ceSMatthias Ringwald   return((uint32_t) Value);
240*f763b8ceSMatthias Ringwald }
241*f763b8ceSMatthias Ringwald 
242*f763b8ceSMatthias Ringwald /**
243*f763b8ceSMatthias Ringwald   * @brief Start the audio Codec play feature.
244*f763b8ceSMatthias Ringwald   * @note For this codec no Play options are required.
245*f763b8ceSMatthias Ringwald   * @param DeviceAddr: Device address on communication Bus.
246*f763b8ceSMatthias Ringwald   * @retval 0 if correct communication, else wrong communication
247*f763b8ceSMatthias Ringwald   */
cs43l22_Play(uint16_t DeviceAddr,uint16_t * pBuffer,uint16_t Size)248*f763b8ceSMatthias Ringwald uint32_t cs43l22_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size)
249*f763b8ceSMatthias Ringwald {
250*f763b8ceSMatthias Ringwald   uint32_t counter = 0;
251*f763b8ceSMatthias Ringwald 
252*f763b8ceSMatthias Ringwald   if(Is_cs43l22_Stop == 1)
253*f763b8ceSMatthias Ringwald   {
254*f763b8ceSMatthias Ringwald     /* Enable the digital soft ramp */
255*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MISC_CTL, 0x06);
256*f763b8ceSMatthias Ringwald 
257*f763b8ceSMatthias Ringwald     /* Enable Output device */
258*f763b8ceSMatthias Ringwald     counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
259*f763b8ceSMatthias Ringwald 
260*f763b8ceSMatthias Ringwald     /* Power on the Codec */
261*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL1, 0x9E);
262*f763b8ceSMatthias Ringwald     Is_cs43l22_Stop = 0;
263*f763b8ceSMatthias Ringwald   }
264*f763b8ceSMatthias Ringwald 
265*f763b8ceSMatthias Ringwald   /* Return communication control value */
266*f763b8ceSMatthias Ringwald   return counter;
267*f763b8ceSMatthias Ringwald }
268*f763b8ceSMatthias Ringwald 
269*f763b8ceSMatthias Ringwald /**
270*f763b8ceSMatthias Ringwald   * @brief Pauses playing on the audio codec.
271*f763b8ceSMatthias Ringwald   * @param DeviceAddr: Device address on communication Bus.
272*f763b8ceSMatthias Ringwald   * @retval 0 if correct communication, else wrong communication
273*f763b8ceSMatthias Ringwald   */
cs43l22_Pause(uint16_t DeviceAddr)274*f763b8ceSMatthias Ringwald uint32_t cs43l22_Pause(uint16_t DeviceAddr)
275*f763b8ceSMatthias Ringwald {
276*f763b8ceSMatthias Ringwald   uint32_t counter = 0;
277*f763b8ceSMatthias Ringwald 
278*f763b8ceSMatthias Ringwald   /* Pause the audio file playing */
279*f763b8ceSMatthias Ringwald   /* Mute the output first */
280*f763b8ceSMatthias Ringwald   counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_ON);
281*f763b8ceSMatthias Ringwald 
282*f763b8ceSMatthias Ringwald   /* Put the Codec in Power save mode */
283*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL1, 0x01);
284*f763b8ceSMatthias Ringwald 
285*f763b8ceSMatthias Ringwald   return counter;
286*f763b8ceSMatthias Ringwald }
287*f763b8ceSMatthias Ringwald 
288*f763b8ceSMatthias Ringwald /**
289*f763b8ceSMatthias Ringwald   * @brief Resumes playing on the audio codec.
290*f763b8ceSMatthias Ringwald   * @param DeviceAddr: Device address on communication Bus.
291*f763b8ceSMatthias Ringwald   * @retval 0 if correct communication, else wrong communication
292*f763b8ceSMatthias Ringwald   */
cs43l22_Resume(uint16_t DeviceAddr)293*f763b8ceSMatthias Ringwald uint32_t cs43l22_Resume(uint16_t DeviceAddr)
294*f763b8ceSMatthias Ringwald {
295*f763b8ceSMatthias Ringwald   uint32_t counter = 0;
296*f763b8ceSMatthias Ringwald   volatile uint32_t index = 0x00;
297*f763b8ceSMatthias Ringwald   /* Resumes the audio file playing */
298*f763b8ceSMatthias Ringwald   /* Unmute the output first */
299*f763b8ceSMatthias Ringwald   counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
300*f763b8ceSMatthias Ringwald 
301*f763b8ceSMatthias Ringwald   for(index = 0x00; index < 0xFF; index++);
302*f763b8ceSMatthias Ringwald 
303*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, OutputDev);
304*f763b8ceSMatthias Ringwald 
305*f763b8ceSMatthias Ringwald   /* Exit the Power save mode */
306*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL1, 0x9E);
307*f763b8ceSMatthias Ringwald 
308*f763b8ceSMatthias Ringwald   return counter;
309*f763b8ceSMatthias Ringwald }
310*f763b8ceSMatthias Ringwald 
311*f763b8ceSMatthias Ringwald /**
312*f763b8ceSMatthias Ringwald   * @brief Stops audio Codec playing. It powers down the codec.
313*f763b8ceSMatthias Ringwald   * @param DeviceAddr: Device address on communication Bus.
314*f763b8ceSMatthias Ringwald   * @param CodecPdwnMode: selects the  power down mode.
315*f763b8ceSMatthias Ringwald   *          - CODEC_PDWN_HW: Physically power down the codec. When resuming from this
316*f763b8ceSMatthias Ringwald   *                           mode, the codec is set to default configuration
317*f763b8ceSMatthias Ringwald   *                           (user should re-Initialize the codec in order to
318*f763b8ceSMatthias Ringwald   *                            play again the audio stream).
319*f763b8ceSMatthias Ringwald   * @retval 0 if correct communication, else wrong communication
320*f763b8ceSMatthias Ringwald   */
cs43l22_Stop(uint16_t DeviceAddr,uint32_t CodecPdwnMode)321*f763b8ceSMatthias Ringwald uint32_t cs43l22_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode)
322*f763b8ceSMatthias Ringwald {
323*f763b8ceSMatthias Ringwald   uint32_t counter = 0;
324*f763b8ceSMatthias Ringwald 
325*f763b8ceSMatthias Ringwald   /* Mute the output first */
326*f763b8ceSMatthias Ringwald   counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_ON);
327*f763b8ceSMatthias Ringwald 
328*f763b8ceSMatthias Ringwald   /* Disable the digital soft ramp */
329*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MISC_CTL, 0x04);
330*f763b8ceSMatthias Ringwald 
331*f763b8ceSMatthias Ringwald   /* Power down the DAC and the speaker (PMDAC and PMSPK bits)*/
332*f763b8ceSMatthias Ringwald   counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL1, 0x9F);
333*f763b8ceSMatthias Ringwald 
334*f763b8ceSMatthias Ringwald   Is_cs43l22_Stop = 1;
335*f763b8ceSMatthias Ringwald   return counter;
336*f763b8ceSMatthias Ringwald }
337*f763b8ceSMatthias Ringwald 
338*f763b8ceSMatthias Ringwald /**
339*f763b8ceSMatthias Ringwald   * @brief Sets higher or lower the codec volume level.
340*f763b8ceSMatthias Ringwald   * @param DeviceAddr: Device address on communication Bus.
341*f763b8ceSMatthias Ringwald   * @param Volume: a byte value from 0 to 255 (refer to codec registers
342*f763b8ceSMatthias Ringwald   *         description for more details).
343*f763b8ceSMatthias Ringwald   * @retval 0 if correct communication, else wrong communication
344*f763b8ceSMatthias Ringwald   */
cs43l22_SetVolume(uint16_t DeviceAddr,uint8_t Volume)345*f763b8ceSMatthias Ringwald uint32_t cs43l22_SetVolume(uint16_t DeviceAddr, uint8_t Volume)
346*f763b8ceSMatthias Ringwald {
347*f763b8ceSMatthias Ringwald   uint32_t counter = 0;
348*f763b8ceSMatthias Ringwald   uint8_t convertedvol = VOLUME_CONVERT(Volume);
349*f763b8ceSMatthias Ringwald 
350*f763b8ceSMatthias Ringwald   if(Volume > 0xE6)
351*f763b8ceSMatthias Ringwald   {
352*f763b8ceSMatthias Ringwald     /* Set the Master volume */
353*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MASTER_A_VOL, convertedvol - 0xE7);
354*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MASTER_B_VOL, convertedvol - 0xE7);
355*f763b8ceSMatthias Ringwald   }
356*f763b8ceSMatthias Ringwald   else
357*f763b8ceSMatthias Ringwald   {
358*f763b8ceSMatthias Ringwald     /* Set the Master volume */
359*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MASTER_A_VOL, convertedvol + 0x19);
360*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MASTER_B_VOL, convertedvol + 0x19);
361*f763b8ceSMatthias Ringwald   }
362*f763b8ceSMatthias Ringwald 
363*f763b8ceSMatthias Ringwald   return counter;
364*f763b8ceSMatthias Ringwald }
365*f763b8ceSMatthias Ringwald 
366*f763b8ceSMatthias Ringwald /**
367*f763b8ceSMatthias Ringwald   * @brief Sets new frequency.
368*f763b8ceSMatthias Ringwald   * @param DeviceAddr: Device address on communication Bus.
369*f763b8ceSMatthias Ringwald   * @param AudioFreq: Audio frequency used to play the audio stream.
370*f763b8ceSMatthias Ringwald   * @retval 0 if correct communication, else wrong communication
371*f763b8ceSMatthias Ringwald   */
cs43l22_SetFrequency(uint16_t DeviceAddr,uint32_t AudioFreq)372*f763b8ceSMatthias Ringwald uint32_t cs43l22_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq)
373*f763b8ceSMatthias Ringwald {
374*f763b8ceSMatthias Ringwald   return 0;
375*f763b8ceSMatthias Ringwald }
376*f763b8ceSMatthias Ringwald 
377*f763b8ceSMatthias Ringwald /**
378*f763b8ceSMatthias Ringwald   * @brief Enables or disables the mute feature on the audio codec.
379*f763b8ceSMatthias Ringwald   * @param DeviceAddr: Device address on communication Bus.
380*f763b8ceSMatthias Ringwald   * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the
381*f763b8ceSMatthias Ringwald   *             mute mode.
382*f763b8ceSMatthias Ringwald   * @retval 0 if correct communication, else wrong communication
383*f763b8ceSMatthias Ringwald   */
cs43l22_SetMute(uint16_t DeviceAddr,uint32_t Cmd)384*f763b8ceSMatthias Ringwald uint32_t cs43l22_SetMute(uint16_t DeviceAddr, uint32_t Cmd)
385*f763b8ceSMatthias Ringwald {
386*f763b8ceSMatthias Ringwald   uint32_t counter = 0;
387*f763b8ceSMatthias Ringwald 
388*f763b8ceSMatthias Ringwald   /* Set the Mute mode */
389*f763b8ceSMatthias Ringwald   if(Cmd == AUDIO_MUTE_ON)
390*f763b8ceSMatthias Ringwald   {
391*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0xFF);
392*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_HEADPHONE_A_VOL, 0x01);
393*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_HEADPHONE_B_VOL, 0x01);
394*f763b8ceSMatthias Ringwald   }
395*f763b8ceSMatthias Ringwald   else /* AUDIO_MUTE_OFF Disable the Mute */
396*f763b8ceSMatthias Ringwald   {
397*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_HEADPHONE_A_VOL, 0x00);
398*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_HEADPHONE_B_VOL, 0x00);
399*f763b8ceSMatthias Ringwald     counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, OutputDev);
400*f763b8ceSMatthias Ringwald   }
401*f763b8ceSMatthias Ringwald   return counter;
402*f763b8ceSMatthias Ringwald }
403*f763b8ceSMatthias Ringwald 
404*f763b8ceSMatthias Ringwald /**
405*f763b8ceSMatthias Ringwald   * @brief Switch dynamically (while audio file is played) the output target
406*f763b8ceSMatthias Ringwald   *         (speaker or headphone).
407*f763b8ceSMatthias Ringwald   * @note This function modifies a global variable of the audio codec driver: OutputDev.
408*f763b8ceSMatthias Ringwald   * @param DeviceAddr: Device address on communication Bus.
409*f763b8ceSMatthias Ringwald   * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER,
410*f763b8ceSMatthias Ringwald   *         OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO
411*f763b8ceSMatthias Ringwald   * @retval 0 if correct communication, else wrong communication
412*f763b8ceSMatthias Ringwald   */
cs43l22_SetOutputMode(uint16_t DeviceAddr,uint8_t Output)413*f763b8ceSMatthias Ringwald uint32_t cs43l22_SetOutputMode(uint16_t DeviceAddr, uint8_t Output)
414*f763b8ceSMatthias Ringwald {
415*f763b8ceSMatthias Ringwald   uint32_t counter = 0;
416*f763b8ceSMatthias Ringwald 
417*f763b8ceSMatthias Ringwald   switch (Output)
418*f763b8ceSMatthias Ringwald   {
419*f763b8ceSMatthias Ringwald     case OUTPUT_DEVICE_SPEAKER:
420*f763b8ceSMatthias Ringwald       counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0xFA); /* SPK always ON & HP always OFF */
421*f763b8ceSMatthias Ringwald       OutputDev = 0xFA;
422*f763b8ceSMatthias Ringwald       break;
423*f763b8ceSMatthias Ringwald 
424*f763b8ceSMatthias Ringwald     case OUTPUT_DEVICE_HEADPHONE:
425*f763b8ceSMatthias Ringwald       counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0xAF); /* SPK always OFF & HP always ON */
426*f763b8ceSMatthias Ringwald       OutputDev = 0xAF;
427*f763b8ceSMatthias Ringwald       break;
428*f763b8ceSMatthias Ringwald 
429*f763b8ceSMatthias Ringwald     case OUTPUT_DEVICE_BOTH:
430*f763b8ceSMatthias Ringwald       counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0xAA); /* SPK always ON & HP always ON */
431*f763b8ceSMatthias Ringwald       OutputDev = 0xAA;
432*f763b8ceSMatthias Ringwald       break;
433*f763b8ceSMatthias Ringwald 
434*f763b8ceSMatthias Ringwald     case OUTPUT_DEVICE_AUTO:
435*f763b8ceSMatthias Ringwald       counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0x05); /* Detect the HP or the SPK automatically */
436*f763b8ceSMatthias Ringwald       OutputDev = 0x05;
437*f763b8ceSMatthias Ringwald       break;
438*f763b8ceSMatthias Ringwald 
439*f763b8ceSMatthias Ringwald     default:
440*f763b8ceSMatthias Ringwald       counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0x05); /* Detect the HP or the SPK automatically */
441*f763b8ceSMatthias Ringwald       OutputDev = 0x05;
442*f763b8ceSMatthias Ringwald       break;
443*f763b8ceSMatthias Ringwald   }
444*f763b8ceSMatthias Ringwald   return counter;
445*f763b8ceSMatthias Ringwald }
446*f763b8ceSMatthias Ringwald 
447*f763b8ceSMatthias Ringwald /**
448*f763b8ceSMatthias Ringwald   * @brief Resets cs43l22 registers.
449*f763b8ceSMatthias Ringwald   * @param DeviceAddr: Device address on communication Bus.
450*f763b8ceSMatthias Ringwald   * @retval 0 if correct communication, else wrong communication
451*f763b8ceSMatthias Ringwald   */
cs43l22_Reset(uint16_t DeviceAddr)452*f763b8ceSMatthias Ringwald uint32_t cs43l22_Reset(uint16_t DeviceAddr)
453*f763b8ceSMatthias Ringwald {
454*f763b8ceSMatthias Ringwald   return 0;
455*f763b8ceSMatthias Ringwald }
456*f763b8ceSMatthias Ringwald 
457*f763b8ceSMatthias Ringwald /**
458*f763b8ceSMatthias Ringwald   * @brief  Writes/Read a single data.
459*f763b8ceSMatthias Ringwald   * @param  Addr: I2C address
460*f763b8ceSMatthias Ringwald   * @param  Reg: Reg address
461*f763b8ceSMatthias Ringwald   * @param  Value: Data to be written
462*f763b8ceSMatthias Ringwald   * @retval None
463*f763b8ceSMatthias Ringwald   */
CODEC_IO_Write(uint8_t Addr,uint8_t Reg,uint8_t Value)464*f763b8ceSMatthias Ringwald static uint8_t CODEC_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value)
465*f763b8ceSMatthias Ringwald {
466*f763b8ceSMatthias Ringwald   uint32_t result = 0;
467*f763b8ceSMatthias Ringwald 
468*f763b8ceSMatthias Ringwald   AUDIO_IO_Write(Addr, Reg, Value);
469*f763b8ceSMatthias Ringwald 
470*f763b8ceSMatthias Ringwald #ifdef VERIFY_WRITTENDATA
471*f763b8ceSMatthias Ringwald   /* Verify that the data has been correctly written */
472*f763b8ceSMatthias Ringwald   result = (AUDIO_IO_Read(Addr, Reg) == Value)? 0:1;
473*f763b8ceSMatthias Ringwald #endif /* VERIFY_WRITTENDATA */
474*f763b8ceSMatthias Ringwald 
475*f763b8ceSMatthias Ringwald   return result;
476*f763b8ceSMatthias Ringwald }
477*f763b8ceSMatthias Ringwald 
478*f763b8ceSMatthias Ringwald /**
479*f763b8ceSMatthias Ringwald   * @}
480*f763b8ceSMatthias Ringwald   */
481*f763b8ceSMatthias Ringwald 
482*f763b8ceSMatthias Ringwald /**
483*f763b8ceSMatthias Ringwald   * @}
484*f763b8ceSMatthias Ringwald   */
485*f763b8ceSMatthias Ringwald 
486*f763b8ceSMatthias Ringwald /**
487*f763b8ceSMatthias Ringwald   * @}
488*f763b8ceSMatthias Ringwald   */
489*f763b8ceSMatthias Ringwald 
490*f763b8ceSMatthias Ringwald /**
491*f763b8ceSMatthias Ringwald   * @}
492*f763b8ceSMatthias Ringwald   */
493*f763b8ceSMatthias Ringwald 
494*f763b8ceSMatthias Ringwald /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
495