1 /*
2 * Copyright (c) 2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_SMIX_DRV_H
9 #define HPM_SMIX_DRV_H
10
11 #include "hpm_common.h"
12 #include "hpm_soc_feature.h"
13 #include "hpm_smix_regs.h"
14 #include <math.h>
15
16 /**
17 * @brief SMIX driver APIs
18 * @defgroup smix_interface SMIX driver APIs
19 * @ingroup smix_interface
20 * @{
21 */
22
23 typedef enum {
24 smix_dma_transfer_burst_1t = 0U,
25 smix_dma_transfer_burst_2t = 1U,
26 smix_dma_transfer_burst_4t = 2U,
27 smix_dma_transfer_burst_8t = 3U,
28 smix_dma_transfer_burst_16t = 4U,
29 smix_dma_transfer_burst_32t = 5U,
30 smix_dma_transfer_burst_64t = 6U,
31 smix_dma_transfer_burst_128t = 7U,
32 } smix_dma_transfer_burst_t;
33
34 typedef enum {
35 smix_dma_transfer_byte = 0U,
36 smix_dma_transfer_half_word = 1U,
37 smix_dma_transfer_word = 2U,
38 } smix_dma_transfer_width_t;
39
40 typedef enum {
41 smix_dma_address_increment = 0U,
42 smix_dma_address_decrement = 1U,
43 smix_dma_address_fixed = 2U
44 } smix_dma_address_control_t;
45
46 typedef enum {
47 smix_dma_mode_normal = 0,
48 smix_dma_mode_handshake = 1,
49 } smix_dma_handshake_mode_t;
50
51 typedef enum {
52 smix_dma_req_i2s0_rx = 6,
53 smix_dma_req_i2s0_tx = 7,
54 smix_dma_req_i2s1_rx = 8,
55 smix_dma_req_i2s1_tx = 9,
56 smix_dma_req_i2s2_rx = 10,
57 smix_dma_req_i2s2_tx = 11,
58 smix_dma_req_i2s3_rx = 12,
59 smix_dma_req_i2s3_tx = 13,
60
61 smix_dma_req_mixer_src_ch0 = 16,
62 smix_dma_req_mixer_src_ch1 = 17,
63 smix_dma_req_mixer_src_ch2 = 18,
64 smix_dma_req_mixer_src_ch3 = 19,
65 smix_dma_req_mixer_src_ch4 = 20,
66 smix_dma_req_mixer_src_ch5 = 21,
67 smix_dma_req_mixer_src_ch6 = 22,
68 smix_dma_req_mixer_src_ch7 = 23,
69 smix_dma_req_mixer_src_ch8 = 24,
70 smix_dma_req_mixer_src_ch9 = 25,
71 smix_dma_req_mixer_src_ch10 = 26,
72 smix_dma_req_mixer_src_ch11 = 27,
73 smix_dma_req_mixer_src_ch12 = 28,
74 smix_dma_req_mixer_src_ch13 = 29,
75
76 smix_dma_req_mixer_dst_ch0 = 30,
77 smix_dma_req_mixer_dst_ch1 = 31,
78 } smix_dma_req_t;
79
80
81 typedef enum {
82 smix_src_clk_i2s0_bclk = 0,
83 smix_src_clk_i2s0_fclk = 1,
84 smix_src_clk_i2s0_mclk = 2,
85 smix_src_clk_i2s1_bclk = 3,
86 smix_src_clk_i2s1_fclk = 4,
87 smix_src_clk_i2s1_mclk = 5,
88 smix_src_clk_i2s2_bclk = 6,
89 smix_src_clk_i2s2_fclk = 7,
90 smix_src_clk_i2s2_mclk = 8,
91 smix_src_clk_i2s3_bclk = 9,
92 smix_src_clk_i2s3_fclk = 10,
93 smix_src_clk_i2s3_mclk = 11,
94 smix_src_clk_none = 15,
95 } smix_src_clk_source_t;
96
97
98 typedef struct {
99 uint32_t ctrl; /**< Control */
100 uint32_t trans_size; /**< Transfer size in source width */
101 uint32_t src_addr; /**< Source address */
102 uint32_t reserved0; /**< reserved */
103 uint32_t dst_addr; /**< Destination address */
104 uint32_t reserved1; /**< reserved */
105 uint32_t linked_ptr; /**< Linked descriptor address */
106 uint32_t reserved2; /**< resetved */
107 } smix_dma_linked_descriptor_t;
108
109
110 typedef struct {
111 uint8_t priority; /**< Channel priority */
112 uint8_t src_burst_size; /**< Source burst size */
113 uint8_t src_req_sel;
114 uint8_t dst_req_sel;
115 uint8_t src_mode; /**< Source work mode */
116 uint8_t dst_mode; /**< Destination work mode */
117 uint8_t src_width; /**< Source width */
118 uint8_t dst_width; /**< Destination width */
119 uint8_t src_addr_ctrl; /**< Source address control */
120 uint8_t dst_addr_ctrl; /**< Destination address control */
121 bool abort_int_en; /**< enable abort interrupt */
122 bool error_int_en; /**< enable error interrupt */
123 bool complete_int_en; /**< enable complete interrupt */
124 uint32_t src_addr; /**< Source address */
125 uint32_t dst_addr; /**< Destination address */
126 uint32_t linked_ptr; /**< Next linked descriptor */
127 uint32_t trans_bytes; /**< Total size to be transferred in byte */
128 } smix_dma_ch_config_t;
129
130
131 typedef enum {
132 smix_mixer_gain_decrease_12db = 0x400,
133 smix_mixer_gain_decrease_6db = 0x800,
134 smix_mixer_gain_0db = 0xfff,
135 smix_mixer_gain_increase_6db = 0x1800,
136 smix_mixer_gain_increase_12db = 0x1fff,
137 } smix_mixer_gain_t;
138
139 typedef enum {
140 smix_mixer_no_rate_convert,
141 smix_mixer_upper_2x_sample,
142 smix_mixer_upper_3x_sample,
143 smix_mixer_upper_4x_sample,
144 smix_mixer_upper_6x_sample,
145 smix_mixer_upper_8x_sample,
146 smix_mixer_upper_12x_sample,
147 smix_mixer_lower_2x_sample,
148 } smix_mixer_rate_convert_t;
149
150 typedef struct {
151 bool underflow_int_en;
152 uint8_t fifo_thr;
153 bool calsat_int_en;
154 bool da_int_en;
155 bool auto_deactivate_en;
156 bool fadeout_done_int_en;
157 bool deactivate_en;
158 bool active_en;
159 bool fadeout_now_en;
160 bool fadeout_auto_en;
161 bool fadein_en;
162 bool channel_en;
163 bool mixer_en;
164
165 uint16_t gain;
166 uint32_t length;
167 uint32_t fadein_delta;
168 uint32_t fadeout_delta;
169 uint8_t src_ch_mask;
170 } smix_mixer_dst_config_t;
171
172
173 typedef struct {
174 uint8_t fifo_thr;
175 bool calsat_int_en;
176 bool dn_int_en;
177 uint8_t fir_shift;
178 bool auto_deactivate_en;
179 bool fadeout_int_en;
180 uint8_t convert_rate;
181
182 uint16_t gain;
183 uint32_t fadein_delta;
184 uint32_t fadeout_delta;
185 uint32_t length;
186 } smix_mixer_source_config_t;
187
188 #ifdef __cplusplus
189 extern "C" {
190 #endif
191
192 /**
193 * @brief smix dma check transfer complete status
194 *
195 * @param [in] ptr SMIX base address
196 * @param [in] ch_index dma channel
197 * @retval true for transfer complete
198 */
smix_dma_check_transfer_complete(SMIX_Type * ptr,uint8_t ch_index)199 static inline bool smix_dma_check_transfer_complete(SMIX_Type *ptr, uint8_t ch_index)
200 {
201 if ((SMIX_DMAC_TC_ST_CH_GET(ptr->DMAC_TC_ST) & (1U << ch_index)) != 0) {
202 ptr->DMAC_TC_ST = (1U << ch_index); /* W1C clear status*/
203 return true;
204 }
205 return false;
206 }
207
208 /**
209 * @brief smix dma check transfer abort status
210 *
211 * @param [in] ptr SMIX base address
212 * @param [in] ch_index dma channel
213 * @retval true for transfer abort
214 */
smix_dma_check_transfer_abort(SMIX_Type * ptr,uint8_t ch_index)215 static inline bool smix_dma_check_transfer_abort(SMIX_Type *ptr, uint8_t ch_index)
216 {
217 if ((SMIX_DMAC_ABRT_ST_CH_GET(ptr->DMAC_ABRT_ST) & (1U << ch_index)) != 0) {
218 ptr->DMAC_ABRT_ST = (1U << ch_index); /* W1C clear status*/
219 return true;
220 }
221 return false;
222 }
223
224 /**
225 * @brief smix dma check transfer error status
226 *
227 * @param [in] ptr SMIX base address
228 * @param [in] ch_index dma channel
229 * @retval true for transfer error
230 */
smix_dma_check_transfer_error(SMIX_Type * ptr,uint8_t ch_index)231 static inline bool smix_dma_check_transfer_error(SMIX_Type *ptr, uint8_t ch_index)
232 {
233 if ((SMIX_DMAC_ERR_ST_CH_GET(ptr->DMAC_ERR_ST) & (1U << ch_index)) != 0) {
234 ptr->DMAC_ERR_ST = (1U << ch_index); /* W1C clear status*/
235 return true;
236 }
237 return false;
238 }
239
240 /**
241 * @brief smix mixer enable source channel for dst
242 *
243 * @param [in] ptr SMIX base address
244 * @param [in] dst_ch dst channel
245 * @param [in] source_ch_mask source channel mask
246 */
smix_mixer_dst_enable_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)247 static inline void smix_mixer_dst_enable_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
248 {
249 ptr->DST_CH[dst_ch].SOURCE_EN |= source_ch_mask;
250 }
251
252 /**
253 * @brief smix mixer disable source channel for dst
254 *
255 * @param [in] ptr SMIX base address
256 * @param [in] dst_ch dst channel
257 * @param [in] source_ch_mask source channel mask
258 */
smix_mixer_dst_disable_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)259 static inline void smix_mixer_dst_disable_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
260 {
261 ptr->DST_CH[dst_ch].SOURCE_EN &= ~source_ch_mask;
262 }
263
264 /**
265 * @brief smix mixer active source channel for dst
266 *
267 * @param [in] ptr SMIX base address
268 * @param [in] dst_ch dst channel
269 * @param [in] source_ch_mask source channel mask
270 */
smix_mixer_dst_active_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)271 static inline void smix_mixer_dst_active_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
272 {
273 ptr->DST_CH[dst_ch].SOURCE_ACT |= source_ch_mask;
274 }
275
276 /**
277 * @brief smix mixer deactive source channel for dst
278 *
279 * @param [in] ptr SMIX base address
280 * @param [in] dst_ch dst channel
281 * @param [in] source_ch_mask source channel mask
282 */
smix_mixer_dst_deactive_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)283 static inline void smix_mixer_dst_deactive_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
284 {
285 ptr->DST_CH[dst_ch].SOURCE_DEACT |= source_ch_mask;
286 }
287
288 /**
289 * @brief smix mixer fadein source channel for dst
290 *
291 * @param [in] ptr SMIX base address
292 * @param [in] dst_ch dst channel
293 * @param [in] source_ch_mask source channel mask
294 */
smix_mixer_dst_fadein_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)295 static inline void smix_mixer_dst_fadein_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
296 {
297 ptr->DST_CH[dst_ch].SOURCE_FADEIN_CTRL |= source_ch_mask;
298 }
299
300 /**
301 * @brief smix mixer fadeout source channel for dst
302 *
303 * @param [in] ptr SMIX base address
304 * @param [in] dst_ch dst channel
305 * @param [in] source_ch_mask source channel mask
306 */
smix_mixer_dst_fadeout_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)307 static inline void smix_mixer_dst_fadeout_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
308 {
309 ptr->DST_CH[dst_ch].SOURCE_MFADEOUT_CTRL |= source_ch_mask;
310 }
311
312 /**
313 * @brief smix mixer enable dst channel
314 *
315 * @param [in] ptr SMIX base address
316 *
317 * @note two dst channel share same enable bit in DST_CH[0].CTRL.MIXER_EN, DST_CH[1].CTRL.MIXER_EN should not be set
318 */
smix_mixer_dst_enable(SMIX_Type * ptr)319 static inline void smix_mixer_dst_enable(SMIX_Type *ptr)
320 {
321 ptr->DST_CH[0].CTRL |= SMIX_DST_CH_CTRL_DST_EN_MASK;
322 ptr->DST_CH[1].CTRL &= ~SMIX_DST_CH_CTRL_DST_EN_MASK;
323 }
324
325 /**
326 * @brief smix mixer disable dst channel
327 *
328 * @param [in] ptr SMIX base address
329 *
330 * @note two dst channel share same enable bit in DST_CH[0].CTRL.MIXER_EN, DST_CH[1].CTRL.MIXER_EN should not be set
331 */
smix_mixer_dst_disable(SMIX_Type * ptr)332 static inline void smix_mixer_dst_disable(SMIX_Type *ptr)
333 {
334 ptr->DST_CH[0].CTRL &= ~SMIX_DST_CH_CTRL_DST_EN_MASK;
335 }
336
337 /**
338 * @brief smix mixer get calculate saturation register value
339 *
340 * @param [in] ptr SMIX base address
341 * @retval calculate saturation register value
342 */
smix_mixer_get_calsat_status(SMIX_Type * ptr)343 static inline uint32_t smix_mixer_get_calsat_status(SMIX_Type *ptr)
344 {
345 return ptr->CALSAT_ST;
346 }
347
348 /**
349 * @brief smix mixer check dst channel calculate saturation error
350 *
351 * @param [in] ptr SMIX base address
352 * @param [in] dst_ch dst channel
353 * @retval true for calculate saturation error occurred
354 */
smix_mixer_check_dst_cal_saturation_error(SMIX_Type * ptr,uint8_t dst_ch)355 static inline bool smix_mixer_check_dst_cal_saturation_error(SMIX_Type *ptr, uint8_t dst_ch)
356 {
357 return ((SMIX_CALSAT_ST_DST_GET(ptr->CALSAT_ST) & (1U << dst_ch)) != 0) ? true : false;
358 }
359
360 /**
361 * @brief smix mixer check source channel calculate saturation error
362 *
363 * @param [in] ptr SMIX base address
364 * @param [in] source_ch source channel
365 * @retval true for calculate saturation error occurred
366 */
smix_mixer_check_source_cal_saturation_error(SMIX_Type * ptr,uint8_t source_ch)367 static inline bool smix_mixer_check_source_cal_saturation_error(SMIX_Type *ptr, uint8_t source_ch)
368 {
369 return ((SMIX_CALSAT_ST_SRC_GET(ptr->CALSAT_ST) & (1U << source_ch)) != 0) ? true : false;
370 }
371
372 /**
373 * @brief smix mixer check dst channel data ubderflew
374 *
375 * @param [in] ptr SMIX base address
376 * @param [in] dst_ch dst channel
377 * @retval true for data underflew
378 */
smix_mixer_check_dst_data_underflew(SMIX_Type * ptr,uint8_t dst_ch)379 static inline bool smix_mixer_check_dst_data_underflew(SMIX_Type *ptr, uint8_t dst_ch)
380 {
381 return ((SMIX_DATA_ST_DST_UNDL_GET(ptr->DATA_ST) & (1U << dst_ch)) != 0) ? true : false;
382 }
383
384 /**
385 * @brief smix mixer check dst channel data available
386 *
387 * @param [in] ptr SMIX base address
388 * @param [in] dst_ch dst channel
389 * @retval true for data available
390 */
smix_mixer_check_dst_data_available(SMIX_Type * ptr,uint8_t dst_ch)391 static inline bool smix_mixer_check_dst_data_available(SMIX_Type *ptr, uint8_t dst_ch)
392 {
393 return ((SMIX_DATA_ST_DST_DA_GET(ptr->DATA_ST) & (1U << dst_ch)) != 0) ? true : false;
394 }
395
396 /**
397 * @brief smix mixer check source channel data available
398 *
399 * @param [in] ptr SMIX base address
400 * @param [in] source_ch source channel
401 * @retval true for source channel need new data
402 */
smix_mixer_check_source_data_needed(SMIX_Type * ptr,uint8_t source_ch)403 static inline bool smix_mixer_check_source_data_needed(SMIX_Type *ptr, uint8_t source_ch)
404 {
405 return ((SMIX_DATA_ST_SRC_DN_GET(ptr->DATA_ST) & (1U << source_ch)) != 0) ? true : false;
406 }
407
408 /**
409 * @brief smix mixer config dst channel fadein delta
410 *
411 * @param [in] ptr SMIX base address
412 * @param [in] ch dst channel
413 * @param [in] target_sample_rate target sample rate
414 * @param [in] ms fadein consumed time in ms
415 * @retval status_success if no error occurs
416 */
417 hpm_stat_t smix_mixer_config_dst_fadein_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms);
418
419 /**
420 * @brief smix mixer config dst channel fadeout delta
421 *
422 * @param [in] ptr SMIX base address
423 * @param [in] ch dst channel
424 * @param [in] target_sample_rate target sample rate
425 * @param [in] ms fadeout consumed time in ms
426 * @retval status_success if no error occurs
427 */
428 hpm_stat_t smix_mixer_config_dst_fadeout_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms);
429
430 /**
431 * @brief smix mixer config source channel fadein delta
432 *
433 * @param [in] ptr SMIX base address
434 * @param [in] ch source channel
435 * @param [in] target_sample_rate target sample rate
436 * @param [in] ms fadein consumed time in ms
437 * @retval status_success if no error occurs
438 */
439 hpm_stat_t smix_mixer_config_source_fadein_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms);
440
441 /**
442 * @brief smix mixer config source channel fadeout delta
443 *
444 * @param [in] ptr SMIX base address
445 * @param [in] ch source channel
446 * @param [in] target_sample_rate target sample rate
447 * @param [in] ms fadeout consumed time in ms
448 * @retval status_success if no error occurs
449 */
450 hpm_stat_t smix_mixer_config_source_fadeout_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms);
451
452 /**
453 * @brief smix get dma channel default config
454 *
455 * @param [in] ptr SMIX base address
456 * @param [in] config smix_dma_ch_config_t
457 */
458 void smix_get_dma_default_ch_config(SMIX_Type *ptr, smix_dma_ch_config_t *config);
459
460 /**
461 * @brief smix get dst channel default config
462 *
463 * @param [in] ptr SMIX base address
464 * @param [in] config smix_mixer_dst_config_t
465 */
466 void smix_get_mixer_dst_ch_default_config(SMIX_Type *ptr, smix_mixer_dst_config_t *config);
467
468 /**
469 * @brief smix get source channel default config
470 *
471 * @param [in] ptr SMIX base address
472 * @param [in] config smix_mixer_source_config_t
473 */
474 void smix_get_mixer_source_ch_default_config(SMIX_Type *ptr, smix_mixer_source_config_t *config);
475
476 /**
477 * @brief smix config dma channel
478 *
479 * @param [in] ptr SMIX base address
480 * @param [in] ch dma channel
481 * @param [in] config smix_dma_ch_config_t
482 * @param [in] start true for start dma
483 * @retval status_success if no error occurs
484 */
485 hpm_stat_t smix_config_dma_channel(SMIX_Type *ptr, uint8_t ch, smix_dma_ch_config_t *config, bool start);
486
487 /**
488 * @brief smix mixer config source channel
489 *
490 * @param [in] ptr SMIX base address
491 * @param [in] ch source channel
492 * @param [in] src smix_mixer_source_config_t
493 * @retval status_success if no error occurs
494 */
495 hpm_stat_t smix_mixer_config_source_ch(SMIX_Type *ptr, uint8_t ch, smix_mixer_source_config_t *src);
496
497 /**
498 * @brief smix mixer config dst channel
499 *
500 * @param [in] ptr SMIX base address
501 * @param [in] ch dst channel
502 * @param [in] src smix_mixer_dst_config_t
503 * @retval status_success if no error occurs
504 */
505 hpm_stat_t smix_mixer_config_dst_ch(SMIX_Type *ptr, uint8_t ch, smix_mixer_dst_config_t *dst);
506
507 /**
508 * @}
509 */
510
511 #ifdef __cplusplus
512 }
513 #endif
514
515 #endif /* HPM_SMIX_DRV_H */
516