2 The contents of this file are subject to the AROS Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
3 http://www.aros.org/license.html
5 Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
6 ANY KIND, either express or implied. See the License for the specific language governing rights and
7 limitations under the License.
9 (C) Copyright xxxx-2009 Davy Wentzler.
10 (C) Copyright 2009-2010 Stephen Jones.
12 The Initial Developer of the Original Code is Davy Wentzler.
19 #include <devices/ahi.h>
20 #include <exec/memory.h>
21 #include <libraries/ahi_sub.h>
24 #include <proto/ahi_sub.h>
25 #include <proto/exec.h>
26 #include <proto/dos.h>
27 #include <proto/utility.h>
29 #include <aros/debug.h>
36 #include "pci_wrapper.h"
43 /******************************************************************************
44 ** Globals ********************************************************************
45 ******************************************************************************/
47 static BOOL
build_buffer_descriptor_list(struct HDAudioChip
*card
, ULONG nr_of_buffers
, ULONG buffer_size
, struct Stream
*stream
);
48 static void free_buffer_descriptor_list(struct HDAudioChip
*card
, ULONG nr_of_buffers
, struct Stream
*stream
);
49 static BOOL
stream_reset(struct Stream
*stream
, struct HDAudioChip
*card
);
50 void set_converter_format(struct HDAudioChip
*card
, UBYTE nid
);
53 static const char *Inputs
[INPUTS
] =
66 static const char *Outputs
[OUTPUTS
] =
73 #define uint32 unsigned int
76 /******************************************************************************
77 ** AHIsub_AllocAudio **********************************************************
78 ******************************************************************************/
80 ULONG
_AHIsub_AllocAudio(struct TagItem
* taglist
,
81 struct AHIAudioCtrlDrv
* AudioCtrl
,
82 struct DriverBase
* AHIsubBase
)
84 struct HDAudioBase
* card_base
= (struct HDAudioBase
*) AHIsubBase
;
90 card_num
= (GetTagData(AHIDB_AudioID
, 0, taglist
) & 0x0000f000) >> 12;
92 if (card_num
>= card_base
->cards_found
||
93 card_base
->driverdatas
[card_num
] == NULL
)
95 D(bug("[HDAudio] no data for card = %ld\n", card_num
));
96 Req("No HDAudioChip for card %ld.", card_num
);
102 struct HDAudioChip
*card
;
104 card
= card_base
->driverdatas
[card_num
];
105 AudioCtrl
->ahiac_DriverData
= card
;
107 ObtainSemaphore(&card_base
->semaphore
);
108 in_use
= (card
->audioctrl
!= NULL
);
111 card
->audioctrl
= AudioCtrl
;
113 ReleaseSemaphore(&card_base
->semaphore
);
120 //bug("AudioCtrl->ahiac_MixFreq = %lu\n", AudioCtrl->ahiac_MixFreq);
121 if (AudioCtrl
->ahiac_MixFreq
< card
->frequencies
[0].frequency
)
122 AudioCtrl
->ahiac_MixFreq
= card
->frequencies
[0].frequency
;
124 card
->selected_freq_index
= 0;
125 for (i
= 1; i
< card
->nr_of_frequencies
; i
++)
127 if ((ULONG
) card
->frequencies
[i
].frequency
>= AudioCtrl
->ahiac_MixFreq
)
129 if ((AudioCtrl
->ahiac_MixFreq
- (LONG
) card
->frequencies
[i
- 1].frequency
)
130 < ((LONG
) card
->frequencies
[i
].frequency
- AudioCtrl
->ahiac_MixFreq
))
132 card
->selected_freq_index
= i
- 1;
137 card
->selected_freq_index
= i
;
143 //bug("card->selected_freq_index = %lu\n", card->selected_freq_index);
145 ret
= AHISF_KNOWHIFI
| AHISF_KNOWSTEREO
| AHISF_MIXING
| AHISF_TIMING
;
147 for (i
= 0; i
< card
->nr_of_frequencies
; i
++)
149 if (AudioCtrl
->ahiac_MixFreq
== card
->frequencies
[i
].frequency
)
151 ret
|= AHISF_CANRECORD
;
162 /******************************************************************************
163 ** AHIsub_FreeAudio ***********************************************************
164 ******************************************************************************/
166 void _AHIsub_FreeAudio(struct AHIAudioCtrlDrv
* AudioCtrl
,
167 struct DriverBase
* AHIsubBase
)
169 struct HDAudioBase
* card_base
= (struct HDAudioBase
*) AHIsubBase
;
170 struct HDAudioChip
* card
= (struct HDAudioChip
*) AudioCtrl
->ahiac_DriverData
;
174 ObtainSemaphore(&card_base
->semaphore
);
175 if (card
->audioctrl
== AudioCtrl
)
177 // Release it if we own it.
178 card
->audioctrl
= NULL
;
181 ReleaseSemaphore(&card_base
->semaphore
);
183 AudioCtrl
->ahiac_DriverData
= NULL
;
188 /******************************************************************************
189 ** AHIsub_Disable *************************************************************
190 ******************************************************************************/
192 void _AHIsub_Disable(struct AHIAudioCtrlDrv
* AudioCtrl
,
193 struct DriverBase
* AHIsubBase
)
195 // V6 drivers do not have to preserve all registers
201 /******************************************************************************
202 ** AHIsub_Enable **************************************************************
203 ******************************************************************************/
205 void _AHIsub_Enable(struct AHIAudioCtrlDrv
* AudioCtrl
,
206 struct DriverBase
* AHIsubBase
)
208 // V6 drivers do not have to preserve all registers
214 /******************************************************************************
215 ** AHIsub_Start ***************************************************************
216 ******************************************************************************/
218 ULONG
_AHIsub_Start(ULONG flags
,
219 struct AHIAudioCtrlDrv
* AudioCtrl
,
220 struct DriverBase
* AHIsubBase
)
222 struct HDAudioChip
* card
= (struct HDAudioChip
*) AudioCtrl
->ahiac_DriverData
;
223 ULONG dma_buffer_size
= 0;
224 struct Stream
*input_stream
= &(card
->streams
[0]);
225 struct Stream
*output_stream
= &(card
->streams
[card
->nr_of_input_streams
]);
227 if (flags
& AHISF_PLAY
)
229 ULONG dma_sample_frame_size
;
231 detect_headphone_change(card
);
233 card
->mix_buffer
= (APTR
) AllocVec(AudioCtrl
->ahiac_BuffSize
, MEMF_PUBLIC
| MEMF_CLEAR
);
235 if (card
->mix_buffer
== NULL
)
237 D(bug("[HDAudio] Unable to allocate %ld bytes for mixing buffer.", AudioCtrl
->ahiac_BuffSize
));
241 /* Allocate a buffer large enough for 32-bit double-buffered playback (mono or stereo) */
242 if (AudioCtrl
->ahiac_Flags
& AHIACF_STEREO
)
244 dma_sample_frame_size
= 4 * 2;
245 dma_buffer_size
= AudioCtrl
->ahiac_MaxBuffSamples
* dma_sample_frame_size
;
249 dma_sample_frame_size
= 4;
250 dma_buffer_size
= AudioCtrl
->ahiac_MaxBuffSamples
* dma_sample_frame_size
;
253 //bug("dma_buffer_size = %ld, %lx, freq = %d\n", dma_buffer_size, dma_buffer_size, AudioCtrl->ahiac_MixFreq);
254 build_buffer_descriptor_list(card
, 2, dma_buffer_size
, output_stream
);
256 card
->playback_buffer1
= (APTR
) output_stream
->bdl
[0].lower_address
;
257 card
->playback_buffer2
= (APTR
) output_stream
->bdl
[1].lower_address
;
259 //bug("BDLE[0] = %lx, BDLE[1] = %lx\n", output_stream->bdl[0].lower_address, output_stream->bdl[1].lower_address);
260 if (stream_reset(output_stream
, card
) == FALSE
)
265 // 4.5.3 Starting Streams
266 outb_setbits((output_stream
->tag
<< 4), output_stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
+ 2, card
); // set stream number
267 pci_outl(dma_buffer_size
* 2, output_stream
->sd_reg_offset
+ HD_SD_OFFSET_CYCLIC_BUFFER_LEN
, card
);
268 pci_outw(1, output_stream
->sd_reg_offset
+ HD_SD_OFFSET_LAST_VALID_INDEX
, card
); // 2 buffers, last valid index = 1
270 // set sample rate and format
271 pci_outw(((card
->frequencies
[card
->selected_freq_index
].base44100
> 0) ? BASE44
: 0) | // base freq: 48 or 44.1 kHz
272 (card
->frequencies
[card
->selected_freq_index
].mult
<< 11) | // multiplier
273 (card
->frequencies
[card
->selected_freq_index
].div
<< 8) | // divisor
274 FORMAT_24BITS
| // set to 24-bit for now
276 output_stream
->sd_reg_offset
+ HD_SD_OFFSET_FORMAT
, card
);
278 send_command_4(card
->codecnr
, card
->dac_nid
, VERB_SET_CONVERTER_FORMAT
,
279 ((card
->frequencies
[card
->selected_freq_index
].base44100
> 0) ? BASE44
: 0) | // base freq: 48 or 44.1 kHz
280 (card
->frequencies
[card
->selected_freq_index
].mult
<< 11) | // multiplier
281 (card
->frequencies
[card
->selected_freq_index
].div
<< 8) | // divisor
282 FORMAT_24BITS
| // set to 24-bit for now
283 FORMAT_STEREO
, card
); // stereo
285 send_command_4(card
->codecnr
, card
->dac_nid
, 0xA, 0, card
);
288 // set BDL for scatter/gather
289 pci_outl((ULONG
) output_stream
->bdl
, output_stream
->sd_reg_offset
+ HD_SD_OFFSET_BDL_ADDR_LOW
, card
);
290 pci_outl(0, output_stream
->sd_reg_offset
+ HD_SD_OFFSET_BDL_ADDR_HIGH
, card
);
292 // set stream ID and channel for DAC
293 send_command_12(card
->codecnr
, card
->dac_nid
, VERB_SET_CONVERTER_STREAM_CHANNEL
, (output_stream
->tag
<< 4), card
); // stream 1, channel 0
295 card
->current_bytesize
= dma_buffer_size
;
296 card
->current_frames
= AudioCtrl
->ahiac_MaxBuffSamples
;
297 card
->current_buffer
= card
->playback_buffer1
;
299 card
->is_playing
= TRUE
;
302 if (flags
& AHISF_RECORD
)
304 dma_buffer_size
= RECORD_BUFFER_SAMPLES
* 4;
306 build_buffer_descriptor_list(card
, 2, dma_buffer_size
, input_stream
);
308 card
->record_buffer1
= (APTR
) input_stream
->bdl
[0].lower_address
;
309 card
->record_buffer2
= (APTR
) input_stream
->bdl
[1].lower_address
;
311 if (stream_reset(input_stream
, card
) == FALSE
)
316 // 4.5.3 Starting Streams
317 outb_setbits((input_stream
->tag
<< 4), input_stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
+ 2, card
); // set stream number
318 pci_outl(dma_buffer_size
* 2, input_stream
->sd_reg_offset
+ HD_SD_OFFSET_CYCLIC_BUFFER_LEN
, card
);
319 pci_outw(1, input_stream
->sd_reg_offset
+ HD_SD_OFFSET_LAST_VALID_INDEX
, card
); // 2 buffers, last valid index = 1
321 // set sample rate and format
322 pci_outw(((card
->frequencies
[card
->selected_freq_index
].base44100
> 0) ? BASE44
: 0) | // base freq: 48 or 44.1 kHz
323 (card
->frequencies
[card
->selected_freq_index
].mult
<< 11) | // multiplier
324 (card
->frequencies
[card
->selected_freq_index
].div
<< 8) | // divisor
325 FORMAT_16BITS
| // set to 16-bit for now
327 input_stream
->sd_reg_offset
+ HD_SD_OFFSET_FORMAT
, card
);
329 send_command_4(card
->codecnr
, card
->adc_nid
, VERB_SET_CONVERTER_FORMAT
,
330 ((card
->frequencies
[card
->selected_freq_index
].base44100
> 0) ? BASE44
: 0) | // base freq: 48 or 44.1 kHz
331 (card
->frequencies
[card
->selected_freq_index
].mult
<< 11) | // multiplier
332 (card
->frequencies
[card
->selected_freq_index
].div
<< 8) | // divisor
333 FORMAT_16BITS
| // set to 16-bit for now
334 FORMAT_STEREO
, card
); // stereo
336 // set BDL for scatter/gather
337 pci_outl((ULONG
) input_stream
->bdl
, input_stream
->sd_reg_offset
+ HD_SD_OFFSET_BDL_ADDR_LOW
, card
);
338 pci_outl(0, input_stream
->sd_reg_offset
+ HD_SD_OFFSET_BDL_ADDR_HIGH
, card
);
340 // set stream ID and channel for ADC
341 send_command_12(card
->codecnr
, card
->adc_nid
, VERB_SET_CONVERTER_STREAM_CHANNEL
, (input_stream
->tag
<< 4), card
);
343 D(bug("[HDAudio] RECORD\n"));
344 codec_discovery(card
); // tbd < --------------------
346 card
->current_record_bytesize
= dma_buffer_size
;
347 card
->current_record_buffer
= card
->record_buffer1
;
349 card
->is_recording
= TRUE
;
352 if (flags
& AHISF_PLAY
)
356 timer
= 0; // for demo/test
358 //bug("GOING TO PLAY\n");
359 outl_setbits((1 << output_stream
->index
), HD_INTCTL
, card
);
360 outl_setbits(HD_SD_CONTROL_STREAM_RUN
| HD_SD_STATUS_MASK
, output_stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
); // Stream Run
364 if (flags
& AHISF_RECORD
)
367 outl_setbits((1 << input_stream
->index
), HD_INTCTL
, card
);
368 outl_setbits(HD_SD_CONTROL_STREAM_RUN
| HD_SD_STATUS_MASK
, input_stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
); // Stream Run
376 /******************************************************************************
377 ** AHIsub_Update **************************************************************
378 ******************************************************************************/
380 void _AHIsub_Update(ULONG flags
,
381 struct AHIAudioCtrlDrv
* AudioCtrl
,
382 struct DriverBase
* AHIsubBase
)
384 struct HDAudioChip
* card
= (struct HDAudioChip
*) AudioCtrl
->ahiac_DriverData
;
386 card
->current_frames
= AudioCtrl
->ahiac_BuffSamples
;
388 if (AudioCtrl
->ahiac_Flags
& AHIACF_STEREO
)
390 card
->current_bytesize
= card
->current_frames
* 4;
394 card
->current_bytesize
= card
->current_frames
* 2;
399 /******************************************************************************
400 ** AHIsub_Stop ****************************************************************
401 ******************************************************************************/
403 void _AHIsub_Stop(ULONG flags
,
404 struct AHIAudioCtrlDrv
* AudioCtrl
,
405 struct DriverBase
* AHIsubBase
)
407 struct HDAudioChip
* card
= (struct HDAudioChip
*) AudioCtrl
->ahiac_DriverData
;
411 if ((flags
& AHISF_PLAY
) && card
->is_playing
)
413 struct Stream
*output_stream
= &(card
->streams
[card
->nr_of_input_streams
]);
414 outl_clearbits(HD_SD_CONTROL_STREAM_RUN
, output_stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
);
415 card
->is_playing
= FALSE
;
417 card
->current_bytesize
= 0;
418 card
->current_frames
= 0;
419 card
->current_buffer
= NULL
;
421 if (card
->mix_buffer
)
423 FreeVec(card
->mix_buffer
);
425 card
->mix_buffer
= NULL
;
427 free_buffer_descriptor_list(card
, 2, output_stream
);
429 D(bug("[HDAudio] IRQ's received was %d\n", z
));
432 if ((flags
& AHISF_RECORD
) && card
->is_recording
)
434 struct Stream
*input_stream
= &(card
->streams
[0]);
435 outl_clearbits(HD_SD_CONTROL_STREAM_RUN
, input_stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
);
437 card
->record_buffer1
= NULL
;
438 card
->record_buffer2
= NULL
;
439 card
->current_record_bytesize
= 0;
441 card
->is_recording
= FALSE
;
443 free_buffer_descriptor_list(card
, 2, input_stream
);
446 card
->current_bytesize
= 0;
450 /******************************************************************************
451 ** AHIsub_GetAttr *************************************************************
452 ******************************************************************************/
454 LONG
_AHIsub_GetAttr(ULONG attribute
,
457 struct TagItem
* taglist
,
458 struct AHIAudioCtrlDrv
* AudioCtrl
,
459 struct DriverBase
* AHIsubBase
)
461 struct HDAudioBase
* card_base
= (struct HDAudioBase
*) AHIsubBase
;
462 struct HDAudioChip
* card
= card_base
->driverdatas
[0];
470 case AHIDB_Frequencies
:
472 return card
->nr_of_frequencies
;
475 case AHIDB_Frequency
: // Index->Frequency
476 return (LONG
) card
->frequencies
[argument
].frequency
;
478 case AHIDB_Index
: // Frequency->Index
480 if (argument
<= (LONG
) card
->frequencies
[0].frequency
)
485 if (argument
>= (LONG
) card
->frequencies
[card
->nr_of_frequencies
- 1].frequency
)
487 return card
->nr_of_frequencies
- 1;
490 for (i
= 1; i
< card
->nr_of_frequencies
; i
++)
492 if ((LONG
) card
->frequencies
[i
].frequency
> argument
)
494 if ((argument
- (LONG
) card
->frequencies
[i
- 1].frequency
) < ((LONG
) card
->frequencies
[i
].frequency
- argument
))
505 return 0; // Will not happen
509 return (LONG
) "Davy Wentzler";
511 case AHIDB_Copyright
:
512 return (LONG
) "(C) 2010 Stephen Jones, (C) 2010-2016 The AROS Dev Team";
515 return (LONG
) LibIDString
;
517 case AHIDB_Annotation
:
518 return (LONG
) "HD Audio driver";
523 case AHIDB_FullDuplex
:
529 case AHIDB_MaxRecordSamples
:
530 return RECORD_BUFFER_SAMPLES
;
535 unsigned long res = (unsigned long) (0x10000 * pow (10.0, dB / 20.0));
536 double dB = 20.0 * log10(0xVALUE / 65536.0);
538 printf("dB = %f, res = %lx\n", dB, res);*/
540 case AHIDB_MinMonitorVolume
:
541 return (unsigned long) (0x10000 * pow (10.0, -34.5 / 20.0)); // -34.5 dB
543 case AHIDB_MaxMonitorVolume
:
544 return (unsigned long) (0x10000 * pow (10.0, 12.0 / 20.0)); // 12 dB
546 case AHIDB_MinInputGain
:
547 return (unsigned long) (0x10000 * pow (10.0, card
->adc_min_gain
/ 20.0));
549 case AHIDB_MaxInputGain
:
550 return (unsigned long) (0x10000 * pow (10.0, card
->adc_max_gain
/ 20.0));
552 case AHIDB_MinOutputVolume
:
553 return (unsigned long) (0x10000 * pow (10.0, card
->dac_min_gain
/ 20.0));
555 case AHIDB_MaxOutputVolume
:
556 return (unsigned long) (0x10000 * pow (10.0, card
->dac_max_gain
/ 20.0));
562 return (LONG
) Inputs
[argument
];
568 return (LONG
) Outputs
[argument
];
576 /******************************************************************************
577 ** AHIsub_HardwareControl *****************************************************
578 ******************************************************************************/
580 ULONG
_AHIsub_HardwareControl(ULONG attribute
,
582 struct AHIAudioCtrlDrv
* AudioCtrl
,
583 struct DriverBase
* AHIsubBase
)
585 struct HDAudioBase
* card_base
= (struct HDAudioBase
*) AHIsubBase
;
586 struct HDAudioChip
* card
= card_base
->driverdatas
[0];
590 case AHIC_MonitorVolume
:
592 double dB
= 20.0 * log10(argument
/ 65536.0);
594 card
->monitor_volume
= argument
;
595 set_monitor_volumes(card
, dB
);
600 case AHIC_MonitorVolume_Query
:
602 return card
->monitor_volume
;
607 double dB
= 20.0 * log10(argument
/ 65536.0);
608 card
->input_gain
= argument
;
610 set_adc_gain(card
, dB
);
614 case AHIC_InputGain_Query
:
615 return card
->input_gain
;
617 case AHIC_OutputVolume
:
619 double dB
= 20.0 * log10(argument
/ 65536.0);
620 card
->output_volume
= argument
;
622 set_dac_gain(card
, dB
);
627 case AHIC_OutputVolume_Query
:
628 return card
->output_volume
;
631 card
->input
= argument
;
636 case AHIC_Input_Query
:
640 card
->output
= argument
;
644 case AHIC_Output_Query
:
653 static BOOL
build_buffer_descriptor_list(struct HDAudioChip
*card
, ULONG nr_of_buffers
, ULONG buffer_size
, struct Stream
*stream
)
657 stream
->bdl
= pci_alloc_consistent(nr_of_buffers
* sizeof(struct BDLE
), &(stream
->bdl_nonaligned
), 128);
658 stream
->bdl_nonaligned_addresses
= (APTR
) AllocVec(nr_of_buffers
* 8, MEMF_PUBLIC
| MEMF_CLEAR
);
660 for (entry
= 0; entry
< nr_of_buffers
; entry
++)
662 APTR non_aligned_address
= 0;
664 stream
->bdl
[entry
].lower_address
= (ULONG
) pci_alloc_consistent(buffer_size
, &non_aligned_address
, 128);
665 stream
->bdl
[entry
].upper_address
= 0;
666 stream
->bdl
[entry
].length
= buffer_size
;
667 stream
->bdl
[entry
].reserved_ioc
= 1;
669 stream
->bdl_nonaligned_addresses
[entry
] = non_aligned_address
;
671 //bug("BDL %d = %lx\n", entry, stream->bdl[entry].lower_address);
678 static void free_buffer_descriptor_list(struct HDAudioChip
*card
, ULONG nr_of_buffers
, struct Stream
*stream
)
682 stream
->bdl
= pci_alloc_consistent(nr_of_buffers
* sizeof(struct BDLE
), &(stream
->bdl_nonaligned
), 128);
683 stream
->bdl_nonaligned_addresses
= (APTR
) AllocVec(nr_of_buffers
* 8, MEMF_PUBLIC
| MEMF_CLEAR
);
685 for (entry
= 0; entry
< nr_of_buffers
; entry
++)
687 pci_free_consistent(stream
->bdl_nonaligned_addresses
[entry
]);
688 stream
->bdl
[entry
].lower_address
= 0;
689 stream
->bdl_nonaligned_addresses
[entry
] = NULL
;
692 pci_free_consistent(stream
->bdl_nonaligned
);
693 stream
->bdl_nonaligned
= NULL
;
695 FreeVec(stream
->bdl_nonaligned_addresses
);
696 stream
->bdl_nonaligned_addresses
= NULL
;
700 static BOOL
stream_reset(struct Stream
*stream
, struct HDAudioChip
*card
)
705 outb_clearbits(HD_SD_CONTROL_STREAM_RUN
, stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
); // stop stream run
707 outb_setbits(0x1C, stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
);
708 outb_setbits(0x1C, stream
->sd_reg_offset
+ HD_SD_OFFSET_STATUS
, card
);
709 outb_setbits(0x1, stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
); // stream reset
711 for (i
= 0; i
< 1000; i
++)
713 if ((pci_inb(stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
) & 0x1) == 0x1)
723 D(bug("[HDAudio] Stream reset not ok\n"));
727 outb_clearbits(0x1, stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
); // stream reset
729 for (i
= 0; i
< 1000; i
++)
731 if ((pci_inb(stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
) & 0x1) == 0x0)
741 D(bug("[HDAudio] Stream reset 2 not ok\n"));
745 outb_clearbits(HD_SD_CONTROL_STREAM_RUN
, stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
); // stop stream run
747 control
= pci_inb(stream
->sd_reg_offset
+ HD_SD_OFFSET_CONTROL
, card
);
748 if ((control
& 0x1) == 1)
757 void set_converter_format(struct HDAudioChip
*card
, UBYTE nid
)
759 send_command_4(card
->codecnr
, nid
, VERB_SET_CONVERTER_FORMAT
, (1 << 14) | (0x3 << 4) | 1, card
); // 44.1kHz 24-bits stereo