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 | |
| 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>
| -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; |
