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, ®Val) != 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, ®_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