aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorMatthew Ranostay <mranostay@embeddedalley.com>2008-09-07 06:03:41 -0400
committerJaroslav Kysela <perex@perex.cz>2008-09-09 03:11:41 -0400
commitd9737751eb7f2f3f6e973834ea9f215e855d46ea (patch)
treef05edb13c14d0f56c77e6b750acd8ecc13a46ac0 /sound/pci
parentf14d8e975054ae186eba229485a213dfcc7a25da (diff)
ALSA: hda: SPDIF mux controls
Dynamically create mux controls for SPDIF outs on certain IDT/Sigmatel codecs. 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/patch_sigmatel.c114
1 files changed, 112 insertions, 2 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index c72c748322a1..8ff7b95c34e5 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -173,6 +173,9 @@ struct sigmatel_spec {
173 unsigned int num_dmics; 173 unsigned int num_dmics;
174 hda_nid_t *dmux_nids; 174 hda_nid_t *dmux_nids;
175 unsigned int num_dmuxes; 175 unsigned int num_dmuxes;
176 hda_nid_t *smux_nids;
177 unsigned int num_smuxes;
178
176 hda_nid_t dig_in_nid; 179 hda_nid_t dig_in_nid;
177 hda_nid_t mono_nid; 180 hda_nid_t mono_nid;
178 hda_nid_t anabeep_nid; 181 hda_nid_t anabeep_nid;
@@ -193,6 +196,8 @@ struct sigmatel_spec {
193 unsigned int cur_dmux[2]; 196 unsigned int cur_dmux[2];
194 struct hda_input_mux *input_mux; 197 struct hda_input_mux *input_mux;
195 unsigned int cur_mux[3]; 198 unsigned int cur_mux[3];
199 struct hda_input_mux *sinput_mux;
200 unsigned int cur_smux[2];
196 unsigned int powerdown_adcs; 201 unsigned int powerdown_adcs;
197 202
198 /* i/o switches */ 203 /* i/o switches */
@@ -209,6 +214,7 @@ struct sigmatel_spec {
209 struct snd_kcontrol_new *kctl_alloc; 214 struct snd_kcontrol_new *kctl_alloc;
210 struct hda_input_mux private_dimux; 215 struct hda_input_mux private_dimux;
211 struct hda_input_mux private_imux; 216 struct hda_input_mux private_imux;
217 struct hda_input_mux private_smux;
212 struct hda_input_mux private_mono_mux; 218 struct hda_input_mux private_mono_mux;
213}; 219};
214 220
@@ -251,6 +257,10 @@ static hda_nid_t stac92hd73xx_dmux_nids[2] = {
251 0x20, 0x21, 257 0x20, 0x21,
252}; 258};
253 259
260static hda_nid_t stac92hd73xx_smux_nids[2] = {
261 0x22, 0x23,
262};
263
254#define STAC92HD83XXX_NUM_DMICS 2 264#define STAC92HD83XXX_NUM_DMICS 2
255static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { 265static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
256 0x11, 0x12, 0 266 0x11, 0x12, 0
@@ -294,6 +304,10 @@ static hda_nid_t stac92hd71bxx_dmux_nids[1] = {
294 0x1c, 304 0x1c,
295}; 305};
296 306
307static hda_nid_t stac92hd71bxx_smux_nids[2] = {
308 0x24, 0x25,
309};
310
297static hda_nid_t stac92hd71bxx_dac_nids[1] = { 311static hda_nid_t stac92hd71bxx_dac_nids[1] = {
298 0x10, /*0x11, */ 312 0x10, /*0x11, */
299}; 313};
@@ -340,6 +354,10 @@ static hda_nid_t stac927x_mux_nids[3] = {
340 0x15, 0x16, 0x17 354 0x15, 0x16, 0x17
341}; 355};
342 356
357static hda_nid_t stac927x_smux_nids[1] = {
358 0x21,
359};
360
343static hda_nid_t stac927x_dac_nids[6] = { 361static hda_nid_t stac927x_dac_nids[6] = {
344 0x02, 0x03, 0x04, 0x05, 0x06, 0 362 0x02, 0x03, 0x04, 0x05, 0x06, 0
345}; 363};
@@ -365,6 +383,10 @@ static hda_nid_t stac9205_dmux_nids[1] = {
365 0x1d, 383 0x1d,
366}; 384};
367 385
386static hda_nid_t stac9205_smux_nids[1] = {
387 0x21,
388};
389
368#define STAC9205_NUM_DMICS 2 390#define STAC9205_NUM_DMICS 2
369static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { 391static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
370 0x17, 0x18, 0 392 0x17, 0x18, 0
@@ -388,7 +410,7 @@ static hda_nid_t stac922x_pin_nids[10] = {
388static hda_nid_t stac92hd73xx_pin_nids[13] = { 410static hda_nid_t stac92hd73xx_pin_nids[13] = {
389 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 411 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
390 0x0f, 0x10, 0x11, 0x12, 0x13, 412 0x0f, 0x10, 0x11, 0x12, 0x13,
391 0x14, 0x1e, 0x22 413 0x14, 0x22, 0x23
392}; 414};
393 415
394static hda_nid_t stac92hd83xxx_pin_nids[14] = { 416static hda_nid_t stac92hd83xxx_pin_nids[14] = {
@@ -443,6 +465,36 @@ static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
443 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]); 465 spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]);
444} 466}
445 467
468static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol,
469 struct snd_ctl_elem_info *uinfo)
470{
471 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
472 struct sigmatel_spec *spec = codec->spec;
473 return snd_hda_input_mux_info(spec->sinput_mux, uinfo);
474}
475
476static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol,
477 struct snd_ctl_elem_value *ucontrol)
478{
479 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
480 struct sigmatel_spec *spec = codec->spec;
481 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
482
483 ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx];
484 return 0;
485}
486
487static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
488 struct snd_ctl_elem_value *ucontrol)
489{
490 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
491 struct sigmatel_spec *spec = codec->spec;
492 unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
493
494 return snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol,
495 spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]);
496}
497
446static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 498static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
447{ 499{
448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 500 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -993,6 +1045,15 @@ static struct snd_kcontrol_new stac_dmux_mixer = {
993 .put = stac92xx_dmux_enum_put, 1045 .put = stac92xx_dmux_enum_put,
994}; 1046};
995 1047
1048static struct snd_kcontrol_new stac_smux_mixer = {
1049 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1050 .name = "IEC958 Mux",
1051 /* count set later */
1052 .info = stac92xx_smux_enum_info,
1053 .get = stac92xx_smux_enum_get,
1054 .put = stac92xx_smux_enum_put,
1055};
1056
996static const char *slave_vols[] = { 1057static const char *slave_vols[] = {
997 "Front Playback Volume", 1058 "Front Playback Volume",
998 "Surround Playback Volume", 1059 "Surround Playback Volume",
@@ -1044,6 +1105,13 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1044 if (err < 0) 1105 if (err < 0)
1045 return err; 1106 return err;
1046 } 1107 }
1108 if (spec->num_smuxes > 0) {
1109 stac_smux_mixer.count = spec->num_smuxes;
1110 err = snd_ctl_add(codec->bus->card,
1111 snd_ctl_new1(&stac_smux_mixer, codec));
1112 if (err < 0)
1113 return err;
1114 }
1047 1115
1048 if (spec->multiout.dig_out_nid) { 1116 if (spec->multiout.dig_out_nid) {
1049 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 1117 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
@@ -2811,6 +2879,34 @@ static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
2811 return 0; 2879 return 0;
2812}; 2880};
2813 2881
2882static const char *stac92xx_spdif_labels[3] = {
2883 "Digital Playback", "Analog Mux 1", "Analog Mux 2"
2884};
2885
2886static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
2887{
2888 struct sigmatel_spec *spec = codec->spec;
2889 struct hda_input_mux *spdif_mux = &spec->private_smux;
2890 int i, num_cons;
2891 hda_nid_t con_lst[ARRAY_SIZE(stac92xx_spdif_labels)];
2892
2893 num_cons = snd_hda_get_connections(codec,
2894 spec->smux_nids[0],
2895 con_lst,
2896 HDA_MAX_NUM_INPUTS);
2897 if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_spdif_labels))
2898 return -EINVAL;
2899
2900 for (i = 0; i < num_cons; i++) {
2901 spdif_mux->items[spdif_mux->num_items].label =
2902 stac92xx_spdif_labels[i];
2903 spdif_mux->items[spdif_mux->num_items].index = i;
2904 spdif_mux->num_items++;
2905 }
2906
2907 return 0;
2908}
2909
2814/* labels for dmic mux inputs */ 2910/* labels for dmic mux inputs */
2815static const char *stac92xx_dmic_labels[5] = { 2911static const char *stac92xx_dmic_labels[5] = {
2816 "Analog Inputs", "Digital Mic 1", "Digital Mic 2", 2912 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
@@ -3114,6 +3210,11 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3114 if (err < 0) 3210 if (err < 0)
3115 return err; 3211 return err;
3116 } 3212 }
3213 if (spec->num_smuxes > 0) {
3214 err = stac92xx_auto_create_spdif_mux_ctls(codec);
3215 if (err < 0)
3216 return err;
3217 }
3117 3218
3118 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3219 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3119 if (spec->multiout.max_channels > 2) 3220 if (spec->multiout.max_channels > 2)
@@ -3130,6 +3231,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3130 spec->input_mux = &spec->private_imux; 3231 spec->input_mux = &spec->private_imux;
3131 if (!spec->dinput_mux) 3232 if (!spec->dinput_mux)
3132 spec->dinput_mux = &spec->private_dimux; 3233 spec->dinput_mux = &spec->private_dimux;
3234 spec->sinput_mux = &spec->private_smux;
3133 spec->mono_mux = &spec->private_mono_mux; 3235 spec->mono_mux = &spec->private_mono_mux;
3134 3236
3135 return 1; 3237 return 1;
@@ -3800,10 +3902,12 @@ again:
3800 spec->adc_nids = stac92hd73xx_adc_nids; 3902 spec->adc_nids = stac92hd73xx_adc_nids;
3801 spec->dmic_nids = stac92hd73xx_dmic_nids; 3903 spec->dmic_nids = stac92hd73xx_dmic_nids;
3802 spec->dmux_nids = stac92hd73xx_dmux_nids; 3904 spec->dmux_nids = stac92hd73xx_dmux_nids;
3905 spec->smux_nids = stac92hd73xx_smux_nids;
3803 3906
3804 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); 3907 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
3805 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); 3908 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
3806 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); 3909 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
3910 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
3807 spec->dinput_mux = &stac92hd73xx_dmux; 3911 spec->dinput_mux = &stac92hd73xx_dmux;
3808 /* GPIO0 High = Enable EAPD */ 3912 /* GPIO0 High = Enable EAPD */
3809 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; 3913 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
@@ -3842,7 +3946,7 @@ again:
3842 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); 3946 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
3843 spec->pwr_nids = stac92hd73xx_pwr_nids; 3947 spec->pwr_nids = stac92hd73xx_pwr_nids;
3844 3948
3845 err = stac92xx_parse_auto_config(codec, 0x22, 0x24); 3949 err = stac92xx_parse_auto_config(codec, 0x25, 0x27);
3846 3950
3847 if (!err) { 3951 if (!err) {
3848 if (spec->board_config < 0) { 3952 if (spec->board_config < 0) {
@@ -4081,11 +4185,13 @@ again:
4081 spec->adc_nids = stac92hd71bxx_adc_nids; 4185 spec->adc_nids = stac92hd71bxx_adc_nids;
4082 spec->dmic_nids = stac92hd71bxx_dmic_nids; 4186 spec->dmic_nids = stac92hd71bxx_dmic_nids;
4083 spec->dmux_nids = stac92hd71bxx_dmux_nids; 4187 spec->dmux_nids = stac92hd71bxx_dmux_nids;
4188 spec->smux_nids = stac92hd71bxx_smux_nids;
4084 spec->pwr_nids = stac92hd71bxx_pwr_nids; 4189 spec->pwr_nids = stac92hd71bxx_pwr_nids;
4085 4190
4086 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); 4191 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
4087 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); 4192 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
4088 spec->num_dmics = STAC92HD71BXX_NUM_DMICS; 4193 spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
4194 spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids);
4089 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); 4195 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
4090 4196
4091 spec->multiout.num_dacs = 1; 4197 spec->multiout.num_dacs = 1;
@@ -4254,6 +4360,8 @@ static int patch_stac927x(struct hda_codec *codec)
4254 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); 4360 spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
4255 spec->mux_nids = stac927x_mux_nids; 4361 spec->mux_nids = stac927x_mux_nids;
4256 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); 4362 spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
4363 spec->smux_nids = stac927x_smux_nids;
4364 spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids);
4257 spec->dac_list = stac927x_dac_nids; 4365 spec->dac_list = stac927x_dac_nids;
4258 spec->multiout.dac_nids = spec->dac_nids; 4366 spec->multiout.dac_nids = spec->dac_nids;
4259 4367
@@ -4375,6 +4483,8 @@ static int patch_stac9205(struct hda_codec *codec)
4375 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids); 4483 spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
4376 spec->mux_nids = stac9205_mux_nids; 4484 spec->mux_nids = stac9205_mux_nids;
4377 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); 4485 spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
4486 spec->smux_nids = stac9205_smux_nids;
4487 spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids);
4378 spec->dmic_nids = stac9205_dmic_nids; 4488 spec->dmic_nids = stac9205_dmic_nids;
4379 spec->num_dmics = STAC9205_NUM_DMICS; 4489 spec->num_dmics = STAC9205_NUM_DMICS;
4380 spec->dmux_nids = stac9205_dmux_nids; 4490 spec->dmux_nids = stac9205_dmux_nids;