1 #include "AC97.h"
2
3
4
5
6
7 /* AC97 Mixer and Mode control function prototypes */
8
9 static int AC97_write(const DEV_STRUCT * pCC, u16_t wAddr, u16_t
10 wData);
11 static int AC97_write_unsynced(const DEV_STRUCT * pCC, u16_t wAddr,
12 u16_t wData);
13 static int AC97_read_unsynced(const DEV_STRUCT * pCC, u16_t wAddr,
14 u16_t *data);
15 static void set_nice_volume(void);
16 static int AC97_get_volume(struct volume_level *level);
17 static int AC97_set_volume(const struct volume_level *level);
18
19
20
21 #define AC97_0DB_GAIN 0x0008
22 #define AC97_MAX_ATTN 0x003f
23 #define AC97_MUTE 0x8000U
24
25
26 /* Control function defines */
27 #define AC97_CTL_4SPKR 0x00U /* 4-spkr output mode enable */
28 #define AC97_CTL_MICBOOST 0x01U /* Mic boost (+30 dB) enable */
29 #define AC97_CTL_PWRDOWN 0x02U /* power-down mode */
30 #define AC97_CTL_DOSMODE 0x03U /* A/D sync to DAC1 */
31
32 /* Timeout waiting for: */
33 #define AC97_ERR_WIP_TIMEOUT -1 /* write in progress complete */
34 #define AC97_ERR_DATA_TIMEOUT -2 /* data ready */
35 #define AC97_ERR_SRC_NOT_BUSY_TIMEOUT -3 /* SRC not busy */
36 #define AC97_ERR_SRC_SYNC_TIMEOUT -4 /* state #1 */
37
38
39
40
41
42
43 /* Timeouts in milliseconds */
44 #define WIP_TIMEOUT 250UL
45 #define DRDY_TIMEOUT 250UL
46
47 /* The default SRC syncronization state number is 1. This state occurs
48 just after de-assertion of SYNC. This is supposed to be the safest
49 state for accessing the codec with an ES1371 Rev 1. Later versions
50 of the chip allegedly don't require syncronization. Be very careful
51 if you change this ! */
52
53 #define SRC_UNSYNCED 0xffffffffUL
54 static u32_t SrcSyncState = 0x00010000UL;
55 static DEV_STRUCT *dev;
56
57
58 #if 0
59 static void set_src_sync_state (int state)
60 {
61 if (state < 0)
62 SrcSyncState = SRC_UNSYNCED;
63 else {
64 SrcSyncState = (u32_t)state << 16;
65 SrcSyncState &= 0x00070000Ul;
66 }
67 }
68 #endif
69
70
AC97_write(const DEV_STRUCT * pCC,u16_t wAddr,u16_t wData)71 static int AC97_write (const DEV_STRUCT * pCC, u16_t wAddr, u16_t wData)
72 {
73 u32_t dtemp, i;
74 u16_t wBaseAddr = pCC->base;
75
76 /* wait for WIP bit (Write In Progress) to go away */
77 /* remember, register CODEC_READ (0x14)
78 is a pseudo read-write register */
79 if (WaitBitd (wBaseAddr + CODEC_READ, 30, 0, WIP_TIMEOUT)){
80 printf("AC97_ERR_WIP_TIMEOUT\n");
81 return (AC97_ERR_WIP_TIMEOUT);
82 }
83 if (SRC_UNSYNCED != SrcSyncState)
84 {
85 /* enable SRC state data in SRC mux */
86 if (WaitBitd (wBaseAddr + SAMPLE_RATE_CONV, SRC_BUSY_BIT, 0, 1000))
87 return (AC97_ERR_SRC_NOT_BUSY_TIMEOUT);
88
89 /* todo: why are we writing an undefined register? */
90 dtemp = pci_inl(wBaseAddr + SAMPLE_RATE_CONV);
91 pci_outl(wBaseAddr + SAMPLE_RATE_CONV, (dtemp & SRC_CTLMASK) |
92 0x00010000UL);
93
94 /* wait for a SAFE time to write addr/data and then do it */
95 /*_disable(); */
96 for( i = 0; i < 0x1000UL; ++i )
97 if( (pci_inl(wBaseAddr + SAMPLE_RATE_CONV) & 0x00070000UL) ==
98 SrcSyncState )
99 break;
100
101 if (i >= 0x1000UL) {
102 /* _enable(); */
103 return (AC97_ERR_SRC_SYNC_TIMEOUT);
104 }
105 }
106
107 /* A test for 5880 - prime the PCI data bus */
108 {
109 u32_t dat = ((u32_t) wAddr << 16) | wData;
110 char page = pci_inb(wBaseAddr + MEM_PAGE);
111
112 pci_outl (wBaseAddr + MEM_PAGE, dat);
113
114 /* write addr and data */
115 pci_outl(wBaseAddr + CODEC_READ, dat);
116
117 pci_outb(wBaseAddr + MEM_PAGE, page); /* restore page reg */
118 }
119
120 if (SRC_UNSYNCED != SrcSyncState)
121 {
122 /* _enable(); */
123
124 /* restore SRC reg */
125 if (WaitBitd (wBaseAddr + SAMPLE_RATE_CONV, SRC_BUSY_BIT, 0, 1000))
126 return (AC97_ERR_SRC_NOT_BUSY_TIMEOUT);
127
128 pci_outl(wBaseAddr + SAMPLE_RATE_CONV, dtemp & 0xfff8ffffUL);
129 }
130
131 return 0;
132 }
133
134
135 #if 0
136 static int AC97_read (const DEV_STRUCT * pCC, u16_t wAddr, u16_t *data)
137 {
138 u32_t dtemp, i;
139 u16_t base = pCC->base;
140
141 /* wait for WIP to go away */
142 if (WaitBitd (base + CODEC_READ, 30, 0, WIP_TIMEOUT))
143 return (AC97_ERR_WIP_TIMEOUT);
144
145 if (SRC_UNSYNCED != SrcSyncState)
146 {
147 /* enable SRC state data in SRC mux */
148 if (WaitBitd (base + SAMPLE_RATE_CONV, SRC_BUSY_BIT, 0, 1000))
149 return (AC97_ERR_SRC_NOT_BUSY_TIMEOUT);
150
151 dtemp = pci_inl(base + SAMPLE_RATE_CONV);
152 pci_outl(base + SAMPLE_RATE_CONV, (dtemp & SRC_CTLMASK) |
153 0x00010000UL);
154
155 /* wait for a SAFE time to write a read request and then do it */
156 /* todo: how do we solve the lock() problem? */
157 /* _disable(); */
158 for( i = 0; i < 0x1000UL; ++i )
159 if( (pci_inl(base + SAMPLE_RATE_CONV) & 0x00070000UL) ==
160 SrcSyncState )
161 break;
162
163 if (i >= 0x1000UL) {
164 /*_enable();*/
165 return (AC97_ERR_SRC_SYNC_TIMEOUT);
166 }
167 }
168
169 /* A test for 5880 - prime the PCI data bus */
170 {
171 /* set bit 23, this means read in stead of write. */
172 u32_t dat = ((u32_t) wAddr << 16) | (1UL << 23);
173 char page = pci_inb(base + MEM_PAGE);
174
175 /* todo: why are we putting data in the mem page register??? */
176 pci_outl(base + MEM_PAGE, dat);
177
178 /* write addr w/data=0 and assert read request */
179 pci_outl(base + CODEC_READ, dat);
180
181 pci_outb(base + MEM_PAGE, page); /* restore page reg */
182
183 }
184 if (SRC_UNSYNCED != SrcSyncState)
185 {
186
187 /*_enable();*/
188
189 /* restore SRC reg */
190 if (WaitBitd (base + SAMPLE_RATE_CONV, SRC_BUSY_BIT, 0, 1000))
191 return (AC97_ERR_SRC_NOT_BUSY_TIMEOUT);
192
193 pci_outl(base + SAMPLE_RATE_CONV, dtemp & 0xfff8ffffUL);
194 }
195
196 /* now wait for the stinkin' data (DRDY = data ready) */
197 if (WaitBitd (base + CODEC_READ, 31, 1, DRDY_TIMEOUT))
198 return (AC97_ERR_DATA_TIMEOUT);
199
200 dtemp = pci_inl(base + CODEC_READ);
201
202 if (data)
203 *data = (u16_t) dtemp;
204
205 return 0;
206 }
207 #endif
208
209
AC97_write_unsynced(const DEV_STRUCT * pCC,u16_t wAddr,u16_t wData)210 static int AC97_write_unsynced (const DEV_STRUCT * pCC, u16_t wAddr,
211 u16_t wData)
212 {
213 /* wait for WIP to go away */
214 if (WaitBitd (pCC->base + CODEC_READ, 30, 0, WIP_TIMEOUT))
215 return (AC97_ERR_WIP_TIMEOUT);
216
217 /* write addr and data */
218 pci_outl(pCC->base + CODEC_READ, ((u32_t) wAddr << 16) | wData);
219 return 0;
220 }
221
222
AC97_read_unsynced(const DEV_STRUCT * pCC,u16_t wAddr,u16_t * data)223 static int AC97_read_unsynced (const DEV_STRUCT * pCC, u16_t wAddr,
224 u16_t *data)
225 {
226 u32_t dtemp;
227
228 /* wait for WIP to go away */
229 if (WaitBitd (pCC->base + CODEC_READ, 30, 0, WIP_TIMEOUT))
230 return (AC97_ERR_WIP_TIMEOUT);
231
232 /* write addr w/data=0 and assert read request */
233 pci_outl(pCC->base + CODEC_READ, ((u32_t) wAddr << 16) | (1UL << 23));
234
235 /* now wait for the stinkin' data (RDY) */
236 if (WaitBitd (pCC->base + CODEC_READ, 31, 1, DRDY_TIMEOUT))
237 return (AC97_ERR_DATA_TIMEOUT);
238
239 dtemp = pci_inl(pCC->base + CODEC_READ);
240
241 if (data)
242 *data = (u16_t) dtemp;
243
244 return 0;
245 }
246
247
AC97_init(DEV_STRUCT * pCC)248 int AC97_init( DEV_STRUCT * pCC ) {
249 int retVal;
250 /* All powerdown modes: off */
251
252 dev = pCC;
253
254 retVal = AC97_write (pCC, AC97_POWERDOWN_CONTROL_STAT, 0x0000U);
255 if (OK != retVal)
256 return (retVal);
257
258 /* Mute Line Out & set to 0dB attenuation */
259
260 retVal = AC97_write (pCC, AC97_MASTER_VOLUME, 0x0000U);
261 if (OK != retVal)
262 return (retVal);
263
264
265 retVal = AC97_write (pCC, AC97_MONO_VOLUME, 0x8000U);
266 if (OK != retVal)
267 return (retVal);
268
269 retVal = AC97_write (pCC, AC97_PHONE_VOLUME, 0x8008U);
270 if (OK != retVal)
271 return (retVal);
272
273 retVal = AC97_write (pCC, AC97_MIC_VOLUME, 0x0008U);
274 if (OK != retVal)
275 return (retVal);
276
277 retVal = AC97_write (pCC, AC97_LINE_IN_VOLUME, 0x0808U);
278 if (OK != retVal)
279 return (retVal);
280
281 retVal = AC97_write (pCC, AC97_CD_VOLUME, 0x0808U);
282 if (OK != retVal)
283 return (retVal);
284
285 retVal = AC97_write (pCC, AC97_AUX_IN_VOLUME, 0x0808U);
286 if (OK != retVal)
287 return (retVal);
288
289 retVal = AC97_write (pCC, AC97_PCM_OUT_VOLUME, 0x0808U);
290 if (OK != retVal)
291 return (retVal);
292
293 retVal = AC97_write (pCC, AC97_RECORD_GAIN_VOLUME, 0x0000U);
294 if (OK != retVal)
295 return (retVal);
296
297 /* Connect Line In to ADC */
298 retVal = AC97_write (pCC, AC97_RECORD_SELECT, 0x0404U);
299 if (OK != retVal)
300 return (retVal);
301
302 retVal = AC97_write (pCC, AC97_GENERAL_PURPOSE, 0x0000U);
303 if (OK != retVal)
304 return (retVal);
305
306 set_nice_volume();
307
308 return OK;
309 }
310
311
set_nice_volume(void)312 static void set_nice_volume(void) {
313 /* goofy code to set the DAC1 channel to an audibe volume
314 to be able to test it without using the mixer */
315
316 AC97_write_unsynced(dev, AC97_PCM_OUT_VOLUME, 0x0808);/* the higher,
317 the softer */
318 AC97_write_unsynced(dev, AC97_MASTER_VOLUME, 0x0101);
319 AC97_write_unsynced(dev, 0x38, 0); /* not crucial */
320
321 AC97_write_unsynced(dev, AC97_LINE_IN_VOLUME, 0x0303);
322 AC97_write_unsynced(dev, AC97_MIC_VOLUME, 0x005f);
323
324 /* mute record gain */
325 AC97_write_unsynced(dev, AC97_RECORD_GAIN_VOLUME, 0xFFFF);
326 /* mic record volume high */
327 AC97_write_unsynced(dev, AC97_RECORD_GAIN_MIC_VOL, 0x0000);
328
329 /* Also, to be able test recording without mixer:
330 select ONE channel as input below. */
331
332 /* select LINE IN */
333 /*AC97_write_unsynced(dev, AC97_RECORD_SELECT, 0x0404);*/
334
335 /* select MIC */
336 AC97_write_unsynced(dev, AC97_RECORD_SELECT, 0x0000);
337
338 /* unmute record gain */
339 AC97_write_unsynced(dev, AC97_RECORD_GAIN_VOLUME, 0x0000);
340 }
341
342
get_volume(u8_t * left,u8_t * right,int cmd)343 static int get_volume(u8_t *left, u8_t *right, int cmd) {
344 u16_t value = 0;
345
346 AC97_read_unsynced(dev, (u16_t)cmd, &value);
347
348 *left = value>>8;
349 *right = value&0xff;
350
351 return OK;
352 }
353
354
set_volume(int left,int right,int cmd)355 static int set_volume(int left, int right, int cmd) {
356 u16_t waarde;
357
358 waarde = (u16_t)((left<<8)|right);
359
360 AC97_write_unsynced(dev, (u16_t)cmd, waarde);
361
362 return OK;
363 }
364
365
convert(int left_in,int right_in,int max_in,int * left_out,int * right_out,int max_out,int swaplr)366 void convert(int left_in, int right_in, int max_in, int *left_out,
367 int *right_out, int max_out, int swaplr) {
368 int tmp;
369
370 if(left_in < 0) left_in = 0;
371 else if(left_in > max_in) left_in = max_in;
372 if(right_in < 0) right_in = 0;
373 else if(right_in > max_in) right_in = max_in;
374
375 if (swaplr) {
376 tmp = left_in;
377 left_in = right_in;
378 right_in = tmp;
379 }
380
381 *left_out = (-left_in) + max_out;
382 *right_out = (-right_in) + max_out;
383 }
384
385
AC97_get_set_volume(struct volume_level * level,int flag)386 int AC97_get_set_volume(struct volume_level *level, int flag) {
387 if (flag) {
388 return AC97_set_volume(level);
389 }
390 else {
391 return AC97_get_volume(level);
392 }
393 }
394
395
AC97_get_volume(struct volume_level * level)396 static int AC97_get_volume(struct volume_level *level) {
397 int cmd;
398 u8_t left;
399 u8_t right;
400
401 switch(level->device) {
402 case Master:
403 cmd = AC97_MASTER_VOLUME;
404 get_volume(&left, &right, cmd);
405 convert(left, right, 0x1f,
406 &(level->left), &(level->right), 0x1f, 0);
407 break;
408 case Dac:
409 return EINVAL;
410 break;
411 case Fm:
412 cmd = AC97_PCM_OUT_VOLUME;
413 get_volume(&left, &right, cmd);
414 convert(left, right, 0x1f,
415 &(level->left), &(level->right), 0x1f, 0);
416 break;
417 case Cd:
418 cmd = AC97_CD_VOLUME;
419 get_volume(&left, &right, cmd);
420 convert(left, right, 0x1f,
421 &(level->left), &(level->right), 0x1f, 0);
422 break;
423 case Line:
424 cmd = AC97_LINE_IN_VOLUME;
425 get_volume(&left, &right, cmd);
426 convert(left, right, 0x1f,
427 &(level->left), &(level->right), 0x1f, 0);
428 break;
429 case Mic:
430 cmd = AC97_MIC_VOLUME;
431 get_volume(&left, &right, cmd);
432 convert(left, right, 0x1f,
433 &(level->left), &(level->right), 0x1f, 1);
434 break;
435 case Speaker:
436 return EINVAL;
437 case Treble:
438 cmd = AC97_MASTER_TONE;
439 get_volume(&left, &right, cmd);
440 convert(left, right, 0xf,
441 &(level->left), &(level->right), 0xf, 1);
442 break;
443 case Bass:
444 cmd = AC97_MASTER_TONE;
445 get_volume(&left, &right, cmd);
446 convert(left, right, 0xf,
447 &(level->left), &(level->right), 0xf, 1);
448 break;
449 default:
450 return EINVAL;
451 }
452 return OK;
453 }
454
455
AC97_set_volume(const struct volume_level * level)456 static int AC97_set_volume(const struct volume_level *level) {
457 int cmd;
458 int left;
459 int right;
460
461 switch(level->device) {
462 case Master:
463 cmd = AC97_MASTER_VOLUME;
464 convert(level->left, level->right, 0x1f, &left, &right, 0x1f, 0);
465 break;
466 case Dac:
467 return EINVAL;
468 case Fm:
469 cmd = AC97_PCM_OUT_VOLUME;
470 convert(level->left, level->right, 0x1f, &left, &right, 0x1f, 0);
471 break;
472 case Cd:
473 cmd = AC97_CD_VOLUME;
474 convert(level->left, level->right, 0x1f, &left, &right, 0x1f, 0);
475 break;
476 case Line:
477 cmd = AC97_LINE_IN_VOLUME;
478 convert(level->left, level->right, 0x1f, &left, &right, 0x1f, 0);
479 break;
480 case Mic:
481 cmd = AC97_MIC_VOLUME;
482 convert(level->left, level->right, 0x1f, &left, &right, 0x1f, 1);
483 break;
484 case Speaker:
485 return EINVAL;
486 case Treble:
487 return EINVAL;
488 case Bass:
489 return EINVAL;
490 default:
491 return EINVAL;
492 }
493 set_volume(left, right, cmd);
494
495 return OK;
496 }
497