Ensure chosen frequency isn't less than the minimum. Fixes problem of sound
[AROS.git] / workbench / devs / AHI / Drivers / HDAudio / misc.c
blob8544c6edadc6b2757085f4c7c11734410c482bc3
1 #include <config.h>
3 #include <exec/memory.h>
4 #include <proto/expansion.h>
6 #include <proto/dos.h>
7 #ifdef __AROS__
8 #include <aros/debug.h>
9 #endif
10 #include <math.h>
12 #include "library.h"
13 #include "regs.h"
14 #include "interrupt.h"
15 #include "misc.h"
16 #include "pci_wrapper.h"
19 extern int z;
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);
51 #ifdef __AROS__
52 #define DebugPrintF bug
53 INTGW(static, void, playbackinterrupt, PlaybackInterrupt);
54 INTGW(static, void, recordinterrupt, RecordInterrupt);
55 INTGW(static, ULONG, cardinterrupt, CardInterrupt);
56 #endif
58 void micro_delay(unsigned int val)
60 replymp = (struct MsgPort *) CreateMsgPort();
61 if (!replymp)
63 bug("Could not create the reply port!\n");
64 return;
67 TimerIO = (struct timerequest *) CreateIORequest(replymp, sizeof(struct timerequest));
69 if (TimerIO == NULL)
71 DebugPrintF("Out of memory.\n");
72 return;
75 if (OpenDevice((CONST_STRPTR) "timer.device", UNIT_MICROHZ, (struct IORequest *) TimerIO, 0) != 0)
77 DebugPrintF("Unable to open 'timer.device'.\n");
78 return;
80 else
82 TimerBase = (struct Device *) TimerIO->tr_node.io_Device;
85 if (TimerIO)
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);
92 TimerIO = NULL;
93 CloseDevice((struct IORequest *) TimerIO);
96 if (replymp)
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;
111 UWORD command_word;
112 int i;
113 unsigned short uval;
115 card = (struct HDAudioChip *) AllocVec(sizeof(struct HDAudioChip), MEMF_PUBLIC | MEMF_CLEAR);
117 if (card == NULL)
119 Req("Unable to allocate driver structure.");
120 return NULL;
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;
128 #ifdef __AROS__
129 card->interrupt.is_Code = (void(*)(void)) &cardinterrupt;
130 #else
131 card->interrupt.is_Code = (void(*)(void)) CardInterrupt;
132 #endif
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;
138 #ifdef __AROS__
139 card->playback_interrupt.is_Code = &playbackinterrupt;
140 #else
141 card->interrupt.is_Code = PlaybackInterrupt;
142 #endif
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;
148 #ifdef __AROS__
149 card->record_interrupt.is_Code = &recordinterrupt;
150 #else
151 card->interrupt.is_Code = RecordInterrupt;
152 #endif
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);
159 card->pci_dev = 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");
175 FreeVec(card);
176 return NULL;
179 card->interrupt_added = TRUE;
181 card->card_initialized = TRUE;
182 card->input = 0;
183 card->output = 0;
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);
192 return card;
196 /******************************************************************************
197 ** DriverData deallocation ****************************************************
198 ******************************************************************************/
200 void FreeDriverData(struct HDAudioChip* card, struct DriverBase* AHIsubBase)
202 if (card != NULL)
204 if (card->pci_dev != NULL)
206 if (card->card_initialized)
208 card_cleanup(card);
211 if (card->pci_master_enabled)
213 UWORD cmd;
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);
226 FreeVec(card);
232 int card_init(struct HDAudioChip *card)
234 struct PCIDevice *dev = (struct PCIDevice *) card->pci_dev;
235 UWORD uwval;
236 unsigned char pval, byt;
237 long *ptr;
238 int i;
240 if (reset_chip(card) == FALSE)
242 bug("Reset chip failed\n");
243 return -1;
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");
252 return -1;
255 for (i = 0; i < 16; i++)
257 if (card->codecbits & (1 << i))
259 card->codecnr = i;
260 break;
264 if (alloc_streams(card) == FALSE)
266 bug("Allocating streams failed!\n");
267 return -1;
270 if (allocate_corb(card) == FALSE)
272 bug("Allocating CORB failed!\n");
273 return -1;
276 if (allocate_rirb(card) == FALSE)
278 bug("Allocating RIRB failed!\n");
279 return -1;
282 if (allocate_pos_buffer(card) == FALSE)
284 bug("Allocating position buffer failed!\n");
285 return -1;
288 // enable interrupts
289 pci_outl(HD_INTCTL_CIE | HD_INTCTL_GLOBAL, HD_INTCTL, card);
290 udelay(200);
292 power_up_all_nodes(card);
294 if (perform_codec_specific_settings(card) == FALSE)
296 return -1;
299 if (dumpAll)
301 codec_discovery(card);
304 bug("card_init() was a success!\n");
306 return 0;
310 void card_cleanup(struct HDAudioChip *card)
315 static BOOL reset_chip(struct HDAudioChip *card)
317 int counter = 0;
318 UBYTE ubval = 0;
319 UWORD uwval = 0;
320 int count;
321 UBYTE tcsel;
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
326 assigned TC0.
328 #define TCSEL_PCIREG 0x44
329 tcsel = inb_config(TCSEL_PCIREG, card->pci_dev);
330 tcsel &= ~0x07;
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)
349 break;
352 udelay(100);
355 if (counter == 1000)
357 bug("Couldn't reset chip!\n");
358 return FALSE;
361 udelay(100);
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");
374 break;
377 udelay(100);
380 if (counter == 1000)
382 bug("Couldn't reset chip!\n");
383 return FALSE;
386 // The software must wait 250 microseconds after reading CRST as 1, but it's suggested to wait longer
387 udelay(1000);
389 // do not accept unsolicited events for now (jack sense etc.)
390 //outl_setbits((1 << 8), HD_GCTL, card); // accept unsolicited events
392 return TRUE;
396 void codec_discovery(struct HDAudioChip *card)
398 int i;
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)
412 int j;
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;
426 ULONG widget_caps;
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
454 ULONG entry = 0;
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);
462 bug("\n");
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)
485 int i;
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;
490 bug("power up\n");
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
492 udelay(20000);
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)
501 int j;
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;
511 ULONG widget_caps;
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)
540 void* address;
541 unsigned long a;
543 address = (void *) AllocVec(size + boundary, MEMF_PUBLIC | MEMF_CLEAR);
545 if (address != NULL)
547 a = (unsigned long) address;
548 a = (a + boundary - 1) & ~(boundary - 1);
549 address = (void *) a;
552 if (NonAlignedAddress)
554 *NonAlignedAddress = address;
557 return address;
561 void pci_free_consistent(void* addr)
563 FreeVec(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)
580 wp = 0;
582 else
584 wp++;
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)
603 wp = 0;
605 else
607 wp++;
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)
621 int timeout = 10000;
622 int i;
623 UBYTE rirb_wp;
625 udelay(20); //
627 // wait for interrupt
628 for (i = 0; i < timeout; i++)
630 if (card->rirb_irq > 0)
632 card->rirb_irq--;
633 break;
635 udelay(10);
638 if (i == timeout)
640 bug("No IRQ!\n");
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);
650 udelay(5000);
652 else
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");
663 ULONG addr;
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");
676 else
678 //bug("Response is %lx\n", response);
679 return response;
684 bug("ERROR in get_response() card->rirb_rp = %u!rirb_wp = %u\n", card->rirb_rp, rirb_wp);
685 return 0;
689 static BOOL allocate_corb(struct HDAudioChip *card)
691 UBYTE corbsize_reg;
693 // 4.4.1.3 Initialize the CORB
695 // stop the DMA
696 outb_clearbits(HD_CORBRUN, HD_CORBCTL, card);
698 // set CORB size
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
719 // Set CORB base
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);
733 // run it
734 outb_setbits(HD_CORBRUN, HD_CORBCTL, card);
736 if (card->corb)
738 return TRUE;
740 else
742 return FALSE;
747 static BOOL allocate_rirb(struct HDAudioChip *card)
749 UBYTE rirbsize_reg;
751 // 4.4.2.2 Initialize the RIRB
753 // stop the DMA
754 outb_clearbits(HD_RIRBRUN, HD_RIRBCTL, card);
756 // set rirb size
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;
774 card->rirb_irq = 0;
776 // Allocate rirb memory
777 card->rirb = pci_alloc_consistent(4 * 2 * card->rirb_entries, NULL, 128); // todo: virtual
778 card->rirb_rp = 0;
780 // Set rirb base
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);
795 if (card->rirb)
797 return TRUE;
799 else
801 return FALSE;
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)
815 return TRUE;
817 else
819 return FALSE;
824 static BOOL alloc_streams(struct HDAudioChip *card)
826 int i;
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);
847 if (card->streams)
849 return TRUE;
851 else
853 return FALSE;
858 /*static ULONG ResetHandler(struct ExceptionContext *ctx, struct ExecBase *pExecBase, struct HDAudioChip *card)
860 struct PCIDevice *dev = card->pci_dev;
862 return 0UL;
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
883 UBYTE old;
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)
911 return FALSE;
915 determine_frequencies(card);
916 return TRUE;
920 static void perform_realtek_specific_settings(struct HDAudioChip *card, UWORD device)
922 bug("Found Realtek codec\n");
924 card->dac_nid = 0x2;
925 card->dac_volume_nid = 0x2;
926 card->adc_nid = 0x8;
928 card->adc_mixer_nid = 0x23;
929 card->line_in_nid = 0x1A;
930 card->mic1_nid = 0x18;
931 card->mic2_nid = 0x19;
932 card->cd_nid = 0x1C;
934 card->adc_mixer_is_mux = FALSE;
936 // FRONT pin (0x14)
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
974 // Front DAC (0xC)
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;
1036 // Front DAC (0xC)
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
1079 else
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;
1101 // FRONT pin (0x14)
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;
1125 else
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;
1136 ULONG parm;
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;
1148 card->cd_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);
1157 if (dac == -1)
1159 bug("Didn't find DAC!\n");
1160 return FALSE;
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");
1175 // find FRONT pin
1176 front = find_pin_widget_with_encoding(card, 0);
1177 bug("Front PIN = %xh\n", front);
1179 if (front == -1)
1181 bug("Didn't find jack/pin for line output!\n");
1183 else
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
1190 // find SPEAKER
1191 if (force_speaker_nid >= 0)
1193 bug("Using speaker nid from config file");
1194 speaker = force_speaker_nid;
1196 else
1198 speaker = find_speaker_nid(card);
1200 bug("Speaker NID = %xh\n", speaker);
1202 if (speaker == -1)
1204 bug("No speaker pin found, continuing anyway!\n");
1206 else
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");
1241 else
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;
1257 if (front != -1)
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");
1294 else
1296 bug("Odd, before_front doesn't seem to have volume control\n");
1300 else
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));
1317 return TRUE;
1321 static int find_pin_widget_with_encoding(struct HDAudioChip *card, UBYTE encoding)
1323 int i;
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)
1336 int j;
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;
1347 ULONG widget_caps;
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);
1358 return (int) (NID);
1365 return -1;
1369 static int find_speaker_nid(struct HDAudioChip *card)
1371 int i;
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)
1384 int j;
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;
1395 ULONG widget_caps;
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
1406 return (int) (NID);
1413 return -1;
1417 static int find_headphone_nid(struct HDAudioChip *card)
1419 int i;
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)
1432 int j;
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;
1443 ULONG widget_caps;
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
1454 return (int) (NID);
1461 return -1;
1465 static int find_audio_output(struct HDAudioChip *card, UBYTE digital)
1467 int i;
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)
1480 int j;
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;
1491 ULONG widget_caps;
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)
1500 return (int) (NID);
1507 return -1;
1511 static void determine_frequencies(struct HDAudioChip *card)
1513 ULONG verb = get_parameter(card->dac_nid, 0xA, card);
1514 UWORD samplerate_flags = verb & 0x0FFF;
1515 int i;
1516 ULONG freqs = 0;
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))
1531 freqs++;
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;
1539 freqs = 0;
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;
1552 freqs++;
1556 if (default_freq_found == FALSE)
1558 bug("44100 Hz is not supported!\n");
1559 if (freqs > 0)
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)
1571 switch (bitnr)
1573 case 0: freq->frequency = 8000;
1574 freq->base44100 = 0;
1575 freq->mult = 0;
1576 freq->div = 5;
1577 break;
1579 case 1: freq->frequency = 11025;
1580 freq->base44100 = 1;
1581 freq->mult = 0;
1582 freq->div = 3;
1583 break;
1585 case 2: freq->frequency = 16000;
1586 freq->base44100 = 0;
1587 freq->mult = 0;
1588 freq->div = 2;
1589 break;
1591 case 3: freq->frequency = 22050;
1592 freq->base44100 = 1;
1593 freq->mult = 0;
1594 freq->div = 1;
1595 break;
1597 case 4: freq->frequency = 32000;
1598 freq->base44100 = 0;
1599 freq->mult = 0;
1600 freq->div = 2;
1601 break;
1603 case 5: freq->frequency = 44100;
1604 freq->base44100 = 1;
1605 freq->mult = 0;
1606 freq->div = 0;
1607 break;
1609 case 6: freq->frequency = 48000;
1610 freq->base44100 = 0;
1611 freq->mult = 0;
1612 freq->div = 0;
1613 break;
1615 case 7: freq->frequency = 88200;
1616 freq->base44100 = 1;
1617 freq->mult = 1;
1618 freq->div = 0;
1619 break;
1621 case 8: freq->frequency = 96000;
1622 freq->base44100 = 0;
1623 freq->mult = 1;
1624 freq->div = 0;
1625 break;
1627 case 9: freq->frequency = 176400;
1628 freq->base44100 = 1;
1629 freq->mult = 3;
1630 freq->div = 0;
1631 break;
1633 case 10: freq->frequency = 192000;
1634 freq->base44100 = 0;
1635 freq->mult = 3;
1636 freq->div = 0;
1637 break;
1639 default: bug("Unsupported frequency!\n");
1640 break;
1645 void set_monitor_volumes(struct HDAudioChip *card, double dB)
1647 int i;
1648 int dB_steps = (int) ((dB + 34.5) / 1.5);
1650 if (dB_steps < 0)
1652 dB_steps = 0;
1654 else if (dB_steps > 31)
1656 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);
1665 else // mute
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)
1675 int i;
1677 if (card->input >= INPUTS)
1679 card->input = 0;
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);
1686 return;
1688 else
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);
1699 else // mute
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)
1713 int i;
1714 int dB_steps = (int) ( (dB - card->adc_min_gain) / card->adc_step_gain);
1716 if (dB_steps < 0)
1718 dB_steps = 0;
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);
1725 else
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)
1734 int i;
1735 int dB_steps = (int) ( (dB - card->dac_min_gain) / card->dac_step_gain);
1737 if (dB_steps < 0)
1739 dB_steps = 0;
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()
1768 forceQuery = TRUE;
1772 void setDumpAll()
1774 dumpAll = TRUE;
1778 void setForceSpeaker(int speaker_nid)
1780 force_speaker_nid = speaker_nid;
1785 BOOL is_jack_connected(struct HDAudioChip *card, UBYTE NID)
1787 ULONG result;
1789 send_command_12(card->codecnr, NID, VERB_EXECUTE_PIN_SENSE, 0, card);
1790 udelay(2000);
1791 result = send_command_12(card->codecnr, NID, VERB_GET_PIN_SENSE, 0, card);
1793 if (result & 0x80000000)
1795 return TRUE;
1797 else
1799 return FALSE;
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;