1 /*
2  * The Clear BSD License
3  * Copyright (c) 2016, Freescale Semiconductor, Inc.
4  * Copyright 2016-2017 NXP
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted (subject to the limitations in the disclaimer below) provided
9  * that the following conditions are met:
10  *
11  * o Redistributions of source code must retain the above copyright notice, this list
12  *   of conditions and the following disclaimer.
13  *
14  * o Redistributions in binary form must reproduce the above copyright notice, this
15  *   list of conditions and the following disclaimer in the documentation and/or
16  *   other materials provided with the distribution.
17  *
18  * o Neither the name of the copyright holder nor the names of its
19  *   contributors may be used to endorse or promote products derived from this
20  *   software without specific prior written permission.
21  *
22  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
27  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Change Logs:
35  * Date           Author       Notes
36  * 2019-11-09     LiWeiHao     Porting to RT-Thread
37  */
38 
39 #ifndef _FSL_WM8904_H_
40 #define _FSL_WM8904_H_
41 
42 #include "fsl_common.h"
43 #include "rtdevice.h"
44 #include "rtthread.h"
45 
46 /*!
47  * @addtogroup wm8904
48  * @{
49  */
50 
51 /*******************************************************************************
52  * Definitions
53  ******************************************************************************/
54 
55 /*! @brief WM8904 I2C address. */
56 #define WM8904_I2C_ADDRESS (0x1A)
57 
58 /*! @brief WM8904 I2C bit rate. */
59 #define WM8904_I2C_BITRATE (400000U)
60 
61 /*! @brief WM8904 status return codes. */
62 enum _wm8904_status
63 {
64     kStatus_WM8904_Success = 0x0, /*!< Success */
65     kStatus_WM8904_Fail = 0x1    /*!< Failure */
66 };
67 
68 /*! @brief The audio data transfer protocol. */
69 typedef enum _wm8904_protocol
70 {
71     kWM8904_ProtocolRightJustified = 0x0, /*!< Right justified mode */
72     kWM8904_ProtocolLeftJustified = 0x1,  /*!< Left justified mode */
73     kWM8904_ProtocolI2S = 0x2,            /*!< I2S mode */
74     kWM8904_ProtocolDSP = 0x3             /*!< DSP mode */
75 } wm8904_protocol_t;
76 
77 /*! @brief The SYSCLK / fs ratio. */
78 typedef enum _wm8904_fs_ratio
79 {
80     kWM8904_FsRatio64X = 0x0,   /*!< SYSCLK is   64 * sample rate * frame width */
81     kWM8904_FsRatio128X = 0x1,  /*!< SYSCLK is  128 * sample rate * frame width */
82     kWM8904_FsRatio192X = 0x2,  /*!< SYSCLK is  192 * sample rate * frame width */
83     kWM8904_FsRatio256X = 0x3,  /*!< SYSCLK is  256 * sample rate * frame width */
84     kWM8904_FsRatio384X = 0x4,  /*!< SYSCLK is  384 * sample rate * frame width */
85     kWM8904_FsRatio512X = 0x5,  /*!< SYSCLK is  512 * sample rate * frame width */
86     kWM8904_FsRatio768X = 0x6,  /*!< SYSCLK is  768 * sample rate * frame width */
87     kWM8904_FsRatio1024X = 0x7, /*!< SYSCLK is 1024 * sample rate * frame width */
88     kWM8904_FsRatio1408X = 0x8, /*!< SYSCLK is 1408 * sample rate * frame width */
89     kWM8904_FsRatio1536X = 0x9  /*!< SYSCLK is 1536 * sample rate * frame width */
90 } wm8904_fs_ratio_t;
91 
92 /*! @brief Sample rate. */
93 typedef enum _wm8904_sample_rate
94 {
95     kWM8904_SampleRate8kHz = 0x0,  /*!< 8 kHz */
96     kWM8904_SampleRate12kHz = 0x1, /*!< 11.025kHz, 12kHz */
97     kWM8904_SampleRate16kHz = 0x2, /*!< 16kHz */
98     kWM8904_SampleRate24kHz = 0x3, /*!< 22.05kHz, 24kHz */
99     kWM8904_SampleRate32kHz = 0x4, /*!< 32kHz */
100     kWM8904_SampleRate48kHz = 0x5  /*!< 44.1kHz, 48kHz */
101 } wm8904_sample_rate_t;
102 
103 /*! @brief Bit width. */
104 typedef enum _wm8904_bit_width
105 {
106     kWM8904_BitWidth16 = 0x0, /*!< 16 bits */
107     kWM8904_BitWidth20 = 0x1, /*!< 20 bits */
108     kWM8904_BitWidth24 = 0x2, /*!< 24 bits */
109     kWM8904_BitWidth32 = 0x3  /*!< 32 bits */
110 } wm8904_bit_width_t;
111 
112 /*! @brief Audio format configuration. */
113 typedef struct _wm8904_audio_format
114 {
115     wm8904_fs_ratio_t fsRatio;       /*!< SYSCLK / fs ratio */
116     wm8904_sample_rate_t sampleRate; /*!< Sample rate */
117     wm8904_bit_width_t bitWidth;     /*!< Bit width */
118 } wm8904_audio_format_t;
119 
120 /*! @brief WM8904 data. */
121 typedef struct _wm8904_handle
122 {
123     struct rt_i2c_bus_device *i2c; /*!< Configured I2C instance */
124 } wm8904_handle_t;
125 
126 /*! @brief Configuration structure of WM8904. */
127 typedef struct _wm8904_config
128 {
129     bool master;                  /*!< Master or slave */
130     wm8904_protocol_t protocol;   /*!< Audio transfer protocol */
131     wm8904_audio_format_t format; /*!< Audio format */
132 } wm8904_config_t;
133 
134 /*******************************************************************************
135  * API
136  ******************************************************************************/
137 #if defined(__cplusplus)
138 extern "C"
139 {
140 #endif
141 
142 /*!
143 * @brief Initializes WM8904.
144 *
145 * @param handle WM8904 handle structure.
146 * @param codec_config WM8904 configuration structure.
147 */
148 status_t WM8904_Init(wm8904_handle_t *handle, wm8904_config_t *config);
149 
150 /*!
151 * @brief Deinitializes the WM8904 codec.
152 *
153 * This function resets WM8904.
154 *
155 * @param handle WM8904 handle structure.
156 *
157 * @return kStatus_WM8904_Success if successful, different code otherwise.
158 */
159 status_t WM8904_Deinit(wm8904_handle_t *handle);
160 
161 /*!
162 * @brief Fills the configuration structure with default values.
163 *
164 * The default values are:
165 *
166 *   master = false;
167 *   protocol = kWM8904_ProtocolI2S;
168 *   format.fsRatio = kWM8904_FsRatio64X;
169 *   format.sampleRate = kWM8904_SampleRate48kHz;
170 *   format.bitWidth = kWM8904_BitWidth16;
171 *
172 * @param handle WM8904 handle structure to be filled with default values.
173 */
174 void WM8904_GetDefaultConfig(wm8904_config_t *config);
175 
176 /*!
177 * @brief Sets WM8904 as master or slave.
178 *
179 * @param handle WM8904 handle structure.
180 * @param master true for master, false for slave.
181 *
182 * @return kStatus_WM8904_Success if successful, different code otherwise.
183 */
184 status_t WM8904_SetMasterSlave(wm8904_handle_t *handle, bool master);
185 
186 /*!
187 * @brief Sets the audio data transfer protocol.
188 *
189 * @param handle WM8904 handle structure.
190 * @param protocol Audio transfer protocol.
191 *
192 * @return kStatus_WM8904_Success if successful, different code otherwise.
193 */
194 status_t WM8904_SetProtocol(wm8904_handle_t *handle, wm8904_protocol_t protocol);
195 
196 /*!
197 * @brief Sets the audio data format.
198 *
199 * @param handle WM8904 handle structure.
200 * @param format Audio format parameters.
201 *
202 * @return kStatus_WM8904_Success if successful, different code otherwise.
203 */
204 status_t WM8904_SetAudioFormat(wm8904_handle_t *handle, wm8904_audio_format_t *format);
205 
206 /*!
207 * @brief Sets the headphone output volume.
208 *
209 * The parameter should be from 0 to 63.
210 * The resulting volume will be (parameter - 57 dB).
211 * 0 for -57 dB, 57 for 0 dB, 63 for +6 dB etc.
212 *
213 * @param handle WM8904 handle structure.
214 * @param volumeLeft Volume of the left channel.
215 * @param volumeRight Volume of the right channel.
216 *
217 * @return kStatus_WM8904_Success if successful, different code otherwise.
218 */
219 status_t WM8904_SetVolume(wm8904_handle_t *handle, uint16_t volumeLeft, uint16_t volumeRight);
220 
221 /*!
222 * @brief Sets the headphone output mute.
223 *
224 * @param handle WM8904 handle structure.
225 * @param muteLeft true to mute left channel, false to unmute.
226 * @param muteRight true to mute right channel, false to unmute.
227 *
228 * @return kStatus_WM8904_Success if successful, different code otherwise.
229 */
230 status_t WM8904_SetMute(wm8904_handle_t *handle, bool muteLeft, bool muteRight);
231 
232 /*!
233 * @brief Reads content of all WM8904 registers and prints it to debug console.
234 *
235 * @param handle WM8904 handle structure.
236 *
237 * @return kStatus_WM8904_Success if successful, different code otherwise.
238 */
239 status_t WM8904_PrintRegisters(wm8904_handle_t *handle);
240 
241 #if defined(__cplusplus)
242 }
243 #endif
244 
245 /*! @} */
246 
247 #endif /* _FSL_WM8904_H_ */
248