1 /*
2  * Copyright  2019 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 /*
9  * fsl_tfa9xxx.h
10  *
11  */
12 
13 #ifndef FSL_TFA9XXX_H_
14 #define FSL_TFA9XXX_H_
15 
16 #include "tfa2_container.h"
17 #include "tfa2_dev.h"
18 #include "fsl_common.h"
19 #include "fsl_codec_i2c.h"
20 
21 /*!
22  * @addtogroup tfa9xxx
23  * @ingroup codec
24  * @{
25  */
26 /*******************************************************************************
27  * Definitions
28  ******************************************************************************/
29 /*! @name Driver version */
30 /*@{*/
31 /*! @brief TFA9XXX driver version 8.1.2. */
32 #define FSL_TFA9XXX_DRIVER_VERSION (MAKE_VERSION(8, 1, 2))
33 /*@}*/
34 
35 /*! @brief tfa9xxx handle size */
36 #ifndef TFA9XXX_I2C_HANDLER_SIZE
37 #define TFA9XXX_I2C_HANDLER_SIZE (CODEC_I2C_MASTER_HANDLER_SIZE)
38 #endif
39 
40 /*! @brief TFA9XXX_ I2C baudrate */
41 #define TFA9XXX_I2C_BAUDRATE        (400000U)
42 #define TFA9XXX_DEV_NUM             2 /* The total number of TFA device */
43 #define TFA9XXX_I2C_ADDR_0          0x34
44 #define TFA9XXX_I2C_ADDR_1          0x35
45 #define TFA9XXX_I2C_ADDR_2          0x36
46 #define TFA9XXX_I2C_ADDR_3          0x37
47 #define BOARD_I2C_TRANSFER_SIZE_MAX 255U
48 
49 /*!
50  * @brief The audio data transfer protocol choice.
51  * TFA9XXX only supports I2S format.
52  */
53 typedef enum _tfa9xxx_protocol
54 {
55     kTFA9XXX_BusI2S = 0, /*!< I2S type */
56 } tfa9xxx_protocol_t;
57 
58 /*! @brief audio sample rate definition, more sample rates can be supported in the future */
59 enum _tfa9xxx_sample_rate
60 {
61     kTFA9XXX_AudioSampleRate48KHz = 48000U, /*!< Sample rate 48000 Hz */
62 };
63 
64 /*! @brief audio bit width, more bit width can be supported in the future */
65 enum _tfa9xxx_audio_bit_width
66 {
67     kTFA9XXX_AudioBitWidth16bit = 16U, /*!< audio bit width 16 */
68 };
69 
70 /*! @brief play channel */
71 enum _tfa98xxx_play_channel
72 {
73     kTFA9XXX_PlayChannelLeft0  = 1U, /*!< codec play channel left 0 */
74     kTFA9XXX_PlayChannelRight0 = 2U, /*!< codec play channel right 0 */
75 };
76 
77 /*! @brief tfa9xxx audio format */
78 typedef struct _tfa9xxx_audio_format
79 {
80     enum _tfa9xxx_sample_rate sampleRate;   /*!< sample rate */
81     enum _tfa9xxx_audio_bit_width bitWidth; /*!< bit width */
82 } tfa9xxx_audio_format_t;
83 
84 /*! @brief tfa9xxx device */
85 typedef struct tfa2_device tfa9xxx_device_t;
86 
87 /*! @brief Initialize structure of TFA9XXX */
88 typedef struct tfa9xxx_config
89 {
90     tfa9xxx_protocol_t protocol;   /*!< Audio transfer protocol */
91     tfa9xxx_audio_format_t format; /*!< Audio format */
92     uint8_t slaveAddress;          /*!< tfa9xxx device address */
93     codec_i2c_config_t i2cConfig;  /*!< i2c configuration */
94     uint8_t *tfaContainer;         /*!< tfa container array */
95     uint8_t deviceIndex;           /*!< tfa device index, starting from 0, up to TFA9XXX_DEV_NUM - 1 */
96 } tfa9xxx_config_t;
97 
98 /*! @brief tfa9xxx codec handler
99  * Application should allocate a buffer with TFA9XXX_HANDLE_SIZE for handle definition, such as
100  * uint8_t tfa9xxxHandleBuffer[TFA9XXX_HANDLE_SIZE];
101  * tfa9xxx_handle_t *tfa9xxxHandle = tfa9xxxHandleBuffer;
102  */
103 typedef struct _tfa9xxx_handle
104 {
105     tfa9xxx_config_t *config;                    /*!< tfa9xxx config pointer */
106     uint8_t i2cHandle[TFA9XXX_I2C_HANDLER_SIZE]; /*!< i2c handle */
107 } tfa9xxx_handle_t;
108 
109 /*******************************************************************************
110  * API
111  ******************************************************************************/
112 #if defined(__cplusplus)
113 extern "C" {
114 #endif
115 
116 /*!
117  * @brief Initialize the TFA, put the TFA to operating state, allocate memory side.
118  *
119  * @param handle TFA9XXX handle structure.
120  * @param tfa9xxxConfig TFA9XXX configuration structure.
121  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
122  */
123 status_t TFA9XXX_Init(tfa9xxx_handle_t *handle, tfa9xxx_config_t *tfa9xxxConfig);
124 
125 /*!
126  * @brief Deinitialize the TFA, put the TFA to powerdown state.
127  *
128  * @param handle TFA9XXX handle structure.
129  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
130  */
131 status_t TFA9XXX_Deinit(tfa9xxx_handle_t *handle);
132 
133 /*!
134  * @brief Mute/Unmute the TFA
135  *
136  * This function has dependency on internal structure, it has to be called after TFA9XXX_CreatePlatform();
137  *
138  * @param handle TFA9XXX handle structure.
139  * @param isMute true is mute, false is unmute..
140  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
141  */
142 status_t TFA9XXX_SetMute(tfa9xxx_handle_t *handle, bool isMute);
143 
144 /*!
145  * @brief Configure the TFA based on I2S format.
146  * Assuming TFA_Init() is already called by calling CODEC_Init(), the TFA will be in operating state. So before calling
147  * TFA_SetFormat(), the TFA needs to be in powerdown state by calling TFA_Stop().
148  *
149  * @param handle TFA9XXX handle structure.
150  * @param mclk The mclk.
151  * @param sampleRate The sample rate.
152  * @param bitWidth The bit width.
153  * @return Returns @ref kStatus_Success if success, otherwise returns error code.
154  */
155 status_t TFA9XXX_ConfigDataFormat(tfa9xxx_handle_t *handle, uint32_t mclk, uint32_t sampleRate, uint32_t bitWidth);
156 
157 /*!
158  * @brief Set the volume level.
159  *
160  * This function has dependency on internal structure, it has to be called after TFA9XXX_CreatePlatform();
161  *
162  * @param handle TFA9XXX handle structure.
163  * @param volume volume volume value, support 0 ~ 100, 0 is mute, 100 is the maximum volume value.
164  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
165  */
166 status_t TFA9XXX_SetVolume(tfa9xxx_handle_t *handle, uint32_t volume);
167 
168 /*!
169  * @brief Set the audio channel for a speaker.
170  * By default, I2S channel is configured by the `.tfaContainer` in `tfa9xxx_config_t`. So you don't need to call this
171  * function. However, if required, calling this function allows overwriting I2S channel selection. This can be useful
172  * when the tuning is done, and you simply want to change the I2S channel.
173  *
174  * This function has dependency on internal structure, it has to be called after TFA9XXX_CreatePlatform();
175  *
176  * @param handle TFA9XXX handle structure.
177  * @param playChannel _codec_play_channel play channel, available values are kCODEC_PlayChannelSpeakerLeft,
178  * kCODEC_PlayChannelSpeakerRight, kCODEC_PlayChannelSpeakerLeft | kCODEC_PlayChannelSpeakerRight.
179  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
180  */
181 status_t TFA9XXX_SetPlayChannel(tfa9xxx_handle_t *handle, uint32_t playChannel);
182 
183 /*!
184  * @brief Start the TFA.
185  *
186  * Start device will initialize if the device is in cold state
187  * if already warm then only clocks will be started.
188  *
189  * This function has dependency on internal structure, it has to be called after TFA9XXX_CreatePlatform();
190  *
191  * @param handle The TFA codec handle.
192  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
193  */
194 status_t TFA9XXX_Start(tfa9xxx_handle_t *handle);
195 
196 /*!
197  * @brief Stop the TFA
198  *
199  * Stop will put the TFA in powerdown/standby mode, the next time TFA start will be a warm start.
200  *
201  * This function has dependency on internal structure, it has to be called after TFA9XXX_CreatePlatform();
202  *
203  * @param handle The TFA9XXX handle structure.
204  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
205  */
206 status_t TFA9XXX_Stop(tfa9xxx_handle_t *handle);
207 
208 /*!
209  * @brief Reset the TFA
210  *
211  * Reset will put the in powerdown/standby mode, the next time TFA start will be a cold start.
212  *
213  * This function has dependency on internal structure, it has to be called after TFA9XXX_CreatePlatform();
214  *
215  * @param handle The TFA9XXX handle structure.
216  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
217  */
218 status_t TFA9XXX_Reset(tfa9xxx_handle_t *handle);
219 
220 /*!
221  * @brief check if TFA is calibrated.
222  *
223  * This function has dependency on internal structure, it has to be called after TFA9XXX_CreatePlatform();
224  *
225  * @param handle The TFA9XXX handle structure.
226  * @param isTFACalibrated This value stores if TFA is calibrated.
227  * @return status_t Returns kStatus_Success if operation is successfully, otherwise returns error code..
228  */
229 status_t TFA9XXX_CheckCalibrationStatus(tfa9xxx_handle_t *handle, bool *isTFACalibrated);
230 
231 /*!
232  * @brief Start Speakerboost Calibration.
233  *
234  * The calibration will measure speaker impedance, and calculate the speaker impedance at 25 degree.
235  * This value will be used to estimate the real-time temperature.
236  *
237  * This function has dependency on internal structure, it has to be called after TFA9XXX_CreatePlatform();
238  *
239  * @param handle The TFA codec handle.
240  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
241  */
242 status_t TFA9XXX_CalibrateSpeakerBoost(tfa9xxx_handle_t *handle);
243 
244 /*!
245  * @brief Hardcode calibration value for DSP usage instead of triggering calibration.
246  *
247  * This function has dependency on internal structure, it has to be called after TFA9XXX_CreatePlatform();
248  *
249  * @param handle TFA9XXX handle structure.
250  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
251  */
252 status_t TFA9XXX_HardcodeCalibrationValue(tfa9xxx_handle_t *handle);
253 
254 /*!
255  * @brief Get the status of a running TFA.
256  *
257  * This function has dependency on internal structure, it has to be called after TFA9XXX_CreatePlatform();
258  *
259  * @param handle The TFA9XXX handle structure.
260  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
261  */
262 status_t TFA9XXX_GetStatus(tfa9xxx_handle_t *handle);
263 
264 /*!
265  * @brief Convert the return check value from TFA driver to predefined error code.
266  *
267  * @param rc Return check value from TFA driver.
268  * @return status_t Returns kStatus_Success if success, otherwise returns error code.
269  */
270 status_t TFA9XXX_ConvertErrorCode(int32_t rc);
271 
272 #if defined(__cplusplus)
273 }
274 #endif
275 
276 /*! @} */
277 #endif /* FSL_TFA9XXX_H_ */
278