diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-01-23 05:57:22 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-01-23 05:57:22 -0500 |
commit | e3c75964666a27cec46d2cccf2d9806336becd48 (patch) | |
tree | 5b961f9f0aa389b5e17464c77e597cee033f4153 /sound/pci/hda/patch_sigmatel.c | |
parent | 028b9445b4b10fa8da61ba7cf14ff72cc877ef41 (diff) |
ALSA: hda - Create "Input Source" control dynamically for STAC/IDT
Instead of fixed kcontrol_new element, build "Input Source" controls
dynamically. If the number of input-source items is 0 or 1, we don't
need to create such a control.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index b3c3a02a4222..80a4c288b319 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -958,16 +958,6 @@ static struct hda_verb stac9205_core_init[] = { | |||
958 | .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ | 958 | .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ |
959 | } | 959 | } |
960 | 960 | ||
961 | #define STAC_INPUT_SOURCE(cnt) \ | ||
962 | { \ | ||
963 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
964 | .name = "Input Source", \ | ||
965 | .count = cnt, \ | ||
966 | .info = stac92xx_mux_enum_info, \ | ||
967 | .get = stac92xx_mux_enum_get, \ | ||
968 | .put = stac92xx_mux_enum_put, \ | ||
969 | } | ||
970 | |||
971 | #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ | 961 | #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ |
972 | { \ | 962 | { \ |
973 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 963 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
@@ -982,7 +972,6 @@ static struct hda_verb stac9205_core_init[] = { | |||
982 | static struct snd_kcontrol_new stac9200_mixer[] = { | 972 | static struct snd_kcontrol_new stac9200_mixer[] = { |
983 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), | 973 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), |
984 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), | 974 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), |
985 | STAC_INPUT_SOURCE(1), | ||
986 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), | 975 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), |
987 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), | 976 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), |
988 | { } /* end */ | 977 | { } /* end */ |
@@ -1098,7 +1087,6 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | |||
1098 | }; | 1087 | }; |
1099 | 1088 | ||
1100 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | 1089 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { |
1101 | STAC_INPUT_SOURCE(2), | ||
1102 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), | 1090 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), |
1103 | 1091 | ||
1104 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1092 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
@@ -1127,7 +1115,6 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | |||
1127 | }; | 1115 | }; |
1128 | 1116 | ||
1129 | static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | 1117 | static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { |
1130 | STAC_INPUT_SOURCE(2), | ||
1131 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), | 1118 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), |
1132 | 1119 | ||
1133 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1120 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
@@ -1141,14 +1128,12 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | |||
1141 | static struct snd_kcontrol_new stac925x_mixer[] = { | 1128 | static struct snd_kcontrol_new stac925x_mixer[] = { |
1142 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), | 1129 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), |
1143 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), | 1130 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), |
1144 | STAC_INPUT_SOURCE(1), | ||
1145 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), | 1131 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), |
1146 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), | 1132 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), |
1147 | { } /* end */ | 1133 | { } /* end */ |
1148 | }; | 1134 | }; |
1149 | 1135 | ||
1150 | static struct snd_kcontrol_new stac9205_mixer[] = { | 1136 | static struct snd_kcontrol_new stac9205_mixer[] = { |
1151 | STAC_INPUT_SOURCE(2), | ||
1152 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), | 1137 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), |
1153 | 1138 | ||
1154 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), | 1139 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), |
@@ -1161,7 +1146,6 @@ static struct snd_kcontrol_new stac9205_mixer[] = { | |||
1161 | 1146 | ||
1162 | /* This needs to be generated dynamically based on sequence */ | 1147 | /* This needs to be generated dynamically based on sequence */ |
1163 | static struct snd_kcontrol_new stac922x_mixer[] = { | 1148 | static struct snd_kcontrol_new stac922x_mixer[] = { |
1164 | STAC_INPUT_SOURCE(2), | ||
1165 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), | 1149 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), |
1166 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), | 1150 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), |
1167 | 1151 | ||
@@ -1172,7 +1156,6 @@ static struct snd_kcontrol_new stac922x_mixer[] = { | |||
1172 | 1156 | ||
1173 | 1157 | ||
1174 | static struct snd_kcontrol_new stac927x_mixer[] = { | 1158 | static struct snd_kcontrol_new stac927x_mixer[] = { |
1175 | STAC_INPUT_SOURCE(3), | ||
1176 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), | 1159 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), |
1177 | 1160 | ||
1178 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), | 1161 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), |
@@ -2777,22 +2760,37 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { | |||
2777 | }; | 2760 | }; |
2778 | 2761 | ||
2779 | /* add dynamic controls */ | 2762 | /* add dynamic controls */ |
2780 | static int stac92xx_add_control_temp(struct sigmatel_spec *spec, | 2763 | static struct snd_kcontrol_new * |
2781 | struct snd_kcontrol_new *ktemp, | 2764 | stac_control_new(struct sigmatel_spec *spec, |
2782 | int idx, const char *name, | 2765 | struct snd_kcontrol_new *ktemp, |
2783 | unsigned long val) | 2766 | const char *name) |
2784 | { | 2767 | { |
2785 | struct snd_kcontrol_new *knew; | 2768 | struct snd_kcontrol_new *knew; |
2786 | 2769 | ||
2787 | snd_array_init(&spec->kctls, sizeof(*knew), 32); | 2770 | snd_array_init(&spec->kctls, sizeof(*knew), 32); |
2788 | knew = snd_array_new(&spec->kctls); | 2771 | knew = snd_array_new(&spec->kctls); |
2789 | if (!knew) | 2772 | if (!knew) |
2790 | return -ENOMEM; | 2773 | return NULL; |
2791 | *knew = *ktemp; | 2774 | *knew = *ktemp; |
2792 | knew->index = idx; | ||
2793 | knew->name = kstrdup(name, GFP_KERNEL); | 2775 | knew->name = kstrdup(name, GFP_KERNEL); |
2794 | if (!knew->name) | 2776 | if (!knew->name) { |
2777 | /* roolback */ | ||
2778 | memset(knew, 0, sizeof(*knew)); | ||
2779 | spec->kctls.alloced--; | ||
2780 | return NULL; | ||
2781 | } | ||
2782 | return knew; | ||
2783 | } | ||
2784 | |||
2785 | static int stac92xx_add_control_temp(struct sigmatel_spec *spec, | ||
2786 | struct snd_kcontrol_new *ktemp, | ||
2787 | int idx, const char *name, | ||
2788 | unsigned long val) | ||
2789 | { | ||
2790 | struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name); | ||
2791 | if (!knew) | ||
2795 | return -ENOMEM; | 2792 | return -ENOMEM; |
2793 | knew->index = idx; | ||
2796 | knew->private_value = val; | 2794 | knew->private_value = val; |
2797 | return 0; | 2795 | return 0; |
2798 | } | 2796 | } |
@@ -2814,6 +2812,29 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, | |||
2814 | return stac92xx_add_control_idx(spec, type, 0, name, val); | 2812 | return stac92xx_add_control_idx(spec, type, 0, name, val); |
2815 | } | 2813 | } |
2816 | 2814 | ||
2815 | static struct snd_kcontrol_new stac_input_src_temp = { | ||
2816 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2817 | .name = "Input Source", | ||
2818 | .info = stac92xx_mux_enum_info, | ||
2819 | .get = stac92xx_mux_enum_get, | ||
2820 | .put = stac92xx_mux_enum_put, | ||
2821 | }; | ||
2822 | |||
2823 | static int stac92xx_add_input_source(struct sigmatel_spec *spec) | ||
2824 | { | ||
2825 | struct snd_kcontrol_new *knew; | ||
2826 | struct hda_input_mux *imux = &spec->private_imux; | ||
2827 | |||
2828 | if (!spec->num_adcs || imux->num_items <= 1) | ||
2829 | return 0; /* no need for input source control */ | ||
2830 | knew = stac_control_new(spec, &stac_input_src_temp, | ||
2831 | stac_input_src_temp.name); | ||
2832 | if (!knew) | ||
2833 | return -ENOMEM; | ||
2834 | knew->count = spec->num_adcs; | ||
2835 | return 0; | ||
2836 | } | ||
2837 | |||
2817 | /* check whether the line-input can be used as line-out */ | 2838 | /* check whether the line-input can be used as line-out */ |
2818 | static hda_nid_t check_line_out_switch(struct hda_codec *codec) | 2839 | static hda_nid_t check_line_out_switch(struct hda_codec *codec) |
2819 | { | 2840 | { |
@@ -3699,6 +3720,10 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3699 | return err; | 3720 | return err; |
3700 | } | 3721 | } |
3701 | 3722 | ||
3723 | err = stac92xx_add_input_source(spec); | ||
3724 | if (err < 0) | ||
3725 | return err; | ||
3726 | |||
3702 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 3727 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
3703 | if (spec->multiout.max_channels > 2) | 3728 | if (spec->multiout.max_channels > 2) |
3704 | spec->surr_switch = 1; | 3729 | spec->surr_switch = 1; |
@@ -3812,6 +3837,10 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) | |||
3812 | return err; | 3837 | return err; |
3813 | } | 3838 | } |
3814 | 3839 | ||
3840 | err = stac92xx_add_input_source(spec); | ||
3841 | if (err < 0) | ||
3842 | return err; | ||
3843 | |||
3815 | if (spec->autocfg.dig_out_pin) | 3844 | if (spec->autocfg.dig_out_pin) |
3816 | spec->multiout.dig_out_nid = 0x05; | 3845 | spec->multiout.dig_out_nid = 0x05; |
3817 | if (spec->autocfg.dig_in_pin) | 3846 | if (spec->autocfg.dig_in_pin) |
@@ -5426,7 +5455,6 @@ static struct hda_verb stac9872_core_init[] = { | |||
5426 | static struct snd_kcontrol_new stac9872_mixer[] = { | 5455 | static struct snd_kcontrol_new stac9872_mixer[] = { |
5427 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | 5456 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), |
5428 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | 5457 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), |
5429 | STAC_INPUT_SOURCE(1), | ||
5430 | { } /* end */ | 5458 | { } /* end */ |
5431 | }; | 5459 | }; |
5432 | 5460 | ||