1 /*
2  * Copyright 2018-2019 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_ak4497.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 
14 /*******************************************************************************
15  * Prototypes
16  ******************************************************************************/
17 
18 /*******************************************************************************
19  * Variables
20  ******************************************************************************/
21 
22 /*******************************************************************************
23  * Code
24  ******************************************************************************/
Delay(void)25 static void Delay(void)
26 {
27     uint32_t i;
28     for (i = 0; i < 1000U; i++)
29     {
30         __NOP();
31     }
32 }
33 
AK4497_DefaultConfig(ak4497_config_t * config)34 void AK4497_DefaultConfig(ak4497_config_t *config)
35 {
36     config->ak4497Mode      = kAK4497_PcmMode;
37     config->dataChannelMode = kAK4497_NormalMode;
38     /* PCM mode setting. */
39     config->pcmConfig.pcmSampleFreqMode = kAK4497_AutoSettingMode;
40     config->pcmConfig.pcmSdataFormat    = kAK4497_32BitI2S;
41     config->pcmConfig.pcmTdmMode        = kAK4497_Normal;
42     config->pcmConfig.pcmSdsSlot        = kAK4497_L1R1;
43     /* DSD mode setting. */
44     config->dsdConfig.dsdMclk         = kAK4497_mclk512fs;
45     config->dsdConfig.dsdPath         = kAK4497_Path1;
46     config->dsdConfig.dsdPlaybackPath = kAK4497_NormalPath;
47     config->dsdConfig.dsdDataMute     = kAK4497_DsdMuteDisable;
48     config->dsdConfig.dsdDclkPolarity = kAK4497_FallingEdge;
49 }
50 
AK4497_Init(ak4497_handle_t * handle,ak4497_config_t * config)51 status_t AK4497_Init(ak4497_handle_t *handle, ak4497_config_t *config)
52 {
53     assert(handle != NULL);
54     assert(config != NULL);
55     status_t ret = kStatus_Success;
56 
57     handle->config = config;
58 
59     /* i2c bus initialization */
60     if (CODEC_I2C_Init(handle->i2cHandle, config->i2cConfig.codecI2CInstance, AK4497_I2C_BITRATE,
61                        config->i2cConfig.codecI2CSourceClock) != (status_t)kStatus_HAL_I2cSuccess)
62     {
63         return kStatus_Fail;
64     }
65 
66     ret = AK4497_ModifyReg(handle, AK4497_CONTROL2, AK4497_CONTROL2_SMUTE_MASK,
67                            1U << AK4497_CONTROL2_SMUTE_SHIFT); /* Soft ware mute */
68 
69     ret = AK4497_ModifyReg(handle, AK4497_CONTROL1,
70                            AK4497_CONTROL1_DIF0_MASK | AK4497_CONTROL1_DIF1_MASK | AK4497_CONTROL1_DIF2_MASK,
71                            (uint8_t)config->pcmConfig.pcmSdataFormat << AK4497_CONTROL1_DIF0_SHIFT);
72     ret = AK4497_ModifyReg(handle, AK4497_CONTROL3, AK4497_CONTROL3_SELLR_MASK,
73                            (uint8_t)config->dataChannelMode << AK4497_CONTROL3_SELLR_SHIFT);
74     if (config->ak4497Mode == kAK4497_PcmMode) /* PCM mode*/
75     {
76         if (config->pcmConfig.pcmSampleFreqMode != kAK4497_ManualSettingMode)
77         {
78             if (config->pcmConfig.pcmSampleFreqMode == kAK4497_AutoSettingMode)
79             {
80                 ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_AFSD_MASK,
81                                        0U << AK4497_CONTROL1_AFSD_SHIFT); /*Auto setting mode*/
82                 ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_ACKS_MASK,
83                                        1U << AK4497_CONTROL1_ACKS_SHIFT);
84             }
85             else
86             {
87                 ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_AFSD_MASK,
88                                        1U << AK4497_CONTROL1_AFSD_SHIFT); /* Auto Detect mode*/
89                 ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_ACKS_MASK,
90                                        0U << AK4497_CONTROL1_ACKS_SHIFT);
91             }
92         }
93         ret = AK4497_ModifyReg(handle, AK4497_CONTROL7, AK4497_CONTROL7_TDM0_MASK | AK4497_CONTROL7_TDM1_MASK,
94                                (uint8_t)config->pcmConfig.pcmTdmMode << AK4497_CONTROL7_TDM0_SHIFT);
95         ret = AK4497_ModifyReg(handle, AK4497_CONTROL8, AK4497_CONTROL8_SDS0_MASK,
96                                ((uint8_t)config->pcmConfig.pcmSdsSlot & 0x1U) << AK4497_CONTROL8_SDS0_SHIFT);
97         ret = AK4497_ModifyReg(handle, AK4497_CONTROL7, AK4497_CONTROL7_SDS1_MASK,
98                                (((uint8_t)config->pcmConfig.pcmSdsSlot & 0x2U) >> 1U) << AK4497_CONTROL7_SDS1_SHIFT);
99         ret = AK4497_ModifyReg(handle, AK4497_CONTROL7, AK4497_CONTROL7_SDS2_MASK,
100                                (((uint8_t)config->pcmConfig.pcmSdsSlot & 0x4U) >> 2U) << AK4497_CONTROL7_SDS2_SHIFT);
101     }
102 
103     else if (config->ak4497Mode == kAK4497_DsdMode) /*DSD mode*/
104     {
105         ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_EXDF_MASK, 0U << AK4497_CONTROL1_EXDF_SHIFT);
106         ret = AK4497_ModifyReg(handle, AK4497_CONTROL3, AK4497_CONTROL3_DP_MASK, 1U << AK4497_CONTROL3_DP_SHIFT);
107         ret = AK4497_ModifyReg(handle, AK4497_CONTROL3, AK4497_CONTROL3_DCKS_MASK,
108                                (uint8_t)config->dsdConfig.dsdMclk << AK4497_CONTROL3_DCKS_SHIFT);
109         ret = AK4497_ModifyReg(handle, AK4497_DSD2, AK4497_DSD2_DSDPATH_MASK,
110                                (uint8_t)config->dsdConfig.dsdPath << AK4497_DSD2_DSDPATH_SHIFT);
111         ret = AK4497_ModifyReg(handle, AK4497_DSD1, AK4497_DSD1_DSDD_MASK,
112                                (uint8_t)config->dsdConfig.dsdPlaybackPath << AK4497_DSD1_DSDD_SHIFT);
113         ret = AK4497_ModifyReg(handle, AK4497_DSD1, AK4497_DSD1_DDM_MASK,
114                                (uint8_t)config->dsdConfig.dsdDataMute << AK4497_DSD1_DDM_SHIFT);
115         ret = AK4497_ModifyReg(handle, AK4497_CONTROL3, AK4497_CONTROL3_DCKB_MASK,
116                                (uint8_t)config->dsdConfig.dsdDclkPolarity << AK4497_CONTROL3_DCKB_SHIFT);
117     }
118     else /* EXDF mode*/
119     {
120         ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_EXDF_MASK, 1U << AK4497_CONTROL1_EXDF_SHIFT);
121         ret = AK4497_ModifyReg(handle, AK4497_CONTROL3, AK4497_CONTROL3_DP_MASK, 0U << AK4497_CONTROL3_DP_SHIFT);
122     }
123 
124     ret = AK4497_ModifyReg(handle, AK4497_CONTROL2, AK4497_CONTROL2_SMUTE_MASK,
125                            0U << AK4497_CONTROL2_SMUTE_SHIFT); /* Normal Operation */
126 
127     ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_RSTN_MASK,
128                            0U << AK4497_CONTROL1_RSTN_SHIFT); /* Rest the ak4497 */
129     Delay(); /* Need to wait to ensure the ak4497 has updated the above registers. */
130     ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_RSTN_MASK,
131                            1U << AK4497_CONTROL1_RSTN_SHIFT); /* Normal Operation */
132     Delay();
133 
134     return ret;
135 }
136 
AK4497_SetEncoding(ak4497_handle_t * handle,uint8_t format)137 status_t AK4497_SetEncoding(ak4497_handle_t *handle, uint8_t format)
138 {
139     ak4497_config_t *config = (ak4497_config_t *)handle->config;
140     status_t ret            = kStatus_Success;
141 
142     if (format == (uint8_t)kAK4497_DsdMode)
143     {
144         ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_EXDF_MASK, 0U << AK4497_CONTROL1_EXDF_SHIFT);
145         ret = AK4497_ModifyReg(handle, AK4497_CONTROL3, AK4497_CONTROL3_DP_MASK, 1U << AK4497_CONTROL3_DP_SHIFT);
146         ret = AK4497_ModifyReg(handle, AK4497_CONTROL3, AK4497_CONTROL3_DCKS_MASK,
147                                (uint8_t)config->dsdConfig.dsdMclk << AK4497_CONTROL3_DCKS_SHIFT);
148         ret = AK4497_ModifyReg(handle, AK4497_DSD2, AK4497_DSD2_DSDPATH_MASK,
149                                (uint8_t)config->dsdConfig.dsdPath << AK4497_DSD2_DSDPATH_SHIFT);
150         ret = AK4497_ModifyReg(handle, AK4497_DSD1, AK4497_DSD1_DSDD_MASK,
151                                (uint8_t)config->dsdConfig.dsdPlaybackPath << AK4497_DSD1_DSDD_SHIFT);
152         ret = AK4497_ModifyReg(handle, AK4497_DSD1, AK4497_DSD1_DDM_MASK,
153                                (uint8_t)config->dsdConfig.dsdDataMute << AK4497_DSD1_DDM_SHIFT);
154         ret = AK4497_ModifyReg(handle, AK4497_CONTROL3, AK4497_CONTROL3_DCKB_MASK,
155                                (uint8_t)config->dsdConfig.dsdDclkPolarity << AK4497_CONTROL3_DCKB_SHIFT);
156         config->ak4497Mode = kAK4497_DsdMode;
157     }
158 
159     if (format == (uint8_t)kAK4497_PcmMode)
160     {
161         ret = AK4497_ModifyReg(handle, AK4497_CONTROL7, AK4497_CONTROL7_TDM0_MASK | AK4497_CONTROL7_TDM1_MASK,
162                                (uint8_t)config->pcmConfig.pcmTdmMode << AK4497_CONTROL7_TDM0_SHIFT);
163         ret = AK4497_ModifyReg(handle, AK4497_CONTROL8, AK4497_CONTROL8_SDS0_MASK,
164                                ((uint8_t)config->pcmConfig.pcmSdsSlot & 0x1U) << AK4497_CONTROL8_SDS0_SHIFT);
165         ret = AK4497_ModifyReg(handle, AK4497_CONTROL7, AK4497_CONTROL7_SDS1_MASK,
166                                (((uint8_t)config->pcmConfig.pcmSdsSlot & 0x2U) >> 1U) << AK4497_CONTROL7_SDS1_SHIFT);
167         ret = AK4497_ModifyReg(handle, AK4497_CONTROL7, AK4497_CONTROL7_SDS2_MASK,
168                                (((uint8_t)config->pcmConfig.pcmSdsSlot & 0x4U) >> 2U) << AK4497_CONTROL7_SDS2_SHIFT);
169         ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_EXDF_MASK, 0U << AK4497_CONTROL1_EXDF_SHIFT);
170         ret = AK4497_ModifyReg(handle, AK4497_CONTROL3, AK4497_CONTROL3_DP_MASK, 0U << AK4497_CONTROL3_DP_SHIFT);
171 
172         config->ak4497Mode = kAK4497_PcmMode;
173     }
174 
175     return ret;
176 }
177 
AK4497_ConfigDataFormat(ak4497_handle_t * handle,uint32_t mclk,uint32_t sampleRate,uint32_t bitWidth)178 status_t AK4497_ConfigDataFormat(ak4497_handle_t *handle, uint32_t mclk, uint32_t sampleRate, uint32_t bitWidth)
179 {
180     ak4497_pcm_samplefreqselect_t samplefreq;
181     ak4497_dsd_dclk_t dsdsel;
182     ak4497_pcm_sdata_format_t sdataFormat;
183     ak4497_config_t *config = (ak4497_config_t *)handle->config;
184     status_t ret            = kStatus_Success;
185 
186     if (config->ak4497Mode == kAK4497_DsdMode)
187     {
188         switch (sampleRate * bitWidth)
189         {
190             case 2048000U:
191             case 2822400U:
192             case 3072000U:
193                 dsdsel = kAK4497_dclk64fs;
194                 break;
195             case 4096000U:
196             case 5644800U:
197             case 6144000U:
198                 dsdsel = kAK4497_dclk128fs;
199                 break;
200             case 8192000U:
201             case 11289600U:
202             case 12288000U:
203                 dsdsel = kAK4497_dclk256fs;
204                 break;
205             case 16284000U:
206             case 22579200U:
207             case 24576000U:
208                 dsdsel = kAK4497_dclk512fs;
209                 break;
210             default:
211                 ret = kStatus_Fail;
212                 break;
213         }
214 
215         if (ret != kStatus_Success)
216         {
217             return ret;
218         }
219 
220         ret = AK4497_ModifyReg(handle, AK4497_DSD1, AK4497_DSD1_DSDSEL0_MASK,
221                                ((uint8_t)dsdsel & 0x1U) << AK4497_DSD1_DSDSEL0_SHIFT); /* Set DSDSEL0 */
222         ret = AK4497_ModifyReg(handle, AK4497_DSD2, AK4497_DSD2_DSDSEL1_MASK,
223                                (((uint8_t)dsdsel & 0x2U) >> 1U) << AK4497_DSD2_DSDSEL1_SHIFT); /* Set DSDSEL1 */
224     }
225     else /* PCM mode */
226     {
227         switch (sampleRate)
228         {
229             case 8000U:
230             case 11025U:
231             case 16000U:
232             case 22050U:
233             case 32000U:
234             case 44100U:
235             case 48000U:
236                 samplefreq = kAK4497_NormalSpeed;
237                 break;
238             case 88200U:
239             case 96000U:
240                 samplefreq = kAK4497_DoubleSpeed;
241                 break;
242             case 176400U:
243             case 192000U:
244                 samplefreq = kAK4497_QuadSpeed;
245                 break;
246             case 352800U:
247             case 384000U:
248                 samplefreq = kAK4497_OctSpeed;
249                 break;
250             case 705600U:
251             case 768000U:
252                 samplefreq = kAK4497_HexSpeed;
253                 break;
254             default:
255                 ret = kStatus_Fail;
256                 break;
257         }
258 
259         if (ret != kStatus_Success)
260         {
261             return ret;
262         }
263 
264         switch (bitWidth)
265         {
266             /* For PCM, only strero mode supported. */
267             case 16U:
268             case 24U:
269                 sdataFormat = kAK4497_16_24BitI2S;
270                 break;
271             case 32U:
272                 sdataFormat = kAK4497_32BitI2S;
273                 break;
274             default:
275                 ret = kStatus_Fail;
276                 break;
277         }
278 
279         if (ret != kStatus_Success)
280         {
281             return ret;
282         }
283 
284         ret = AK4497_ModifyReg(handle, AK4497_CONTROL2, AK4497_CONTROL2_DFS0_MASK | AK4497_CONTROL2_DFS1_MASK,
285                                ((uint8_t)samplefreq & 0x3U) << AK4497_CONTROL2_DFS0_SHIFT); /* Set DFS[1:0] */
286         ret = AK4497_ModifyReg(handle, AK4497_CONTROL4, AK4497_CONTROL4_DFS2_MASK | AK4497_CONTROL4_DFS2_MASK,
287                                (((uint8_t)samplefreq & 0x4U) >> 2U) << AK4497_CONTROL4_DFS2_SHIFT); /* Set DFS[2] */
288         ret = AK4497_ModifyReg(handle, AK4497_CONTROL1,
289                                AK4497_CONTROL1_DIF0_MASK | AK4497_CONTROL1_DIF1_MASK | AK4497_CONTROL1_DIF2_MASK,
290                                (uint8_t)sdataFormat << AK4497_CONTROL1_DIF0_SHIFT);
291     }
292 
293     ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_RSTN_MASK,
294                            0U << AK4497_CONTROL1_RSTN_SHIFT); /* Rest the ak4497 */
295 
296     Delay();
297 
298     ret = AK4497_ModifyReg(handle, AK4497_CONTROL1, AK4497_CONTROL1_RSTN_MASK,
299                            1U << AK4497_CONTROL1_RSTN_SHIFT); /* Normal Operation */
300     Delay();
301 
302     return ret;
303 }
304 
AK4497_SetVolume(ak4497_handle_t * handle,uint8_t value)305 status_t AK4497_SetVolume(ak4497_handle_t *handle, uint8_t value)
306 {
307     status_t retval = kStatus_Success;
308     /*
309      * 255 levels, 0.5dB setp + mute (value = 0)
310      */
311     retval = AK4497_WriteReg(handle, AK4497_LCHATT, value);
312     retval = AK4497_WriteReg(handle, AK4497_RCHATT, value);
313 
314     return retval;
315 }
316 
AK4497_GetVolume(ak4497_handle_t * handle,uint8_t * value)317 status_t AK4497_GetVolume(ak4497_handle_t *handle, uint8_t *value)
318 {
319     status_t retval = kStatus_Success;
320     /*
321      * 255 levels, 0.5dB setp + mute (value = 0);
322      * R-channel volume regarded the same as the L-channel, here just read the L-channel value.
323      */
324     retval = AK4497_ReadReg(handle, AK4497_LCHATT, value);
325 
326     return retval;
327 }
328 
AK4497_Deinit(ak4497_handle_t * handle)329 status_t AK4497_Deinit(ak4497_handle_t *handle)
330 {
331     status_t ret = kStatus_Success;
332 
333     ret = AK4497_ModifyReg(handle, AK4497_CONTROL2, AK4497_CONTROL2_SMUTE_MASK,
334                            1U << AK4497_CONTROL2_SMUTE_SHIFT); /* Soft ware mute */
335 
336     ret = CODEC_I2C_Deinit(handle->i2cHandle);
337 
338     return ret;
339 }
340 
AK4497_ModuleControl(ak4497_handle_t * handle,ak4497_module_ctrl_cmd_t cmd,uint32_t data)341 status_t AK4497_ModuleControl(ak4497_handle_t *handle, ak4497_module_ctrl_cmd_t cmd, uint32_t data)
342 {
343     status_t ret = kStatus_Success;
344 
345     if (cmd == kAK4497_ModuleSwitchI2SInInterface)
346     {
347         ret = AK4497_SetEncoding(handle, (uint8_t)data);
348     }
349     else
350     {
351         ret = kStatus_InvalidArgument;
352     }
353 
354     return ret;
355 }
356 
AK4497_WriteReg(ak4497_handle_t * handle,uint8_t reg,uint8_t val)357 status_t AK4497_WriteReg(ak4497_handle_t *handle, uint8_t reg, uint8_t val)
358 {
359     assert(handle->config != NULL);
360     assert(handle->config->slaveAddress != 0U);
361 
362     Delay(); /* Ensure the Codec I2C bus free before writing the slave. */
363 
364     return CODEC_I2C_Send(handle->i2cHandle, handle->config->slaveAddress, reg, 1U, (uint8_t *)&val, 1U);
365 }
366 
AK4497_ReadReg(ak4497_handle_t * handle,uint8_t reg,uint8_t * val)367 status_t AK4497_ReadReg(ak4497_handle_t *handle, uint8_t reg, uint8_t *val)
368 {
369     assert(handle->config != NULL);
370     assert(handle->config->slaveAddress != 0U);
371 
372     Delay(); /* Ensure the Codec I2C bus free before reading the slave. */
373 
374     return CODEC_I2C_Receive(handle->i2cHandle, handle->config->slaveAddress, reg, 1U, val, 1U);
375 }
376 
AK4497_ModifyReg(ak4497_handle_t * handle,uint8_t reg,uint8_t mask,uint8_t val)377 status_t AK4497_ModifyReg(ak4497_handle_t *handle, uint8_t reg, uint8_t mask, uint8_t val)
378 {
379     status_t retval = kStatus_Success;
380     uint8_t reg_val = 0;
381     retval          = AK4497_ReadReg(handle, reg, &reg_val);
382     if (retval != kStatus_Success)
383     {
384         return kStatus_Fail;
385     }
386     reg_val &= (uint8_t)~mask;
387     reg_val |= val;
388     retval = AK4497_WriteReg(handle, reg, reg_val);
389     if (retval != kStatus_Success)
390     {
391         return kStatus_Fail;
392     }
393     return kStatus_Success;
394 }
395