1 #include "sample_rate_converter.h"
2
3
4
5
6 #define SRC_RATE 48000U
7 #define reg(n) DSP->base + n
8
9
10 /* register/base and control equates for the SRC RAM */
11 #define SRC_SYNTH_FIFO 0x00
12 #define SRC_DAC_FIFO 0x20
13 #define SRC_ADC_FIFO 0x40
14
15 #define SRC_SYNTH_LVOL 0x7c
16 #define SRC_SYNTH_RVOL 0x7d
17 #define SRC_DAC_LVOL 0x7e
18 #define SRC_DAC_RVOL 0x7f
19 #define SRC_ADC_LVOL 0x6c
20 #define SRC_ADC_RVOL 0x6d
21
22 #define SRC_TRUNC_N_OFF 0x00
23 #define SRC_INT_REGS_OFF 0x01
24 #define SRC_ACCUM_FRAC_OFF 0x02
25 #define SRC_VFREQ_FRAC_OFF 0x03
26
27 /* miscellaneous control defines */
28 #define SRC_IOPOLL_COUNT 0x1000UL
29
30 #define SRC_SYNTHFREEZE (1UL << 21)
31 #define SRC_DACFREEZE (1UL << 20)
32 #define SRC_ADCFREEZE (1UL << 19)
33
34
35
36
37 static int src_reg_read(const DEV_STRUCT * DSP, u16_t reg, u16_t
38 *data);
39 static int src_reg_write(const DEV_STRUCT * DSP, u16_t reg, u16_t val);
40
41
src_init(DEV_STRUCT * DSP)42 int src_init ( DEV_STRUCT * DSP ) {
43 u32_t i;
44 int retVal;
45
46 /* Clear all SRC RAM then init - keep SRC disabled until done */
47 /* Wait till SRC_RAM_BUSY is 0 */
48 if (WaitBitd (reg(SAMPLE_RATE_CONV), SRC_BUSY_BIT, 0, 1000))
49 return (SRC_ERR_NOT_BUSY_TIMEOUT);
50
51 pci_outl(reg(SAMPLE_RATE_CONV), SRC_DISABLE);
52
53 /* from the opensound system driver, no idea where the specification is */
54 /* there are indeed 7 bits for the addresses of the SRC */
55 for( i = 0; i < 0x80; ++i ) {
56 if (SRC_SUCCESS != (retVal = src_reg_write(DSP, (u16_t)i, 0U)))
57 return (retVal);
58 }
59
60 if (SRC_SUCCESS != (retVal =
61 src_reg_write(DSP, SRC_SYNTH_BASE + SRC_TRUNC_N_OFF, 16 << 4)))
62 return (retVal);
63 if (SRC_SUCCESS != (retVal = src_reg_write(DSP,
64 SRC_SYNTH_BASE + SRC_INT_REGS_OFF, 16 << 10)))
65 return (retVal);
66 if (SRC_SUCCESS != (retVal =
67 src_reg_write(DSP, SRC_DAC_BASE + SRC_TRUNC_N_OFF, 16 << 4)))
68 return (retVal);
69 if (SRC_SUCCESS != (retVal =
70 src_reg_write(DSP, SRC_DAC_BASE + SRC_INT_REGS_OFF, 16 << 10)))
71 return (retVal);
72 if (SRC_SUCCESS != (retVal =
73 src_reg_write(DSP, SRC_SYNTH_LVOL, 1 << 12)))
74 return (retVal);
75 if (SRC_SUCCESS != (retVal =
76 src_reg_write(DSP, SRC_SYNTH_RVOL, 1 << 12)))
77 return (retVal);
78 if (SRC_SUCCESS != (retVal =
79 src_reg_write(DSP, SRC_DAC_LVOL, 1 << 12)))
80 return (retVal);
81 if (SRC_SUCCESS != (retVal =
82 src_reg_write(DSP, SRC_DAC_RVOL, 1 << 12)))
83 return (retVal);
84 if (SRC_SUCCESS != (retVal =
85 src_reg_write(DSP, SRC_ADC_LVOL, 1 << 12)))
86 return (retVal);
87 if (SRC_SUCCESS != (retVal =
88 src_reg_write(DSP, SRC_ADC_RVOL, 1 << 12)))
89 return (retVal);
90
91 /* default some rates */
92 src_set_rate(DSP, SRC_SYNTH_BASE, SRC_RATE);
93 src_set_rate(DSP, SRC_DAC_BASE, SRC_RATE);
94 src_set_rate(DSP, SRC_ADC_BASE, SRC_RATE);
95
96 /* now enable the whole deal */
97 if (WaitBitd (reg(SAMPLE_RATE_CONV), SRC_BUSY_BIT, 0, 1000))
98 return (SRC_ERR_NOT_BUSY_TIMEOUT);
99
100 pci_outl(reg(SAMPLE_RATE_CONV), 0UL);
101
102 return 0;
103 }
104
105
src_reg_read(const DEV_STRUCT * DSP,u16_t reg,u16_t * data)106 static int src_reg_read(const DEV_STRUCT * DSP, u16_t reg, u16_t *data) {
107 u32_t dtemp;
108
109 /* wait for ready */
110 if (WaitBitd (reg(SAMPLE_RATE_CONV), SRC_BUSY_BIT, 0, 1000))
111 return (SRC_ERR_NOT_BUSY_TIMEOUT);
112
113 dtemp = pci_inl(reg(SAMPLE_RATE_CONV));
114
115 /* assert a read request */
116 /*pci_outl(reg(SAMPLE_RATE_CONV),
117 (dtemp & SRC_CTLMASK) | ((u32_t) reg << 25));*/
118 pci_outl(reg(SAMPLE_RATE_CONV), (dtemp &
119 (DIS_REC|DIS_P2|DIS_P1|SRC_DISABLE)) | ((u32_t) reg << 25));
120
121 /* now wait for the data */
122 if (WaitBitd (reg(SAMPLE_RATE_CONV), SRC_BUSY_BIT, 0, 1000))
123 return (SRC_ERR_NOT_BUSY_TIMEOUT);
124
125 if (NULL != data)
126 *data = (u16_t) pci_inl(reg(SAMPLE_RATE_CONV));
127
128 return 0;
129 }
130
131
src_reg_write(const DEV_STRUCT * DSP,u16_t reg,u16_t val)132 static int src_reg_write(const DEV_STRUCT * DSP, u16_t reg, u16_t val) {
133 u32_t dtemp;
134
135 /* wait for ready */
136 if (WaitBitd (reg(SAMPLE_RATE_CONV), SRC_BUSY_BIT, 0, 1000))
137 return (SRC_ERR_NOT_BUSY_TIMEOUT);
138
139 dtemp = pci_inl(reg(SAMPLE_RATE_CONV));
140
141 /* assert the write request */
142 pci_outl(reg(SAMPLE_RATE_CONV),
143 (dtemp & SRC_CTLMASK) | SRC_RAM_WE | ((u32_t) reg << 25) | val);
144
145 return 0;
146 }
147
148
src_set_rate(const DEV_STRUCT * DSP,char base,u16_t rate)149 void src_set_rate(const DEV_STRUCT * DSP, char base, u16_t rate) {
150 u32_t freq, dtemp, i;
151 u16_t N, truncM, truncStart, wtemp;
152
153
154 if( base != SRC_ADC_BASE )
155 {
156 /* freeze the channel */
157 dtemp = base == SRC_SYNTH_BASE ? SRC_SYNTHFREEZE : SRC_DACFREEZE;
158 for( i = 0; i < SRC_IOPOLL_COUNT; ++i )
159 if( !(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_RAM_BUSY) )
160 break;
161 pci_outl(reg(SAMPLE_RATE_CONV),
162 (pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_CTLMASK) |
163 dtemp);
164
165 /* calculate new frequency and write it - preserve accum */
166 /* please don't try to understand. */
167 freq = ((u32_t) rate << 16) / 3000U;
168 src_reg_read(DSP, base + SRC_INT_REGS_OFF, &wtemp);
169
170 src_reg_write(DSP, base + SRC_INT_REGS_OFF,
171 (wtemp & 0x00ffU) |
172 ((u16_t) (freq >> 6) & 0xfc00));
173
174 src_reg_write(DSP, base + SRC_VFREQ_FRAC_OFF, (u16_t) freq >> 1);
175
176 /* un-freeze the channel */
177 dtemp = base == SRC_SYNTH_BASE ? SRC_SYNTHFREEZE : SRC_DACFREEZE;
178 for( i = 0; i < SRC_IOPOLL_COUNT; ++i )
179 if( !(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_RAM_BUSY) )
180 break;
181 pci_outl(reg(SAMPLE_RATE_CONV),
182 (pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_CTLMASK) &
183 ~dtemp);
184 }
185 else /* setting ADC rate */
186 {
187 /* freeze the channel */
188 for( i = 0; i < SRC_IOPOLL_COUNT; ++i )
189 if( !(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_RAM_BUSY) )
190 break;
191 pci_outl(reg(SAMPLE_RATE_CONV),
192 (pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_CTLMASK) |
193 SRC_ADCFREEZE);
194
195
196
197 /* derive oversample ratio */
198 N = rate/3000U;
199 if( N == 15 || N == 13 || N == 11 || N == 9 )
200 --N;
201 src_reg_write(DSP, SRC_ADC_LVOL, N << 8);
202 src_reg_write(DSP, SRC_ADC_RVOL, N << 8);
203
204 /* truncate the filter and write n/trunc_start */
205 truncM = (21*N - 1) | 1;
206 if( rate >= 24000U )
207 {
208 if( truncM > 239 )
209 truncM = 239;
210 truncStart = (239 - truncM) >> 1;
211 src_reg_write(DSP, base + SRC_TRUNC_N_OFF,
212 (truncStart << 9) | (N << 4));
213 }
214 else
215 {
216 if( truncM > 119 )
217 truncM = 119;
218 truncStart = (119 - truncM) >> 1;
219 src_reg_write(DSP, base + SRC_TRUNC_N_OFF,
220 0x8000U | (truncStart << 9) | (N << 4));
221 }
222
223 /* calculate new frequency and write it - preserve accum */
224 freq = ((48000UL << 16) / rate) * N;
225 src_reg_read(DSP, base + SRC_INT_REGS_OFF, &wtemp);
226 src_reg_write(DSP, base + SRC_INT_REGS_OFF,
227 (wtemp & 0x00ffU) |
228 ((u16_t) (freq >> 6) & 0xfc00));
229 src_reg_write(DSP, base + SRC_VFREQ_FRAC_OFF, (u16_t) freq >> 1);
230
231 /* un-freeze the channel */
232 for( i = 0; i < SRC_IOPOLL_COUNT; ++i )
233 if( !(pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_RAM_BUSY) )
234 break;
235 pci_outl(reg(SAMPLE_RATE_CONV),
236 (pci_inl(reg(SAMPLE_RATE_CONV)) & SRC_CTLMASK) &
237 ~SRC_ADCFREEZE);
238 }
239 return;
240 }
241