• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_smix_drv.h"
9 
smix_get_dma_default_ch_config(SMIX_Type * ptr,smix_dma_ch_config_t * config)10 void smix_get_dma_default_ch_config(SMIX_Type *ptr, smix_dma_ch_config_t *config)
11 {
12     (void) ptr;
13     config->priority = 0;
14     config->src_mode = smix_dma_mode_normal;
15     config->dst_mode = smix_dma_mode_normal;
16     config->src_width = smix_dma_transfer_half_word;
17     config->dst_width = smix_dma_transfer_half_word;
18     config->src_addr_ctrl = smix_dma_address_increment;
19     config->dst_addr_ctrl = smix_dma_address_increment;
20     config->src_burst_size = smix_dma_transfer_burst_1t;
21     config->trans_bytes = 0;
22     config->linked_ptr = 0;
23     config->src_req_sel = 0;
24     config->dst_req_sel = 0;
25 
26     config->abort_int_en = false;
27     config->error_int_en = false;
28     config->complete_int_en = false;
29 }
30 
31 
smix_get_mixer_dst_ch_default_config(SMIX_Type * ptr,smix_mixer_dst_config_t * config)32 void smix_get_mixer_dst_ch_default_config(SMIX_Type *ptr, smix_mixer_dst_config_t *config)
33 {
34     (void) ptr;
35     config->underflow_int_en = false;
36     config->fifo_thr = 8; /* Must be greater than or equal to 8 */
37     config->calsat_int_en = false;
38     config->da_int_en = false;
39     config->auto_deactivate_en = false;
40     config->fadeout_done_int_en = false;
41     config->deactivate_en = false;
42     config->active_en = true;
43     config->fadeout_now_en = false;
44     config->fadeout_auto_en = false;
45     config->fadein_en = false;
46     config->channel_en = true;
47     config->mixer_en = true;
48 
49     config->gain = smix_mixer_gain_0db;
50     config->length = 0; /* 0 = infinite length */
51     config->fadein_delta = 6; /* 48K sample rate, need 3s */
52     config->fadeout_delta = 14; /* 48K sample rate, need 1/3s */
53     config->src_ch_mask = 0x1;
54 }
55 
smix_get_mixer_source_ch_default_config(SMIX_Type * ptr,smix_mixer_source_config_t * config)56 void smix_get_mixer_source_ch_default_config(SMIX_Type *ptr, smix_mixer_source_config_t *config)
57 {
58     (void) ptr;
59     config->fifo_thr = 4; /* Must be greater than or equal to 4 */
60     config->calsat_int_en = false;
61     config->dn_int_en = false;
62     config->fir_shift = 0;
63     config->auto_deactivate_en = true;
64     config->fadeout_int_en = false;
65 
66     config->convert_rate = smix_mixer_no_rate_convert;
67     config->gain = smix_mixer_gain_0db;
68     config->fadein_delta = 6; /* 48K sample rate, need 3s */
69     config->fadeout_delta = 14; /* 48K sample rate, need 1/3s */
70     config->length = 0; /* 0 = infinite length */
71 }
72 
smix_config_dma_channel(SMIX_Type * ptr,uint8_t ch,smix_dma_ch_config_t * config,bool start)73 hpm_stat_t smix_config_dma_channel(SMIX_Type *ptr, uint8_t ch, smix_dma_ch_config_t *config, bool start)
74 {
75     uint32_t tmp;
76 
77     if ((config->trans_bytes & ((1 << config->dst_width) - 1))
78      || (config->src_addr & ((1 << config->src_width) - 1))
79      || (config->dst_addr & ((1 << config->dst_width) - 1))
80      || (config->linked_ptr & 0x7)) {
81         return status_invalid_argument;
82     }
83 
84     ptr->DMA_CH[ch].SRCADDR = SMIX_DMA_CH_SRCADDR_PTR_SET(config->src_addr);
85     ptr->DMA_CH[ch].DSTADDR = SMIX_DMA_CH_DSTADDR_PTR_SET(config->dst_addr);
86     ptr->DMA_CH[ch].BURST_COUNT = SMIX_DMA_CH_BURST_COUNT_NUM_SET(config->trans_bytes >> config->src_width);
87     ptr->DMA_CH[ch].LLP = SMIX_DMA_CH_LLP_PTR_SET(config->linked_ptr);
88 
89     /* clear status bit, W1C */
90     ptr->DMAC_ERR_ST = 1 << ch;
91     ptr->DMAC_ABRT_ST = 1 << ch;
92     ptr->DMAC_TC_ST = 1 << ch;
93 
94     tmp = SMIX_DMA_CH_CTL_SRCREQSEL_SET(config->src_req_sel)
95         | SMIX_DMA_CH_CTL_DSTREQSEL_SET(config->dst_req_sel)
96         | SMIX_DMA_CH_CTL_PRIORITY_SET(config->priority)
97         | SMIX_DMA_CH_CTL_SRCBURSTSIZE_SET(config->src_burst_size)
98         | SMIX_DMA_CH_CTL_SRCWIDTH_SET(config->src_width)
99         | SMIX_DMA_CH_CTL_DSTWIDTH_SET(config->dst_width)
100         | SMIX_DMA_CH_CTL_SRCMODE_SET(config->src_mode)
101         | SMIX_DMA_CH_CTL_DSTMODE_SET(config->dst_mode)
102         | SMIX_DMA_CH_CTL_SRCADDRCTRL_SET(config->src_addr_ctrl)
103         | SMIX_DMA_CH_CTL_DSTADDRCTRL_SET(config->dst_addr_ctrl)
104         | SMIX_DMA_CH_CTL_ABRT_INT_EN_SET(config->abort_int_en)
105         | SMIX_DMA_CH_CTL_ERR_INT_EN_SET(config->error_int_en)
106         | SMIX_DMA_CH_CTL_TC_INT_EN_SET(config->complete_int_en);
107 
108     if (start) {
109         tmp |= SMIX_DMA_CH_CTL_EN_MASK;
110     }
111     ptr->DMA_CH[ch].CTL = tmp;
112 
113     return status_success;
114 }
115 
smix_mixer_config_source_ch(SMIX_Type * ptr,uint8_t ch,smix_mixer_source_config_t * src)116 hpm_stat_t smix_mixer_config_source_ch(SMIX_Type *ptr, uint8_t ch, smix_mixer_source_config_t *src)
117 {
118     /* reset fifo */
119     ptr->SOURCE_CH[ch].CTRL |= SMIX_SOURCE_CH_CTRL_FIFO_RESET_MASK;
120     ptr->SOURCE_CH[ch].CTRL &= ~SMIX_SOURCE_CH_CTRL_FIFO_RESET_MASK;
121 
122     ptr->SOURCE_CH[ch].CTRL = SMIX_SOURCE_CH_CTRL_THRSH_SET(src->fifo_thr)
123                         | SMIX_SOURCE_CH_CTRL_CALSAT_INT_EN_SET(src->calsat_int_en)
124                         | SMIX_SOURCE_CH_CTRL_DN_INT_EN_SET(src->dn_int_en)
125                         | SMIX_SOURCE_CH_CTRL_SHFT_CTRL_SET(src->fir_shift)
126                         | SMIX_SOURCE_CH_CTRL_AUTODEACTAFTERFADEOUT_EN_SET(src->auto_deactivate_en)
127                         | SMIX_SOURCE_CH_CTRL_FADEOUT_DONE_IE_SET(src->fadeout_int_en)
128                         | SMIX_SOURCE_CH_CTRL_RATECONV_SET(src->convert_rate);
129 
130     ptr->SOURCE_CH[ch].GAIN = SMIX_SOURCE_CH_GAIN_VAL_SET(src->gain);
131 
132     ptr->SOURCE_CH[ch].FADEIN = SMIX_SOURCE_CH_FADEIN_DELTA_SET(src->fadein_delta);
133 
134     ptr->SOURCE_CH[ch].FADEOUT = SMIX_SOURCE_CH_FADEOUT_DELTA_SET(src->fadeout_delta);
135 
136     if (src->length == 0) {
137         ptr->SOURCE_CH[ch].BUFSIZE = SMIX_SOURCE_CH_BUFSIZE_MAXIDX_SET(0);
138     } else {
139         ptr->SOURCE_CH[ch].BUFSIZE = SMIX_SOURCE_CH_BUFSIZE_MAXIDX_SET(src->length - 1);
140     }
141 
142     return status_success;
143 }
144 
145 
smix_mixer_config_dst_ch(SMIX_Type * ptr,uint8_t ch,smix_mixer_dst_config_t * dst)146 hpm_stat_t smix_mixer_config_dst_ch(SMIX_Type *ptr, uint8_t ch, smix_mixer_dst_config_t *dst)
147 {
148     /* Reset */
149     ptr->DST_CH[ch].CTRL |= SMIX_DST_CH_CTRL_SOFTRST_MASK;
150     ptr->DST_CH[ch].CTRL &= ~SMIX_DST_CH_CTRL_SOFTRST_MASK;
151 
152     ptr->DST_CH[ch].GAIN = SMIX_DST_CH_GAIN_VAL_SET(dst->gain);
153 
154     if (dst->length == 0) {
155         ptr->DST_CH[ch].BUFSIZE = SMIX_DST_CH_BUFSIZE_MAX_IDX_SET(0);
156     } else {
157         ptr->DST_CH[ch].BUFSIZE = SMIX_DST_CH_BUFSIZE_MAX_IDX_SET(dst->length - 1);
158     }
159 
160     ptr->DST_CH[ch].FADEIN = SMIX_DST_CH_FADEIN_DELTA_SET(dst->fadein_delta);
161 
162     ptr->DST_CH[ch].FADEOUT = SMIX_DST_CH_FADEOUT_DELTA_SET(dst->fadeout_delta);
163 
164     ptr->DST_CH[ch].SOURCE_EN = dst->src_ch_mask;
165     ptr->DST_CH[ch].SOURCE_ACT = dst->src_ch_mask;
166 
167     ptr->DST_CH[ch].CTRL = SMIX_DST_CH_CTRL_DATA_UNFL_IE_SET(dst->underflow_int_en)
168                         | SMIX_DST_CH_CTRL_THRSH_SET(dst->fifo_thr)
169                         | SMIX_DST_CH_CTRL_CALSAT_INT_EN_SET(dst->calsat_int_en)
170                         | SMIX_DST_CH_CTRL_DA_INT_EN_SET(dst->da_int_en)
171                         | SMIX_DST_CH_CTRL_ADEACTFADEOUT_EN_SET(dst->auto_deactivate_en)
172                         | SMIX_DST_CH_CTRL_FADEOUT_DONE_IE_SET(dst->fadeout_done_int_en)
173                         | SMIX_DST_CH_CTRL_DST_DEACT_SET(dst->deactivate_en)
174                         | SMIX_DST_CH_CTRL_DST_ACT_SET(dst->active_en)
175                         | SMIX_DST_CH_CTRL_DSTFADOUT_MEN_SET(dst->fadeout_now_en)
176                         | SMIX_DST_CH_CTRL_DSTFADOUT_AEN_SET(dst->fadeout_auto_en)
177                         | SMIX_DST_CH_CTRL_DSTFADIN_EN_SET(dst->fadein_en)
178                         | SMIX_DST_CH_CTRL_DST_EN_SET(dst->channel_en);
179 
180     /* Workaround: DST_CH[0].CTRL.MIXER_EN bit controls mixer module enable or disable, DST_CH[1].CTRL.MIXER_EN should not be set */
181     if (dst->mixer_en) {
182         ptr->DST_CH[0].CTRL |= SMIX_DST_CH_CTRL_MIXER_EN_MASK;
183         ptr->DST_CH[1].CTRL &= ~SMIX_DST_CH_CTRL_MIXER_EN_MASK;
184     }
185 
186     return status_success;
187 }
188 
smix_mixer_config_dst_fadein_delta(SMIX_Type * ptr,uint8_t ch,uint32_t target_sample_rate,uint32_t ms)189 hpm_stat_t smix_mixer_config_dst_fadein_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms)
190 {
191     uint32_t delta = SMIX_DST_CH_FADEIN_DELTA_MASK * 1000 / target_sample_rate / ms;
192 
193     if (delta == 0) {
194         return status_invalid_argument;
195     }
196     ptr->DST_CH[ch].FADEIN = SMIX_DST_CH_FADEIN_DELTA_SET(delta);
197     return status_success;
198 }
199 
smix_mixer_config_dst_fadeout_delta(SMIX_Type * ptr,uint8_t ch,uint32_t target_sample_rate,uint32_t ms)200 hpm_stat_t smix_mixer_config_dst_fadeout_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms)
201 {
202     uint32_t delta = (uint32_t)log2(target_sample_rate * ms / 1000);
203 
204     /* fadeout delta valid bit: 14 */
205     if (delta > 0x3fff) {
206         return status_invalid_argument;
207     }
208     ptr->DST_CH[ch].FADEOUT = SMIX_DST_CH_FADEOUT_DELTA_SET(delta);
209     return status_success;
210 }
211 
smix_mixer_config_source_fadein_delta(SMIX_Type * ptr,uint8_t ch,uint32_t target_sample_rate,uint32_t ms)212 hpm_stat_t smix_mixer_config_source_fadein_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms)
213 {
214     uint32_t delta = SMIX_DST_CH_FADEIN_DELTA_MASK * 1000 / target_sample_rate / ms;
215 
216     if (delta == 0) {
217         return status_invalid_argument;
218     }
219     ptr->SOURCE_CH[ch].FADEIN = SMIX_SOURCE_CH_FADEIN_DELTA_SET(delta);
220     return status_success;
221 }
222 
smix_mixer_config_source_fadeout_delta(SMIX_Type * ptr,uint8_t ch,uint32_t target_sample_rate,uint32_t ms)223 hpm_stat_t smix_mixer_config_source_fadeout_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms)
224 {
225     uint32_t delta = (uint32_t)log2(target_sample_rate * ms / 1000);
226 
227     /* fadeout delta valid bit: 14 */
228     if (delta > 0x3fff) {
229         return status_invalid_argument;
230     }
231     ptr->SOURCE_CH[ch].FADEOUT = SMIX_SOURCE_CH_FADEOUT_DELTA_SET(delta);
232     return status_success;
233 }