Specific settings for IDT 92HD75B codec from Joni Valtanen.
[AROS.git] / workbench / devs / AHI / Drivers / HDAudio / misc.c
blobb13727f0f62ecbd3c0ff68a332ba1eadd3cd10d1
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 BOOL perform_realtek_specific_settings(struct HDAudioChip *card, UWORD device);
34 static BOOL perform_via_specific_settings(struct HDAudioChip *card, UWORD device);
35 static BOOL perform_idt_specific_settings(struct HDAudioChip *card, UWORD device);
36 static int find_pin_widget_with_encoding(struct HDAudioChip *card, UBYTE encoding);
37 static BOOL interrogate_unknown_chip(struct HDAudioChip *card);
38 static int find_audio_output(struct HDAudioChip *card, UBYTE digital);
39 static int find_speaker_nid(struct HDAudioChip *card);
40 static int find_headphone_nid(struct HDAudioChip *card);
41 static BOOL power_up_all_nodes(struct HDAudioChip *card);
43 struct Device *TimerBase = NULL;
44 struct timerequest *TimerIO = NULL;
45 struct MsgPort *replymp = NULL;
46 static BOOL forceQuery = FALSE;
47 static BOOL dumpAll = FALSE;
48 static int force_speaker_nid = -1;
49 //void AddResetHandler(struct HDAudioChip *card);
52 #ifdef __AROS__
53 #define DebugPrintF bug
54 INTGW(static, void, playbackinterrupt, PlaybackInterrupt);
55 INTGW(static, void, recordinterrupt, RecordInterrupt);
56 INTGW(static, ULONG, cardinterrupt, CardInterrupt);
57 #endif
59 void micro_delay(unsigned int val)
61 replymp = (struct MsgPort *) CreateMsgPort();
62 if (!replymp)
64 bug("Could not create the reply port!\n");
65 return;
68 TimerIO = (struct timerequest *) CreateIORequest(replymp, sizeof(struct timerequest));
70 if (TimerIO == NULL)
72 DebugPrintF("Out of memory.\n");
73 return;
76 if (OpenDevice((CONST_STRPTR) "timer.device", UNIT_MICROHZ, (struct IORequest *) TimerIO, 0) != 0)
78 DebugPrintF("Unable to open 'timer.device'.\n");
79 return;
81 else
83 TimerBase = (struct Device *) TimerIO->tr_node.io_Device;
86 TimerIO->tr_node.io_Command = TR_ADDREQUEST; /* Add a request. */
87 TimerIO->tr_time.tv_secs = 0; /* 0 seconds. */
88 TimerIO->tr_time.tv_micro = val; /* 'val' micro seconds. */
89 DoIO((struct IORequest *) TimerIO);
90 CloseDevice((struct IORequest *) TimerIO);
91 DeleteIORequest((struct IORequest *) TimerIO);
92 TimerIO = NULL;
94 if (replymp)
96 DeleteMsgPort(replymp);
101 /******************************************************************************
102 ** DriverData allocation ******************************************************
103 ******************************************************************************/
105 struct HDAudioChip* AllocDriverData(APTR dev, struct DriverBase* AHIsubBase)
107 struct HDAudioBase* card_base = (struct HDAudioBase*) AHIsubBase;
108 struct HDAudioChip* card;
109 UWORD command_word;
110 int i;
111 unsigned short uval;
112 BOOL success = TRUE;
114 card = (struct HDAudioChip *) AllocVec(sizeof(struct HDAudioChip), MEMF_PUBLIC | MEMF_CLEAR);
116 if (card == NULL)
118 Req("Unable to allocate driver structure.");
119 return NULL;
122 card->ahisubbase = AHIsubBase;
124 card->interrupt.is_Node.ln_Type = IRQTYPE;
125 card->interrupt.is_Node.ln_Pri = 0;
126 card->interrupt.is_Node.ln_Name = (char *) LibName;
127 #ifdef __AROS__
128 card->interrupt.is_Code = (void(*)(void)) &cardinterrupt;
129 #else
130 card->interrupt.is_Code = (void(*)(void)) CardInterrupt;
131 #endif
132 card->interrupt.is_Data = (APTR) card;
134 card->playback_interrupt.is_Node.ln_Type = IRQTYPE;
135 card->playback_interrupt.is_Node.ln_Pri = 0;
136 card->playback_interrupt.is_Node.ln_Name = (char *) LibName;
137 #ifdef __AROS__
138 card->playback_interrupt.is_Code = &playbackinterrupt;
139 #else
140 card->playback_interrupt.is_Code = PlaybackInterrupt;
141 #endif
142 card->playback_interrupt.is_Data = (APTR) card;
144 card->record_interrupt.is_Node.ln_Type = IRQTYPE;
145 card->record_interrupt.is_Node.ln_Pri = 0;
146 card->record_interrupt.is_Node.ln_Name = (char *) LibName;
147 #ifdef __AROS__
148 card->record_interrupt.is_Code = &recordinterrupt;
149 #else
150 card->record_interrupt.is_Code = RecordInterrupt;
151 #endif
152 card->record_interrupt.is_Data = (APTR) card;
154 command_word = inw_config(PCI_COMMAND, dev);
155 command_word |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
156 outw_config(PCI_COMMAND, command_word, dev);
158 card->pci_dev = dev;
159 card->pci_master_enabled = TRUE;
161 card->iobase = ahi_pci_get_base_address(0, dev);
162 card->length = ahi_pci_get_base_size(0, dev);
163 card->irq = ahi_pci_get_irq(dev);
164 card->chiprev = inb_config(PCI_REVISION_ID, dev);
165 card->model = inb_config(PCI_SUBSYSTEM_ID, dev);
167 ahi_pci_add_intserver(&card->interrupt, dev);
169 /* Initialize chip */
170 if (card_init(card) < 0)
172 DebugPrintF("Unable to initialize Card subsystem.\n");
174 success = FALSE;
177 card->interrupt_added = TRUE;
179 card->card_initialized = TRUE;
180 card->input = 0;
181 card->output = 0;
182 card->monitor_volume = (unsigned long) (0x10000 * pow (10.0, -6.0 / 20.0)); // -6 dB
183 card->input_gain = 0x10000; // 0dB
184 card->output_volume = 0x10000; // 0dB
186 if (success)
188 set_monitor_volumes(card, -6.0); // -6dB monitor volume
190 //AddResetHandler(card);
193 if (!success)
195 FreeDriverData(card, AHIsubBase);
196 card = NULL;
199 return card;
203 /******************************************************************************
204 ** DriverData deallocation ****************************************************
205 ******************************************************************************/
207 void FreeDriverData(struct HDAudioChip* card, struct DriverBase* AHIsubBase)
209 if (card != NULL)
211 if (card->pci_dev != NULL)
213 if (card->card_initialized)
215 card_cleanup(card);
218 if (card->pci_master_enabled)
220 UWORD cmd;
222 cmd = inw_config(PCI_COMMAND, card->pci_dev);
223 cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
224 outw_config(PCI_COMMAND, cmd, card->pci_dev);
228 if (card->interrupt_added)
230 ahi_pci_rem_intserver(&card->interrupt, card->pci_dev);
233 FreeVec(card);
239 int card_init(struct HDAudioChip *card)
241 struct PCIDevice *dev = (struct PCIDevice *) card->pci_dev;
242 UWORD uwval;
243 unsigned char pval, byt;
244 long *ptr;
245 int i;
247 if (reset_chip(card) == FALSE)
249 bug("Reset chip failed\n");
250 return -1;
253 // 4.3 Codec discovery: 15 codecs can be connected, bits that are on indicate a codec
254 card->codecbits = pci_inw(HD_STATESTS, card);
256 if (card->codecbits == 0)
258 bug("No codecs found!\n");
259 return -1;
262 if (alloc_streams(card) == FALSE)
264 bug("Allocating streams failed!\n");
265 return -1;
268 if (allocate_corb(card) == FALSE)
270 bug("Allocating CORB failed!\n");
271 return -1;
274 if (allocate_rirb(card) == FALSE)
276 bug("Allocating RIRB failed!\n");
277 return -1;
280 if (allocate_pos_buffer(card) == FALSE)
282 bug("Allocating position buffer failed!\n");
283 return -1;
286 // enable interrupts
287 pci_outl(HD_INTCTL_CIE | HD_INTCTL_GLOBAL, HD_INTCTL, card);
288 udelay(200);
290 /* Find the first codec with an audio function group */
291 for (i = 0; i < 16; i++)
293 if (card->codecbits & (1 << i))
295 card->codecnr = i;
296 if (power_up_all_nodes(card))
297 break;
301 if (perform_codec_specific_settings(card) == FALSE)
303 return -1;
306 if (dumpAll)
308 codec_discovery(card);
311 bug("card_init() was a success!\n");
313 return 0;
317 void card_cleanup(struct HDAudioChip *card)
322 static BOOL reset_chip(struct HDAudioChip *card)
324 int counter = 0;
325 UBYTE ubval = 0;
326 UWORD uwval = 0;
327 int count;
328 UBYTE tcsel;
331 Intel® HIgh Definition Audio Traffic Class Assignment (TCSEL), bits 0:2 -> 000 = TC0
332 This register assigned the value to be placed in the TC field. CORB and RIRB data will always be
333 assigned TC0.
335 #define TCSEL_PCIREG 0x44
336 tcsel = inb_config(TCSEL_PCIREG, card->pci_dev);
337 tcsel &= ~0x07;
338 outb_config(TCSEL_PCIREG, tcsel, card->pci_dev);
340 pci_outb(0, HD_CORBCTL, card);
341 pci_outb(0, HD_RIRBCTL, card);
343 // Clear STATESTS just to be sure. After reset, this register holds the ID's of the connected codecs
344 pci_outb(0xFF, HD_STATESTS, card);
346 // Transition to reset state
347 outl_clearbits(1, HD_GCTL, card);
349 // Wait for bit 0 to read 0
350 for (counter = 0; counter < 1000; counter++)
352 ubval = pci_inb(HD_GCTL, card);
354 if ((ubval & 0x1) == 0)
356 break;
359 udelay(100);
362 if (counter == 1000)
364 bug("Couldn't reset chip!\n");
365 return FALSE;
368 udelay(100);
369 // 4.2.2. Take controller out of reset
370 outl_setbits(1, HD_GCTL, card);
373 // Wait for bit 0 to read 1
374 for (counter = 0; counter < 1000; counter++)
376 ubval = pci_inb(HD_GCTL, card);
378 if ((ubval & 0x1) == 1)
380 bug("Codec came out of reset!\n");
381 break;
384 udelay(100);
387 if (counter == 1000)
389 bug("Couldn't reset chip!\n");
390 return FALSE;
393 // The software must wait 250 microseconds after reading CRST as 1, but it's suggested to wait longer
394 udelay(1000);
396 // do not accept unsolicited events for now (jack sense etc.)
397 //outl_setbits((1 << 8), HD_GCTL, card); // accept unsolicited events
399 return TRUE;
403 void codec_discovery(struct HDAudioChip *card)
405 int i;
406 ULONG node_count_response = get_parameter(0, VERB_GET_PARMS_NODE_COUNT, card);
407 UBYTE node_count = node_count_response & 0xFF;
408 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
409 bug("Node count = %x, starting_node = %x\n", node_count, starting_node);
411 for (i = 0; i < node_count; i++)
413 ULONG function_group_response = get_parameter(starting_node + i, VERB_GET_PARMS_FUNCTION_GROUP_TYPE, card);
414 UBYTE function_group = function_group_response & 0xFF;
415 //bug("Function group = %x, UnSol cap = %x\n", function_group, (function_group_response >> 8) & 0x1);
417 if (function_group == AUDIO_FUNCTION)
419 int j;
421 ULONG subnode_count_response = get_parameter(starting_node + i, VERB_GET_PARMS_NODE_COUNT, card);
422 UBYTE subnode_count = subnode_count_response & 0xFF;
423 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
424 ULONG connections = 0;
425 bug("Subnode count = %d, sub_starting_node = %x\n", subnode_count, sub_starting_node);
427 //bug("Audio supported = %lx\n", get_parameter(starting_node + i, 0xA, card));
428 //bug("Sup streams = %lx\n", get_parameter(starting_node + i, 0xB, card));
430 for (j = 0; j < subnode_count; j++) // widgets
432 const ULONG NID = j + sub_starting_node;
433 ULONG widget_caps;
435 widget_caps = get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
437 //if ((NID == 0x18) || (NID == 0xB))
439 bug("Subnode %x has caps %lx\n", NID, widget_caps);
440 bug("%xh: Supported PCM size/rate = %lx\n", NID, get_parameter(NID, VERB_GET_PARMS_SUPPORTED_PCM_SIZE_RATE, card));
442 if (AUDIO_WIDGET_CAPS(widget_caps) == 0x4) // pin complex
444 ULONG config_default = 0;
446 bug("PIN: caps = %lx\n", get_parameter(NID, VERB_GET_PARMS_PIN_CAPS, card));
447 config_default = send_command_12(card->codecnr, NID, VERB_GET_CONFIG_DEFAULT, 0, card);
449 bug("PIN: Config default = %lx\n", config_default);
451 bug("PIN: Connected = %s\n", is_jack_connected(card, NID) ? "TRUE" : "FALSE");
454 bug("%xh: Input Amp caps = %lx\n", NID, get_parameter(NID, 0xD, card));
455 bug("%xh: Output Amp caps = %lx\n", NID, get_parameter(NID, 0x12, card));
457 connections = get_parameter(NID, 0xE, card);
458 bug("%xh: Conn list len = %lx\n", NID, connections);
459 if (connections > 0) // print connections
461 ULONG entry = 0;
463 for (entry = 0; entry < connections; entry+=4)
465 ULONG connectedTo = send_command_12(card->codecnr, NID, VERB_GET_CONNECTION_LIST_ENTRY, entry, card);
467 bug("%lx, ", connectedTo);
469 bug("\n");
472 bug("%xh: Supported power state = %lx\n", NID, get_parameter(NID, 0xF, card));
474 bug("%xh: Connection selection = %lx\n", NID, send_command_12(card->codecnr, NID, VERB_GET_CONNECTION_SELECT, 0, card));
476 bug("%xh: Output Amp gain = %lx\n", NID, send_command_4(card->codecnr, NID, 0xB, 0x8000, card));
477 bug("%xh: Input Amp gain = %lx\n", NID, send_command_4(card->codecnr, NID, 0xB, 0x0000, card));
478 bug("%xh: Format = %lx\n", NID, send_command_4(card->codecnr, NID, 0xA, 0, card));
479 bug("%xh: Power state = %lx\n", NID, send_command_12(card->codecnr, NID, 0xF05, 0, card));
480 bug("%xh: Stream = %lx\n", NID, send_command_12(card->codecnr, NID, 0xF06, 0, card));
481 bug("%xh: Pin widget control = %lx\n", NID, send_command_12(card->codecnr, NID, 0xF07, 0, card));
482 bug("--------------------------------\n\n");
490 static BOOL power_up_all_nodes(struct HDAudioChip *card)
492 int i;
493 ULONG node_count_response = get_parameter(0, VERB_GET_PARMS_NODE_COUNT, card);
494 UBYTE node_count = node_count_response & 0xFF;
495 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
496 BOOL audio_found = FALSE;
498 bug("power up\n");
499 send_command_12(card->codecnr, 1, VERB_SET_POWER_STATE , 0, card); // send function reset to audio node, this should power up all nodes
500 udelay(20000);
502 for (i = 0; i < node_count; i++)
504 ULONG function_group_response = get_parameter(starting_node + i, VERB_GET_PARMS_FUNCTION_GROUP_TYPE, card);
505 UBYTE function_group = function_group_response & 0xFF;
507 if (function_group == AUDIO_FUNCTION)
509 int j;
511 ULONG subnode_count_response = get_parameter(starting_node + i, VERB_GET_PARMS_NODE_COUNT, card);
512 UBYTE subnode_count = subnode_count_response & 0xFF;
513 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
514 ULONG connections = 0;
516 audio_found = TRUE;
518 for (j = 0; j < subnode_count; j++) // widgets
520 const ULONG NID = j + sub_starting_node;
521 ULONG widget_caps;
523 widget_caps = get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
526 if (AUDIO_WIDGET_POWER_CONTROL(widget_caps) == 1) // power control
528 ULONG power_state = 0;
530 power_state = send_command_12(card->codecnr, NID, VERB_GET_POWER_STATE , 0, card);
531 bug("%xh: power state = %xh\n", NID, power_state);
533 if (power_state != 0)
535 bug("Setting power state to 0\n");
536 send_command_12(card->codecnr, NID, VERB_SET_POWER_STATE , 0, card);
544 return audio_found;
548 // allocates memory on the given boundary. Returns the aligned memory address and the non-aligned memory address
549 // in NonAlignedAddress, if not NULL.
550 void *pci_alloc_consistent(size_t size, APTR *NonAlignedAddress, unsigned int boundary)
552 void* address;
553 unsigned long a;
555 address = (void *) AllocVec(size + boundary, MEMF_PUBLIC | MEMF_CLEAR);
557 if (address != NULL)
559 a = (unsigned long) address;
560 a = (a + boundary - 1) & ~(boundary - 1);
561 address = (void *) a;
564 if (NonAlignedAddress)
566 *NonAlignedAddress = address;
569 return address;
573 void pci_free_consistent(void* addr)
575 FreeVec(addr);
579 ULONG get_parameter(UBYTE node, UBYTE parameter, struct HDAudioChip *card)
581 return send_command_12(card->codecnr, node, VERB_GET_PARMS, parameter, card);
585 ULONG send_command_4(UBYTE codec, UBYTE node, UBYTE verb, UWORD payload, struct HDAudioChip *card)
587 UWORD wp = pci_inw(HD_CORBWP, card) & 0xFF;
588 ULONG data = (codec << 28) | (node << 20) | (verb << 16) | payload;
590 if (wp == card->corb_entries - 1)
592 wp = 0;
594 else
596 wp++;
599 //bug("Sending command %lx\n", data);
601 card->corb[wp] = data;
602 pci_outw(wp, HD_CORBWP, card);
604 return get_response(card);
608 ULONG send_command_12(UBYTE codec, UBYTE node, UWORD verb, UBYTE payload, struct HDAudioChip *card)
610 UWORD wp = pci_inw(HD_CORBWP, card) & 0xFF;
611 ULONG data = (codec << 28) | (node << 20) | (verb << 8) | payload;
613 if (wp == card->corb_entries - 1)
615 wp = 0;
617 else
619 wp++;
622 //bug("Sending command %lx\n", data);
624 card->corb[wp] = data;
625 pci_outw(wp, HD_CORBWP, card);
627 return get_response(card);
631 ULONG get_response(struct HDAudioChip *card)
633 int timeout = 10000;
634 int i;
635 UBYTE rirb_wp;
637 udelay(20); //
639 // wait for interrupt
640 for (i = 0; i < timeout; i++)
642 if (card->rirb_irq > 0)
644 card->rirb_irq--;
645 break;
647 udelay(10);
650 if (i == timeout)
652 bug("No IRQ!\n");
655 for (i = 0; i < timeout; i++)
657 rirb_wp = pci_inb(HD_RIRBWP, card);
659 if (rirb_wp == card->rirb_rp) // strange, we expect the wp to have increased
661 bug("WP has not increased! rirb_wp = %u, rirb_rp = %lu\n", rirb_wp, card->rirb_rp);
662 udelay(5000);
664 else
666 if ( ((rirb_wp > card->rirb_rp) &&
667 ((rirb_wp - card->rirb_rp) >= 2)) ||
669 ((rirb_wp < card->rirb_rp) &&
670 ( ((int) rirb_wp) + card->rirb_entries) - card->rirb_rp >= 2))
672 bug("Write pointer is more than 1 step ahead!\n");
675 ULONG addr;
676 ULONG response, response_ex; // 3.6.5 Response Input Ring Buffer
678 card->rirb_rp = rirb_wp;
679 addr = card->rirb_rp;
680 addr *= 2; // 64-bit entries
682 response = card->rirb[addr];
683 response_ex = card->rirb[addr + 1];
684 if (response_ex & 0x10) // unsolicited
686 bug("Unsolicited response! Skipping!\n");
688 else
690 //bug("Response is %lx\n", response);
691 return response;
696 bug("ERROR in get_response() card->rirb_rp = %u!rirb_wp = %u\n", card->rirb_rp, rirb_wp);
697 return 0;
701 static BOOL allocate_corb(struct HDAudioChip *card)
703 UBYTE corbsize_reg;
705 // 4.4.1.3 Initialize the CORB
707 // stop the DMA
708 outb_clearbits(HD_CORBRUN, HD_CORBCTL, card);
710 // set CORB size
711 corbsize_reg = pci_inb(HD_CORBSIZE, card);
712 if (corbsize_reg & (1 << 6))
714 pci_outb(0x2, HD_CORBSIZE, card);
715 card->corb_entries = 256;
717 else if (corbsize_reg & (1 << 5))
719 pci_outb(0x1, HD_CORBSIZE, card);
720 card->corb_entries = 16;
722 else if (corbsize_reg & (1 << 4))
724 pci_outb(0x0, HD_CORBSIZE, card);
725 card->corb_entries = 2;
728 // Allocate CORB memory
729 card->corb = pci_alloc_consistent(4 * card->corb_entries, NULL, 128); // todo: virtual
731 // Set CORB base
732 pci_outl((ULONG) card->corb, HD_CORB_LOW, card);
733 pci_outl(0, HD_CORB_HIGH, card);
735 //bug("Before reset rp: corbrp = %x\n", pci_inw(0x4A, card));
737 // Reset read pointer: if we set this, the CORB will not work??
738 //outw_setbits(HD_CORBRPRST, HD_CORBRP, card);
740 //bug("After reset rp: corbrp = %x\n", pci_inw(0x4A, card));
742 // Write a 0 to the write pointer to clear
743 pci_outw(0, HD_CORBWP, card);
745 // run it
746 outb_setbits(HD_CORBRUN, HD_CORBCTL, card);
748 if (card->corb)
750 return TRUE;
752 else
754 return FALSE;
759 static BOOL allocate_rirb(struct HDAudioChip *card)
761 UBYTE rirbsize_reg;
763 // 4.4.2.2 Initialize the RIRB
765 // stop the DMA
766 outb_clearbits(HD_RIRBRUN, HD_RIRBCTL, card);
768 // set rirb size
769 rirbsize_reg = pci_inb(HD_RIRBSIZE, card);
770 if (rirbsize_reg & (1 << 6))
772 pci_outb(0x2, HD_RIRBSIZE, card);
773 card->rirb_entries = 256;
775 else if (rirbsize_reg & (1 << 5))
777 pci_outb(0x1, HD_RIRBSIZE, card);
778 card->rirb_entries = 16;
780 else if (rirbsize_reg & (1 << 4))
782 pci_outb(0x0, HD_RIRBSIZE, card);
783 card->rirb_entries = 2;
786 card->rirb_irq = 0;
788 // Allocate rirb memory
789 card->rirb = pci_alloc_consistent(4 * 2 * card->rirb_entries, NULL, 128); // todo: virtual
790 card->rirb_rp = 0;
792 // Set rirb base
793 pci_outl((ULONG) card->rirb, HD_RIRB_LOW, card);
794 pci_outl(0, HD_RIRB_HIGH, card);
796 // Reset read pointer: if we set this, it will not come out of reset??
797 //outw_setbits(HD_RIRBWPRST, HD_RIRBWP, card);
799 // Set N=1, which generates an interrupt for every response
800 pci_outw(1, HD_RINTCNT, card);
802 pci_outb(0x5, HD_RIRBSTS, card);
804 // run it and enable IRQ
805 outb_setbits(HD_RIRBRUN | HD_RINTCTL | 0x4, HD_RIRBCTL, card);
807 if (card->rirb)
809 return TRUE;
811 else
813 return FALSE;
819 static BOOL allocate_pos_buffer(struct HDAudioChip *card)
821 card->dma_position_buffer = pci_alloc_consistent(sizeof(APTR) * 36, NULL, 128);
822 //pci_outl((ULONG) card->dma_position_buffer | HD_DPLBASE_ENABLE, HD_DPLBASE, card);
823 pci_outl(0, HD_DPUBASE, card);
825 if (card->dma_position_buffer)
827 return TRUE;
829 else
831 return FALSE;
836 static BOOL alloc_streams(struct HDAudioChip *card)
838 int i;
839 card->nr_of_input_streams = (pci_inw(HD_GCAP, card) & HD_GCAP_ISS_MASK) >> 8;
840 card->nr_of_output_streams = (pci_inw(HD_GCAP, card) & HD_GCAP_OSS_MASK) >> 12;
841 card->nr_of_streams = card->nr_of_input_streams + card->nr_of_output_streams;
842 //bug("Streams in = %d, out = %d\n", card->nr_of_input_streams, card->nr_of_output_streams);
844 card->streams = (struct Stream *) AllocVec(sizeof(struct Stream) * card->nr_of_streams, MEMF_PUBLIC | MEMF_CLEAR);
846 for (i = 0; i < card->nr_of_streams; i++)
848 card->streams[i].bdl = NULL;
849 card->streams[i].bdl_nonaligned_addresses = NULL;
850 card->streams[i].sd_reg_offset = HD_SD_BASE_OFFSET + HD_SD_DESCRIPTOR_SIZE * i;
851 card->streams[i].index = i;
852 card->streams[i].tag = i + 1;
853 card->streams[i].fifo_size = pci_inw(card->streams[i].sd_reg_offset + HD_SD_OFFSET_FIFO_SIZE, card);
855 // clear the descriptor error, fifo error and buffer completion interrupt status flags
856 pci_outb(HD_SD_STATUS_MASK, card->streams[i].sd_reg_offset + HD_SD_OFFSET_STATUS, card);
859 if (card->streams)
861 return TRUE;
863 else
865 return FALSE;
870 /*static ULONG ResetHandler(struct ExceptionContext *ctx, struct ExecBase *pExecBase, struct HDAudioChip *card)
872 struct PCIDevice *dev = card->pci_dev;
874 return 0UL;
878 void AddResetHandler(struct HDAudioChip *card)
880 static struct Interrupt interrupt;
882 interrupt.is_Code = (void (*)())ResetHandler;
883 interrupt.is_Data = (APTR) card;
884 interrupt.is_Node.ln_Pri = 0;
885 interrupt.is_Node.ln_Type = NT_EXTINTERRUPT;
886 interrupt.is_Node.ln_Name = "reset handler";
888 AddResetCallback(&interrupt);
892 static BOOL perform_codec_specific_settings(struct HDAudioChip *card)
894 BOOL found = FALSE;
895 ULONG vendor_device_id = get_parameter(0x0, VERB_GET_PARMS_VENDOR_DEVICE, card); // get vendor and device ID from root node
896 UBYTE old;
897 UWORD vendor = (vendor_device_id >> 16);
898 UWORD device = (vendor_device_id & 0xFFFF);
900 card->frequencies = NULL;
901 card->nr_of_frequencies = 0;
902 card->selected_freq_index = 0;
904 card->dac_min_gain = -64.0;
905 card->dac_max_gain = 0;
906 card->dac_step_gain = 1.0;
907 card->speaker_nid = 255; // off
908 card->headphone_nid = 255; // off
909 card->speaker_active = FALSE;
910 bug("vendor = %x, device = %x\n", vendor, device);
912 if (vendor == 0x10EC && forceQuery == FALSE) // Realtek
914 found = perform_realtek_specific_settings(card, device);
916 else if (vendor == 0x1106 && forceQuery == FALSE) // VIA
918 found = perform_via_specific_settings(card, device);
920 else if (vendor == 0x111d /*&& forceQuery == FALSE*/) // IDT
922 found = perform_idt_specific_settings(card, device);
925 if (!found) // default: fall-back
927 if (interrogate_unknown_chip(card) == FALSE)
929 return FALSE;
933 determine_frequencies(card);
934 return TRUE;
938 static BOOL perform_realtek_specific_settings(struct HDAudioChip *card, UWORD device)
940 bug("Found Realtek codec\n");
942 if (!(device == 0x662
943 || device == 0x663
944 || device == 0x268
945 || device == 0x269
946 || device == 0x888))
948 bug("Unknown Realtek codec.\n");
949 return FALSE;
952 card->dac_nid = 0x2;
953 card->dac_volume_nid = 0x2;
954 card->adc_nid = 0x8;
956 card->adc_mixer_nid = 0x23;
957 card->line_in_nid = 0x1A;
958 card->mic1_nid = 0x18;
959 card->mic2_nid = 0x19;
960 card->cd_nid = 0x1C;
962 card->adc_mixer_is_mux = FALSE;
964 // FRONT pin (0x14)
965 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)
967 send_command_12(card->codecnr, 0x14, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
968 card->speaker_active = TRUE;
970 // MIC1 pin (0x18) as input
971 send_command_12(card->codecnr, card->mic1_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
973 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
976 // device specific support
977 if (device == 0x662 || device == 0x663) // Realtek ALC662/663
979 bug("Adding ALC662/663 specific support\n");
981 card->adc_mixer_indices[0] = 2; // line in
982 card->adc_mixer_indices[1] = 0; // mic1
983 card->adc_mixer_indices[2] = 1; // mic2
984 card->adc_mixer_indices[3] = 4; // cd
985 card->adc_mixer_indices[4] = 8; // mon mixer
987 card->adc_min_gain = -13.5;
988 card->adc_max_gain = 33.0;
989 card->adc_step_gain = 1.5;
991 // LINE2 pin (0x1B) as second front output (duplicates sound of 0xC (front DAC))
992 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)
994 send_command_12(card->codecnr, 0x1B, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
996 // Monitor mixer (0xB): set the first 3 inputs to 0dB and unmute them
997 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
999 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
1001 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
1003 // Front DAC (0xC)
1004 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1006 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
1008 // LINE1 pin (0x1A) as input
1009 send_command_12(card->codecnr, card->line_in_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1011 // MIC2 pin (0x19) as input
1012 send_command_12(card->codecnr, card->mic2_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1014 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
1016 else if (device == 0x268)
1018 bug("Adding ALC268 specific support\n");
1020 card->speaker_nid = 0x14;
1021 card->headphone_nid = 0x15;
1023 card->adc_mixer_indices[0] = 2; // line in
1024 card->adc_mixer_indices[1] = 0; // mic1
1025 card->adc_mixer_indices[2] = 5; // mic2
1026 card->adc_mixer_indices[3] = 3; // cd
1027 card->adc_mixer_indices[4] = 255; // no mon mixer
1029 card->adc_min_gain = -16.5;
1030 card->adc_max_gain = 30.0;
1031 card->adc_step_gain = 1.5;
1033 card->adc_mixer_is_mux = TRUE;
1035 // sum widget before output (0xF)
1036 send_command_4(card->codecnr, 0xF, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute
1038 // sum widget before headphone output (0x10)
1039 send_command_4(card->codecnr, 0x10, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (2 << 8), card); // unmute
1041 // HP-OUT pin (0x15)
1042 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)
1044 send_command_12(card->codecnr, 0x15, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1046 send_command_12(card->codecnr, 0x14, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1048 send_command_12(card->codecnr, 0x15, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1050 else if (device == 0x269) // Dell mini etc.
1052 bug("Adding ALC269 specific support\n");
1054 card->speaker_nid = 0x14;
1055 card->headphone_nid = 0x15;
1057 card->adc_mixer_indices[0] = 2; // line in
1058 card->adc_mixer_indices[1] = 0; // mic1
1059 card->adc_mixer_indices[2] = 1; // mic2
1060 card->adc_mixer_indices[3] = 4; // cd
1061 card->adc_mixer_indices[4] = 6; // mon mixer
1063 card->adc_min_gain = -17;
1064 card->adc_max_gain = 29.0;
1065 card->adc_step_gain = 1.0;
1067 card->adc_mixer_is_mux = TRUE;
1069 // Front DAC (0xC)
1070 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1072 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
1074 // sum widget before output (0xF)
1075 send_command_4(card->codecnr, 0xF, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute
1077 // sum widget before headphone output (0x10)
1078 send_command_4(card->codecnr, 0x10, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (2 << 8), card); // unmute
1080 // HP-OUT pin (0x15)
1081 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)
1083 send_command_12(card->codecnr, 0x15, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1085 send_command_12(card->codecnr, 0x14, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1087 send_command_12(card->codecnr, 0x15, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1089 else if (device == 0x888) // ALC888
1091 bug("Adding ALC888 specific support\n");
1093 card->adc_mixer_indices[0] = 2; // line in
1094 card->adc_mixer_indices[1] = 0; // mic1
1095 card->adc_mixer_indices[2] = 1; // mic2
1096 card->adc_mixer_indices[3] = 4; // cd
1097 card->adc_mixer_indices[4] = 10; // mon mixer
1099 card->adc_min_gain = -16.5;
1100 card->adc_max_gain = 30.0;
1101 card->adc_step_gain = 1.5;
1103 card->dac_min_gain = -46.5;
1104 card->dac_max_gain = 0;
1105 card->dac_step_gain = 1.5;
1107 card->dac_volume_nid = 0xC;
1109 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1110 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
1113 return TRUE;
1117 static BOOL perform_via_specific_settings(struct HDAudioChip *card, UWORD device)
1119 bug("Found VIA codec\n");
1121 if (!(device == 0xE721))
1123 bug("Unknown VIA codec.\n");
1124 return FALSE;
1127 card->dac_nid = 0x10;
1128 card->adc_nid = 0x13;
1130 card->adc_mixer_nid = 0x17;
1131 card->line_in_nid = 0x1B;
1132 card->mic1_nid = 0x1A;
1133 card->mic2_nid = 0x1E;
1134 card->cd_nid = 0x1F;
1136 card->adc_mixer_is_mux = TRUE;
1138 // FRONT pin (0x1C)
1139 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)
1140 send_command_12(card->codecnr, 0x1C, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1142 // MIC1 pin as input
1143 send_command_12(card->codecnr, card->mic1_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1144 send_command_4(card->codecnr, card->mic1_nid, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute input
1147 // device specific support
1148 if (device == 0xE721) // VIA VT1708B
1150 bug("Adding VIA VT1708B specific support\n");
1152 card->adc_mixer_indices[0] = 3; // line in
1153 card->adc_mixer_indices[1] = 2; // mic1
1154 card->adc_mixer_indices[2] = 4; // mic2
1155 card->adc_mixer_indices[3] = 1; // cd
1156 card->adc_mixer_indices[4] = 255; // mon mixer
1158 card->adc_min_gain = -13.5;
1159 card->adc_max_gain = 33.0;
1160 card->adc_step_gain = 1.5;
1163 return TRUE;
1167 IDT specific settings
1169 information: http://www.idt.com/document/92hd75b-datasheet-92hd75-being-discontinued-see-pdn-notice
1171 TODO: input
1174 static BOOL perform_idt_specific_settings(struct HDAudioChip *card, UWORD device)
1176 bug("Found IDT codec\n");
1178 if (!(device == 0x7608))
1180 bug("Unknown IDT codec.\n");
1181 return FALSE;
1184 card->dac_nid = 0x10;
1185 card->adc_nid = 0x12;
1186 card->adc_mixer_nid = 0x1C;
1187 card->dac_volume_nid = 0x10;
1189 card->speaker_nid = 0x0D;
1190 card->headphone_nid = 0x0A;
1192 card->line_in_nid = 0x0B;
1193 card->mic1_nid = 0x0B;
1194 card->mic2_nid = 0x0C;
1195 card->cd_nid = 0x0E; /* no cd but ...*/
1197 card->adc_mixer_is_mux = TRUE;
1199 /* to not to enable headphone and the speaker at the same time */
1200 card->speaker_active = TRUE;
1202 /* enable eapd. Specs says this is spdif out, but this is required */
1203 send_command_12(card->codecnr, 0x1f, VERB_SET_EAPD, 0x2, card);
1205 /* set connections */
1206 send_command_12 (card->codecnr, 0x0f, VERB_SET_CONNECTION_SELECT, 0, card); /* 48QFN specific */
1207 send_command_12 (card->codecnr, 0x0a, VERB_SET_CONNECTION_SELECT, 0, card); /* headset */
1208 send_command_12 (card->codecnr, 0x0d, VERB_SET_CONNECTION_SELECT, 0, card); /* speaker */
1210 /* set output gains */
1211 send_command_4 (card->codecnr, 0x0f, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1212 send_command_4 (card->codecnr, 0x0a, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1213 send_command_4 (card->codecnr, 0x0d, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1215 /* enable outputs */
1216 send_command_12(card->codecnr, 0x0f, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1217 send_command_12(card->codecnr, 0x0a, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1218 send_command_12(card->codecnr, 0x0d, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1220 if (device == 0x7608)
1222 /* move 0x7608 specific stuff here */
1224 /* Not sure about indices */
1225 card->adc_mixer_indices[0] = 3; // line in
1226 card->adc_mixer_indices[1] = 2; // mic1
1227 card->adc_mixer_indices[2] = 4; // mic2
1228 card->adc_mixer_indices[3] = 1; // cd
1229 card->adc_mixer_indices[4] = 255; // no mon mixer
1231 card->adc_min_gain = 0.0;
1232 card->adc_max_gain = 22.5;
1233 card->adc_step_gain = 1.5;
1235 card->dac_min_gain = -95.25;
1236 card->dac_max_gain = 0.0;
1237 card->dac_step_gain = 0.75;
1240 return TRUE;
1244 static BOOL interrogate_unknown_chip(struct HDAudioChip *card)
1246 int dac, front, speaker = -1, steps = 0, offset0dB = 0;
1247 double step_size = 0.25;
1248 ULONG parm;
1250 bug("Unknown codec, interrogating chip...\n");
1252 card->dac_nid = 0x2;
1253 card->dac_volume_nid = 0;
1254 card->adc_nid = 0x8;
1256 card->adc_mixer_nid = 255;
1257 card->line_in_nid = 255;
1258 card->mic1_nid = 255;
1259 card->mic2_nid = 255;
1260 card->cd_nid = 255;
1262 card->adc_mixer_is_mux = FALSE;
1265 // find out the first PCM DAC
1266 dac = find_audio_output(card, 0); // analogue out
1267 bug("DAC NID = %xh\n", dac);
1269 if (dac == -1)
1271 bug("Didn't find DAC!\n");
1272 return FALSE;
1275 card->dac_nid = dac;
1277 parm = get_parameter(dac, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1278 bug("audio widget caps for dac = %lx\n", parm);
1279 if (parm & 0x4) // OutAmpPre
1281 card->dac_volume_nid = dac;
1282 bug("DAC seems to have volume control\n");
1285 // find FRONT pin
1286 front = find_pin_widget_with_encoding(card, 0);
1287 bug("Front PIN = %xh\n", front);
1289 if (front == -1)
1291 bug("Didn't find jack/pin for line output!\n");
1293 else
1295 send_command_4(card->codecnr, front, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute output of FRONT
1296 send_command_12(card->codecnr, front, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1300 // find SPEAKER
1301 if (force_speaker_nid >= 0)
1303 bug("Using speaker nid from config file");
1304 speaker = force_speaker_nid;
1306 else
1308 speaker = find_speaker_nid(card);
1310 bug("Speaker NID = %xh\n", speaker);
1312 if (speaker == -1)
1314 bug("No speaker pin found, continuing anyway!\n");
1316 card->speaker_nid = speaker;
1317 card->headphone_nid = find_headphone_nid(card);
1319 bug("Headphone NID = %xh\n", card->headphone_nid);
1321 if (speaker != -1)
1323 // check if there is a power amp and if so, enable it
1324 if (get_parameter(speaker, VERB_GET_PARMS_PIN_CAPS, card) & PIN_CAPS_EAPD_CAPABLE)
1326 bug("Enabling power amp of speaker\n");
1327 send_command_12(card->codecnr, speaker, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1330 send_command_4(card->codecnr, speaker, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute output
1333 send_command_4(card->codecnr, card->headphone_nid, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute headphone
1334 send_command_12(card->codecnr, card->headphone_nid, VERB_SET_PIN_WIDGET_CONTROL, 0xC0, card); // output enabled and headphone enabled
1336 // check if there is a power amp and if so, enable it
1337 if (get_parameter(card->headphone_nid, VERB_GET_PARMS_PIN_CAPS, card) & PIN_CAPS_EAPD_CAPABLE)
1339 bug("Enabling power amp of headphone port\n");
1340 send_command_12(card->codecnr, card->headphone_nid, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1343 if (speaker != -1)
1345 if (card->headphone_nid != 255 && // headphone found NID and
1346 is_jack_connected(card, card->headphone_nid) == FALSE) // no headphone connected -> switch on the speaker
1348 send_command_12(card->codecnr, speaker, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1349 card->speaker_active = TRUE;
1351 if (card->dac_volume_nid == 0)
1353 bug("Volume NID has not been set yet, so let's see if the speaker has volume control...\n");
1354 parm = get_parameter(speaker, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1355 bug("Audio widget caps for speaker = %lx\n", parm);
1356 if (parm & 0x4) // OutAmpPre
1358 card->dac_volume_nid = speaker;
1359 bug("Speaker seems to have volume control\n");
1361 else
1363 bug("Speaker did not have volume control\n");
1367 else if (card->headphone_nid != 255 && // headphone found NID and
1368 is_jack_connected(card, card->headphone_nid) == TRUE) // headphone connected -> switch off the speaker
1370 //send_command_4(card->codecnr, speaker, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR | (1 << 7), card); // set amplifier gain: mute output
1371 send_command_12(card->codecnr, speaker, VERB_SET_PIN_WIDGET_CONTROL, 0x0, card); // output disabled
1376 UBYTE before_front = 0;
1377 if (front != -1)
1379 // now the hard part: see if the input of FRONT is equal to the DAC NID
1380 before_front = (UBYTE) send_command_12(card->codecnr, front, VERB_GET_CONNECTION_LIST_ENTRY, 0, card);
1382 else if (speaker != -1)
1384 bug("setting before_front to before speaker\n");
1385 if (card->headphone_nid != 255 &&
1386 is_jack_connected(card, card->headphone_nid) == FALSE)
1388 before_front = (UBYTE) send_command_12(card->codecnr, speaker, VERB_GET_CONNECTION_LIST_ENTRY, 0, card);
1390 else // use headphone
1392 before_front = (UBYTE) send_command_12(card->codecnr, card->headphone_nid, VERB_GET_CONNECTION_LIST_ENTRY, 0, card);
1396 if (before_front != dac)
1398 bug("The widget before front (%xh) is not equal to DAC!\n", before_front);
1400 send_command_4(card->codecnr, before_front, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1401 bug("Let's hope it was a mute that now got unmuted!\n");
1403 bug("audio widget caps for before_front= %lx\n", get_parameter(before_front, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card));
1405 if (card->dac_volume_nid == 0) // volume NID not set yet
1407 bug("Checking if before_front has volume control\n");
1408 parm = get_parameter(before_front, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1409 if (parm & 0x4) // OutAmpPre
1411 card->dac_volume_nid = before_front;
1412 bug("before_front seems to have volume control\n");
1414 else
1416 bug("Odd, before_front doesn't seem to have volume control\n");
1420 else
1422 bug("The widget before front or speaker is equal to DAC.\n");
1425 parm = get_parameter(card->dac_volume_nid, VERB_GET_PARMS_OUTPUT_AMP_CAPS , card);
1426 if ((parm & 0x7fffffff) == 0)
1427 parm = get_parameter(0x1, VERB_GET_PARMS_OUTPUT_AMP_CAPS, card);
1428 bug("Output amp caps = %lx\n", parm);
1430 step_size = (((parm >> 16) & 0x7F) + 1) * 0.25;
1431 steps = ((parm >> 8) & 0x7F);
1432 offset0dB = (parm & 0x7F);
1434 card->dac_min_gain = -(offset0dB * step_size);
1435 card->dac_max_gain = card->dac_min_gain + step_size * steps;
1436 card->dac_step_gain = step_size;
1437 bug("Gain step size = %lu * 0.25 dB, max gain = %d\n", (((parm >> 16) & 0x7F) + 1), (int) (card->dac_max_gain));
1439 return TRUE;
1443 static int find_pin_widget_with_encoding(struct HDAudioChip *card, UBYTE encoding)
1445 int i;
1446 ULONG node_count_response = get_parameter(0, VERB_GET_PARMS_NODE_COUNT, card);
1447 UBYTE node_count = node_count_response & 0xFF;
1448 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
1450 for (i = 0; i < node_count; i++)
1452 ULONG function_group_response = get_parameter(starting_node + i, VERB_GET_PARMS_FUNCTION_GROUP_TYPE, card);
1453 UBYTE function_group = function_group_response & 0xFF;
1454 //bug("Function group = %x, UnSol cap = %x\n", function_group, (function_group_response >> 8) & 0x1);
1456 if (function_group == AUDIO_FUNCTION)
1458 int j;
1460 ULONG subnode_count_response = get_parameter(starting_node + i, VERB_GET_PARMS_NODE_COUNT, card);
1461 UBYTE subnode_count = subnode_count_response & 0xFF;
1462 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
1463 ULONG config_default;
1466 for (j = 0; j < subnode_count; j++) // widgets
1468 const ULONG NID = j + sub_starting_node;
1469 ULONG widget_caps;
1471 widget_caps = get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1473 if (((widget_caps >> 20) & 0xF) == 4) // node is a pin widget
1475 config_default = send_command_12(card->codecnr, NID, VERB_GET_CONFIG_DEFAULT, 0, card);
1477 if (((config_default >> 20) & 0xF) == encoding)
1479 bug("Config default for NID %x = %x\n", NID, config_default);
1480 return (int) (NID);
1487 return -1;
1491 static int find_speaker_nid(struct HDAudioChip *card)
1493 int i;
1494 ULONG node_count_response = get_parameter(0, VERB_GET_PARMS_NODE_COUNT, card);
1495 UBYTE node_count = node_count_response & 0xFF;
1496 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
1498 for (i = 0; i < node_count; i++)
1500 ULONG function_group_response = get_parameter(starting_node + i, VERB_GET_PARMS_FUNCTION_GROUP_TYPE, card);
1501 UBYTE function_group = function_group_response & 0xFF;
1502 //bug("Function group = %x, UnSol cap = %x\n", function_group, (function_group_response >> 8) & 0x1);
1504 if (function_group == AUDIO_FUNCTION)
1506 int j;
1508 ULONG subnode_count_response = get_parameter(starting_node + i, VERB_GET_PARMS_NODE_COUNT, card);
1509 UBYTE subnode_count = subnode_count_response & 0xFF;
1510 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
1511 ULONG config_default;
1514 for (j = 0; j < subnode_count; j++) // widgets
1516 const ULONG NID = j + sub_starting_node;
1517 ULONG widget_caps;
1519 widget_caps = get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1521 if (AUDIO_WIDGET_CAPS(widget_caps) == 4) // node is a pin widget
1523 config_default = send_command_12(card->codecnr, NID, VERB_GET_CONFIG_DEFAULT, 0, card);
1525 if ( (((config_default >> 20) & 0xF) == 1) && // the default device/use is a speaker
1526 (((config_default >> 16) & 0xB) == 3)) // connection type is internal
1528 return (int) (NID);
1530 //else bug("Pin widget 0x%x not a speaker: config_default=0x%lx\n", NID, config_default);
1536 return -1;
1540 static int find_headphone_nid(struct HDAudioChip *card)
1542 int i;
1543 ULONG node_count_response = get_parameter(0, VERB_GET_PARMS_NODE_COUNT, card);
1544 UBYTE node_count = node_count_response & 0xFF;
1545 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
1547 for (i = 0; i < node_count; i++)
1549 ULONG function_group_response = get_parameter(starting_node + i, VERB_GET_PARMS_FUNCTION_GROUP_TYPE, card);
1550 UBYTE function_group = function_group_response & 0xFF;
1551 //bug("Function group = %x, UnSol cap = %x\n", function_group, (function_group_response >> 8) & 0x1);
1553 if (function_group == AUDIO_FUNCTION)
1555 int j;
1557 ULONG subnode_count_response = get_parameter(starting_node + i, VERB_GET_PARMS_NODE_COUNT, card);
1558 UBYTE subnode_count = subnode_count_response & 0xFF;
1559 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
1560 ULONG config_default;
1563 for (j = 0; j < subnode_count; j++) // widgets
1565 const ULONG NID = j + sub_starting_node;
1566 ULONG widget_caps;
1568 widget_caps = get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1570 if (AUDIO_WIDGET_CAPS(widget_caps) == 4) // node is a pin widget
1572 config_default = send_command_12(card->codecnr, NID, VERB_GET_CONFIG_DEFAULT, 0, card);
1574 if ( (((config_default >> 20) & 0xF) == 2) && // the default device/use is a headphone output
1575 (((config_default >> 16) & 0xF) == 1) ) // connection type is mini-jack
1577 return (int) (NID);
1584 return -1;
1588 static int find_audio_output(struct HDAudioChip *card, UBYTE digital)
1590 int i;
1591 ULONG node_count_response = get_parameter(0, VERB_GET_PARMS_NODE_COUNT, card);
1592 UBYTE node_count = node_count_response & 0xFF;
1593 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
1595 for (i = 0; i < node_count; i++)
1597 ULONG function_group_response = get_parameter(starting_node + i, VERB_GET_PARMS_FUNCTION_GROUP_TYPE, card);
1598 UBYTE function_group = function_group_response & 0xFF;
1599 //bug("Function group = %x, UnSol cap = %x\n", function_group, (function_group_response >> 8) & 0x1);
1601 if (function_group == AUDIO_FUNCTION)
1603 int j;
1605 ULONG subnode_count_response = get_parameter(starting_node + i, VERB_GET_PARMS_NODE_COUNT, card);
1606 UBYTE subnode_count = subnode_count_response & 0xFF;
1607 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
1608 ULONG config_default;
1611 for (j = 0; j < subnode_count; j++) // widgets
1613 const ULONG NID = j + sub_starting_node;
1614 ULONG widget_caps;
1616 widget_caps = get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1618 if (((widget_caps >> 20) & 0xF) == 0) // audio output
1620 if ((widget_caps & 0x1) == 1 && // stereo
1621 ((widget_caps >> 9) & 0x1) == digital)
1623 return (int) (NID);
1630 return -1;
1634 static void determine_frequencies(struct HDAudioChip *card)
1636 ULONG verb = get_parameter(card->dac_nid, 0xA, card);
1637 UWORD samplerate_flags = verb & 0x0FFF;
1638 int i;
1639 ULONG freqs = 0;
1640 BOOL default_freq_found = FALSE;
1642 if (samplerate_flags == 0)
1644 verb = get_parameter(0x1, 0xA, card);
1645 samplerate_flags = verb & 0x0FFF;
1646 bug("dac_nid didn't have a list of sample rates, trying AFG node\n");
1649 // count number of frequencies
1650 for (i = 0; i < 12; i++)
1652 if (samplerate_flags & (1 << i))
1654 freqs++;
1658 bug("Frequencies found = %lu\n", freqs);
1659 card->frequencies = (struct Freq *) AllocVec(sizeof(struct Freq) * freqs, MEMF_PUBLIC | MEMF_CLEAR);
1660 card->nr_of_frequencies = freqs;
1662 freqs = 0;
1663 for (i = 0; i < 12; i++)
1665 if (samplerate_flags & (1 << i))
1667 set_frequency_info(&(card->frequencies[freqs]), i);
1669 if (card->frequencies[freqs].frequency == 44100 && !default_freq_found)
1671 card->selected_freq_index = freqs; // set default freq index to 44100 Hz
1672 default_freq_found = TRUE;
1675 freqs++;
1679 if (default_freq_found == FALSE)
1681 bug("44100 Hz is not supported!\n");
1682 if (freqs > 0)
1684 bug("Setting default frequency to %lu\n", card->frequencies[0].frequency);
1685 card->selected_freq_index = 0;
1692 static void set_frequency_info(struct Freq *freq, UWORD bitnr)
1694 switch (bitnr)
1696 case 0: freq->frequency = 8000;
1697 freq->base44100 = 0;
1698 freq->mult = 0;
1699 freq->div = 5;
1700 break;
1702 case 1: freq->frequency = 11025;
1703 freq->base44100 = 1;
1704 freq->mult = 0;
1705 freq->div = 3;
1706 break;
1708 case 2: freq->frequency = 16000;
1709 freq->base44100 = 0;
1710 freq->mult = 0;
1711 freq->div = 2;
1712 break;
1714 case 3: freq->frequency = 22050;
1715 freq->base44100 = 1;
1716 freq->mult = 0;
1717 freq->div = 1;
1718 break;
1720 case 4: freq->frequency = 32000;
1721 freq->base44100 = 0;
1722 freq->mult = 0;
1723 freq->div = 2;
1724 break;
1726 case 5: freq->frequency = 44100;
1727 freq->base44100 = 1;
1728 freq->mult = 0;
1729 freq->div = 0;
1730 break;
1732 case 6: freq->frequency = 48000;
1733 freq->base44100 = 0;
1734 freq->mult = 0;
1735 freq->div = 0;
1736 break;
1738 case 7: freq->frequency = 88200;
1739 freq->base44100 = 1;
1740 freq->mult = 1;
1741 freq->div = 0;
1742 break;
1744 case 8: freq->frequency = 96000;
1745 freq->base44100 = 0;
1746 freq->mult = 1;
1747 freq->div = 0;
1748 break;
1750 case 9: freq->frequency = 176400;
1751 freq->base44100 = 1;
1752 freq->mult = 3;
1753 freq->div = 0;
1754 break;
1756 case 10: freq->frequency = 192000;
1757 freq->base44100 = 0;
1758 freq->mult = 3;
1759 freq->div = 0;
1760 break;
1762 default: bug("Unsupported frequency!\n");
1763 break;
1768 void set_monitor_volumes(struct HDAudioChip *card, double dB)
1770 int i;
1771 int dB_steps = (int) ((dB + 34.5) / 1.5);
1773 if (dB_steps < 0)
1775 dB_steps = 0;
1777 else if (dB_steps > 31)
1779 dB_steps = 31;
1782 for (i = 0; i < 9; i++)
1784 if (i == 0 || i == 1 || i == 2 || i == 4)
1786 send_command_4(card->codecnr, 0xB, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (i << 8) | dB_steps, card);
1788 else // mute
1790 send_command_4(card->codecnr, 0xB, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (i << 8) | (1 << 7), card);
1796 void set_adc_input(struct HDAudioChip *card)
1798 int i;
1800 if (card->input >= INPUTS)
1802 card->input = 0;
1805 if (card->adc_mixer_is_mux == TRUE)
1807 send_command_12(card->codecnr, card->adc_mixer_nid, VERB_SET_CONNECTION_SELECT,
1808 card->adc_mixer_indices[card->input], card);
1809 return;
1811 else
1813 for (i = 0; i < INPUTS; i++)
1815 if (card->adc_mixer_indices[i] != 255) // input is present
1817 if (i == card->input) // unmute or select
1819 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN,
1820 INPUT_AMP_GAIN | AMP_GAIN_LR | (card->adc_mixer_indices[i] << 8), card);
1822 else // mute
1824 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN,
1825 INPUT_AMP_GAIN | AMP_GAIN_LR | (card->adc_mixer_indices[i] << 8) | (1 << 7), card);
1834 void set_adc_gain(struct HDAudioChip *card, double dB)
1836 int i;
1837 int dB_steps = (int) ( (dB - card->adc_min_gain) / card->adc_step_gain);
1839 if (dB_steps < 0)
1841 dB_steps = 0;
1844 if (card->adc_mixer_is_mux == TRUE)
1846 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
1848 else
1850 send_command_4(card->codecnr, card->adc_nid, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
1855 void set_dac_gain(struct HDAudioChip *card, double dB)
1857 int i;
1858 int dB_steps = (int) ( (dB - card->dac_min_gain) / card->dac_step_gain);
1860 if (dB_steps < 0)
1862 dB_steps = 0;
1865 send_command_4(card->codecnr, card->dac_volume_nid, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
1869 void switch_nid_to_input(struct HDAudioChip *card, UBYTE NID)
1871 ULONG data = send_command_12(card->codecnr, NID, VERB_GET_PIN_WIDGET_CONTROL , 0, card);
1873 data |= 0x20; // input enable
1874 data &= ~(0x40); // output disable
1875 send_command_12(card->codecnr, NID, VERB_SET_PIN_WIDGET_CONTROL, data, card);
1879 void switch_nid_to_output(struct HDAudioChip *card, UBYTE NID)
1881 ULONG data = send_command_12(card->codecnr, NID, VERB_GET_PIN_WIDGET_CONTROL , 0, card);
1883 data &= ~(0x20); // input disable
1884 data |= 0x40; // output enable
1885 send_command_12(card->codecnr, NID, VERB_SET_PIN_WIDGET_CONTROL, data, card);
1889 void setForceQuery(void)
1891 forceQuery = TRUE;
1895 void setDumpAll(void)
1897 dumpAll = TRUE;
1901 void setForceSpeaker(int speaker_nid)
1903 force_speaker_nid = speaker_nid;
1908 BOOL is_jack_connected(struct HDAudioChip *card, UBYTE NID)
1910 ULONG result;
1912 send_command_12(card->codecnr, NID, VERB_EXECUTE_PIN_SENSE, 0, card);
1913 udelay(2000);
1914 result = send_command_12(card->codecnr, NID, VERB_GET_PIN_SENSE, 0, card);
1916 if (result & 0x80000000)
1918 //bug("jack connected\n");
1919 return TRUE;
1921 else
1923 //bug("jack disconnected\n");
1924 return FALSE;
1930 void detect_headphone_change(struct HDAudioChip *card)
1932 if (card->speaker_nid != 255 &&
1933 card->headphone_nid != 255)
1935 if (card->speaker_active &&
1936 is_jack_connected(card, card->headphone_nid)) // disable speaker
1938 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x0, card); // output disabled
1939 card->speaker_active = FALSE;
1941 else if (card->speaker_active == FALSE &&
1942 is_jack_connected(card, card->headphone_nid) == FALSE) // enable speaker
1944 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1945 card->speaker_active = TRUE;