grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / devs / AHI / Drivers / HDAudio / misc.c
blob2180b2b07304433480ec6cf1c0394aa8a46dc48e
1 /*
2 The contents of this file are subject to the AROS Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
3 http://www.aros.org/license.html
5 Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
6 ANY KIND, either express or implied. See the License for the specific language governing rights and
7 limitations under the License.
9 (C) Copyright xxxx-2009 Davy Wentzler.
10 (C) Copyright 2009-2010 Stephen Jones.
12 The Initial Developer of the Original Code is Davy Wentzler.
14 All Rights Reserved.
17 #include <config.h>
19 #include <exec/memory.h>
20 #include <proto/expansion.h>
22 #include <proto/dos.h>
23 #ifdef __AROS__
24 #include <aros/debug.h>
25 #endif
26 #include <math.h>
28 #include "library.h"
29 #include "regs.h"
30 #include "interrupt.h"
31 #include "misc.h"
32 #include "pci_wrapper.h"
35 /* Public functions in main.c */
36 static void perform_controller_specific_settings(struct HDAudioChip *card);
37 int card_init(struct HDAudioChip *card);
38 void card_cleanup(struct HDAudioChip *card);
39 static BOOL allocate_corb(struct HDAudioChip *card);
40 static BOOL allocate_rirb(struct HDAudioChip *card);
41 static BOOL allocate_pos_buffer(struct HDAudioChip *card);
42 static BOOL alloc_streams(struct HDAudioChip *card);
43 static BOOL perform_codec_specific_settings(struct HDAudioChip *card);
44 static void determine_frequencies(struct HDAudioChip *card);
45 static void set_frequency_info(struct Freq *freq, UWORD bitnr);
46 static BOOL reset_chip(struct HDAudioChip *card);
47 static ULONG get_response(struct HDAudioChip *card);
48 static BOOL perform_realtek_specific_settings(struct HDAudioChip *card, UWORD device);
49 static BOOL perform_via_specific_settings(struct HDAudioChip *card, UWORD device);
50 static BOOL perform_idt_specific_settings(struct HDAudioChip *card, UWORD device);
51 static void set_gpio(UBYTE mask, struct HDAudioChip *card);
52 static BOOL interrogate_unknown_chip(struct HDAudioChip *card);
53 static UBYTE find_widget(struct HDAudioChip *card, UBYTE type, UBYTE pin_type);
54 static BOOL power_up_all_nodes(struct HDAudioChip *card);
56 struct Device *TimerBase = NULL;
57 struct timerequest *TimerIO = NULL;
58 struct MsgPort *replymp = NULL;
59 static BOOL forceQuery = FALSE;
60 static BOOL dumpAll = FALSE;
61 static int force_speaker_nid = 0;
62 //void AddResetHandler(struct HDAudioChip *card);
65 #ifdef __AROS__
66 #define DebugPrintF bug
67 INTGW(static, void, playbackinterrupt, PlaybackInterrupt);
68 INTGW(static, void, recordinterrupt, RecordInterrupt);
69 INTGW(static, ULONG, cardinterrupt, CardInterrupt);
70 #endif
72 void micro_delay(unsigned int val)
74 replymp = (struct MsgPort *) CreateMsgPort();
75 if (!replymp)
77 D(bug("[HDAudio] Could not create the reply port!\n"));
78 return;
81 TimerIO = (struct timerequest *) CreateIORequest(replymp, sizeof(struct timerequest));
83 if (TimerIO == NULL)
85 D(bug("[HDAudio] Out of memory.\n"));
86 return;
89 if (OpenDevice((CONST_STRPTR) "timer.device", UNIT_MICROHZ, (struct IORequest *) TimerIO, 0) != 0)
91 D(bug("[HDAudio] Unable to open 'timer.device'.\n"));
92 return;
94 else
96 TimerBase = (struct Device *) TimerIO->tr_node.io_Device;
99 TimerIO->tr_node.io_Command = TR_ADDREQUEST; /* Add a request. */
100 TimerIO->tr_time.tv_secs = 0; /* 0 seconds. */
101 TimerIO->tr_time.tv_micro = val; /* 'val' micro seconds. */
102 DoIO((struct IORequest *) TimerIO);
103 CloseDevice((struct IORequest *) TimerIO);
104 DeleteIORequest((struct IORequest *) TimerIO);
105 TimerIO = NULL;
107 if (replymp)
109 DeleteMsgPort(replymp);
114 /******************************************************************************
115 ** DriverData allocation ******************************************************
116 ******************************************************************************/
118 struct HDAudioChip* AllocDriverData(APTR dev, struct DriverBase* AHIsubBase)
120 struct HDAudioChip* card;
121 UWORD command_word;
122 BOOL success = TRUE;
124 card = (struct HDAudioChip *) AllocVec(sizeof(struct HDAudioChip), MEMF_PUBLIC | MEMF_CLEAR);
126 if (card == NULL)
128 Req("Unable to allocate driver structure.");
129 return NULL;
132 card->ahisubbase = AHIsubBase;
134 card->interrupt.is_Node.ln_Type = IRQTYPE;
135 card->interrupt.is_Node.ln_Pri = 0;
136 card->interrupt.is_Node.ln_Name = (char *) LibName;
137 #ifdef __AROS__
138 card->interrupt.is_Code = (void(*)(void)) &cardinterrupt;
139 #else
140 card->interrupt.is_Code = (void(*)(void)) CardInterrupt;
141 #endif
142 card->interrupt.is_Data = (APTR) card;
144 card->playback_interrupt.is_Node.ln_Type = IRQTYPE;
145 card->playback_interrupt.is_Node.ln_Pri = 0;
146 card->playback_interrupt.is_Node.ln_Name = (char *) LibName;
147 #ifdef __AROS__
148 card->playback_interrupt.is_Code = (APTR)&playbackinterrupt;
149 #else
150 card->playback_interrupt.is_Code = PlaybackInterrupt;
151 #endif
152 card->playback_interrupt.is_Data = (APTR) card;
154 card->record_interrupt.is_Node.ln_Type = IRQTYPE;
155 card->record_interrupt.is_Node.ln_Pri = 0;
156 card->record_interrupt.is_Node.ln_Name = (char *) LibName;
157 #ifdef __AROS__
158 card->record_interrupt.is_Code = (APTR)&recordinterrupt;
159 #else
160 card->record_interrupt.is_Code = RecordInterrupt;
161 #endif
162 card->record_interrupt.is_Data = (APTR) card;
164 command_word = inw_config(PCI_COMMAND, dev);
165 command_word |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
166 outw_config(PCI_COMMAND, command_word, dev);
168 card->pci_dev = dev;
169 card->pci_master_enabled = TRUE;
171 card->iobase = ahi_pci_get_base_address(0, dev);
172 card->length = ahi_pci_get_base_size(0, dev);
173 card->chiprev = inb_config(PCI_REVISION_ID, dev);
174 card->model = inb_config(PCI_SUBSYSTEM_ID, dev);
176 perform_controller_specific_settings(card);
178 ahi_pci_add_intserver(&card->interrupt, dev);
180 /* Initialize chip */
181 if (card_init(card) < 0)
183 D(bug("[HDAudio] Unable to initialize Card subsystem.\n"));
185 success = FALSE;
188 card->interrupt_added = TRUE;
190 card->card_initialized = TRUE;
191 card->input = 0;
192 card->output = 0;
193 card->monitor_volume = (unsigned long) (0x10000 * pow (10.0, -6.0 / 20.0)); // -6 dB
194 card->input_gain = 0x10000; // 0dB
195 card->output_volume = 0x10000; // 0dB
197 if (success)
199 set_monitor_volumes(card, -6.0); // -6dB monitor volume
202 if (!success)
204 FreeDriverData(card, AHIsubBase);
205 card = NULL;
208 return card;
212 /******************************************************************************
213 ** DriverData deallocation ****************************************************
214 ******************************************************************************/
216 void FreeDriverData(struct HDAudioChip* card, struct DriverBase* AHIsubBase)
218 if (card != NULL)
220 if (card->pci_dev != NULL)
222 if (card->card_initialized)
224 card_cleanup(card);
227 if (card->pci_master_enabled)
229 UWORD cmd;
231 cmd = inw_config(PCI_COMMAND, card->pci_dev);
232 cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
233 outw_config(PCI_COMMAND, cmd, card->pci_dev);
237 if (card->interrupt_added)
239 ahi_pci_rem_intserver(&card->interrupt, card->pci_dev);
242 FreeVec(card);
246 #define CNT_VEN_ID_ATI_SB 0x437B1002
247 #define CNT_VEN_ID_ATI_SB2 0x43831002
248 #define CNT_VEN_ID_ATI_HUDSON 0x780D1022
249 #define CNT_VEN_ID_NVIDIA 0x10DE
251 /* This is the controller specific portion, for fixes to southbridge */
252 static void perform_controller_specific_settings(struct HDAudioChip *card)
254 ULONG data, subsystem;
255 ULONG mask = (1 << 16) - 1;
257 /* Get vendor/product/subsystem IDs */
258 data = inl_config(0x0, card->pci_dev);
259 D(bug("DEBUG: Controller Vendor ID: %x\n", data));
260 subsystem = inl_config(0x2C, card->pci_dev);
262 /* NVidia is for all nvidia MCP chipsets, create mask to get rid of device ID */
264 /* Check for ATI Southbridge or AMD Hudson controller */
265 if (data == CNT_VEN_ID_ATI_SB || data == CNT_VEN_ID_ATI_SB2 || data == CNT_VEN_ID_ATI_HUDSON)
267 D(bug("[HDAudio] ATI SB/AMD Hudson scontroller detected, setting snoop to on.\n"));
268 data = inb_config(0x42, card->pci_dev);
269 data &= ~0x07;
270 data |= 0x02;
271 outb_config(0x42, data, card->pci_dev);
274 /* Check for NVidia MCP controller */
275 if ((data & mask) == CNT_VEN_ID_NVIDIA )
277 D(bug("[HDAudio] NVidia MCP controller detected, setting snoop to on.\n"));
278 data = inb_config(0x4E, card->pci_dev);
279 data |= 0x0F;
280 outb_config(0x4E, data, card->pci_dev);
282 data = inb_config(0x4D, card->pci_dev);
283 data |= 0x01;
284 outb_config(0x4D, data, card->pci_dev);
286 data = inb_config(0x4C, card->pci_dev);
287 data |= 0x01;
288 outb_config(0x4C, data, card->pci_dev);
291 /* Check for HP Compaq nc6320 laptop */
292 if (subsystem == 0x30aa103c)
294 D(bug("[HDAudio] HP Compaq nc6320 laptop detected, correcting IRQ\n"));
295 data = inb_config(0x3C, card->pci_dev);
296 if (data == 10)
297 outb_config(0x3C, 11, card->pci_dev);
301 int card_init(struct HDAudioChip *card)
303 int i;
305 if (reset_chip(card) == FALSE)
307 D(bug("[HDAudio] Reset chip failed\n"));
308 return -1;
311 // 4.3 Codec discovery: 15 codecs can be connected, bits that are on indicate a codec
312 card->codecbits = pci_inw(HD_STATESTS, card);
314 if (card->codecbits == 0)
316 D(bug("[HDAudio] No codecs found!\n"));
317 return -1;
320 if (alloc_streams(card) == FALSE)
322 D(bug("[HDAudio] Allocating streams failed!\n"));
323 return -1;
326 if (allocate_corb(card) == FALSE)
328 D(bug("[HDAudio] Allocating CORB failed!\n"));
329 return -1;
332 if (allocate_rirb(card) == FALSE)
334 D(bug("[HDAudio] Allocating RIRB failed!\n"));
335 return -1;
338 if (allocate_pos_buffer(card) == FALSE)
340 D(bug("[HDAudio] Allocating position buffer failed!\n"));
341 return -1;
344 // enable interrupts
345 pci_outl(HD_INTCTL_CIE | HD_INTCTL_GLOBAL, HD_INTCTL, card);
346 udelay(200);
348 /* Find the first codec with an audio function group */
349 for (i = 0; i < 16; i++)
351 if (card->codecbits & (1 << i))
353 card->codecnr = i;
354 if (power_up_all_nodes(card))
355 break;
359 if (perform_codec_specific_settings(card) == FALSE)
361 return -1;
364 if (dumpAll)
366 codec_discovery(card);
369 D(bug("[HDAudio] card_init() was a success!\n"));
371 return 0;
375 void card_cleanup(struct HDAudioChip *card)
380 static BOOL reset_chip(struct HDAudioChip *card)
382 int counter = 0;
383 UBYTE ubval = 0;
384 UBYTE tcsel;
387 Intel® HIgh Definition Audio Traffic Class Assignment (TCSEL), bits 0:2 -> 000 = TC0
388 This register assigned the value to be placed in the TC field. CORB and RIRB data will always be
389 assigned TC0.
391 #define TCSEL_PCIREG 0x44
392 tcsel = inb_config(TCSEL_PCIREG, card->pci_dev);
393 tcsel &= ~0x07;
394 outb_config(TCSEL_PCIREG, tcsel, card->pci_dev);
396 pci_outb(0, HD_CORBCTL, card);
397 pci_outb(0, HD_RIRBCTL, card);
399 // Clear STATESTS just to be sure. After reset, this register holds the ID's of the connected codecs
400 pci_outb(0xFF, HD_STATESTS, card);
402 // Transition to reset state
403 outl_clearbits(1, HD_GCTL, card);
405 // Wait for bit 0 to read 0
406 for (counter = 0; counter < 1000; counter++)
408 ubval = pci_inb(HD_GCTL, card);
410 if ((ubval & 0x1) == 0)
412 break;
415 udelay(100);
418 if (counter == 1000)
420 D(bug("[HDAudio] Couldn't reset chip!\n"));
421 return FALSE;
424 udelay(100);
425 // 4.2.2. Take controller out of reset
426 outl_setbits(1, HD_GCTL, card);
429 // Wait for bit 0 to read 1
430 for (counter = 0; counter < 1000; counter++)
432 ubval = pci_inb(HD_GCTL, card);
434 if ((ubval & 0x1) == 1)
436 D(bug("[HDAudio] Codec came out of reset!\n"));
437 break;
440 udelay(100);
443 if (counter == 1000)
445 D(bug("[HDAudio] Couldn't reset chip!\n"));
446 return FALSE;
449 // The software must wait 250 microseconds after reading CRST as 1, but it's suggested to wait longer
450 udelay(1000);
452 // do not accept unsolicited events for now (jack sense etc.)
453 //outl_setbits((1 << 8), HD_GCTL, card); // accept unsolicited events
455 return TRUE;
459 void codec_discovery(struct HDAudioChip *card)
461 int i;
463 ULONG subnode_count_response = get_parameter(card->function_group, VERB_GET_PARMS_NODE_COUNT, card);
464 UBYTE subnode_count = subnode_count_response & 0xFF;
465 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
466 ULONG connections = 0;
468 D(bug("[HDAudio] Subnode count = %d, sub_starting_node = %x\n", subnode_count, sub_starting_node));
470 //D(bug("[HDAudio] Audio supported = %lx\n", get_parameter(card->function_group, 0xA, card)));
471 //D(bug("[HDAudio] Sup streams = %lx\n", get_parameter(card->function_group, 0xB, card)));
473 for (i = 0; i < subnode_count; i++) // widgets
475 const ULONG NID = i + sub_starting_node;
476 ULONG widget_caps;
478 widget_caps = get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
480 //if ((NID == 0x18) || (NID == 0xB))
482 D(bug("[HDAudio] Subnode %x has caps %lx\n", NID, widget_caps));
483 D(bug("[HDAudio] %xh: Supported PCM size/rate = %lx\n", NID, get_parameter(NID, VERB_GET_PARMS_SUPPORTED_PCM_SIZE_RATE, card)));
485 if (AUDIO_WIDGET_CAPS(widget_caps) == 0x4) // pin complex
487 D(bug("[HDAudio] PIN: caps = %lx\n", get_parameter(NID, VERB_GET_PARMS_PIN_CAPS, card)));
488 D(bug("[HDAudio] PIN: Connected = %s\n", is_jack_connected(card, NID) ? "TRUE" : "FALSE"));
491 D(bug("[HDAudio] %xh: Input Amp caps = %lx\n", NID, get_parameter(NID, 0xD, card)));
492 D(bug("[HDAudio] %xh: Output Amp caps = %lx\n", NID, get_parameter(NID, 0x12, card)));
494 connections = get_parameter(NID, 0xE, card);
495 D(bug("[HDAudio] %xh: Conn list len = %lx\n", NID, connections));
496 if (connections > 0) // print connections
498 ULONG entry = 0;
500 for (entry = 0; entry < connections; entry+=4)
502 ULONG connectedTo = send_command_12(card->codecnr, NID, VERB_GET_CONNECTION_LIST_ENTRY, entry, card);
504 bug("%lx, ", connectedTo);
506 bug("\n");
509 D(bug("[HDAudio] %xh: Supported power state = %lx\n", NID, get_parameter(NID, 0xF, card)));
511 D(ULONG n);
512 D(n = send_command_12(card->codecnr, NID, VERB_GET_CONNECTION_SELECT, 0, card));
513 D(bug("[HDAudio] %xh: Connection selection = %lx\n", NID, n));
515 D(n = send_command_4(card->codecnr, NID, 0xB, 0x8000, card));
516 D(bug("[HDAudio] %xh: Output Amp gain = %lx\n", NID, n));
517 D(n = send_command_4(card->codecnr, NID, 0xB, 0x0000, card));
518 D(bug("[HDAudio] %xh: Input Amp gain = %lx\n", NID, n));
519 D(n = send_command_4(card->codecnr, NID, 0xA, 0, card));
520 D(bug("[HDAudio] %xh: Format = %lx\n", NID, n));
521 D(n = send_command_12(card->codecnr, NID, 0xF05, 0, card));
522 D(bug("[HDAudio] %xh: Power state = %lx\n", NID, n));
523 D(n = send_command_12(card->codecnr, NID, 0xF06, 0, card));
524 D(bug("[HDAudio] %xh: Stream = %lx\n", NID, n));
525 D(n = send_command_12(card->codecnr, NID, 0xF07, 0, card));
526 D(bug("[HDAudio] %xh: Pin widget control = %lx\n", NID, n));
527 D(bug("[HDAudio] --------------------------------\n\n"));
533 static BOOL power_up_all_nodes(struct HDAudioChip *card)
535 int i;
536 ULONG node_count_response = get_parameter(0, VERB_GET_PARMS_NODE_COUNT, card);
537 UBYTE node_count = node_count_response & 0xFF;
538 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
539 BOOL audio_found = FALSE;
541 D(bug("[HDAudio] power up\n"));
542 send_command_12(card->codecnr, 1, VERB_SET_POWER_STATE , 0, card); // send function reset to audio node, this should power up all nodes
543 udelay(20000);
545 for (i = 0; i < node_count && !audio_found; i++)
547 ULONG function_group_response = get_parameter(starting_node + i, VERB_GET_PARMS_FUNCTION_GROUP_TYPE, card);
548 UBYTE function_group = function_group_response & 0xFF;
550 if (function_group == AUDIO_FUNCTION)
552 int j;
554 ULONG subnode_count_response = get_parameter(starting_node + i, VERB_GET_PARMS_NODE_COUNT, card);
555 UBYTE subnode_count = subnode_count_response & 0xFF;
556 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
558 audio_found = TRUE;
559 card->function_group = starting_node + i;
561 for (j = 0; j < subnode_count; j++) // widgets
563 const ULONG NID = j + sub_starting_node;
564 ULONG widget_caps;
566 widget_caps = get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
569 if (AUDIO_WIDGET_POWER_CONTROL(widget_caps) == 1) // power control
571 ULONG power_state = 0;
573 power_state = send_command_12(card->codecnr, NID, VERB_GET_POWER_STATE, 0, card);
574 D(bug("[HDAudio] %xh: power state = %xh\n", NID, power_state));
576 if (power_state != 0)
578 D(bug("[HDAudio] Setting power state to 0\n"));
579 send_command_12(card->codecnr, NID, VERB_SET_POWER_STATE, 0, card);
587 return audio_found;
591 // allocates memory on the given boundary. Returns the aligned memory address and the non-aligned memory address
592 // in NonAlignedAddress, if not NULL.
593 void *pci_alloc_consistent(size_t size, APTR *NonAlignedAddress, unsigned int boundary)
595 void* address;
596 unsigned long a;
598 address = (void *) AllocVec(size + boundary, MEMF_PUBLIC | MEMF_CLEAR);
600 if (address != NULL)
602 a = (unsigned long) address;
603 a = (a + boundary - 1) & ~(boundary - 1);
604 address = (void *) a;
607 if (NonAlignedAddress)
609 *NonAlignedAddress = address;
612 return address;
616 void pci_free_consistent(void* addr)
618 FreeVec(addr);
622 ULONG get_parameter(UBYTE node, UBYTE parameter, struct HDAudioChip *card)
624 return send_command_12(card->codecnr, node, VERB_GET_PARMS, parameter, card);
628 ULONG send_command_4(UBYTE codec, UBYTE node, UBYTE verb, UWORD payload, struct HDAudioChip *card)
630 UWORD wp = pci_inw(HD_CORBWP, card) & 0xFF;
631 ULONG data = (codec << 28) | (node << 20) | (verb << 16) | payload;
633 if (wp == card->corb_entries - 1)
635 wp = 0;
637 else
639 wp++;
642 //bug("Sending command %lx\n", data);
644 card->corb[wp] = data;
645 pci_outw(wp, HD_CORBWP, card);
647 return get_response(card);
651 ULONG send_command_12(UBYTE codec, UBYTE node, UWORD verb, UBYTE payload, struct HDAudioChip *card)
653 UWORD wp = pci_inw(HD_CORBWP, card) & 0xFF;
654 ULONG data = (codec << 28) | (node << 20) | (verb << 8) | payload;
656 if (wp == card->corb_entries - 1)
658 wp = 0;
660 else
662 wp++;
665 //bug("Sending command %lx\n", data);
667 card->corb[wp] = data;
668 pci_outw(wp, HD_CORBWP, card);
670 return get_response(card);
674 ULONG get_response(struct HDAudioChip *card)
676 int timeout = 10000;
677 int i;
678 UBYTE rirb_wp;
680 udelay(20); //
682 // wait for interrupt
683 for (i = 0; i < timeout; i++)
685 if (card->rirb_irq > 0)
687 card->rirb_irq--;
688 break;
690 udelay(10);
693 if (i == timeout)
695 D(bug("[HDAudio] No IRQ!\n"));
698 for (i = 0; i < timeout; i++)
700 rirb_wp = pci_inb(HD_RIRBWP, card);
702 if (rirb_wp == card->rirb_rp) // strange, we expect the wp to have increased
704 D(bug("[HDAudio] WP has not increased! rirb_wp = %u, rirb_rp = %lu\n", rirb_wp, card->rirb_rp));
705 udelay(5000);
707 else
709 if ( ((rirb_wp > card->rirb_rp) &&
710 ((rirb_wp - card->rirb_rp) >= 2)) ||
712 ((rirb_wp < card->rirb_rp) &&
713 ( ((int) rirb_wp) + card->rirb_entries) - card->rirb_rp >= 2))
715 D(bug("[HDAudio] Write pointer is more than 1 step ahead!\n"));
718 ULONG addr;
719 ULONG response, response_ex; // 3.6.5 Response Input Ring Buffer
721 card->rirb_rp = rirb_wp;
722 addr = card->rirb_rp;
723 addr *= 2; // 64-bit entries
725 response = card->rirb[addr];
726 response_ex = card->rirb[addr + 1];
727 if (response_ex & 0x10) // unsolicited
729 D(bug("[HDAudio] Unsolicited response! Skipping!\n"));
731 else
733 //bug("Response is %lx\n", response);
734 return response;
739 D(bug("[HDAudio] ERROR in get_response() card->rirb_rp = %u!rirb_wp = %u\n", card->rirb_rp, rirb_wp));
740 return 0;
744 static BOOL allocate_corb(struct HDAudioChip *card)
746 UBYTE corbsize_reg;
748 // 4.4.1.3 Initialize the CORB
750 // stop the DMA
751 outb_clearbits(HD_CORBRUN, HD_CORBCTL, card);
753 // set CORB size
754 corbsize_reg = pci_inb(HD_CORBSIZE, card);
755 if (corbsize_reg & (1 << 6))
757 pci_outb(0x2, HD_CORBSIZE, card);
758 card->corb_entries = 256;
760 else if (corbsize_reg & (1 << 5))
762 pci_outb(0x1, HD_CORBSIZE, card);
763 card->corb_entries = 16;
765 else if (corbsize_reg & (1 << 4))
767 pci_outb(0x0, HD_CORBSIZE, card);
768 card->corb_entries = 2;
771 // Allocate CORB memory
772 card->corb = pci_alloc_consistent(4 * card->corb_entries, NULL, 128); // todo: virtual
774 // Set CORB base
775 pci_outl((ULONG) card->corb, HD_CORB_LOW, card);
776 pci_outl(0, HD_CORB_HIGH, card);
778 //bug("Before reset rp: corbrp = %x\n", pci_inw(0x4A, card));
780 // Reset read pointer: if we set this, the CORB will not work??
781 //outw_setbits(HD_CORBRPRST, HD_CORBRP, card);
783 //bug("After reset rp: corbrp = %x\n", pci_inw(0x4A, card));
785 // Write a 0 to the write pointer to clear
786 pci_outw(0, HD_CORBWP, card);
788 // run it
789 outb_setbits(HD_CORBRUN, HD_CORBCTL, card);
791 if (card->corb)
793 return TRUE;
795 else
797 return FALSE;
802 static BOOL allocate_rirb(struct HDAudioChip *card)
804 UBYTE rirbsize_reg;
806 // 4.4.2.2 Initialize the RIRB
808 // stop the DMA
809 outb_clearbits(HD_RIRBRUN, HD_RIRBCTL, card);
811 // set rirb size
812 rirbsize_reg = pci_inb(HD_RIRBSIZE, card);
813 if (rirbsize_reg & (1 << 6))
815 pci_outb(0x2, HD_RIRBSIZE, card);
816 card->rirb_entries = 256;
818 else if (rirbsize_reg & (1 << 5))
820 pci_outb(0x1, HD_RIRBSIZE, card);
821 card->rirb_entries = 16;
823 else if (rirbsize_reg & (1 << 4))
825 pci_outb(0x0, HD_RIRBSIZE, card);
826 card->rirb_entries = 2;
829 card->rirb_irq = 0;
831 // Allocate rirb memory
832 card->rirb = pci_alloc_consistent(4 * 2 * card->rirb_entries, NULL, 128); // todo: virtual
833 card->rirb_rp = 0;
835 // Set rirb base
836 pci_outl((ULONG) card->rirb, HD_RIRB_LOW, card);
837 pci_outl(0, HD_RIRB_HIGH, card);
839 // Reset read pointer: if we set this, it will not come out of reset??
840 //outw_setbits(HD_RIRBWPRST, HD_RIRBWP, card);
842 // Set N=1, which generates an interrupt for every response
843 pci_outw(1, HD_RINTCNT, card);
845 pci_outb(0x5, HD_RIRBSTS, card);
847 // run it and enable IRQ
848 outb_setbits(HD_RIRBRUN | HD_RINTCTL | 0x4, HD_RIRBCTL, card);
850 if (card->rirb)
852 return TRUE;
854 else
856 return FALSE;
862 static BOOL allocate_pos_buffer(struct HDAudioChip *card)
864 card->dma_position_buffer = pci_alloc_consistent(sizeof(APTR) * 36, NULL, 128);
865 //pci_outl((ULONG) card->dma_position_buffer | HD_DPLBASE_ENABLE, HD_DPLBASE, card);
866 pci_outl(0, HD_DPUBASE, card);
868 if (card->dma_position_buffer)
870 return TRUE;
872 else
874 return FALSE;
879 static BOOL alloc_streams(struct HDAudioChip *card)
881 int i;
882 card->nr_of_input_streams = (pci_inw(HD_GCAP, card) & HD_GCAP_ISS_MASK) >> 8;
883 card->nr_of_output_streams = (pci_inw(HD_GCAP, card) & HD_GCAP_OSS_MASK) >> 12;
884 card->nr_of_streams = card->nr_of_input_streams + card->nr_of_output_streams;
885 //bug("Streams in = %d, out = %d\n", card->nr_of_input_streams, card->nr_of_output_streams);
887 card->streams = (struct Stream *) AllocVec(sizeof(struct Stream) * card->nr_of_streams, MEMF_PUBLIC | MEMF_CLEAR);
889 for (i = 0; i < card->nr_of_streams; i++)
891 card->streams[i].bdl = NULL;
892 card->streams[i].bdl_nonaligned_addresses = NULL;
893 card->streams[i].sd_reg_offset = HD_SD_BASE_OFFSET + HD_SD_DESCRIPTOR_SIZE * i;
894 card->streams[i].index = i;
895 card->streams[i].tag = i + 1;
896 card->streams[i].fifo_size = pci_inw(card->streams[i].sd_reg_offset + HD_SD_OFFSET_FIFO_SIZE, card);
898 // clear the descriptor error, fifo error and buffer completion interrupt status flags
899 pci_outb(HD_SD_STATUS_MASK, card->streams[i].sd_reg_offset + HD_SD_OFFSET_STATUS, card);
902 if (card->streams)
904 return TRUE;
906 else
908 return FALSE;
913 /*static ULONG ResetHandler(struct ExceptionContext *ctx, struct ExecBase *pExecBase, struct HDAudioChip *card)
915 struct PCIDevice *dev = card->pci_dev;
917 return 0UL;
921 void AddResetHandler(struct HDAudioChip *card)
923 static struct Interrupt interrupt;
925 interrupt.is_Code = (void (*)())ResetHandler;
926 interrupt.is_Data = (APTR) card;
927 interrupt.is_Node.ln_Pri = 0;
928 interrupt.is_Node.ln_Type = NT_EXTINTERRUPT;
929 interrupt.is_Node.ln_Name = "reset handler";
931 AddResetCallback(&interrupt);
935 static BOOL perform_codec_specific_settings(struct HDAudioChip *card)
937 BOOL configured = FALSE;
938 ULONG vendor_device_id = get_parameter(0x0, VERB_GET_PARMS_VENDOR_DEVICE, card); // get vendor and device ID from root node
939 UWORD vendor = (vendor_device_id >> 16);
940 UWORD device = (vendor_device_id & 0xFFFF);
942 card->frequencies = NULL;
943 card->nr_of_frequencies = 0;
944 card->selected_freq_index = 0;
946 card->dac_min_gain = -64.0;
947 card->dac_max_gain = 0;
948 card->dac_step_gain = 1.0;
949 card->speaker_nid = 0; // off
950 card->headphone_nid = 0; // off
951 card->speaker_active = FALSE;
953 D(bug("[HDAudio] vendor = %x, device = %x\n", vendor, device));
955 if (vendor == 0x10EC && forceQuery == FALSE) // Realtek
957 configured = perform_realtek_specific_settings(card, device);
959 else if (vendor == 0x1106 && forceQuery == FALSE) // VIA
961 configured = perform_via_specific_settings(card, device);
963 else if (vendor == 0x111d || (vendor == 0x8384 && forceQuery == FALSE)) // IDT
965 configured = perform_idt_specific_settings(card, device);
968 if (!configured) // default: fall-back
970 if (interrogate_unknown_chip(card) == FALSE)
972 return FALSE;
976 determine_frequencies(card);
977 return TRUE;
981 static BOOL perform_realtek_specific_settings(struct HDAudioChip *card, UWORD device)
983 D(bug("[HDAudio] Found Realtek codec\n"));
985 if (!(device == 0x662
986 || device == 0x663
987 || device == 0x268
988 || device == 0x269
989 || device == 0x888))
991 D(bug("[HDAudio] Unknown Realtek codec.\n"));
992 return FALSE;
995 card->dac_nid = 0x2;
996 card->dac_volume_nids[0] = 0x2;
997 card->dac_volume_count = 1;
998 card->adc_nid = 0x8;
1000 card->adc_mixer_nid = 0x23;
1001 card->line_in_nid = 0x1A;
1002 card->mic1_nid = 0x18;
1003 card->mic2_nid = 0x19;
1004 card->cd_nid = 0x1C;
1006 card->adc_mixer_is_mux = FALSE;
1008 // FRONT pin (0x14)
1009 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)
1011 send_command_12(card->codecnr, 0x14, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1012 card->speaker_active = TRUE;
1014 // MIC1 pin (0x18) as input
1015 send_command_12(card->codecnr, card->mic1_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1017 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
1020 // device specific support
1021 if (device == 0x662 || device == 0x663) // Realtek ALC662/663
1023 D(bug("[HDAudio] Adding ALC662/663 specific support\n"));
1025 card->adc_mixer_indices[0] = 2; // line in
1026 card->adc_mixer_indices[1] = 0; // mic1
1027 card->adc_mixer_indices[2] = 1; // mic2
1028 card->adc_mixer_indices[3] = 4; // cd
1029 card->adc_mixer_indices[4] = 8; // mon mixer
1031 card->adc_min_gain = -13.5;
1032 card->adc_max_gain = 33.0;
1033 card->adc_step_gain = 1.5;
1035 // LINE2 pin (0x1B) as second front output (duplicates sound of 0xC (front DAC))
1036 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)
1038 send_command_12(card->codecnr, 0x1B, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1040 // Monitor mixer (0xB): set the first 3 inputs to 0dB and unmute them
1041 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
1043 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
1045 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
1047 // Front DAC (0xC)
1048 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1050 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
1052 // LINE1 pin (0x1A) as input
1053 send_command_12(card->codecnr, card->line_in_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1055 // MIC2 pin (0x19) as input
1056 send_command_12(card->codecnr, card->mic2_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1058 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
1060 else if (device == 0x268)
1062 D(bug("[HDAudio] Adding ALC268 specific support\n"));
1064 card->speaker_nid = 0x14;
1065 card->headphone_nid = 0x15;
1067 card->adc_mixer_indices[0] = 2; // line in
1068 card->adc_mixer_indices[1] = 0; // mic1
1069 card->adc_mixer_indices[2] = 5; // mic2
1070 card->adc_mixer_indices[3] = 3; // cd
1071 card->adc_mixer_indices[4] = 255; // no mon mixer
1073 card->adc_min_gain = -16.5;
1074 card->adc_max_gain = 30.0;
1075 card->adc_step_gain = 1.5;
1077 card->adc_mixer_is_mux = TRUE;
1079 // sum widget before output (0xF)
1080 send_command_4(card->codecnr, 0xF, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute
1082 // sum widget before headphone output (0x10)
1083 send_command_4(card->codecnr, 0x10, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (2 << 8), card); // unmute
1085 // HP-OUT pin (0x15)
1086 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)
1088 send_command_12(card->codecnr, 0x15, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1090 send_command_12(card->codecnr, 0x14, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1092 send_command_12(card->codecnr, 0x15, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1094 else if (device == 0x269) // Dell mini etc.
1096 D(bug("[HDAudio] Adding ALC269 specific support\n"));
1098 card->speaker_nid = 0x14;
1099 card->headphone_nid = 0x15;
1101 card->adc_mixer_indices[0] = 2; // line in
1102 card->adc_mixer_indices[1] = 0; // mic1
1103 card->adc_mixer_indices[2] = 1; // mic2
1104 card->adc_mixer_indices[3] = 4; // cd
1105 card->adc_mixer_indices[4] = 6; // mon mixer
1107 card->adc_min_gain = -17;
1108 card->adc_max_gain = 29.0;
1109 card->adc_step_gain = 1.0;
1111 card->adc_mixer_is_mux = TRUE;
1113 // Front DAC (0xC)
1114 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1116 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
1118 // sum widget before output (0xF)
1119 send_command_4(card->codecnr, 0xF, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute
1121 // sum widget before headphone output (0x10)
1122 send_command_4(card->codecnr, 0x10, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (2 << 8), card); // unmute
1124 // HP-OUT pin (0x15)
1125 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)
1127 send_command_12(card->codecnr, 0x15, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1129 send_command_12(card->codecnr, 0x14, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1131 send_command_12(card->codecnr, 0x15, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1133 else if (device == 0x888) // ALC888
1135 D(bug("[HDAudio] Adding ALC888 specific support\n"));
1137 card->adc_mixer_indices[0] = 2; // line in
1138 card->adc_mixer_indices[1] = 0; // mic1
1139 card->adc_mixer_indices[2] = 1; // mic2
1140 card->adc_mixer_indices[3] = 4; // cd
1141 card->adc_mixer_indices[4] = 10; // mon mixer
1143 card->adc_min_gain = -16.5;
1144 card->adc_max_gain = 30.0;
1145 card->adc_step_gain = 1.5;
1147 card->dac_min_gain = -46.5;
1148 card->dac_max_gain = 0;
1149 card->dac_step_gain = 1.5;
1151 card->dac_volume_nids[0] = 0xC;
1152 card->dac_volume_count = 1;
1154 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1155 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
1158 return TRUE;
1162 static BOOL perform_via_specific_settings(struct HDAudioChip *card, UWORD device)
1164 D(bug("[HDAudio] Found VIA codec\n"));
1166 if (!(device == 0xE721 || device == 0x0397))
1168 D(bug("[HDAudio] Unknown VIA codec.\n"));
1169 return FALSE;
1172 card->dac_nid = 0x10;
1173 card->adc_nid = 0x13;
1175 card->adc_mixer_nid = 0x17;
1176 card->line_in_nid = 0x1B;
1177 card->mic1_nid = 0x1A;
1178 card->mic2_nid = 0x1E;
1179 card->cd_nid = 0x1F;
1181 card->adc_mixer_is_mux = TRUE;
1183 // FRONT pin (0x1C)
1184 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)
1185 send_command_12(card->codecnr, 0x1C, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1187 // MIC1 pin as input
1188 send_command_12(card->codecnr, card->mic1_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1189 send_command_4(card->codecnr, card->mic1_nid, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute input
1192 // device specific support
1193 if (device == 0xE721) // VIA VT1708B
1195 D(bug("[HDAudio] Adding VIA VT1708B specific support\n"));
1197 card->adc_mixer_indices[0] = 3; // line in
1198 card->adc_mixer_indices[1] = 2; // mic1
1199 card->adc_mixer_indices[2] = 4; // mic2
1200 card->adc_mixer_indices[3] = 1; // cd
1201 card->adc_mixer_indices[4] = 255; // mon mixer
1203 card->adc_min_gain = -13.5;
1204 card->adc_max_gain = 33.0;
1205 card->adc_step_gain = 1.5;
1208 return TRUE;
1212 IDT specific settings
1214 information: http://www.idt.com/document/92hd75b-datasheet-92hd75-being-discontinued-see-pdn-notice
1216 TODO: input
1219 static BOOL perform_idt_specific_settings(struct HDAudioChip *card, UWORD device)
1221 D(bug("[HDAudio] Found IDT codec\n"));
1223 if (device == 0x76a0)
1225 D(bug("[HDAudio] STAC9205 detected.\n"));
1227 card->eapd_gpio_mask = 0x1;
1228 set_gpio(card->eapd_gpio_mask, card);
1230 return FALSE;
1233 if (!(device == 0x7608))
1235 D(bug("[HDAudio] Unknown IDT codec.\n"));
1236 return FALSE;
1239 card->dac_nid = 0x10;
1240 card->adc_nid = 0x12;
1241 card->adc_mixer_nid = 0x1C;
1242 card->dac_volume_nids[0] = 0x10;
1243 card->dac_volume_count = 1;
1245 card->speaker_nid = 0x0D;
1246 card->headphone_nid = 0x0A;
1248 card->line_in_nid = 0x0B;
1249 card->mic1_nid = 0x0B;
1250 card->mic2_nid = 0x0C;
1251 card->cd_nid = 0x0E; /* no cd but ...*/
1253 card->adc_mixer_is_mux = TRUE;
1255 /* to not to enable headphone and the speaker at the same time */
1256 card->speaker_active = TRUE;
1258 /* enable eapd. Specs says this is spdif out, but this is required */
1259 send_command_12(card->codecnr, 0x1f, VERB_SET_EAPD, 0x2, card);
1261 /* set connections */
1262 send_command_12 (card->codecnr, 0x0f, VERB_SET_CONNECTION_SELECT, 0, card); /* 48QFN specific */
1263 send_command_12 (card->codecnr, 0x0a, VERB_SET_CONNECTION_SELECT, 0, card); /* headset */
1264 send_command_12 (card->codecnr, 0x0d, VERB_SET_CONNECTION_SELECT, 0, card); /* speaker */
1266 /* set output gains */
1267 send_command_4 (card->codecnr, 0x0f, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1268 send_command_4 (card->codecnr, 0x0a, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1269 send_command_4 (card->codecnr, 0x0d, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1271 /* enable outputs */
1272 send_command_12(card->codecnr, 0x0f, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1273 send_command_12(card->codecnr, 0x0a, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1274 send_command_12(card->codecnr, 0x0d, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1276 if (device == 0x7608)
1278 /* move 0x7608 specific stuff here */
1280 /* Not sure about indices */
1281 card->adc_mixer_indices[0] = 3; // line in
1282 card->adc_mixer_indices[1] = 2; // mic1
1283 card->adc_mixer_indices[2] = 4; // mic2
1284 card->adc_mixer_indices[3] = 1; // cd
1285 card->adc_mixer_indices[4] = 255; // no mon mixer
1287 card->adc_min_gain = 0.0;
1288 card->adc_max_gain = 22.5;
1289 card->adc_step_gain = 1.5;
1291 card->dac_min_gain = -95.25;
1292 card->dac_max_gain = 0.0;
1293 card->dac_step_gain = 0.75;
1296 return TRUE;
1300 static void update_gpio(UBYTE mask, BOOL on, struct HDAudioChip *card)
1302 ULONG gpio_data, gpio_enable, gpio_dir;
1304 gpio_enable = send_command_12(card->codecnr, card->function_group,
1305 VERB_GET_GPIO_ENABLE, 0, card);
1306 gpio_enable |= mask;
1307 send_command_12(card->codecnr, card->function_group, VERB_SET_GPIO_ENABLE,
1308 gpio_enable, card);
1310 gpio_dir = send_command_12(card->codecnr, card->function_group,
1311 VERB_GET_GPIO_DIR, 0, card);
1312 gpio_dir |= mask;
1313 send_command_12(card->codecnr, card->function_group, VERB_SET_GPIO_DIR,
1314 gpio_dir, card);
1316 gpio_data = send_command_12(card->codecnr, card->function_group,
1317 VERB_GET_GPIO_DATA, 0, card);
1318 if (on)
1319 gpio_data |= mask;
1320 else
1321 gpio_data &= ~mask;
1322 send_command_12(card->codecnr, card->function_group, VERB_SET_GPIO_DATA,
1323 gpio_data, card);
1327 static void set_gpio(UBYTE mask, struct HDAudioChip *card)
1329 update_gpio(mask, TRUE, card);
1333 static UBYTE get_connected_widget(UBYTE nid, UBYTE index,
1334 struct HDAudioChip *card)
1336 UBYTE input_nid = 0;
1337 ULONG connections, entry;
1339 connections = get_parameter(nid, 0xE, card);
1340 if (index < connections)
1342 entry = send_command_12(card->codecnr, nid,
1343 VERB_GET_CONNECTION_LIST_ENTRY, index, card);
1344 input_nid = entry >> ((index % 4) * 8);
1347 return input_nid;
1351 static UBYTE get_selected_widget(UBYTE nid, struct HDAudioChip *card)
1353 UBYTE input_nid = 0;
1354 ULONG connections;
1355 ULONG index;
1357 connections = get_parameter(nid, 0xE, card);
1358 if (connections > 0)
1360 if (connections == 1)
1361 index = 0;
1362 else
1364 index = send_command_12(card->codecnr, nid,
1365 VERB_GET_CONNECTION_SELECT, 0, card);
1368 input_nid = get_connected_widget(nid, index, card);
1371 return input_nid;
1375 /* Adds a widget to the array of volume controlling widgets if it has volume
1376 * control */
1377 static void check_widget_volume(UBYTE nid, struct HDAudioChip *card)
1379 ULONG parm;
1381 parm = get_parameter(nid, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1382 D(bug("[HDAudio] NID %xh: Audio widget caps = %lx\n", nid, parm));
1383 if (parm & 0x4) // OutAmpPre
1385 D(bug("[HDAudio] NID %xh has volume control\n", nid));
1386 card->dac_volume_nids[card->dac_volume_count++] = nid;
1388 else
1390 D(bug("[HDAudio] NID %xh does not have volume control\n", nid));
1395 static BOOL interrogate_unknown_chip(struct HDAudioChip *card)
1397 int dac, adc, front, steps = 0, offset0dB = 0;
1398 double step_size = 0.25;
1399 ULONG parm, widget_caps, nid;
1400 UWORD connections, i;
1401 UBYTE before_front = 0;
1403 D(bug("[HDAudio] Unknown codec, interrogating chip...\n"));
1405 // find out the first PCM DAC
1406 dac = find_widget(card, 0, 0);
1407 D(bug("[HDAudio] DAC NID = %xh\n", dac));
1409 if (dac == 0)
1411 bug("Didn't find DAC!\n");
1412 return FALSE;
1415 card->dac_nid = dac;
1417 check_widget_volume(dac, card);
1419 // find FRONT pin
1420 front = find_widget(card, 4, 0);
1421 D(bug("[HDAudio] Front PIN = %xh\n", front));
1423 if (front == 0)
1425 D(bug("[HDAudio] Didn't find jack/pin for line output!\n"));
1427 else
1429 send_command_4(card->codecnr, front, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute output of FRONT
1430 send_command_12(card->codecnr, front, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1431 send_command_12(card->codecnr, front, VERB_SET_CONNECTION_SELECT, 0, card); // use first input
1432 check_widget_volume(front, card);
1435 // find SPEAKER
1436 if (force_speaker_nid > 0)
1438 D(bug("[HDAudio] Using speaker nid from config file"));
1439 card->speaker_nid = force_speaker_nid;
1441 else
1443 card->speaker_nid = find_widget(card, 4, 1);
1445 D(bug("[HDAudio] Speaker NID = %xh\n", card->speaker_nid));
1447 if (card->speaker_nid != 0)
1449 // check if there is a power amp and if so, enable it
1450 if (get_parameter(card->speaker_nid, VERB_GET_PARMS_PIN_CAPS, card) & PIN_CAPS_EAPD_CAPABLE)
1452 D(bug("[HDAudio] Enabling power amp of speaker\n"));
1453 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1456 // set amplifier gain: unmute output
1457 send_command_4(card->codecnr, card->speaker_nid, VERB_SET_AMP_GAIN,
1458 OUTPUT_AMP_GAIN | INPUT_AMP_GAIN | AMP_GAIN_LR | 0x0, card);
1460 D(bug("[HDAudio] Enabling speaker output\n"));
1461 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1462 card->speaker_active = TRUE;
1463 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_CONNECTION_SELECT, 0, card); // use first input
1465 check_widget_volume(card->speaker_nid, card);
1467 else
1469 D(bug("[HDAudio] No speaker pin found, continuing anyway!\n"));
1472 // Find headphones socket
1473 card->headphone_nid = find_widget(card, 4, 2);
1475 D(bug("[HDAudio] Headphone NID = %xh\n", card->headphone_nid));
1477 if (card->headphone_nid != 0)
1479 send_command_4(card->codecnr, card->headphone_nid, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute headphone
1480 send_command_12(card->codecnr, card->headphone_nid, VERB_SET_PIN_WIDGET_CONTROL, 0xC0, card); // output enabled and headphone enabled
1481 send_command_12(card->codecnr, card->headphone_nid, VERB_SET_CONNECTION_SELECT, 0, card); // use first input
1483 // check if there is a power amp and if so, enable it
1484 if (get_parameter(card->headphone_nid, VERB_GET_PARMS_PIN_CAPS, card) & PIN_CAPS_EAPD_CAPABLE)
1486 D(bug("[HDAudio] Enabling power amp of headphone port\n"));
1487 send_command_12(card->codecnr, card->headphone_nid, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1490 // unmute widget before headphone jack if it's not the DAC
1491 nid = send_command_12(card->codecnr, card->headphone_nid,
1492 VERB_GET_CONNECTION_LIST_ENTRY, 0, card);
1493 if (nid != dac)
1495 connections = get_parameter(nid, 0xE, card);
1496 for (i = 0; i < connections; i++)
1497 send_command_4(card->codecnr, nid, VERB_SET_AMP_GAIN,
1498 INPUT_AMP_GAIN | AMP_GAIN_LR | i << 8, card);
1501 check_widget_volume(card->headphone_nid, card);
1504 // find the node before the front, speaker or HP node
1505 if (front != 0)
1506 nid = front;
1507 else if (card->speaker_nid != 0)
1508 nid = card->speaker_nid;
1509 else if (card->headphone_nid != 0)
1510 nid = card->headphone_nid;
1511 else nid = 0;
1513 if (nid != 0)
1514 before_front = (UBYTE)send_command_12(card->codecnr, nid,
1515 VERB_GET_CONNECTION_LIST_ENTRY, 0, card);
1517 if (before_front != dac)
1519 D(bug("[HDAudio] The widget before front/speaker/HP (%xh) is not equal to DAC!\n", before_front));
1521 send_command_4(card->codecnr, before_front, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1522 D(bug("[HDAudio] Let's hope it was a mute that now got unmuted!\n"));
1524 check_widget_volume(before_front, card);
1526 else
1528 D(bug("[HDAudio] The widget before front/speaker/HP is equal to DAC.\n"));
1531 for (i = 0; card->dac_volume_nids[i] != 0; i++)
1533 parm = get_parameter(card->dac_volume_nids[i],
1534 VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1535 if ((parm & 0x8) != 0)
1536 parm = get_parameter(card->dac_volume_nids[i],
1537 VERB_GET_PARMS_OUTPUT_AMP_CAPS , card);
1538 else
1539 parm = get_parameter(card->function_group,
1540 VERB_GET_PARMS_OUTPUT_AMP_CAPS, card);
1541 D(bug("[HDAudio] NID %xh: Output amp caps = %lx\n", card->dac_volume_nids[i], parm));
1543 step_size = (((parm >> 16) & 0x7F) + 1) * 0.25;
1544 steps = ((parm >> 8) & 0x7F);
1545 offset0dB = (parm & 0x7F);
1547 if (steps != 0)
1549 card->dac_min_gain = -(offset0dB * step_size);
1550 card->dac_max_gain = card->dac_min_gain + step_size * steps;
1551 card->dac_step_gain = step_size;
1552 D(bug("[HDAudio] Gain step size = %lu * 0.25 dB,"
1553 " min gain = %d, max gain = %d\n",
1554 (((parm >> 16) & 0x7F) + 1), (int) (card->dac_min_gain),
1555 (int) (card->dac_max_gain)));
1559 // find out the first PCM ADC
1560 adc = find_widget(card, 1, 0);
1561 D(bug("[HDAudio] ADC NID = %xh\n", adc));
1563 if (adc != 0)
1565 card->adc_nid = adc;
1567 card->line_in_nid = find_widget(card, 4, 8);
1568 D(bug("[HDAudio] Line-in NID = %xh\n", card->line_in_nid));
1569 card->mic1_nid = find_widget(card, 4, 0xA);
1570 D(bug("[HDAudio] Mic1 NID = %xh\n", card->mic1_nid));
1572 nid = adc;
1573 while (nid != 0)
1575 widget_caps = get_parameter(nid,
1576 VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1577 D(bug("[HDAudio] audio widget caps = %lx\n", widget_caps));
1579 if (((widget_caps >> 20) & 0xF) == 0x3)
1581 card->adc_mixer_nid = nid;
1582 D(bug("[HDAudio] ADC mixer NID = %xh\n", card->adc_mixer_nid));
1583 card->adc_mixer_is_mux = TRUE;
1586 // set amplifier gain and unmute
1587 send_command_4(card->codecnr, nid, VERB_SET_AMP_GAIN,
1588 OUTPUT_AMP_GAIN | INPUT_AMP_GAIN | AMP_GAIN_LR | 0x0, card);
1590 nid = get_selected_widget(nid, card);
1593 if (card->line_in_nid != 0)
1595 send_command_12(card->codecnr, card->line_in_nid,
1596 VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1597 send_command_4(card->codecnr, card->line_in_nid, VERB_SET_AMP_GAIN,
1598 OUTPUT_AMP_GAIN | INPUT_AMP_GAIN | AMP_GAIN_LR | 0x0, card);
1600 if (card->mic1_nid != 0)
1602 send_command_12(card->codecnr, card->mic1_nid,
1603 VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1604 send_command_4(card->codecnr, card->mic1_nid, VERB_SET_AMP_GAIN,
1605 OUTPUT_AMP_GAIN | INPUT_AMP_GAIN | AMP_GAIN_LR | 0x0, card);
1608 else
1609 bug("[HDAudio] Didn't find ADC!\n");
1611 return TRUE;
1615 static UBYTE find_widget(struct HDAudioChip *card, UBYTE type, UBYTE pin_type)
1617 ULONG node_count_response = get_parameter(card->function_group,
1618 VERB_GET_PARMS_NODE_COUNT, card);
1619 UBYTE node_count = node_count_response & 0xFF;
1620 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
1621 UBYTE i;
1622 ULONG config_default;
1624 for (i = 0; i < node_count; i++) // widgets
1626 UBYTE nid = i + starting_node;
1627 ULONG widget_caps, pin_caps, connections;
1629 widget_caps = get_parameter(nid, VERB_GET_PARMS_AUDIO_WIDGET_CAPS,
1630 card);
1632 if (((widget_caps >> 20) & 0xF) == type)
1634 BOOL ok;
1636 if (type == 4) // node is a pin widget
1638 config_default = send_command_12(card->codecnr, nid,
1639 VERB_GET_CONFIG_DEFAULT, 0, card);
1641 if (((config_default >> 20) & 0xF) == pin_type)
1643 D(bug("[HDAudio] Config default for NID %x = %x\n", nid,
1644 config_default));
1645 if ((widget_caps & 1 << 8) != 0)
1646 connections = get_parameter(nid, 0xE, card) & 0x7f;
1647 else
1648 connections = 0;
1649 pin_caps =
1650 get_parameter(nid, VERB_GET_PARMS_PIN_CAPS, card);
1651 switch (pin_type)
1653 case 0x0:
1654 case 0x1:
1655 case 0x2:
1656 case 0x4:
1657 case 0x5:
1658 ok = (pin_caps & PIN_CAPS_OUTPUT_CAPABLE) != 0
1659 && connections != 0;
1660 break;
1661 default:
1662 ok = (pin_caps & PIN_CAPS_INPUT_CAPABLE) != 0;
1665 // check speaker connection type is internal
1666 if (pin_type == 1 && (config_default >> 16 & 0xB) != 3)
1667 ok = FALSE;
1669 // check headphone connection type is mini-jack
1670 if (pin_type == 2 && (config_default >> 16 & 0xF) != 1)
1671 ok = FALSE;
1673 // check microphone connection type is mini-jack
1674 if (pin_type == 0xA && (config_default >> 16 & 0xF) != 1)
1675 ok = FALSE;
1678 else
1679 ok = (widget_caps & 0x1) == 1 && // stereo
1680 ((widget_caps >> 9) & 0x1) == 0; // analogue
1682 if (ok)
1683 return nid;
1687 return 0;
1691 static void determine_frequencies(struct HDAudioChip *card)
1693 ULONG verb = get_parameter(card->dac_nid, 0xA, card);
1694 UWORD samplerate_flags = verb & 0x0FFF;
1695 int i;
1696 ULONG freqs = 0;
1697 BOOL default_freq_found = FALSE;
1699 if (samplerate_flags == 0)
1701 verb = get_parameter(0x1, 0xA, card);
1702 samplerate_flags = verb & 0x0FFF;
1703 D(bug("[HDAudio] dac_nid didn't have a list of sample rates, trying AFG node\n"));
1706 // count number of frequencies
1707 for (i = 0; i < 12; i++)
1709 if (samplerate_flags & (1 << i))
1711 freqs++;
1715 D(bug("[HDAudio] Frequencies found = %lu\n", freqs));
1716 card->frequencies = (struct Freq *) AllocVec(sizeof(struct Freq) * freqs, MEMF_PUBLIC | MEMF_CLEAR);
1717 card->nr_of_frequencies = freqs;
1719 freqs = 0;
1720 for (i = 0; i < 12; i++)
1722 if (samplerate_flags & (1 << i))
1724 set_frequency_info(&(card->frequencies[freqs]), i);
1726 if (card->frequencies[freqs].frequency == 44100 && !default_freq_found)
1728 card->selected_freq_index = freqs; // set default freq index to 44100 Hz
1729 default_freq_found = TRUE;
1732 freqs++;
1736 if (default_freq_found == FALSE)
1738 D(bug("[HDAudio] 44100 Hz is not supported!\n"));
1739 if (freqs > 0)
1741 D(bug("[HDAudio] Setting default frequency to %lu\n", card->frequencies[0].frequency));
1742 card->selected_freq_index = 0;
1749 static void set_frequency_info(struct Freq *freq, UWORD bitnr)
1751 switch (bitnr)
1753 case 0: freq->frequency = 8000;
1754 freq->base44100 = 0;
1755 freq->mult = 0;
1756 freq->div = 5;
1757 break;
1759 case 1: freq->frequency = 11025;
1760 freq->base44100 = 1;
1761 freq->mult = 0;
1762 freq->div = 3;
1763 break;
1765 case 2: freq->frequency = 16000;
1766 freq->base44100 = 0;
1767 freq->mult = 0;
1768 freq->div = 2;
1769 break;
1771 case 3: freq->frequency = 22050;
1772 freq->base44100 = 1;
1773 freq->mult = 0;
1774 freq->div = 1;
1775 break;
1777 case 4: freq->frequency = 32000;
1778 freq->base44100 = 0;
1779 freq->mult = 0;
1780 freq->div = 2;
1781 break;
1783 case 5: freq->frequency = 44100;
1784 freq->base44100 = 1;
1785 freq->mult = 0;
1786 freq->div = 0;
1787 break;
1789 case 6: freq->frequency = 48000;
1790 freq->base44100 = 0;
1791 freq->mult = 0;
1792 freq->div = 0;
1793 break;
1795 case 7: freq->frequency = 88200;
1796 freq->base44100 = 1;
1797 freq->mult = 1;
1798 freq->div = 0;
1799 break;
1801 case 8: freq->frequency = 96000;
1802 freq->base44100 = 0;
1803 freq->mult = 1;
1804 freq->div = 0;
1805 break;
1807 case 9: freq->frequency = 176400;
1808 freq->base44100 = 1;
1809 freq->mult = 3;
1810 freq->div = 0;
1811 break;
1813 case 10: freq->frequency = 192000;
1814 freq->base44100 = 0;
1815 freq->mult = 3;
1816 freq->div = 0;
1817 break;
1819 default:
1820 D(bug("[HDAudio] Unsupported frequency!\n"));
1821 break;
1826 void set_monitor_volumes(struct HDAudioChip *card, double dB)
1828 #if 0
1829 int i;
1830 #endif
1831 int dB_steps = (int) ((dB + 34.5) / 1.5);
1833 if (dB_steps < 0)
1835 dB_steps = 0;
1837 else if (dB_steps > 31)
1839 dB_steps = 31;
1842 #if 0
1843 for (i = 0; i < 9; i++)
1845 if (i == 0 || i == 1 || i == 2 || i == 4)
1847 send_command_4(card->codecnr, 0xB, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (i << 8) | dB_steps, card);
1849 else // mute
1851 send_command_4(card->codecnr, 0xB, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (i << 8) | (1 << 7), card);
1854 #endif
1858 void set_adc_input(struct HDAudioChip *card)
1860 int i;
1862 if (card->input >= INPUTS)
1864 card->input = 0;
1867 if (card->adc_mixer_is_mux == TRUE)
1869 D(bug("[HDAudio] Selecting ADC input %d\n", card->adc_mixer_indices[card->input]));
1870 send_command_12(card->codecnr, card->adc_mixer_nid, VERB_SET_CONNECTION_SELECT,
1871 card->adc_mixer_indices[card->input], card);
1872 return;
1874 else
1876 for (i = 0; i < INPUTS; i++)
1878 if (card->adc_mixer_indices[i] != 255) // input is present
1880 if (i == card->input) // unmute or select
1882 D(bug("[HDAudio] Unmuting ADC input %d\n", card->adc_mixer_indices[i]));
1883 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN,
1884 INPUT_AMP_GAIN | AMP_GAIN_LR | (card->adc_mixer_indices[i] << 8), card);
1886 else // mute
1888 D(bug("[HDAudio] Muting ADC input %d\n", card->adc_mixer_indices[i]));
1889 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN,
1890 INPUT_AMP_GAIN | AMP_GAIN_LR | (card->adc_mixer_indices[i] << 8) | (1 << 7), card);
1899 void set_adc_gain(struct HDAudioChip *card, double dB)
1901 int dB_steps = (int) ( (dB - card->adc_min_gain) / card->adc_step_gain);
1903 if (dB_steps < 0)
1905 dB_steps = 0;
1908 if (card->adc_mixer_is_mux == TRUE)
1910 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
1912 else
1914 send_command_4(card->codecnr, card->adc_nid, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
1919 void set_dac_gain(struct HDAudioChip *card, double dB)
1921 int i;
1922 int dB_steps = (int) ( (dB - card->dac_min_gain) / card->dac_step_gain);
1924 if (dB_steps < 0)
1926 dB_steps = 0;
1929 for (i = 0; i < card->dac_volume_count; i++)
1930 send_command_4(card->codecnr, card->dac_volume_nids[i],
1931 VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
1935 void setForceQuery(void)
1937 forceQuery = TRUE;
1941 void setDumpAll(void)
1943 dumpAll = TRUE;
1947 void setForceSpeaker(int speaker_nid)
1949 force_speaker_nid = speaker_nid;
1954 BOOL is_jack_connected(struct HDAudioChip *card, UBYTE NID)
1956 ULONG result;
1958 send_command_12(card->codecnr, NID, VERB_EXECUTE_PIN_SENSE, 0, card);
1959 udelay(2000);
1960 result = send_command_12(card->codecnr, NID, VERB_GET_PIN_SENSE, 0, card);
1962 if (result & 0x80000000)
1964 D(bug("[HDAudio] jack connected\n"));
1965 return TRUE;
1967 else
1969 D(bug("[HDAudio] jack disconnected\n"));
1970 return FALSE;
1976 void detect_headphone_change(struct HDAudioChip *card)
1978 if (card->speaker_nid != 0 &&
1979 card->headphone_nid != 0)
1981 if (card->speaker_active &&
1982 is_jack_connected(card, card->headphone_nid)) // disable speaker
1984 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x0, card); // output disabled
1985 card->speaker_active = FALSE;
1987 else if (card->speaker_active == FALSE &&
1988 is_jack_connected(card, card->headphone_nid) == FALSE) // enable speaker
1990 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1991 card->speaker_active = TRUE;