diff options
author | Matthew Ranostay <mranostay@embeddedalley.com> | 2008-01-24 05:49:21 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:30:13 -0500 |
commit | 09a99959180d25f4e5070f902e3adc1b20439cd6 (patch) | |
tree | 991af44ef8181a899e56b52ff31035b6bf654b7d /sound/pci | |
parent | 90da78bf6aaabd4d31c6663b7c1d1b9c5a8c023f (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/pci')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 61 |
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 | */ |
772 | static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) | 772 | u32 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 | ||
378 | u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction); | ||
378 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | 379 | int 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 | ||
757 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | 757 | static 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 | ||
776 | static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | 773 | static 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 | ||
1158 | static unsigned int ref925x_pin_configs[8] = { | 1152 | static 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 | ||
1163 | static unsigned int stac925x_MA6_pin_configs[8] = { | 1157 | static unsigned int stac925x_MA6_pin_configs[8] = { |
@@ -1561,7 +1555,7 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
1561 | 1555 | ||
1562 | static unsigned int ref9205_pin_configs[12] = { | 1556 | static 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, | |||
2018 | enum { | 2012 | enum { |
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 { | |||
2025 | static struct snd_kcontrol_new stac92xx_control_templates[] = { | 2020 | static 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; |