1 #include "sample_rate_converter.h"
6 #define SRC_RATE 48000U
7 #define reg(n) DSP->base + n
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
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
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
27 /* miscellaneous control defines */
28 #define SRC_IOPOLL_COUNT 0x1000UL
30 #define SRC_SYNTHFREEZE (1UL << 21)
31 #define SRC_DACFREEZE (1UL << 20)
32 #define SRC_ADCFREEZE (1UL << 19)
37 static int src_reg_read(const DEV_STRUCT
* DSP
, u16_t reg
, u16_t
39 static int src_reg_write(const DEV_STRUCT
* DSP
, u16_t reg
, u16_t val
);
42 int src_init ( DEV_STRUCT
* DSP
) {
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
);
51 pci_outl(reg(SAMPLE_RATE_CONV
), SRC_DISABLE
);
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)))
60 if (SRC_SUCCESS
!= (retVal
=
61 src_reg_write(DSP
, SRC_SYNTH_BASE
+ SRC_TRUNC_N_OFF
, 16 << 4)))
63 if (SRC_SUCCESS
!= (retVal
= src_reg_write(DSP
,
64 SRC_SYNTH_BASE
+ SRC_INT_REGS_OFF
, 16 << 10)))
66 if (SRC_SUCCESS
!= (retVal
=
67 src_reg_write(DSP
, SRC_DAC_BASE
+ SRC_TRUNC_N_OFF
, 16 << 4)))
69 if (SRC_SUCCESS
!= (retVal
=
70 src_reg_write(DSP
, SRC_DAC_BASE
+ SRC_INT_REGS_OFF
, 16 << 10)))
72 if (SRC_SUCCESS
!= (retVal
=
73 src_reg_write(DSP
, SRC_SYNTH_LVOL
, 1 << 12)))
75 if (SRC_SUCCESS
!= (retVal
=
76 src_reg_write(DSP
, SRC_SYNTH_RVOL
, 1 << 12)))
78 if (SRC_SUCCESS
!= (retVal
=
79 src_reg_write(DSP
, SRC_DAC_LVOL
, 1 << 12)))
81 if (SRC_SUCCESS
!= (retVal
=
82 src_reg_write(DSP
, SRC_DAC_RVOL
, 1 << 12)))
84 if (SRC_SUCCESS
!= (retVal
=
85 src_reg_write(DSP
, SRC_ADC_LVOL
, 1 << 12)))
87 if (SRC_SUCCESS
!= (retVal
=
88 src_reg_write(DSP
, SRC_ADC_RVOL
, 1 << 12)))
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
);
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
);
100 pci_outl(reg(SAMPLE_RATE_CONV
), 0UL);
106 static int src_reg_read(const DEV_STRUCT
* DSP
, u16_t reg
, u16_t
*data
) {
110 if (WaitBitd (reg(SAMPLE_RATE_CONV
), SRC_BUSY_BIT
, 0, 1000))
111 return (SRC_ERR_NOT_BUSY_TIMEOUT
);
113 dtemp
= pci_inl(reg(SAMPLE_RATE_CONV
));
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));
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
);
126 *data
= (u16_t
) pci_inl(reg(SAMPLE_RATE_CONV
));
132 static int src_reg_write(const DEV_STRUCT
* DSP
, u16_t reg
, u16_t val
) {
136 if (WaitBitd (reg(SAMPLE_RATE_CONV
), SRC_BUSY_BIT
, 0, 1000))
137 return (SRC_ERR_NOT_BUSY_TIMEOUT
);
139 dtemp
= pci_inl(reg(SAMPLE_RATE_CONV
));
141 /* assert the write request */
142 pci_outl(reg(SAMPLE_RATE_CONV
),
143 (dtemp
& SRC_CTLMASK
) | SRC_RAM_WE
| ((u32_t
) reg
<< 25) | val
);
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
;
154 if( base
!= SRC_ADC_BASE
)
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
) )
161 pci_outl(reg(SAMPLE_RATE_CONV
),
162 (pci_inl(reg(SAMPLE_RATE_CONV
)) & SRC_CTLMASK
) |
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
);
170 src_reg_write(DSP
, base
+ SRC_INT_REGS_OFF
,
172 ((u16_t
) (freq
>> 6) & 0xfc00));
174 src_reg_write(DSP
, base
+ SRC_VFREQ_FRAC_OFF
, (u16_t
) freq
>> 1);
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
) )
181 pci_outl(reg(SAMPLE_RATE_CONV
),
182 (pci_inl(reg(SAMPLE_RATE_CONV
)) & SRC_CTLMASK
) &
185 else /* setting ADC rate */
187 /* freeze the channel */
188 for( i
= 0; i
< SRC_IOPOLL_COUNT
; ++i
)
189 if( !(pci_inl(reg(SAMPLE_RATE_CONV
)) & SRC_RAM_BUSY
) )
191 pci_outl(reg(SAMPLE_RATE_CONV
),
192 (pci_inl(reg(SAMPLE_RATE_CONV
)) & SRC_CTLMASK
) |
197 /* derive oversample ratio */
199 if( N
== 15 || N
== 13 || N
== 11 || N
== 9 )
201 src_reg_write(DSP
, SRC_ADC_LVOL
, N
<< 8);
202 src_reg_write(DSP
, SRC_ADC_RVOL
, N
<< 8);
204 /* truncate the filter and write n/trunc_start */
205 truncM
= (21*N
- 1) | 1;
210 truncStart
= (239 - truncM
) >> 1;
211 src_reg_write(DSP
, base
+ SRC_TRUNC_N_OFF
,
212 (truncStart
<< 9) | (N
<< 4));
218 truncStart
= (119 - truncM
) >> 1;
219 src_reg_write(DSP
, base
+ SRC_TRUNC_N_OFF
,
220 0x8000U
| (truncStart
<< 9) | (N
<< 4));
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
,
228 ((u16_t
) (freq
>> 6) & 0xfc00));
229 src_reg_write(DSP
, base
+ SRC_VFREQ_FRAC_OFF
, (u16_t
) freq
>> 1);
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
) )
235 pci_outl(reg(SAMPLE_RATE_CONV
),
236 (pci_inl(reg(SAMPLE_RATE_CONV
)) & SRC_CTLMASK
) &