Merge branch 'test/hda-vol-ofs' into next/hda
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 64eb110..75914bc 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -352,5 +352,4 @@
STAC9872
========
- vaio Setup for VAIO FE550G/SZ110
- vaio-ar Setup for VAIO AR
+ N/A
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 0cf2424..a259b3e 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2642,7 +2642,7 @@
int dev;
if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
- return 0; /* no substreams assigned */
+ continue; /* no substreams assigned */
if (!cpcm->pcm) {
dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type);
@@ -3419,10 +3419,20 @@
cfg->input_pins[AUTO_PIN_AUX] = nid;
break;
case AC_JACK_SPDIF_OUT:
+ case AC_JACK_DIG_OTHER_OUT:
cfg->dig_out_pin = nid;
+ if (loc == AC_JACK_LOC_HDMI)
+ cfg->dig_out_type = HDA_PCM_TYPE_HDMI;
+ else
+ cfg->dig_out_type = HDA_PCM_TYPE_SPDIF;
break;
case AC_JACK_SPDIF_IN:
+ case AC_JACK_DIG_OTHER_IN:
cfg->dig_in_pin = nid;
+ if (loc == AC_JACK_LOC_HDMI)
+ cfg->dig_in_type = HDA_PCM_TYPE_HDMI;
+ else
+ cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
break;
}
}
@@ -3528,6 +3538,8 @@
cfg->hp_pins[1], cfg->hp_pins[2],
cfg->hp_pins[3], cfg->hp_pins[4]);
snd_printd(" mono: mono_out=0x%x\n", cfg->mono_out_pin);
+ if (cfg->dig_out_pin)
+ snd_printd(" dig-out=0x%x\n", cfg->dig_out_pin);
snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x,"
" cd=0x%x, aux=0x%x\n",
cfg->input_pins[AUTO_PIN_MIC],
@@ -3536,6 +3548,8 @@
cfg->input_pins[AUTO_PIN_FRONT_LINE],
cfg->input_pins[AUTO_PIN_CD],
cfg->input_pins[AUTO_PIN_AUX]);
+ if (cfg->dig_out_pin)
+ snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin);
return 0;
}
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index d53ce1f..ec687b2 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -357,6 +357,8 @@
hda_nid_t dig_out_pin;
hda_nid_t dig_in_pin;
hda_nid_t mono_out_pin;
+ int dig_out_type; /* HDA_PCM_TYPE_XXX */
+ int dig_in_type; /* HDA_PCM_TYPE_XXX */
};
#define get_defcfg_connect(cfg) \
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 5d249a5..4cfa78c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -269,6 +269,7 @@
* dig_out_nid and hp_nid are optional
*/
hda_nid_t alt_dac_nid;
+ int dig_out_type;
/* capture */
unsigned int num_adc_nids;
@@ -305,6 +306,9 @@
unsigned int jack_present: 1;
unsigned int master_sw: 1;
+ /* other flags */
+ unsigned int no_analog :1; /* digital I/O only */
+
/* for virtual master */
hda_nid_t vmaster_nid;
#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -2018,11 +2022,13 @@
spec->multiout.dig_out_nid);
if (err < 0)
return err;
- err = snd_hda_create_spdif_share_sw(codec,
- &spec->multiout);
- if (err < 0)
- return err;
- spec->multiout.share_spdif = 1;
+ if (!spec->no_analog) {
+ err = snd_hda_create_spdif_share_sw(codec,
+ &spec->multiout);
+ if (err < 0)
+ return err;
+ spec->multiout.share_spdif = 1;
+ }
}
if (spec->dig_in_nid) {
err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
@@ -2031,7 +2037,8 @@
}
/* if we have no master control, let's create it */
- if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
+ if (!spec->no_analog &&
+ !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
unsigned int vmaster_tlv[4];
snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
HDA_OUTPUT, vmaster_tlv);
@@ -2040,7 +2047,8 @@
if (err < 0)
return err;
}
- if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
+ if (!spec->no_analog &&
+ !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
err = snd_hda_add_vmaster(codec, "Master Playback Switch",
NULL, alc_slave_sws);
if (err < 0)
@@ -3059,6 +3067,9 @@
codec->num_pcms = 1;
codec->pcm_info = info;
+ if (spec->no_analog)
+ goto skip_analog;
+
info->name = spec->stream_name_analog;
if (spec->stream_analog_playback) {
if (snd_BUG_ON(!spec->multiout.dac_nids))
@@ -3082,12 +3093,16 @@
}
}
+ skip_analog:
/* SPDIF for stream index #1 */
if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
codec->num_pcms = 2;
info = spec->pcm_rec + 1;
info->name = spec->stream_name_digital;
- info->pcm_type = HDA_PCM_TYPE_SPDIF;
+ if (spec->dig_out_type)
+ info->pcm_type = spec->dig_out_type;
+ else
+ info->pcm_type = HDA_PCM_TYPE_SPDIF;
if (spec->multiout.dig_out_nid &&
spec->stream_digital_playback) {
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
@@ -3102,6 +3117,9 @@
codec->spdif_status_reset = 1;
}
+ if (spec->no_analog)
+ return 0;
+
/* If the use of more than one ADC is requested for the current
* model, configure a second analog capture-only PCM.
*/
@@ -10464,8 +10482,14 @@
alc262_ignore);
if (err < 0)
return err;
- if (!spec->autocfg.line_outs)
+ if (!spec->autocfg.line_outs) {
+ if (spec->autocfg.dig_out_pin || spec->autocfg.dig_in_pin) {
+ spec->multiout.max_channels = 2;
+ spec->no_analog = 1;
+ goto dig_only;
+ }
return 0; /* can't find valid BIOS pin config */
+ }
err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
if (err < 0)
return err;
@@ -10475,8 +10499,11 @@
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
- if (spec->autocfg.dig_out_pin)
+ dig_only:
+ if (spec->autocfg.dig_out_pin) {
spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
+ spec->dig_out_type = spec->autocfg.dig_out_type;
+ }
if (spec->autocfg.dig_in_pin)
spec->dig_in_nid = ALC262_DIGIN_NID;
@@ -10871,7 +10898,7 @@
spec->capsrc_nids = alc262_capsrc_nids;
}
}
- if (!spec->cap_mixer)
+ if (!spec->cap_mixer && !spec->no_analog)
set_capture_mixer(spec);
spec->vmaster_nid = 0x0c;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index c2d4abe..0fa6c59 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -844,10 +844,6 @@
};
static struct hda_verb stac92hd83xxx_core_init[] = {
- /* start of config #1 */
- { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3},
-
- /* start of config #2 */
{ 0xa, AC_VERB_SET_CONNECT_SEL, 0x0},
{ 0xb, AC_VERB_SET_CONNECT_SEL, 0x0},
{ 0xd, AC_VERB_SET_CONNECT_SEL, 0x1},
@@ -2558,7 +2554,7 @@
codec->num_pcms++;
info++;
info->name = "STAC92xx Digital";
- info->pcm_type = HDA_PCM_TYPE_SPDIF;
+ info->pcm_type = spec->autocfg.dig_out_type;
if (spec->multiout.dig_out_nid) {
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
@@ -4779,7 +4775,9 @@
static int patch_stac92hd83xxx(struct hda_codec *codec)
{
struct sigmatel_spec *spec;
+ hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
int err;
+ int num_dacs;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
@@ -4798,13 +4796,21 @@
spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
spec->multiout.dac_nids = spec->dac_nids;
+
+ /* set port 0xe to select the last DAC
+ */
+ num_dacs = snd_hda_get_connections(codec, 0x0e,
+ conn, STAC92HD83_DAC_COUNT + 1) - 1;
+
+ snd_hda_codec_write_cache(codec, 0xe, 0,
+ AC_VERB_SET_CONNECT_SEL, num_dacs);
+
spec->init = stac92hd83xxx_core_init;
switch (codec->vendor_id) {
case 0x111d7605:
break;
default:
spec->num_pwrs--;
- spec->init++; /* switch to config #2 */
}
spec->mixer = stac92hd83xxx_mixer;
@@ -5370,223 +5376,65 @@
* STAC9872 hack
*/
-/* static config for Sony VAIO FE550G and Sony VAIO AR */
-static hda_nid_t vaio_dacs[] = { 0x2 };
-#define VAIO_HP_DAC 0x5
-static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
-static hda_nid_t vaio_mux_nids[] = { 0x15 };
-
-static struct hda_input_mux vaio_mux = {
- .num_items = 3,
- .items = {
- /* { "HP", 0x0 }, */
- { "Mic Jack", 0x1 },
- { "Internal Mic", 0x2 },
- { "PCM", 0x3 },
- }
-};
-
-static struct hda_verb vaio_init[] = {
- {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
- {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
- {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
- {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
- {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
+static struct hda_verb stac9872_core_init[] = {
{0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
- {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
- {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
{}
};
-static struct hda_verb vaio_ar_init[] = {
- {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
- {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
- {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
- {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
-/* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
- {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
- {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
-/* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
- {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
- {}
-};
-
-static struct snd_kcontrol_new vaio_mixer[] = {
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT),
- /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
+static struct snd_kcontrol_new stac9872_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .count = 1,
- .info = stac92xx_mux_enum_info,
- .get = stac92xx_mux_enum_get,
- .put = stac92xx_mux_enum_put,
- },
- {}
+ STAC_INPUT_SOURCE(1),
+ { } /* end */
};
-static struct snd_kcontrol_new vaio_ar_mixer[] = {
- HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT),
- /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
- HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
- /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .count = 1,
- .info = stac92xx_mux_enum_info,
- .get = stac92xx_mux_enum_get,
- .put = stac92xx_mux_enum_put,
- },
- {}
+static hda_nid_t stac9872_pin_nids[] = {
+ 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x11, 0x13, 0x14,
};
-static struct hda_codec_ops stac9872_patch_ops = {
- .build_controls = stac92xx_build_controls,
- .build_pcms = stac92xx_build_pcms,
- .init = stac92xx_init,
- .free = stac92xx_free,
-#ifdef SND_HDA_NEEDS_RESUME
- .resume = stac92xx_resume,
-#endif
+static hda_nid_t stac9872_adc_nids[] = {
+ 0x8 /*,0x6*/
};
-static int stac9872_vaio_init(struct hda_codec *codec)
-{
- int err;
-
- err = stac92xx_init(codec);
- if (err < 0)
- return err;
- if (codec->patch_ops.unsol_event)
- codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
- return 0;
-}
-
-static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
-{
- if (get_pin_presence(codec, 0x0a)) {
- stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
- stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
- } else {
- stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
- stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
- }
-}
-
-static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
-{
- switch (res >> 26) {
- case STAC_HP_EVENT:
- stac9872_vaio_hp_detect(codec, res);
- break;
- }
-}
-
-static struct hda_codec_ops stac9872_vaio_patch_ops = {
- .build_controls = stac92xx_build_controls,
- .build_pcms = stac92xx_build_pcms,
- .init = stac9872_vaio_init,
- .free = stac92xx_free,
- .unsol_event = stac9872_vaio_unsol_event,
-#ifdef CONFIG_PM
- .resume = stac92xx_resume,
-#endif
-};
-
-enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
- CXD9872RD_VAIO,
- /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
- STAC9872AK_VAIO,
- /* Unknown. id=0x83847661 and subsys=0x104D1200. */
- STAC9872K_VAIO,
- /* AR Series. id=0x83847664 and subsys=104D1300 */
- CXD9872AKD_VAIO,
- STAC_9872_MODELS,
-};
-
-static const char *stac9872_models[STAC_9872_MODELS] = {
- [CXD9872RD_VAIO] = "vaio",
- [CXD9872AKD_VAIO] = "vaio-ar",
-};
-
-static struct snd_pci_quirk stac9872_cfg_tbl[] = {
- SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
- SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
- SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
- SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
- {}
+static hda_nid_t stac9872_mux_nids[] = {
+ 0x15
};
static int patch_stac9872(struct hda_codec *codec)
{
struct sigmatel_spec *spec;
- int board_config;
+ int err;
- board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
- stac9872_models,
- stac9872_cfg_tbl);
- if (board_config < 0)
- /* unknown config, let generic-parser do its job... */
- return snd_hda_parse_generic_codec(codec);
-
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
-
codec->spec = spec;
- switch (board_config) {
- case CXD9872RD_VAIO:
- case STAC9872AK_VAIO:
- case STAC9872K_VAIO:
- spec->mixer = vaio_mixer;
- spec->init = vaio_init;
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
- spec->multiout.dac_nids = vaio_dacs;
- spec->multiout.hp_nid = VAIO_HP_DAC;
- spec->num_adcs = ARRAY_SIZE(vaio_adcs);
- spec->adc_nids = vaio_adcs;
- spec->num_pwrs = 0;
- spec->input_mux = &vaio_mux;
- spec->mux_nids = vaio_mux_nids;
- codec->patch_ops = stac9872_vaio_patch_ops;
- break;
-
- case CXD9872AKD_VAIO:
- spec->mixer = vaio_ar_mixer;
- spec->init = vaio_ar_init;
- spec->multiout.max_channels = 2;
- spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
- spec->multiout.dac_nids = vaio_dacs;
- spec->multiout.hp_nid = VAIO_HP_DAC;
- spec->num_adcs = ARRAY_SIZE(vaio_adcs);
- spec->num_pwrs = 0;
- spec->adc_nids = vaio_adcs;
- spec->input_mux = &vaio_mux;
- spec->mux_nids = vaio_mux_nids;
- codec->patch_ops = stac9872_patch_ops;
- break;
- }
+#if 0 /* no model right now */
+ spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
+ stac9872_models,
+ stac9872_cfg_tbl);
+#endif
+
+ spec->num_pins = ARRAY_SIZE(stac9872_pin_nids);
+ spec->pin_nids = stac9872_pin_nids;
+ spec->multiout.dac_nids = spec->dac_nids;
+ spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids);
+ spec->adc_nids = stac9872_adc_nids;
+ spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids);
+ spec->mux_nids = stac9872_mux_nids;
+ spec->mixer = stac9872_mixer;
+ spec->init = stac9872_core_init;
+
+ err = stac92xx_parse_auto_config(codec, 0x10, 0x12);
+ if (err < 0) {
+ stac92xx_free(codec);
+ return -EINVAL;
+ }
+ spec->input_mux = &spec->private_imux;
+ codec->patch_ops = stac92xx_patch_ops;
return 0;
}