aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMatthew Ranostay <mranostay@embeddedalley.com>2008-01-24 05:49:21 -0500
committerJaroslav Kysela <perex@perex.cz>2008-01-31 11:30:13 -0500
commit09a99959180d25f4e5070f902e3adc1b20439cd6 (patch)
tree991af44ef8181a899e56b52ff31035b6bf654b7d /sound
parent90da78bf6aaabd4d31c6663b7c1d1b9c5a8c023f (diff)
[ALSA] hda: Add dynamic mono mixer support for STAC92xx codecs
Allows for dynamically creating mono out mixer controls and well as mono mux controls. Signed-off-by: Matthew Ranostay <mranostay@embeddedalley.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_codec.c2
-rw-r--r--sound/pci/hda/hda_local.h1
-rw-r--r--sound/pci/hda/patch_sigmatel.c61
3 files changed, 53 insertions, 11 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index df927be176af..26812dc2b7f2 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -769,7 +769,7 @@ get_alloc_amp_hash(struct hda_codec *codec, u32 key)
769/* 769/*
770 * query AMP capabilities for the given widget and direction 770 * query AMP capabilities for the given widget and direction
771 */ 771 */
772static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) 772u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
773{ 773{
774 struct hda_amp_info *info; 774 struct hda_amp_info *info;
775 775
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 8a96047d3c79..ad0014ab71f9 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -375,6 +375,7 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
375 return codec->wcaps[nid - codec->start_nid]; 375 return codec->wcaps[nid - codec->start_nid];
376} 376}
377 377
378u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
378int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 379int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
379 unsigned int caps); 380 unsigned int caps);
380 381
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index e014ae38db0f..b8152efbfc8c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -756,7 +756,6 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
756 756
757static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { 757static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
758 STAC_INPUT_SOURCE(2), 758 STAC_INPUT_SOURCE(2),
759 STAC_MONO_MUX,
760 759
761 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), 760 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
762 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), 761 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
@@ -768,15 +767,12 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
768 767
769 HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT), 768 HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT),
770 HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT), 769 HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT),
771
772 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x14, 0x1, 0, HDA_INPUT),
773 { } /* end */ 770 { } /* end */
774}; 771};
775 772
776static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { 773static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
777 STAC_INPUT_SOURCE(2), 774 STAC_INPUT_SOURCE(2),
778 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), 775 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2),
779 STAC_MONO_MUX,
780 776
781 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), 777 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
782 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), 778 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
@@ -785,8 +781,6 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
785 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), 781 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
786 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), 782 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
787 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), 783 HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT),
788
789 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x14, 0x1, 0, HDA_INPUT),
790 { } /* end */ 784 { } /* end */
791}; 785};
792 786
@@ -1157,7 +1151,7 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = {
1157 1151
1158static unsigned int ref925x_pin_configs[8] = { 1152static unsigned int ref925x_pin_configs[8] = {
1159 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, 1153 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
1160 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e, 1154 0x90a70320, 0x02214210, 0x01019020, 0x9033032e,
1161}; 1155};
1162 1156
1163static unsigned int stac925x_MA6_pin_configs[8] = { 1157static unsigned int stac925x_MA6_pin_configs[8] = {
@@ -1561,7 +1555,7 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
1561 1555
1562static unsigned int ref9205_pin_configs[12] = { 1556static unsigned int ref9205_pin_configs[12] = {
1563 0x40000100, 0x40000100, 0x01016011, 0x01014010, 1557 0x40000100, 0x40000100, 0x01016011, 0x01014010,
1564 0x01813122, 0x01a19021, 0x40000100, 0x40000100, 1558 0x01813122, 0x01a19021, 0x01019020, 0x40000100,
1565 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030 1559 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
1566}; 1560};
1567 1561
@@ -2018,6 +2012,7 @@ static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
2018enum { 2012enum {
2019 STAC_CTL_WIDGET_VOL, 2013 STAC_CTL_WIDGET_VOL,
2020 STAC_CTL_WIDGET_MUTE, 2014 STAC_CTL_WIDGET_MUTE,
2015 STAC_CTL_WIDGET_MONO_MUX,
2021 STAC_CTL_WIDGET_IO_SWITCH, 2016 STAC_CTL_WIDGET_IO_SWITCH,
2022 STAC_CTL_WIDGET_CLFE_SWITCH 2017 STAC_CTL_WIDGET_CLFE_SWITCH
2023}; 2018};
@@ -2025,6 +2020,7 @@ enum {
2025static struct snd_kcontrol_new stac92xx_control_templates[] = { 2020static struct snd_kcontrol_new stac92xx_control_templates[] = {
2026 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2021 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2027 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2022 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2023 STAC_MONO_MUX,
2028 STAC_CODEC_IO_SWITCH(NULL, 0), 2024 STAC_CODEC_IO_SWITCH(NULL, 0),
2029 STAC_CODEC_CLFE_SWITCH(NULL, 0), 2025 STAC_CODEC_CLFE_SWITCH(NULL, 0),
2030}; 2026};
@@ -2388,7 +2384,9 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
2388 mono_mux->items[mono_mux->num_items].index = i; 2384 mono_mux->items[mono_mux->num_items].index = i;
2389 mono_mux->num_items++; 2385 mono_mux->num_items++;
2390 } 2386 }
2391 return 0; 2387
2388 return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX,
2389 "Mono Mux", spec->mono_nid);
2392} 2390}
2393 2391
2394/* labels for dmic mux inputs */ 2392/* labels for dmic mux inputs */
@@ -2570,6 +2568,50 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
2570 spec->autocfg.line_outs = spec->autocfg.hp_outs; 2568 spec->autocfg.line_outs = spec->autocfg.hp_outs;
2571 hp_speaker_swap = 1; 2569 hp_speaker_swap = 1;
2572 } 2570 }
2571 if (spec->autocfg.mono_out_pin) {
2572 int dir = (get_wcaps(codec, spec->autocfg.mono_out_pin)
2573 & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT;
2574 u32 caps = query_amp_caps(codec,
2575 spec->autocfg.mono_out_pin, dir);
2576 hda_nid_t conn_list[1];
2577
2578 /* get the mixer node and then the mono mux if it exists */
2579 if (snd_hda_get_connections(codec,
2580 spec->autocfg.mono_out_pin, conn_list, 1) &&
2581 snd_hda_get_connections(codec, conn_list[0],
2582 conn_list, 1)) {
2583
2584 int wcaps = get_wcaps(codec, conn_list[0]);
2585 int wid_type = (wcaps & AC_WCAP_TYPE)
2586 >> AC_WCAP_TYPE_SHIFT;
2587 /* LR swap check, some stac925x have a mux that
2588 * changes the DACs output path instead of the
2589 * mono-mux path.
2590 */
2591 if (wid_type == AC_WID_AUD_SEL &&
2592 !(wcaps & AC_WCAP_LR_SWAP))
2593 spec->mono_nid = conn_list[0];
2594 }
2595 /* all mono outs have a least a mute/unmute switch */
2596 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE,
2597 "Mono Playback Switch",
2598 HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin,
2599 1, 0, dir));
2600 if (err < 0)
2601 return err;
2602 /* check to see if there is volume support for the amp */
2603 if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) {
2604 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL,
2605 "Mono Playback Volume",
2606 HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin,
2607 1, 0, dir));
2608 if (err < 0)
2609 return err;
2610 }
2611
2612 stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin,
2613 AC_PINCTL_OUT_EN);
2614 }
2573 2615
2574 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) 2616 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
2575 return err; 2617 return err;
@@ -3317,7 +3359,6 @@ again:
3317 3359
3318 spec->gpio_mask = spec->gpio_data = 0x00000001; /* GPIO0 High = EAPD */ 3360 spec->gpio_mask = spec->gpio_data = 0x00000001; /* GPIO0 High = EAPD */
3319 3361
3320 spec->mono_nid = 0x15;
3321 spec->mux_nids = stac92hd71bxx_mux_nids; 3362 spec->mux_nids = stac92hd71bxx_mux_nids;
3322 spec->adc_nids = stac92hd71bxx_adc_nids; 3363 spec->adc_nids = stac92hd71bxx_adc_nids;
3323 spec->dmic_nids = stac92hd71bxx_dmic_nids; 3364 spec->dmic_nids = stac92hd71bxx_dmic_nids;