1 #include "codec.h"
2
3
4 /* Timeouts in milliseconds */
5 #define WIP_TIMEOUT 250UL
6 #define DRDY_TIMEOUT 250UL
7
8 /* The default SRC syncronization state number is 1. This state occurs
9 just after de-assertion of SYNC. This is supposed to be the safest
10 state for accessing the codec with an ES1371 Rev 1. Later versions
11 of the chip allegedly don't require syncronization. Be very careful
12 if you change this ! */
13
14 #define SRC_UNSYNCED 0xffffffffUL
15 static u32_t SrcSyncState = 0x00010000UL;
16
17
CodecSetSrcSyncState(int state)18 void CodecSetSrcSyncState (int state)
19 {
20 if (state < 0)
21 SrcSyncState = SRC_UNSYNCED;
22 else {
23 SrcSyncState = (u32_t)state << 16;
24 SrcSyncState &= 0x00070000Ul;
25 }
26 }
27
28
CodecWrite(DEV_STRUCT * pCC,u16_t wAddr,u16_t wData)29 int CodecWrite (DEV_STRUCT * pCC, u16_t wAddr, u16_t wData)
30 {
31 u32_t dtemp, i;
32 u16_t wBaseAddr = pCC->base;
33
34 /* wait for WIP bit (Write In Progress) to go away */
35 /* remember, register CONC_dCODECCTL_OFF (0x14)
36 is a pseudo read-write register */
37 if (WaitBitd (wBaseAddr + CONC_dCODECCTL_OFF, 30, 0, WIP_TIMEOUT)){
38 printf("CODEC_ERR_WIP_TIMEOUT\n");
39 return (CODEC_ERR_WIP_TIMEOUT);
40 }
41 if (SRC_UNSYNCED != SrcSyncState)
42 {
43 /* enable SRC state data in SRC mux */
44 if (WaitBitd (wBaseAddr + CONC_dSRCIO_OFF, SRC_BUSY_BIT, 0, 1000))
45 return (CODEC_ERR_SRC_NOT_BUSY_TIMEOUT);
46
47 /* todo: why are we writing an undefined register? */
48 dtemp = pci_inl(wBaseAddr + CONC_dSRCIO_OFF);
49 pci_outl(wBaseAddr + CONC_dSRCIO_OFF, (dtemp & SRC_CTLMASK) |
50 0x00010000UL);
51
52 /* wait for a SAFE time to write addr/data and then do it */
53 /*_disable(); */
54 for( i = 0; i < 0x1000UL; ++i )
55 if( (pci_inl(wBaseAddr + CONC_dSRCIO_OFF) & 0x00070000UL) ==
56 SrcSyncState )
57 break;
58
59 if (i >= 0x1000UL) {
60 /* _enable(); */
61 return (CODEC_ERR_SRC_SYNC_TIMEOUT);
62 }
63 }
64
65 /* A test for 5880 - prime the PCI data bus */
66 {
67 u32_t dat = ((u32_t) wAddr << 16) | wData;
68 char page = pci_inb(wBaseAddr + CONC_bMEMPAGE_OFF);
69
70 pci_outl (wBaseAddr + CONC_bMEMPAGE_OFF, dat);
71
72 /* write addr and data */
73 pci_outl(wBaseAddr + CONC_dCODECCTL_OFF, dat);
74
75 pci_outb(wBaseAddr + CONC_bMEMPAGE_OFF, page); /* restore page reg */
76 }
77
78 if (SRC_UNSYNCED != SrcSyncState)
79 {
80 /* _enable(); */
81
82 /* restore SRC reg */
83 if (WaitBitd (wBaseAddr + CONC_dSRCIO_OFF, SRC_BUSY_BIT, 0, 1000))
84 return (CODEC_ERR_SRC_NOT_BUSY_TIMEOUT);
85
86 pci_outl(wBaseAddr + CONC_dSRCIO_OFF, dtemp & 0xfff8ffffUL);
87 }
88
89 return 0;
90 }
91
CodecRead(DEV_STRUCT * pCC,u16_t wAddr,u16_t * data)92 int CodecRead (DEV_STRUCT * pCC, u16_t wAddr, u16_t *data)
93 {
94 u32_t dtemp, i;
95 u16_t base = pCC->base;
96
97 /* wait for WIP to go away */
98 if (WaitBitd (base + CONC_dCODECCTL_OFF, 30, 0, WIP_TIMEOUT))
99 return (CODEC_ERR_WIP_TIMEOUT);
100
101 if (SRC_UNSYNCED != SrcSyncState)
102 {
103 /* enable SRC state data in SRC mux */
104 if (WaitBitd (base + CONC_dSRCIO_OFF, SRC_BUSY_BIT, 0, 1000))
105 return (CODEC_ERR_SRC_NOT_BUSY_TIMEOUT);
106
107 dtemp = pci_inl(base + CONC_dSRCIO_OFF);
108 pci_outl(base + CONC_dSRCIO_OFF, (dtemp & SRC_CTLMASK) |
109 0x00010000UL);
110
111 /* wait for a SAFE time to write a read request and then do it */
112 /* todo: how do we solve the lock() problem? */
113 /* _disable(); */
114 for( i = 0; i < 0x1000UL; ++i )
115 if( (pci_inl(base + CONC_dSRCIO_OFF) & 0x00070000UL) ==
116 SrcSyncState )
117 break;
118
119 if (i >= 0x1000UL) {
120 /*_enable();*/
121 return (CODEC_ERR_SRC_SYNC_TIMEOUT);
122 }
123 }
124
125 /* A test for 5880 - prime the PCI data bus */
126 {
127 /* set bit 23, this means read in stead of write. */
128 u32_t dat = ((u32_t) wAddr << 16) | (1UL << 23);
129 char page = pci_inb(base + CONC_bMEMPAGE_OFF);
130
131 /* todo: why are we putting data in the mem page register??? */
132 pci_outl(base + CONC_bMEMPAGE_OFF, dat);
133
134 /* write addr w/data=0 and assert read request */
135 pci_outl(base + CONC_dCODECCTL_OFF, dat);
136
137 pci_outb(base + CONC_bMEMPAGE_OFF, page); /* restore page reg */
138
139 }
140 if (SRC_UNSYNCED != SrcSyncState)
141 {
142
143 /*_enable();*/
144
145 /* restore SRC reg */
146 if (WaitBitd (base + CONC_dSRCIO_OFF, SRC_BUSY_BIT, 0, 1000))
147 return (CODEC_ERR_SRC_NOT_BUSY_TIMEOUT);
148
149 pci_outl(base + CONC_dSRCIO_OFF, dtemp & 0xfff8ffffUL);
150 }
151
152 /* now wait for the stinkin' data (DRDY = data ready) */
153 if (WaitBitd (base + CONC_dCODECCTL_OFF, 31, 1, DRDY_TIMEOUT))
154 return (CODEC_ERR_DATA_TIMEOUT);
155
156 dtemp = pci_inl(base + CONC_dCODECCTL_OFF);
157
158 if (data)
159 *data = (u16_t) dtemp;
160
161 return 0;
162 }
163
164
CodecWriteUnsynced(DEV_STRUCT * pCC,u16_t wAddr,u16_t wData)165 int CodecWriteUnsynced (DEV_STRUCT * pCC, u16_t wAddr, u16_t wData)
166 {
167 /* wait for WIP to go away */
168 if (WaitBitd (pCC->base + CONC_dCODECCTL_OFF, 30, 0, WIP_TIMEOUT))
169 return (CODEC_ERR_WIP_TIMEOUT);
170
171 /* write addr and data */
172 pci_outl(pCC->base + CONC_dCODECCTL_OFF, ((u32_t) wAddr << 16) | wData);
173 return 0;
174 }
175
176
CodecReadUnsynced(DEV_STRUCT * pCC,u16_t wAddr,u16_t * data)177 int CodecReadUnsynced (DEV_STRUCT * pCC, u16_t wAddr, u16_t *data)
178 {
179 u32_t dtemp;
180
181 /* wait for WIP to go away */
182 if (WaitBitd (pCC->base + CONC_dCODECCTL_OFF, 30, 0, WIP_TIMEOUT))
183 return (CODEC_ERR_WIP_TIMEOUT);
184
185 /* write addr w/data=0 and assert read request */
186 pci_outl(pCC->base + CONC_dCODECCTL_OFF, ((u32_t) wAddr << 16) | (1UL << 23));
187
188 /* now wait for the stinkin' data (RDY) */
189 if (WaitBitd (pCC->base + CONC_dCODECCTL_OFF, 31, 1, DRDY_TIMEOUT))
190 return (CODEC_ERR_DATA_TIMEOUT);
191
192 dtemp = pci_inl(pCC->base + CONC_dCODECCTL_OFF);
193
194 if (data)
195 *data = (u16_t) dtemp;
196
197 return 0;
198 }
199
CODECInit(DEV_STRUCT * pCC)200 int CODECInit( DEV_STRUCT * pCC )
201 {
202 int retVal;
203 /* All powerdown modes: off */
204
205 retVal = CodecWrite (pCC, AC97_POWERDOWN_CONTROL_STAT, 0x0000U);
206 if (OK != retVal)
207 return (retVal);
208
209 /* Mute Line Out & set to 0dB attenuation */
210
211 retVal = CodecWrite (pCC, AC97_MASTER_VOLUME, 0x0000U);
212 if (OK != retVal)
213 return (retVal);
214
215
216 retVal = CodecWrite (pCC, AC97_MONO_VOLUME, 0x8000U);
217 if (OK != retVal)
218 return (retVal);
219
220 retVal = CodecWrite (pCC, AC97_PHONE_VOLUME, 0x8008U);
221 if (OK != retVal)
222 return (retVal);
223
224 retVal = CodecWrite (pCC, AC97_MIC_VOLUME, 0x0008U);
225 if (OK != retVal)
226 return (retVal);
227
228 retVal = CodecWrite (pCC, AC97_LINE_IN_VOLUME, 0x0808U);
229 if (OK != retVal)
230 return (retVal);
231
232 retVal = CodecWrite (pCC, AC97_CD_VOLUME, 0x0808U);
233 if (OK != retVal)
234 return (retVal);
235
236 retVal = CodecWrite (pCC, AC97_AUX_IN_VOLUME, 0x0808U);
237 if (OK != retVal)
238 return (retVal);
239
240 retVal = CodecWrite (pCC, AC97_PCM_OUT_VOLUME, 0x0808U);
241 if (OK != retVal)
242 return (retVal);
243
244 retVal = CodecWrite (pCC, AC97_RECORD_GAIN_VOLUME, 0x0000U);
245 if (OK != retVal)
246 return (retVal);
247
248 /* Connect Line In to ADC */
249 retVal = CodecWrite (pCC, AC97_RECORD_SELECT, 0x0404U);
250 if (OK != retVal)
251 return (retVal);
252
253 retVal = CodecWrite (pCC, AC97_GENERAL_PURPOSE, 0x0000U);
254 if (OK != retVal)
255 return (retVal);
256
257 return OK;
258 }
259
260
261
262
263
264
265