1 /*
2 * Copyright 2021 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_codec_wm8962_adapter.h"
10 #include "fsl_codec_common.h"
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14 /*! @brief module capability definition */
15 #define HAL_WM8962_MODULE_CAPABILITY \
16 (kCODEC_SupportModuleADC | kCODEC_SupportModuleDAC | kCODEC_SupportModuleHeadphone | kCODEC_SupportModuleSpeaker | \
17 kCODEC_SupportModuleMic | kCODEC_SupportModuleMixer | kCODEC_SupportModuleMicbias | kCODEC_SupportModuleLinein)
18
19 #define HAL_WM8962_PLAY_CAPABILITY \
20 (kCODEC_SupportPlayChannelLeft0 | kCODEC_SupportPlayChannelRight0 | kCODEC_SupportPlayChannelLeft1 | \
21 kCODEC_SupportPlayChannelRight1 | kCODEC_SupportPlaySourcePGA | kCODEC_SupportPlaySourceDAC | \
22 kCODEC_SupportPlaySourceInput)
23
24 #define HAL_WM8962_VOLUME_CAPABILITY \
25 (kCODEC_SupportPlayChannelLeft0 | kCODEC_SupportPlayChannelRight0 | kCODEC_SupportPlayChannelLeft1 | \
26 kCODEC_SupportPlayChannelRight1 | kCODEC_VolumeDAC)
27
28 #define HAL_WM8962_RECORD_CAPABILITY \
29 (kCODEC_SupportPlayChannelLeft0 | kCODEC_SupportPlayChannelLeft1 | kCODEC_SupportPlayChannelLeft2 | \
30 kCODEC_SupportPlayChannelRight0 | kCODEC_SupportPlayChannelRight1 | kCODEC_SupportPlayChannelRight2)
31
32 /*! @brief wm8962 map protocol */
33 #define HAL_WM8962_MAP_PROTOCOL(protocol) \
34 ((protocol) == kCODEC_BusI2S ? kWM8962_BusI2S : \
35 (protocol) == kCODEC_BusLeftJustified ? kWM8962_BusLeftJustified : \
36 (protocol) == kCODEC_BusRightJustified ? kWM8962_BusRightJustified : \
37 (protocol) == kCODEC_BusPCMA ? kWM8962_BusPCMA : \
38 (protocol) == kCODEC_BusPCMB ? kWM8962_BusPCMB : \
39 kWM8962_BusI2S)
40
41 /*! @brief wm8962 map module */
42 #define HAL_WM8962_MAP_MODULE(module) \
43 ((module) == (uint32_t)kCODEC_ModuleADC ? kWM8962_ModuleADC : \
44 (module) == (uint32_t)kCODEC_ModuleDAC ? kWM8962_ModuleDAC : \
45 (module) == (uint32_t)kCODEC_ModuleHeadphone ? kWM8962_ModuleHeadphone : \
46 (module) == (uint32_t)kCODEC_ModuleMicbias ? kWM8962_ModuleMICB : \
47 (module) == (uint32_t)kCODEC_ModuleMic ? kWM8962_ModuleMIC : \
48 (module) == (uint32_t)kCODEC_ModuleLinein ? kWM8962_ModuleLineIn : \
49 (module) == (uint32_t)kCODEC_ModuleSpeaker ? kWM8962_ModuleSpeaker : \
50 kWM8962_ModuleADC)
51
52 /*******************************************************************************
53 * Prototypes
54 ******************************************************************************/
55
56 /*******************************************************************************
57 * Variables
58 ******************************************************************************/
59 static const codec_capability_t s_wm8962_capability = {
60 .codecPlayCapability = HAL_WM8962_PLAY_CAPABILITY,
61 .codecVolumeCapability = HAL_WM8962_VOLUME_CAPABILITY,
62 .codecModuleCapability = HAL_WM8962_MODULE_CAPABILITY,
63 .codecRecordCapability = HAL_WM8962_RECORD_CAPABILITY,
64 };
65 /*******************************************************************************
66 * Code
67 ******************************************************************************/
68 /*!
69 * brief Codec initilization.
70 *
71 * param handle codec handle.
72 * param config codec configuration.
73 * return kStatus_Success is success, else initial failed.
74 */
HAL_CODEC_WM8962_Init(void * handle,void * config)75 status_t HAL_CODEC_WM8962_Init(void *handle, void *config)
76 {
77 assert((config != NULL) && (handle != NULL));
78
79 codec_config_t *codecConfig = (codec_config_t *)config;
80
81 wm8962_config_t *devConfig = (wm8962_config_t *)(codecConfig->codecDevConfig);
82 wm8962_handle_t *devHandle = (wm8962_handle_t *)((uintptr_t)(((codec_handle_t *)handle)->codecDevHandle));
83
84 ((codec_handle_t *)handle)->codecCapability = &s_wm8962_capability;
85
86 /* codec device initialization */
87 return WM8962_Init(devHandle, devConfig);
88 }
89
90 /*!
91 * brief Codec de-initilization.
92 *
93 * param handle codec handle.
94 * return kStatus_Success is success, else de-initial failed.
95 */
HAL_CODEC_WM8962_Deinit(void * handle)96 status_t HAL_CODEC_WM8962_Deinit(void *handle)
97 {
98 assert(handle != NULL);
99
100 return WM8962_Deinit((wm8962_handle_t *)((uintptr_t)(((codec_handle_t *)handle)->codecDevHandle)));
101 }
102
103 /*!
104 * brief set audio data format.
105 *
106 * param handle codec handle.
107 * param mclk master clock frequency in HZ.
108 * param sampleRate sample rate in HZ.
109 * param bitWidth bit width.
110 * return kStatus_Success is success, else configure failed.
111 */
HAL_CODEC_WM8962_SetFormat(void * handle,uint32_t mclk,uint32_t sampleRate,uint32_t bitWidth)112 status_t HAL_CODEC_WM8962_SetFormat(void *handle, uint32_t mclk, uint32_t sampleRate, uint32_t bitWidth)
113 {
114 assert(handle != NULL);
115
116 return WM8962_ConfigDataFormat((wm8962_handle_t *)((uintptr_t)(((codec_handle_t *)handle)->codecDevHandle)), mclk,
117 sampleRate, bitWidth);
118 }
119
120 /*!
121 * brief set audio codec module volume.
122 *
123 * param handle codec handle.
124 * param channel audio codec play channel, can be a value or combine value of _codec_play_channel.
125 * param volume volume value, support 0 ~ 100, 0 is mute, 100 is the maximum volume value.
126 * return kStatus_Success is success, else configure failed.
127 */
HAL_CODEC_WM8962_SetVolume(void * handle,uint32_t playChannel,uint32_t volume)128 status_t HAL_CODEC_WM8962_SetVolume(void *handle, uint32_t playChannel, uint32_t volume)
129 {
130 assert(handle != NULL);
131
132 status_t retVal = kStatus_Success;
133 uint32_t mappedVolume = 0U;
134
135 if (((playChannel & (uint32_t)kCODEC_VolumeHeadphoneLeft) != 0U) ||
136 ((playChannel & (uint32_t)kCODEC_VolumeHeadphoneRight) != 0U))
137 {
138 /*
139 * 0 is mute
140 * 1 - 100 is mapped to 0x30 - 0x7F
141 */
142 mappedVolume = (volume * (WM8962_HEADPHONE_MAX_VOLUME_vALUE - WM8962_HEADPHONE_MIN_VOLUME_vALUE)) / 100U +
143 WM8962_HEADPHONE_MIN_VOLUME_vALUE;
144 retVal = WM8962_SetModuleVolume((wm8962_handle_t *)((uintptr_t)(((codec_handle_t *)handle)->codecDevHandle)),
145 kWM8962_ModuleHeadphone, mappedVolume);
146 }
147
148 if (((playChannel & (uint32_t)kCODEC_VolumeSpeakerLeft) != 0U) ||
149 ((playChannel & (uint32_t)kCODEC_VolumeSpeakerRight) != 0U))
150 {
151 /*
152 * 0 is mute
153 * 1 - 100 is mapped to 0x30 - 0x7F
154 */
155 mappedVolume = (volume * (WM8962_HEADPHONE_MAX_VOLUME_vALUE - WM8962_HEADPHONE_MIN_VOLUME_vALUE)) / 100U +
156 WM8962_HEADPHONE_MIN_VOLUME_vALUE;
157 retVal = WM8962_SetModuleVolume((wm8962_handle_t *)((uintptr_t)(((codec_handle_t *)handle)->codecDevHandle)),
158 kWM8962_ModuleSpeaker, mappedVolume);
159 }
160
161 if ((playChannel & (uint32_t)kCODEC_VolumeDAC) != 0U)
162 {
163 /*
164 * 0 is mute
165 * 0 - 100 is mapped to 0x00 - 0xFF
166 */
167 mappedVolume = (volume * (WM8962_DAC_MAX_VOLUME_vALUE - 0U)) / 100U;
168
169 retVal = WM8962_SetModuleVolume((wm8962_handle_t *)((uintptr_t)(((codec_handle_t *)handle)->codecDevHandle)),
170 kWM8962_ModuleDAC, mappedVolume);
171 }
172
173 return retVal;
174 }
175
176 /*!
177 * brief set audio codec module mute.
178 *
179 * param handle codec handle.
180 * param channel audio codec play channel, can be a value or combine value of _codec_play_channel.
181 * param isMute true is mute, false is unmute.
182 * return kStatus_Success is success, else configure failed.
183 */
HAL_CODEC_WM8962_SetMute(void * handle,uint32_t playChannel,bool isMute)184 status_t HAL_CODEC_WM8962_SetMute(void *handle, uint32_t playChannel, bool isMute)
185 {
186 assert(handle != NULL);
187
188 status_t retVal = kStatus_Success;
189
190 if (((playChannel & (uint32_t)kWM8962_HeadphoneLeft) != 0U) ||
191 ((playChannel & (uint32_t)kWM8962_HeadphoneRight) != 0U))
192 {
193 retVal = WM8962_SetModuleMute((wm8962_handle_t *)((uintptr_t)(((codec_handle_t *)handle)->codecDevHandle)),
194 kWM8962_ModuleHeadphone, isMute);
195 }
196
197 if (((playChannel & (uint32_t)kWM8962_SpeakerLeft) != 0U) || ((playChannel & (uint32_t)kWM8962_SpeakerRight) != 0U))
198 {
199 retVal = WM8962_SetModuleMute((wm8962_handle_t *)((uintptr_t)(((codec_handle_t *)handle)->codecDevHandle)),
200 kWM8962_ModuleSpeaker, isMute);
201 }
202
203 return retVal;
204 }
205
206 /*!
207 * brief set audio codec module power.
208 *
209 * param handle codec handle.
210 * param module audio codec module.
211 * param powerOn true is power on, false is power down.
212 * return kStatus_Success is success, else configure failed.
213 */
HAL_CODEC_WM8962_SetPower(void * handle,uint32_t module,bool powerOn)214 status_t HAL_CODEC_WM8962_SetPower(void *handle, uint32_t module, bool powerOn)
215 {
216 assert(handle != NULL);
217
218 return WM8962_SetModulePower((wm8962_handle_t *)((uintptr_t)(((codec_handle_t *)handle)->codecDevHandle)),
219 HAL_WM8962_MAP_MODULE(module), powerOn);
220 }
221
222 /*!
223 * brief codec set record channel.
224 *
225 * param handle codec handle.
226 * param leftRecordChannel audio codec record channel, reference _codec_record_channel, can be a value or combine value
227 of member in _codec_record_channel.
228 * param rightRecordChannel audio codec record channel, reference _codec_record_channel, can be a value combine of
229 member in _codec_record_channel.
230
231 * return kStatus_Success is success, else configure failed.
232 */
HAL_CODEC_WM8962_SetRecordChannel(void * handle,uint32_t leftRecordChannel,uint32_t rightRecordChannel)233 status_t HAL_CODEC_WM8962_SetRecordChannel(void *handle, uint32_t leftRecordChannel, uint32_t rightRecordChannel)
234 {
235 return kStatus_CODEC_NotSupport;
236 }
237
238 /*!
239 * brief codec set record source.
240 *
241 * param handle codec handle.
242 * param source audio codec record source, can be a value or combine value of _codec_record_source.
243 *
244 * @return kStatus_Success is success, else configure failed.
245 */
HAL_CODEC_WM8962_SetRecord(void * handle,uint32_t recordSource)246 status_t HAL_CODEC_WM8962_SetRecord(void *handle, uint32_t recordSource)
247 {
248 return kStatus_CODEC_NotSupport;
249 }
250
251 /*!
252 * brief codec set play source.
253 *
254 * param handle codec handle.
255 * param playSource audio codec play source, can be a value or combine value of _codec_play_source.
256 *
257 * return kStatus_Success is success, else configure failed.
258 */
HAL_CODEC_WM8962_SetPlay(void * handle,uint32_t playSource)259 status_t HAL_CODEC_WM8962_SetPlay(void *handle, uint32_t playSource)
260 {
261 return kStatus_CODEC_NotSupport;
262 }
263
264 /*!
265 * brief codec module control.
266 *
267 * param handle codec handle.
268 * param cmd module control cmd, reference _codec_module_ctrl_cmd.
269 * param moduleData value to write, when cmd is kCODEC_ModuleRecordSourceChannel, the data should be a value combine
270 * of channel and source, please reference macro CODEC_MODULE_RECORD_SOURCE_CHANNEL(source, LP, LN, RP, RN), reference
271 * codec specific driver for detail configurations.
272 * return kStatus_Success is success, else configure failed.
273 */
HAL_CODEC_WM8962_ModuleControl(void * handle,uint32_t cmd,uint32_t moduleData)274 status_t HAL_CODEC_WM8962_ModuleControl(void *handle, uint32_t cmd, uint32_t moduleData)
275 {
276 return kStatus_CODEC_NotSupport;
277 }
278