aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_codec.c40
-rw-r--r--sound/pci/hda/hda_codec.h2
-rw-r--r--sound/pci/hda/hda_generic.c20
-rw-r--r--sound/pci/hda/hda_local.h3
-rw-r--r--sound/pci/hda/patch_sigmatel.c2
5 files changed, 52 insertions, 15 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 53e36495fae5..bc3ed249b0fc 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -574,6 +574,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
574 flush_scheduled_work(); 574 flush_scheduled_work();
575#endif 575#endif
576 list_del(&codec->list); 576 list_del(&codec->list);
577 snd_array_free(&codec->mixers);
577 codec->bus->caddr_tbl[codec->addr] = NULL; 578 codec->bus->caddr_tbl[codec->addr] = NULL;
578 if (codec->patch_ops.free) 579 if (codec->patch_ops.free)
579 codec->patch_ops.free(codec); 580 codec->patch_ops.free(codec);
@@ -622,6 +623,7 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
622 mutex_init(&codec->spdif_mutex); 623 mutex_init(&codec->spdif_mutex);
623 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); 624 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
624 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 625 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
626 snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32);
625 627
626#ifdef CONFIG_SND_HDA_POWER_SAVE 628#ifdef CONFIG_SND_HDA_POWER_SAVE
627 INIT_DELAYED_WORK(&codec->power_work, hda_power_work); 629 INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
@@ -1090,6 +1092,32 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1090 return _snd_hda_find_mixer_ctl(codec, name, 0); 1092 return _snd_hda_find_mixer_ctl(codec, name, 0);
1091} 1093}
1092 1094
1095/* Add a control element and assign to the codec */
1096int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl)
1097{
1098 int err;
1099 struct snd_kcontrol **knewp;
1100
1101 err = snd_ctl_add(codec->bus->card, kctl);
1102 if (err < 0)
1103 return err;
1104 knewp = snd_array_new(&codec->mixers);
1105 if (!knewp)
1106 return -ENOMEM;
1107 *knewp = kctl;
1108 return 0;
1109}
1110
1111/* Clear all controls assigned to the given codec */
1112void snd_hda_ctls_clear(struct hda_codec *codec)
1113{
1114 int i;
1115 struct snd_kcontrol **kctls = codec->mixers.list;
1116 for (i = 0; i < codec->mixers.used; i++)
1117 snd_ctl_remove(codec->bus->card, kctls[i]);
1118 snd_array_free(&codec->mixers);
1119}
1120
1093/* create a virtual master control and add slaves */ 1121/* create a virtual master control and add slaves */
1094int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 1122int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1095 unsigned int *tlv, const char **slaves) 1123 unsigned int *tlv, const char **slaves)
@@ -1107,7 +1135,7 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1107 kctl = snd_ctl_make_virtual_master(name, tlv); 1135 kctl = snd_ctl_make_virtual_master(name, tlv);
1108 if (!kctl) 1136 if (!kctl)
1109 return -ENOMEM; 1137 return -ENOMEM;
1110 err = snd_ctl_add(codec->bus->card, kctl); 1138 err = snd_hda_ctl_add(codec, kctl);
1111 if (err < 0) 1139 if (err < 0)
1112 return err; 1140 return err;
1113 1141
@@ -1571,7 +1599,7 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
1571 kctl = snd_ctl_new1(dig_mix, codec); 1599 kctl = snd_ctl_new1(dig_mix, codec);
1572 kctl->id.index = idx; 1600 kctl->id.index = idx;
1573 kctl->private_value = nid; 1601 kctl->private_value = nid;
1574 err = snd_ctl_add(codec->bus->card, kctl); 1602 err = snd_hda_ctl_add(codec, kctl);
1575 if (err < 0) 1603 if (err < 0)
1576 return err; 1604 return err;
1577 } 1605 }
@@ -1615,7 +1643,7 @@ int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
1615 if (!mout->dig_out_nid) 1643 if (!mout->dig_out_nid)
1616 return 0; 1644 return 0;
1617 /* ATTENTION: here mout is passed as private_data, instead of codec */ 1645 /* ATTENTION: here mout is passed as private_data, instead of codec */
1618 return snd_ctl_add(codec->bus->card, 1646 return snd_hda_ctl_add(codec,
1619 snd_ctl_new1(&spdif_share_sw, mout)); 1647 snd_ctl_new1(&spdif_share_sw, mout));
1620} 1648}
1621 1649
@@ -1717,7 +1745,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
1717 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { 1745 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
1718 kctl = snd_ctl_new1(dig_mix, codec); 1746 kctl = snd_ctl_new1(dig_mix, codec);
1719 kctl->private_value = nid; 1747 kctl->private_value = nid;
1720 err = snd_ctl_add(codec->bus->card, kctl); 1748 err = snd_hda_ctl_add(codec, kctl);
1721 if (err < 0) 1749 if (err < 0)
1722 return err; 1750 return err;
1723 } 1751 }
@@ -2440,7 +2468,7 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
2440 kctl = snd_ctl_new1(knew, codec); 2468 kctl = snd_ctl_new1(knew, codec);
2441 if (!kctl) 2469 if (!kctl)
2442 return -ENOMEM; 2470 return -ENOMEM;
2443 err = snd_ctl_add(codec->bus->card, kctl); 2471 err = snd_hda_ctl_add(codec, kctl);
2444 if (err < 0) { 2472 if (err < 0) {
2445 if (!codec->addr) 2473 if (!codec->addr)
2446 return err; 2474 return err;
@@ -2448,7 +2476,7 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
2448 if (!kctl) 2476 if (!kctl)
2449 return -ENOMEM; 2477 return -ENOMEM;
2450 kctl->id.device = codec->addr; 2478 kctl->id.device = codec->addr;
2451 err = snd_ctl_add(codec->bus->card, kctl); 2479 err = snd_hda_ctl_add(codec, kctl);
2452 if (err < 0) 2480 if (err < 0)
2453 return err; 2481 return err;
2454 } 2482 }
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 53f3b08b24cd..8813ec10ca13 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -740,6 +740,8 @@ struct hda_codec {
740 hda_nid_t start_nid; 740 hda_nid_t start_nid;
741 u32 *wcaps; 741 u32 *wcaps;
742 742
743 struct snd_array mixers; /* list of assigned mixer elements */
744
743 struct hda_cache_rec amp_cache; /* cache for amp access */ 745 struct hda_cache_rec amp_cache; /* cache for amp access */
744 struct hda_cache_rec cmd_cache; /* cache for other commands */ 746 struct hda_cache_rec cmd_cache; /* cache for other commands */
745 747
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 0ca30894f7c6..98ff010d5b95 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -723,7 +723,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
723 if (is_loopback) 723 if (is_loopback)
724 add_input_loopback(codec, node->nid, HDA_INPUT, index); 724 add_input_loopback(codec, node->nid, HDA_INPUT, index);
725 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); 725 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
726 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 726 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
727 if (err < 0)
727 return err; 728 return err;
728 created = 1; 729 created = 1;
729 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) && 730 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
@@ -732,7 +733,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
732 if (is_loopback) 733 if (is_loopback)
733 add_input_loopback(codec, node->nid, HDA_OUTPUT, 0); 734 add_input_loopback(codec, node->nid, HDA_OUTPUT, 0);
734 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); 735 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
735 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 736 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
737 if (err < 0)
736 return err; 738 return err;
737 created = 1; 739 created = 1;
738 } 740 }
@@ -745,14 +747,16 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
745 (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) { 747 (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) {
746 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT); 748 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT);
747 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); 749 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
748 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 750 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
751 if (err < 0)
749 return err; 752 return err;
750 created = 1; 753 created = 1;
751 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) && 754 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
752 (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) { 755 (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) {
753 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT); 756 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT);
754 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); 757 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
755 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 758 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
759 if (err < 0)
756 return err; 760 return err;
757 created = 1; 761 created = 1;
758 } 762 }
@@ -849,8 +853,8 @@ static int build_input_controls(struct hda_codec *codec)
849 } 853 }
850 854
851 /* create input MUX if multiple sources are available */ 855 /* create input MUX if multiple sources are available */
852 if ((err = snd_ctl_add(codec->bus->card, 856 err = snd_hda_ctl_add(codec, snd_ctl_new1(&cap_sel, codec));
853 snd_ctl_new1(&cap_sel, codec))) < 0) 857 if (err < 0)
854 return err; 858 return err;
855 859
856 /* no volume control? */ 860 /* no volume control? */
@@ -867,8 +871,8 @@ static int build_input_controls(struct hda_codec *codec)
867 HDA_CODEC_VOLUME(name, adc_node->nid, 871 HDA_CODEC_VOLUME(name, adc_node->nid,
868 spec->input_mux.items[i].index, 872 spec->input_mux.items[i].index,
869 HDA_INPUT); 873 HDA_INPUT);
870 if ((err = snd_ctl_add(codec->bus->card, 874 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
871 snd_ctl_new1(&knew, codec))) < 0) 875 if (err < 0)
872 return err; 876 return err;
873 } 877 }
874 878
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 7957fefda730..48faaf8cd21b 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -393,6 +393,9 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
393int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 393int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
394 unsigned int caps); 394 unsigned int caps);
395 395
396int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl);
397void snd_hda_ctls_clear(struct hda_codec *codec);
398
396/* 399/*
397 * hwdep interface 400 * hwdep interface
398 */ 401 */
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 3db39adad79a..9c67af8e2089 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1250,7 +1250,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1250 } 1250 }
1251 if (spec->num_dmuxes > 0) { 1251 if (spec->num_dmuxes > 0) {
1252 stac_dmux_mixer.count = spec->num_dmuxes; 1252 stac_dmux_mixer.count = spec->num_dmuxes;
1253 err = snd_ctl_add(codec->bus->card, 1253 err = snd_hda_ctl_add(codec,
1254 snd_ctl_new1(&stac_dmux_mixer, codec)); 1254 snd_ctl_new1(&stac_dmux_mixer, codec));
1255 if (err < 0) 1255 if (err < 0)
1256 return err; 1256 return err;