- Handle multiple nodes having output volume control.
[AROS.git] / workbench / devs / AHI / Drivers / HDAudio / misc.c
blobccbabe086c92f30267c7a18491254a74003e4270
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 write_default_pin_config(UBYTE nid, ULONG data,
52 struct HDAudioChip *card);
53 static void set_gpio(UBYTE mask, struct HDAudioChip *card);
54 static BOOL interrogate_unknown_chip(struct HDAudioChip *card);
55 static UBYTE find_widget(struct HDAudioChip *card, UBYTE type, UBYTE pin_type);
56 static BOOL power_up_all_nodes(struct HDAudioChip *card);
58 struct Device *TimerBase = NULL;
59 struct timerequest *TimerIO = NULL;
60 struct MsgPort *replymp = NULL;
61 static BOOL forceQuery = FALSE;
62 static BOOL dumpAll = FALSE;
63 static int force_speaker_nid = 0;
64 //void AddResetHandler(struct HDAudioChip *card);
67 #ifdef __AROS__
68 #define DebugPrintF bug
69 INTGW(static, void, playbackinterrupt, PlaybackInterrupt);
70 INTGW(static, void, recordinterrupt, RecordInterrupt);
71 INTGW(static, ULONG, cardinterrupt, CardInterrupt);
72 #endif
74 void micro_delay(unsigned int val)
76 replymp = (struct MsgPort *) CreateMsgPort();
77 if (!replymp)
79 D(bug("[HDAudio] Could not create the reply port!\n"));
80 return;
83 TimerIO = (struct timerequest *) CreateIORequest(replymp, sizeof(struct timerequest));
85 if (TimerIO == NULL)
87 D(bug("[HDAudio] Out of memory.\n"));
88 return;
91 if (OpenDevice((CONST_STRPTR) "timer.device", UNIT_MICROHZ, (struct IORequest *) TimerIO, 0) != 0)
93 D(bug("[HDAudio] Unable to open 'timer.device'.\n"));
94 return;
96 else
98 TimerBase = (struct Device *) TimerIO->tr_node.io_Device;
101 TimerIO->tr_node.io_Command = TR_ADDREQUEST; /* Add a request. */
102 TimerIO->tr_time.tv_secs = 0; /* 0 seconds. */
103 TimerIO->tr_time.tv_micro = val; /* 'val' micro seconds. */
104 DoIO((struct IORequest *) TimerIO);
105 CloseDevice((struct IORequest *) TimerIO);
106 DeleteIORequest((struct IORequest *) TimerIO);
107 TimerIO = NULL;
109 if (replymp)
111 DeleteMsgPort(replymp);
116 /******************************************************************************
117 ** DriverData allocation ******************************************************
118 ******************************************************************************/
120 struct HDAudioChip* AllocDriverData(APTR dev, struct DriverBase* AHIsubBase)
122 struct HDAudioBase* card_base = (struct HDAudioBase*) AHIsubBase;
123 struct HDAudioChip* card;
124 UWORD command_word;
125 int i;
126 unsigned short uval;
127 BOOL success = TRUE;
129 card = (struct HDAudioChip *) AllocVec(sizeof(struct HDAudioChip), MEMF_PUBLIC | MEMF_CLEAR);
131 if (card == NULL)
133 Req("Unable to allocate driver structure.");
134 return NULL;
137 card->ahisubbase = AHIsubBase;
139 card->interrupt.is_Node.ln_Type = IRQTYPE;
140 card->interrupt.is_Node.ln_Pri = 0;
141 card->interrupt.is_Node.ln_Name = (char *) LibName;
142 #ifdef __AROS__
143 card->interrupt.is_Code = (void(*)(void)) &cardinterrupt;
144 #else
145 card->interrupt.is_Code = (void(*)(void)) CardInterrupt;
146 #endif
147 card->interrupt.is_Data = (APTR) card;
149 card->playback_interrupt.is_Node.ln_Type = IRQTYPE;
150 card->playback_interrupt.is_Node.ln_Pri = 0;
151 card->playback_interrupt.is_Node.ln_Name = (char *) LibName;
152 #ifdef __AROS__
153 card->playback_interrupt.is_Code = (APTR)&playbackinterrupt;
154 #else
155 card->playback_interrupt.is_Code = PlaybackInterrupt;
156 #endif
157 card->playback_interrupt.is_Data = (APTR) card;
159 card->record_interrupt.is_Node.ln_Type = IRQTYPE;
160 card->record_interrupt.is_Node.ln_Pri = 0;
161 card->record_interrupt.is_Node.ln_Name = (char *) LibName;
162 #ifdef __AROS__
163 card->record_interrupt.is_Code = (APTR)&recordinterrupt;
164 #else
165 card->record_interrupt.is_Code = RecordInterrupt;
166 #endif
167 card->record_interrupt.is_Data = (APTR) card;
169 command_word = inw_config(PCI_COMMAND, dev);
170 command_word |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
171 outw_config(PCI_COMMAND, command_word, dev);
173 card->pci_dev = dev;
174 card->pci_master_enabled = TRUE;
176 card->iobase = ahi_pci_get_base_address(0, dev);
177 card->length = ahi_pci_get_base_size(0, dev);
178 card->chiprev = inb_config(PCI_REVISION_ID, dev);
179 card->model = inb_config(PCI_SUBSYSTEM_ID, dev);
181 perform_controller_specific_settings(card);
183 ahi_pci_add_intserver(&card->interrupt, dev);
185 /* Initialize chip */
186 if (card_init(card) < 0)
188 D(bug("[HDAudio] Unable to initialize Card subsystem.\n"));
190 success = FALSE;
193 card->interrupt_added = TRUE;
195 card->card_initialized = TRUE;
196 card->input = 0;
197 card->output = 0;
198 card->monitor_volume = (unsigned long) (0x10000 * pow (10.0, -6.0 / 20.0)); // -6 dB
199 card->input_gain = 0x10000; // 0dB
200 card->output_volume = 0x10000; // 0dB
202 if (success)
204 set_monitor_volumes(card, -6.0); // -6dB monitor volume
207 if (!success)
209 FreeDriverData(card, AHIsubBase);
210 card = NULL;
213 return card;
217 /******************************************************************************
218 ** DriverData deallocation ****************************************************
219 ******************************************************************************/
221 void FreeDriverData(struct HDAudioChip* card, struct DriverBase* AHIsubBase)
223 if (card != NULL)
225 if (card->pci_dev != NULL)
227 if (card->card_initialized)
229 card_cleanup(card);
232 if (card->pci_master_enabled)
234 UWORD cmd;
236 cmd = inw_config(PCI_COMMAND, card->pci_dev);
237 cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
238 outw_config(PCI_COMMAND, cmd, card->pci_dev);
242 if (card->interrupt_added)
244 ahi_pci_rem_intserver(&card->interrupt, card->pci_dev);
247 FreeVec(card);
251 #define CNT_VEN_ID_ATI_SB 0x437B1002
252 #define CNT_VEN_ID_ATI_SB2 0x43831002
253 #define CNT_VEN_ID_ATI_HUDSON 0x780D1022
254 #define CNT_VEN_ID_NVIDIA 0x10DE
256 /* This is the controller specific portion, for fixes to southbridge */
257 static void perform_controller_specific_settings(struct HDAudioChip *card)
259 ULONG data, subsystem;
260 ULONG mask = (1 << 16) - 1;
262 /* Get vendor/product/subsystem IDs */
263 data = inl_config(0x0, card->pci_dev);
264 D(bug("DEBUG: Controller Vendor ID: %x\n", data));
265 subsystem = inl_config(0x2C, card->pci_dev);
267 /* NVidia is for all nvidia MCP chipsets, create mask to get rid of device ID */
269 /* Check for ATI Southbridge or AMD Hudson controller */
270 if (data == CNT_VEN_ID_ATI_SB || data == CNT_VEN_ID_ATI_SB2 || data == CNT_VEN_ID_ATI_HUDSON)
272 D(bug("[HDAudio] ATI SB/AMD Hudson scontroller detected, setting snoop to on.\n"));
273 data = inb_config(0x42, card->pci_dev);
274 data &= ~0x07;
275 data |= 0x02;
276 outb_config(0x42, data, card->pci_dev);
279 /* Check for NVidia MCP controller */
280 if ((data & mask) == CNT_VEN_ID_NVIDIA )
282 D(bug("[HDAudio] NVidia MCP controller detected, setting snoop to on.\n"));
283 data = inb_config(0x4E, card->pci_dev);
284 data |= 0x0F;
285 outb_config(0x4E, data, card->pci_dev);
287 data = inb_config(0x4D, card->pci_dev);
288 data |= 0x01;
289 outb_config(0x4D, data, card->pci_dev);
291 data = inb_config(0x4C, card->pci_dev);
292 data |= 0x01;
293 outb_config(0x4C, data, card->pci_dev);
296 /* Check for HP Compaq nc6320 laptop */
297 if (subsystem == 0x30aa103c)
299 D(bug("[HDAudio] HP Compaq nc6320 laptop detected, correcting IRQ\n"));
300 data = inb_config(0x3C, card->pci_dev);
301 if (data == 10)
302 outb_config(0x3C, 11, card->pci_dev);
306 int card_init(struct HDAudioChip *card)
308 struct PCIDevice *dev = (struct PCIDevice *) card->pci_dev;
309 UWORD uwval;
310 unsigned char pval, byt;
311 long *ptr;
312 int i;
314 if (reset_chip(card) == FALSE)
316 D(bug("[HDAudio] Reset chip failed\n"));
317 return -1;
320 // 4.3 Codec discovery: 15 codecs can be connected, bits that are on indicate a codec
321 card->codecbits = pci_inw(HD_STATESTS, card);
323 if (card->codecbits == 0)
325 D(bug("[HDAudio] No codecs found!\n"));
326 return -1;
329 if (alloc_streams(card) == FALSE)
331 D(bug("[HDAudio] Allocating streams failed!\n"));
332 return -1;
335 if (allocate_corb(card) == FALSE)
337 D(bug("[HDAudio] Allocating CORB failed!\n"));
338 return -1;
341 if (allocate_rirb(card) == FALSE)
343 D(bug("[HDAudio] Allocating RIRB failed!\n"));
344 return -1;
347 if (allocate_pos_buffer(card) == FALSE)
349 D(bug("[HDAudio] Allocating position buffer failed!\n"));
350 return -1;
353 // enable interrupts
354 pci_outl(HD_INTCTL_CIE | HD_INTCTL_GLOBAL, HD_INTCTL, card);
355 udelay(200);
357 /* Find the first codec with an audio function group */
358 for (i = 0; i < 16; i++)
360 if (card->codecbits & (1 << i))
362 card->codecnr = i;
363 if (power_up_all_nodes(card))
364 break;
368 if (perform_codec_specific_settings(card) == FALSE)
370 return -1;
373 if (dumpAll)
375 codec_discovery(card);
378 D(bug("[HDAudio] card_init() was a success!\n"));
380 return 0;
384 void card_cleanup(struct HDAudioChip *card)
389 static BOOL reset_chip(struct HDAudioChip *card)
391 int counter = 0;
392 UBYTE ubval = 0;
393 UWORD uwval = 0;
394 int count;
395 UBYTE tcsel;
398 Intel® HIgh Definition Audio Traffic Class Assignment (TCSEL), bits 0:2 -> 000 = TC0
399 This register assigned the value to be placed in the TC field. CORB and RIRB data will always be
400 assigned TC0.
402 #define TCSEL_PCIREG 0x44
403 tcsel = inb_config(TCSEL_PCIREG, card->pci_dev);
404 tcsel &= ~0x07;
405 outb_config(TCSEL_PCIREG, tcsel, card->pci_dev);
407 pci_outb(0, HD_CORBCTL, card);
408 pci_outb(0, HD_RIRBCTL, card);
410 // Clear STATESTS just to be sure. After reset, this register holds the ID's of the connected codecs
411 pci_outb(0xFF, HD_STATESTS, card);
413 // Transition to reset state
414 outl_clearbits(1, HD_GCTL, card);
416 // Wait for bit 0 to read 0
417 for (counter = 0; counter < 1000; counter++)
419 ubval = pci_inb(HD_GCTL, card);
421 if ((ubval & 0x1) == 0)
423 break;
426 udelay(100);
429 if (counter == 1000)
431 D(bug("[HDAudio] Couldn't reset chip!\n"));
432 return FALSE;
435 udelay(100);
436 // 4.2.2. Take controller out of reset
437 outl_setbits(1, HD_GCTL, card);
440 // Wait for bit 0 to read 1
441 for (counter = 0; counter < 1000; counter++)
443 ubval = pci_inb(HD_GCTL, card);
445 if ((ubval & 0x1) == 1)
447 D(bug("[HDAudio] Codec came out of reset!\n"));
448 break;
451 udelay(100);
454 if (counter == 1000)
456 D(bug("[HDAudio] Couldn't reset chip!\n"));
457 return FALSE;
460 // The software must wait 250 microseconds after reading CRST as 1, but it's suggested to wait longer
461 udelay(1000);
463 // do not accept unsolicited events for now (jack sense etc.)
464 //outl_setbits((1 << 8), HD_GCTL, card); // accept unsolicited events
466 return TRUE;
470 void codec_discovery(struct HDAudioChip *card)
472 int i;
474 ULONG subnode_count_response = get_parameter(card->function_group, VERB_GET_PARMS_NODE_COUNT, card);
475 UBYTE subnode_count = subnode_count_response & 0xFF;
476 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
477 ULONG connections = 0;
479 D(bug("[HDAudio] Subnode count = %d, sub_starting_node = %x\n", subnode_count, sub_starting_node));
481 //D(bug("[HDAudio] Audio supported = %lx\n", get_parameter(card->function_group, 0xA, card)));
482 //D(bug("[HDAudio] Sup streams = %lx\n", get_parameter(card->function_group, 0xB, card)));
484 for (i = 0; i < subnode_count; i++) // widgets
486 const ULONG NID = i + sub_starting_node;
487 ULONG widget_caps;
489 widget_caps = get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
491 //if ((NID == 0x18) || (NID == 0xB))
493 D(bug("[HDAudio] Subnode %x has caps %lx\n", NID, widget_caps));
494 D(bug("[HDAudio] %xh: Supported PCM size/rate = %lx\n", NID, get_parameter(NID, VERB_GET_PARMS_SUPPORTED_PCM_SIZE_RATE, card)));
496 if (AUDIO_WIDGET_CAPS(widget_caps) == 0x4) // pin complex
498 ULONG config_default = 0;
500 D(bug("[HDAudio] PIN: caps = %lx\n", get_parameter(NID, VERB_GET_PARMS_PIN_CAPS, card)));
501 config_default = send_command_12(card->codecnr, NID, VERB_GET_CONFIG_DEFAULT, 0, card);
503 D(bug("[HDAudio] PIN: Config default = %lx\n", config_default));
505 D(bug("[HDAudio] PIN: Connected = %s\n", is_jack_connected(card, NID) ? "TRUE" : "FALSE"));
508 D(bug("[HDAudio] %xh: Input Amp caps = %lx\n", NID, get_parameter(NID, 0xD, card)));
509 D(bug("[HDAudio] %xh: Output Amp caps = %lx\n", NID, get_parameter(NID, 0x12, card)));
511 connections = get_parameter(NID, 0xE, card);
512 D(bug("[HDAudio] %xh: Conn list len = %lx\n", NID, connections));
513 if (connections > 0) // print connections
515 ULONG entry = 0;
517 for (entry = 0; entry < connections; entry+=4)
519 ULONG connectedTo = send_command_12(card->codecnr, NID, VERB_GET_CONNECTION_LIST_ENTRY, entry, card);
521 bug("%lx, ", connectedTo);
523 bug("\n");
526 D(bug("[HDAudio] %xh: Supported power state = %lx\n", NID, get_parameter(NID, 0xF, card)));
528 D(ULONG n);
529 D(n = send_command_12(card->codecnr, NID, VERB_GET_CONNECTION_SELECT, 0, card));
530 D(bug("[HDAudio] %xh: Connection selection = %lx\n", NID, n));
532 D(n = send_command_4(card->codecnr, NID, 0xB, 0x8000, card));
533 D(bug("[HDAudio] %xh: Output Amp gain = %lx\n", NID, n));
534 D(n = send_command_4(card->codecnr, NID, 0xB, 0x0000, card));
535 D(bug("[HDAudio] %xh: Input Amp gain = %lx\n", NID, n));
536 D(n = send_command_4(card->codecnr, NID, 0xA, 0, card));
537 D(bug("[HDAudio] %xh: Format = %lx\n", NID, n));
538 D(n = send_command_12(card->codecnr, NID, 0xF05, 0, card));
539 D(bug("[HDAudio] %xh: Power state = %lx\n", NID, n));
540 D(n = send_command_12(card->codecnr, NID, 0xF06, 0, card));
541 D(bug("[HDAudio] %xh: Stream = %lx\n", NID, n));
542 D(n = send_command_12(card->codecnr, NID, 0xF07, 0, card));
543 D(bug("[HDAudio] %xh: Pin widget control = %lx\n", NID, n));
544 D(bug("[HDAudio] --------------------------------\n\n"));
550 static BOOL power_up_all_nodes(struct HDAudioChip *card)
552 int i;
553 ULONG node_count_response = get_parameter(0, VERB_GET_PARMS_NODE_COUNT, card);
554 UBYTE node_count = node_count_response & 0xFF;
555 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
556 BOOL audio_found = FALSE;
558 D(bug("[HDAudio] power up\n"));
559 send_command_12(card->codecnr, 1, VERB_SET_POWER_STATE , 0, card); // send function reset to audio node, this should power up all nodes
560 udelay(20000);
562 for (i = 0; i < node_count && !audio_found; i++)
564 ULONG function_group_response = get_parameter(starting_node + i, VERB_GET_PARMS_FUNCTION_GROUP_TYPE, card);
565 UBYTE function_group = function_group_response & 0xFF;
567 if (function_group == AUDIO_FUNCTION)
569 int j;
571 ULONG subnode_count_response = get_parameter(starting_node + i, VERB_GET_PARMS_NODE_COUNT, card);
572 UBYTE subnode_count = subnode_count_response & 0xFF;
573 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
574 ULONG connections = 0;
576 audio_found = TRUE;
577 card->function_group = starting_node + i;
579 for (j = 0; j < subnode_count; j++) // widgets
581 const ULONG NID = j + sub_starting_node;
582 ULONG widget_caps;
584 widget_caps = get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
587 if (AUDIO_WIDGET_POWER_CONTROL(widget_caps) == 1) // power control
589 ULONG power_state = 0;
591 power_state = send_command_12(card->codecnr, NID, VERB_GET_POWER_STATE, 0, card);
592 D(bug("[HDAudio] %xh: power state = %xh\n", NID, power_state));
594 if (power_state != 0)
596 D(bug("[HDAudio] Setting power state to 0\n"));
597 send_command_12(card->codecnr, NID, VERB_SET_POWER_STATE, 0, card);
605 return audio_found;
609 // allocates memory on the given boundary. Returns the aligned memory address and the non-aligned memory address
610 // in NonAlignedAddress, if not NULL.
611 void *pci_alloc_consistent(size_t size, APTR *NonAlignedAddress, unsigned int boundary)
613 void* address;
614 unsigned long a;
616 address = (void *) AllocVec(size + boundary, MEMF_PUBLIC | MEMF_CLEAR);
618 if (address != NULL)
620 a = (unsigned long) address;
621 a = (a + boundary - 1) & ~(boundary - 1);
622 address = (void *) a;
625 if (NonAlignedAddress)
627 *NonAlignedAddress = address;
630 return address;
634 void pci_free_consistent(void* addr)
636 FreeVec(addr);
640 ULONG get_parameter(UBYTE node, UBYTE parameter, struct HDAudioChip *card)
642 return send_command_12(card->codecnr, node, VERB_GET_PARMS, parameter, card);
646 ULONG send_command_4(UBYTE codec, UBYTE node, UBYTE verb, UWORD payload, struct HDAudioChip *card)
648 UWORD wp = pci_inw(HD_CORBWP, card) & 0xFF;
649 ULONG data = (codec << 28) | (node << 20) | (verb << 16) | payload;
651 if (wp == card->corb_entries - 1)
653 wp = 0;
655 else
657 wp++;
660 //bug("Sending command %lx\n", data);
662 card->corb[wp] = data;
663 pci_outw(wp, HD_CORBWP, card);
665 return get_response(card);
669 ULONG send_command_12(UBYTE codec, UBYTE node, UWORD verb, UBYTE payload, struct HDAudioChip *card)
671 UWORD wp = pci_inw(HD_CORBWP, card) & 0xFF;
672 ULONG data = (codec << 28) | (node << 20) | (verb << 8) | payload;
674 if (wp == card->corb_entries - 1)
676 wp = 0;
678 else
680 wp++;
683 //bug("Sending command %lx\n", data);
685 card->corb[wp] = data;
686 pci_outw(wp, HD_CORBWP, card);
688 return get_response(card);
692 ULONG get_response(struct HDAudioChip *card)
694 int timeout = 10000;
695 int i;
696 UBYTE rirb_wp;
698 udelay(20); //
700 // wait for interrupt
701 for (i = 0; i < timeout; i++)
703 if (card->rirb_irq > 0)
705 card->rirb_irq--;
706 break;
708 udelay(10);
711 if (i == timeout)
713 D(bug("[HDAudio] No IRQ!\n"));
716 for (i = 0; i < timeout; i++)
718 rirb_wp = pci_inb(HD_RIRBWP, card);
720 if (rirb_wp == card->rirb_rp) // strange, we expect the wp to have increased
722 D(bug("[HDAudio] WP has not increased! rirb_wp = %u, rirb_rp = %lu\n", rirb_wp, card->rirb_rp));
723 udelay(5000);
725 else
727 if ( ((rirb_wp > card->rirb_rp) &&
728 ((rirb_wp - card->rirb_rp) >= 2)) ||
730 ((rirb_wp < card->rirb_rp) &&
731 ( ((int) rirb_wp) + card->rirb_entries) - card->rirb_rp >= 2))
733 D(bug("[HDAudio] Write pointer is more than 1 step ahead!\n"));
736 ULONG addr;
737 ULONG response, response_ex; // 3.6.5 Response Input Ring Buffer
739 card->rirb_rp = rirb_wp;
740 addr = card->rirb_rp;
741 addr *= 2; // 64-bit entries
743 response = card->rirb[addr];
744 response_ex = card->rirb[addr + 1];
745 if (response_ex & 0x10) // unsolicited
747 D(bug("[HDAudio] Unsolicited response! Skipping!\n"));
749 else
751 //bug("Response is %lx\n", response);
752 return response;
757 D(bug("[HDAudio] ERROR in get_response() card->rirb_rp = %u!rirb_wp = %u\n", card->rirb_rp, rirb_wp));
758 return 0;
762 static BOOL allocate_corb(struct HDAudioChip *card)
764 UBYTE corbsize_reg;
766 // 4.4.1.3 Initialize the CORB
768 // stop the DMA
769 outb_clearbits(HD_CORBRUN, HD_CORBCTL, card);
771 // set CORB size
772 corbsize_reg = pci_inb(HD_CORBSIZE, card);
773 if (corbsize_reg & (1 << 6))
775 pci_outb(0x2, HD_CORBSIZE, card);
776 card->corb_entries = 256;
778 else if (corbsize_reg & (1 << 5))
780 pci_outb(0x1, HD_CORBSIZE, card);
781 card->corb_entries = 16;
783 else if (corbsize_reg & (1 << 4))
785 pci_outb(0x0, HD_CORBSIZE, card);
786 card->corb_entries = 2;
789 // Allocate CORB memory
790 card->corb = pci_alloc_consistent(4 * card->corb_entries, NULL, 128); // todo: virtual
792 // Set CORB base
793 pci_outl((ULONG) card->corb, HD_CORB_LOW, card);
794 pci_outl(0, HD_CORB_HIGH, card);
796 //bug("Before reset rp: corbrp = %x\n", pci_inw(0x4A, card));
798 // Reset read pointer: if we set this, the CORB will not work??
799 //outw_setbits(HD_CORBRPRST, HD_CORBRP, card);
801 //bug("After reset rp: corbrp = %x\n", pci_inw(0x4A, card));
803 // Write a 0 to the write pointer to clear
804 pci_outw(0, HD_CORBWP, card);
806 // run it
807 outb_setbits(HD_CORBRUN, HD_CORBCTL, card);
809 if (card->corb)
811 return TRUE;
813 else
815 return FALSE;
820 static BOOL allocate_rirb(struct HDAudioChip *card)
822 UBYTE rirbsize_reg;
824 // 4.4.2.2 Initialize the RIRB
826 // stop the DMA
827 outb_clearbits(HD_RIRBRUN, HD_RIRBCTL, card);
829 // set rirb size
830 rirbsize_reg = pci_inb(HD_RIRBSIZE, card);
831 if (rirbsize_reg & (1 << 6))
833 pci_outb(0x2, HD_RIRBSIZE, card);
834 card->rirb_entries = 256;
836 else if (rirbsize_reg & (1 << 5))
838 pci_outb(0x1, HD_RIRBSIZE, card);
839 card->rirb_entries = 16;
841 else if (rirbsize_reg & (1 << 4))
843 pci_outb(0x0, HD_RIRBSIZE, card);
844 card->rirb_entries = 2;
847 card->rirb_irq = 0;
849 // Allocate rirb memory
850 card->rirb = pci_alloc_consistent(4 * 2 * card->rirb_entries, NULL, 128); // todo: virtual
851 card->rirb_rp = 0;
853 // Set rirb base
854 pci_outl((ULONG) card->rirb, HD_RIRB_LOW, card);
855 pci_outl(0, HD_RIRB_HIGH, card);
857 // Reset read pointer: if we set this, it will not come out of reset??
858 //outw_setbits(HD_RIRBWPRST, HD_RIRBWP, card);
860 // Set N=1, which generates an interrupt for every response
861 pci_outw(1, HD_RINTCNT, card);
863 pci_outb(0x5, HD_RIRBSTS, card);
865 // run it and enable IRQ
866 outb_setbits(HD_RIRBRUN | HD_RINTCTL | 0x4, HD_RIRBCTL, card);
868 if (card->rirb)
870 return TRUE;
872 else
874 return FALSE;
880 static BOOL allocate_pos_buffer(struct HDAudioChip *card)
882 card->dma_position_buffer = pci_alloc_consistent(sizeof(APTR) * 36, NULL, 128);
883 //pci_outl((ULONG) card->dma_position_buffer | HD_DPLBASE_ENABLE, HD_DPLBASE, card);
884 pci_outl(0, HD_DPUBASE, card);
886 if (card->dma_position_buffer)
888 return TRUE;
890 else
892 return FALSE;
897 static BOOL alloc_streams(struct HDAudioChip *card)
899 int i;
900 card->nr_of_input_streams = (pci_inw(HD_GCAP, card) & HD_GCAP_ISS_MASK) >> 8;
901 card->nr_of_output_streams = (pci_inw(HD_GCAP, card) & HD_GCAP_OSS_MASK) >> 12;
902 card->nr_of_streams = card->nr_of_input_streams + card->nr_of_output_streams;
903 //bug("Streams in = %d, out = %d\n", card->nr_of_input_streams, card->nr_of_output_streams);
905 card->streams = (struct Stream *) AllocVec(sizeof(struct Stream) * card->nr_of_streams, MEMF_PUBLIC | MEMF_CLEAR);
907 for (i = 0; i < card->nr_of_streams; i++)
909 card->streams[i].bdl = NULL;
910 card->streams[i].bdl_nonaligned_addresses = NULL;
911 card->streams[i].sd_reg_offset = HD_SD_BASE_OFFSET + HD_SD_DESCRIPTOR_SIZE * i;
912 card->streams[i].index = i;
913 card->streams[i].tag = i + 1;
914 card->streams[i].fifo_size = pci_inw(card->streams[i].sd_reg_offset + HD_SD_OFFSET_FIFO_SIZE, card);
916 // clear the descriptor error, fifo error and buffer completion interrupt status flags
917 pci_outb(HD_SD_STATUS_MASK, card->streams[i].sd_reg_offset + HD_SD_OFFSET_STATUS, card);
920 if (card->streams)
922 return TRUE;
924 else
926 return FALSE;
931 /*static ULONG ResetHandler(struct ExceptionContext *ctx, struct ExecBase *pExecBase, struct HDAudioChip *card)
933 struct PCIDevice *dev = card->pci_dev;
935 return 0UL;
939 void AddResetHandler(struct HDAudioChip *card)
941 static struct Interrupt interrupt;
943 interrupt.is_Code = (void (*)())ResetHandler;
944 interrupt.is_Data = (APTR) card;
945 interrupt.is_Node.ln_Pri = 0;
946 interrupt.is_Node.ln_Type = NT_EXTINTERRUPT;
947 interrupt.is_Node.ln_Name = "reset handler";
949 AddResetCallback(&interrupt);
953 static BOOL perform_codec_specific_settings(struct HDAudioChip *card)
955 BOOL configured = FALSE;
956 ULONG vendor_device_id = get_parameter(0x0, VERB_GET_PARMS_VENDOR_DEVICE, card); // get vendor and device ID from root node
957 UBYTE old;
958 UWORD vendor = (vendor_device_id >> 16);
959 UWORD device = (vendor_device_id & 0xFFFF);
961 card->frequencies = NULL;
962 card->nr_of_frequencies = 0;
963 card->selected_freq_index = 0;
965 card->dac_min_gain = -64.0;
966 card->dac_max_gain = 0;
967 card->dac_step_gain = 1.0;
968 card->speaker_nid = 0; // off
969 card->headphone_nid = 0; // off
970 card->speaker_active = FALSE;
972 D(bug("[HDAudio] vendor = %x, device = %x\n", vendor, device));
974 if (vendor == 0x10EC && forceQuery == FALSE) // Realtek
976 configured = perform_realtek_specific_settings(card, device);
978 else if (vendor == 0x1106 && forceQuery == FALSE) // VIA
980 configured = perform_via_specific_settings(card, device);
982 else if (vendor == 0x111d || vendor == 0x8384 && forceQuery == FALSE) // IDT
984 configured = perform_idt_specific_settings(card, device);
987 if (!configured) // default: fall-back
989 if (interrogate_unknown_chip(card) == FALSE)
991 return FALSE;
995 determine_frequencies(card);
996 return TRUE;
1000 static BOOL perform_realtek_specific_settings(struct HDAudioChip *card, UWORD device)
1002 D(bug("[HDAudio] Found Realtek codec\n"));
1004 if (!(device == 0x662
1005 || device == 0x663
1006 || device == 0x268
1007 || device == 0x269
1008 || device == 0x888))
1010 D(bug("[HDAudio] Unknown Realtek codec.\n"));
1011 return FALSE;
1014 card->dac_nid = 0x2;
1015 card->dac_volume_nids[0] = 0x2;
1016 card->dac_volume_count = 1;
1017 card->adc_nid = 0x8;
1019 card->adc_mixer_nid = 0x23;
1020 card->line_in_nid = 0x1A;
1021 card->mic1_nid = 0x18;
1022 card->mic2_nid = 0x19;
1023 card->cd_nid = 0x1C;
1025 card->adc_mixer_is_mux = FALSE;
1027 // FRONT pin (0x14)
1028 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)
1030 send_command_12(card->codecnr, 0x14, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1031 card->speaker_active = TRUE;
1033 // MIC1 pin (0x18) as input
1034 send_command_12(card->codecnr, card->mic1_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1036 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
1039 // device specific support
1040 if (device == 0x662 || device == 0x663) // Realtek ALC662/663
1042 D(bug("[HDAudio] Adding ALC662/663 specific support\n"));
1044 card->adc_mixer_indices[0] = 2; // line in
1045 card->adc_mixer_indices[1] = 0; // mic1
1046 card->adc_mixer_indices[2] = 1; // mic2
1047 card->adc_mixer_indices[3] = 4; // cd
1048 card->adc_mixer_indices[4] = 8; // mon mixer
1050 card->adc_min_gain = -13.5;
1051 card->adc_max_gain = 33.0;
1052 card->adc_step_gain = 1.5;
1054 // LINE2 pin (0x1B) as second front output (duplicates sound of 0xC (front DAC))
1055 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)
1057 send_command_12(card->codecnr, 0x1B, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1059 // Monitor mixer (0xB): set the first 3 inputs to 0dB and unmute them
1060 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
1062 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
1064 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
1066 // Front DAC (0xC)
1067 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1069 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
1071 // LINE1 pin (0x1A) as input
1072 send_command_12(card->codecnr, card->line_in_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1074 // MIC2 pin (0x19) as input
1075 send_command_12(card->codecnr, card->mic2_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1077 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
1079 else if (device == 0x268)
1081 D(bug("[HDAudio] Adding ALC268 specific support\n"));
1083 card->speaker_nid = 0x14;
1084 card->headphone_nid = 0x15;
1086 card->adc_mixer_indices[0] = 2; // line in
1087 card->adc_mixer_indices[1] = 0; // mic1
1088 card->adc_mixer_indices[2] = 5; // mic2
1089 card->adc_mixer_indices[3] = 3; // cd
1090 card->adc_mixer_indices[4] = 255; // no mon mixer
1092 card->adc_min_gain = -16.5;
1093 card->adc_max_gain = 30.0;
1094 card->adc_step_gain = 1.5;
1096 card->adc_mixer_is_mux = TRUE;
1098 // sum widget before output (0xF)
1099 send_command_4(card->codecnr, 0xF, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute
1101 // sum widget before headphone output (0x10)
1102 send_command_4(card->codecnr, 0x10, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (2 << 8), card); // unmute
1104 // HP-OUT pin (0x15)
1105 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)
1107 send_command_12(card->codecnr, 0x15, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1109 send_command_12(card->codecnr, 0x14, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1111 send_command_12(card->codecnr, 0x15, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1113 else if (device == 0x269) // Dell mini etc.
1115 D(bug("[HDAudio] Adding ALC269 specific support\n"));
1117 card->speaker_nid = 0x14;
1118 card->headphone_nid = 0x15;
1120 card->adc_mixer_indices[0] = 2; // line in
1121 card->adc_mixer_indices[1] = 0; // mic1
1122 card->adc_mixer_indices[2] = 1; // mic2
1123 card->adc_mixer_indices[3] = 4; // cd
1124 card->adc_mixer_indices[4] = 6; // mon mixer
1126 card->adc_min_gain = -17;
1127 card->adc_max_gain = 29.0;
1128 card->adc_step_gain = 1.0;
1130 card->adc_mixer_is_mux = TRUE;
1132 // Front DAC (0xC)
1133 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1135 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
1137 // sum widget before output (0xF)
1138 send_command_4(card->codecnr, 0xF, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute
1140 // sum widget before headphone output (0x10)
1141 send_command_4(card->codecnr, 0x10, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (2 << 8), card); // unmute
1143 // HP-OUT pin (0x15)
1144 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)
1146 send_command_12(card->codecnr, 0x15, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1148 send_command_12(card->codecnr, 0x14, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1150 send_command_12(card->codecnr, 0x15, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1152 else if (device == 0x888) // ALC888
1154 D(bug("[HDAudio] Adding ALC888 specific support\n"));
1156 card->adc_mixer_indices[0] = 2; // line in
1157 card->adc_mixer_indices[1] = 0; // mic1
1158 card->adc_mixer_indices[2] = 1; // mic2
1159 card->adc_mixer_indices[3] = 4; // cd
1160 card->adc_mixer_indices[4] = 10; // mon mixer
1162 card->adc_min_gain = -16.5;
1163 card->adc_max_gain = 30.0;
1164 card->adc_step_gain = 1.5;
1166 card->dac_min_gain = -46.5;
1167 card->dac_max_gain = 0;
1168 card->dac_step_gain = 1.5;
1170 card->dac_volume_nids[0] = 0xC;
1171 card->dac_volume_count = 1;
1173 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1174 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
1177 return TRUE;
1181 static BOOL perform_via_specific_settings(struct HDAudioChip *card, UWORD device)
1183 D(bug("[HDAudio] Found VIA codec\n"));
1185 if (!(device == 0xE721 || device == 0x0397))
1187 D(bug("[HDAudio] Unknown VIA codec.\n"));
1188 return FALSE;
1191 card->dac_nid = 0x10;
1192 card->adc_nid = 0x13;
1194 card->adc_mixer_nid = 0x17;
1195 card->line_in_nid = 0x1B;
1196 card->mic1_nid = 0x1A;
1197 card->mic2_nid = 0x1E;
1198 card->cd_nid = 0x1F;
1200 card->adc_mixer_is_mux = TRUE;
1202 // FRONT pin (0x1C)
1203 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)
1204 send_command_12(card->codecnr, 0x1C, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1206 // MIC1 pin as input
1207 send_command_12(card->codecnr, card->mic1_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1208 send_command_4(card->codecnr, card->mic1_nid, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute input
1211 // device specific support
1212 if (device == 0xE721) // VIA VT1708B
1214 D(bug("[HDAudio] Adding VIA VT1708B specific support\n"));
1216 card->adc_mixer_indices[0] = 3; // line in
1217 card->adc_mixer_indices[1] = 2; // mic1
1218 card->adc_mixer_indices[2] = 4; // mic2
1219 card->adc_mixer_indices[3] = 1; // cd
1220 card->adc_mixer_indices[4] = 255; // mon mixer
1222 card->adc_min_gain = -13.5;
1223 card->adc_max_gain = 33.0;
1224 card->adc_step_gain = 1.5;
1227 return TRUE;
1231 IDT specific settings
1233 information: http://www.idt.com/document/92hd75b-datasheet-92hd75-being-discontinued-see-pdn-notice
1235 TODO: input
1238 static BOOL perform_idt_specific_settings(struct HDAudioChip *card, UWORD device)
1240 D(bug("[HDAudio] Found IDT codec\n"));
1242 if (device == 0x76a0)
1244 D(bug("[HDAudio] STAC9205 detected.\n"));
1246 card->eapd_gpio_mask = 0x1;
1247 set_gpio(card->eapd_gpio_mask, card);
1249 return FALSE;
1252 if (!(device == 0x7608))
1254 D(bug("[HDAudio] Unknown IDT codec.\n"));
1255 return FALSE;
1258 card->dac_nid = 0x10;
1259 card->adc_nid = 0x12;
1260 card->adc_mixer_nid = 0x1C;
1261 card->dac_volume_nids[0] = 0x10;
1262 card->dac_volume_count = 1;
1264 card->speaker_nid = 0x0D;
1265 card->headphone_nid = 0x0A;
1267 card->line_in_nid = 0x0B;
1268 card->mic1_nid = 0x0B;
1269 card->mic2_nid = 0x0C;
1270 card->cd_nid = 0x0E; /* no cd but ...*/
1272 card->adc_mixer_is_mux = TRUE;
1274 /* to not to enable headphone and the speaker at the same time */
1275 card->speaker_active = TRUE;
1277 /* enable eapd. Specs says this is spdif out, but this is required */
1278 send_command_12(card->codecnr, 0x1f, VERB_SET_EAPD, 0x2, card);
1280 /* set connections */
1281 send_command_12 (card->codecnr, 0x0f, VERB_SET_CONNECTION_SELECT, 0, card); /* 48QFN specific */
1282 send_command_12 (card->codecnr, 0x0a, VERB_SET_CONNECTION_SELECT, 0, card); /* headset */
1283 send_command_12 (card->codecnr, 0x0d, VERB_SET_CONNECTION_SELECT, 0, card); /* speaker */
1285 /* set output gains */
1286 send_command_4 (card->codecnr, 0x0f, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1287 send_command_4 (card->codecnr, 0x0a, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1288 send_command_4 (card->codecnr, 0x0d, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1290 /* enable outputs */
1291 send_command_12(card->codecnr, 0x0f, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1292 send_command_12(card->codecnr, 0x0a, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1293 send_command_12(card->codecnr, 0x0d, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1295 if (device == 0x7608)
1297 /* move 0x7608 specific stuff here */
1299 /* Not sure about indices */
1300 card->adc_mixer_indices[0] = 3; // line in
1301 card->adc_mixer_indices[1] = 2; // mic1
1302 card->adc_mixer_indices[2] = 4; // mic2
1303 card->adc_mixer_indices[3] = 1; // cd
1304 card->adc_mixer_indices[4] = 255; // no mon mixer
1306 card->adc_min_gain = 0.0;
1307 card->adc_max_gain = 22.5;
1308 card->adc_step_gain = 1.5;
1310 card->dac_min_gain = -95.25;
1311 card->dac_max_gain = 0.0;
1312 card->dac_step_gain = 0.75;
1315 return TRUE;
1319 static void write_default_pin_config(UBYTE nid, ULONG data,
1320 struct HDAudioChip *card)
1322 UWORD i;
1324 for (i = 0; i < 4; i++)
1326 send_command_12(card->codecnr, nid, 0x71c + i, (UBYTE)data, card);
1327 data >>= 8;
1332 static void update_gpio(UBYTE mask, BOOL on, struct HDAudioChip *card)
1334 ULONG gpio_data, gpio_enable, gpio_dir;
1336 gpio_enable = send_command_12(card->codecnr, card->function_group,
1337 VERB_GET_GPIO_ENABLE, 0, card);
1338 gpio_enable |= mask;
1339 send_command_12(card->codecnr, card->function_group, VERB_SET_GPIO_ENABLE,
1340 gpio_enable, card);
1342 gpio_dir = send_command_12(card->codecnr, card->function_group,
1343 VERB_GET_GPIO_DIR, 0, card);
1344 gpio_dir |= mask;
1345 send_command_12(card->codecnr, card->function_group, VERB_SET_GPIO_DIR,
1346 gpio_dir, card);
1348 gpio_data = send_command_12(card->codecnr, card->function_group,
1349 VERB_GET_GPIO_DATA, 0, card);
1350 if (on)
1351 gpio_data |= mask;
1352 else
1353 gpio_data &= ~mask;
1354 send_command_12(card->codecnr, card->function_group, VERB_SET_GPIO_DATA,
1355 gpio_data, card);
1359 static void set_gpio(UBYTE mask, struct HDAudioChip *card)
1361 update_gpio(mask, TRUE, card);
1365 static UBYTE get_connected_widget(UBYTE nid, UBYTE index,
1366 struct HDAudioChip *card)
1368 UBYTE input_nid = 0;
1369 ULONG connections, entry;
1371 connections = get_parameter(nid, 0xE, card);
1372 if (index < connections)
1374 entry = send_command_12(card->codecnr, nid,
1375 VERB_GET_CONNECTION_LIST_ENTRY, index, card);
1376 input_nid = entry >> ((index % 4) * 8);
1379 return input_nid;
1383 static UBYTE get_selected_widget(UBYTE nid, struct HDAudioChip *card)
1385 UBYTE input_nid = 0;
1386 ULONG connections;
1387 ULONG index;
1389 connections = get_parameter(nid, 0xE, card);
1390 if (connections > 0)
1392 if (connections == 1)
1393 index = 0;
1394 else
1396 index = send_command_12(card->codecnr, nid,
1397 VERB_GET_CONNECTION_SELECT, 0, card);
1400 input_nid = get_connected_widget(nid, index, card);
1403 return input_nid;
1407 /* Adds a widget to the array of volume controlling widgets if it has volume
1408 * control */
1409 static void check_widget_volume(UBYTE nid, struct HDAudioChip *card)
1411 ULONG parm;
1413 parm = get_parameter(nid, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1414 D(bug("[HDAudio] NID %xh: Audio widget caps = %lx\n", nid, parm));
1415 if (parm & 0x4) // OutAmpPre
1417 D(bug("[HDAudio] NID %xh has volume control\n", nid));
1418 card->dac_volume_nids[card->dac_volume_count++] = nid;
1420 else
1422 D(bug("[HDAudio] NID %xh does not have volume control\n", nid));
1427 static BOOL interrogate_unknown_chip(struct HDAudioChip *card)
1429 int dac, adc, front, steps = 0, offset0dB = 0;
1430 double step_size = 0.25;
1431 ULONG parm, widget_caps, nid;
1432 UWORD connections, i;
1433 UBYTE before_front = 0;
1435 D(bug("[HDAudio] Unknown codec, interrogating chip...\n"));
1437 // find out the first PCM DAC
1438 dac = find_widget(card, 0, 0);
1439 D(bug("[HDAudio] DAC NID = %xh\n", dac));
1441 if (dac == 0)
1443 bug("Didn't find DAC!\n");
1444 return FALSE;
1447 card->dac_nid = dac;
1449 check_widget_volume(dac, card);
1451 // find FRONT pin
1452 front = find_widget(card, 4, 0);
1453 D(bug("[HDAudio] Front PIN = %xh\n", front));
1455 if (front == 0)
1457 D(bug("[HDAudio] Didn't find jack/pin for line output!\n"));
1459 else
1461 send_command_4(card->codecnr, front, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute output of FRONT
1462 send_command_12(card->codecnr, front, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1463 send_command_12(card->codecnr, front, VERB_SET_CONNECTION_SELECT, 0, card); // use first input
1464 check_widget_volume(front, card);
1467 // find SPEAKER
1468 if (force_speaker_nid > 0)
1470 D(bug("[HDAudio] Using speaker nid from config file"));
1471 card->speaker_nid = force_speaker_nid;
1473 else
1475 card->speaker_nid = find_widget(card, 4, 1);
1477 D(bug("[HDAudio] Speaker NID = %xh\n", card->speaker_nid));
1479 if (card->speaker_nid != 0)
1481 // check if there is a power amp and if so, enable it
1482 if (get_parameter(card->speaker_nid, VERB_GET_PARMS_PIN_CAPS, card) & PIN_CAPS_EAPD_CAPABLE)
1484 D(bug("[HDAudio] Enabling power amp of speaker\n"));
1485 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1488 // set amplifier gain: unmute output
1489 send_command_4(card->codecnr, card->speaker_nid, VERB_SET_AMP_GAIN,
1490 OUTPUT_AMP_GAIN | INPUT_AMP_GAIN | AMP_GAIN_LR | 0x0, card);
1492 D(bug("[HDAudio] Enabling speaker output\n"));
1493 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1494 card->speaker_active = TRUE;
1495 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_CONNECTION_SELECT, 0, card); // use first input
1497 check_widget_volume(card->speaker_nid, card);
1499 else
1501 D(bug("[HDAudio] No speaker pin found, continuing anyway!\n"));
1504 // Find headphones socket
1505 card->headphone_nid = find_widget(card, 4, 2);
1507 D(bug("[HDAudio] Headphone NID = %xh\n", card->headphone_nid));
1509 if (card->headphone_nid != 0)
1511 send_command_4(card->codecnr, card->headphone_nid, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute headphone
1512 send_command_12(card->codecnr, card->headphone_nid, VERB_SET_PIN_WIDGET_CONTROL, 0xC0, card); // output enabled and headphone enabled
1513 send_command_12(card->codecnr, card->headphone_nid, VERB_SET_CONNECTION_SELECT, 0, card); // use first input
1515 // check if there is a power amp and if so, enable it
1516 if (get_parameter(card->headphone_nid, VERB_GET_PARMS_PIN_CAPS, card) & PIN_CAPS_EAPD_CAPABLE)
1518 D(bug("[HDAudio] Enabling power amp of headphone port\n"));
1519 send_command_12(card->codecnr, card->headphone_nid, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1522 // unmute widget before headphone jack if it's not the DAC
1523 nid = send_command_12(card->codecnr, card->headphone_nid,
1524 VERB_GET_CONNECTION_LIST_ENTRY, 0, card);
1525 if (nid != dac)
1527 connections = get_parameter(nid, 0xE, card);
1528 for (i = 0; i < connections; i++)
1529 send_command_4(card->codecnr, nid, VERB_SET_AMP_GAIN,
1530 INPUT_AMP_GAIN | AMP_GAIN_LR | i << 8, card);
1533 check_widget_volume(card->headphone_nid, card);
1536 // find the node before the front, speaker or HP node
1537 if (front != 0)
1538 nid = front;
1539 else if (card->speaker_nid != 0)
1540 nid = card->speaker_nid;
1541 else if (card->headphone_nid != 0)
1542 nid = card->headphone_nid;
1544 if (nid != 0)
1545 before_front = (UBYTE)send_command_12(card->codecnr, nid,
1546 VERB_GET_CONNECTION_LIST_ENTRY, 0, card);
1548 if (before_front != dac)
1550 D(bug("[HDAudio] The widget before front/speaker/HP (%xh) is not equal to DAC!\n", before_front));
1552 send_command_4(card->codecnr, before_front, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1553 D(bug("[HDAudio] Let's hope it was a mute that now got unmuted!\n"));
1555 check_widget_volume(before_front, card);
1557 else
1559 D(bug("[HDAudio] The widget before front/speaker/HP is equal to DAC.\n"));
1562 for (i = 0; card->dac_volume_nids[i] != 0; i++)
1564 parm = get_parameter(card->dac_volume_nids[i],
1565 VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1566 if ((parm & 0x8) != 0)
1567 parm = get_parameter(card->dac_volume_nids[i],
1568 VERB_GET_PARMS_OUTPUT_AMP_CAPS , card);
1569 else
1570 parm = get_parameter(card->function_group,
1571 VERB_GET_PARMS_OUTPUT_AMP_CAPS, card);
1572 D(bug("[HDAudio] NID %xh: Output amp caps = %lx\n", card->dac_volume_nids[i], parm));
1574 step_size = (((parm >> 16) & 0x7F) + 1) * 0.25;
1575 steps = ((parm >> 8) & 0x7F);
1576 offset0dB = (parm & 0x7F);
1578 if (steps != 0)
1580 card->dac_min_gain = -(offset0dB * step_size);
1581 card->dac_max_gain = card->dac_min_gain + step_size * steps;
1582 card->dac_step_gain = step_size;
1583 D(bug("[HDAudio] Gain step size = %lu * 0.25 dB,"
1584 " min gain = %d, max gain = %d\n",
1585 (((parm >> 16) & 0x7F) + 1), (int) (card->dac_min_gain),
1586 (int) (card->dac_max_gain)));
1590 // find out the first PCM ADC
1591 adc = find_widget(card, 1, 0);
1592 D(bug("[HDAudio] ADC NID = %xh\n", adc));
1594 if (adc != 0)
1596 card->adc_nid = adc;
1598 card->line_in_nid = find_widget(card, 4, 8);
1599 D(bug("[HDAudio] Line-in NID = %xh\n", card->line_in_nid));
1600 card->mic1_nid = find_widget(card, 4, 0xA);
1601 D(bug("[HDAudio] Mic1 NID = %xh\n", card->mic1_nid));
1603 nid = adc;
1604 while (nid != 0)
1606 widget_caps = get_parameter(nid,
1607 VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1608 D(bug("[HDAudio] audio widget caps = %lx\n", widget_caps));
1610 if (((widget_caps >> 20) & 0xF) == 0x3)
1612 card->adc_mixer_nid = nid;
1613 D(bug("[HDAudio] ADC mixer NID = %xh\n", card->adc_mixer_nid));
1614 card->adc_mixer_is_mux = TRUE;
1617 // set amplifier gain and unmute
1618 send_command_4(card->codecnr, nid, VERB_SET_AMP_GAIN,
1619 OUTPUT_AMP_GAIN | INPUT_AMP_GAIN | AMP_GAIN_LR | 0x0, card);
1621 nid = get_selected_widget(nid, card);
1624 if (card->line_in_nid != 0)
1626 send_command_12(card->codecnr, card->line_in_nid,
1627 VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1628 send_command_4(card->codecnr, card->line_in_nid, VERB_SET_AMP_GAIN,
1629 OUTPUT_AMP_GAIN | INPUT_AMP_GAIN | AMP_GAIN_LR | 0x0, card);
1631 if (card->mic1_nid != 0)
1633 send_command_12(card->codecnr, card->mic1_nid,
1634 VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1635 send_command_4(card->codecnr, card->mic1_nid, VERB_SET_AMP_GAIN,
1636 OUTPUT_AMP_GAIN | INPUT_AMP_GAIN | AMP_GAIN_LR | 0x0, card);
1639 else
1640 bug("[HDAudio] Didn't find ADC!\n");
1642 return TRUE;
1646 static UBYTE find_widget(struct HDAudioChip *card, UBYTE type, UBYTE pin_type)
1648 ULONG node_count_response = get_parameter(card->function_group,
1649 VERB_GET_PARMS_NODE_COUNT, card);
1650 UBYTE node_count = node_count_response & 0xFF;
1651 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
1652 UBYTE i;
1653 ULONG config_default;
1655 for (i = 0; i < node_count; i++) // widgets
1657 UBYTE nid = i + starting_node;
1658 ULONG widget_caps, pin_caps, connections;
1660 widget_caps = get_parameter(nid, VERB_GET_PARMS_AUDIO_WIDGET_CAPS,
1661 card);
1663 if (((widget_caps >> 20) & 0xF) == type)
1665 BOOL ok;
1667 if (type == 4) // node is a pin widget
1669 config_default = send_command_12(card->codecnr, nid,
1670 VERB_GET_CONFIG_DEFAULT, 0, card);
1672 if (((config_default >> 20) & 0xF) == pin_type)
1674 D(bug("[HDAudio] Config default for NID %x = %x\n", nid,
1675 config_default));
1676 if ((widget_caps & 1 << 8) != 0)
1677 connections = get_parameter(nid, 0xE, card) & 0x7f;
1678 else
1679 connections = 0;
1680 pin_caps =
1681 get_parameter(nid, VERB_GET_PARMS_PIN_CAPS, card);
1682 switch (pin_type)
1684 case 0x0:
1685 case 0x1:
1686 case 0x2:
1687 case 0x4:
1688 case 0x5:
1689 ok = (pin_caps & PIN_CAPS_OUTPUT_CAPABLE) != 0
1690 && connections != 0;
1691 break;
1692 default:
1693 ok = (pin_caps & PIN_CAPS_INPUT_CAPABLE) != 0;
1696 // check speaker connection type is internal
1697 if (pin_type == 1 && (config_default >> 16 & 0xB) != 3)
1698 ok = FALSE;
1700 // check headphone connection type is mini-jack
1701 if (pin_type == 2 && (config_default >> 16 & 0xF) != 1)
1702 ok = FALSE;
1704 // check microphone connection type is mini-jack
1705 if (pin_type == 0xA && (config_default >> 16 & 0xF) != 1)
1706 ok = FALSE;
1709 else
1710 ok = (widget_caps & 0x1) == 1 && // stereo
1711 ((widget_caps >> 9) & 0x1) == 0; // analogue
1713 if (ok)
1714 return nid;
1718 return 0;
1722 static void determine_frequencies(struct HDAudioChip *card)
1724 ULONG verb = get_parameter(card->dac_nid, 0xA, card);
1725 UWORD samplerate_flags = verb & 0x0FFF;
1726 int i;
1727 ULONG freqs = 0;
1728 BOOL default_freq_found = FALSE;
1730 if (samplerate_flags == 0)
1732 verb = get_parameter(0x1, 0xA, card);
1733 samplerate_flags = verb & 0x0FFF;
1734 D(bug("[HDAudio] dac_nid didn't have a list of sample rates, trying AFG node\n"));
1737 // count number of frequencies
1738 for (i = 0; i < 12; i++)
1740 if (samplerate_flags & (1 << i))
1742 freqs++;
1746 D(bug("[HDAudio] Frequencies found = %lu\n", freqs));
1747 card->frequencies = (struct Freq *) AllocVec(sizeof(struct Freq) * freqs, MEMF_PUBLIC | MEMF_CLEAR);
1748 card->nr_of_frequencies = freqs;
1750 freqs = 0;
1751 for (i = 0; i < 12; i++)
1753 if (samplerate_flags & (1 << i))
1755 set_frequency_info(&(card->frequencies[freqs]), i);
1757 if (card->frequencies[freqs].frequency == 44100 && !default_freq_found)
1759 card->selected_freq_index = freqs; // set default freq index to 44100 Hz
1760 default_freq_found = TRUE;
1763 freqs++;
1767 if (default_freq_found == FALSE)
1769 D(bug("[HDAudio] 44100 Hz is not supported!\n"));
1770 if (freqs > 0)
1772 D(bug("[HDAudio] Setting default frequency to %lu\n", card->frequencies[0].frequency));
1773 card->selected_freq_index = 0;
1780 static void set_frequency_info(struct Freq *freq, UWORD bitnr)
1782 switch (bitnr)
1784 case 0: freq->frequency = 8000;
1785 freq->base44100 = 0;
1786 freq->mult = 0;
1787 freq->div = 5;
1788 break;
1790 case 1: freq->frequency = 11025;
1791 freq->base44100 = 1;
1792 freq->mult = 0;
1793 freq->div = 3;
1794 break;
1796 case 2: freq->frequency = 16000;
1797 freq->base44100 = 0;
1798 freq->mult = 0;
1799 freq->div = 2;
1800 break;
1802 case 3: freq->frequency = 22050;
1803 freq->base44100 = 1;
1804 freq->mult = 0;
1805 freq->div = 1;
1806 break;
1808 case 4: freq->frequency = 32000;
1809 freq->base44100 = 0;
1810 freq->mult = 0;
1811 freq->div = 2;
1812 break;
1814 case 5: freq->frequency = 44100;
1815 freq->base44100 = 1;
1816 freq->mult = 0;
1817 freq->div = 0;
1818 break;
1820 case 6: freq->frequency = 48000;
1821 freq->base44100 = 0;
1822 freq->mult = 0;
1823 freq->div = 0;
1824 break;
1826 case 7: freq->frequency = 88200;
1827 freq->base44100 = 1;
1828 freq->mult = 1;
1829 freq->div = 0;
1830 break;
1832 case 8: freq->frequency = 96000;
1833 freq->base44100 = 0;
1834 freq->mult = 1;
1835 freq->div = 0;
1836 break;
1838 case 9: freq->frequency = 176400;
1839 freq->base44100 = 1;
1840 freq->mult = 3;
1841 freq->div = 0;
1842 break;
1844 case 10: freq->frequency = 192000;
1845 freq->base44100 = 0;
1846 freq->mult = 3;
1847 freq->div = 0;
1848 break;
1850 default:
1851 D(bug("[HDAudio] Unsupported frequency!\n"));
1852 break;
1857 void set_monitor_volumes(struct HDAudioChip *card, double dB)
1859 int i;
1860 int dB_steps = (int) ((dB + 34.5) / 1.5);
1862 if (dB_steps < 0)
1864 dB_steps = 0;
1866 else if (dB_steps > 31)
1868 dB_steps = 31;
1871 #if 0
1872 for (i = 0; i < 9; i++)
1874 if (i == 0 || i == 1 || i == 2 || i == 4)
1876 send_command_4(card->codecnr, 0xB, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (i << 8) | dB_steps, card);
1878 else // mute
1880 send_command_4(card->codecnr, 0xB, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (i << 8) | (1 << 7), card);
1883 #endif
1887 void set_adc_input(struct HDAudioChip *card)
1889 int i;
1891 if (card->input >= INPUTS)
1893 card->input = 0;
1896 if (card->adc_mixer_is_mux == TRUE)
1898 D(bug("[HDAudio] Selecting ADC input %d\n", card->adc_mixer_indices[card->input]));
1899 send_command_12(card->codecnr, card->adc_mixer_nid, VERB_SET_CONNECTION_SELECT,
1900 card->adc_mixer_indices[card->input], card);
1901 return;
1903 else
1905 for (i = 0; i < INPUTS; i++)
1907 if (card->adc_mixer_indices[i] != 255) // input is present
1909 if (i == card->input) // unmute or select
1911 D(bug("[HDAudio] Unmuting ADC input %d\n", card->adc_mixer_indices[i]));
1912 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN,
1913 INPUT_AMP_GAIN | AMP_GAIN_LR | (card->adc_mixer_indices[i] << 8), card);
1915 else // mute
1917 D(bug("[HDAudio] Muting ADC input %d\n", card->adc_mixer_indices[i]));
1918 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN,
1919 INPUT_AMP_GAIN | AMP_GAIN_LR | (card->adc_mixer_indices[i] << 8) | (1 << 7), card);
1928 void set_adc_gain(struct HDAudioChip *card, double dB)
1930 int i;
1931 int dB_steps = (int) ( (dB - card->adc_min_gain) / card->adc_step_gain);
1933 if (dB_steps < 0)
1935 dB_steps = 0;
1938 if (card->adc_mixer_is_mux == TRUE)
1940 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
1942 else
1944 send_command_4(card->codecnr, card->adc_nid, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
1949 void set_dac_gain(struct HDAudioChip *card, double dB)
1951 int i;
1952 int dB_steps = (int) ( (dB - card->dac_min_gain) / card->dac_step_gain);
1954 if (dB_steps < 0)
1956 dB_steps = 0;
1959 for (i = 0; i < card->dac_volume_count; i++)
1960 send_command_4(card->codecnr, card->dac_volume_nids[i],
1961 VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
1965 void setForceQuery(void)
1967 forceQuery = TRUE;
1971 void setDumpAll(void)
1973 dumpAll = TRUE;
1977 void setForceSpeaker(int speaker_nid)
1979 force_speaker_nid = speaker_nid;
1984 BOOL is_jack_connected(struct HDAudioChip *card, UBYTE NID)
1986 ULONG result;
1988 send_command_12(card->codecnr, NID, VERB_EXECUTE_PIN_SENSE, 0, card);
1989 udelay(2000);
1990 result = send_command_12(card->codecnr, NID, VERB_GET_PIN_SENSE, 0, card);
1992 if (result & 0x80000000)
1994 D(bug("[HDAudio] jack connected\n"));
1995 return TRUE;
1997 else
1999 D(bug("[HDAudio] jack disconnected\n"));
2000 return FALSE;
2006 void detect_headphone_change(struct HDAudioChip *card)
2008 if (card->speaker_nid != 0 &&
2009 card->headphone_nid != 0)
2011 if (card->speaker_active &&
2012 is_jack_connected(card, card->headphone_nid)) // disable speaker
2014 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x0, card); // output disabled
2015 card->speaker_active = FALSE;
2017 else if (card->speaker_active == FALSE &&
2018 is_jack_connected(card, card->headphone_nid) == FALSE) // enable speaker
2020 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
2021 card->speaker_active = TRUE;