1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-12-05     zylx         The first version for STM32F4xx
9  * 2019-4-25      misonyo      port to IMXRT
10  */
11 
12 #ifndef __DRV_WM8960_H__
13 #define __DRV_WM8960_H__
14 
15 #include <rtthread.h>
16 #include <rtdevice.h>
17 
18 #include "fsl_common.h"
19 /*!
20  * @addtogroup wm8960
21  * @{
22  */
23 
24 /*******************************************************************************
25  * Definitions
26  ******************************************************************************/
27 /*! @name Driver version */
28 /*@{*/
29 /*! @brief CLOCK driver version 2.1.0 */
30 #define FSL_WM8960_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
31 /*@}*/
32 
33 /*! @brief wm8960 handle size */
34 #ifndef WM8960_HANDLE_SIZE
35 #define WM8960_HANDLE_SIZE (100U)
36 #endif
37 
38 /*! @brief Define the register address of WM8960. */
39 #define WM8960_LINVOL 0x0
40 #define WM8960_RINVOL 0x1
41 #define WM8960_LOUT1 0x2
42 #define WM8960_ROUT1 0x3
43 #define WM8960_CLOCK1 0x4
44 #define WM8960_DACCTL1 0x5
45 #define WM8960_DACCTL2 0x6
46 #define WM8960_IFACE1 0x7
47 #define WM8960_CLOCK2 0x8
48 #define WM8960_IFACE2 0x9
49 #define WM8960_LDAC 0xa
50 #define WM8960_RDAC 0xb
51 
52 #define WM8960_RESET 0xf
53 #define WM8960_3D 0x10
54 #define WM8960_ALC1 0x11
55 #define WM8960_ALC2 0x12
56 #define WM8960_ALC3 0x13
57 #define WM8960_NOISEG 0x14
58 #define WM8960_LADC 0x15
59 #define WM8960_RADC 0x16
60 #define WM8960_ADDCTL1 0x17
61 #define WM8960_ADDCTL2 0x18
62 #define WM8960_POWER1 0x19
63 #define WM8960_POWER2 0x1a
64 #define WM8960_ADDCTL3 0x1b
65 #define WM8960_APOP1 0x1c
66 #define WM8960_APOP2 0x1d
67 
68 #define WM8960_LINPATH 0x20
69 #define WM8960_RINPATH 0x21
70 #define WM8960_LOUTMIX 0x22
71 
72 #define WM8960_ROUTMIX 0x25
73 #define WM8960_MONOMIX1 0x26
74 #define WM8960_MONOMIX2 0x27
75 #define WM8960_LOUT2 0x28
76 #define WM8960_ROUT2 0x29
77 #define WM8960_MONO 0x2a
78 #define WM8960_INBMIX1 0x2b
79 #define WM8960_INBMIX2 0x2c
80 #define WM8960_BYPASS1 0x2d
81 #define WM8960_BYPASS2 0x2e
82 #define WM8960_POWER3 0x2f
83 #define WM8960_ADDCTL4 0x30
84 #define WM8960_CLASSD1 0x31
85 
86 #define WM8960_CLASSD3 0x33
87 #define WM8960_PLL1 0x34
88 #define WM8960_PLL2 0x35
89 #define WM8960_PLL3 0x36
90 #define WM8960_PLL4 0x37
91 
92 /*! @brief Cache register number */
93 #define WM8960_CACHEREGNUM 56
94 
95 /*! @brief WM8960_IFACE1 FORMAT bits */
96 #define WM8960_IFACE1_FORMAT_MASK 0x03
97 #define WM8960_IFACE1_FORMAT_SHIFT 0x00
98 #define WM8960_IFACE1_FORMAT_RJ 0x00
99 #define WM8960_IFACE1_FORMAT_LJ 0x01
100 #define WM8960_IFACE1_FORMAT_I2S 0x02
101 #define WM8960_IFACE1_FORMAT_DSP 0x03
102 #define WM8960_IFACE1_FORMAT(x) ((x << WM8960_IFACE1_FORMAT_SHIFT) & WM8960_IFACE1_FORMAT_MASK)
103 
104 /*! @brief WM8960_IFACE1 WL bits */
105 #define WM8960_IFACE1_WL_MASK 0x0C
106 #define WM8960_IFACE1_WL_SHIFT 0x02
107 #define WM8960_IFACE1_WL_16BITS 0x00
108 #define WM8960_IFACE1_WL_20BITS 0x01
109 #define WM8960_IFACE1_WL_24BITS 0x02
110 #define WM8960_IFACE1_WL_32BITS 0x03
111 #define WM8960_IFACE1_WL(x) ((x << WM8960_IFACE1_WL_SHIFT) & WM8960_IFACE1_WL_MASK)
112 
113 /*! @brief WM8960_IFACE1 LRP bit */
114 #define WM8960_IFACE1_LRP_MASK 0x10
115 #define WM8960_IFACE1_LRP_SHIFT 0x04
116 #define WM8960_IFACE1_LRCLK_NORMAL_POL 0x00
117 #define WM8960_IFACE1_LRCLK_INVERT_POL 0x01
118 #define WM8960_IFACE1_DSP_MODEA 0x00
119 #define WM8960_IFACE1_DSP_MODEB 0x01
120 #define WM8960_IFACE1_LRP(x) ((x << WM8960_IFACE1_LRP_SHIFT) & WM8960_IFACE1_LRP_MASK)
121 
122 /*! @brief WM8960_IFACE1 DLRSWAP bit */
123 #define WM8960_IFACE1_DLRSWAP_MASK 0x20
124 #define WM8960_IFACE1_DLRSWAP_SHIFT 0x05
125 #define WM8960_IFACE1_DACCH_NORMAL 0x00
126 #define WM8960_IFACE1_DACCH_SWAP 0x01
127 #define WM8960_IFACE1_DLRSWAP(x) ((x << WM8960_IFACE1_DLRSWAP_SHIFT) & WM8960_IFACE1_DLRSWAP_MASK)
128 
129 /*! @brief WM8960_IFACE1 MS bit */
130 #define WM8960_IFACE1_MS_MASK 0x40
131 #define WM8960_IFACE1_MS_SHIFT 0x06
132 #define WM8960_IFACE1_SLAVE 0x00
133 #define WM8960_IFACE1_MASTER 0x01
134 #define WM8960_IFACE1_MS(x) ((x << WM8960_IFACE1_MS_SHIFT) & WM8960_IFACE1_MS_MASK)
135 
136 /*! @brief WM8960_IFACE1 BCLKINV bit */
137 #define WM8960_IFACE1_BCLKINV_MASK 0x80
138 #define WM8960_IFACE1_BCLKINV_SHIFT 0x07
139 #define WM8960_IFACE1_BCLK_NONINVERT 0x00
140 #define WM8960_IFACE1_BCLK_INVERT 0x01
141 #define WM8960_IFACE1_BCLKINV(x) ((x << WM8960_IFACE1_BCLKINV_SHIFT) & WM8960_IFACE1_BCLKINV_MASK)
142 
143 /*! @brief WM8960_IFACE1 ALRSWAP bit */
144 #define WM8960_IFACE1_ALRSWAP_MASK 0x100
145 #define WM8960_IFACE1_ALRSWAP_SHIFT 0x08
146 #define WM8960_IFACE1_ADCCH_NORMAL 0x00
147 #define WM8960_IFACE1_ADCCH_SWAP 0x01
148 #define WM8960_IFACE1_ALRSWAP(x) ((x << WM8960_IFACE1_ALRSWAP_SHIFT) & WM8960_IFACE1_ALRSWAP_MASK)
149 
150 /*! @brief WM8960_POWER1 */
151 #define WM8960_POWER1_VREF_MASK 0x40
152 #define WM8960_POWER1_VREF_SHIFT 0x06
153 
154 #define WM8960_POWER1_AINL_MASK 0x20
155 #define WM8960_POWER1_AINL_SHIFT 0x05
156 
157 #define WM8960_POWER1_AINR_MASK 0x10
158 #define WM8960_POWER1_AINR_SHIFT 0x04
159 
160 #define WM8960_POWER1_ADCL_MASK 0x08
161 #define WM8960_POWER1_ADCL_SHIFT 0x03
162 
163 #define WM8960_POWER1_ADCR_MASK 0x0
164 #define WM8960_POWER1_ADCR_SHIFT 0x02
165 
166 #define WM8960_POWER1_MICB_MASK 0x02
167 #define WM8960_POWER1_MICB_SHIFT 0x01
168 
169 #define WM8960_POWER1_DIGENB_MASK 0x01
170 #define WM8960_POWER1_DIGENB_SHIFT 0x00
171 
172 /*! @brief WM8960_POWER2 */
173 #define WM8960_POWER2_DACL_MASK 0x100
174 #define WM8960_POWER2_DACL_SHIFT 0x08
175 
176 #define WM8960_POWER2_DACR_MASK 0x80
177 #define WM8960_POWER2_DACR_SHIFT 0x07
178 
179 #define WM8960_POWER2_LOUT1_MASK 0x40
180 #define WM8960_POWER2_LOUT1_SHIFT 0x06
181 
182 #define WM8960_POWER2_ROUT1_MASK 0x20
183 #define WM8960_POWER2_ROUT1_SHIFT 0x05
184 
185 #define WM8960_POWER2_SPKL_MASK 0x10
186 #define WM8960_POWER2_SPKL_SHIFT 0x04
187 
188 #define WM8960_POWER2_SPKR_MASK 0x08
189 #define WM8960_POWER2_SPKR_SHIFT 0x03
190 
191 #define WM8960_POWER3_LMIC_MASK 0x20
192 #define WM8960_POWER3_LMIC_SHIFT 0x05
193 #define WM8960_POWER3_RMIC_MASK 0x10
194 #define WM8960_POWER3_RMIC_SHIFT 0x04
195 #define WM8960_POWER3_LOMIX_MASK 0x08
196 #define WM8960_POWER3_LOMIX_SHIFT 0x03
197 #define WM8960_POWER3_ROMIX_MASK 0x04
198 #define WM8960_POWER3_ROMIX_SHIFT 0x02
199 /*! @brief WM8960 I2C address. */
200 #define WM8960_I2C_ADDR 0x1A
201 /*! @brief WM8960 I2C baudrate */
202 #define WM8960_I2C_BAUDRATE (100000U)
203 
204 /*! @brief Modules in WM8960 board. */
205 typedef enum _wm8960_module
206 {
207     kWM8960_ModuleADC     = 0, /*!< ADC module in WM8960 */
208     kWM8960_ModuleDAC     = 1, /*!< DAC module in WM8960 */
209     kWM8960_ModuleVREF    = 2, /*!< VREF module */
210     kWM8960_ModuleHP      = 3, /*!< Headphone */
211     kWM8960_ModuleMICB    = 4, /*!< Mic bias */
212     kWM8960_ModuleMIC     = 5, /*!< Input Mic */
213     kWM8960_ModuleLineIn  = 6, /*!< Analog in PGA  */
214     kWM8960_ModuleLineOut = 7, /*!< Line out module */
215     kWM8960_ModuleSpeaker = 8, /*!< Speaker module */
216     kWM8960_ModuleOMIX    = 9, /*!< Output mixer */
217 } wm8960_module_t;
218 
219 /*! @brief wm8960 play channel */
220 enum _wm8960_play_channel
221 {
222     kWM8960_HeadphoneLeft  = 1, /*!< wm8960 headphone left channel */
223     kWM8960_HeadphoneRight = 2, /*!< wm8960 headphone right channel */
224     kWM8960_SpeakerLeft    = 4, /*!< wm8960 speaker left channel */
225     kWM8960_SpeakerRight   = 8, /*!< wm8960 speaker right channel */
226 };
227 
228 /*! @brief wm8960 play source */
229 typedef enum _wm8960_play_source
230 {
231     kWM8960_PlaySourcePGA   = 1, /*!< wm8960 play source PGA */
232     kWM8960_PlaySourceInput = 2, /*!< wm8960 play source Input */
233     kWM8960_PlaySourceDAC   = 4, /*!< wm8960 play source DAC */
234 } wm8960_play_source_t;
235 
236 /*!
237  * @brief WM8960 data route.
238  * Only provide some typical data route, not all route listed.
239  * Note: Users cannot combine any routes, once a new route is set, the previous one would be replaced.
240  */
241 typedef enum _wm8960_route
242 {
243     kWM8960_RouteBypass            = 0, /*!< LINEIN->Headphone. */
244     kWM8960_RoutePlayback          = 1, /*!<  I2SIN->DAC->Headphone. */
245     kWM8960_RoutePlaybackandRecord = 2, /*!< I2SIN->DAC->Headphone, LINEIN->ADC->I2SOUT. */
246     kWM8960_RouteRecord            = 5  /*!< LINEIN->ADC->I2SOUT. */
247 } wm8960_route_t;
248 
249 /*!
250  * @brief The audio data transfer protocol choice.
251  * WM8960 only supports I2S format and PCM format.
252  */
253 typedef enum _wm8960_protocol
254 {
255     kWM8960_BusI2S            = 2,           /*!< I2S type */
256     kWM8960_BusLeftJustified  = 1,           /*!< Left justified mode */
257     kWM8960_BusRightJustified = 0,           /*!< Right justified mode */
258     kWM8960_BusPCMA           = 3,           /*!< PCM A mode */
259     kWM8960_BusPCMB           = 3 | (1 << 4) /*!< PCM B mode */
260 } wm8960_protocol_t;
261 
262 /*! @brief wm8960 input source */
263 typedef enum _wm8960_input
264 {
265     kWM8960_InputClosed                = 0, /*!< Input device is closed */
266     kWM8960_InputSingleEndedMic        = 1, /*!< Input as single ended mic, only use L/RINPUT1 */
267     kWM8960_InputDifferentialMicInput2 = 2, /*!< Input as differential mic, use L/RINPUT1 and L/RINPUT2 */
268     kWM8960_InputDifferentialMicInput3 = 3, /*!< Input as differential mic, use L/RINPUT1 and L/RINPUT3*/
269     kWM8960_InputLineINPUT2            = 4, /*!< Input as line input, only use L/RINPUT2 */
270     kWM8960_InputLineINPUT3            = 5  /*!< Input as line input, only use L/RINPUT3 */
271 } wm8960_input_t;
272 
273 /*! @brief audio sample rate definition */
274 enum _wm8960_sample_rate
275 {
276     kWM8960_AudioSampleRate8KHz    = 8000U,   /*!< Sample rate 8000 Hz */
277     kWM8960_AudioSampleRate11025Hz = 11025U,  /*!< Sample rate 11025 Hz */
278     kWM8960_AudioSampleRate12KHz   = 12000U,  /*!< Sample rate 12000 Hz */
279     kWM8960_AudioSampleRate16KHz   = 16000U,  /*!< Sample rate 16000 Hz */
280     kWM8960_AudioSampleRate22050Hz = 22050U,  /*!< Sample rate 22050 Hz */
281     kWM8960_AudioSampleRate24KHz   = 24000U,  /*!< Sample rate 24000 Hz */
282     kWM8960_AudioSampleRate32KHz   = 32000U,  /*!< Sample rate 32000 Hz */
283     kWM8960_AudioSampleRate44100Hz = 44100U,  /*!< Sample rate 44100 Hz */
284     kWM8960_AudioSampleRate48KHz   = 48000U,  /*!< Sample rate 48000 Hz */
285     kWM8960_AudioSampleRate96KHz   = 96000U,  /*!< Sample rate 96000 Hz */
286     kWM8960_AudioSampleRate192KHz  = 192000U, /*!< Sample rate 192000 Hz */
287     kWM8960_AudioSampleRate384KHz  = 384000U, /*!< Sample rate 384000 Hz */
288 };
289 
290 /*! @brief audio bit width */
291 enum _wm8960_audio_bit_width
292 {
293     kWM8960_AudioBitWidth16bit = 16U, /*!< audio bit width 16 */
294     kWM8960_AudioBitWidth20bit = 20U, /*!< audio bit width 20 */
295     kWM8960_AudioBitWidth24bit = 24U, /*!< audio bit width 24 */
296     kWM8960_AudioBitWidth32bit = 32U, /*!< audio bit width 32 */
297 };
298 
299 /*! @brief wm8960 audio format */
300 typedef struct _wm8960_audio_format
301 {
302     uint32_t mclk_HZ;    /*!< master clock frequency */
303     uint32_t sampleRate; /*!< sample rate */
304     uint32_t bitWidth;   /*!< bit width */
305 } wm8960_audio_format_t;
306 
307 /*! @brief Initialize structure of WM8960 */
308 typedef struct wm8960_config
309 {
310     wm8960_route_t route;            /*!< Audio data route.*/
311     wm8960_protocol_t bus;           /*!< Audio transfer protocol */
312     wm8960_audio_format_t format;    /*!< Audio format */
313     rt_bool_t master_slave;               /*!< Master or slave. */
314     rt_bool_t enableSpeaker;              /*!< True means enable class D speaker as output, false means no */
315     wm8960_input_t leftInputSource;  /*!< Left input source for WM8960 */
316     wm8960_input_t rightInputSource; /*!< Right input source for wm8960 */
317     wm8960_play_source_t playSource; /*!< play source */
318     uint8_t slaveAddress;            /*!< wm8960 device address */
319     //codec_i2c_config_t i2cConfig;    /*!< i2c configuration */
320 } wm8960_config_t;
321 
322 /*! @brief wm8960 codec handler
323  * Applicationi should allocate a buffer with WM8960_HANDLE_SIZE for handle definition, such as
324  * uint8_t wm8960HandleBuffer[WM8960_HANDLE_SIZE];
325  * wm8904_handle_t *wm8904Handle = wm8960HandleBuffer;
326  */
327 typedef struct _wm8960_handle
328 {
329     const wm8960_config_t *config; /*!< wm8904 config pointer */
330     void *i2cHandle;               /*!< i2c handle */
331 } wm8960_handle_t;
332 /*******************************************************************************
333  * API
334  ******************************************************************************/
335 #if defined(__cplusplus)
336 extern "C" {
337 #endif
338 
339 /*!
340  * @brief WM8960 initialize function.
341  *
342  * The second parameter is NULL to WM8960 in this version. If users want
343  * to change the settings, they have to use wm8960_write_reg() or wm8960_modify_reg()
344  * to set the register value of WM8960.
345  * Note: If the codec_config is NULL, it would initialize WM8960 using default settings.
346  * The default setting:
347  * codec_config->route = kWM8960_RoutePlaybackandRecord
348  * codec_config->bus = kWM8960_BusI2S
349  * codec_config->master = slave
350  *
351  * @param handle WM8960 handle structure.
352  * @param wm8960Config WM8960 configuration structure.
353  */
354 void WM8960_init(struct rt_i2c_bus_device *dev, wm8960_config_t *wm8960Config);
355 
356 /*!
357  * @brief Deinit the WM8960 codec.
358  *
359  * This function close all modules in WM8960 to save power.
360  *
361  * @param handle WM8960 handle structure pointer.
362  */
363 void WM8960_Deinit(struct rt_i2c_bus_device *dev);
364 
365 /*!
366  * @brief Set audio data route in WM8960.
367  *
368  * This function would set the data route according to route. The route cannot be combined,
369  * as all route would enable different modules.
370  * Note: If a new route is set, the previous route would not work.
371  *
372  * @param handle WM8960 handle structure.
373  * @param route Audio data route in WM8960.
374  */
375 void WM8960_SetDataRoute(struct rt_i2c_bus_device *dev, wm8960_route_t route);
376 
377 /*!
378  * @brief Set left audio input source in WM8960.
379  *
380  * @param handle WM8960 handle structure.
381  * @param input Audio input source.
382  */
383 void WM8960_SetLeftInput(struct rt_i2c_bus_device *dev, wm8960_input_t input);
384 
385 /*!
386  * @brief Set right audio input source in WM8960.
387  *
388  * @param handle WM8960 handle structure.
389  * @param input Audio input source.
390  */
391 void WM8960_SetRightInput(struct rt_i2c_bus_device *dev, wm8960_input_t input);
392 
393 /*!
394  * @brief Set the audio transfer protocol.
395  *
396  * WM8960 only supports I2S, left justified, right justified, PCM A, PCM B format.
397  *
398  * @param handle WM8960 handle structure.
399  * @param bus Audio data transfer protocol.
400  */
401 void WM8960_SetProtocol(struct rt_i2c_bus_device *dev, wm8960_protocol_t protocol);
402 
403 /*!
404  * @brief Set WM8960 as master or slave.
405  *
406  * @param handle WM8960 handle structure.
407  * @param master 1 represent master, 0 represent slave.
408  */
409 void WM8960_SetMasterSlave(struct rt_i2c_bus_device *dev, rt_bool_t master);
410 
411 /*!
412  * @brief Set the volume of different modules in WM8960.
413  *
414  * This function would set the volume of WM8960 modules. Uses need to appoint the module.
415  * The function assume that left channel and right channel has the same volume.
416  *
417  * @param handle WM8960 handle structure.
418  * @param module Module to set volume, it can be ADC, DAC, Headphone and so on.
419  * @param volume Volume value need to be set.
420  */
421 void WM8960_SetVolume(struct rt_i2c_bus_device *dev, wm8960_module_t module, rt_uint32_t volume);
422 
423 /*!
424  * @brief Get the volume of different modules in WM8960.
425  *
426  * This function gets the volume of WM8960 modules. Uses need to appoint the module.
427  * The function assume that left channel and right channel has the same volume.
428  *
429  * @param handle WM8960 handle structure.
430  * @param module Module to set volume, it can be ADC, DAC, Headphone and so on.
431  * @return Volume value of the module.
432  */
433 rt_uint32_t WM8960_GetVolume(struct rt_i2c_bus_device *dev, wm8960_module_t module);
434 
435 /*!
436  * @brief Mute modules in WM8960.
437  *
438  * @param handle WM8960 handle structure.
439  * @param module Modules need to be mute.
440  * @param isEnabled Mute or unmute, 1 represent mute.
441  */
442 void WM8960_SetMute(struct rt_i2c_bus_device *dev, wm8960_module_t module, rt_bool_t isEnabled);
443 
444 /*!
445  * @brief Enable/disable expected devices.
446  *
447  * @param handle WM8960 handle structure.
448  * @param module Module expected to enable.
449  * @param isEnabled Enable or disable moudles.
450  */
451 void WM8960_SetModule(struct rt_i2c_bus_device *dev, wm8960_module_t module, rt_bool_t isEnabled);
452 
453 /*!
454  * @brief SET the WM8960 play source.
455  *
456  * @param handle WM8960 handle structure.
457  * @param playSource play source , can be a value combine of kWM8960_ModuleHeadphoneSourcePGA,
458  * kWM8960_ModuleHeadphoneSourceDAC, kWM8960_ModulePlaySourceInput, kWM8960_ModulePlayMonoRight,
459  * kWM8960_ModulePlayMonoLeft.
460  *
461  * @return kStatus_WM8904_Success if successful, different code otherwise..
462  */
463 void WM8960_SetPlay(struct rt_i2c_bus_device *dev, uint32_t playSource);
464 
465 /*!
466  * @brief Configure the data format of audio data.
467  *
468  * This function would configure the registers about the sample rate, bit depths.
469  *
470  * @param handle WM8960 handle structure pointer.
471  * @param sysclk system clock of the codec which can be generated by MCLK or PLL output.
472  * @param sample_rate Sample rate of audio file running in WM8960. WM8960 now
473  * supports 8k, 11.025k, 12k, 16k, 22.05k, 24k, 32k, 44.1k, 48k and 96k sample rate.
474  * @param bits Bit depth of audio file (WM8960 only supports 16bit, 20bit, 24bit
475  * and 32 bit in HW).
476  */
477 void WM8960_ConfigDataFormat(struct rt_i2c_bus_device *dev, uint32_t sysclk, rt_uint32_t sample_rate, rt_uint32_t bits);
478 
479 /*!
480  * @brief Enable/disable jack detect feature.
481  *
482  * @param handle WM8960 handle structure.
483  * @param isEnabled Enable or disable moudles.
484  */
485 void WM8960_SetJackDetect(struct rt_i2c_bus_device *dev, rt_bool_t isEnabled);
486 
487 /*!
488  * @brief Write register to WM8960 using I2C.
489  *
490  * @param handle WM8960 handle structure.
491  * @param reg The register address in WM8960.
492  * @param val Value needs to write into the register.
493  */
494 void wm8960_write_reg(struct rt_i2c_bus_device *dev, rt_uint8_t reg, rt_uint16_t val);
495 
496 /*!
497  * @brief Read register from WM8960 using I2C.
498  * @param handle WM8960 handle structure.
499  * @param reg The register address in WM8960.
500  * @param val Value written to.
501  */
502 void wm8960_read_reg(struct rt_i2c_bus_device *dev, rt_uint8_t reg, rt_uint16_t *val);
503 
504 /*!
505  * @brief Modify some bits in the register using I2C.
506  * @param handle WM8960 handle structure.
507  * @param reg The register address in WM8960.
508  * @param mask The mask code for the bits want to write. The bit you want to write should be 0.
509  * @param val Value needs to write into the register.
510  */
511 void wm8960_modify_reg(struct rt_i2c_bus_device *dev, rt_uint8_t reg, rt_uint16_t mask, rt_uint16_t val);
512 
513 #if defined(__cplusplus)
514 }
515 #endif
516 
517 /*! @} */
518 
519 #endif /* _FSL_WM8960_H_ */
520 
521 /*******************************************************************************
522  * API
523  ******************************************************************************/
524