1 /*
2  * Copyright  2017-2021 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _FSL_CS42448_H_
10 #define _FSL_CS42448_H_
11 
12 #include "fsl_codec_i2c.h"
13 
14 /*!
15  * @addtogroup cs42448
16  * @ingroup codec
17  * @{
18  */
19 
20 /*******************************************************************************
21  * Definitions
22  ******************************************************************************/
23 /*! @name Driver version */
24 /*@{*/
25 /*! @brief cs42448 driver version 2.0.1. */
26 #define FSL_CS42448_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
27 /*@}*/
28 
29 /*! @brief CS42448 handle size */
30 #ifndef CS42448_I2C_HANDLER_SIZE
31 #define CS42448_I2C_HANDLER_SIZE CODEC_I2C_MASTER_HANDLER_SIZE
32 #endif
33 
34 /*! @brief Define the register address of CS42448. */
35 #define CS42448_ID                 0x01U
36 #define CS42448_POWER_CONTROL      0x02U
37 #define CS42448_FUNCTIONAL_MODE    0x03U
38 #define CS42448_INTERFACE_FORMATS  0x04U
39 #define CS42448_ADC_CONTROL        0x05U
40 #define CS42448_TRANSITION_CONTROL 0x06U
41 #define CS42448_CHANNEL_MUTE       0x07U
42 #define CS42448_VOL_CONTROL_AOUT1  0x08U
43 #define CS42448_VOL_CONTROL_AOUT2  0x09U
44 #define CS42448_VOL_CONTROL_AOUT3  0x0AU
45 #define CS42448_VOL_CONTROL_AOUT4  0x0BU
46 #define CS42448_VOL_CONTROL_AOUT5  0x0CU
47 #define CS42448_VOL_CONTROL_AOUT6  0x0DU
48 #define CS42448_VOL_CONTROL_AOUT7  0x0EU
49 #define CS42448_VOL_CONTROL_AOUT8  0x0FU
50 #define CS42448_DAC_CHANNEL_INVERT 0x10U
51 #define CS42448_VOL_CONTROL_AIN1   0x11U
52 #define CS42448_VOL_CONTROL_AIN2   0x12U
53 #define CS42448_VOL_CONTROL_AIN3   0x13U
54 #define CS42448_VOL_CONTROL_AIN4   0x14U
55 #define CS42448_ADC_CHANNEL_INVERT 0x17U
56 #define CS42448_STATUS_CONTROL     0x18U
57 #define CS42448_STATUS             0x19U
58 #define CS42448_STATUS_MASK        0x1AU
59 #define CS42448_MUTEC_PIN_CONTROL  0x1BU
60 
61 #define CS42448_POWER_CONTROL_PDN_MASK  0x1U
62 #define CS42448_POWER_CONTROL_PDN_SHIFT 0U
63 #define CS42448_POWER_CONTROL_PDN(x) \
64     (((uint8_t)((uint8_t)(x) << CS42448_POWER_CONTROL_PDN_SHIFT)) & CS42448_POWER_CONTROL_PDN_MASK)
65 #define CS42448_POWER_CONTROL_PDN_DAC1_MASK  0x2U
66 #define CS42448_POWER_CONTROL_PDN_DAC1_SHIFT 2U
67 #define CS42448_POWER_CONTROL_PDN_DAC1(x) \
68     (((uint8_t)((uint8_t)(x) << CS42448_POWER_CONTROL_PDN_DAC1_SHIFT)) & CS42448_POWER_CONTROL_PDN_DAC1_MASK)
69 #define CS42448_POWER_CONTROL_PDN_DAC2_MASK  0x4U
70 #define CS42448_POWER_CONTROL_PDN_DAC2_SHIFT 3U
71 #define CS42448_POWER_CONTROL_PDN_DAC2(x) \
72     (((uint8_t)((uint8_t)(x) << CS42448_POWER_CONTROL_PDN_DAC2_SHIFT)) & CS42448_POWER_CONTROL_PDN_DAC2_MASK)
73 #define CS42448_POWER_CONTROL_PDN_DAC3_MASK  0x8U
74 #define CS42448_POWER_CONTROL_PDN_DAC3_SHIFT 4U
75 #define CS42448_POWER_CONTROL_PDN_DAC3(x) \
76     (((uint8_t)((uint8_t)(x) << CS42448_POWER_CONTROL_PDN_DAC3_SHIFT)) & CS42448_POWER_CONTROL_PDN_DAC3_MASK)
77 #define CS42448_POWER_CONTROL_PDN_DAC4_MASK  0x10U
78 #define CS42448_POWER_CONTROL_PDN_DAC4_SHIFT 5U
79 #define CS42448_POWER_CONTROL_PDN_DAC4(x) \
80     (((uint8_t)((uint8_t)(x) << CS42448_POWER_CONTROL_PDN_DAC4_SHIFT)) & CS42448_POWER_CONTROL_PDN_DAC4_MASK)
81 #define CS42448_POWER_CONTROL_PDN_ADC1_MASK  0x20U
82 #define CS42448_POWER_CONTROL_PDN_ADC1_SHIFT 5U
83 #define CS42448_POWER_CONTROL_PDN_ADC1(x) \
84     (((uint8_t)((uint8_t)(x) << CS42448_POWER_CONTROL_PDN_ADC1_SHIFT)) & CS42448_POWER_CONTROL_PDN_ADC1_MASK)
85 #define CS42448_POWER_CONTROL_PDN_ADC2_MASK  0x40U
86 #define CS42448_POWER_CONTROL_PDN_ADC2_SHIFT 6U
87 #define CS42448_POWER_CONTROL_PDN_ADC2(x) \
88     (((uint8_t)((uint8_t)(x) << CS42448_POWER_CONTROL_PDN_ADC2_SHIFT)) & CS42448_POWER_CONTROL_PDN_ADC2_MASK)
89 
90 #define CS42448_FUNCTIONAL_MODE_ADC_FM_MASK  0x30U
91 #define CS42448_FUNCTIONAL_MODE_ADC_FM_SHIFT 4U
92 #define CS42448_FUNCTIONAL_MODE_ADC_FM(x) \
93     (((uint8_t)((uint8_t)(x) << CS42448_FUNCTIONAL_MODE_ADC_FM_SHIFT)) & CS42448_FUNCTIONAL_MODE_ADC_FM_MASK)
94 #define CS42448_FUNCTIONAL_MODE_DAC_FM_MASK  0xC0U
95 #define CS42448_FUNCTIONAL_MODE_DAC_FM_SHIFT 6U
96 #define CS42448_FUNCTIONAL_MODE_DAC_FM(x) \
97     (((uint8_t)((uint8_t)(x) << CS42448_FUNCTIONAL_MODE_DAC_FM_SHIFT)) & CS42448_FUNCTIONAL_MODE_DAC_FM_MASK)
98 
99 #define CS42448_INTERFACE_FORMATS_DAC_DIF_MASK  0x38U
100 #define CS42448_INTERFACE_FORMATS_DAC_DIF_SHIFT 3U
101 #define CS42448_INTERFACE_FORMATS_DAC_DIF(x) \
102     (((uint8_t)((uint8_t)(x) << CS42448_INTERFACE_FORMATS_DAC_DIF_SHIFT)) & CS42448_INTERFACE_FORMATS_DAC_DIF_MASK)
103 
104 /*! @brief CS42448 volume setting range */
105 #define CS42448_AOUT_MAX_VOLUME_VALUE 0xFFU
106 
107 /*! @brief Cache register number */
108 #define CS42448_CACHEREGNUM 28U
109 
110 /*! @brief CS42448 I2C address. */
111 #define CS42448_I2C_ADDR 0x48U
112 
113 /*! @brief CS42448 I2C baudrate */
114 #define CS42448_I2C_BITRATE (100000U)
115 
116 /*! @brief cs42448 reset function pointer */
117 typedef void (*cs42448_reset)(bool state);
118 
119 /*! @brief CS42448 support modes. */
120 typedef enum _cs42448_func_mode
121 {
122     kCS42448_ModeMasterSSM = 0x0, /*!< master single speed mode */
123     kCS42448_ModeMasterDSM = 0x1, /*!< master dual speed mode */
124     kCS42448_ModeMasterQSM = 0x2, /*!< master quad speed mode */
125     kCS42448_ModeSlave     = 0x3, /*!< master single speed mode */
126 } cs42448_func_mode;
127 
128 /*! @brief Modules in CS42448 board. */
129 typedef enum _cs42448_module
130 {
131     kCS42448_ModuleDACPair1 = 0x2,  /*!< DAC pair1 (AOUT1 and AOUT2) module in CS42448 */
132     kCS42448_ModuleDACPair2 = 0x4,  /*!< DAC pair2 (AOUT3 and AOUT4) module in CS42448 */
133     kCS42448_ModuleDACPair3 = 0x8,  /*!< DAC pair3 (AOUT5 and AOUT6) module in CS42448 */
134     kCS42448_ModuleDACPair4 = 0x10, /*!< DAC pair4 (AOUT7 and AOUT8) module in CS42448 */
135     kCS42448_ModuleADCPair1 = 0x20, /*!< ADC pair1 (AIN1 and AIN2) module in CS42448 */
136     kCS42448_ModuleADCPair2 = 0x40, /*!< ADC pair2 (AIN3 and AIN4) module in CS42448 */
137     kCS42448_ModuleADCPair3 = 0x80, /*!< ADC pair3 (AIN5 and AIN6) module in CS42448 */
138 } cs42448_module_t;
139 
140 /*! @brief CS42448 supported audio bus type. */
141 typedef enum _cs42448_bus
142 {
143     kCS42448_BusLeftJustified  = 0x0, /*!< Left justified format, up to 24 bits.*/
144     kCS42448_BusI2S            = 0x1, /*!< I2S format, up to 24 bits */
145     kCS42448_BusRightJustified = 0x2, /*!< Right justified, can support 16bits and 24 bits */
146     kCS42448_BusOL1            = 0x4, /*!< One-Line #1 mode */
147     kCS42448_BusOL2            = 0x5, /*!< One-Line #2 mode */
148     kCS42448_BusTDM            = 0x6  /*!< TDM mode */
149 } cs42448_bus_t;
150 
151 /*! @brief CS424488 play channel
152  * @anchor _cs42448_play_channel
153  */
154 enum
155 {
156     kCS42448_AOUT1 = 1U, /*!< aout1 */
157     kCS42448_AOUT2 = 2U, /*!< aout2 */
158     kCS42448_AOUT3 = 3U, /*!< aout3 */
159     kCS42448_AOUT4 = 4U, /*!< aout4 */
160     kCS42448_AOUT5 = 5U, /*!< aout5 */
161     kCS42448_AOUT6 = 6U, /*!< aout6 */
162     kCS42448_AOUT7 = 7U, /*!< aout7 */
163     kCS42448_AOUT8 = 8U, /*!< aout8 */
164 };
165 
166 /*! @brief cs42448 audio format */
167 typedef struct _cs42448_audio_format
168 {
169     uint32_t mclk_HZ;    /*!< master clock frequency */
170     uint32_t sampleRate; /*!< sample rate */
171     uint32_t bitWidth;   /*!< bit width */
172 } cs42448_audio_format_t;
173 
174 /*! @brief Initialize structure of CS42448 */
175 typedef struct cs42448_config
176 {
177     cs42448_bus_t bus;             /*!< Audio transfer protocol */
178     cs42448_audio_format_t format; /*!< cs42448 audio format */
179     cs42448_func_mode ADCMode;     /*!< CS42448 ADC function mode. */
180     cs42448_func_mode DACMode;     /*!< CS42448 DAC function mode. */
181     bool master;                   /*!< true is master, false is slave */
182     codec_i2c_config_t i2cConfig;  /*!< i2c bus configuration */
183     uint8_t slaveAddress;          /*!< slave address */
184     cs42448_reset reset;           /*!< reset function pointer */
185 } cs42448_config_t;
186 
187 /*! @brief cs42448 handler */
188 typedef struct _cs42448_handle
189 {
190     cs42448_config_t *config;                    /*!< cs42448 config pointer */
191     uint8_t i2cHandle[CS42448_I2C_HANDLER_SIZE]; /*!< i2c handle pointer */
192 } cs42448_handle_t;
193 
194 /*******************************************************************************
195  * API
196  ******************************************************************************/
197 #if defined(__cplusplus)
198 extern "C" {
199 #endif
200 
201 /*!
202  * @brief CS42448 initialize function.
203  *
204  * The second parameter is NULL to CS42448 in this version. If users want
205  * to change the settings, they have to use cs42448_write_reg() or cs42448_modify_reg()
206  * to set the register value of CS42448.
207  * Note: If the codec_config is NULL, it would initialize CS42448 using default settings.
208  * The default setting:
209  * codec_config->bus = kCS42448_BusI2S
210  * codec_config->ADCmode = kCS42448_ModeSlave
211  * codec_config->DACmode = kCS42448_ModeSlave
212  *
213  * @param handle CS42448 handle structure.
214  * @param config CS42448 configuration structure.
215  */
216 status_t CS42448_Init(cs42448_handle_t *handle, cs42448_config_t *config);
217 
218 /*!
219  * @brief Deinit the CS42448 codec.
220  *
221  * This function close all modules in CS42448 to save power.
222  *
223  * @param handle CS42448 handle structure pointer.
224  */
225 status_t CS42448_Deinit(cs42448_handle_t *handle);
226 
227 /*!
228  * @brief Set the audio transfer protocol.
229  *
230  * CS42448 only supports I2S, left justified, right justified, PCM A, PCM B format.
231  *
232  * @param handle CS42448 handle structure.
233  * @param protocol Audio data transfer protocol.
234  * @param bitWidth bit width
235  */
236 status_t CS42448_SetProtocol(cs42448_handle_t *handle, cs42448_bus_t protocol, uint32_t bitWidth);
237 
238 /*!
239  * @brief Set CS42448 to differernt working mode.
240  *
241  * @deprecated api, Do not use it anymore. It has been superceded by @ref CS42448_SelectFunctionalMode.
242  *
243  * @param handle CS42448 handle structure.
244  * @param mode differenht working mode of CS42448.
245  */
246 void CS42448_SetFuncMode(cs42448_handle_t *handle, cs42448_func_mode mode);
247 
248 /*!
249  * @brief Set CS42448 to differernt functional mode.
250  *
251  * @param handle CS42448 handle structure.
252  * @param adcMode differenht working mode of CS42448.
253  * @param dacMode differenht working mode of CS42448.
254  */
255 status_t CS42448_SelectFunctionalMode(cs42448_handle_t *handle, cs42448_func_mode adcMode, cs42448_func_mode dacMode);
256 
257 /*!
258  * @brief Set the volume of different modules in CS42448.
259  *
260  * This function would set the volume of CS42448 modules. Uses need to appoint the module.
261  * The function assume that left channel and right channel has the same volume.
262  *
263  * @param handle CS42448 handle structure.
264  * @param channel AOUT channel, it shall be 1~8.
265  * @param volume Volume value need to be set.
266  */
267 status_t CS42448_SetAOUTVolume(cs42448_handle_t *handle, uint8_t channel, uint8_t volume);
268 
269 /*!
270  * @brief Set the volume of different modules in CS42448.
271  *
272  * This function would set the volume of CS42448 modules. Uses need to appoint the module.
273  * The function assume that left channel and right channel has the same volume.
274  *
275  * @param handle CS42448 handle structure.
276  * @param channel AIN channel, it shall be 1~4.
277  * @param volume Volume value need to be set.
278  */
279 status_t CS42448_SetAINVolume(cs42448_handle_t *handle, uint8_t channel, uint8_t volume);
280 
281 /*!
282  * @brief Get the volume of different AOUT channel in CS42448.
283  *
284  * This function gets the volume of CS42448 modules. Uses need to appoint the module.
285  * The function assume that left channel and right channel has the same volume.
286  *
287  * @param handle CS42448 handle structure.
288  * @param channel AOUT channel, it shall be 1~8.
289  */
290 uint8_t CS42448_GetAOUTVolume(cs42448_handle_t *handle, uint8_t channel);
291 
292 /*!
293  * @brief Get the volume of different AIN channel in CS42448.
294  *
295  * This function gets the volume of CS42448 modules. Uses need to appoint the module.
296  * The function assume that left channel and right channel has the same volume.
297  *
298  * @param handle CS42448 handle structure.
299  * @param channel AIN channel, it shall be 1~4.
300  */
301 uint8_t CS42448_GetAINVolume(cs42448_handle_t *handle, uint8_t channel);
302 
303 /*!
304  * @brief Mute modules in CS42448.
305  *
306  * @param handle CS42448 handle structure.
307  * @param channelMask Channel mask for mute. Mute channel 0, it shall be 0x1, while mute channel 0 and 1, it shall
308  * be 0x3. Mute all channel, it shall be 0xFF. Each bit represent one channel, 1 means mute, 0 means unmute.
309  */
310 status_t CS42448_SetMute(cs42448_handle_t *handle, uint8_t channelMask);
311 
312 /*!
313  * @brief Mute channel modules in CS42448.
314  *
315  * @param handle CS42448 handle structure.
316  * @param channel reference _cs42448_play_channel.
317  * @param isMute true is mute, falase is unmute.
318  */
319 status_t CS42448_SetChannelMute(cs42448_handle_t *handle, uint8_t channel, bool isMute);
320 
321 /*!
322  * @brief Enable/disable expected devices.
323  *
324  * @param handle CS42448 handle structure.
325  * @param module Module expected to enable.
326  * @param isEnabled Enable or disable moudles.
327  */
328 status_t CS42448_SetModule(cs42448_handle_t *handle, cs42448_module_t module, bool isEnabled);
329 
330 /*!
331  * @brief Configure the data format of audio data.
332  *
333  * This function would configure the registers about the sample rate, bit depths.
334  *
335  * @param handle CS42448 handle structure pointer.
336  * @param mclk Master clock frequency of I2S.
337  * @param sample_rate Sample rate of audio file running in CS42448. CS42448 now
338  * supports 8k, 11.025k, 12k, 16k, 22.05k, 24k, 32k, 44.1k, 48k and 96k sample rate.
339  * @param bits Bit depth of audio file (CS42448 only supports 16bit, 20bit, 24bit
340  * and 32 bit in HW).
341  */
342 status_t CS42448_ConfigDataFormat(cs42448_handle_t *handle, uint32_t mclk, uint32_t sample_rate, uint32_t bits);
343 
344 /*!
345  * @brief Write register to CS42448 using I2C.
346  *
347  * @param handle CS42448 handle structure.
348  * @param reg The register address in CS42448.
349  * @param val Value needs to write into the register.
350  */
351 status_t CS42448_WriteReg(cs42448_handle_t *handle, uint8_t reg, uint8_t val);
352 
353 /*!
354  * @brief Read register from CS42448 using I2C.
355  * @param handle CS42448 handle structure.
356  * @param reg The register address in CS42448.
357  * @param val Value written to.
358  */
359 status_t CS42448_ReadReg(cs42448_handle_t *handle, uint8_t reg, uint8_t *val);
360 
361 /*!
362  * @brief Modify some bits in the register using I2C.
363  * @param handle CS42448 handle structure.
364  * @param reg The register address in CS42448.
365  * @param mask The mask code for the bits want to write. The bit you want to write should be 0.
366  * @param val Value needs to write into the register.
367  */
368 status_t CS42448_ModifyReg(cs42448_handle_t *handle, uint8_t reg, uint8_t mask, uint8_t val);
369 
370 #if defined(__cplusplus)
371 }
372 #endif
373 
374 /*! @} */
375 
376 #endif /* _FSL_CS42448_H_ */
377