Skip to content

Commit 8128c9f

Browse files
committed
Merge branch 'topic/hda' into for-linus
2 parents bb14eb0 + 6b45214 commit 8128c9f

File tree

3 files changed

+88
-29
lines changed

3 files changed

+88
-29
lines changed

sound/pci/hda/hda_local.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,8 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
600600
#define get_amp_nid_(pv) ((pv) & 0xffff)
601601
#define get_amp_nid(kc) get_amp_nid_((kc)->private_value)
602602
#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
603-
#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
603+
#define get_amp_direction_(pv) (((pv) >> 18) & 0x1)
604+
#define get_amp_direction(kc) get_amp_direction_((kc)->private_value)
604605
#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
605606
#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
606607
#define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1)

sound/pci/hda/patch_conexant.c

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ struct conexant_spec {
136136
unsigned int thinkpad:1;
137137
unsigned int hp_laptop:1;
138138
unsigned int asus:1;
139+
unsigned int pin_eapd_ctrls:1;
140+
unsigned int single_adc_amp:1;
139141

140142
unsigned int adc_switching:1;
141143

@@ -3430,12 +3432,14 @@ static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
34303432
static void do_automute(struct hda_codec *codec, int num_pins,
34313433
hda_nid_t *pins, bool on)
34323434
{
3435+
struct conexant_spec *spec = codec->spec;
34333436
int i;
34343437
for (i = 0; i < num_pins; i++)
34353438
snd_hda_codec_write(codec, pins[i], 0,
34363439
AC_VERB_SET_PIN_WIDGET_CONTROL,
34373440
on ? PIN_OUT : 0);
3438-
cx_auto_turn_eapd(codec, num_pins, pins, on);
3441+
if (spec->pin_eapd_ctrls)
3442+
cx_auto_turn_eapd(codec, num_pins, pins, on);
34393443
}
34403444

34413445
static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
@@ -3460,9 +3464,12 @@ static void cx_auto_update_speakers(struct hda_codec *codec)
34603464
int on = 1;
34613465

34623466
/* turn on HP EAPD when HP jacks are present */
3463-
if (spec->auto_mute)
3464-
on = spec->hp_present;
3465-
cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
3467+
if (spec->pin_eapd_ctrls) {
3468+
if (spec->auto_mute)
3469+
on = spec->hp_present;
3470+
cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
3471+
}
3472+
34663473
/* mute speakers in auto-mode if HP or LO jacks are plugged */
34673474
if (spec->auto_mute)
34683475
on = !(spec->hp_present ||
@@ -3889,20 +3896,10 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
38893896
#define cx_auto_parse_beep(codec)
38903897
#endif
38913898

3892-
static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
3893-
{
3894-
int i;
3895-
for (i = 0; i < nums; i++)
3896-
if (list[i] == nid)
3897-
return true;
3898-
return false;
3899-
}
3900-
3901-
/* parse extra-EAPD that aren't assigned to any pins */
3899+
/* parse EAPDs */
39023900
static void cx_auto_parse_eapd(struct hda_codec *codec)
39033901
{
39043902
struct conexant_spec *spec = codec->spec;
3905-
struct auto_pin_cfg *cfg = &spec->autocfg;
39063903
hda_nid_t nid, end_nid;
39073904

39083905
end_nid = codec->start_nid + codec->num_nodes;
@@ -3911,14 +3908,18 @@ static void cx_auto_parse_eapd(struct hda_codec *codec)
39113908
continue;
39123909
if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
39133910
continue;
3914-
if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3915-
found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3916-
found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs))
3917-
continue;
39183911
spec->eapds[spec->num_eapds++] = nid;
39193912
if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
39203913
break;
39213914
}
3915+
3916+
/* NOTE: below is a wild guess; if we have more than two EAPDs,
3917+
* it's a new chip, where EAPDs are supposed to be associated to
3918+
* pins, and we can control EAPD per pin.
3919+
* OTOH, if only one or two EAPDs are found, it's an old chip,
3920+
* thus it might control over all pins.
3921+
*/
3922+
spec->pin_eapd_ctrls = spec->num_eapds > 2;
39223923
}
39233924

39243925
static int cx_auto_parse_auto_config(struct hda_codec *codec)
@@ -4024,8 +4025,9 @@ static void cx_auto_init_output(struct hda_codec *codec)
40244025
}
40254026
}
40264027
cx_auto_update_speakers(codec);
4027-
/* turn on/off extra EAPDs, too */
4028-
cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4028+
/* turn on all EAPDs if no individual EAPD control is available */
4029+
if (!spec->pin_eapd_ctrls)
4030+
cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
40294031
}
40304032

40314033
static void cx_auto_init_input(struct hda_codec *codec)
@@ -4212,6 +4214,8 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
42124214
int idx = get_input_connection(codec, adc_nid, nid);
42134215
if (idx < 0)
42144216
continue;
4217+
if (spec->single_adc_amp)
4218+
idx = 0;
42154219
return cx_auto_add_volume_idx(codec, label, pfx,
42164220
cidx, adc_nid, HDA_INPUT, idx);
42174221
}
@@ -4252,14 +4256,21 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
42524256
struct hda_input_mux *imux = &spec->private_imux;
42534257
const char *prev_label;
42544258
int input_conn[HDA_MAX_NUM_INPUTS];
4255-
int i, err, cidx;
4259+
int i, j, err, cidx;
42564260
int multi_connection;
42574261

4262+
if (!imux->num_items)
4263+
return 0;
4264+
42584265
multi_connection = 0;
42594266
for (i = 0; i < imux->num_items; i++) {
42604267
cidx = get_input_connection(codec, spec->imux_info[i].adc,
42614268
spec->imux_info[i].pin);
4262-
input_conn[i] = (spec->imux_info[i].adc << 8) | cidx;
4269+
if (cidx < 0)
4270+
continue;
4271+
input_conn[i] = spec->imux_info[i].adc;
4272+
if (!spec->single_adc_amp)
4273+
input_conn[i] |= cidx << 8;
42634274
if (i > 0 && input_conn[i] != input_conn[0])
42644275
multi_connection = 1;
42654276
}
@@ -4288,6 +4299,15 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
42884299
err = cx_auto_add_capture_volume(codec, nid,
42894300
"Capture", "", cidx);
42904301
} else {
4302+
bool dup_found = false;
4303+
for (j = 0; j < i; j++) {
4304+
if (input_conn[j] == input_conn[i]) {
4305+
dup_found = true;
4306+
break;
4307+
}
4308+
}
4309+
if (dup_found)
4310+
continue;
42914311
err = cx_auto_add_capture_volume(codec, nid,
42924312
label, " Capture", cidx);
42934313
}
@@ -4412,6 +4432,12 @@ static int patch_conexant_auto(struct hda_codec *codec)
44124432
codec->spec = spec;
44134433
codec->pin_amp_workaround = 1;
44144434

4435+
switch (codec->vendor_id) {
4436+
case 0x14f15045:
4437+
spec->single_adc_amp = 1;
4438+
break;
4439+
}
4440+
44154441
apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
44164442

44174443
err = cx_auto_search_adcs(codec);

sound/pci/hda/patch_realtek.c

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ struct alc_spec {
116116
const hda_nid_t *capsrc_nids;
117117
hda_nid_t dig_in_nid; /* digital-in NID; optional */
118118
hda_nid_t mixer_nid; /* analog-mixer NID */
119+
DECLARE_BITMAP(vol_ctls, 0x20 << 1);
120+
DECLARE_BITMAP(sw_ctls, 0x20 << 1);
119121

120122
/* capture setup for dynamic dual-adc switch */
121123
hda_nid_t cur_adc;
@@ -3006,14 +3008,32 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
30063008
return 0;
30073009
}
30083010

3011+
static inline unsigned int get_ctl_pos(unsigned int data)
3012+
{
3013+
hda_nid_t nid = get_amp_nid_(data);
3014+
unsigned int dir = get_amp_direction_(data);
3015+
return (nid << 1) | dir;
3016+
}
3017+
3018+
#define is_ctl_used(bits, data) \
3019+
test_bit(get_ctl_pos(data), bits)
3020+
#define mark_ctl_usage(bits, data) \
3021+
set_bit(get_ctl_pos(data), bits)
3022+
30093023
static int alc_auto_add_vol_ctl(struct hda_codec *codec,
30103024
const char *pfx, int cidx,
30113025
hda_nid_t nid, unsigned int chs)
30123026
{
3027+
struct alc_spec *spec = codec->spec;
3028+
unsigned int val;
30133029
if (!nid)
30143030
return 0;
3031+
val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
3032+
if (is_ctl_used(spec->vol_ctls, val) && chs != 2) /* exclude LFE */
3033+
return 0;
3034+
mark_ctl_usage(spec->vol_ctls, val);
30153035
return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
3016-
HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
3036+
val);
30173037
}
30183038

30193039
#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
@@ -3026,6 +3046,7 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
30263046
const char *pfx, int cidx,
30273047
hda_nid_t nid, unsigned int chs)
30283048
{
3049+
struct alc_spec *spec = codec->spec;
30293050
int wid_type;
30303051
int type;
30313052
unsigned long val;
@@ -3042,6 +3063,9 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
30423063
type = ALC_CTL_BIND_MUTE;
30433064
val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
30443065
}
3066+
if (is_ctl_used(spec->sw_ctls, val) && chs != 2) /* exclude LFE */
3067+
return 0;
3068+
mark_ctl_usage(spec->sw_ctls, val);
30453069
return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
30463070
}
30473071

@@ -3136,12 +3160,16 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
31363160
int err;
31373161

31383162
if (!dac) {
3163+
unsigned int val;
31393164
/* the corresponding DAC is already occupied */
31403165
if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
31413166
return 0; /* no way */
31423167
/* create a switch only */
3143-
return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
3144-
HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3168+
val = HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT);
3169+
if (is_ctl_used(spec->sw_ctls, val))
3170+
return 0; /* already created */
3171+
mark_ctl_usage(spec->sw_ctls, val);
3172+
return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
31453173
}
31463174

31473175
sw = alc_look_for_out_mute_nid(codec, pin, dac);
@@ -3186,8 +3214,12 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
31863214
if (!num_pins || !pins[0])
31873215
return 0;
31883216

3189-
if (num_pins == 1)
3190-
return alc_auto_create_extra_out(codec, *pins, *dacs, pfx);
3217+
if (num_pins == 1) {
3218+
hda_nid_t dac = *dacs;
3219+
if (!dac)
3220+
dac = spec->multiout.dac_nids[0];
3221+
return alc_auto_create_extra_out(codec, *pins, dac, pfx);
3222+
}
31913223

31923224
if (dacs[num_pins - 1]) {
31933225
/* OK, we have a multi-output system with individual volumes */

0 commit comments

Comments
 (0)