aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 17:25:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-28 17:25:01 -0400
commit68d99b2c8efcb6ed3807a55569300c53b5f88be5 (patch)
treef189c8f2132d3668a2f0e503f5c3f8695b26a1c8 /sound/core
parent0e59e7e7feb5a12938fbf9135147eeda3238c6c4 (diff)
parent8128c9f21509f9a8b6da94ac432d845dda458406 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (549 commits) ALSA: hda - Fix ADC input-amp handling for Cx20549 codec ALSA: hda - Keep EAPD turned on for old Conexant chips ALSA: hda/realtek - Fix missing volume controls with ALC260 ASoC: wm8940: Properly set codec->dapm.bias_level ALSA: hda - Fix pin-config for ASUS W90V ALSA: hda - Fix surround/CLFE headphone and speaker pins order ALSA: hda - Fix typo ALSA: Update the sound git tree URL ALSA: HDA: Add new revision for ALC662 ASoC: max98095: Convert codec->hw_write to snd_soc_write ASoC: keep pointer to resource so it can be freed ASoC: sgtl5000: Fix wrong mask in some snd_soc_update_bits calls ASoC: wm8996: Fix wrong mask for setting WM8996_AIF_CLOCKING_2 ASoC: da7210: Add support for line out and DAC ASoC: da7210: Add support for DAPM ALSA: hda/realtek - Fix DAC assignments of multiple speakers ASoC: Use SGTL5000_LINREG_VDDD_MASK instead of hardcoded mask value ASoC: Set sgtl5000->ldo in ldo_regulator_register ASoC: wm8996: Use SND_SOC_DAPM_AIF_OUT for AIF2 Capture ASoC: wm8994: Use SND_SOC_DAPM_AIF_OUT for AIF3 Capture ...
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/control.c84
-rw-r--r--sound/core/control_compat.c4
-rw-r--r--sound/core/jack.c1
-rw-r--r--sound/core/oss/mixer_oss.c2
-rw-r--r--sound/core/pcm_lib.c26
-rw-r--r--sound/core/pcm_native.c19
6 files changed, 117 insertions, 19 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index f8c5be464510..978fe1a8e9f0 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -989,7 +989,6 @@ struct user_element {
989 void *tlv_data; /* TLV data */ 989 void *tlv_data; /* TLV data */
990 unsigned long tlv_data_size; /* TLV data size */ 990 unsigned long tlv_data_size; /* TLV data size */
991 void *priv_data; /* private data (like strings for enumerated type) */ 991 void *priv_data; /* private data (like strings for enumerated type) */
992 unsigned long priv_data_size; /* size of private data in bytes */
993}; 992};
994 993
995static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol, 994static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
@@ -1001,6 +1000,28 @@ static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
1001 return 0; 1000 return 0;
1002} 1001}
1003 1002
1003static int snd_ctl_elem_user_enum_info(struct snd_kcontrol *kcontrol,
1004 struct snd_ctl_elem_info *uinfo)
1005{
1006 struct user_element *ue = kcontrol->private_data;
1007 const char *names;
1008 unsigned int item;
1009
1010 item = uinfo->value.enumerated.item;
1011
1012 *uinfo = ue->info;
1013
1014 item = min(item, uinfo->value.enumerated.items - 1);
1015 uinfo->value.enumerated.item = item;
1016
1017 names = ue->priv_data;
1018 for (; item > 0; --item)
1019 names += strlen(names) + 1;
1020 strcpy(uinfo->value.enumerated.name, names);
1021
1022 return 0;
1023}
1024
1004static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, 1025static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
1005 struct snd_ctl_elem_value *ucontrol) 1026 struct snd_ctl_elem_value *ucontrol)
1006{ 1027{
@@ -1055,11 +1076,46 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
1055 return change; 1076 return change;
1056} 1077}
1057 1078
1079static int snd_ctl_elem_init_enum_names(struct user_element *ue)
1080{
1081 char *names, *p;
1082 size_t buf_len, name_len;
1083 unsigned int i;
1084
1085 if (ue->info.value.enumerated.names_length > 64 * 1024)
1086 return -EINVAL;
1087
1088 names = memdup_user(
1089 (const void __user *)ue->info.value.enumerated.names_ptr,
1090 ue->info.value.enumerated.names_length);
1091 if (IS_ERR(names))
1092 return PTR_ERR(names);
1093
1094 /* check that there are enough valid names */
1095 buf_len = ue->info.value.enumerated.names_length;
1096 p = names;
1097 for (i = 0; i < ue->info.value.enumerated.items; ++i) {
1098 name_len = strnlen(p, buf_len);
1099 if (name_len == 0 || name_len >= 64 || name_len == buf_len) {
1100 kfree(names);
1101 return -EINVAL;
1102 }
1103 p += name_len + 1;
1104 buf_len -= name_len + 1;
1105 }
1106
1107 ue->priv_data = names;
1108 ue->info.value.enumerated.names_ptr = 0;
1109
1110 return 0;
1111}
1112
1058static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol) 1113static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol)
1059{ 1114{
1060 struct user_element *ue = kcontrol->private_data; 1115 struct user_element *ue = kcontrol->private_data;
1061 if (ue->tlv_data) 1116
1062 kfree(ue->tlv_data); 1117 kfree(ue->tlv_data);
1118 kfree(ue->priv_data);
1063 kfree(ue); 1119 kfree(ue);
1064} 1120}
1065 1121
@@ -1072,8 +1128,8 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
1072 long private_size; 1128 long private_size;
1073 struct user_element *ue; 1129 struct user_element *ue;
1074 int idx, err; 1130 int idx, err;
1075 1131
1076 if (card->user_ctl_count >= MAX_USER_CONTROLS) 1132 if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
1077 return -ENOMEM; 1133 return -ENOMEM;
1078 if (info->count < 1) 1134 if (info->count < 1)
1079 return -EINVAL; 1135 return -EINVAL;
@@ -1101,7 +1157,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
1101 memcpy(&kctl.id, &info->id, sizeof(info->id)); 1157 memcpy(&kctl.id, &info->id, sizeof(info->id));
1102 kctl.count = info->owner ? info->owner : 1; 1158 kctl.count = info->owner ? info->owner : 1;
1103 access |= SNDRV_CTL_ELEM_ACCESS_USER; 1159 access |= SNDRV_CTL_ELEM_ACCESS_USER;
1104 kctl.info = snd_ctl_elem_user_info; 1160 if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED)
1161 kctl.info = snd_ctl_elem_user_enum_info;
1162 else
1163 kctl.info = snd_ctl_elem_user_info;
1105 if (access & SNDRV_CTL_ELEM_ACCESS_READ) 1164 if (access & SNDRV_CTL_ELEM_ACCESS_READ)
1106 kctl.get = snd_ctl_elem_user_get; 1165 kctl.get = snd_ctl_elem_user_get;
1107 if (access & SNDRV_CTL_ELEM_ACCESS_WRITE) 1166 if (access & SNDRV_CTL_ELEM_ACCESS_WRITE)
@@ -1122,6 +1181,11 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
1122 if (info->count > 64) 1181 if (info->count > 64)
1123 return -EINVAL; 1182 return -EINVAL;
1124 break; 1183 break;
1184 case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
1185 private_size = sizeof(unsigned int);
1186 if (info->count > 128 || info->value.enumerated.items == 0)
1187 return -EINVAL;
1188 break;
1125 case SNDRV_CTL_ELEM_TYPE_BYTES: 1189 case SNDRV_CTL_ELEM_TYPE_BYTES:
1126 private_size = sizeof(unsigned char); 1190 private_size = sizeof(unsigned char);
1127 if (info->count > 512) 1191 if (info->count > 512)
@@ -1143,9 +1207,17 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
1143 ue->info.access = 0; 1207 ue->info.access = 0;
1144 ue->elem_data = (char *)ue + sizeof(*ue); 1208 ue->elem_data = (char *)ue + sizeof(*ue);
1145 ue->elem_data_size = private_size; 1209 ue->elem_data_size = private_size;
1210 if (ue->info.type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
1211 err = snd_ctl_elem_init_enum_names(ue);
1212 if (err < 0) {
1213 kfree(ue);
1214 return err;
1215 }
1216 }
1146 kctl.private_free = snd_ctl_elem_user_free; 1217 kctl.private_free = snd_ctl_elem_user_free;
1147 _kctl = snd_ctl_new(&kctl, access); 1218 _kctl = snd_ctl_new(&kctl, access);
1148 if (_kctl == NULL) { 1219 if (_kctl == NULL) {
1220 kfree(ue->priv_data);
1149 kfree(ue); 1221 kfree(ue);
1150 return -ENOMEM; 1222 return -ENOMEM;
1151 } 1223 }
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 426874429a5e..2bb95a7a8809 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -83,6 +83,8 @@ struct snd_ctl_elem_info32 {
83 u32 items; 83 u32 items;
84 u32 item; 84 u32 item;
85 char name[64]; 85 char name[64];
86 u64 names_ptr;
87 u32 names_length;
86 } enumerated; 88 } enumerated;
87 unsigned char reserved[128]; 89 unsigned char reserved[128];
88 } value; 90 } value;
@@ -372,6 +374,8 @@ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
372 &data32->value.enumerated, 374 &data32->value.enumerated,
373 sizeof(data->value.enumerated))) 375 sizeof(data->value.enumerated)))
374 goto error; 376 goto error;
377 data->value.enumerated.names_ptr =
378 (uintptr_t)compat_ptr(data->value.enumerated.names_ptr);
375 break; 379 break;
376 default: 380 default:
377 break; 381 break;
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 53b53e97c896..240a3e13470d 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -30,6 +30,7 @@ static int jack_switch_types[] = {
30 SW_LINEOUT_INSERT, 30 SW_LINEOUT_INSERT,
31 SW_JACK_PHYSICAL_INSERT, 31 SW_JACK_PHYSICAL_INSERT,
32 SW_VIDEOOUT_INSERT, 32 SW_VIDEOOUT_INSERT,
33 SW_LINEIN_INSERT,
33}; 34};
34 35
35static int snd_jack_dev_free(struct snd_device *device) 36static int snd_jack_dev_free(struct snd_device *device)
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index d8359cfeca15..1b5e0c49a0ad 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -499,7 +499,7 @@ static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, c
499 499
500 memset(&id, 0, sizeof(id)); 500 memset(&id, 0, sizeof(id));
501 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 501 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
502 strcpy(id.name, name); 502 strlcpy(id.name, name, sizeof(id.name));
503 id.index = index; 503 id.index = index;
504 return snd_ctl_find_id(card, &id); 504 return snd_ctl_find_id(card, &id);
505} 505}
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 62e90b862a0d..95d1e789715f 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1399,6 +1399,32 @@ int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
1399 1399
1400EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2); 1400EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
1401 1401
1402static int snd_pcm_hw_rule_noresample_func(struct snd_pcm_hw_params *params,
1403 struct snd_pcm_hw_rule *rule)
1404{
1405 unsigned int base_rate = (unsigned int)(uintptr_t)rule->private;
1406 struct snd_interval *rate;
1407
1408 rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1409 return snd_interval_list(rate, 1, &base_rate, 0);
1410}
1411
1412/**
1413 * snd_pcm_hw_rule_noresample - add a rule to allow disabling hw resampling
1414 * @runtime: PCM runtime instance
1415 * @base_rate: the rate at which the hardware does not resample
1416 */
1417int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime,
1418 unsigned int base_rate)
1419{
1420 return snd_pcm_hw_rule_add(runtime, SNDRV_PCM_HW_PARAMS_NORESAMPLE,
1421 SNDRV_PCM_HW_PARAM_RATE,
1422 snd_pcm_hw_rule_noresample_func,
1423 (void *)(uintptr_t)base_rate,
1424 SNDRV_PCM_HW_PARAM_RATE, -1);
1425}
1426EXPORT_SYMBOL(snd_pcm_hw_rule_noresample);
1427
1402static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params, 1428static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
1403 snd_pcm_hw_param_t var) 1429 snd_pcm_hw_param_t var)
1404{ 1430{
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index c74e228731ed..d7d2179c0363 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2058,16 +2058,12 @@ EXPORT_SYMBOL(snd_pcm_open_substream);
2058 2058
2059static int snd_pcm_open_file(struct file *file, 2059static int snd_pcm_open_file(struct file *file,
2060 struct snd_pcm *pcm, 2060 struct snd_pcm *pcm,
2061 int stream, 2061 int stream)
2062 struct snd_pcm_file **rpcm_file)
2063{ 2062{
2064 struct snd_pcm_file *pcm_file; 2063 struct snd_pcm_file *pcm_file;
2065 struct snd_pcm_substream *substream; 2064 struct snd_pcm_substream *substream;
2066 int err; 2065 int err;
2067 2066
2068 if (rpcm_file)
2069 *rpcm_file = NULL;
2070
2071 err = snd_pcm_open_substream(pcm, stream, file, &substream); 2067 err = snd_pcm_open_substream(pcm, stream, file, &substream);
2072 if (err < 0) 2068 if (err < 0)
2073 return err; 2069 return err;
@@ -2083,8 +2079,7 @@ static int snd_pcm_open_file(struct file *file,
2083 substream->pcm_release = pcm_release_private; 2079 substream->pcm_release = pcm_release_private;
2084 } 2080 }
2085 file->private_data = pcm_file; 2081 file->private_data = pcm_file;
2086 if (rpcm_file) 2082
2087 *rpcm_file = pcm_file;
2088 return 0; 2083 return 0;
2089} 2084}
2090 2085
@@ -2113,7 +2108,6 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file)
2113static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) 2108static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
2114{ 2109{
2115 int err; 2110 int err;
2116 struct snd_pcm_file *pcm_file;
2117 wait_queue_t wait; 2111 wait_queue_t wait;
2118 2112
2119 if (pcm == NULL) { 2113 if (pcm == NULL) {
@@ -2131,7 +2125,7 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
2131 add_wait_queue(&pcm->open_wait, &wait); 2125 add_wait_queue(&pcm->open_wait, &wait);
2132 mutex_lock(&pcm->open_mutex); 2126 mutex_lock(&pcm->open_mutex);
2133 while (1) { 2127 while (1) {
2134 err = snd_pcm_open_file(file, pcm, stream, &pcm_file); 2128 err = snd_pcm_open_file(file, pcm, stream);
2135 if (err >= 0) 2129 if (err >= 0)
2136 break; 2130 break;
2137 if (err == -EAGAIN) { 2131 if (err == -EAGAIN) {
@@ -3156,8 +3150,8 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
3156/* 3150/*
3157 * mmap the DMA buffer on RAM 3151 * mmap the DMA buffer on RAM
3158 */ 3152 */
3159static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, 3153int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
3160 struct vm_area_struct *area) 3154 struct vm_area_struct *area)
3161{ 3155{
3162 area->vm_flags |= VM_RESERVED; 3156 area->vm_flags |= VM_RESERVED;
3163#ifdef ARCH_HAS_DMA_MMAP_COHERENT 3157#ifdef ARCH_HAS_DMA_MMAP_COHERENT
@@ -3177,6 +3171,7 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3177 area->vm_ops = &snd_pcm_vm_ops_data_fault; 3171 area->vm_ops = &snd_pcm_vm_ops_data_fault;
3178 return 0; 3172 return 0;
3179} 3173}
3174EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap);
3180 3175
3181/* 3176/*
3182 * mmap the DMA buffer on I/O memory area 3177 * mmap the DMA buffer on I/O memory area
@@ -3242,7 +3237,7 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3242 if (substream->ops->mmap) 3237 if (substream->ops->mmap)
3243 err = substream->ops->mmap(substream, area); 3238 err = substream->ops->mmap(substream, area);
3244 else 3239 else
3245 err = snd_pcm_default_mmap(substream, area); 3240 err = snd_pcm_lib_default_mmap(substream, area);
3246 if (!err) 3241 if (!err)
3247 atomic_inc(&substream->mmap_count); 3242 atomic_inc(&substream->mmap_count);
3248 return err; 3243 return err;