1 /*
2  * Copyright  2021 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_codec_sgtl_adapter.h"
10 #include "fsl_codec_common.h"
11 /*******************************************************************************
12  * Definitions
13  ******************************************************************************/
14 /*! @brief module capability definition */
15 #define HAL_SGTL_MODULE_CAPABILITY                                                                                \
16     kCODEC_SupportModuleADC | kCODEC_SupportModuleDAC | kCODEC_SupportModulePGA | kCODEC_SupportModuleHeadphone | \
17         kCODEC_SupportModuleLinein | kCODEC_SupportModuleI2SIn | kCODEC_SupportModuleI2SOut | kCODEC_SupportModuleMic
18 #define HAL_SGTL_PLAY_CAPABILITY                                                                        \
19     kCODEC_SupportPlayChannelLeft0 | kCODEC_SupportPlayChannelRight0 | kCODEC_SupportPlayChannelLeft1 | \
20         kCODEC_SupportPlayChannelRight1 | kCODEC_SupportPlaySourceInput | kCODEC_SupportPlaySourceDAC | \
21         kCODEC_SupportPlayChannelLeft2 | kCODEC_SupportPlayChannelRight2
22 #define HAL_SGTL_RECORD_CAPABILITY kCODEC_SupportRecordSourceLineInput | kCODEC_SupportRecordSourceSingleEndMic
23 #define HAL_SGTL_VOLUME_CAPABILITY                                                                      \
24     kCODEC_SupportPlayChannelLeft0 | kCODEC_SupportPlayChannelRight0 | kCODEC_SupportPlayChannelLeft1 | \
25         kCODEC_SupportPlayChannelRight1 | kCODEC_SupportPlayChannelLeft2 | kCODEC_SupportPlayChannelRight2
26 /*! @brief sgtl map module */
27 #define HAL_SGTL_MAP_MODULE(module)                                       \
28     ((module) == (uint32_t)kCODEC_ModuleADC       ? kSGTL_ModuleADC :     \
29      (module) == (uint32_t)kCODEC_ModuleDAC       ? kSGTL_ModuleDAC :     \
30      (module) == (uint32_t)kCODEC_ModuleHeadphone ? kSGTL_ModuleHP :      \
31      (module) == (uint32_t)kCODEC_ModuleI2SIn     ? kSGTL_ModuleI2SIN :   \
32      (module) == (uint32_t)kCODEC_ModuleI2SOut    ? kSGTL_ModuleI2SOUT :  \
33      (module) == (uint32_t)kCODEC_ModuleLinein    ? kSGTL_ModuleLineIn :  \
34      (module) == (uint32_t)kCODEC_ModuleLineout   ? kSGTL_ModuleLineOut : \
35                                                     kSGTL_ModuleMicin)
36 
37 /*******************************************************************************
38  * Prototypes
39  ******************************************************************************/
40 
41 /*******************************************************************************
42  * Variables
43  ******************************************************************************/
44 static const codec_capability_t s_sgtl5000_capability = {
45     .codecPlayCapability   = HAL_SGTL_PLAY_CAPABILITY,
46     .codecVolumeCapability = HAL_SGTL_VOLUME_CAPABILITY,
47     .codecModuleCapability = HAL_SGTL_MODULE_CAPABILITY,
48     .codecRecordCapability = HAL_SGTL_RECORD_CAPABILITY,
49 };
50 /*******************************************************************************
51  * Code
52  ******************************************************************************/
53 /*!
54  * brief Codec initilization.
55  *
56  * param handle codec handle.
57  * param config codec configuration.
58  * return kStatus_Success is success, else initial failed.
59  */
HAL_CODEC_SGTL5000_Init(void * handle,void * config)60 status_t HAL_CODEC_SGTL5000_Init(void *handle, void *config)
61 {
62     assert((config != NULL) && (handle != NULL));
63 
64     codec_config_t *codecConfig = (codec_config_t *)config;
65 
66     sgtl_config_t *devConfig = (sgtl_config_t *)(codecConfig->codecDevConfig);
67     sgtl_handle_t *devHandle = (sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle));
68 
69     ((codec_handle_t *)handle)->codecCapability = &s_sgtl5000_capability;
70 
71     /* codec device initialization */
72     return SGTL_Init(devHandle, devConfig);
73 }
74 
75 /*!
76  * brief Codec de-initilization.
77  *
78  * param handle codec handle.
79  * return kStatus_Success is success, else de-initial failed.
80  */
HAL_CODEC_SGTL5000_Deinit(void * handle)81 status_t HAL_CODEC_SGTL5000_Deinit(void *handle)
82 {
83     assert(handle != NULL);
84 
85     return SGTL_Deinit((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)));
86 }
87 
88 /*!
89  * brief set audio data format.
90  *
91  * param handle codec handle.
92  * param mclk master clock frequency in HZ.
93  * param sampleRate sample rate in HZ.
94  * param bitWidth bit width.
95  * return kStatus_Success is success, else configure failed.
96  */
HAL_CODEC_SGTL5000_SetFormat(void * handle,uint32_t mclk,uint32_t sampleRate,uint32_t bitWidth)97 status_t HAL_CODEC_SGTL5000_SetFormat(void *handle, uint32_t mclk, uint32_t sampleRate, uint32_t bitWidth)
98 {
99     assert(handle != NULL);
100 
101     return SGTL_ConfigDataFormat((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)), mclk,
102                                  sampleRate, bitWidth);
103 }
104 
105 /*!
106  * brief set audio codec module volume.
107  *
108  * param handle codec handle.
109  * param channel audio codec play channel, can be a value or combine value of _codec_play_channel.
110  * param volume volume value, support 0 ~ 100, 0 is mute, 100 is the maximum volume value.
111  * return kStatus_Success is success, else configure failed.
112  */
HAL_CODEC_SGTL5000_SetVolume(void * handle,uint32_t playChannel,uint32_t volume)113 status_t HAL_CODEC_SGTL5000_SetVolume(void *handle, uint32_t playChannel, uint32_t volume)
114 {
115     assert(handle != NULL);
116 
117     uint32_t mappedVolume = 0;
118     status_t ret          = kStatus_Success;
119 
120     if ((playChannel & ((uint32_t)kCODEC_PlayChannelHeadphoneLeft | (uint32_t)kCODEC_PlayChannelHeadphoneRight)) != 0U)
121     {
122         if (volume == 0U)
123         {
124             ret = SGTL_SetMute((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
125                                kSGTL_ModuleHP, true);
126         }
127         else
128         {
129             /* 1-100 mapped to 0x7F-0 */
130             mappedVolume = SGTL5000_HEADPHONE_MAX_VOLUME_VALUE -
131                            ((volume - 1U) * (SGTL5000_HEADPHONE_MAX_VOLUME_VALUE + 2U)) / 100U;
132 
133             ret = SGTL_SetVolume((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
134                                  kSGTL_ModuleHP, mappedVolume);
135             if (ret == kStatus_Success)
136             {
137                 ret = SGTL_SetMute((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
138                                    kSGTL_ModuleHP, false);
139             }
140         }
141     }
142 
143     if ((playChannel & ((uint32_t)kCODEC_PlayChannelLineOutLeft | (uint32_t)kCODEC_PlayChannelLineOutRight)) != 0U)
144     {
145         if (volume == 0U)
146         {
147             ret = SGTL_SetMute((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
148                                kSGTL_ModuleLineOut, true);
149         }
150         else
151         {
152             /* 1-100 mapped to 0-0x1F */
153             mappedVolume = ((volume - 1U) * (SGTL5000_LINE_OUT_MAX_VOLUME_VALUE + 1U)) / 100U;
154 
155             ret = SGTL_SetVolume((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
156                                  kSGTL_ModuleLineOut, mappedVolume);
157             if (ret == kStatus_Success)
158             {
159                 ret = SGTL_SetMute((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
160                                    kSGTL_ModuleLineOut, false);
161             }
162         }
163     }
164 
165     return ret;
166 }
167 
168 /*!
169  * brief set audio codec module mute.
170  *
171  * param handle codec handle.
172  * param channel audio codec play channel, can be a value or combine value of _codec_play_channel.
173  * param isMute true is mute, false is unmute.
174  * return kStatus_Success is success, else configure failed.
175  */
HAL_CODEC_SGTL5000_SetMute(void * handle,uint32_t playChannel,bool isMute)176 status_t HAL_CODEC_SGTL5000_SetMute(void *handle, uint32_t playChannel, bool isMute)
177 {
178     assert(handle != NULL);
179 
180     status_t retVal = kStatus_Success;
181 
182     if ((playChannel & ((uint32_t)kCODEC_PlayChannelHeadphoneLeft | (uint32_t)kCODEC_PlayChannelHeadphoneRight)) != 0U)
183     {
184         retVal = SGTL_SetMute((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)), kSGTL_ModuleHP,
185                               isMute);
186     }
187 
188     if (((playChannel & ((uint32_t)kCODEC_PlayChannelLineOutLeft | (uint32_t)kCODEC_PlayChannelLineOutRight)) != 0U) &&
189         (retVal == kStatus_Success))
190     {
191         retVal = SGTL_SetMute((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
192                               kSGTL_ModuleLineOut, isMute);
193     }
194 
195     return retVal;
196 }
197 
198 /*!
199  * brief set audio codec module power.
200  *
201  * param handle codec handle.
202  * param module audio codec module.
203  * param powerOn true is power on, false is power down.
204  * return kStatus_Success is success, else configure failed.
205  */
HAL_CODEC_SGTL5000_SetPower(void * handle,uint32_t module,bool powerOn)206 status_t HAL_CODEC_SGTL5000_SetPower(void *handle, uint32_t module, bool powerOn)
207 {
208     assert(handle != NULL);
209 
210     if (powerOn)
211     {
212         return SGTL_EnableModule((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
213                                  HAL_SGTL_MAP_MODULE(module));
214     }
215     else
216     {
217         return SGTL_DisableModule((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
218                                   HAL_SGTL_MAP_MODULE(module));
219     }
220 }
221 
222 /*!
223  * brief codec set record source.
224  *
225  * param handle codec handle.
226  * param source audio codec record source, can be a value or combine value of _codec_record_source.
227  *
228  * return kStatus_Success is success, else configure failed.
229  */
HAL_CODEC_SGTL5000_SetRecord(void * handle,uint32_t recordSource)230 status_t HAL_CODEC_SGTL5000_SetRecord(void *handle, uint32_t recordSource)
231 {
232     assert(handle != NULL);
233 
234     if (recordSource == (uint32_t)kCODEC_RecordSourceLineInput)
235     {
236         return SGTL_SetRecord((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
237                               kSGTL_RecordSourceLineIn);
238     }
239 
240     if (recordSource == (uint32_t)kCODEC_RecordSourceSingleEndMic)
241     {
242         return SGTL_SetRecord((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
243                               kSGTL_RecordSourceMic);
244     }
245 
246     return kStatus_CODEC_NotSupport;
247 }
248 
249 /*!
250  * brief codec set record channel.
251  *
252  * param handle codec handle.
253  * param leftRecordChannel audio codec record channel, reference _codec_record_channel, can be a value or combine value
254  of member in _codec_record_channel.
255  * param rightRecordChannel audio codec record channel, reference _codec_record_channel, can be a value combine of
256  member in _codec_record_channel.
257 
258  * return kStatus_Success is success, else configure failed.
259  */
HAL_CODEC_SGTL5000_SetRecordChannel(void * handle,uint32_t leftRecordChannel,uint32_t rightRecordChannel)260 status_t HAL_CODEC_SGTL5000_SetRecordChannel(void *handle, uint32_t leftRecordChannel, uint32_t rightRecordChannel)
261 {
262     return kStatus_CODEC_NotSupport;
263 }
264 
265 /*!
266  * brief codec set play source.
267  *
268  * param handle codec handle.
269  * param playSource audio codec play source, can be a value or combine value of _codec_play_source.
270  *
271  * return kStatus_Success is success, else configure failed.
272  */
HAL_CODEC_SGTL5000_SetPlay(void * handle,uint32_t playSource)273 status_t HAL_CODEC_SGTL5000_SetPlay(void *handle, uint32_t playSource)
274 {
275     assert(handle != NULL);
276 
277     if (playSource == (uint32_t)kCODEC_PlaySourceInput)
278     {
279         return SGTL_SetPlay((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
280                             kSGTL_PlaySourceLineIn);
281     }
282 
283     if (playSource == (uint32_t)kCODEC_PlaySourceDAC)
284     {
285         return SGTL_SetPlay((sgtl_handle_t *)((uint32_t)(((codec_handle_t *)handle)->codecDevHandle)),
286                             kSGTL_PlaySourceDAC);
287     }
288 
289     return kStatus_CODEC_NotSupport;
290 }
291 
292 /*!
293  * brief codec module control.
294  *
295  * param handle codec handle.
296  * param cmd module control cmd, reference _codec_module_ctrl_cmd.
297  * param data value to write, when cmd is kCODEC_ModuleRecordSourceChannel, the data should be a value combine
298  *  of channel and source, please reference macro CODEC_MODULE_RECORD_SOURCE_CHANNEL(source, LP, LN, RP, RN), reference
299  *  codec specific driver for detail configurations.
300  * return kStatus_Success is success, else configure failed.
301  */
HAL_CODEC_SGTL5000_ModuleControl(void * handle,uint32_t cmd,uint32_t data)302 status_t HAL_CODEC_SGTL5000_ModuleControl(void *handle, uint32_t cmd, uint32_t data)
303 {
304     return kStatus_CODEC_NotSupport;
305 }
306