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