3 #include <exec/memory.h>
4 #include <proto/expansion.h>
8 #include <aros/debug.h>
14 #include "interrupt.h"
16 #include "pci_wrapper.h"
21 /* Public functions in main.c */
22 int card_init(struct HDAudioChip
*card
);
23 void card_cleanup(struct HDAudioChip
*card
);
24 static BOOL
allocate_corb(struct HDAudioChip
*card
);
25 static BOOL
allocate_rirb(struct HDAudioChip
*card
);
26 static BOOL
allocate_pos_buffer(struct HDAudioChip
*card
);
27 static BOOL
alloc_streams(struct HDAudioChip
*card
);
28 static BOOL
perform_codec_specific_settings(struct HDAudioChip
*card
);
29 static void determine_frequencies(struct HDAudioChip
*card
);
30 static void set_frequency_info(struct Freq
*freq
, UWORD bitnr
);
31 static BOOL
reset_chip(struct HDAudioChip
*card
);
32 static ULONG
get_response(struct HDAudioChip
*card
);
33 static void perform_realtek_specific_settings(struct HDAudioChip
*card
, UWORD device
);
34 static void perform_via_specific_settings(struct HDAudioChip
*card
, UWORD device
);
35 static int find_pin_widget_with_encoding(struct HDAudioChip
*card
, UBYTE encoding
);
36 static BOOL
interrogate_unknown_chip(struct HDAudioChip
*card
);
37 static int find_audio_output(struct HDAudioChip
*card
, UBYTE digital
);
38 static int find_speaker_nid(struct HDAudioChip
*card
);
39 static int find_headphone_nid(struct HDAudioChip
*card
);
40 static void power_up_all_nodes(struct HDAudioChip
*card
);
42 struct Device
*TimerBase
= NULL
;
43 struct timerequest
*TimerIO
= NULL
;
44 struct MsgPort
*replymp
= NULL
;
45 static BOOL forceQuery
= FALSE
;
46 static BOOL dumpAll
= FALSE
;
47 static int force_speaker_nid
= -1;
48 //void AddResetHandler(struct HDAudioChip *card);
52 #define DebugPrintF bug
53 INTGW(static, void, playbackinterrupt
, PlaybackInterrupt
);
54 INTGW(static, void, recordinterrupt
, RecordInterrupt
);
55 INTGW(static, ULONG
, cardinterrupt
, CardInterrupt
);
58 void micro_delay(unsigned int val
)
60 replymp
= (struct MsgPort
*) CreateMsgPort();
63 bug("Could not create the reply port!\n");
67 TimerIO
= (struct timerequest
*) CreateIORequest(replymp
, sizeof(struct timerequest
));
71 DebugPrintF("Out of memory.\n");
75 if (OpenDevice((CONST_STRPTR
) "timer.device", UNIT_MICROHZ
, (struct IORequest
*) TimerIO
, 0) != 0)
77 DebugPrintF("Unable to open 'timer.device'.\n");
82 TimerBase
= (struct Device
*) TimerIO
->tr_node
.io_Device
;
87 TimerIO
->tr_node
.io_Command
= TR_ADDREQUEST
; /* Add a request. */
88 TimerIO
->tr_time
.tv_secs
= 0; /* 0 seconds. */
89 TimerIO
->tr_time
.tv_micro
= val
; /* 'val' micro seconds. */
90 DoIO((struct IORequest
*) TimerIO
);
91 DeleteIORequest((struct IORequest
*) TimerIO
);
93 CloseDevice((struct IORequest
*) TimerIO
);
98 DeleteMsgPort(replymp
);
103 /******************************************************************************
104 ** DriverData allocation ******************************************************
105 ******************************************************************************/
107 struct HDAudioChip
* AllocDriverData(APTR dev
, struct DriverBase
* AHIsubBase
)
109 struct HDAudioBase
* card_base
= (struct HDAudioBase
*) AHIsubBase
;
110 struct HDAudioChip
* card
;
115 card
= (struct HDAudioChip
*) AllocVec(sizeof(struct HDAudioChip
), MEMF_PUBLIC
| MEMF_CLEAR
);
119 Req("Unable to allocate driver structure.");
123 card
->ahisubbase
= AHIsubBase
;
125 card
->interrupt
.is_Node
.ln_Type
= IRQTYPE
;
126 card
->interrupt
.is_Node
.ln_Pri
= 0;
127 card
->interrupt
.is_Node
.ln_Name
= (char *) LibName
;
129 card
->interrupt
.is_Code
= (void(*)(void)) &cardinterrupt
;
131 card
->interrupt
.is_Code
= (void(*)(void)) CardInterrupt
;
133 card
->interrupt
.is_Data
= (APTR
) card
;
135 card
->playback_interrupt
.is_Node
.ln_Type
= IRQTYPE
;
136 card
->playback_interrupt
.is_Node
.ln_Pri
= 0;
137 card
->playback_interrupt
.is_Node
.ln_Name
= (char *) LibName
;
139 card
->playback_interrupt
.is_Code
= &playbackinterrupt
;
141 card
->interrupt
.is_Code
= PlaybackInterrupt
;
143 card
->playback_interrupt
.is_Data
= (APTR
) card
;
145 card
->record_interrupt
.is_Node
.ln_Type
= IRQTYPE
;
146 card
->record_interrupt
.is_Node
.ln_Pri
= 0;
147 card
->record_interrupt
.is_Node
.ln_Name
= (char *) LibName
;
149 card
->record_interrupt
.is_Code
= &recordinterrupt
;
151 card
->interrupt
.is_Code
= RecordInterrupt
;
153 card
->record_interrupt
.is_Data
= (APTR
) card
;
155 command_word
= inw_config(PCI_COMMAND
, dev
);
156 command_word
|= PCI_COMMAND_IO
| PCI_COMMAND_MEMORY
| PCI_COMMAND_MASTER
;
157 outw_config(PCI_COMMAND
, command_word
, dev
);
160 card
->pci_master_enabled
= TRUE
;
162 card
->iobase
= ahi_pci_get_base_address(0, dev
);
163 card
->length
= ahi_pci_get_base_size(0, dev
);
164 card
->irq
= ahi_pci_get_irq(dev
);
165 card
->chiprev
= inb_config(PCI_REVISION_ID
, dev
);
166 card
->model
= inb_config(PCI_SUBSYSTEM_ID
, dev
);
168 ahi_pci_add_intserver(&card
->interrupt
, dev
);
170 /* Initialize chip */
171 if (card_init(card
) < 0)
173 DebugPrintF("Unable to initialize Card subsystem.\n");
179 card
->interrupt_added
= TRUE
;
181 card
->card_initialized
= TRUE
;
184 card
->monitor_volume
= (unsigned long) (0x10000 * pow (10.0, -6.0 / 20.0)); // -6 dB
185 card
->input_gain
= 0x10000; // 0dB
186 card
->output_volume
= 0x10000; // 0dB
188 set_monitor_volumes(card
, -6.0); // -6dB monitor volume
190 //AddResetHandler(card);
196 /******************************************************************************
197 ** DriverData deallocation ****************************************************
198 ******************************************************************************/
200 void FreeDriverData(struct HDAudioChip
* card
, struct DriverBase
* AHIsubBase
)
204 if (card
->pci_dev
!= NULL
)
206 if (card
->card_initialized
)
211 if (card
->pci_master_enabled
)
215 cmd
= inw_config(PCI_COMMAND
, card
->pci_dev
);
216 cmd
&= ~(PCI_COMMAND_IO
| PCI_COMMAND_MEMORY
| PCI_COMMAND_MASTER
);
217 outw_config(PCI_COMMAND
, cmd
, card
->pci_dev
);
221 if (card
->interrupt_added
)
223 ahi_pci_rem_intserver(&card
->interrupt
, card
->pci_dev
);
232 int card_init(struct HDAudioChip
*card
)
234 struct PCIDevice
*dev
= (struct PCIDevice
*) card
->pci_dev
;
236 unsigned char pval
, byt
;
240 if (reset_chip(card
) == FALSE
)
242 bug("Reset chip failed\n");
246 // 4.3 Codec discovery: 15 codecs can be connected, bits that are on indicate a codec
247 card
->codecbits
= pci_inw(HD_STATESTS
, card
);
249 if (card
->codecbits
== 0)
251 bug("No codecs found!\n");
255 for (i
= 0; i
< 16; i
++)
257 if (card
->codecbits
& (1 << i
))
264 if (alloc_streams(card
) == FALSE
)
266 bug("Allocating streams failed!\n");
270 if (allocate_corb(card
) == FALSE
)
272 bug("Allocating CORB failed!\n");
276 if (allocate_rirb(card
) == FALSE
)
278 bug("Allocating RIRB failed!\n");
282 if (allocate_pos_buffer(card
) == FALSE
)
284 bug("Allocating position buffer failed!\n");
289 pci_outl(HD_INTCTL_CIE
| HD_INTCTL_GLOBAL
, HD_INTCTL
, card
);
292 power_up_all_nodes(card
);
294 if (perform_codec_specific_settings(card
) == FALSE
)
301 codec_discovery(card
);
304 bug("card_init() was a success!\n");
310 void card_cleanup(struct HDAudioChip
*card
)
315 static BOOL
reset_chip(struct HDAudioChip
*card
)
324 Intel® HIgh Definition Audio Traffic Class Assignment (TCSEL), bits 0:2 -> 000 = TC0
325 This register assigned the value to be placed in the TC field. CORB and RIRB data will always be
328 #define TCSEL_PCIREG 0x44
329 tcsel
= inb_config(TCSEL_PCIREG
, card
->pci_dev
);
331 outb_config(TCSEL_PCIREG
, tcsel
, card
->pci_dev
);
333 pci_outb(0, HD_CORBCTL
, card
);
334 pci_outb(0, HD_RIRBCTL
, card
);
336 // Clear STATESTS just to be sure. After reset, this register holds the ID's of the connected codecs
337 pci_outb(0xFF, HD_STATESTS
, card
);
339 // Transition to reset state
340 outl_clearbits(1, HD_GCTL
, card
);
342 // Wait for bit 0 to read 0
343 for (counter
= 0; counter
< 1000; counter
++)
345 ubval
= pci_inb(HD_GCTL
, card
);
347 if ((ubval
& 0x1) == 0)
357 bug("Couldn't reset chip!\n");
362 // 4.2.2. Take controller out of reset
363 outl_setbits(1, HD_GCTL
, card
);
366 // Wait for bit 0 to read 1
367 for (counter
= 0; counter
< 1000; counter
++)
369 ubval
= pci_inb(HD_GCTL
, card
);
371 if ((ubval
& 0x1) == 1)
373 bug("Codec came out of reset!\n");
382 bug("Couldn't reset chip!\n");
386 // The software must wait 250 microseconds after reading CRST as 1, but it's suggested to wait longer
389 // do not accept unsolicited events for now (jack sense etc.)
390 //outl_setbits((1 << 8), HD_GCTL, card); // accept unsolicited events
396 void codec_discovery(struct HDAudioChip
*card
)
399 ULONG node_count_response
= get_parameter(0, VERB_GET_PARMS_NODE_COUNT
, card
);
400 UBYTE node_count
= node_count_response
& 0xFF;
401 UBYTE starting_node
= (node_count_response
>> 16) & 0xFF;
402 bug("Node count = %x, starting_node = %x\n", node_count
, starting_node
);
404 for (i
= 0; i
< node_count
; i
++)
406 ULONG function_group_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_FUNCTION_GROUP_TYPE
, card
);
407 UBYTE function_group
= function_group_response
& 0xFF;
408 //bug("Function group = %x, UnSol cap = %x\n", function_group, (function_group_response >> 8) & 0x1);
410 if (function_group
== AUDIO_FUNCTION
)
414 ULONG subnode_count_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_NODE_COUNT
, card
);
415 UBYTE subnode_count
= subnode_count_response
& 0xFF;
416 UBYTE sub_starting_node
= (subnode_count_response
>> 16) & 0xFF;
417 ULONG connections
= 0;
418 bug("Subnode count = %d, sub_starting_node = %x\n", subnode_count
, sub_starting_node
);
420 //bug("Audio supported = %lx\n", get_parameter(starting_node + i, 0xA, card));
421 //bug("Sup streams = %lx\n", get_parameter(starting_node + i, 0xB, card));
423 for (j
= 0; j
< subnode_count
; j
++) // widgets
425 const ULONG NID
= j
+ sub_starting_node
;
428 widget_caps
= get_parameter(NID
, VERB_GET_PARMS_AUDIO_WIDGET_CAPS
, card
);
430 //if ((NID == 0x18) || (NID == 0xB))
432 bug("Subnode %x has caps %lx\n", NID
, widget_caps
);
433 bug("%xh: Supported PCM size/rate = %lx\n", NID
, get_parameter(NID
, VERB_GET_PARMS_SUPPORTED_PCM_SIZE_RATE
, card
));
435 if (AUDIO_WIDGET_CAPS(widget_caps
) == 0x4) // pin complex
437 ULONG config_default
= 0;
439 bug("PIN: caps = %lx\n", get_parameter(NID
, VERB_GET_PARMS_PIN_CAPS
, card
));
440 config_default
= send_command_12(card
->codecnr
, NID
, VERB_GET_CONFIG_DEFAULT
, 0, card
);
442 bug("PIN: Config default = %lx\n", config_default
);
444 bug("PIN: Connected = %s\n", is_jack_connected(card
, NID
) ? "TRUE" : "FALSE");
447 bug("%xh: Input Amp caps = %lx\n", NID
, get_parameter(NID
, 0xD, card
));
448 bug("%xh: Output Amp caps = %lx\n", NID
, get_parameter(NID
, 0x12, card
));
450 connections
= get_parameter(NID
, 0xE, card
);
451 bug("%xh: Conn list len = %lx\n", NID
, connections
);
452 if (connections
> 0) // print connections
456 for (entry
= 0; entry
< connections
; entry
+=4)
458 ULONG connectedTo
= send_command_12(card
->codecnr
, NID
, VERB_GET_CONNECTION_LIST_ENTRY
, entry
, card
);
460 bug("%lx, ", connectedTo
);
465 bug("%xh: Supported power state = %lx\n", NID
, get_parameter(NID
, 0xF, card
));
467 bug("%xh: Connection selection = %lx\n", NID
, send_command_12(card
->codecnr
, NID
, VERB_GET_CONNECTION_SELECT
, 0, card
));
469 bug("%xh: Output Amp gain = %lx\n", NID
, send_command_4(card
->codecnr
, NID
, 0xB, 0x8000, card
));
470 bug("%xh: Input Amp gain = %lx\n", NID
, send_command_4(card
->codecnr
, NID
, 0xB, 0x0000, card
));
471 bug("%xh: Format = %lx\n", NID
, send_command_4(card
->codecnr
, NID
, 0xA, 0, card
));
472 bug("%xh: Power state = %lx\n", NID
, send_command_12(card
->codecnr
, NID
, 0xF05, 0, card
));
473 bug("%xh: Stream = %lx\n", NID
, send_command_12(card
->codecnr
, NID
, 0xF06, 0, card
));
474 bug("%xh: Pin widget control = %lx\n", NID
, send_command_12(card
->codecnr
, NID
, 0xF07, 0, card
));
475 bug("--------------------------------\n\n");
483 static void power_up_all_nodes(struct HDAudioChip
*card
)
486 ULONG node_count_response
= get_parameter(0, VERB_GET_PARMS_NODE_COUNT
, card
);
487 UBYTE node_count
= node_count_response
& 0xFF;
488 UBYTE starting_node
= (node_count_response
>> 16) & 0xFF;
491 send_command_12(card
->codecnr
, 1, VERB_SET_POWER_STATE
, 0, card
); // send function reset to audio node, this should power up all nodes
494 for (i
= 0; i
< node_count
; i
++)
496 ULONG function_group_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_FUNCTION_GROUP_TYPE
, card
);
497 UBYTE function_group
= function_group_response
& 0xFF;
499 if (function_group
== AUDIO_FUNCTION
)
503 ULONG subnode_count_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_NODE_COUNT
, card
);
504 UBYTE subnode_count
= subnode_count_response
& 0xFF;
505 UBYTE sub_starting_node
= (subnode_count_response
>> 16) & 0xFF;
506 ULONG connections
= 0;
508 for (j
= 0; j
< subnode_count
; j
++) // widgets
510 const ULONG NID
= j
+ sub_starting_node
;
513 widget_caps
= get_parameter(NID
, VERB_GET_PARMS_AUDIO_WIDGET_CAPS
, card
);
516 if (AUDIO_WIDGET_POWER_CONTROL(widget_caps
) == 1) // power control
518 ULONG power_state
= 0;
520 power_state
= send_command_12(card
->codecnr
, NID
, VERB_GET_POWER_STATE
, 0, card
);
521 bug("%xh: power state = %xh\n", power_state
);
523 if (power_state
!= 0)
525 bug("Setting power state to 0\n");
526 send_command_12(card
->codecnr
, NID
, VERB_SET_POWER_STATE
, 0, card
);
536 // allocates memory on the given boundary. Returns the aligned memory address and the non-aligned memory address
537 // in NonAlignedAddress, if not NULL.
538 void *pci_alloc_consistent(size_t size
, APTR
*NonAlignedAddress
, unsigned int boundary
)
543 address
= (void *) AllocVec(size
+ boundary
, MEMF_PUBLIC
| MEMF_CLEAR
);
547 a
= (unsigned long) address
;
548 a
= (a
+ boundary
- 1) & ~(boundary
- 1);
549 address
= (void *) a
;
552 if (NonAlignedAddress
)
554 *NonAlignedAddress
= address
;
561 void pci_free_consistent(void* addr
)
567 ULONG
get_parameter(UBYTE node
, UBYTE parameter
, struct HDAudioChip
*card
)
569 return send_command_12(card
->codecnr
, node
, VERB_GET_PARMS
, parameter
, card
);
573 ULONG
send_command_4(UBYTE codec
, UBYTE node
, UBYTE verb
, UWORD payload
, struct HDAudioChip
*card
)
575 UWORD wp
= pci_inw(HD_CORBWP
, card
) & 0xFF;
576 ULONG data
= (codec
<< 28) | (node
<< 20) | (verb
<< 16) | payload
;
578 if (wp
== card
->corb_entries
- 1)
587 //bug("Sending command %lx\n", data);
589 card
->corb
[wp
] = data
;
590 pci_outw(wp
, HD_CORBWP
, card
);
592 return get_response(card
);
596 ULONG
send_command_12(UBYTE codec
, UBYTE node
, UWORD verb
, UBYTE payload
, struct HDAudioChip
*card
)
598 UWORD wp
= pci_inw(HD_CORBWP
, card
) & 0xFF;
599 ULONG data
= (codec
<< 28) | (node
<< 20) | (verb
<< 8) | payload
;
601 if (wp
== card
->corb_entries
- 1)
610 //bug("Sending command %lx\n", data);
612 card
->corb
[wp
] = data
;
613 pci_outw(wp
, HD_CORBWP
, card
);
615 return get_response(card
);
619 ULONG
get_response(struct HDAudioChip
*card
)
627 // wait for interrupt
628 for (i
= 0; i
< timeout
; i
++)
630 if (card
->rirb_irq
> 0)
643 for (i
= 0; i
< timeout
; i
++)
645 rirb_wp
= pci_inb(HD_RIRBWP
, card
);
647 if (rirb_wp
== card
->rirb_rp
) // strange, we expect the wp to have increased
649 bug("WP has not increased! rirb_wp = %u, rirb_rp = %lu\n", rirb_wp
, card
->rirb_rp
);
654 if ( ((rirb_wp
> card
->rirb_rp
) &&
655 ((rirb_wp
- card
->rirb_rp
) >= 2)) ||
657 ((rirb_wp
< card
->rirb_rp
) &&
658 ( ((int) rirb_wp
) + card
->rirb_entries
) - card
->rirb_rp
>= 2))
660 bug("Write pointer is more than 1 step ahead!\n");
664 ULONG response
, response_ex
; // 3.6.5 Response Input Ring Buffer
666 card
->rirb_rp
= rirb_wp
;
667 addr
= card
->rirb_rp
;
668 addr
*= 2; // 64-bit entries
670 response
= card
->rirb
[addr
];
671 response_ex
= card
->rirb
[addr
+ 1];
672 if (response_ex
& 0x10) // unsolicited
674 bug("Unsolicited response! Skipping!\n");
678 //bug("Response is %lx\n", response);
684 bug("ERROR in get_response() card->rirb_rp = %u!rirb_wp = %u\n", card
->rirb_rp
, rirb_wp
);
689 static BOOL
allocate_corb(struct HDAudioChip
*card
)
693 // 4.4.1.3 Initialize the CORB
696 outb_clearbits(HD_CORBRUN
, HD_CORBCTL
, card
);
699 corbsize_reg
= pci_inb(HD_CORBSIZE
, card
);
700 if (corbsize_reg
& (1 << 6))
702 pci_outb(0x2, HD_CORBSIZE
, card
);
703 card
->corb_entries
= 256;
705 else if (corbsize_reg
& (1 << 5))
707 pci_outb(0x1, HD_CORBSIZE
, card
);
708 card
->corb_entries
= 16;
710 else if (corbsize_reg
& (1 << 4))
712 pci_outb(0x0, HD_CORBSIZE
, card
);
713 card
->corb_entries
= 2;
716 // Allocate CORB memory
717 card
->corb
= pci_alloc_consistent(4 * card
->corb_entries
, NULL
, 128); // todo: virtual
720 pci_outl((ULONG
) card
->corb
, HD_CORB_LOW
, card
);
721 pci_outl(0, HD_CORB_HIGH
, card
);
723 //bug("Before reset rp: corbrp = %x\n", pci_inw(0x4A, card));
725 // Reset read pointer: if we set this, the CORB will not work??
726 //outw_setbits(HD_CORBRPRST, HD_CORBRP, card);
728 //bug("After reset rp: corbrp = %x\n", pci_inw(0x4A, card));
730 // Write a 0 to the write pointer to clear
731 pci_outw(0, HD_CORBWP
, card
);
734 outb_setbits(HD_CORBRUN
, HD_CORBCTL
, card
);
747 static BOOL
allocate_rirb(struct HDAudioChip
*card
)
751 // 4.4.2.2 Initialize the RIRB
754 outb_clearbits(HD_RIRBRUN
, HD_RIRBCTL
, card
);
757 rirbsize_reg
= pci_inb(HD_RIRBSIZE
, card
);
758 if (rirbsize_reg
& (1 << 6))
760 pci_outb(0x2, HD_RIRBSIZE
, card
);
761 card
->rirb_entries
= 256;
763 else if (rirbsize_reg
& (1 << 5))
765 pci_outb(0x1, HD_RIRBSIZE
, card
);
766 card
->rirb_entries
= 16;
768 else if (rirbsize_reg
& (1 << 4))
770 pci_outb(0x0, HD_RIRBSIZE
, card
);
771 card
->rirb_entries
= 2;
776 // Allocate rirb memory
777 card
->rirb
= pci_alloc_consistent(4 * 2 * card
->rirb_entries
, NULL
, 128); // todo: virtual
781 pci_outl((ULONG
) card
->rirb
, HD_RIRB_LOW
, card
);
782 pci_outl(0, HD_RIRB_HIGH
, card
);
784 // Reset read pointer: if we set this, it will not come out of reset??
785 //outw_setbits(HD_RIRBWPRST, HD_RIRBWP, card);
787 // Set N=1, which generates an interrupt for every response
788 pci_outw(1, HD_RINTCNT
, card
);
790 pci_outb(0x5, HD_RIRBSTS
, card
);
792 // run it and enable IRQ
793 outb_setbits(HD_RIRBRUN
| HD_RINTCTL
| 0x4, HD_RIRBCTL
, card
);
807 static BOOL
allocate_pos_buffer(struct HDAudioChip
*card
)
809 card
->dma_position_buffer
= pci_alloc_consistent(sizeof(APTR
) * 36, NULL
, 128);
810 //pci_outl((ULONG) card->dma_position_buffer | HD_DPLBASE_ENABLE, HD_DPLBASE, card);
811 pci_outl(0, HD_DPUBASE
, card
);
813 if (card
->dma_position_buffer
)
824 static BOOL
alloc_streams(struct HDAudioChip
*card
)
827 card
->nr_of_input_streams
= (pci_inw(HD_GCAP
, card
) & HD_GCAP_ISS_MASK
) >> 8;
828 card
->nr_of_output_streams
= (pci_inw(HD_GCAP
, card
) & HD_GCAP_OSS_MASK
) >> 12;
829 card
->nr_of_streams
= card
->nr_of_input_streams
+ card
->nr_of_output_streams
;
830 //bug("Streams in = %d, out = %d\n", card->nr_of_input_streams, card->nr_of_output_streams);
832 card
->streams
= (struct Stream
*) AllocVec(sizeof(struct Stream
) * card
->nr_of_streams
, MEMF_PUBLIC
| MEMF_CLEAR
);
834 for (i
= 0; i
< card
->nr_of_streams
; i
++)
836 card
->streams
[i
].bdl
= NULL
;
837 card
->streams
[i
].bdl_nonaligned_addresses
= NULL
;
838 card
->streams
[i
].sd_reg_offset
= HD_SD_BASE_OFFSET
+ HD_SD_DESCRIPTOR_SIZE
* i
;
839 card
->streams
[i
].index
= i
;
840 card
->streams
[i
].tag
= i
+ 1;
841 card
->streams
[i
].fifo_size
= pci_inw(card
->streams
[i
].sd_reg_offset
+ HD_SD_OFFSET_FIFO_SIZE
, card
);
843 // clear the descriptor error, fifo error and buffer completion interrupt status flags
844 pci_outb(HD_SD_STATUS_MASK
, card
->streams
[i
].sd_reg_offset
+ HD_SD_OFFSET_STATUS
, card
);
858 /*static ULONG ResetHandler(struct ExceptionContext *ctx, struct ExecBase *pExecBase, struct HDAudioChip *card)
860 struct PCIDevice *dev = card->pci_dev;
866 void AddResetHandler(struct HDAudioChip *card)
868 static struct Interrupt interrupt;
870 interrupt.is_Code = (void (*)())ResetHandler;
871 interrupt.is_Data = (APTR) card;
872 interrupt.is_Node.ln_Pri = 0;
873 interrupt.is_Node.ln_Type = NT_EXTINTERRUPT;
874 interrupt.is_Node.ln_Name = "reset handler";
876 AddResetCallback(&interrupt);
880 static BOOL
perform_codec_specific_settings(struct HDAudioChip
*card
)
882 ULONG vendor_device_id
= get_parameter(0x0, VERB_GET_PARMS_VENDOR_DEVICE
, card
); // get vendor and device ID from root node
884 UWORD vendor
= (vendor_device_id
>> 16);
885 UWORD device
= (vendor_device_id
& 0xFFFF);
887 card
->frequencies
= NULL
;
888 card
->nr_of_frequencies
= 0;
889 card
->selected_freq_index
= 0;
891 card
->dac_min_gain
= -64.0;
892 card
->dac_max_gain
= 0;
893 card
->dac_step_gain
= 1.0;
894 card
->speaker_nid
= 255; // off
895 card
->headphone_nid
= 255; // off
896 card
->speaker_active
= FALSE
;
897 bug("vendor = %x, device = %x\n", vendor
, device
);
899 if (vendor
== 0x10EC && forceQuery
== FALSE
) // Realtek
901 perform_realtek_specific_settings(card
, device
);
903 else if (vendor
== 0x1106 && forceQuery
== FALSE
) // VIA
905 perform_via_specific_settings(card
, device
);
907 else // default: fall-back
909 if (interrogate_unknown_chip(card
) == FALSE
)
915 determine_frequencies(card
);
920 static void perform_realtek_specific_settings(struct HDAudioChip
*card
, UWORD device
)
922 bug("Found Realtek codec\n");
925 card
->dac_volume_nid
= 0x2;
928 card
->adc_mixer_nid
= 0x23;
929 card
->line_in_nid
= 0x1A;
930 card
->mic1_nid
= 0x18;
931 card
->mic2_nid
= 0x19;
934 card
->adc_mixer_is_mux
= FALSE
;
937 send_command_4(card
->codecnr
, 0x14, VERB_SET_AMP_GAIN
, OUTPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // set amplifier gain: unmute output of FRONT (Port-D)
939 send_command_12(card
->codecnr
, 0x14, VERB_SET_PIN_WIDGET_CONTROL
, 0x40, card
); // output enabled
941 // MIC1 pin (0x18) as input
942 send_command_12(card
->codecnr
, card
->mic1_nid
, VERB_SET_PIN_WIDGET_CONTROL
, 0x20, card
); // input enabled
944 send_command_4(card
->codecnr
, card
->mic1_nid
, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| 0, card
); // set amplifier gain: unmute input and set boost to +10dB
947 // device specific support
948 if (device
== 0x662 || device
== 0x663) // Realtek ALC662/663
950 bug("Adding ALC662/663 specific support\n");
952 card
->adc_mixer_indices
[0] = 2; // line in
953 card
->adc_mixer_indices
[1] = 0; // mic1
954 card
->adc_mixer_indices
[2] = 1; // mic2
955 card
->adc_mixer_indices
[3] = 4; // cd
956 card
->adc_mixer_indices
[4] = 8; // mon mixer
958 card
->adc_min_gain
= -13.5;
959 card
->adc_max_gain
= 33.0;
960 card
->adc_step_gain
= 1.5;
962 // LINE2 pin (0x1B) as second front output (duplicates sound of 0xC (front DAC))
963 send_command_4(card
->codecnr
, 0x1B, VERB_SET_AMP_GAIN
, OUTPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // set amplifier gain: unmute output of LINE2 (Port-E)
965 send_command_12(card
->codecnr
, 0x1B, VERB_SET_PIN_WIDGET_CONTROL
, 0x40, card
); // output enabled
967 // Monitor mixer (0xB): set the first 3 inputs to 0dB and unmute them
968 send_command_4(card
->codecnr
, 0xB, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| 23 | (0 << 8), card
); // set input amplifier gain and unmute (index 0 is MIC1), 23 is 0dB
970 send_command_4(card
->codecnr
, 0xB, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| 23 | (1 << 8), card
); // set input amplifier gain and unmute (index 2 is MIC2), 23 is 0dB
972 send_command_4(card
->codecnr
, 0xB, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| 23 | (2 << 8), card
); // set input amplifier gain and unmute (index 2 is LINE1), 23 is 0dB
975 send_command_4(card
->codecnr
, 0xC, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // unmute PCM at index 0
977 send_command_4(card
->codecnr
, 0xC, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| (1 << 8), card
); // unmute monitor mixer at index 1
979 // LINE1 pin (0x1A) as input
980 send_command_12(card
->codecnr
, card
->line_in_nid
, VERB_SET_PIN_WIDGET_CONTROL
, 0x20, card
); // input enabled
982 // MIC2 pin (0x19) as input
983 send_command_12(card
->codecnr
, card
->mic2_nid
, VERB_SET_PIN_WIDGET_CONTROL
, 0x20, card
); // input enabled
985 send_command_4(card
->codecnr
, card
->adc_mixer_nid
, VERB_SET_AMP_GAIN
, OUTPUT_AMP_GAIN
| AMP_GAIN_LR
| 11, card
); // set amplifier gain: unmute and set to 0dB
987 else if (device
== 0x268)
989 bug("Adding ALC268 specific support\n");
991 card
->adc_mixer_indices
[0] = 2; // line in
992 card
->adc_mixer_indices
[1] = 0; // mic1
993 card
->adc_mixer_indices
[2] = 5; // mic2
994 card
->adc_mixer_indices
[3] = 3; // cd
995 card
->adc_mixer_indices
[4] = 255; // no mon mixer
997 card
->adc_min_gain
= -16.5;
998 card
->adc_max_gain
= 30.0;
999 card
->adc_step_gain
= 1.5;
1001 card
->adc_mixer_is_mux
= TRUE
;
1003 // sum widget before output (0xF)
1004 send_command_4(card
->codecnr
, 0xF, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // unmute
1006 // sum widget before headphone output (0x10)
1007 send_command_4(card
->codecnr
, 0x10, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| (2 << 8), card
); // unmute
1009 // HP-OUT pin (0x15)
1010 //send_command_4(card->codecnr, 0x15, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute output of HP-OUT (Port-A)
1012 //send_command_12(card->codecnr, 0x15, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1014 send_command_12(card
->codecnr
, 0x14, VERB_SET_EAPD
, 0x2, card
); // enable EAPD (external power amp)
1016 //send_command_12(card->codecnr, 0x15, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1018 switch_nid_to_input(card
, 0x15);
1020 else if (device
== 0x269) // Dell mini etc.
1022 bug("Adding ALC269 specific support\n");
1024 card
->adc_mixer_indices
[0] = 2; // line in
1025 card
->adc_mixer_indices
[1] = 0; // mic1
1026 card
->adc_mixer_indices
[2] = 1; // mic2
1027 card
->adc_mixer_indices
[3] = 4; // cd
1028 card
->adc_mixer_indices
[4] = 6; // mon mixer
1030 card
->adc_min_gain
= -17;
1031 card
->adc_max_gain
= 29.0;
1032 card
->adc_step_gain
= 1.0;
1034 card
->adc_mixer_is_mux
= TRUE
;
1037 send_command_4(card
->codecnr
, 0xC, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // unmute PCM at index 0
1039 send_command_4(card
->codecnr
, 0xC, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| (1 << 8), card
); // unmute monitor mixer at index 1
1041 // sum widget before output (0xF)
1042 send_command_4(card
->codecnr
, 0xF, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // unmute
1044 // sum widget before headphone output (0x10)
1045 send_command_4(card
->codecnr
, 0x10, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| (2 << 8), card
); // unmute
1047 // HP-OUT pin (0x15)
1048 send_command_4(card
->codecnr
, 0x15, VERB_SET_AMP_GAIN
, OUTPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // set amplifier gain: unmute output of HP-OUT (Port-A)
1050 send_command_12(card
->codecnr
, 0x15, VERB_SET_PIN_WIDGET_CONTROL
, 0x40, card
); // output enabled
1052 send_command_12(card
->codecnr
, 0x14, VERB_SET_EAPD
, 0x2, card
); // enable EAPD (external power amp)
1054 send_command_12(card
->codecnr
, 0x15, VERB_SET_EAPD
, 0x2, card
); // enable EAPD (external power amp)
1056 else if (device
== 0x888) // ALC888
1058 bug("Adding ALC888 specific support\n");
1060 card
->adc_mixer_indices
[0] = 2; // line in
1061 card
->adc_mixer_indices
[1] = 0; // mic1
1062 card
->adc_mixer_indices
[2] = 1; // mic2
1063 card
->adc_mixer_indices
[3] = 4; // cd
1064 card
->adc_mixer_indices
[4] = 10; // mon mixer
1066 card
->adc_min_gain
= -16.5;
1067 card
->adc_max_gain
= 30.0;
1068 card
->adc_step_gain
= 1.5;
1070 card
->dac_min_gain
= -46.5;
1071 card
->dac_max_gain
= 0;
1072 card
->dac_step_gain
= 1.5;
1074 card
->dac_volume_nid
= 0xC;
1076 send_command_4(card
->codecnr
, 0xC, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // unmute PCM at index 0
1077 send_command_4(card
->codecnr
, 0xC, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| (1 << 8), card
); // unmute monitor mixer at index 1
1081 bug("Unsupported Realtek codec! Playback may work.\n");
1086 static void perform_via_specific_settings(struct HDAudioChip
*card
, UWORD device
)
1088 bug("Found VIA codec\n");
1090 card
->dac_nid
= 0x10;
1091 card
->adc_nid
= 0x13;
1093 card
->adc_mixer_nid
= 0x17;
1094 card
->line_in_nid
= 0x1B;
1095 card
->mic1_nid
= 0x1A;
1096 card
->mic2_nid
= 0x1E;
1097 card
->cd_nid
= 0x1F;
1099 card
->adc_mixer_is_mux
= TRUE
;
1102 send_command_4(card
->codecnr
, 0x1C, VERB_SET_AMP_GAIN
, OUTPUT_AMP_GAIN
| AMP_GAIN_LR
| 0x1B, card
); // set amplifier gain: unmute output and set to 0dB of FRONT (Port-D)
1103 send_command_12(card
->codecnr
, 0x1C, VERB_SET_PIN_WIDGET_CONTROL
, 0x40, card
); // output enabled
1105 // MIC1 pin as input
1106 send_command_12(card
->codecnr
, card
->mic1_nid
, VERB_SET_PIN_WIDGET_CONTROL
, 0x20, card
); // input enabled
1107 send_command_4(card
->codecnr
, card
->mic1_nid
, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // set amplifier gain: unmute input
1110 // device specific support
1111 if (device
== 0xE721) // VIA VT1708B
1113 bug("Adding VIA VT1708B specific support\n");
1115 card
->adc_mixer_indices
[0] = 3; // line in
1116 card
->adc_mixer_indices
[1] = 2; // mic1
1117 card
->adc_mixer_indices
[2] = 4; // mic2
1118 card
->adc_mixer_indices
[3] = 1; // cd
1119 card
->adc_mixer_indices
[4] = 255; // mon mixer
1121 card
->adc_min_gain
= -13.5;
1122 card
->adc_max_gain
= 33.0;
1123 card
->adc_step_gain
= 1.5;
1127 bug("Unsupported VIA codec! Playback may work.\n");
1132 static BOOL
interrogate_unknown_chip(struct HDAudioChip
*card
)
1134 int dac
, front
, speaker
= -1, steps
= 0, offset0dB
= 0;
1135 double step_size
= 0.25;
1138 bug("Unknown codec, interrogating chip...\n");
1140 card
->dac_nid
= 0x2;
1141 card
->dac_volume_nid
= 0;
1142 card
->adc_nid
= 0x8;
1144 card
->adc_mixer_nid
= 255;
1145 card
->line_in_nid
= 255;
1146 card
->mic1_nid
= 255;
1147 card
->mic2_nid
= 255;
1150 card
->adc_mixer_is_mux
= FALSE
;
1153 // find out the first PCM DAC
1154 dac
= find_audio_output(card
, 0); // analogue out
1155 bug("DAC NID = %xh\n", dac
);
1159 bug("Didn't find DAC!\n");
1163 card
->dac_nid
= dac
;
1165 parm
= get_parameter(dac
, VERB_GET_PARMS_AUDIO_WIDGET_CAPS
, card
);
1166 bug("audio widget caps for dac = %lx\n", parm
);
1167 if (parm
& 0x4) // OutAmpPre
1169 card
->dac_volume_nid
= dac
;
1170 bug("DAC seems to have volume control\n");
1176 front
= find_pin_widget_with_encoding(card
, 0);
1177 bug("Front PIN = %xh\n", front
);
1181 bug("Didn't find jack/pin for line output!\n");
1185 send_command_4(card
->codecnr
, front
, VERB_SET_AMP_GAIN
, OUTPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // set amplifier gain: unmute output of FRONT (Port-D)
1186 send_command_12(card
->codecnr
, front
, VERB_SET_PIN_WIDGET_CONTROL
, 0x40, card
); // output enabled
1191 if (force_speaker_nid
>= 0)
1193 bug("Using speaker nid from config file");
1194 speaker
= force_speaker_nid
;
1198 speaker
= find_speaker_nid(card
);
1200 bug("Speaker NID = %xh\n", speaker
);
1204 bug("No speaker pin found, continuing anyway!\n");
1208 card
->speaker_nid
= speaker
;
1209 card
->headphone_nid
= find_headphone_nid(card
);
1211 bug("Headphone NID = %xh\n", card
->headphone_nid
);
1213 // check if there is a power amp and if so, enable it
1214 if (get_parameter(speaker
, VERB_GET_PARMS_PIN_CAPS
, card
) & PIN_CAPS_EAPD_CAPABLE
)
1216 bug("Enabling power amp of speaker\n");
1217 send_command_12(card
->codecnr
, speaker
, VERB_SET_EAPD
, 0x2, card
); // enable EAPD (external power amp)
1220 send_command_4(card
->codecnr
, speaker
, VERB_SET_AMP_GAIN
, OUTPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // set amplifier gain: unmute output
1222 send_command_4(card
->codecnr
, card
->headphone_nid
, VERB_SET_AMP_GAIN
, OUTPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // set amplifier gain: unmute headphone
1223 send_command_12(card
->codecnr
, card
->headphone_nid
, VERB_SET_PIN_WIDGET_CONTROL
, 0xC0, card
); // output enabled and headphone enabled
1225 if (card
->headphone_nid
!= 255 && // headphone found NID and
1226 is_jack_connected(card
, card
->headphone_nid
) == FALSE
) // no headphone connected -> switch on the speaker
1228 send_command_12(card
->codecnr
, speaker
, VERB_SET_PIN_WIDGET_CONTROL
, 0x40, card
); // output enabled
1229 card
->speaker_active
= TRUE
;
1231 if (card
->dac_volume_nid
== 0)
1233 bug("Volume NID has not been set yet, so let's see if the speaker has volume control...\n");
1234 parm
= get_parameter(speaker
, VERB_GET_PARMS_AUDIO_WIDGET_CAPS
, card
);
1235 bug("Audio widget caps for speaker = %lx\n", parm
);
1236 if (parm
& 0x4) // OutAmpPre
1238 card
->dac_volume_nid
= speaker
;
1239 bug("Speaker seems to have volume control\n");
1243 bug("Speaker did not have volume control\n");
1247 else if (card
->headphone_nid
!= 255 && // headphone found NID and
1248 is_jack_connected(card
, card
->headphone_nid
) == TRUE
) // headphone connected -> switch off the speaker
1250 //send_command_4(card->codecnr, speaker, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR | (1 << 7), card); // set amplifier gain: mute output
1251 send_command_12(card
->codecnr
, speaker
, VERB_SET_PIN_WIDGET_CONTROL
, 0x0, card
); // output enabled
1256 UBYTE before_front
= 0;
1259 // now the hard part: see if the input of FRONT is equal to the DAC NID
1260 before_front
= (UBYTE
) send_command_12(card
->codecnr
, front
, VERB_GET_CONNECTION_LIST_ENTRY
, 0, card
);
1262 else if (speaker
!= -1)
1264 bug("setting before_front to before speaker\n");
1265 if (card
->headphone_nid
!= 255 &&
1266 is_jack_connected(card
, card
->headphone_nid
) == FALSE
)
1268 before_front
= (UBYTE
) send_command_12(card
->codecnr
, speaker
, VERB_GET_CONNECTION_LIST_ENTRY
, 0, card
);
1270 else // use headphone
1272 before_front
= (UBYTE
) send_command_12(card
->codecnr
, card
->headphone_nid
, VERB_GET_CONNECTION_LIST_ENTRY
, 0, card
);
1276 if (before_front
!= dac
)
1278 bug("The widget before front (%xh) is not equal to DAC!\n", before_front
);
1280 send_command_4(card
->codecnr
, before_front
, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
, card
); // unmute PCM at index 0
1281 bug("Let's hope it was a mute that now got unmuted!\n");
1283 bug("audio widget caps for before_front= %lx\n", get_parameter(before_front
, VERB_GET_PARMS_AUDIO_WIDGET_CAPS
, card
));
1285 if (card
->dac_volume_nid
== 0) // volume NID not set yet
1287 bug("Checking if before_front has volume control\n");
1288 parm
= get_parameter(before_front
, VERB_GET_PARMS_AUDIO_WIDGET_CAPS
, card
);
1289 if (parm
& 0x4) // OutAmpPre
1291 card
->dac_volume_nid
= before_front
;
1292 bug("before_front seems to have volume control\n");
1296 bug("Odd, before_front doesn't seem to have volume control\n");
1302 bug("The widget before front or speaker is equal to DAC.\n");
1305 parm
= get_parameter(card
->dac_volume_nid
, VERB_GET_PARMS_OUTPUT_AMP_CAPS
, card
);
1306 bug("Output amp caps = %lx\n", parm
);
1308 step_size
= (((parm
>> 16) & 0x7F) + 1) * 0.25;
1309 steps
= ((parm
>> 8) & 0x7F);
1310 offset0dB
= (parm
& 0x7F);
1312 card
->dac_min_gain
= -(offset0dB
* step_size
);
1313 card
->dac_max_gain
= card
->dac_min_gain
+ step_size
* steps
;
1314 card
->dac_step_gain
= step_size
;
1315 bug("Gain step size = %lu * 0.25 dB, max gain = %d\n", (((parm
>> 16) & 0x7F) + 1), (int) (card
->dac_max_gain
));
1321 static int find_pin_widget_with_encoding(struct HDAudioChip
*card
, UBYTE encoding
)
1324 ULONG node_count_response
= get_parameter(0, VERB_GET_PARMS_NODE_COUNT
, card
);
1325 UBYTE node_count
= node_count_response
& 0xFF;
1326 UBYTE starting_node
= (node_count_response
>> 16) & 0xFF;
1328 for (i
= 0; i
< node_count
; i
++)
1330 ULONG function_group_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_FUNCTION_GROUP_TYPE
, card
);
1331 UBYTE function_group
= function_group_response
& 0xFF;
1332 //bug("Function group = %x, UnSol cap = %x\n", function_group, (function_group_response >> 8) & 0x1);
1334 if (function_group
== AUDIO_FUNCTION
)
1338 ULONG subnode_count_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_NODE_COUNT
, card
);
1339 UBYTE subnode_count
= subnode_count_response
& 0xFF;
1340 UBYTE sub_starting_node
= (subnode_count_response
>> 16) & 0xFF;
1341 ULONG config_default
;
1344 for (j
= 0; j
< subnode_count
; j
++) // widgets
1346 const ULONG NID
= j
+ sub_starting_node
;
1349 widget_caps
= get_parameter(NID
, VERB_GET_PARMS_AUDIO_WIDGET_CAPS
, card
);
1351 if (((widget_caps
>> 20) & 0xF) == 4) // node is a pin widget
1353 config_default
= send_command_12(card
->codecnr
, NID
, VERB_GET_CONFIG_DEFAULT
, 0, card
);
1355 if (((config_default
>> 20) & 0xF) == encoding
)
1357 bug("Config default for NID %x = %x\n", NID
, config_default
);
1369 static int find_speaker_nid(struct HDAudioChip
*card
)
1372 ULONG node_count_response
= get_parameter(0, VERB_GET_PARMS_NODE_COUNT
, card
);
1373 UBYTE node_count
= node_count_response
& 0xFF;
1374 UBYTE starting_node
= (node_count_response
>> 16) & 0xFF;
1376 for (i
= 0; i
< node_count
; i
++)
1378 ULONG function_group_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_FUNCTION_GROUP_TYPE
, card
);
1379 UBYTE function_group
= function_group_response
& 0xFF;
1380 //bug("Function group = %x, UnSol cap = %x\n", function_group, (function_group_response >> 8) & 0x1);
1382 if (function_group
== AUDIO_FUNCTION
)
1386 ULONG subnode_count_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_NODE_COUNT
, card
);
1387 UBYTE subnode_count
= subnode_count_response
& 0xFF;
1388 UBYTE sub_starting_node
= (subnode_count_response
>> 16) & 0xFF;
1389 ULONG config_default
;
1392 for (j
= 0; j
< subnode_count
; j
++) // widgets
1394 const ULONG NID
= j
+ sub_starting_node
;
1397 widget_caps
= get_parameter(NID
, VERB_GET_PARMS_AUDIO_WIDGET_CAPS
, card
);
1399 if (AUDIO_WIDGET_CAPS(widget_caps
) == 4) // node is a pin widget
1401 config_default
= send_command_12(card
->codecnr
, NID
, VERB_GET_CONFIG_DEFAULT
, 0, card
);
1403 if ( (((config_default
>> 20) & 0xF) == 1) && // the default device/use is a speaker
1404 (((config_default
>> 16) & 0xF) == 3) ) // connection type is internal
1417 static int find_headphone_nid(struct HDAudioChip
*card
)
1420 ULONG node_count_response
= get_parameter(0, VERB_GET_PARMS_NODE_COUNT
, card
);
1421 UBYTE node_count
= node_count_response
& 0xFF;
1422 UBYTE starting_node
= (node_count_response
>> 16) & 0xFF;
1424 for (i
= 0; i
< node_count
; i
++)
1426 ULONG function_group_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_FUNCTION_GROUP_TYPE
, card
);
1427 UBYTE function_group
= function_group_response
& 0xFF;
1428 //bug("Function group = %x, UnSol cap = %x\n", function_group, (function_group_response >> 8) & 0x1);
1430 if (function_group
== AUDIO_FUNCTION
)
1434 ULONG subnode_count_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_NODE_COUNT
, card
);
1435 UBYTE subnode_count
= subnode_count_response
& 0xFF;
1436 UBYTE sub_starting_node
= (subnode_count_response
>> 16) & 0xFF;
1437 ULONG config_default
;
1440 for (j
= 0; j
< subnode_count
; j
++) // widgets
1442 const ULONG NID
= j
+ sub_starting_node
;
1445 widget_caps
= get_parameter(NID
, VERB_GET_PARMS_AUDIO_WIDGET_CAPS
, card
);
1447 if (AUDIO_WIDGET_CAPS(widget_caps
) == 4) // node is a pin widget
1449 config_default
= send_command_12(card
->codecnr
, NID
, VERB_GET_CONFIG_DEFAULT
, 0, card
);
1451 if ( (((config_default
>> 20) & 0xF) == 2) && // the default device/use is a headphone output
1452 (((config_default
>> 16) & 0xF) == 1) ) // connection type is mini-jack
1465 static int find_audio_output(struct HDAudioChip
*card
, UBYTE digital
)
1468 ULONG node_count_response
= get_parameter(0, VERB_GET_PARMS_NODE_COUNT
, card
);
1469 UBYTE node_count
= node_count_response
& 0xFF;
1470 UBYTE starting_node
= (node_count_response
>> 16) & 0xFF;
1472 for (i
= 0; i
< node_count
; i
++)
1474 ULONG function_group_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_FUNCTION_GROUP_TYPE
, card
);
1475 UBYTE function_group
= function_group_response
& 0xFF;
1476 //bug("Function group = %x, UnSol cap = %x\n", function_group, (function_group_response >> 8) & 0x1);
1478 if (function_group
== AUDIO_FUNCTION
)
1482 ULONG subnode_count_response
= get_parameter(starting_node
+ i
, VERB_GET_PARMS_NODE_COUNT
, card
);
1483 UBYTE subnode_count
= subnode_count_response
& 0xFF;
1484 UBYTE sub_starting_node
= (subnode_count_response
>> 16) & 0xFF;
1485 ULONG config_default
;
1488 for (j
= 0; j
< subnode_count
; j
++) // widgets
1490 const ULONG NID
= j
+ sub_starting_node
;
1493 widget_caps
= get_parameter(NID
, VERB_GET_PARMS_AUDIO_WIDGET_CAPS
, card
);
1495 if (((widget_caps
>> 20) & 0xF) == 0) // audio output
1497 if ((widget_caps
& 0x1) == 1 && // stereo
1498 ((widget_caps
>> 9) & 0x1) == digital
)
1511 static void determine_frequencies(struct HDAudioChip
*card
)
1513 ULONG verb
= get_parameter(card
->dac_nid
, 0xA, card
);
1514 UWORD samplerate_flags
= verb
& 0x0FFF;
1517 BOOL default_freq_found
= FALSE
;
1519 if (samplerate_flags
== 0)
1521 verb
= get_parameter(0x1, 0xA, card
);
1522 samplerate_flags
= verb
& 0x0FFF;
1523 bug("dac_nid didn't have a list of sample rates, trying AFG node\n");
1526 // count number of frequencies
1527 for (i
= 0; i
< 12; i
++)
1529 if (samplerate_flags
& (1 << i
))
1535 bug("Frequencies found = %lu\n", freqs
);
1536 card
->frequencies
= (struct Freq
*) AllocVec(sizeof(struct Freq
) * freqs
, MEMF_PUBLIC
| MEMF_CLEAR
);
1537 card
->nr_of_frequencies
= freqs
;
1540 for (i
= 0; i
< 12; i
++)
1542 if (samplerate_flags
& (1 << i
))
1544 set_frequency_info(&(card
->frequencies
[freqs
]), i
);
1546 if (card
->frequencies
[freqs
].frequency
== 44100 && !default_freq_found
)
1548 card
->selected_freq_index
= freqs
; // set default freq index to 44100 Hz
1549 default_freq_found
= TRUE
;
1556 if (default_freq_found
== FALSE
)
1558 bug("44100 Hz is not supported!\n");
1561 bug("Setting default frequency to %lu\n", card
->frequencies
[0].frequency
);
1562 card
->selected_freq_index
= 0;
1569 static void set_frequency_info(struct Freq
*freq
, UWORD bitnr
)
1573 case 0: freq
->frequency
= 8000;
1574 freq
->base44100
= 0;
1579 case 1: freq
->frequency
= 11025;
1580 freq
->base44100
= 1;
1585 case 2: freq
->frequency
= 16000;
1586 freq
->base44100
= 0;
1591 case 3: freq
->frequency
= 22050;
1592 freq
->base44100
= 1;
1597 case 4: freq
->frequency
= 32000;
1598 freq
->base44100
= 0;
1603 case 5: freq
->frequency
= 44100;
1604 freq
->base44100
= 1;
1609 case 6: freq
->frequency
= 48000;
1610 freq
->base44100
= 0;
1615 case 7: freq
->frequency
= 88200;
1616 freq
->base44100
= 1;
1621 case 8: freq
->frequency
= 96000;
1622 freq
->base44100
= 0;
1627 case 9: freq
->frequency
= 176400;
1628 freq
->base44100
= 1;
1633 case 10: freq
->frequency
= 192000;
1634 freq
->base44100
= 0;
1639 default: bug("Unsupported frequency!\n");
1645 void set_monitor_volumes(struct HDAudioChip
*card
, double dB
)
1648 int dB_steps
= (int) ((dB
+ 34.5) / 1.5);
1654 else if (dB_steps
> 31)
1659 for (i
= 0; i
< 9; i
++)
1661 if (i
== 0 || i
== 1 || i
== 2 || i
== 4)
1663 send_command_4(card
->codecnr
, 0xB, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| (i
<< 8) | dB_steps
, card
);
1667 send_command_4(card
->codecnr
, 0xB, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| (i
<< 8) | (1 << 7), card
);
1673 void set_adc_input(struct HDAudioChip
*card
)
1677 if (card
->input
>= INPUTS
)
1682 if (card
->adc_mixer_is_mux
== TRUE
)
1684 send_command_12(card
->codecnr
, card
->adc_mixer_nid
, VERB_SET_CONNECTION_SELECT
,
1685 card
->adc_mixer_indices
[card
->input
], card
);
1690 for (i
= 0; i
< INPUTS
; i
++)
1692 if (card
->adc_mixer_indices
[i
] != 255) // input is present
1694 if (i
== card
->input
) // unmute or select
1696 send_command_4(card
->codecnr
, card
->adc_mixer_nid
, VERB_SET_AMP_GAIN
,
1697 INPUT_AMP_GAIN
| AMP_GAIN_LR
| (card
->adc_mixer_indices
[i
] << 8), card
);
1701 send_command_4(card
->codecnr
, card
->adc_mixer_nid
, VERB_SET_AMP_GAIN
,
1702 INPUT_AMP_GAIN
| AMP_GAIN_LR
| (card
->adc_mixer_indices
[i
] << 8) | (1 << 7), card
);
1711 void set_adc_gain(struct HDAudioChip
*card
, double dB
)
1714 int dB_steps
= (int) ( (dB
- card
->adc_min_gain
) / card
->adc_step_gain
);
1721 if (card
->adc_mixer_is_mux
== TRUE
)
1723 send_command_4(card
->codecnr
, card
->adc_mixer_nid
, VERB_SET_AMP_GAIN
, OUTPUT_AMP_GAIN
| AMP_GAIN_LR
| dB_steps
, card
);
1727 send_command_4(card
->codecnr
, card
->adc_nid
, VERB_SET_AMP_GAIN
, INPUT_AMP_GAIN
| AMP_GAIN_LR
| dB_steps
, card
);
1732 void set_dac_gain(struct HDAudioChip
*card
, double dB
)
1735 int dB_steps
= (int) ( (dB
- card
->dac_min_gain
) / card
->dac_step_gain
);
1742 send_command_4(card
->codecnr
, card
->dac_volume_nid
, VERB_SET_AMP_GAIN
, OUTPUT_AMP_GAIN
| AMP_GAIN_LR
| dB_steps
, card
);
1746 void switch_nid_to_input(struct HDAudioChip
*card
, UBYTE NID
)
1748 ULONG data
= send_command_12(card
->codecnr
, NID
, VERB_GET_PIN_WIDGET_CONTROL
, 0, card
);
1750 data
|= 0x20; // input enable
1751 data
&= ~(0x40); // output disable
1752 send_command_12(card
->codecnr
, NID
, VERB_SET_PIN_WIDGET_CONTROL
, data
, card
);
1756 void switch_nid_to_output(struct HDAudioChip
*card
, UBYTE NID
)
1758 ULONG data
= send_command_12(card
->codecnr
, NID
, VERB_GET_PIN_WIDGET_CONTROL
, 0, card
);
1760 data
&= ~(0x20); // input disable
1761 data
|= 0x40; // output enable
1762 send_command_12(card
->codecnr
, NID
, VERB_SET_PIN_WIDGET_CONTROL
, data
, card
);
1766 void setForceQuery()
1778 void setForceSpeaker(int speaker_nid
)
1780 force_speaker_nid
= speaker_nid
;
1785 BOOL
is_jack_connected(struct HDAudioChip
*card
, UBYTE NID
)
1789 send_command_12(card
->codecnr
, NID
, VERB_EXECUTE_PIN_SENSE
, 0, card
);
1791 result
= send_command_12(card
->codecnr
, NID
, VERB_GET_PIN_SENSE
, 0, card
);
1793 if (result
& 0x80000000)
1805 void detect_headphone_change(struct HDAudioChip
*card
)
1807 if (card
->speaker_nid
!= 255 &&
1808 card
->headphone_nid
!= 255)
1810 if (card
->speaker_active
&&
1811 is_jack_connected(card
, card
->headphone_nid
)) // disable speaker
1813 send_command_12(card
->codecnr
, card
->speaker_nid
, VERB_SET_PIN_WIDGET_CONTROL
, 0x0, card
); // output disabled
1814 card
->speaker_active
= FALSE
;
1816 else if (card
->speaker_active
== FALSE
&&
1817 is_jack_connected(card
, card
->headphone_nid
) == FALSE
) // enable speaker
1819 send_command_12(card
->codecnr
, card
->speaker_nid
, VERB_SET_PIN_WIDGET_CONTROL
, 0x40, card
); // output enabled
1820 card
->speaker_active
= TRUE
;