|
@@ -1541,6 +1541,63 @@ static int alc_read_coef_idx(struct hda_codec *codec,
|
|
|
return val;
|
|
|
}
|
|
|
|
|
|
+/* set right pin controls for digital I/O */
|
|
|
+static void alc_auto_init_digital(struct hda_codec *codec)
|
|
|
+{
|
|
|
+ struct alc_spec *spec = codec->spec;
|
|
|
+ int i;
|
|
|
+ hda_nid_t pin;
|
|
|
+
|
|
|
+ for (i = 0; i < spec->autocfg.dig_outs; i++) {
|
|
|
+ pin = spec->autocfg.dig_out_pins[i];
|
|
|
+ if (pin) {
|
|
|
+ snd_hda_codec_write(codec, pin, 0,
|
|
|
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
|
|
|
+ PIN_OUT);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pin = spec->autocfg.dig_in_pin;
|
|
|
+ if (pin)
|
|
|
+ snd_hda_codec_write(codec, pin, 0,
|
|
|
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
|
|
|
+ PIN_IN);
|
|
|
+}
|
|
|
+
|
|
|
+/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
|
|
|
+static void alc_auto_parse_digital(struct hda_codec *codec)
|
|
|
+{
|
|
|
+ struct alc_spec *spec = codec->spec;
|
|
|
+ int i, err;
|
|
|
+ hda_nid_t dig_nid;
|
|
|
+
|
|
|
+ /* support multiple SPDIFs; the secondary is set up as a slave */
|
|
|
+ for (i = 0; i < spec->autocfg.dig_outs; i++) {
|
|
|
+ err = snd_hda_get_connections(codec,
|
|
|
+ spec->autocfg.dig_out_pins[i],
|
|
|
+ &dig_nid, 1);
|
|
|
+ if (err < 0)
|
|
|
+ continue;
|
|
|
+ if (!i) {
|
|
|
+ spec->multiout.dig_out_nid = dig_nid;
|
|
|
+ spec->dig_out_type = spec->autocfg.dig_out_type[0];
|
|
|
+ } else {
|
|
|
+ spec->multiout.slave_dig_outs = spec->slave_dig_outs;
|
|
|
+ if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
|
|
|
+ break;
|
|
|
+ spec->slave_dig_outs[i - 1] = dig_nid;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (spec->autocfg.dig_in_pin) {
|
|
|
+ hda_nid_t dig_nid;
|
|
|
+ err = snd_hda_get_connections(codec,
|
|
|
+ spec->autocfg.dig_in_pin,
|
|
|
+ &dig_nid, 1);
|
|
|
+ if (err > 0)
|
|
|
+ spec->dig_in_nid = dig_nid;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* ALC888
|
|
|
*/
|
|
@@ -5013,7 +5070,7 @@ static void alc880_auto_init_input_src(struct hda_codec *codec)
|
|
|
static int alc880_parse_auto_config(struct hda_codec *codec)
|
|
|
{
|
|
|
struct alc_spec *spec = codec->spec;
|
|
|
- int i, err;
|
|
|
+ int err;
|
|
|
static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
|
|
|
|
|
|
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
|
|
@@ -5044,25 +5101,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
|
|
|
|
|
|
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
|
|
|
|
|
|
- /* check multiple SPDIF-out (for recent codecs) */
|
|
|
- for (i = 0; i < spec->autocfg.dig_outs; i++) {
|
|
|
- hda_nid_t dig_nid;
|
|
|
- err = snd_hda_get_connections(codec,
|
|
|
- spec->autocfg.dig_out_pins[i],
|
|
|
- &dig_nid, 1);
|
|
|
- if (err < 0)
|
|
|
- continue;
|
|
|
- if (!i)
|
|
|
- spec->multiout.dig_out_nid = dig_nid;
|
|
|
- else {
|
|
|
- spec->multiout.slave_dig_outs = spec->slave_dig_outs;
|
|
|
- if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
|
|
|
- break;
|
|
|
- spec->slave_dig_outs[i - 1] = dig_nid;
|
|
|
- }
|
|
|
- }
|
|
|
- if (spec->autocfg.dig_in_pin)
|
|
|
- spec->dig_in_nid = ALC880_DIGIN_NID;
|
|
|
+ alc_auto_parse_digital(codec);
|
|
|
|
|
|
if (spec->kctls.list)
|
|
|
add_mixer(spec, spec->kctls.list);
|
|
@@ -5085,6 +5124,7 @@ static void alc880_auto_init(struct hda_codec *codec)
|
|
|
alc880_auto_init_extra_out(codec);
|
|
|
alc880_auto_init_analog_input(codec);
|
|
|
alc880_auto_init_input_src(codec);
|
|
|
+ alc_auto_init_digital(codec);
|
|
|
if (spec->unsol_event)
|
|
|
alc_inithook(codec);
|
|
|
}
|
|
@@ -6724,6 +6764,7 @@ static void alc260_auto_init(struct hda_codec *codec)
|
|
|
alc260_auto_init_multi_out(codec);
|
|
|
alc260_auto_init_analog_input(codec);
|
|
|
alc260_auto_init_input_src(codec);
|
|
|
+ alc_auto_init_digital(codec);
|
|
|
if (spec->unsol_event)
|
|
|
alc_inithook(codec);
|
|
|
}
|
|
@@ -10546,7 +10587,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
|
|
|
{
|
|
|
struct alc_spec *spec = codec->spec;
|
|
|
static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
|
|
|
- int i, err;
|
|
|
+ int err;
|
|
|
|
|
|
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
|
|
|
alc882_ignore);
|
|
@@ -10576,25 +10617,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
|
|
|
|
|
|
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
|
|
|
|
|
|
- /* check multiple SPDIF-out (for recent codecs) */
|
|
|
- for (i = 0; i < spec->autocfg.dig_outs; i++) {
|
|
|
- hda_nid_t dig_nid;
|
|
|
- err = snd_hda_get_connections(codec,
|
|
|
- spec->autocfg.dig_out_pins[i],
|
|
|
- &dig_nid, 1);
|
|
|
- if (err < 0)
|
|
|
- continue;
|
|
|
- if (!i)
|
|
|
- spec->multiout.dig_out_nid = dig_nid;
|
|
|
- else {
|
|
|
- spec->multiout.slave_dig_outs = spec->slave_dig_outs;
|
|
|
- if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
|
|
|
- break;
|
|
|
- spec->slave_dig_outs[i - 1] = dig_nid;
|
|
|
- }
|
|
|
- }
|
|
|
- if (spec->autocfg.dig_in_pin)
|
|
|
- spec->dig_in_nid = ALC880_DIGIN_NID;
|
|
|
+ alc_auto_parse_digital(codec);
|
|
|
|
|
|
if (spec->kctls.list)
|
|
|
add_mixer(spec, spec->kctls.list);
|
|
@@ -10624,6 +10647,7 @@ static void alc882_auto_init(struct hda_codec *codec)
|
|
|
alc882_auto_init_hp_out(codec);
|
|
|
alc882_auto_init_analog_input(codec);
|
|
|
alc882_auto_init_input_src(codec);
|
|
|
+ alc_auto_init_digital(codec);
|
|
|
if (spec->unsol_event)
|
|
|
alc_inithook(codec);
|
|
|
}
|
|
@@ -12154,12 +12178,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
|
|
|
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
|
|
|
|
|
|
dig_only:
|
|
|
- if (spec->autocfg.dig_outs) {
|
|
|
- spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
|
|
|
- spec->dig_out_type = spec->autocfg.dig_out_type[0];
|
|
|
- }
|
|
|
- if (spec->autocfg.dig_in_pin)
|
|
|
- spec->dig_in_nid = ALC262_DIGIN_NID;
|
|
|
+ alc_auto_parse_digital(codec);
|
|
|
|
|
|
if (spec->kctls.list)
|
|
|
add_mixer(spec, spec->kctls.list);
|
|
@@ -12191,6 +12210,7 @@ static void alc262_auto_init(struct hda_codec *codec)
|
|
|
alc262_auto_init_hp_out(codec);
|
|
|
alc262_auto_init_analog_input(codec);
|
|
|
alc262_auto_init_input_src(codec);
|
|
|
+ alc_auto_init_digital(codec);
|
|
|
if (spec->unsol_event)
|
|
|
alc_inithook(codec);
|
|
|
}
|
|
@@ -13327,10 +13347,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
|
|
|
|
|
|
dig_only:
|
|
|
/* digital only support output */
|
|
|
- if (spec->autocfg.dig_outs) {
|
|
|
- spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
|
|
|
- spec->dig_out_type = spec->autocfg.dig_out_type[0];
|
|
|
- }
|
|
|
+ alc_auto_parse_digital(codec);
|
|
|
if (spec->kctls.list)
|
|
|
add_mixer(spec, spec->kctls.list);
|
|
|
|
|
@@ -13360,6 +13377,7 @@ static void alc268_auto_init(struct hda_codec *codec)
|
|
|
alc268_auto_init_hp_out(codec);
|
|
|
alc268_auto_init_mono_speaker_out(codec);
|
|
|
alc268_auto_init_analog_input(codec);
|
|
|
+ alc_auto_init_digital(codec);
|
|
|
if (spec->unsol_event)
|
|
|
alc_inithook(codec);
|
|
|
}
|
|
@@ -14305,8 +14323,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
|
|
|
|
|
|
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
|
|
|
|
|
|
- if (spec->autocfg.dig_outs)
|
|
|
- spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
|
|
|
+ alc_auto_parse_digital(codec);
|
|
|
|
|
|
if (spec->kctls.list)
|
|
|
add_mixer(spec, spec->kctls.list);
|
|
@@ -14354,6 +14371,7 @@ static void alc269_auto_init(struct hda_codec *codec)
|
|
|
alc269_auto_init_multi_out(codec);
|
|
|
alc269_auto_init_hp_out(codec);
|
|
|
alc269_auto_init_analog_input(codec);
|
|
|
+ alc_auto_init_digital(codec);
|
|
|
if (spec->unsol_event)
|
|
|
alc_inithook(codec);
|
|
|
}
|
|
@@ -15515,8 +15533,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
|
|
|
|
|
|
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
|
|
|
|
|
|
- if (spec->autocfg.dig_outs)
|
|
|
- spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
|
|
|
+ alc_auto_parse_digital(codec);
|
|
|
|
|
|
if (spec->kctls.list)
|
|
|
add_mixer(spec, spec->kctls.list);
|
|
@@ -15542,6 +15559,7 @@ static void alc861_auto_init(struct hda_codec *codec)
|
|
|
alc861_auto_init_multi_out(codec);
|
|
|
alc861_auto_init_hp_out(codec);
|
|
|
alc861_auto_init_analog_input(codec);
|
|
|
+ alc_auto_init_digital(codec);
|
|
|
if (spec->unsol_event)
|
|
|
alc_inithook(codec);
|
|
|
}
|
|
@@ -16646,8 +16664,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
|
|
|
|
|
|
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
|
|
|
|
|
|
- if (spec->autocfg.dig_outs)
|
|
|
- spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
|
|
|
+ alc_auto_parse_digital(codec);
|
|
|
|
|
|
if (spec->kctls.list)
|
|
|
add_mixer(spec, spec->kctls.list);
|
|
@@ -16674,6 +16691,7 @@ static void alc861vd_auto_init(struct hda_codec *codec)
|
|
|
alc861vd_auto_init_hp_out(codec);
|
|
|
alc861vd_auto_init_analog_input(codec);
|
|
|
alc861vd_auto_init_input_src(codec);
|
|
|
+ alc_auto_init_digital(codec);
|
|
|
if (spec->unsol_event)
|
|
|
alc_inithook(codec);
|
|
|
}
|
|
@@ -18761,8 +18779,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
|
|
|
|
|
|
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
|
|
|
|
|
|
- if (spec->autocfg.dig_outs)
|
|
|
- spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
|
|
|
+ alc_auto_parse_digital(codec);
|
|
|
|
|
|
if (spec->kctls.list)
|
|
|
add_mixer(spec, spec->kctls.list);
|
|
@@ -18799,6 +18816,7 @@ static void alc662_auto_init(struct hda_codec *codec)
|
|
|
alc662_auto_init_hp_out(codec);
|
|
|
alc662_auto_init_analog_input(codec);
|
|
|
alc662_auto_init_input_src(codec);
|
|
|
+ alc_auto_init_digital(codec);
|
|
|
if (spec->unsol_event)
|
|
|
alc_inithook(codec);
|
|
|
}
|
|
@@ -19124,10 +19142,7 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
|
|
|
|
|
|
dig_only:
|
|
|
/* digital only support output */
|
|
|
- if (spec->autocfg.dig_outs) {
|
|
|
- spec->multiout.dig_out_nid = ALC680_DIGOUT_NID;
|
|
|
- spec->dig_out_type = spec->autocfg.dig_out_type[0];
|
|
|
- }
|
|
|
+ alc_auto_parse_digital(codec);
|
|
|
if (spec->kctls.list)
|
|
|
add_mixer(spec, spec->kctls.list);
|
|
|
|
|
@@ -19151,6 +19166,7 @@ static void alc680_auto_init(struct hda_codec *codec)
|
|
|
alc680_auto_init_multi_out(codec);
|
|
|
alc680_auto_init_hp_out(codec);
|
|
|
alc680_auto_init_analog_input(codec);
|
|
|
+ alc_auto_init_digital(codec);
|
|
|
if (spec->unsol_event)
|
|
|
alc_inithook(codec);
|
|
|
}
|