aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-01-23 05:57:22 -0500
committerTakashi Iwai <tiwai@suse.de>2009-01-23 05:57:22 -0500
commite3c75964666a27cec46d2cccf2d9806336becd48 (patch)
tree5b961f9f0aa389b5e17464c77e597cee033f4153 /sound/pci/hda/patch_sigmatel.c
parent028b9445b4b10fa8da61ba7cf14ff72cc877ef41 (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.c78
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[] = {
982static struct snd_kcontrol_new stac9200_mixer[] = { 972static 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
1100static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { 1089static 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
1129static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { 1117static 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[] = {
1141static struct snd_kcontrol_new stac925x_mixer[] = { 1128static 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
1150static struct snd_kcontrol_new stac9205_mixer[] = { 1136static 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 */
1163static struct snd_kcontrol_new stac922x_mixer[] = { 1148static 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
1174static struct snd_kcontrol_new stac927x_mixer[] = { 1158static 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 */
2780static int stac92xx_add_control_temp(struct sigmatel_spec *spec, 2763static struct snd_kcontrol_new *
2781 struct snd_kcontrol_new *ktemp, 2764stac_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
2785static 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
2815static 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
2823static 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 */
2818static hda_nid_t check_line_out_switch(struct hda_codec *codec) 2839static 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[] = {
5426static struct snd_kcontrol_new stac9872_mixer[] = { 5455static 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