aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c51
1 files changed, 26 insertions, 25 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 4a6dd97deba6..208a3341ec20 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -25,6 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/pci.h> 26#include <linux/pci.h>
27#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
28#include <linux/mutex.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include "hda_codec.h" 30#include "hda_codec.h"
30#include <sound/asoundef.h> 31#include <sound/asoundef.h>
@@ -76,12 +77,12 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire
76 unsigned int verb, unsigned int parm) 77 unsigned int verb, unsigned int parm)
77{ 78{
78 unsigned int res; 79 unsigned int res;
79 down(&codec->bus->cmd_mutex); 80 mutex_lock(&codec->bus->cmd_mutex);
80 if (! codec->bus->ops.command(codec, nid, direct, verb, parm)) 81 if (! codec->bus->ops.command(codec, nid, direct, verb, parm))
81 res = codec->bus->ops.get_response(codec); 82 res = codec->bus->ops.get_response(codec);
82 else 83 else
83 res = (unsigned int)-1; 84 res = (unsigned int)-1;
84 up(&codec->bus->cmd_mutex); 85 mutex_unlock(&codec->bus->cmd_mutex);
85 return res; 86 return res;
86} 87}
87 88
@@ -101,9 +102,9 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
101 unsigned int verb, unsigned int parm) 102 unsigned int verb, unsigned int parm)
102{ 103{
103 int err; 104 int err;
104 down(&codec->bus->cmd_mutex); 105 mutex_lock(&codec->bus->cmd_mutex);
105 err = codec->bus->ops.command(codec, nid, direct, verb, parm); 106 err = codec->bus->ops.command(codec, nid, direct, verb, parm);
106 up(&codec->bus->cmd_mutex); 107 mutex_unlock(&codec->bus->cmd_mutex);
107 return err; 108 return err;
108} 109}
109 110
@@ -371,7 +372,7 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
371 bus->modelname = temp->modelname; 372 bus->modelname = temp->modelname;
372 bus->ops = temp->ops; 373 bus->ops = temp->ops;
373 374
374 init_MUTEX(&bus->cmd_mutex); 375 mutex_init(&bus->cmd_mutex);
375 INIT_LIST_HEAD(&bus->codec_list); 376 INIT_LIST_HEAD(&bus->codec_list);
376 377
377 if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) { 378 if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {
@@ -523,7 +524,7 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
523 524
524 codec->bus = bus; 525 codec->bus = bus;
525 codec->addr = codec_addr; 526 codec->addr = codec_addr;
526 init_MUTEX(&codec->spdif_mutex); 527 mutex_init(&codec->spdif_mutex);
527 init_amp_hash(codec); 528 init_amp_hash(codec);
528 529
529 list_add_tail(&codec->list, &bus->codec_list); 530 list_add_tail(&codec->list, &bus->codec_list);
@@ -881,12 +882,12 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_
881 unsigned long pval; 882 unsigned long pval;
882 int err; 883 int err;
883 884
884 down(&codec->spdif_mutex); /* reuse spdif_mutex */ 885 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
885 pval = kcontrol->private_value; 886 pval = kcontrol->private_value;
886 kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ 887 kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
887 err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); 888 err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
888 kcontrol->private_value = pval; 889 kcontrol->private_value = pval;
889 up(&codec->spdif_mutex); 890 mutex_unlock(&codec->spdif_mutex);
890 return err; 891 return err;
891} 892}
892 893
@@ -896,7 +897,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
896 unsigned long pval; 897 unsigned long pval;
897 int i, indices, err = 0, change = 0; 898 int i, indices, err = 0, change = 0;
898 899
899 down(&codec->spdif_mutex); /* reuse spdif_mutex */ 900 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
900 pval = kcontrol->private_value; 901 pval = kcontrol->private_value;
901 indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; 902 indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
902 for (i = 0; i < indices; i++) { 903 for (i = 0; i < indices; i++) {
@@ -907,7 +908,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
907 change |= err; 908 change |= err;
908 } 909 }
909 kcontrol->private_value = pval; 910 kcontrol->private_value = pval;
910 up(&codec->spdif_mutex); 911 mutex_unlock(&codec->spdif_mutex);
911 return err < 0 ? err : change; 912 return err < 0 ? err : change;
912} 913}
913 914
@@ -1011,7 +1012,7 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c
1011 unsigned short val; 1012 unsigned short val;
1012 int change; 1013 int change;
1013 1014
1014 down(&codec->spdif_mutex); 1015 mutex_lock(&codec->spdif_mutex);
1015 codec->spdif_status = ucontrol->value.iec958.status[0] | 1016 codec->spdif_status = ucontrol->value.iec958.status[0] |
1016 ((unsigned int)ucontrol->value.iec958.status[1] << 8) | 1017 ((unsigned int)ucontrol->value.iec958.status[1] << 8) |
1017 ((unsigned int)ucontrol->value.iec958.status[2] << 16) | 1018 ((unsigned int)ucontrol->value.iec958.status[2] << 16) |
@@ -1026,7 +1027,7 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c
1026 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); 1027 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8);
1027 } 1028 }
1028 1029
1029 up(&codec->spdif_mutex); 1030 mutex_unlock(&codec->spdif_mutex);
1030 return change; 1031 return change;
1031} 1032}
1032 1033
@@ -1054,7 +1055,7 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn
1054 unsigned short val; 1055 unsigned short val;
1055 int change; 1056 int change;
1056 1057
1057 down(&codec->spdif_mutex); 1058 mutex_lock(&codec->spdif_mutex);
1058 val = codec->spdif_ctls & ~1; 1059 val = codec->spdif_ctls & ~1;
1059 if (ucontrol->value.integer.value[0]) 1060 if (ucontrol->value.integer.value[0])
1060 val |= 1; 1061 val |= 1;
@@ -1066,7 +1067,7 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn
1066 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | 1067 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
1067 AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80)); 1068 AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80));
1068 } 1069 }
1069 up(&codec->spdif_mutex); 1070 mutex_unlock(&codec->spdif_mutex);
1070 return change; 1071 return change;
1071} 1072}
1072 1073
@@ -1150,13 +1151,13 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd
1150 unsigned int val = !!ucontrol->value.integer.value[0]; 1151 unsigned int val = !!ucontrol->value.integer.value[0];
1151 int change; 1152 int change;
1152 1153
1153 down(&codec->spdif_mutex); 1154 mutex_lock(&codec->spdif_mutex);
1154 change = codec->spdif_in_enable != val; 1155 change = codec->spdif_in_enable != val;
1155 if (change || codec->in_resume) { 1156 if (change || codec->in_resume) {
1156 codec->spdif_in_enable = val; 1157 codec->spdif_in_enable = val;
1157 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); 1158 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val);
1158 } 1159 }
1159 up(&codec->spdif_mutex); 1160 mutex_unlock(&codec->spdif_mutex);
1160 return change; 1161 return change;
1161} 1162}
1162 1163
@@ -1824,13 +1825,13 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i
1824 */ 1825 */
1825int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) 1826int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout)
1826{ 1827{
1827 down(&codec->spdif_mutex); 1828 mutex_lock(&codec->spdif_mutex);
1828 if (mout->dig_out_used) { 1829 if (mout->dig_out_used) {
1829 up(&codec->spdif_mutex); 1830 mutex_unlock(&codec->spdif_mutex);
1830 return -EBUSY; /* already being used */ 1831 return -EBUSY; /* already being used */
1831 } 1832 }
1832 mout->dig_out_used = HDA_DIG_EXCLUSIVE; 1833 mout->dig_out_used = HDA_DIG_EXCLUSIVE;
1833 up(&codec->spdif_mutex); 1834 mutex_unlock(&codec->spdif_mutex);
1834 return 0; 1835 return 0;
1835} 1836}
1836 1837
@@ -1839,9 +1840,9 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mo
1839 */ 1840 */
1840int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout) 1841int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout)
1841{ 1842{
1842 down(&codec->spdif_mutex); 1843 mutex_lock(&codec->spdif_mutex);
1843 mout->dig_out_used = 0; 1844 mout->dig_out_used = 0;
1844 up(&codec->spdif_mutex); 1845 mutex_unlock(&codec->spdif_mutex);
1845 return 0; 1846 return 0;
1846} 1847}
1847 1848
@@ -1869,7 +1870,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
1869 int chs = substream->runtime->channels; 1870 int chs = substream->runtime->channels;
1870 int i; 1871 int i;
1871 1872
1872 down(&codec->spdif_mutex); 1873 mutex_lock(&codec->spdif_mutex);
1873 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { 1874 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
1874 if (chs == 2 && 1875 if (chs == 2 &&
1875 snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && 1876 snd_hda_is_supported_format(codec, mout->dig_out_nid, format) &&
@@ -1883,7 +1884,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
1883 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); 1884 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
1884 } 1885 }
1885 } 1886 }
1886 up(&codec->spdif_mutex); 1887 mutex_unlock(&codec->spdif_mutex);
1887 1888
1888 /* front */ 1889 /* front */
1889 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); 1890 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format);
@@ -1914,12 +1915,12 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o
1914 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); 1915 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
1915 if (mout->hp_nid) 1916 if (mout->hp_nid)
1916 snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0); 1917 snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0);
1917 down(&codec->spdif_mutex); 1918 mutex_lock(&codec->spdif_mutex);
1918 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) { 1919 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
1919 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); 1920 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
1920 mout->dig_out_used = 0; 1921 mout->dig_out_used = 0;
1921 } 1922 }
1922 up(&codec->spdif_mutex); 1923 mutex_unlock(&codec->spdif_mutex);
1923 return 0; 1924 return 0;
1924} 1925}
1925 1926