Skip to content

Commit 254586f

Browse files
fixed regression if DAC had no amplifier
1 parent 74f0cd0 commit 254586f

File tree

3 files changed

+37
-18
lines changed

3 files changed

+37
-18
lines changed

History.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11

2-
v1.6, 7.6.2025
2+
v1.6, 10.6.2025
33
- fixed: some port trap variables weren't initialized if real-mode port
44
trapping was disabled.
55
- fixed: debug displays may have caused a GPF.
66
- VSBHDA16: option /DIVE added; enable Borland "Runtime error 200" fix.
77
- fixed: VPIC EOI check now tests bits 5/6 of OCW2; handles specific EOIs.
88
- fixed VMPU: set UART mode cmd 0x3F added.
9+
- fixed regression v1.4-v1.5: if DAC had no amplifier, volume was very low
10+
and couldn't be changed with /VOL.
911

1012
v1.5, 8.6.2024
1113
- MPU port emulation if BLASTER variable contains P=xxx.

MPXPLAY/SC_INTHD.C

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,18 @@
4343
typedef uint16_t hda_nid_t;
4444

4545
struct hda_gnode {
46-
hda_nid_t nid; /* NID of this widget */
47-
unsigned short nconns; /* number of input connections */
46+
hda_nid_t nid; /* NID of this widget */
47+
unsigned short nconns; /* number of input connections */
4848
hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
4949
unsigned int wid_caps; /* widget capabilities */
50-
unsigned char type; /* widget type */
51-
unsigned char pin_ctl; /* pin controls */
52-
unsigned char checked; /* the flag indicates that the node is already parsed */
50+
unsigned char type; /* widget type */
51+
unsigned char pin_ctl; /* pin controls */
52+
unsigned char checked; /* the flag indicates that the node is already parsed */
5353
unsigned int pin_caps; /* pin widget capabilities */
54-
unsigned int def_cfg; /* default configuration */
55-
unsigned int amp_out_caps; /* AMP out capabilities */
56-
unsigned int amp_in_caps; /* AMP in capabilities */
57-
unsigned long supported_formats; // format_val
54+
unsigned int def_cfg; /* default configuration */
55+
unsigned int amp_out_caps;/* AMP out capabilities */
56+
unsigned int amp_in_caps; /* AMP in capabilities */
57+
unsigned long supported_formats; /* format_val */
5858
};
5959

6060
struct pcm_vol_s {
@@ -74,8 +74,8 @@ struct intelhd_card_s
7474
hda_nid_t afg_root_nodenum;
7575
int afg_num_nodes;
7676
struct hda_gnode *afg_nodes;
77-
unsigned int def_amp_out_caps;
78-
unsigned int def_amp_in_caps;
77+
unsigned int def_amp_out_caps; /* default amp caps set by audio function group */
78+
unsigned int def_amp_in_caps; /* default amp caps set by audio function group */
7979
struct hda_gnode *dac_node[2]; // DAC nodes
8080
struct hda_gnode *out_pin_node[MAX_PCM_VOLS]; // Output pin (Line-Out) nodes
8181
unsigned int pcm_num_vols; // number of PCM volumes
@@ -386,6 +386,8 @@ static int hda_get_connections(struct intelhd_card_s *card, hda_nid_t nid, hda_n
386386
return conns;
387387
}
388388

389+
/* add a widget to the widget array */
390+
389391
static int hda_add_node(struct intelhd_card_s *card, struct hda_gnode *node, hda_nid_t nid)
390392
///////////////////////////////////////////////////////////////////////////////////////////
391393
{
@@ -542,12 +544,14 @@ static int parse_output_path(struct intelhd_card_s *card,struct hda_gnode *node,
542544
hda_codec_write(card, node->nid, 0, AC_VERB_SET_POWER_STATE, 0 );
543545
#endif
544546
node->checked = 1;
547+
/* is node an "Audio Out" widget (=DAC)? */
545548
if(node->type == AC_WID_AUD_OUT) {
546549
if(node->wid_caps & AC_WCAP_DIGITAL)
547550
return 0;
548551
if(card->dac_node[dac_idx])
549552
return (node == card->dac_node[dac_idx]);
550553

554+
/* store (one of) the volume nodes if the DAC has an output amplifier */
551555
card->dac_node[dac_idx] = node;
552556
if((node->wid_caps & AC_WCAP_OUT_AMP) && (card->pcm_num_vols < MAX_PCM_VOLS)){
553557
card->pcm_vols[card->pcm_num_vols].node = node;
@@ -569,9 +573,11 @@ static int parse_output_path(struct intelhd_card_s *card,struct hda_gnode *node,
569573
select_input_connection(card, node, i);
570574
hda_unmute_input(card, node, i);
571575
hda_unmute_output(card, node);
576+
/* if the selected DAC has no OUT amplifier, use this node to set volume */
572577
if( card->dac_node[dac_idx] && ( card->pcm_num_vols < MAX_PCM_VOLS ) && !( card->dac_node[dac_idx]->wid_caps & AC_WCAP_OUT_AMP ) ) {
573-
if((node->wid_caps & AC_WCAP_IN_AMP) || (node->wid_caps & AC_WCAP_OUT_AMP)) {
578+
if( node->wid_caps & (AC_WCAP_IN_AMP | AC_WCAP_OUT_AMP) ) {
574579
int n = card->pcm_num_vols;
580+
dbgprintf(("parse_output_path: widget %u, index %u used for volume setting\n", node->nid, i ));
575581
card->pcm_vols[n].node = node;
576582
card->pcm_vols[n].index = i;
577583
card->pcm_num_vols++;
@@ -953,7 +959,10 @@ static unsigned int hda_mixer_init(struct intelhd_card_s *card)
953959
//hda_master_vol.submixerchans[i].submixch_max = (card->pcm_vols[i].node->amp_out_caps >> AC_AMPCAP_NUM_STEPS_SHIFT ) & AC_AMPCAP_NUM_STEPS_MASK;
954960
}
955961

956-
dbgprintf(("hda_mixer_init: dac[0]=%d dac[1]=%d out[0]=%d out[1]=%d vol[0]=%d vol[1]=%d\n",
962+
/* this is the important log if something goes wrong with the volume;
963+
* the card->pcm_vols should be DACs or Mixer widgets.
964+
*/
965+
dbgprintf(("hda_mixer_init nodes: dac[0]=%d dac[1]=%d out[0]=%d out[1]=%d vol[0]=%d vol[1]=%d\n",
957966
(int)((card->dac_node[0]) ? card->dac_node[0]->nid: 0),
958967
(int)((card->dac_node[1]) ? card->dac_node[1]->nid: 0),
959968
(int)((card->out_pin_node[0]) ? card->out_pin_node[0]->nid: 0),
@@ -1440,6 +1449,10 @@ static int HDA_adetect( struct audioout_info_s *aui )
14401449
card->codec_index = i;
14411450
if( hda_mixer_init( card ) ) {
14421451
dbgprintf(("HDA_adetect: exit, found mixer for codec %u\n", i ));
1452+
printf("HDA widgets to be used: DAC=%d Pin=%d Volume=%d\n",
1453+
(int)((card->dac_node[0]) ? card->dac_node[0]->nid: 0),
1454+
(int)((card->out_pin_node[0]) ? card->out_pin_node[0]->nid: 0),
1455+
(int)((card->pcm_vols[0].node) ? card->pcm_vols[0].node->nid: 0));
14431456
return( 1 );
14441457
}
14451458
}
@@ -1594,7 +1607,9 @@ static void HDA_writeMIXER( struct audioout_info_s *aui, unsigned long reg, unsi
15941607
///////////////////////////////////////////////////////////////////////////////////////////////
15951608
{
15961609
struct intelhd_card_s *card = aui->card_private_data;
1597-
int maxstep = ( card->dac_node[0]->amp_out_caps >> 8 ) & 0x7F;
1610+
/* v1.6: use pcm_vols[] instead of dac_node[] */
1611+
//int maxstep = ( card->dac_node[0]->amp_out_caps >> 8 ) & 0x7F;
1612+
int maxstep = ( card->pcm_vols[0].node->amp_out_caps >> 8 ) & 0x7F;
15981613
val = maxstep * val / 100;
15991614
hda_set_vol_mute( card, reg, 0, HDA_OUTPUT, 0, val ); /* left channel */
16001615
hda_set_vol_mute( card, reg, 1, HDA_OUTPUT, 0, val ); /* right channel */
@@ -1609,7 +1624,9 @@ static unsigned long HDA_readMIXER( struct audioout_info_s *aui, unsigned long r
16091624
{
16101625
struct intelhd_card_s *card = aui->card_private_data;
16111626
uint32_t val;
1612-
int maxstep = ( card->dac_node[0]->amp_out_caps >> 8 ) & 0x7F;
1627+
/* v1.6: use pcm_vols[] instead of dac_node[] */
1628+
//int maxstep = ( card->dac_node[0]->amp_out_caps >> 8 ) & 0x7F;
1629+
int maxstep = ( card->pcm_vols[0].node->amp_out_caps >> 8 ) & 0x7F;
16131630
val = hda_get_vol_mute( card, reg, 0, HDA_OUTPUT, 0 );
16141631
if ( maxstep )
16151632
val = val * 100 / maxstep;

MPXPLAY/SC_INTHD.H

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ enum {
4242
* widget types
4343
*/
4444
enum {
45-
AC_WID_AUD_OUT, /* 0 Audio Out */
46-
AC_WID_AUD_IN, /* 1 Audio In */
45+
AC_WID_AUD_OUT, /* 0 Audio Out (DAC) */
46+
AC_WID_AUD_IN, /* 1 Audio In (ADC) */
4747
AC_WID_AUD_MIX, /* 2 Audio Mixer */
4848
AC_WID_AUD_SEL, /* 3 Audio Selector */
4949
AC_WID_PIN, /* 4 Pin Complex */

0 commit comments

Comments
 (0)