7 /* AC97 Mixer and Mode control function prototypes */
9 static int AC97_write(const DEV_STRUCT
* pCC
, u16_t wAddr
, u16_t
11 static int AC97_write_unsynced(const DEV_STRUCT
* pCC
, u16_t wAddr
,
13 static int AC97_read_unsynced(const DEV_STRUCT
* pCC
, u16_t wAddr
,
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
);
21 #define AC97_0DB_GAIN 0x0008
22 #define AC97_MAX_ATTN 0x003f
23 #define AC97_MUTE 0x8000U
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 */
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 */
43 /* Timeouts in milliseconds */
44 #define WIP_TIMEOUT 250UL
45 #define DRDY_TIMEOUT 250UL
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 ! */
53 #define SRC_UNSYNCED 0xffffffffUL
54 static u32_t SrcSyncState
= 0x00010000UL
;
55 static DEV_STRUCT
*dev
;
59 static void set_src_sync_state (int state
)
62 SrcSyncState
= SRC_UNSYNCED
;
64 SrcSyncState
= (u32_t
)state
<< 16;
65 SrcSyncState
&= 0x00070000Ul
;
71 static int AC97_write (const DEV_STRUCT
* pCC
, u16_t wAddr
, u16_t wData
)
74 u16_t wBaseAddr
= pCC
->base
;
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
);
83 if (SRC_UNSYNCED
!= SrcSyncState
)
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
);
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
) |
94 /* wait for a SAFE time to write addr/data and then do it */
96 for( i
= 0; i
< 0x1000UL
; ++i
)
97 if( (pci_inl(wBaseAddr
+ SAMPLE_RATE_CONV
) & 0x00070000UL
) ==
103 return (AC97_ERR_SRC_SYNC_TIMEOUT
);
107 /* A test for 5880 - prime the PCI data bus */
109 u32_t dat
= ((u32_t
) wAddr
<< 16) | wData
;
110 char page
= pci_inb(wBaseAddr
+ MEM_PAGE
);
112 pci_outl (wBaseAddr
+ MEM_PAGE
, dat
);
114 /* write addr and data */
115 pci_outl(wBaseAddr
+ CODEC_READ
, dat
);
117 pci_outb(wBaseAddr
+ MEM_PAGE
, page
); /* restore page reg */
120 if (SRC_UNSYNCED
!= SrcSyncState
)
124 /* restore SRC reg */
125 if (WaitBitd (wBaseAddr
+ SAMPLE_RATE_CONV
, SRC_BUSY_BIT
, 0, 1000))
126 return (AC97_ERR_SRC_NOT_BUSY_TIMEOUT
);
128 pci_outl(wBaseAddr
+ SAMPLE_RATE_CONV
, dtemp
& 0xfff8ffffUL
);
136 static int AC97_read (const DEV_STRUCT
* pCC
, u16_t wAddr
, u16_t
*data
)
139 u16_t base
= pCC
->base
;
141 /* wait for WIP to go away */
142 if (WaitBitd (base
+ CODEC_READ
, 30, 0, WIP_TIMEOUT
))
143 return (AC97_ERR_WIP_TIMEOUT
);
145 if (SRC_UNSYNCED
!= SrcSyncState
)
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
);
151 dtemp
= pci_inl(base
+ SAMPLE_RATE_CONV
);
152 pci_outl(base
+ SAMPLE_RATE_CONV
, (dtemp
& SRC_CTLMASK
) |
155 /* wait for a SAFE time to write a read request and then do it */
156 /* todo: how do we solve the lock() problem? */
158 for( i
= 0; i
< 0x1000UL
; ++i
)
159 if( (pci_inl(base
+ SAMPLE_RATE_CONV
) & 0x00070000UL
) ==
165 return (AC97_ERR_SRC_SYNC_TIMEOUT
);
169 /* A test for 5880 - prime the PCI data bus */
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
);
175 /* todo: why are we putting data in the mem page register??? */
176 pci_outl(base
+ MEM_PAGE
, dat
);
178 /* write addr w/data=0 and assert read request */
179 pci_outl(base
+ CODEC_READ
, dat
);
181 pci_outb(base
+ MEM_PAGE
, page
); /* restore page reg */
184 if (SRC_UNSYNCED
!= SrcSyncState
)
189 /* restore SRC reg */
190 if (WaitBitd (base
+ SAMPLE_RATE_CONV
, SRC_BUSY_BIT
, 0, 1000))
191 return (AC97_ERR_SRC_NOT_BUSY_TIMEOUT
);
193 pci_outl(base
+ SAMPLE_RATE_CONV
, dtemp
& 0xfff8ffffUL
);
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
);
200 dtemp
= pci_inl(base
+ CODEC_READ
);
203 *data
= (u16_t
) dtemp
;
210 static int AC97_write_unsynced (const DEV_STRUCT
* pCC
, u16_t wAddr
,
213 /* wait for WIP to go away */
214 if (WaitBitd (pCC
->base
+ CODEC_READ
, 30, 0, WIP_TIMEOUT
))
215 return (AC97_ERR_WIP_TIMEOUT
);
217 /* write addr and data */
218 pci_outl(pCC
->base
+ CODEC_READ
, ((u32_t
) wAddr
<< 16) | wData
);
223 static int AC97_read_unsynced (const DEV_STRUCT
* pCC
, u16_t wAddr
,
228 /* wait for WIP to go away */
229 if (WaitBitd (pCC
->base
+ CODEC_READ
, 30, 0, WIP_TIMEOUT
))
230 return (AC97_ERR_WIP_TIMEOUT
);
232 /* write addr w/data=0 and assert read request */
233 pci_outl(pCC
->base
+ CODEC_READ
, ((u32_t
) wAddr
<< 16) | (1UL << 23));
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
);
239 dtemp
= pci_inl(pCC
->base
+ CODEC_READ
);
242 *data
= (u16_t
) dtemp
;
248 int AC97_init( DEV_STRUCT
* pCC
) {
250 /* All powerdown modes: off */
254 retVal
= AC97_write (pCC
, AC97_POWERDOWN_CONTROL_STAT
, 0x0000U
);
258 /* Mute Line Out & set to 0dB attenuation */
260 retVal
= AC97_write (pCC
, AC97_MASTER_VOLUME
, 0x0000U
);
265 retVal
= AC97_write (pCC
, AC97_MONO_VOLUME
, 0x8000U
);
269 retVal
= AC97_write (pCC
, AC97_PHONE_VOLUME
, 0x8008U
);
273 retVal
= AC97_write (pCC
, AC97_MIC_VOLUME
, 0x0008U
);
277 retVal
= AC97_write (pCC
, AC97_LINE_IN_VOLUME
, 0x0808U
);
281 retVal
= AC97_write (pCC
, AC97_CD_VOLUME
, 0x0808U
);
285 retVal
= AC97_write (pCC
, AC97_AUX_IN_VOLUME
, 0x0808U
);
289 retVal
= AC97_write (pCC
, AC97_PCM_OUT_VOLUME
, 0x0808U
);
293 retVal
= AC97_write (pCC
, AC97_RECORD_GAIN_VOLUME
, 0x0000U
);
297 /* Connect Line In to ADC */
298 retVal
= AC97_write (pCC
, AC97_RECORD_SELECT
, 0x0404U
);
302 retVal
= AC97_write (pCC
, AC97_GENERAL_PURPOSE
, 0x0000U
);
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 */
316 AC97_write_unsynced(dev
, AC97_PCM_OUT_VOLUME
, 0x0808);/* the higher,
318 AC97_write_unsynced(dev
, AC97_MASTER_VOLUME
, 0x0101);
319 AC97_write_unsynced(dev
, 0x38, 0); /* not crucial */
321 AC97_write_unsynced(dev
, AC97_LINE_IN_VOLUME
, 0x0303);
322 AC97_write_unsynced(dev
, AC97_MIC_VOLUME
, 0x005f);
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);
329 /* Also, to be able test recording without mixer:
330 select ONE channel as input below. */
333 /*AC97_write_unsynced(dev, AC97_RECORD_SELECT, 0x0404);*/
336 AC97_write_unsynced(dev
, AC97_RECORD_SELECT
, 0x0000);
338 /* unmute record gain */
339 AC97_write_unsynced(dev
, AC97_RECORD_GAIN_VOLUME
, 0x0000);
343 static int get_volume(u8_t
*left
, u8_t
*right
, int cmd
) {
346 AC97_read_unsynced(dev
, (u16_t
)cmd
, &value
);
355 static int set_volume(int left
, int right
, int cmd
) {
358 waarde
= (u16_t
)((left
<<8)|right
);
360 AC97_write_unsynced(dev
, (u16_t
)cmd
, waarde
);
366 void convert(int left_in
, int right_in
, int max_in
, int *left_out
,
367 int *right_out
, int max_out
, int swaplr
) {
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
;
381 *left_out
= (-left_in
) + max_out
;
382 *right_out
= (-right_in
) + max_out
;
386 int AC97_get_set_volume(struct volume_level
*level
, int flag
) {
388 return AC97_set_volume(level
);
391 return AC97_get_volume(level
);
396 static int AC97_get_volume(struct volume_level
*level
) {
401 switch(level
->device
) {
403 cmd
= AC97_MASTER_VOLUME
;
404 get_volume(&left
, &right
, cmd
);
405 convert(left
, right
, 0x1f,
406 &(level
->left
), &(level
->right
), 0x1f, 0);
412 cmd
= AC97_PCM_OUT_VOLUME
;
413 get_volume(&left
, &right
, cmd
);
414 convert(left
, right
, 0x1f,
415 &(level
->left
), &(level
->right
), 0x1f, 0);
418 cmd
= AC97_CD_VOLUME
;
419 get_volume(&left
, &right
, cmd
);
420 convert(left
, right
, 0x1f,
421 &(level
->left
), &(level
->right
), 0x1f, 0);
424 cmd
= AC97_LINE_IN_VOLUME
;
425 get_volume(&left
, &right
, cmd
);
426 convert(left
, right
, 0x1f,
427 &(level
->left
), &(level
->right
), 0x1f, 0);
430 cmd
= AC97_MIC_VOLUME
;
431 get_volume(&left
, &right
, cmd
);
432 convert(left
, right
, 0x1f,
433 &(level
->left
), &(level
->right
), 0x1f, 1);
438 cmd
= AC97_MASTER_TONE
;
439 get_volume(&left
, &right
, cmd
);
440 convert(left
, right
, 0xf,
441 &(level
->left
), &(level
->right
), 0xf, 1);
444 cmd
= AC97_MASTER_TONE
;
445 get_volume(&left
, &right
, cmd
);
446 convert(left
, right
, 0xf,
447 &(level
->left
), &(level
->right
), 0xf, 1);
456 static int AC97_set_volume(const struct volume_level
*level
) {
461 switch(level
->device
) {
463 cmd
= AC97_MASTER_VOLUME
;
464 convert(level
->left
, level
->right
, 0x1f, &left
, &right
, 0x1f, 0);
469 cmd
= AC97_PCM_OUT_VOLUME
;
470 convert(level
->left
, level
->right
, 0x1f, &left
, &right
, 0x1f, 0);
473 cmd
= AC97_CD_VOLUME
;
474 convert(level
->left
, level
->right
, 0x1f, &left
, &right
, 0x1f, 0);
477 cmd
= AC97_LINE_IN_VOLUME
;
478 convert(level
->left
, level
->right
, 0x1f, &left
, &right
, 0x1f, 0);
481 cmd
= AC97_MIC_VOLUME
;
482 convert(level
->left
, level
->right
, 0x1f, &left
, &right
, 0x1f, 1);
493 set_volume(left
, right
, cmd
);