revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / AHI / Drivers / HDAudio / misc.c
blob84eb8f1de0c7f257b0e84322daefd7c008d37c1d
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.
11 (C) Copyright 2010-2019 The AROS Dev Team.
13 The Initial Developer of the Original Code is Davy Wentzler.
15 All Rights Reserved.
18 #include <config.h>
20 #include <exec/memory.h>
21 #include <proto/expansion.h>
23 #include <proto/dos.h>
24 #ifdef __AROS__
25 #include <aros/debug.h>
26 #endif
27 #include <math.h>
29 #include "library.h"
30 #include "regs.h"
31 #include "interrupt.h"
32 #include "misc.h"
33 #include "pci_wrapper.h"
36 /* Public functions in main.c */
37 static void perform_controller_specific_settings(struct HDAudioChip *card);
38 int card_init(struct HDAudioChip *card);
39 void card_cleanup(struct HDAudioChip *card);
40 static BOOL allocate_corb(struct HDAudioChip *card);
41 static BOOL allocate_rirb(struct HDAudioChip *card);
42 static BOOL allocate_pos_buffer(struct HDAudioChip *card);
43 static BOOL alloc_streams(struct HDAudioChip *card);
44 static BOOL perform_codec_specific_settings(struct HDAudioChip *card);
45 static void determine_frequencies(struct HDAudioChip *card);
46 static void set_frequency_info(struct Freq *freq, UWORD bitnr);
47 static BOOL reset_chip(struct HDAudioChip *card);
48 static void codec_discovery(struct HDAudioChip *card);
49 static ULONG get_response(struct HDAudioChip *card);
50 static BOOL perform_realtek_specific_settings(struct HDAudioChip *card, UWORD device);
51 static BOOL perform_via_specific_settings(struct HDAudioChip *card, UWORD device);
52 static BOOL perform_idt_specific_settings(struct HDAudioChip *card, UWORD device);
53 static BOOL perform_ad_specific_settings(struct HDAudioChip *card,
54 UWORD device);
55 static void set_gpio(UBYTE mask, struct HDAudioChip *card);
56 static BOOL interrogate_unknown_chip(struct HDAudioChip *card);
57 static UBYTE find_widget(struct HDAudioChip *card, UBYTE type, UBYTE pin_type);
58 static BOOL power_up_all_nodes(struct HDAudioChip *card);
60 struct Device *TimerBase = NULL;
61 struct timerequest *TimerIO = NULL;
62 struct MsgPort *replymp = NULL;
63 static BOOL forceQuery = FALSE;
64 static BOOL dumpAll = FALSE;
65 static int force_speaker_nid = 0;
66 //void AddResetHandler(struct HDAudioChip *card);
69 #ifdef __AROS__
70 #define DebugPrintF bug
71 INTGW(static, void, playbackinterrupt, PlaybackInterrupt);
72 INTGW(static, void, recordinterrupt, RecordInterrupt);
73 INTGW(static, ULONG, cardinterrupt, CardInterrupt);
74 #endif
76 void micro_delay(unsigned int val)
78 replymp = (struct MsgPort *) CreateMsgPort();
79 if (!replymp)
81 D(bug("[HDAudio] Could not create the reply port!\n"));
82 return;
85 TimerIO = (struct timerequest *) CreateIORequest(replymp, sizeof(struct timerequest));
87 if (TimerIO == NULL)
89 D(bug("[HDAudio] Out of memory.\n"));
90 return;
93 if (OpenDevice((CONST_STRPTR) "timer.device", UNIT_MICROHZ, (struct IORequest *) TimerIO, 0) != 0)
95 D(bug("[HDAudio] Unable to open 'timer.device'.\n"));
96 return;
98 else
100 TimerBase = (struct Device *) TimerIO->tr_node.io_Device;
103 TimerIO->tr_node.io_Command = TR_ADDREQUEST; /* Add a request. */
104 TimerIO->tr_time.tv_secs = 0; /* 0 seconds. */
105 TimerIO->tr_time.tv_micro = val; /* 'val' micro seconds. */
106 DoIO((struct IORequest *) TimerIO);
107 CloseDevice((struct IORequest *) TimerIO);
108 DeleteIORequest((struct IORequest *) TimerIO);
109 TimerIO = NULL;
111 if (replymp)
113 DeleteMsgPort(replymp);
118 /******************************************************************************
119 ** DriverData allocation ******************************************************
120 ******************************************************************************/
122 struct HDAudioChip* AllocDriverData(APTR dev, struct DriverBase* AHIsubBase)
124 struct HDAudioChip* card;
125 UWORD command_word;
126 BOOL success = TRUE;
128 card = (struct HDAudioChip *) AllocVec(sizeof(struct HDAudioChip), MEMF_PUBLIC | MEMF_CLEAR);
130 if (card == NULL)
132 Req("Unable to allocate driver structure.");
133 return NULL;
136 card->ahisubbase = AHIsubBase;
138 card->interrupt.is_Node.ln_Type = IRQTYPE;
139 card->interrupt.is_Node.ln_Pri = 0;
140 card->interrupt.is_Node.ln_Name = (char *) LibName;
141 #ifdef __AROS__
142 card->interrupt.is_Code = (void(*)(void)) &cardinterrupt;
143 #else
144 card->interrupt.is_Code = (void(*)(void)) CardInterrupt;
145 #endif
146 card->interrupt.is_Data = (APTR) card;
148 card->playback_interrupt.is_Node.ln_Type = IRQTYPE;
149 card->playback_interrupt.is_Node.ln_Pri = 0;
150 card->playback_interrupt.is_Node.ln_Name = (char *) LibName;
151 #ifdef __AROS__
152 card->playback_interrupt.is_Code = (APTR)&playbackinterrupt;
153 #else
154 card->playback_interrupt.is_Code = PlaybackInterrupt;
155 #endif
156 card->playback_interrupt.is_Data = (APTR) card;
158 card->record_interrupt.is_Node.ln_Type = IRQTYPE;
159 card->record_interrupt.is_Node.ln_Pri = 0;
160 card->record_interrupt.is_Node.ln_Name = (char *) LibName;
161 #ifdef __AROS__
162 card->record_interrupt.is_Code = (APTR)&recordinterrupt;
163 #else
164 card->record_interrupt.is_Code = RecordInterrupt;
165 #endif
166 card->record_interrupt.is_Data = (APTR) card;
168 command_word = inw_config(PCI_COMMAND, dev);
169 command_word |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
170 outw_config(PCI_COMMAND, command_word, dev);
172 card->pci_dev = dev;
173 card->pci_master_enabled = TRUE;
175 card->iobase = ahi_pci_get_base_address(0, dev);
176 card->length = ahi_pci_get_base_size(0, dev);
177 card->chiprev = inb_config(PCI_REVISION_ID, dev);
178 card->model = inb_config(PCI_SUBSYSTEM_ID, dev);
180 perform_controller_specific_settings(card);
182 ahi_pci_add_intserver(&card->interrupt, dev);
184 /* Initialize chip */
185 if (card_init(card) < 0)
187 D(bug("[HDAudio] Unable to initialize Card subsystem.\n"));
189 success = FALSE;
192 card->interrupt_added = TRUE;
194 card->card_initialized = TRUE;
195 card->input = 0;
196 card->output = 0;
197 card->monitor_volume = (unsigned long) (0x10000 * pow (10.0, -6.0 / 20.0)); // -6 dB
198 card->input_gain = 0x10000; // 0dB
199 card->output_volume = 0x10000; // 0dB
201 if (success)
203 set_monitor_volumes(card, -6.0); // -6dB monitor volume
206 if (!success)
208 FreeDriverData(card, AHIsubBase);
209 card = NULL;
212 return card;
216 /******************************************************************************
217 ** DriverData deallocation ****************************************************
218 ******************************************************************************/
220 void FreeDriverData(struct HDAudioChip* card, struct DriverBase* AHIsubBase)
222 if (card != NULL)
224 if (card->pci_dev != NULL)
226 if (card->card_initialized)
228 card_cleanup(card);
231 if (card->pci_master_enabled)
233 UWORD cmd;
235 cmd = inw_config(PCI_COMMAND, card->pci_dev);
236 cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
237 outw_config(PCI_COMMAND, cmd, card->pci_dev);
241 if (card->interrupt_added)
243 ahi_pci_rem_intserver(&card->interrupt, card->pci_dev);
246 FreeVec(card);
250 #define CNT_VEN_ID_ATI_SB 0x437B1002
251 #define CNT_VEN_ID_ATI_SB2 0x43831002
252 #define CNT_VEN_ID_ATI_HUDSON 0x780D1022
253 #define CNT_VEN_ID_NVIDIA 0x10DE
255 static const UWORD intel_no_snoop_list[] =
257 0x2668,
258 0x27d8,
259 0x269a,
260 0x284b,
261 0x293e,
262 0x293f,
263 0x3a3e,
264 0x3a6e,
268 /* This is the controller specific portion, for fixes to southbridge */
269 static void perform_controller_specific_settings(struct HDAudioChip *card)
271 ULONG data, subsystem;
272 ULONG mask = (1 << 16) - 1;
273 UWORD i, vendor_id, product_id;
274 BOOL snoop = TRUE;
276 /* Get vendor/product/subsystem IDs */
277 data = inl_config(0x0, card->pci_dev);
278 vendor_id = inw_config(0x0, card->pci_dev);
279 product_id = inw_config(0x2, card->pci_dev);
280 D(bug("DEBUG: Controller Vendor ID: %x\n", data));
281 subsystem = inl_config(0x2C, card->pci_dev);
283 /* Check for Intel controllers that need snoop */
284 if (vendor_id == 0x8086)
286 D(bug("[HDAudio] Intel controller detected, checking if snooping needed\n"));
287 for (i = 0; intel_no_snoop_list[i] != 0; i++)
289 if (intel_no_snoop_list[i] == product_id)
291 snoop = FALSE;
295 if (snoop)
297 D(bug("[HDAudio] Enabling snooping\n"));
298 data = inw_config(0x78, card->pci_dev);
299 data &= ~0x800;
300 outw_config(0x78, data, card->pci_dev);
304 /* Check for ATI Southbridge or AMD Hudson controller */
305 if (data == CNT_VEN_ID_ATI_SB || data == CNT_VEN_ID_ATI_SB2 || data == CNT_VEN_ID_ATI_HUDSON)
307 D(bug("[HDAudio] ATI SB/AMD Hudson controller detected, setting snoop to on.\n"));
308 data = inb_config(0x42, card->pci_dev);
309 data &= ~0x07;
310 data |= 0x02;
311 outb_config(0x42, data, card->pci_dev);
314 /* Check for NVidia MCP controller */
315 if ((data & mask) == CNT_VEN_ID_NVIDIA )
317 D(bug("[HDAudio] NVidia MCP controller detected, setting snoop to on.\n"));
318 data = inb_config(0x4E, card->pci_dev);
319 data |= 0x0F;
320 outb_config(0x4E, data, card->pci_dev);
322 data = inb_config(0x4D, card->pci_dev);
323 data |= 0x01;
324 outb_config(0x4D, data, card->pci_dev);
326 data = inb_config(0x4C, card->pci_dev);
327 data |= 0x01;
328 outb_config(0x4C, data, card->pci_dev);
331 /* Check for HP Compaq laptops with incorrect IRQ number */
332 if (subsystem == 0x30aa103c)
334 D(bug("[HDAudio] HP Compaq nc6320 laptop detected, correcting IRQ\n"));
335 data = inb_config(0x3C, card->pci_dev);
336 if (data == 10)
337 outb_config(0x3C, 11, card->pci_dev);
339 else if (subsystem == 0x30c0103c)
341 D(bug("[HDAudio] HP Compaq 6710b laptop detected, correcting IRQ\n"));
342 data = inb_config(0x3C, card->pci_dev);
343 if (data == 10)
344 outb_config(0x3C, 5, card->pci_dev);
348 int card_init(struct HDAudioChip *card)
350 int i;
352 if (reset_chip(card) == FALSE)
354 D(bug("[HDAudio] Reset chip failed\n"));
355 return -1;
358 // 4.3 Codec discovery: 15 codecs can be connected, bits that are on indicate a codec
359 card->codecbits = pci_inw(HD_STATESTS, card);
361 if (card->codecbits == 0)
363 D(bug("[HDAudio] No codecs found!\n"));
364 return -1;
367 if (alloc_streams(card) == FALSE)
369 D(bug("[HDAudio] Allocating streams failed!\n"));
370 return -1;
373 if (allocate_corb(card) == FALSE)
375 D(bug("[HDAudio] Allocating CORB failed!\n"));
376 return -1;
379 if (allocate_rirb(card) == FALSE)
381 D(bug("[HDAudio] Allocating RIRB failed!\n"));
382 return -1;
385 if (allocate_pos_buffer(card) == FALSE)
387 D(bug("[HDAudio] Allocating position buffer failed!\n"));
388 return -1;
391 // enable interrupts
392 pci_outl(HD_INTCTL_CIE | HD_INTCTL_GLOBAL, HD_INTCTL, card);
393 udelay(200);
395 /* Find the first codec with an audio function group */
396 for (i = 0; i < 16; i++)
398 if (card->codecbits & (1 << i))
400 card->codecnr = i;
401 if (power_up_all_nodes(card))
402 break;
406 if (perform_codec_specific_settings(card) == FALSE)
408 return -1;
411 if (dumpAll)
413 codec_discovery(card);
416 D(bug("[HDAudio] card_init() was a success!\n"));
418 return 0;
422 void card_cleanup(struct HDAudioChip *card)
427 static BOOL reset_chip(struct HDAudioChip *card)
429 int counter = 0;
430 UBYTE ubval = 0;
431 UBYTE tcsel;
434 Intel® HIgh Definition Audio Traffic Class Assignment (TCSEL), bits 0:2 -> 000 = TC0
435 This register assigned the value to be placed in the TC field. CORB and RIRB data will always be
436 assigned TC0.
438 #define TCSEL_PCIREG 0x44
439 tcsel = inb_config(TCSEL_PCIREG, card->pci_dev);
440 tcsel &= ~0x07;
441 outb_config(TCSEL_PCIREG, tcsel, card->pci_dev);
443 pci_outb(0, HD_CORBCTL, card);
444 pci_outb(0, HD_RIRBCTL, card);
446 // Clear STATESTS just to be sure. After reset, this register holds the ID's of the connected codecs
447 pci_outb(0xFF, HD_STATESTS, card);
449 // Transition to reset state
450 outl_clearbits(1, HD_GCTL, card);
452 // Wait for bit 0 to read 0
453 for (counter = 0; counter < 1000; counter++)
455 ubval = pci_inb(HD_GCTL, card);
457 if ((ubval & 0x1) == 0)
459 break;
462 udelay(100);
465 if (counter == 1000)
467 D(bug("[HDAudio] Couldn't reset chip!\n"));
468 return FALSE;
471 udelay(100);
472 // 4.2.2. Take controller out of reset
473 outl_setbits(1, HD_GCTL, card);
476 // Wait for bit 0 to read 1
477 for (counter = 0; counter < 1000; counter++)
479 ubval = pci_inb(HD_GCTL, card);
481 if ((ubval & 0x1) == 1)
483 D(bug("[HDAudio] Codec came out of reset!\n"));
484 break;
487 udelay(100);
490 if (counter == 1000)
492 D(bug("[HDAudio] Couldn't reset chip!\n"));
493 return FALSE;
496 // The software must wait 250 microseconds after reading CRST as 1, but it's suggested to wait longer
497 udelay(1000);
499 // do not accept unsolicited events for now (jack sense etc.)
500 //outl_setbits((1 << 8), HD_GCTL, card); // accept unsolicited events
502 return TRUE;
506 static void codec_discovery(struct HDAudioChip *card)
508 UWORD i, j;
510 ULONG subnode_count_response = get_parameter(card->function_group,
511 VERB_GET_PARMS_NODE_COUNT, card);
512 UBYTE subnode_count = subnode_count_response & 0xFF;
513 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
514 ULONG connections = 0, config_default;
516 bug("[HDAudio] Subnode count = %d, sub_starting_node = %x\n",
517 subnode_count, sub_starting_node);
519 //bug("[HDAudio] Audio supported = %lx\n",
520 // get_parameter(card->function_group, 0xA, card));
521 //bug("[HDAudio] Sup streams = %lx\n",
522 // get_parameter(card->function_group, 0xB, card));
524 for (i = 0; i < subnode_count; i++) // widgets
526 const ULONG NID = i + sub_starting_node;
527 ULONG widget_caps;
529 widget_caps =
530 get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
532 bug("[HDAudio] Subnode %x has caps %lx\n", NID, widget_caps);
533 bug("[HDAudio] %xh: Supported PCM size/rate = %lx\n", NID,
534 get_parameter(NID, VERB_GET_PARMS_SUPPORTED_PCM_SIZE_RATE, card));
536 if (AUDIO_WIDGET_CAPS(widget_caps) == 0x4) // pin complex
538 bug("[HDAudio] PIN: caps = %lx\n",
539 get_parameter(NID, VERB_GET_PARMS_PIN_CAPS, card));
540 bug("[HDAudio] PIN: Connected = %s\n",
541 is_jack_connected(card, NID) ? "TRUE" : "FALSE");
543 config_default = send_command_12(card->codecnr, NID,
544 VERB_GET_CONFIG_DEFAULT, 0, card);
545 bug("[HDAudio] PIN: Configuration Default = %08lx\n",
546 config_default);
549 bug("[HDAudio] %xh: Input Amp caps = %lx\n", NID,
550 get_parameter(NID, 0xD, card));
551 bug("[HDAudio] %xh: Output Amp caps = %lx\n", NID,
552 get_parameter(NID, 0x12, card));
554 connections = get_parameter(NID, 0xE, card);
555 bug("[HDAudio] %xh: Conn list len = %lx\n", NID, connections);
556 if (connections > 0) // print connections
558 ULONG entry = 0;
560 bug("[HDAudio] %xh: Incoming connection list: ", NID);
561 for (entry = 0; entry < connections; entry+=4)
563 ULONG connectedTo = send_command_12(card->codecnr, NID,
564 VERB_GET_CONNECTION_LIST_ENTRY, entry, card);
566 bug("%lx, ", connectedTo);
568 bug("\n");
571 bug("[HDAudio] %xh: Supported power state = %lx\n", NID,
572 get_parameter(NID, 0xF, card));
574 ULONG n;
575 n = send_command_12(card->codecnr, NID,
576 VERB_GET_CONNECTION_SELECT, 0, card);
577 bug("[HDAudio] %xh: Connection selection = %lx\n", NID, n);
579 bug("[HDAudio] %xh: Input Amp gain =", NID);
580 for (j = 0; j < connections; j++)
582 if (j != 0) bug(",");
583 n = send_command_4(card->codecnr, NID, 0xB, j, card);
584 bug(" %ld", n & 0x7f);
585 if (n & 0x80) bug(" (muted)");
587 bug("\n");
589 n = send_command_4(card->codecnr, NID, 0xB, 0x8000, card);
590 bug("[HDAudio] %xh: Output Amp gain = %ld%s\n", NID, n & 0x7f,
591 n & 0x80 ? " (muted)" : "");
593 n = send_command_4(card->codecnr, NID, 0xA, 0, card);
594 bug("[HDAudio] %xh: Format = %lx\n", NID, n);
595 n = send_command_12(card->codecnr, NID, 0xF05, 0, card);
596 bug("[HDAudio] %xh: Power state = %lx\n", NID, n);
597 n = send_command_12(card->codecnr, NID, 0xF06, 0, card);
598 bug("[HDAudio] %xh: Stream = %lx\n", NID, n);
599 n = send_command_12(card->codecnr, NID, 0xF07, 0, card);
600 bug("[HDAudio] %xh: Pin widget control = %lx\n", NID, n);
601 bug("[HDAudio] --------------------------------\n\n");
606 static BOOL power_up_all_nodes(struct HDAudioChip *card)
608 int i;
609 ULONG node_count_response = get_parameter(0, VERB_GET_PARMS_NODE_COUNT, card);
610 UBYTE node_count = node_count_response & 0xFF;
611 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
612 BOOL audio_found = FALSE;
614 D(bug("[HDAudio] power up\n"));
615 send_command_12(card->codecnr, 1, VERB_SET_POWER_STATE , 0, card); // send function reset to audio node, this should power up all nodes
616 udelay(20000);
618 for (i = 0; i < node_count && !audio_found; i++)
620 ULONG function_group_response = get_parameter(starting_node + i, VERB_GET_PARMS_FUNCTION_GROUP_TYPE, card);
621 UBYTE function_group = function_group_response & 0xFF;
623 if (function_group == AUDIO_FUNCTION)
625 int j;
627 ULONG subnode_count_response = get_parameter(starting_node + i, VERB_GET_PARMS_NODE_COUNT, card);
628 UBYTE subnode_count = subnode_count_response & 0xFF;
629 UBYTE sub_starting_node = (subnode_count_response >> 16) & 0xFF;
631 audio_found = TRUE;
632 card->function_group = starting_node + i;
634 for (j = 0; j < subnode_count; j++) // widgets
636 const ULONG NID = j + sub_starting_node;
637 ULONG widget_caps;
639 widget_caps = get_parameter(NID, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
642 if (AUDIO_WIDGET_POWER_CONTROL(widget_caps) == 1) // power control
644 ULONG power_state = 0;
646 power_state = send_command_12(card->codecnr, NID, VERB_GET_POWER_STATE, 0, card);
647 D(bug("[HDAudio] %xh: power state = %xh\n", NID, power_state));
649 if (power_state != 0)
651 D(bug("[HDAudio] Setting power state to 0\n"));
652 send_command_12(card->codecnr, NID, VERB_SET_POWER_STATE, 0, card);
660 return audio_found;
664 // allocates memory on the given boundary. Returns the aligned memory address and the non-aligned memory address
665 // in NonAlignedAddress, if not NULL.
666 void *pci_alloc_consistent(size_t size, APTR *NonAlignedAddress, unsigned int boundary)
668 void* address;
669 unsigned long a;
671 address = (void *) AllocVec(size + boundary, MEMF_PUBLIC | MEMF_CLEAR);
673 if (address != NULL)
675 a = (unsigned long) address;
676 a = (a + boundary - 1) & ~(boundary - 1);
677 address = (void *) a;
680 if (NonAlignedAddress)
682 *NonAlignedAddress = address;
685 return address;
689 void pci_free_consistent(void* addr)
691 FreeVec(addr);
695 ULONG get_parameter(UBYTE node, UBYTE parameter, struct HDAudioChip *card)
697 return send_command_12(card->codecnr, node, VERB_GET_PARMS, parameter, card);
701 ULONG send_command_4(UBYTE codec, UBYTE node, UBYTE verb, UWORD payload, struct HDAudioChip *card)
703 UWORD wp = pci_inw(HD_CORBWP, card) & 0xFF;
704 ULONG data = (codec << 28) | (node << 20) | (verb << 16) | payload;
706 if (wp == card->corb_entries - 1)
708 wp = 0;
710 else
712 wp++;
715 //bug("Sending command %lx\n", data);
717 card->corb[wp] = data;
718 pci_outw(wp, HD_CORBWP, card);
720 return get_response(card);
724 ULONG send_command_12(UBYTE codec, UBYTE node, UWORD verb, UBYTE payload, struct HDAudioChip *card)
726 UWORD wp = pci_inw(HD_CORBWP, card) & 0xFF;
727 ULONG data = (codec << 28) | (node << 20) | (verb << 8) | payload;
729 if (wp == card->corb_entries - 1)
731 wp = 0;
733 else
735 wp++;
738 //bug("Sending command %lx\n", data);
740 card->corb[wp] = data;
741 pci_outw(wp, HD_CORBWP, card);
743 return get_response(card);
747 ULONG get_response(struct HDAudioChip *card)
749 int timeout = 10000;
750 int i;
751 UBYTE rirb_wp;
753 udelay(20); //
755 // wait for interrupt
756 for (i = 0; i < timeout; i++)
758 if (card->rirb_irq > 0)
760 card->rirb_irq--;
761 break;
763 udelay(10);
766 if (i == timeout)
768 D(bug("[HDAudio] No IRQ!\n"));
771 for (i = 0; i < timeout; i++)
773 rirb_wp = pci_inb(HD_RIRBWP, card);
775 if (rirb_wp == card->rirb_rp) // strange, we expect the wp to have increased
777 D(bug("[HDAudio] WP has not increased! rirb_wp = %u, rirb_rp = %lu\n", rirb_wp, card->rirb_rp));
778 udelay(5000);
780 else
782 if ( ((rirb_wp > card->rirb_rp) &&
783 ((rirb_wp - card->rirb_rp) >= 2)) ||
785 ((rirb_wp < card->rirb_rp) &&
786 ( ((int) rirb_wp) + card->rirb_entries) - card->rirb_rp >= 2))
788 D(bug("[HDAudio] Write pointer is more than 1 step ahead!\n"));
791 ULONG addr;
792 ULONG response, response_ex; // 3.6.5 Response Input Ring Buffer
794 card->rirb_rp = rirb_wp;
795 addr = card->rirb_rp;
796 addr *= 2; // 64-bit entries
798 response = card->rirb[addr];
799 response_ex = card->rirb[addr + 1];
800 if (response_ex & 0x10) // unsolicited
802 D(bug("[HDAudio] Unsolicited response! Skipping!\n"));
804 else
806 //bug("Response is %lx\n", response);
807 return response;
812 D(bug("[HDAudio] ERROR in get_response() card->rirb_rp = %u!rirb_wp = %u\n", card->rirb_rp, rirb_wp));
813 return 0;
817 static BOOL allocate_corb(struct HDAudioChip *card)
819 UBYTE corbsize_reg;
821 // 4.4.1.3 Initialize the CORB
823 // stop the DMA
824 outb_clearbits(HD_CORBRUN, HD_CORBCTL, card);
826 // set CORB size
827 corbsize_reg = pci_inb(HD_CORBSIZE, card);
828 if (corbsize_reg & (1 << 6))
830 pci_outb(0x2, HD_CORBSIZE, card);
831 card->corb_entries = 256;
833 else if (corbsize_reg & (1 << 5))
835 pci_outb(0x1, HD_CORBSIZE, card);
836 card->corb_entries = 16;
838 else if (corbsize_reg & (1 << 4))
840 pci_outb(0x0, HD_CORBSIZE, card);
841 card->corb_entries = 2;
844 // Allocate CORB memory
845 card->corb = pci_alloc_consistent(4 * card->corb_entries, NULL, 128); // todo: virtual
847 // Set CORB base
848 #if defined(__AROS__) && (__WORDSIZE==64)
849 pci_outl((ULONG)((IPTR)card->corb & 0xFFFFFFFF), HD_CORB_LOW, card);
850 pci_outl((ULONG)(((IPTR)card->corb >> 32) & 0xFFFFFFFF), HD_CORB_HIGH, card);
851 #else
852 pci_outl((ULONG) card->corb, HD_CORB_LOW, card);
853 pci_outl(0, HD_CORB_HIGH, card);
854 #endif
856 //bug("Before reset rp: corbrp = %x\n", pci_inw(0x4A, card));
858 // Reset read pointer: if we set this, the CORB will not work??
859 //outw_setbits(HD_CORBRPRST, HD_CORBRP, card);
861 //bug("After reset rp: corbrp = %x\n", pci_inw(0x4A, card));
863 // Write a 0 to the write pointer to clear
864 pci_outw(0, HD_CORBWP, card);
866 // run it
867 outb_setbits(HD_CORBRUN, HD_CORBCTL, card);
869 if (card->corb)
871 return TRUE;
873 else
875 return FALSE;
880 static BOOL allocate_rirb(struct HDAudioChip *card)
882 UBYTE rirbsize_reg;
884 // 4.4.2.2 Initialize the RIRB
886 // stop the DMA
887 outb_clearbits(HD_RIRBRUN, HD_RIRBCTL, card);
889 // set rirb size
890 rirbsize_reg = pci_inb(HD_RIRBSIZE, card);
891 if (rirbsize_reg & (1 << 6))
893 pci_outb(0x2, HD_RIRBSIZE, card);
894 card->rirb_entries = 256;
896 else if (rirbsize_reg & (1 << 5))
898 pci_outb(0x1, HD_RIRBSIZE, card);
899 card->rirb_entries = 16;
901 else if (rirbsize_reg & (1 << 4))
903 pci_outb(0x0, HD_RIRBSIZE, card);
904 card->rirb_entries = 2;
907 card->rirb_irq = 0;
909 // Allocate rirb memory
910 card->rirb = pci_alloc_consistent(4 * 2 * card->rirb_entries, NULL, 128); // todo: virtual
911 card->rirb_rp = 0;
913 // Set rirb base
914 #if defined(__AROS__) && (__WORDSIZE==64)
915 pci_outl((ULONG)((IPTR)card->rirb & 0xFFFFFFFF), HD_RIRB_LOW, card);
916 pci_outl((ULONG)(((IPTR)card->rirb >> 32) & 0xFFFFFFFF), HD_RIRB_HIGH, card);
917 #else
918 pci_outl((ULONG) card->rirb, HD_RIRB_LOW, card);
919 pci_outl(0, HD_RIRB_HIGH, card);
920 #endif
922 // Reset read pointer: if we set this, it will not come out of reset??
923 //outw_setbits(HD_RIRBWPRST, HD_RIRBWP, card);
925 // Set N=1, which generates an interrupt for every response
926 pci_outw(1, HD_RINTCNT, card);
928 pci_outb(0x5, HD_RIRBSTS, card);
930 // run it and enable IRQ
931 outb_setbits(HD_RIRBRUN | HD_RINTCTL | 0x4, HD_RIRBCTL, card);
933 if (card->rirb)
935 return TRUE;
937 else
939 return FALSE;
945 static BOOL allocate_pos_buffer(struct HDAudioChip *card)
947 card->dma_position_buffer = pci_alloc_consistent(sizeof(APTR) * 36, NULL, 128);
949 //warning: DMA poition buffer is unused?
950 #if defined(__AROS__) && (__WORDSIZE==64)
951 pci_outl(0, HD_DPLBASE, card);
952 pci_outl(0, HD_DPUBASE, card);
953 #else
954 //pci_outl((ULONG) card->dma_position_buffer | HD_DPLBASE_ENABLE, HD_DPLBASE, card);
955 pci_outl(0, HD_DPLBASE, card);
956 pci_outl(0, HD_DPUBASE, card);
957 #endif
959 if (card->dma_position_buffer)
961 return TRUE;
963 else
965 return FALSE;
970 static BOOL alloc_streams(struct HDAudioChip *card)
972 int i;
973 card->nr_of_input_streams = (pci_inw(HD_GCAP, card) & HD_GCAP_ISS_MASK) >> 8;
974 card->nr_of_output_streams = (pci_inw(HD_GCAP, card) & HD_GCAP_OSS_MASK) >> 12;
975 card->nr_of_streams = card->nr_of_input_streams + card->nr_of_output_streams;
976 //bug("Streams in = %d, out = %d\n", card->nr_of_input_streams, card->nr_of_output_streams);
978 card->streams = (struct Stream *) AllocVec(sizeof(struct Stream) * card->nr_of_streams, MEMF_PUBLIC | MEMF_CLEAR);
980 for (i = 0; i < card->nr_of_streams; i++)
982 card->streams[i].bdl = NULL;
983 card->streams[i].bdl_nonaligned_addresses = NULL;
984 card->streams[i].sd_reg_offset = HD_SD_BASE_OFFSET + HD_SD_DESCRIPTOR_SIZE * i;
985 card->streams[i].index = i;
986 card->streams[i].tag = i + 1;
987 card->streams[i].fifo_size = pci_inw(card->streams[i].sd_reg_offset + HD_SD_OFFSET_FIFO_SIZE, card);
989 // clear the descriptor error, fifo error and buffer completion interrupt status flags
990 pci_outb(HD_SD_STATUS_MASK, card->streams[i].sd_reg_offset + HD_SD_OFFSET_STATUS, card);
993 if (card->streams)
995 return TRUE;
997 else
999 return FALSE;
1004 /*static ULONG ResetHandler(struct ExceptionContext *ctx, struct ExecBase *pExecBase, struct HDAudioChip *card)
1006 struct PCIDevice *dev = card->pci_dev;
1008 return 0UL;
1012 void AddResetHandler(struct HDAudioChip *card)
1014 static struct Interrupt interrupt;
1016 interrupt.is_Code = (void (*)())ResetHandler;
1017 interrupt.is_Data = (APTR) card;
1018 interrupt.is_Node.ln_Pri = 0;
1019 interrupt.is_Node.ln_Type = NT_EXTINTERRUPT;
1020 interrupt.is_Node.ln_Name = "reset handler";
1022 AddResetCallback(&interrupt);
1026 static BOOL perform_codec_specific_settings(struct HDAudioChip *card)
1028 BOOL configured = FALSE;
1029 ULONG vendor_device_id = get_parameter(0x0, VERB_GET_PARMS_VENDOR_DEVICE, card); // get vendor and device ID from root node
1030 UWORD vendor = (vendor_device_id >> 16);
1031 UWORD device = (vendor_device_id & 0xFFFF);
1033 card->dac_min_gain = -64.0;
1034 card->dac_max_gain = 0;
1035 card->dac_step_gain = 1.0;
1037 D(bug("[HDAudio] vendor = %x, device = %x\n", vendor, device));
1039 if (vendor == 0x10EC && forceQuery == FALSE) // Realtek
1041 configured = perform_realtek_specific_settings(card, device);
1043 else if (vendor == 0x1106 && forceQuery == FALSE) // VIA
1045 configured = perform_via_specific_settings(card, device);
1047 else if (vendor == 0x111d || (vendor == 0x8384 && forceQuery == FALSE)) // IDT
1049 configured = perform_idt_specific_settings(card, device);
1051 else if (vendor == 0x11d4 && forceQuery == FALSE) // Analog Devices
1053 configured = perform_ad_specific_settings(card, device);
1056 // call query-based configuration if the vendor-specific configuration
1057 // functions haven't configured the codec or have only partially
1058 // configured it by overriding some values
1059 if (!configured)
1061 if (!interrogate_unknown_chip(card))
1063 return FALSE;
1067 determine_frequencies(card);
1068 return TRUE;
1072 static BOOL perform_realtek_specific_settings(struct HDAudioChip *card, UWORD device)
1074 D(bug("[HDAudio] Found Realtek codec\n"));
1076 if (!(device == 0x662
1077 || device == 0x663
1078 || device == 0x268
1079 || device == 0x269
1080 || device == 0x888))
1082 D(bug("[HDAudio] Unknown Realtek codec.\n"));
1083 return FALSE;
1086 card->dac_nid = 0x2;
1087 card->dac_volume_nids[0] = 0x2;
1088 card->dac_volume_count = 1;
1089 card->adc_nid = 0x8;
1091 card->adc_mixer_nid = 0x23;
1092 card->line_in_nid = 0x1A;
1093 card->mic1_nid = 0x18;
1094 card->mic2_nid = 0x19;
1095 card->cd_nid = 0x1C;
1097 card->adc_mixer_is_mux = FALSE;
1099 // FRONT pin (0x14)
1100 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)
1102 send_command_12(card->codecnr, 0x14, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1103 card->speaker_active = TRUE;
1105 // MIC1 pin (0x18) as input
1106 send_command_12(card->codecnr, card->mic1_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1108 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
1111 // device specific support
1112 if (device == 0x662 || device == 0x663) // Realtek ALC662/663
1114 D(bug("[HDAudio] Adding ALC662/663 specific support\n"));
1116 card->adc_mixer_indices[0] = 2; // line in
1117 card->adc_mixer_indices[1] = 0; // mic1
1118 card->adc_mixer_indices[2] = 1; // mic2
1119 card->adc_mixer_indices[3] = 4; // cd
1120 card->adc_mixer_indices[4] = 8; // mon mixer
1122 card->adc_min_gain = -13.5;
1123 card->adc_max_gain = 33.0;
1124 card->adc_step_gain = 1.5;
1126 // LINE2 pin (0x1B) as second front output (duplicates sound of 0xC (front DAC))
1127 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)
1129 send_command_12(card->codecnr, 0x1B, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1131 // Monitor mixer (0xB): set the first 3 inputs to 0dB and unmute them
1132 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
1134 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
1136 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
1138 // Front DAC (0xC)
1139 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1141 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
1143 // LINE1 pin (0x1A) as input
1144 send_command_12(card->codecnr, card->line_in_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1146 // MIC2 pin (0x19) as input
1147 send_command_12(card->codecnr, card->mic2_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1149 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
1151 else if (device == 0x268)
1153 D(bug("[HDAudio] Adding ALC268 specific support\n"));
1155 card->speaker_nid = 0x14;
1156 card->headphone_nid = 0x15;
1158 card->adc_mixer_indices[0] = 2; // line in
1159 card->adc_mixer_indices[1] = 0; // mic1
1160 card->adc_mixer_indices[2] = 5; // mic2
1161 card->adc_mixer_indices[3] = 3; // cd
1162 card->adc_mixer_indices[4] = 255; // no mon mixer
1164 card->adc_min_gain = -16.5;
1165 card->adc_max_gain = 30.0;
1166 card->adc_step_gain = 1.5;
1168 card->adc_mixer_is_mux = TRUE;
1170 // sum widget before output (0xF)
1171 send_command_4(card->codecnr, 0xF, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute
1173 // sum widget before headphone output (0x10)
1174 send_command_4(card->codecnr, 0x10, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (2 << 8), card); // unmute
1176 // HP-OUT pin (0x15)
1177 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)
1179 send_command_12(card->codecnr, 0x15, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1181 send_command_12(card->codecnr, 0x14, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1183 send_command_12(card->codecnr, 0x15, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1185 else if (device == 0x269) // Dell mini etc.
1187 D(bug("[HDAudio] Adding ALC269 specific support\n"));
1189 card->speaker_nid = 0x14;
1190 card->headphone_nid = 0x15;
1192 card->adc_mixer_indices[0] = 2; // line in
1193 card->adc_mixer_indices[1] = 0; // mic1
1194 card->adc_mixer_indices[2] = 1; // mic2
1195 card->adc_mixer_indices[3] = 4; // cd
1196 card->adc_mixer_indices[4] = 6; // mon mixer
1198 card->adc_min_gain = -17;
1199 card->adc_max_gain = 29.0;
1200 card->adc_step_gain = 1.0;
1202 card->adc_mixer_is_mux = TRUE;
1204 // Front DAC (0xC)
1205 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1207 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
1209 // sum widget before output (0xF)
1210 send_command_4(card->codecnr, 0xF, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute
1212 // sum widget before headphone output (0x10)
1213 send_command_4(card->codecnr, 0x10, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (2 << 8), card); // unmute
1215 // HP-OUT pin (0x15)
1216 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)
1218 send_command_12(card->codecnr, 0x15, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1220 send_command_12(card->codecnr, 0x14, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1222 send_command_12(card->codecnr, 0x15, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1224 else if (device == 0x888) // ALC888
1226 D(bug("[HDAudio] Adding ALC888 specific support\n"));
1228 card->adc_mixer_indices[0] = 2; // line in
1229 card->adc_mixer_indices[1] = 0; // mic1
1230 card->adc_mixer_indices[2] = 1; // mic2
1231 card->adc_mixer_indices[3] = 4; // cd
1232 card->adc_mixer_indices[4] = 10; // mon mixer
1234 card->adc_min_gain = -16.5;
1235 card->adc_max_gain = 30.0;
1236 card->adc_step_gain = 1.5;
1238 card->dac_min_gain = -46.5;
1239 card->dac_max_gain = 0;
1240 card->dac_step_gain = 1.5;
1242 card->dac_volume_nids[0] = 0xC;
1243 card->dac_volume_count = 1;
1245 send_command_4(card->codecnr, 0xC, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // unmute PCM at index 0
1246 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
1249 return TRUE;
1253 static BOOL perform_via_specific_settings(struct HDAudioChip *card, UWORD device)
1255 D(bug("[HDAudio] Found VIA codec\n"));
1257 if (!(device == 0xE721 || device == 0x0397))
1259 D(bug("[HDAudio] Unknown VIA codec.\n"));
1260 return FALSE;
1263 card->dac_nid = 0x10;
1264 card->adc_nid = 0x13;
1266 card->adc_mixer_nid = 0x17;
1267 card->line_in_nid = 0x1B;
1268 card->mic1_nid = 0x1A;
1269 card->mic2_nid = 0x1E;
1270 card->cd_nid = 0x1F;
1272 card->adc_mixer_is_mux = TRUE;
1274 // FRONT pin (0x1C)
1275 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)
1276 send_command_12(card->codecnr, 0x1C, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1278 // MIC1 pin as input
1279 send_command_12(card->codecnr, card->mic1_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1280 send_command_4(card->codecnr, card->mic1_nid, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR, card); // set amplifier gain: unmute input
1283 // device specific support
1284 if (device == 0xE721) // VIA VT1708B
1286 D(bug("[HDAudio] Adding VIA VT1708B specific support\n"));
1288 card->adc_mixer_indices[0] = 3; // line in
1289 card->adc_mixer_indices[1] = 2; // mic1
1290 card->adc_mixer_indices[2] = 4; // mic2
1291 card->adc_mixer_indices[3] = 1; // cd
1292 card->adc_mixer_indices[4] = 255; // mon mixer
1294 card->adc_min_gain = -13.5;
1295 card->adc_max_gain = 33.0;
1296 card->adc_step_gain = 1.5;
1299 return TRUE;
1303 IDT specific settings
1305 information: http://www.idt.com/document/92hd75b-datasheet-92hd75-being-discontinued-see-pdn-notice
1307 TODO: input
1310 static BOOL perform_idt_specific_settings(struct HDAudioChip *card, UWORD device)
1312 D(bug("[HDAudio] Found IDT codec\n"));
1314 if (device == 0x76a0)
1316 D(bug("[HDAudio] STAC9205 detected.\n"));
1318 card->eapd_gpio_mask = 0x1;
1319 set_gpio(card->eapd_gpio_mask, card);
1321 return FALSE;
1324 if (!(device == 0x7608))
1326 D(bug("[HDAudio] Unknown IDT codec.\n"));
1327 return FALSE;
1330 card->dac_nid = 0x10;
1331 card->adc_nid = 0x12;
1332 card->adc_mixer_nid = 0x1C;
1333 card->dac_volume_nids[0] = 0x10;
1334 card->dac_volume_count = 1;
1336 card->speaker_nid = 0x0D;
1337 card->headphone_nid = 0x0A;
1339 card->line_in_nid = 0x0B;
1340 card->mic1_nid = 0x0B;
1341 card->mic2_nid = 0x0C;
1342 card->cd_nid = 0x0E; /* no cd but ...*/
1344 card->adc_mixer_is_mux = TRUE;
1346 /* to not to enable headphone and the speaker at the same time */
1347 card->speaker_active = TRUE;
1349 /* enable eapd. Specs says this is spdif out, but this is required */
1350 send_command_12(card->codecnr, 0x1f, VERB_SET_EAPD, 0x2, card);
1352 /* set connections */
1353 send_command_12 (card->codecnr, 0x0f, VERB_SET_CONNECTION_SELECT, 0, card); /* 48QFN specific */
1354 send_command_12 (card->codecnr, 0x0a, VERB_SET_CONNECTION_SELECT, 0, card); /* headset */
1355 send_command_12 (card->codecnr, 0x0d, VERB_SET_CONNECTION_SELECT, 0, card); /* speaker */
1357 /* set output gains */
1358 send_command_4 (card->codecnr, 0x0f, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1359 send_command_4 (card->codecnr, 0x0a, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1360 send_command_4 (card->codecnr, 0x0d, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR, card);
1362 /* enable outputs */
1363 send_command_12(card->codecnr, 0x0f, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1364 send_command_12(card->codecnr, 0x0a, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1365 send_command_12(card->codecnr, 0x0d, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card);
1367 if (device == 0x7608)
1369 /* move 0x7608 specific stuff here */
1371 /* Not sure about indices */
1372 card->adc_mixer_indices[0] = 3; // line in
1373 card->adc_mixer_indices[1] = 2; // mic1
1374 card->adc_mixer_indices[2] = 4; // mic2
1375 card->adc_mixer_indices[3] = 1; // cd
1376 card->adc_mixer_indices[4] = 255; // no mon mixer
1378 card->adc_min_gain = 0.0;
1379 card->adc_max_gain = 22.5;
1380 card->adc_step_gain = 1.5;
1382 card->dac_min_gain = -95.25;
1383 card->dac_max_gain = 0.0;
1384 card->dac_step_gain = 0.75;
1387 return TRUE;
1391 static BOOL perform_ad_specific_settings(struct HDAudioChip *card,
1392 UWORD device)
1394 D(bug("[HDAudio] Found Analog Devices codec\n"));
1396 // device specific support
1397 if (device == 0x1981) // AD1981HD
1399 D(bug("[HDAudio] Adding AD1981HD specific support\n"));
1400 if (force_speaker_nid == 0)
1402 force_speaker_nid = 0x7;
1405 else if (device == 0x1884) // AD1884
1407 // Use the second DAC for all outputs, since the line-out port can't
1408 // use the first DAC!
1409 card->dac_nid = 0x4;
1410 send_command_12(card->codecnr, 0xe,
1411 VERB_SET_CONNECTION_SELECT, 1, card); // Mono
1412 send_command_12(card->codecnr, 0xf,
1413 VERB_SET_CONNECTION_SELECT, 1, card); // Port F
1414 send_command_12(card->codecnr, 0x22,
1415 VERB_SET_CONNECTION_SELECT, 1, card); // Port A
1416 send_command_12(card->codecnr, 0x23,
1417 VERB_SET_CONNECTION_SELECT, 1, card); // Port E
1420 return FALSE;
1424 static void update_gpio(UBYTE mask, BOOL on, struct HDAudioChip *card)
1426 ULONG gpio_data, gpio_enable, gpio_dir;
1428 gpio_enable = send_command_12(card->codecnr, card->function_group,
1429 VERB_GET_GPIO_ENABLE, 0, card);
1430 gpio_enable |= mask;
1431 send_command_12(card->codecnr, card->function_group, VERB_SET_GPIO_ENABLE,
1432 gpio_enable, card);
1434 gpio_dir = send_command_12(card->codecnr, card->function_group,
1435 VERB_GET_GPIO_DIR, 0, card);
1436 gpio_dir |= mask;
1437 send_command_12(card->codecnr, card->function_group, VERB_SET_GPIO_DIR,
1438 gpio_dir, card);
1440 gpio_data = send_command_12(card->codecnr, card->function_group,
1441 VERB_GET_GPIO_DATA, 0, card);
1442 if (on)
1443 gpio_data |= mask;
1444 else
1445 gpio_data &= ~mask;
1446 send_command_12(card->codecnr, card->function_group, VERB_SET_GPIO_DATA,
1447 gpio_data, card);
1451 static void set_gpio(UBYTE mask, struct HDAudioChip *card)
1453 update_gpio(mask, TRUE, card);
1457 static UBYTE get_connected_widget(UBYTE nid, UBYTE index,
1458 struct HDAudioChip *card)
1460 UBYTE input_nid = 0;
1461 ULONG connections, entry;
1463 connections = get_parameter(nid, 0xE, card);
1464 if (index < connections)
1466 entry = send_command_12(card->codecnr, nid,
1467 VERB_GET_CONNECTION_LIST_ENTRY, index, card);
1468 input_nid = entry >> ((index % 4) * 8);
1471 return input_nid;
1475 static UBYTE get_selected_widget(UBYTE nid, struct HDAudioChip *card)
1477 UBYTE input_nid = 0;
1478 ULONG connections;
1479 ULONG index;
1481 connections = get_parameter(nid, 0xE, card);
1482 if (connections > 0)
1484 if (connections == 1)
1485 index = 0;
1486 else
1488 index = send_command_12(card->codecnr, nid,
1489 VERB_GET_CONNECTION_SELECT, 0, card);
1492 input_nid = get_connected_widget(nid, index, card);
1495 return input_nid;
1499 /* Adds a widget to the array of volume controlling widgets if it has volume
1500 * control */
1501 static void check_widget_volume(UBYTE nid, struct HDAudioChip *card)
1503 ULONG parm;
1505 parm = get_parameter(nid, VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1506 D(bug("[HDAudio] NID %xh: Audio widget caps = %lx\n", nid, parm));
1507 if (parm & 0x4) // OutAmpPre
1509 D(bug("[HDAudio] NID %xh has volume control\n", nid));
1510 card->dac_volume_nids[card->dac_volume_count++] = nid;
1512 else
1514 D(bug("[HDAudio] NID %xh does not have volume control\n", nid));
1519 /* Unmute all of a widget's inputs and outputs */
1520 static void unmute_widget(UBYTE nid, struct HDAudioChip *card)
1522 UWORD connections, i;
1523 ULONG gain;
1525 D(bug("[HDAudio] Unmuting NID %xh\n", nid));
1527 // Get number of inputs
1528 connections = get_parameter(nid, 0xE, card);
1530 // Unmute inputs while retaining their gain levels
1531 for (i = 0; i < connections; i++)
1533 gain = send_command_4(card->codecnr, nid, 0xB, i, card);
1534 send_command_4(card->codecnr, nid, VERB_SET_AMP_GAIN,
1535 INPUT_AMP_GAIN | AMP_GAIN_LR | i << 8 | gain & 0x7f, card);
1538 // Unmute output while retaining its gain level
1539 gain = send_command_4(card->codecnr, nid, 0xB, OUTPUT_AMP_GAIN, card);
1540 send_command_4(card->codecnr, nid, VERB_SET_AMP_GAIN,
1541 OUTPUT_AMP_GAIN | AMP_GAIN_LR | gain & 0x7f, card);
1545 static BOOL interrogate_unknown_chip(struct HDAudioChip *card)
1547 int dac, adc, front, steps = 0, offset0dB = 0;
1548 double step_size = 0.25;
1549 ULONG parm, widget_caps, nid;
1550 UWORD connections, i;
1551 UBYTE before_front = 0, first_subnode, subnode_limit;
1553 D(bug("[HDAudio] Unknown codec, interrogating chip...\n"));
1555 // Umute all widgets
1556 parm = get_parameter(card->function_group, VERB_GET_PARMS_NODE_COUNT, card);
1557 first_subnode = parm >> 16 & 0xFF;
1558 subnode_limit = first_subnode + (parm & 0xFF);
1559 for (i = first_subnode; i < subnode_limit; i++)
1561 unmute_widget(i, card);
1564 if (card->dac_nid == 0)
1566 // find out the first PCM DAC
1567 dac = find_widget(card, 0, 0);
1569 if (dac == 0)
1571 bug("Didn't find DAC!\n");
1572 return FALSE;
1575 card->dac_nid = dac;
1577 D(bug("[HDAudio] DAC NID = %xh\n", card->dac_nid));
1579 check_widget_volume(dac, card);
1581 // find FRONT pin
1582 front = find_widget(card, 4, 0);
1583 D(bug("[HDAudio] Front PIN = %xh\n", front));
1585 if (front == 0)
1587 D(bug("[HDAudio] Didn't find jack/pin for line output!\n"));
1589 else
1591 send_command_12(card->codecnr, front, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1592 send_command_12(card->codecnr, front, VERB_SET_CONNECTION_SELECT, 0, card); // use first input
1593 check_widget_volume(front, card);
1596 // find SPEAKER
1597 if (force_speaker_nid > 0)
1599 D(bug("[HDAudio] Using speaker nid from config file\n"));
1600 card->speaker_nid = force_speaker_nid;
1602 else
1604 card->speaker_nid = find_widget(card, 4, 1);
1606 D(bug("[HDAudio] Speaker NID = %xh\n", card->speaker_nid));
1608 if (card->speaker_nid != 0)
1610 // check if there is a power amp and if so, enable it
1611 if (get_parameter(card->speaker_nid, VERB_GET_PARMS_PIN_CAPS, card) & PIN_CAPS_EAPD_CAPABLE)
1613 D(bug("[HDAudio] Enabling power amp of speaker\n"));
1614 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1617 D(bug("[HDAudio] Enabling speaker output\n"));
1618 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
1619 card->speaker_active = TRUE;
1620 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_CONNECTION_SELECT, 0, card); // use first input
1622 check_widget_volume(card->speaker_nid, card);
1624 else
1626 D(bug("[HDAudio] No speaker pin found, continuing anyway!\n"));
1629 // Find headphones socket
1630 card->headphone_nid = find_widget(card, 4, 2);
1632 D(bug("[HDAudio] Headphone NID = %xh\n", card->headphone_nid));
1634 if (card->headphone_nid != 0)
1636 send_command_12(card->codecnr, card->headphone_nid, VERB_SET_PIN_WIDGET_CONTROL, 0xC0, card); // output enabled and headphone enabled
1637 send_command_12(card->codecnr, card->headphone_nid, VERB_SET_CONNECTION_SELECT, 0, card); // use first input
1639 // check if there is a power amp and if so, enable it
1640 if (get_parameter(card->headphone_nid, VERB_GET_PARMS_PIN_CAPS, card) & PIN_CAPS_EAPD_CAPABLE)
1642 D(bug("[HDAudio] Enabling power amp of headphone port\n"));
1643 send_command_12(card->codecnr, card->headphone_nid, VERB_SET_EAPD, 0x2, card); // enable EAPD (external power amp)
1646 check_widget_volume(card->headphone_nid, card);
1649 // find the node before the front, speaker or HP node
1650 if (front != 0)
1651 nid = front;
1652 else if (card->speaker_nid != 0)
1653 nid = card->speaker_nid;
1654 else if (card->headphone_nid != 0)
1655 nid = card->headphone_nid;
1656 else nid = 0;
1658 if (nid != 0)
1659 before_front = (UBYTE)send_command_12(card->codecnr, nid,
1660 VERB_GET_CONNECTION_LIST_ENTRY, 0, card);
1662 if (before_front != dac)
1664 D(bug("[HDAudio] The widget before front/speaker/HP (%xh) is not equal to DAC!\n", before_front));
1666 check_widget_volume(before_front, card);
1668 else
1670 D(bug("[HDAudio] The widget before front/speaker/HP is equal to DAC.\n"));
1673 for (i = 0; card->dac_volume_nids[i] != 0; i++)
1675 parm = get_parameter(card->dac_volume_nids[i],
1676 VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1677 if ((parm & 0x8) != 0)
1678 parm = get_parameter(card->dac_volume_nids[i],
1679 VERB_GET_PARMS_OUTPUT_AMP_CAPS , card);
1680 else
1681 parm = get_parameter(card->function_group,
1682 VERB_GET_PARMS_OUTPUT_AMP_CAPS, card);
1683 D(bug("[HDAudio] NID %xh: Output amp caps = %lx\n", card->dac_volume_nids[i], parm));
1685 step_size = (((parm >> 16) & 0x7F) + 1) * 0.25;
1686 steps = ((parm >> 8) & 0x7F);
1687 offset0dB = (parm & 0x7F);
1689 if (steps != 0)
1691 card->dac_min_gain = -(offset0dB * step_size);
1692 card->dac_max_gain = card->dac_min_gain + step_size * steps;
1693 card->dac_step_gain = step_size;
1694 D(bug("[HDAudio] Gain step size = %lu * 0.25 dB,"
1695 " min gain = %d, max gain = %d\n",
1696 (((parm >> 16) & 0x7F) + 1), (int) (card->dac_min_gain),
1697 (int) (card->dac_max_gain)));
1701 // find out the first PCM ADC
1702 adc = find_widget(card, 1, 0);
1703 D(bug("[HDAudio] ADC NID = %xh\n", adc));
1705 if (adc != 0)
1707 card->adc_nid = adc;
1709 card->line_in_nid = find_widget(card, 4, 8);
1710 D(bug("[HDAudio] Line-in NID = %xh\n", card->line_in_nid));
1711 card->mic1_nid = find_widget(card, 4, 0xA);
1712 D(bug("[HDAudio] Mic1 NID = %xh\n", card->mic1_nid));
1714 // find ADC mixer by tracing a path from the ADC towards the ports
1715 nid = adc;
1716 while (nid != 0)
1718 widget_caps = get_parameter(nid,
1719 VERB_GET_PARMS_AUDIO_WIDGET_CAPS, card);
1720 D(bug("[HDAudio] audio widget caps = %lx\n", widget_caps));
1722 if (((widget_caps >> 20) & 0xF) == 0x3)
1724 card->adc_mixer_nid = nid;
1725 D(bug("[HDAudio] ADC mixer NID = %xh\n", card->adc_mixer_nid));
1726 card->adc_mixer_is_mux = TRUE;
1729 nid = get_selected_widget(nid, card);
1732 if (card->line_in_nid != 0)
1734 send_command_12(card->codecnr, card->line_in_nid,
1735 VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1737 if (card->mic1_nid != 0)
1739 send_command_12(card->codecnr, card->mic1_nid,
1740 VERB_SET_PIN_WIDGET_CONTROL, 0x20, card); // input enabled
1743 else
1744 bug("[HDAudio] Didn't find ADC!\n");
1746 return TRUE;
1750 static UBYTE find_widget(struct HDAudioChip *card, UBYTE type, UBYTE pin_type)
1752 ULONG node_count_response = get_parameter(card->function_group,
1753 VERB_GET_PARMS_NODE_COUNT, card);
1754 UBYTE node_count = node_count_response & 0xFF;
1755 UBYTE starting_node = (node_count_response >> 16) & 0xFF;
1756 UBYTE i;
1757 ULONG config_default;
1759 for (i = 0; i < node_count; i++) // widgets
1761 UBYTE nid = i + starting_node;
1762 ULONG widget_caps, pin_caps, connections;
1764 widget_caps = get_parameter(nid, VERB_GET_PARMS_AUDIO_WIDGET_CAPS,
1765 card);
1767 if (((widget_caps >> 20) & 0xF) == type)
1769 BOOL ok;
1771 if (type == 4) // node is a pin widget
1773 config_default = send_command_12(card->codecnr, nid,
1774 VERB_GET_CONFIG_DEFAULT, 0, card);
1776 if (((config_default >> 20) & 0xF) == pin_type)
1778 D(bug("[HDAudio] Config default for NID %x = %x\n", nid,
1779 config_default));
1780 if ((widget_caps & 1 << 8) != 0)
1781 connections = get_parameter(nid, 0xE, card) & 0x7f;
1782 else
1783 connections = 0;
1784 pin_caps =
1785 get_parameter(nid, VERB_GET_PARMS_PIN_CAPS, card);
1786 switch (pin_type)
1788 case 0x0:
1789 case 0x1:
1790 case 0x2:
1791 case 0x4:
1792 case 0x5:
1793 ok = (pin_caps & PIN_CAPS_OUTPUT_CAPABLE) != 0
1794 && connections != 0;
1795 break;
1796 default:
1797 ok = (pin_caps & PIN_CAPS_INPUT_CAPABLE) != 0;
1800 // check speaker connection type is internal
1801 if (pin_type == 1 && (config_default >> 16 & 0xB) != 3)
1802 ok = FALSE;
1804 // check headphone connection type is mini-jack
1805 if (pin_type == 2 && (config_default >> 16 & 0xF) != 1)
1806 ok = FALSE;
1808 // check microphone connection type is mini-jack
1809 if (pin_type == 0xA && (config_default >> 16 & 0xF) != 1)
1810 ok = FALSE;
1813 else
1814 ok = (widget_caps & 0x1) == 1 && // stereo
1815 ((widget_caps >> 9) & 0x1) == 0; // analogue
1817 if (ok)
1818 return nid;
1822 return 0;
1826 static void determine_frequencies(struct HDAudioChip *card)
1828 ULONG verb = get_parameter(card->dac_nid, 0xA, card);
1829 UWORD samplerate_flags = verb & 0x0FFF;
1830 int i;
1831 ULONG freqs = 0;
1832 BOOL default_freq_found = FALSE;
1834 if (samplerate_flags == 0)
1836 verb = get_parameter(0x1, 0xA, card);
1837 samplerate_flags = verb & 0x0FFF;
1838 D(bug("[HDAudio] dac_nid didn't have a list of sample rates, trying AFG node\n"));
1841 // count number of frequencies
1842 for (i = 0; i < 12; i++)
1844 if (samplerate_flags & (1 << i))
1846 freqs++;
1850 D(bug("[HDAudio] Frequencies found = %lu\n", freqs));
1851 card->frequencies = (struct Freq *) AllocVec(sizeof(struct Freq) * freqs, MEMF_PUBLIC | MEMF_CLEAR);
1852 card->nr_of_frequencies = freqs;
1854 freqs = 0;
1855 for (i = 0; i < 12; i++)
1857 if (samplerate_flags & (1 << i))
1859 set_frequency_info(&(card->frequencies[freqs]), i);
1861 if (card->frequencies[freqs].frequency == 44100 && !default_freq_found)
1863 card->selected_freq_index = freqs; // set default freq index to 44100 Hz
1864 default_freq_found = TRUE;
1867 freqs++;
1871 if (default_freq_found == FALSE)
1873 D(bug("[HDAudio] 44100 Hz is not supported!\n"));
1874 if (freqs > 0)
1876 D(bug("[HDAudio] Setting default frequency to %lu\n", card->frequencies[0].frequency));
1877 card->selected_freq_index = 0;
1884 static void set_frequency_info(struct Freq *freq, UWORD bitnr)
1886 switch (bitnr)
1888 case 0: freq->frequency = 8000;
1889 freq->base44100 = 0;
1890 freq->mult = 0;
1891 freq->div = 5;
1892 break;
1894 case 1: freq->frequency = 11025;
1895 freq->base44100 = 1;
1896 freq->mult = 0;
1897 freq->div = 3;
1898 break;
1900 case 2: freq->frequency = 16000;
1901 freq->base44100 = 0;
1902 freq->mult = 0;
1903 freq->div = 2;
1904 break;
1906 case 3: freq->frequency = 22050;
1907 freq->base44100 = 1;
1908 freq->mult = 0;
1909 freq->div = 1;
1910 break;
1912 case 4: freq->frequency = 32000;
1913 freq->base44100 = 0;
1914 freq->mult = 0;
1915 freq->div = 2;
1916 break;
1918 case 5: freq->frequency = 44100;
1919 freq->base44100 = 1;
1920 freq->mult = 0;
1921 freq->div = 0;
1922 break;
1924 case 6: freq->frequency = 48000;
1925 freq->base44100 = 0;
1926 freq->mult = 0;
1927 freq->div = 0;
1928 break;
1930 case 7: freq->frequency = 88200;
1931 freq->base44100 = 1;
1932 freq->mult = 1;
1933 freq->div = 0;
1934 break;
1936 case 8: freq->frequency = 96000;
1937 freq->base44100 = 0;
1938 freq->mult = 1;
1939 freq->div = 0;
1940 break;
1942 case 9: freq->frequency = 176400;
1943 freq->base44100 = 1;
1944 freq->mult = 3;
1945 freq->div = 0;
1946 break;
1948 case 10: freq->frequency = 192000;
1949 freq->base44100 = 0;
1950 freq->mult = 3;
1951 freq->div = 0;
1952 break;
1954 default:
1955 D(bug("[HDAudio] Unsupported frequency!\n"));
1956 break;
1961 void set_monitor_volumes(struct HDAudioChip *card, double dB)
1963 #if 0
1964 int i;
1965 #endif
1966 int dB_steps = (int) ((dB + 34.5) / 1.5);
1968 if (dB_steps < 0)
1970 dB_steps = 0;
1972 else if (dB_steps > 31)
1974 dB_steps = 31;
1977 #if 0
1978 for (i = 0; i < 9; i++)
1980 if (i == 0 || i == 1 || i == 2 || i == 4)
1982 send_command_4(card->codecnr, 0xB, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (i << 8) | dB_steps, card);
1984 else // mute
1986 send_command_4(card->codecnr, 0xB, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | (i << 8) | (1 << 7), card);
1989 #endif
1993 void set_adc_input(struct HDAudioChip *card)
1995 int i;
1997 if (card->input >= INPUTS)
1999 card->input = 0;
2002 if (card->adc_mixer_is_mux == TRUE)
2004 D(bug("[HDAudio] Selecting ADC input %d\n", card->adc_mixer_indices[card->input]));
2005 send_command_12(card->codecnr, card->adc_mixer_nid, VERB_SET_CONNECTION_SELECT,
2006 card->adc_mixer_indices[card->input], card);
2007 return;
2009 else
2011 for (i = 0; i < INPUTS; i++)
2013 if (card->adc_mixer_indices[i] != 255) // input is present
2015 if (i == card->input) // unmute or select
2017 D(bug("[HDAudio] Unmuting ADC input %d\n", card->adc_mixer_indices[i]));
2018 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN,
2019 INPUT_AMP_GAIN | AMP_GAIN_LR | (card->adc_mixer_indices[i] << 8), card);
2021 else // mute
2023 D(bug("[HDAudio] Muting ADC input %d\n", card->adc_mixer_indices[i]));
2024 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN,
2025 INPUT_AMP_GAIN | AMP_GAIN_LR | (card->adc_mixer_indices[i] << 8) | (1 << 7), card);
2034 void set_adc_gain(struct HDAudioChip *card, double dB)
2036 int dB_steps = (int) ( (dB - card->adc_min_gain) / card->adc_step_gain);
2038 if (dB_steps < 0)
2040 dB_steps = 0;
2043 if (card->adc_mixer_is_mux == TRUE)
2045 send_command_4(card->codecnr, card->adc_mixer_nid, VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
2047 else
2049 send_command_4(card->codecnr, card->adc_nid, VERB_SET_AMP_GAIN, INPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
2054 void set_dac_gain(struct HDAudioChip *card, double dB)
2056 int i;
2057 int dB_steps = (int) ( (dB - card->dac_min_gain) / card->dac_step_gain);
2059 if (dB_steps < 0)
2061 dB_steps = 0;
2064 for (i = 0; i < card->dac_volume_count; i++)
2065 send_command_4(card->codecnr, card->dac_volume_nids[i],
2066 VERB_SET_AMP_GAIN, OUTPUT_AMP_GAIN | AMP_GAIN_LR | dB_steps, card);
2070 void setForceQuery(void)
2072 forceQuery = TRUE;
2076 void setDumpAll(void)
2078 dumpAll = TRUE;
2082 void setForceSpeaker(int speaker_nid)
2084 force_speaker_nid = speaker_nid;
2089 BOOL is_jack_connected(struct HDAudioChip *card, UBYTE NID)
2091 ULONG result;
2093 send_command_12(card->codecnr, NID, VERB_EXECUTE_PIN_SENSE, 0, card);
2094 udelay(2000);
2095 result = send_command_12(card->codecnr, NID, VERB_GET_PIN_SENSE, 0, card);
2097 if (result & 0x80000000)
2099 D(bug("[HDAudio] jack connected\n"));
2100 return TRUE;
2102 else
2104 D(bug("[HDAudio] jack disconnected\n"));
2105 return FALSE;
2111 void detect_headphone_change(struct HDAudioChip *card)
2113 if (card->speaker_nid != 0 &&
2114 card->headphone_nid != 0)
2116 if (card->speaker_active &&
2117 is_jack_connected(card, card->headphone_nid)) // disable speaker
2119 D(bug("[HDAudio] disabling speaker\n"));
2120 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x0, card); // output disabled
2121 card->speaker_active = FALSE;
2123 else if (card->speaker_active == FALSE &&
2124 is_jack_connected(card, card->headphone_nid) == FALSE) // enable speaker
2126 D(bug("[HDAudio] enabling speaker\n"));
2127 send_command_12(card->codecnr, card->speaker_nid, VERB_SET_PIN_WIDGET_CONTROL, 0x40, card); // output enabled
2128 card->speaker_active = TRUE;