diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 51 |
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 | */ |
1825 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) | 1826 | int 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 | */ |
1840 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout) | 1841 | int 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 | ||