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