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