1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2019 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_sgtl5000.h"
10 
11 /*******************************************************************************
12  * Definitations
13  ******************************************************************************/
14 
15 /*! @brief swap byte sequence in  16 bit data */
16 #define SGTL_SWAP_UINT16_BYTE_SEQUENCE(x) (__REV16(x))
17 
18 /*******************************************************************************
19  * Prototypes
20  ******************************************************************************/
21 
22 /*******************************************************************************
23  * Variables
24  ******************************************************************************/
25 
26 /*******************************************************************************
27  * Code
28  ******************************************************************************/
SGTL_Init(sgtl_handle_t * handle,sgtl_config_t * config)29 status_t SGTL_Init(sgtl_handle_t *handle, sgtl_config_t *config)
30 {
31     assert(handle != NULL);
32     assert(config != NULL);
33 
34     handle->config = config;
35     /* i2c bus initialization */
36     if (CODEC_I2C_Init(handle->i2cHandle, config->i2cConfig.codecI2CInstance, SGTL_I2C_BITRATE,
37                        config->i2cConfig.codecI2CSourceClock) != (status_t)kStatus_HAL_I2cSuccess)
38     {
39         return kStatus_Fail;
40     }
41 
42     if (SGTL_WriteReg(handle, CHIP_ANA_POWER, 0x6AFF) != kStatus_Success)
43     {
44         return kStatus_Fail;
45     }
46 
47     /* Set the data route */
48     if (SGTL_SetDataRoute(handle, config->route) != kStatus_Success)
49     {
50         return kStatus_Fail;
51     }
52 
53     /* Set sgtl5000 to master or slave */
54     SGTL_SetMasterSlave(handle, config->master_slave);
55 
56     /* Input Volume Control
57     Configure ADC left and right analog volume to desired default.
58     Example shows volume of 0dB. */
59     if (SGTL_WriteReg(handle, CHIP_ANA_ADC_CTRL, 0x0000U) != kStatus_Success)
60     {
61         return kStatus_Fail;
62     }
63 
64     /* Volume and Mute Control
65        Configure HP_OUT left and right volume to minimum, unmute.
66        HP_OUT and ramp the volume up to desired volume.*/
67     if (SGTL_WriteReg(handle, CHIP_ANA_HP_CTRL, 0x1818U) != kStatus_Success)
68     {
69         return kStatus_Fail;
70     }
71 
72     if (SGTL_ModifyReg(handle, CHIP_ANA_CTRL, 0xFFEFU, 0x0000U) != kStatus_Success)
73     {
74         return kStatus_Fail;
75     }
76 
77     /* LINEOUT and DAC volume control */
78     if (SGTL_ModifyReg(handle, CHIP_ANA_CTRL, 0xFEFFU, 0x0000U) != kStatus_Success)
79     {
80         return kStatus_Fail;
81     }
82 
83     /* Configure DAC left and right digital volume */
84     if (SGTL_WriteReg(handle, CHIP_DAC_VOL, 0x5C5CU) != kStatus_Success)
85     {
86         return kStatus_Fail;
87     }
88 
89     /* Configure ADC volume, reduce 6db. */
90     if (SGTL_WriteReg(handle, CHIP_ANA_ADC_CTRL, 0x0100U) != kStatus_Success)
91     {
92         return kStatus_Fail;
93     }
94 
95     /* Unmute DAC */
96     if (SGTL_ModifyReg(handle, CHIP_ADCDAC_CTRL, 0xFFFBU, 0x0000U) != kStatus_Success)
97     {
98         return kStatus_Fail;
99     }
100 
101     if (SGTL_ModifyReg(handle, CHIP_ADCDAC_CTRL, 0xFFF7U, 0x0000U) != kStatus_Success)
102     {
103         return kStatus_Fail;
104     }
105 
106     /* Unmute ADC */
107     if (SGTL_ModifyReg(handle, CHIP_ANA_CTRL, 0xFFFEU, 0x0000U) != kStatus_Success)
108     {
109         return kStatus_Fail;
110     }
111 
112     /* Set the audio format */
113     if (SGTL_SetProtocol(handle, config->bus) != kStatus_Success)
114     {
115         return kStatus_Fail;
116     }
117 
118     if (SGTL_ConfigDataFormat(handle, config->format.mclk_HZ, config->format.sampleRate, config->format.bitWidth) !=
119         kStatus_Success)
120     {
121         return kStatus_Fail;
122     }
123 
124     /* sclk valid edge */
125     if (config->format.sclkEdge == kSGTL_SclkValidEdgeRising)
126     {
127         if (SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_RISING_EDGE) !=
128             kStatus_Success)
129         {
130             return kStatus_Fail;
131         }
132     }
133     else
134     {
135         if (SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_FALLING_EDGE) !=
136             kStatus_Success)
137         {
138             return kStatus_Fail;
139         }
140     }
141 
142     return kStatus_Success;
143 }
144 
SGTL_Deinit(sgtl_handle_t * handle)145 status_t SGTL_Deinit(sgtl_handle_t *handle)
146 {
147     status_t ret = kStatus_Success;
148 
149     ret = SGTL_DisableModule(handle, kSGTL_ModuleADC);
150     ret = SGTL_DisableModule(handle, kSGTL_ModuleDAC);
151     ret = SGTL_DisableModule(handle, kSGTL_ModuleDAP);
152     ret = SGTL_DisableModule(handle, kSGTL_ModuleI2SIN);
153     ret = SGTL_DisableModule(handle, kSGTL_ModuleI2SOUT);
154     ret = SGTL_DisableModule(handle, kSGTL_ModuleLineOut);
155 
156     ret = CODEC_I2C_Deinit(handle->i2cHandle);
157 
158     return ret;
159 }
160 
SGTL_SetMasterSlave(sgtl_handle_t * handle,bool master)161 void SGTL_SetMasterSlave(sgtl_handle_t *handle, bool master)
162 {
163     if (master == true)
164     {
165         (void)SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_MS_CLR_MASK, SGTL5000_I2S_MASTER);
166     }
167     else
168     {
169         (void)SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_MS_CLR_MASK, SGTL5000_I2S_SLAVE);
170     }
171 }
172 
SGTL_EnableModule(sgtl_handle_t * handle,sgtl_module_t module)173 status_t SGTL_EnableModule(sgtl_handle_t *handle, sgtl_module_t module)
174 {
175     status_t ret = kStatus_Success;
176     switch (module)
177     {
178         case kSGTL_ModuleADC:
179             ret = SGTL_ModifyReg(handle, CHIP_DIG_POWER, SGTL5000_ADC_ENABLE_CLR_MASK,
180                                  ((uint16_t)1U << SGTL5000_ADC_ENABLE_SHIFT));
181             ret = SGTL_ModifyReg(handle, CHIP_ANA_POWER, SGTL5000_ADC_POWERUP_CLR_MASK,
182                                  ((uint16_t)1U << SGTL5000_ADC_POWERUP_SHIFT));
183             break;
184         case kSGTL_ModuleDAC:
185             ret = SGTL_ModifyReg(handle, CHIP_DIG_POWER, SGTL5000_DAC_ENABLE_CLR_MASK,
186                                  ((uint16_t)1U << SGTL5000_DAC_ENABLE_SHIFT));
187             ret = SGTL_ModifyReg(handle, CHIP_ANA_POWER, SGTL5000_DAC_POWERUP_CLR_MASK,
188                                  ((uint16_t)1U << SGTL5000_DAC_POWERUP_SHIFT));
189             break;
190         case kSGTL_ModuleDAP:
191             ret = SGTL_ModifyReg(handle, CHIP_DIG_POWER, SGTL5000_DAP_ENABLE_CLR_MASK,
192                                  ((uint16_t)1U << SGTL5000_DAP_ENABLE_SHIFT));
193             ret = SGTL_ModifyReg(handle, SGTL5000_DAP_CONTROL, SGTL5000_DAP_CONTROL_DAP_EN_CLR_MASK,
194                                  ((uint16_t)1U << SGTL5000_DAP_CONTROL_DAP_EN_SHIFT));
195             break;
196         case kSGTL_ModuleI2SIN:
197             ret = SGTL_ModifyReg(handle, CHIP_DIG_POWER, SGTL5000_I2S_IN_ENABLE_CLR_MASK,
198                                  ((uint16_t)1U << SGTL5000_I2S_IN_ENABLE_SHIFT));
199             break;
200         case kSGTL_ModuleI2SOUT:
201             ret = SGTL_ModifyReg(handle, CHIP_DIG_POWER, SGTL5000_I2S_OUT_ENABLE_CLR_MASK,
202                                  ((uint16_t)1U << SGTL5000_I2S_OUT_ENABLE_SHIFT));
203             break;
204         case kSGTL_ModuleHP:
205             ret = SGTL_ModifyReg(handle, CHIP_ANA_POWER, SGTL5000_HEADPHONE_POWERUP_CLR_MASK,
206                                  ((uint16_t)1U << SGTL5000_HEADPHONE_POWERUP_SHIFT));
207             break;
208         case kSGTL_ModuleLineOut:
209             ret = SGTL_ModifyReg(handle, CHIP_ANA_POWER, SGTL5000_LINEOUT_POWERUP_CLR_MASK,
210                                  ((uint16_t)1U << SGTL5000_LINEOUT_POWERUP_SHIFT));
211             break;
212         default:
213             ret = kStatus_InvalidArgument;
214             break;
215     }
216     return ret;
217 }
218 
SGTL_DisableModule(sgtl_handle_t * handle,sgtl_module_t module)219 status_t SGTL_DisableModule(sgtl_handle_t *handle, sgtl_module_t module)
220 {
221     status_t ret = kStatus_Success;
222     switch (module)
223     {
224         case kSGTL_ModuleADC:
225             ret = SGTL_ModifyReg(handle, CHIP_DIG_POWER, SGTL5000_ADC_ENABLE_CLR_MASK,
226                                  ((uint16_t)0U << SGTL5000_ADC_ENABLE_SHIFT));
227             ret = SGTL_ModifyReg(handle, CHIP_ANA_POWER, SGTL5000_ADC_POWERUP_CLR_MASK,
228                                  ((uint16_t)0U << SGTL5000_ADC_POWERUP_SHIFT));
229             break;
230         case kSGTL_ModuleDAC:
231             ret = SGTL_ModifyReg(handle, CHIP_DIG_POWER, SGTL5000_DAC_ENABLE_CLR_MASK,
232                                  ((uint16_t)0U << SGTL5000_DAC_ENABLE_SHIFT));
233             ret = SGTL_ModifyReg(handle, CHIP_ANA_POWER, SGTL5000_DAC_POWERUP_CLR_MASK,
234                                  ((uint16_t)0U << SGTL5000_DAC_POWERUP_SHIFT));
235             break;
236         case kSGTL_ModuleDAP:
237             ret = SGTL_ModifyReg(handle, CHIP_DIG_POWER, SGTL5000_DAP_ENABLE_CLR_MASK,
238                                  ((uint16_t)0U << SGTL5000_DAP_ENABLE_SHIFT));
239             ret = SGTL_ModifyReg(handle, SGTL5000_DAP_CONTROL, SGTL5000_DAP_CONTROL_DAP_EN_CLR_MASK,
240                                  ((uint16_t)0U << SGTL5000_DAP_CONTROL_DAP_EN_SHIFT));
241             break;
242         case kSGTL_ModuleI2SIN:
243             ret = SGTL_ModifyReg(handle, CHIP_DIG_POWER, SGTL5000_I2S_IN_ENABLE_CLR_MASK,
244                                  ((uint16_t)0U << SGTL5000_I2S_IN_ENABLE_SHIFT));
245             break;
246         case kSGTL_ModuleI2SOUT:
247             ret = SGTL_ModifyReg(handle, CHIP_DIG_POWER, SGTL5000_I2S_OUT_ENABLE_CLR_MASK,
248                                  ((uint16_t)0U << SGTL5000_I2S_OUT_ENABLE_SHIFT));
249             break;
250         case kSGTL_ModuleHP:
251             ret = SGTL_ModifyReg(handle, CHIP_ANA_POWER, SGTL5000_HEADPHONE_POWERUP_CLR_MASK,
252                                  ((uint16_t)0U << SGTL5000_HEADPHONE_POWERUP_SHIFT));
253             break;
254         case kSGTL_ModuleLineOut:
255             ret = SGTL_ModifyReg(handle, CHIP_ANA_POWER, SGTL5000_LINEOUT_POWERUP_CLR_MASK,
256                                  ((uint16_t)0U << SGTL5000_LINEOUT_POWERUP_SHIFT));
257             break;
258         default:
259             ret = kStatus_InvalidArgument;
260             break;
261     }
262     return ret;
263 }
264 
SGTL_SetDataRoute(sgtl_handle_t * handle,sgtl_route_t route)265 status_t SGTL_SetDataRoute(sgtl_handle_t *handle, sgtl_route_t route)
266 {
267     status_t ret = kStatus_Success;
268     switch (route)
269     {
270         case kSGTL_RouteBypass:
271             /* Bypass means from line-in to HP*/
272             ret = SGTL_WriteReg(handle, CHIP_DIG_POWER, 0x0000);
273             ret = SGTL_EnableModule(handle, kSGTL_ModuleHP);
274             ret = SGTL_ModifyReg(handle, CHIP_ANA_CTRL, SGTL5000_SEL_HP_CLR_MASK, SGTL5000_SEL_HP_LINEIN);
275             break;
276         case kSGTL_RoutePlayback:
277             /* Data route I2S_IN-> DAC-> HP */
278             ret = SGTL_EnableModule(handle, kSGTL_ModuleHP);
279             ret = SGTL_EnableModule(handle, kSGTL_ModuleDAC);
280             ret = SGTL_EnableModule(handle, kSGTL_ModuleI2SIN);
281             ret = SGTL_ModifyReg(handle, CHIP_SSS_CTRL, SGTL5000_DAC_SEL_CLR_MASK, SGTL5000_DAC_SEL_I2S_IN);
282             ret = SGTL_ModifyReg(handle, CHIP_ANA_CTRL, SGTL5000_SEL_HP_CLR_MASK, SGTL5000_SEL_HP_DAC);
283             break;
284         case kSGTL_RoutePlaybackandRecord:
285             /* I2S IN->DAC->HP  LINE_IN->ADC->I2S_OUT */
286             ret = SGTL_EnableModule(handle, kSGTL_ModuleHP);
287             ret = SGTL_EnableModule(handle, kSGTL_ModuleDAC);
288             ret = SGTL_EnableModule(handle, kSGTL_ModuleI2SIN);
289             ret = SGTL_EnableModule(handle, kSGTL_ModuleI2SOUT);
290             ret = SGTL_EnableModule(handle, kSGTL_ModuleADC);
291             ret = SGTL_ModifyReg(handle, CHIP_SSS_CTRL, SGTL5000_DAC_SEL_CLR_MASK, SGTL5000_DAC_SEL_I2S_IN);
292             ret = SGTL_ModifyReg(handle, CHIP_ANA_CTRL, SGTL5000_SEL_HP_CLR_MASK, SGTL5000_SEL_HP_DAC);
293             ret = SGTL_ModifyReg(handle, CHIP_ANA_CTRL, SGTL5000_SEL_ADC_CLR_MASK, SGTL5000_SEL_ADC_LINEIN);
294             ret = SGTL_ModifyReg(handle, CHIP_SSS_CTRL, SGTL5000_I2S_OUT_SEL_CLR_MASK, SGTL5000_I2S_OUT_SEL_ADC);
295             break;
296         case kSGTL_RoutePlaybackwithDAP:
297             /* I2S_IN->DAP->DAC->HP */
298             ret = SGTL_EnableModule(handle, kSGTL_ModuleHP);
299             ret = SGTL_EnableModule(handle, kSGTL_ModuleDAC);
300             ret = SGTL_EnableModule(handle, kSGTL_ModuleI2SIN);
301             ret = SGTL_EnableModule(handle, kSGTL_ModuleDAP);
302             ret = SGTL_ModifyReg(handle, CHIP_SSS_CTRL, SGTL5000_DAP_SEL_CLR_MASK, SGTL5000_DAP_SEL_I2S_IN);
303             ret = SGTL_ModifyReg(handle, CHIP_SSS_CTRL, SGTL5000_DAC_SEL_CLR_MASK, SGTL5000_DAC_SEL_DAP);
304             ret = SGTL_ModifyReg(handle, CHIP_ANA_CTRL, SGTL5000_SEL_HP_CLR_MASK, SGTL5000_SEL_HP_DAC);
305             break;
306         case kSGTL_RoutePlaybackwithDAPandRecord:
307             /* I2S_IN->DAP->DAC->HP,  LINE_IN->ADC->I2S_OUT */
308             ret = SGTL_EnableModule(handle, kSGTL_ModuleHP);
309             ret = SGTL_EnableModule(handle, kSGTL_ModuleDAC);
310             ret = SGTL_EnableModule(handle, kSGTL_ModuleI2SIN);
311             ret = SGTL_EnableModule(handle, kSGTL_ModuleI2SOUT);
312             ret = SGTL_EnableModule(handle, kSGTL_ModuleADC);
313             ret = SGTL_EnableModule(handle, kSGTL_ModuleDAP);
314             ret = SGTL_ModifyReg(handle, SGTL5000_DAP_CONTROL, SGTL5000_DAP_CONTROL_DAP_EN_CLR_MASK, 0x0001);
315             ret = SGTL_ModifyReg(handle, CHIP_SSS_CTRL, SGTL5000_DAP_SEL_CLR_MASK, SGTL5000_DAP_SEL_I2S_IN);
316             ret = SGTL_ModifyReg(handle, CHIP_SSS_CTRL, SGTL5000_DAC_SEL_CLR_MASK, SGTL5000_DAC_SEL_DAP);
317             ret = SGTL_ModifyReg(handle, CHIP_ANA_CTRL, SGTL5000_SEL_HP_CLR_MASK, SGTL5000_SEL_HP_DAC);
318             ret = SGTL_ModifyReg(handle, CHIP_ANA_CTRL, SGTL5000_SEL_ADC_CLR_MASK, SGTL5000_SEL_ADC_LINEIN);
319             ret = SGTL_ModifyReg(handle, CHIP_SSS_CTRL, SGTL5000_I2S_OUT_SEL_CLR_MASK, SGTL5000_I2S_OUT_SEL_ADC);
320             break;
321         case kSGTL_RouteRecord:
322             /* LINE_IN->ADC->I2S_OUT */
323             ret = SGTL_EnableModule(handle, kSGTL_ModuleI2SOUT);
324             ret = SGTL_EnableModule(handle, kSGTL_ModuleADC);
325             ret = SGTL_ModifyReg(handle, CHIP_ANA_CTRL, SGTL5000_SEL_ADC_CLR_MASK, SGTL5000_SEL_ADC_LINEIN);
326             ret = SGTL_ModifyReg(handle, CHIP_SSS_CTRL, SGTL5000_I2S_OUT_SEL_CLR_MASK, SGTL5000_I2S_OUT_SEL_ADC);
327             break;
328         default:
329             ret = kStatus_InvalidArgument;
330             break;
331     }
332     return ret;
333 }
334 
SGTL_SetProtocol(sgtl_handle_t * handle,sgtl_protocol_t protocol)335 status_t SGTL_SetProtocol(sgtl_handle_t *handle, sgtl_protocol_t protocol)
336 {
337     status_t ret = kStatus_Success;
338     switch (protocol)
339     {
340         case kSGTL_BusI2S:
341             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_MODE_CLR_MASK, SGTL5000_I2S_MODE_I2S_LJ);
342             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_LRALIGN_CLR_MASK, SGTL5000_I2S_ONE_BIT_DELAY);
343             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_RISING_EDGE);
344             break;
345         case kSGTL_BusLeftJustified:
346             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_MODE_CLR_MASK, SGTL5000_I2S_MODE_I2S_LJ);
347             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_LRALIGN_CLR_MASK, SGTL5000_I2S_NO_DELAY);
348             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_RISING_EDGE);
349             break;
350         case kSGTL_BusRightJustified:
351             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_MODE_CLR_MASK, SGTL5000_I2S_MODE_RJ);
352             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_RISING_EDGE);
353             break;
354         case kSGTL_BusPCMA:
355             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_MODE_CLR_MASK, SGTL5000_I2S_MODE_PCM);
356             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_LRALIGN_CLR_MASK, SGTL5000_I2S_ONE_BIT_DELAY);
357             ret =
358                 SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_FALLING_EDGE);
359             break;
360         case kSGTL_BusPCMB:
361             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_MODE_CLR_MASK, SGTL5000_I2S_MODE_PCM);
362             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_LRALIGN_CLR_MASK, SGTL5000_I2S_NO_DELAY);
363             ret =
364                 SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_FALLING_EDGE);
365             break;
366         default:
367             ret = kStatus_InvalidArgument;
368             break;
369     }
370     return ret;
371 }
372 
SGTL_SetVolume(sgtl_handle_t * handle,sgtl_module_t module,uint32_t volume)373 status_t SGTL_SetVolume(sgtl_handle_t *handle, sgtl_module_t module, uint32_t volume)
374 {
375     uint16_t vol = 0;
376     status_t ret = kStatus_Success;
377     switch (module)
378     {
379         case kSGTL_ModuleADC:
380             if (volume > SGTL5000_ADC_MAX_VOLUME_VALUE)
381             {
382                 return kStatus_InvalidArgument;
383             }
384 
385             vol = (uint16_t)(volume | (volume << 4U));
386             ret = SGTL_ModifyReg(handle, CHIP_ANA_ADC_CTRL,
387                                  SGTL5000_ADC_VOL_LEFT_CLR_MASK & SGTL5000_ADC_VOL_RIGHT_CLR_MASK, vol);
388             break;
389         case kSGTL_ModuleDAC:
390             if ((volume > SGTL5000_DAC_MAX_VOLUME_VALUE) || (volume < SGTL5000_DAC_MIN_VOLUME_VALUE))
391             {
392                 return kStatus_InvalidArgument;
393             }
394             vol = (uint16_t)(volume | (volume << 8U));
395             ret = SGTL_WriteReg(handle, CHIP_DAC_VOL, vol);
396             break;
397         case kSGTL_ModuleHP:
398             if (volume > SGTL5000_HEADPHONE_MAX_VOLUME_VALUE)
399             {
400                 return kStatus_InvalidArgument;
401             }
402             vol = (uint16_t)(volume | (volume << 8U));
403             ret = SGTL_WriteReg(handle, CHIP_ANA_HP_CTRL, vol);
404             break;
405         case kSGTL_ModuleLineOut:
406             if (volume > SGTL5000_LINE_OUT_MAX_VOLUME_VALUE)
407             {
408                 return kStatus_InvalidArgument;
409             }
410             vol = (uint16_t)(volume | (volume << 8U));
411             ret = SGTL_WriteReg(handle, CHIP_LINE_OUT_VOL, vol);
412             break;
413         default:
414             ret = kStatus_InvalidArgument;
415             break;
416     }
417     return ret;
418 }
419 
SGTL_GetVolume(sgtl_handle_t * handle,sgtl_module_t module)420 uint32_t SGTL_GetVolume(sgtl_handle_t *handle, sgtl_module_t module)
421 {
422     uint16_t vol = 0;
423     status_t ret = kStatus_Success;
424 
425     switch (module)
426     {
427         case kSGTL_ModuleADC:
428             ret = SGTL_ReadReg(handle, CHIP_ANA_ADC_CTRL, &vol);
429             vol = (vol & (uint16_t)SGTL5000_ADC_VOL_LEFT_GET_MASK) >> SGTL5000_ADC_VOL_LEFT_SHIFT;
430             break;
431         case kSGTL_ModuleDAC:
432             ret = SGTL_ReadReg(handle, CHIP_DAC_VOL, &vol);
433             vol = (vol & (uint16_t)SGTL5000_DAC_VOL_LEFT_GET_MASK) >> SGTL5000_DAC_VOL_LEFT_SHIFT;
434             break;
435         case kSGTL_ModuleHP:
436             ret = SGTL_ReadReg(handle, CHIP_ANA_HP_CTRL, &vol);
437             vol = (vol & (uint16_t)SGTL5000_HP_VOL_LEFT_GET_MASK) >> SGTL5000_HP_VOL_LEFT_SHIFT;
438             break;
439         case kSGTL_ModuleLineOut:
440             ret = SGTL_ReadReg(handle, CHIP_LINE_OUT_VOL, &vol);
441             vol = (vol & (uint16_t)SGTL5000_LINE_OUT_VOL_LEFT_GET_MASK) >> SGTL5000_LINE_OUT_VOL_LEFT_SHIFT;
442             break;
443         default:
444             vol = 0;
445             break;
446     }
447     return ret == kStatus_Success ? vol : 0U;
448 }
449 
SGTL_SetMute(sgtl_handle_t * handle,sgtl_module_t module,bool mute)450 status_t SGTL_SetMute(sgtl_handle_t *handle, sgtl_module_t module, bool mute)
451 {
452     status_t ret = kStatus_Success;
453     switch (module)
454     {
455         case kSGTL_ModuleADC:
456             ret = SGTL_ModifyReg(handle, CHIP_ANA_CTRL, SGTL5000_MUTE_ADC_CLR_MASK, mute ? 1U : 0U);
457             break;
458         case kSGTL_ModuleDAC:
459             if (mute)
460             {
461                 ret = SGTL_ModifyReg(handle, CHIP_ADCDAC_CTRL,
462                                      SGTL5000_DAC_MUTE_LEFT_CLR_MASK & SGTL5000_DAC_MUTE_RIGHT_CLR_MASK, 0x000C);
463             }
464             else
465             {
466                 ret = SGTL_ModifyReg(handle, CHIP_ADCDAC_CTRL,
467                                      SGTL5000_DAC_MUTE_LEFT_CLR_MASK & SGTL5000_DAC_MUTE_RIGHT_CLR_MASK, 0x0000);
468             }
469             break;
470         case kSGTL_ModuleHP:
471             ret = SGTL_ModifyReg(handle, CHIP_ANA_CTRL, SGTL5000_MUTE_HP_CLR_MASK,
472                                  ((uint16_t)mute << SGTL5000_MUTE_HP_SHIFT));
473             break;
474         case kSGTL_ModuleLineOut:
475             ret = SGTL_ModifyReg(handle, CHIP_ANA_CTRL, SGTL5000_MUTE_LO_CLR_MASK,
476                                  ((uint16_t)mute << SGTL5000_MUTE_LO_SHIFT));
477             break;
478         default:
479             ret = kStatus_InvalidArgument;
480             break;
481     }
482     return ret;
483 }
484 
SGTL_ConfigDataFormat(sgtl_handle_t * handle,uint32_t mclk,uint32_t sample_rate,uint32_t bits)485 status_t SGTL_ConfigDataFormat(sgtl_handle_t *handle, uint32_t mclk, uint32_t sample_rate, uint32_t bits)
486 {
487     uint16_t val     = 0;
488     uint16_t regVal  = 0;
489     uint16_t mul_clk = 0U;
490     uint32_t sysFs   = 0U;
491     status_t ret     = kStatus_Success;
492 
493     /* Over sample rate can only up to 512, the least to 8k */
494     if ((mclk / (MIN(sample_rate * 6U, 96000U)) > 512U) || (mclk / sample_rate < 256U))
495     {
496         return kStatus_InvalidArgument;
497     }
498 
499     /* Configure the sample rate */
500     switch (sample_rate)
501     {
502         case 8000:
503             if (mclk > 32000U * 512U)
504             {
505                 val   = 0x0038;
506                 sysFs = 48000;
507             }
508             else
509             {
510                 val   = 0x0020;
511                 sysFs = 32000;
512             }
513             break;
514         case 11025:
515             val   = 0x0024;
516             sysFs = 44100;
517             break;
518         case 12000:
519             val   = 0x0028;
520             sysFs = 48000;
521             break;
522         case 16000:
523             if (mclk > 32000U * 512U)
524             {
525                 val   = 0x003C;
526                 sysFs = 96000;
527             }
528             else
529             {
530                 val   = 0x0010;
531                 sysFs = 32000;
532             }
533             break;
534         case 22050:
535             val   = 0x0014;
536             sysFs = 44100;
537             break;
538         case 24000:
539             if (mclk > 48000U * 512U)
540             {
541                 val   = 0x002C;
542                 sysFs = 96000;
543             }
544             else
545             {
546                 val   = 0x0018;
547                 sysFs = 48000;
548             }
549             break;
550         case 32000:
551             val   = 0x0000;
552             sysFs = 32000;
553             break;
554         case 44100:
555             val   = 0x0004;
556             sysFs = 44100;
557             break;
558         case 48000:
559             if (mclk > 48000U * 512U)
560             {
561                 val   = 0x001C;
562                 sysFs = 96000;
563             }
564             else
565             {
566                 val   = 0x0008;
567                 sysFs = 48000;
568             }
569             break;
570         case 96000:
571             val   = 0x000C;
572             sysFs = 96000;
573             break;
574         default:
575             ret = kStatus_InvalidArgument;
576             break;
577     }
578 
579     if (ret != kStatus_Success)
580     {
581         return ret;
582     }
583 
584     if (SGTL_ReadReg(handle, CHIP_I2S_CTRL, &regVal) != kStatus_Success)
585     {
586         return kStatus_Fail;
587     }
588 
589     /* While as slave, Fs is input */
590     if ((regVal & SGTL5000_I2S_MS_GET_MASK) == 0U)
591     {
592         sysFs = sample_rate;
593     }
594     mul_clk = (uint16_t)(mclk / sysFs);
595     /* Configure the mul_clk. Sgtl-5000 only support 256, 384 and 512 oversample rate */
596     if ((mul_clk / 128U - 2U) > 2U)
597     {
598         return kStatus_InvalidArgument;
599     }
600     else
601     {
602         val |= (mul_clk / 128U - 2U);
603     }
604 
605     if (SGTL_WriteReg(handle, CHIP_CLK_CTRL, val) != kStatus_Success)
606     {
607         return kStatus_Fail;
608     }
609 
610     /* Data bits configure,sgtl supports 16bit, 20bit 24bit, 32bit */
611     if (SGTL_ModifyReg(handle, CHIP_I2S_CTRL, 0xFEFF, SGTL5000_I2S_SCLKFREQ_64FS) != kStatus_Success)
612     {
613         return kStatus_Fail;
614     }
615 
616     switch (bits)
617     {
618         case 16:
619             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_DLEN_CLR_MASK, SGTL5000_I2S_DLEN_16);
620             break;
621         case 20:
622             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_DLEN_CLR_MASK, SGTL5000_I2S_DLEN_20);
623             break;
624         case 24:
625             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_DLEN_CLR_MASK, SGTL5000_I2S_DLEN_24);
626             break;
627         case 32:
628             ret = SGTL_ModifyReg(handle, CHIP_I2S_CTRL, SGTL5000_I2S_DLEN_CLR_MASK, SGTL5000_I2S_DLEN_32);
629             break;
630         default:
631             ret = kStatus_InvalidArgument;
632             break;
633     }
634 
635     return ret;
636 }
637 
SGTL_SetPlay(sgtl_handle_t * handle,uint32_t playSource)638 status_t SGTL_SetPlay(sgtl_handle_t *handle, uint32_t playSource)
639 {
640     uint16_t regValue = 0U, regBitMask = 0x40U;
641 
642     /* headphone source form PGA */
643     if (playSource == (uint32_t)kSGTL_PlaySourceLineIn)
644     {
645         regValue = 0x40U;
646     }
647     /* headphone source from DAC */
648     else
649     {
650         regValue = 0U;
651     }
652 
653     return SGTL_ModifyReg(handle, CHIP_ANA_CTRL, regBitMask, regValue);
654 }
655 
SGTL_SetRecord(sgtl_handle_t * handle,uint32_t recordSource)656 status_t SGTL_SetRecord(sgtl_handle_t *handle, uint32_t recordSource)
657 {
658     uint16_t regValue = 0U, regBitMask = 0x4U;
659 
660     /* ADC source form LINEIN */
661     if (recordSource == (uint32_t)kSGTL_RecordSourceLineIn)
662     {
663         regValue = 0x4U;
664     }
665     /* ADC source from MIC */
666     else
667     {
668         regValue = 0U;
669     }
670 
671     return SGTL_ModifyReg(handle, CHIP_ANA_CTRL, regBitMask, regValue);
672 }
673 
SGTL_WriteReg(sgtl_handle_t * handle,uint16_t reg,uint16_t val)674 status_t SGTL_WriteReg(sgtl_handle_t *handle, uint16_t reg, uint16_t val)
675 {
676     uint16_t writeValue = (uint16_t)SGTL_SWAP_UINT16_BYTE_SEQUENCE(val);
677 
678     return CODEC_I2C_Send(handle->i2cHandle, handle->config->slaveAddress, reg, 2U, (uint8_t *)&writeValue, 2U);
679 }
680 
SGTL_ReadReg(sgtl_handle_t * handle,uint16_t reg,uint16_t * val)681 status_t SGTL_ReadReg(sgtl_handle_t *handle, uint16_t reg, uint16_t *val)
682 {
683     status_t retval = 0;
684 
685     uint16_t readValue = 0U;
686 
687     retval = CODEC_I2C_Receive(handle->i2cHandle, handle->config->slaveAddress, reg, 2U, (uint8_t *)&readValue, 2U);
688 
689     *val = (uint16_t)SGTL_SWAP_UINT16_BYTE_SEQUENCE(readValue);
690 
691     return retval;
692 }
693 
SGTL_ModifyReg(sgtl_handle_t * handle,uint16_t reg,uint16_t clr_mask,uint16_t val)694 status_t SGTL_ModifyReg(sgtl_handle_t *handle, uint16_t reg, uint16_t clr_mask, uint16_t val)
695 {
696     status_t retval = 0;
697     uint16_t reg_val;
698 
699     /* Read the register value out */
700     retval = SGTL_ReadReg(handle, reg, &reg_val);
701     if (retval != kStatus_Success)
702     {
703         return kStatus_Fail;
704     }
705 
706     /* Modify the value */
707     reg_val &= clr_mask;
708     reg_val |= val;
709 
710     /* Write the data to register */
711     retval = SGTL_WriteReg(handle, reg, reg_val);
712     if (retval != kStatus_Success)
713     {
714         return kStatus_Fail;
715     }
716 
717     return kStatus_Success;
718 }
719