aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-02-05 15:34:44 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-02-05 15:34:44 -0500
commitea5a273c76f8ba3569705362b00c7d94fb92468e (patch)
treebee0d42010f66a2deb9d7a724cf8f9f8207731c0
parented1741b77c162ad7087949fda39af4ec8c33e663 (diff)
parent094fd3be87b0f102589e2d5c3fa5d06b7e20496d (diff)
Merge tag 'sound-4.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "This was a busy week and I had to prepare a pile of duct tapes for the bugs reported by syzkaller fuzzer in wide range of ALSA core APIs: timer, rawmidi, sequencer, and PCM OSS emulation. Let's see how many other holes we need to plug. Besides that, a few usual boring stuff, HD- and USB-audio quirks, have been added" * tag 'sound-4.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: timer: Fix leftover link at closing ALSA: seq: Fix lockdep warnings due to double mutex locks ALSA: rawmidi: Fix race at copying & updating the position ALSA: rawmidi: Make snd_rawmidi_transmit() race-free ALSA: hda - Add fixup for Mac Mini 7,1 model ALSA: hda/realtek - Support headset mode for ALC225 ALSA: hda/realtek - Support Dell headset mode for ALC225 ALSA: hda/realtek - New codec support of ALC225 ALSA: timer: Sync timer deletion at closing the system timer ALSA: timer: Fix link corruption due to double start or stop ALSA: seq: Fix yet another races among ALSA timer accesses ALSA: pcm: Fix potential deadlock in OSS emulation ALSA: rawmidi: Remove kernel WARNING for NULL user-space buffer check ALSA: seq: Fix race at closing in virmidi driver ALSA: emu10k1: correctly handling failed thread creation ALSA: usb-audio: Add quirk for Microsoft LifeCam HD-6000 ALSA: usb-audio: Add native DSD support for PS Audio NuWave DAC ALSA: usb-audio: Fix OPPO HA-1 vendor ID
-rw-r--r--include/sound/rawmidi.h4
-rw-r--r--sound/core/oss/pcm_oss.c21
-rw-r--r--sound/core/rawmidi.c134
-rw-r--r--sound/core/seq/seq_clientmgr.c3
-rw-r--r--sound/core/seq/seq_ports.c233
-rw-r--r--sound/core/seq/seq_timer.c87
-rw-r--r--sound/core/seq/seq_virmidi.c23
-rw-r--r--sound/core/timer.c44
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c8
-rw-r--r--sound/pci/hda/patch_cirrus.c27
-rw-r--r--sound/pci/hda/patch_realtek.c74
-rw-r--r--sound/usb/quirks.c4
12 files changed, 483 insertions, 179 deletions
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index fdabbb4ddba9..f730b91e472f 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -167,6 +167,10 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
167int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count); 167int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count);
168int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, 168int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
169 unsigned char *buffer, int count); 169 unsigned char *buffer, int count);
170int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
171 unsigned char *buffer, int count);
172int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream,
173 int count);
170 174
171/* main midi functions */ 175/* main midi functions */
172 176
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 0e73d03b30e3..ebc9fdfe64df 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -835,7 +835,8 @@ static int choose_rate(struct snd_pcm_substream *substream,
835 return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL); 835 return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL);
836} 836}
837 837
838static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) 838static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
839 bool trylock)
839{ 840{
840 struct snd_pcm_runtime *runtime = substream->runtime; 841 struct snd_pcm_runtime *runtime = substream->runtime;
841 struct snd_pcm_hw_params *params, *sparams; 842 struct snd_pcm_hw_params *params, *sparams;
@@ -849,7 +850,10 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
849 struct snd_mask sformat_mask; 850 struct snd_mask sformat_mask;
850 struct snd_mask mask; 851 struct snd_mask mask;
851 852
852 if (mutex_lock_interruptible(&runtime->oss.params_lock)) 853 if (trylock) {
854 if (!(mutex_trylock(&runtime->oss.params_lock)))
855 return -EAGAIN;
856 } else if (mutex_lock_interruptible(&runtime->oss.params_lock))
853 return -EINTR; 857 return -EINTR;
854 sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); 858 sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL);
855 params = kmalloc(sizeof(*params), GFP_KERNEL); 859 params = kmalloc(sizeof(*params), GFP_KERNEL);
@@ -1092,7 +1096,7 @@ static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_fil
1092 if (asubstream == NULL) 1096 if (asubstream == NULL)
1093 asubstream = substream; 1097 asubstream = substream;
1094 if (substream->runtime->oss.params) { 1098 if (substream->runtime->oss.params) {
1095 err = snd_pcm_oss_change_params(substream); 1099 err = snd_pcm_oss_change_params(substream, false);
1096 if (err < 0) 1100 if (err < 0)
1097 return err; 1101 return err;
1098 } 1102 }
@@ -1132,7 +1136,7 @@ static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream)
1132 return 0; 1136 return 0;
1133 runtime = substream->runtime; 1137 runtime = substream->runtime;
1134 if (runtime->oss.params) { 1138 if (runtime->oss.params) {
1135 err = snd_pcm_oss_change_params(substream); 1139 err = snd_pcm_oss_change_params(substream, false);
1136 if (err < 0) 1140 if (err < 0)
1137 return err; 1141 return err;
1138 } 1142 }
@@ -2163,7 +2167,7 @@ static int snd_pcm_oss_get_space(struct snd_pcm_oss_file *pcm_oss_file, int stre
2163 runtime = substream->runtime; 2167 runtime = substream->runtime;
2164 2168
2165 if (runtime->oss.params && 2169 if (runtime->oss.params &&
2166 (err = snd_pcm_oss_change_params(substream)) < 0) 2170 (err = snd_pcm_oss_change_params(substream, false)) < 0)
2167 return err; 2171 return err;
2168 2172
2169 info.fragsize = runtime->oss.period_bytes; 2173 info.fragsize = runtime->oss.period_bytes;
@@ -2804,7 +2808,12 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area)
2804 return -EIO; 2808 return -EIO;
2805 2809
2806 if (runtime->oss.params) { 2810 if (runtime->oss.params) {
2807 if ((err = snd_pcm_oss_change_params(substream)) < 0) 2811 /* use mutex_trylock() for params_lock for avoiding a deadlock
2812 * between mmap_sem and params_lock taken by
2813 * copy_from/to_user() in snd_pcm_oss_write/read()
2814 */
2815 err = snd_pcm_oss_change_params(substream, true);
2816 if (err < 0)
2808 return err; 2817 return err;
2809 } 2818 }
2810#ifdef CONFIG_SND_PCM_OSS_PLUGINS 2819#ifdef CONFIG_SND_PCM_OSS_PLUGINS
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index a7759846fbaa..795437b10082 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -942,31 +942,36 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
942 unsigned long flags; 942 unsigned long flags;
943 long result = 0, count1; 943 long result = 0, count1;
944 struct snd_rawmidi_runtime *runtime = substream->runtime; 944 struct snd_rawmidi_runtime *runtime = substream->runtime;
945 unsigned long appl_ptr;
945 946
947 spin_lock_irqsave(&runtime->lock, flags);
946 while (count > 0 && runtime->avail) { 948 while (count > 0 && runtime->avail) {
947 count1 = runtime->buffer_size - runtime->appl_ptr; 949 count1 = runtime->buffer_size - runtime->appl_ptr;
948 if (count1 > count) 950 if (count1 > count)
949 count1 = count; 951 count1 = count;
950 spin_lock_irqsave(&runtime->lock, flags);
951 if (count1 > (int)runtime->avail) 952 if (count1 > (int)runtime->avail)
952 count1 = runtime->avail; 953 count1 = runtime->avail;
954
955 /* update runtime->appl_ptr before unlocking for userbuf */
956 appl_ptr = runtime->appl_ptr;
957 runtime->appl_ptr += count1;
958 runtime->appl_ptr %= runtime->buffer_size;
959 runtime->avail -= count1;
960
953 if (kernelbuf) 961 if (kernelbuf)
954 memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1); 962 memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1);
955 if (userbuf) { 963 if (userbuf) {
956 spin_unlock_irqrestore(&runtime->lock, flags); 964 spin_unlock_irqrestore(&runtime->lock, flags);
957 if (copy_to_user(userbuf + result, 965 if (copy_to_user(userbuf + result,
958 runtime->buffer + runtime->appl_ptr, count1)) { 966 runtime->buffer + appl_ptr, count1)) {
959 return result > 0 ? result : -EFAULT; 967 return result > 0 ? result : -EFAULT;
960 } 968 }
961 spin_lock_irqsave(&runtime->lock, flags); 969 spin_lock_irqsave(&runtime->lock, flags);
962 } 970 }
963 runtime->appl_ptr += count1;
964 runtime->appl_ptr %= runtime->buffer_size;
965 runtime->avail -= count1;
966 spin_unlock_irqrestore(&runtime->lock, flags);
967 result += count1; 971 result += count1;
968 count -= count1; 972 count -= count1;
969 } 973 }
974 spin_unlock_irqrestore(&runtime->lock, flags);
970 return result; 975 return result;
971} 976}
972 977
@@ -1055,23 +1060,16 @@ int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream)
1055EXPORT_SYMBOL(snd_rawmidi_transmit_empty); 1060EXPORT_SYMBOL(snd_rawmidi_transmit_empty);
1056 1061
1057/** 1062/**
1058 * snd_rawmidi_transmit_peek - copy data from the internal buffer 1063 * __snd_rawmidi_transmit_peek - copy data from the internal buffer
1059 * @substream: the rawmidi substream 1064 * @substream: the rawmidi substream
1060 * @buffer: the buffer pointer 1065 * @buffer: the buffer pointer
1061 * @count: data size to transfer 1066 * @count: data size to transfer
1062 * 1067 *
1063 * Copies data from the internal output buffer to the given buffer. 1068 * This is a variant of snd_rawmidi_transmit_peek() without spinlock.
1064 *
1065 * Call this in the interrupt handler when the midi output is ready,
1066 * and call snd_rawmidi_transmit_ack() after the transmission is
1067 * finished.
1068 *
1069 * Return: The size of copied data, or a negative error code on failure.
1070 */ 1069 */
1071int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, 1070int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
1072 unsigned char *buffer, int count) 1071 unsigned char *buffer, int count)
1073{ 1072{
1074 unsigned long flags;
1075 int result, count1; 1073 int result, count1;
1076 struct snd_rawmidi_runtime *runtime = substream->runtime; 1074 struct snd_rawmidi_runtime *runtime = substream->runtime;
1077 1075
@@ -1081,7 +1079,6 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
1081 return -EINVAL; 1079 return -EINVAL;
1082 } 1080 }
1083 result = 0; 1081 result = 0;
1084 spin_lock_irqsave(&runtime->lock, flags);
1085 if (runtime->avail >= runtime->buffer_size) { 1082 if (runtime->avail >= runtime->buffer_size) {
1086 /* warning: lowlevel layer MUST trigger down the hardware */ 1083 /* warning: lowlevel layer MUST trigger down the hardware */
1087 goto __skip; 1084 goto __skip;
@@ -1106,25 +1103,47 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
1106 } 1103 }
1107 } 1104 }
1108 __skip: 1105 __skip:
1106 return result;
1107}
1108EXPORT_SYMBOL(__snd_rawmidi_transmit_peek);
1109
1110/**
1111 * snd_rawmidi_transmit_peek - copy data from the internal buffer
1112 * @substream: the rawmidi substream
1113 * @buffer: the buffer pointer
1114 * @count: data size to transfer
1115 *
1116 * Copies data from the internal output buffer to the given buffer.
1117 *
1118 * Call this in the interrupt handler when the midi output is ready,
1119 * and call snd_rawmidi_transmit_ack() after the transmission is
1120 * finished.
1121 *
1122 * Return: The size of copied data, or a negative error code on failure.
1123 */
1124int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
1125 unsigned char *buffer, int count)
1126{
1127 struct snd_rawmidi_runtime *runtime = substream->runtime;
1128 int result;
1129 unsigned long flags;
1130
1131 spin_lock_irqsave(&runtime->lock, flags);
1132 result = __snd_rawmidi_transmit_peek(substream, buffer, count);
1109 spin_unlock_irqrestore(&runtime->lock, flags); 1133 spin_unlock_irqrestore(&runtime->lock, flags);
1110 return result; 1134 return result;
1111} 1135}
1112EXPORT_SYMBOL(snd_rawmidi_transmit_peek); 1136EXPORT_SYMBOL(snd_rawmidi_transmit_peek);
1113 1137
1114/** 1138/**
1115 * snd_rawmidi_transmit_ack - acknowledge the transmission 1139 * __snd_rawmidi_transmit_ack - acknowledge the transmission
1116 * @substream: the rawmidi substream 1140 * @substream: the rawmidi substream
1117 * @count: the transferred count 1141 * @count: the transferred count
1118 * 1142 *
1119 * Advances the hardware pointer for the internal output buffer with 1143 * This is a variant of __snd_rawmidi_transmit_ack() without spinlock.
1120 * the given size and updates the condition.
1121 * Call after the transmission is finished.
1122 *
1123 * Return: The advanced size if successful, or a negative error code on failure.
1124 */ 1144 */
1125int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) 1145int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
1126{ 1146{
1127 unsigned long flags;
1128 struct snd_rawmidi_runtime *runtime = substream->runtime; 1147 struct snd_rawmidi_runtime *runtime = substream->runtime;
1129 1148
1130 if (runtime->buffer == NULL) { 1149 if (runtime->buffer == NULL) {
@@ -1132,7 +1151,6 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
1132 "snd_rawmidi_transmit_ack: output is not active!!!\n"); 1151 "snd_rawmidi_transmit_ack: output is not active!!!\n");
1133 return -EINVAL; 1152 return -EINVAL;
1134 } 1153 }
1135 spin_lock_irqsave(&runtime->lock, flags);
1136 snd_BUG_ON(runtime->avail + count > runtime->buffer_size); 1154 snd_BUG_ON(runtime->avail + count > runtime->buffer_size);
1137 runtime->hw_ptr += count; 1155 runtime->hw_ptr += count;
1138 runtime->hw_ptr %= runtime->buffer_size; 1156 runtime->hw_ptr %= runtime->buffer_size;
@@ -1142,9 +1160,32 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
1142 if (runtime->drain || snd_rawmidi_ready(substream)) 1160 if (runtime->drain || snd_rawmidi_ready(substream))
1143 wake_up(&runtime->sleep); 1161 wake_up(&runtime->sleep);
1144 } 1162 }
1145 spin_unlock_irqrestore(&runtime->lock, flags);
1146 return count; 1163 return count;
1147} 1164}
1165EXPORT_SYMBOL(__snd_rawmidi_transmit_ack);
1166
1167/**
1168 * snd_rawmidi_transmit_ack - acknowledge the transmission
1169 * @substream: the rawmidi substream
1170 * @count: the transferred count
1171 *
1172 * Advances the hardware pointer for the internal output buffer with
1173 * the given size and updates the condition.
1174 * Call after the transmission is finished.
1175 *
1176 * Return: The advanced size if successful, or a negative error code on failure.
1177 */
1178int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
1179{
1180 struct snd_rawmidi_runtime *runtime = substream->runtime;
1181 int result;
1182 unsigned long flags;
1183
1184 spin_lock_irqsave(&runtime->lock, flags);
1185 result = __snd_rawmidi_transmit_ack(substream, count);
1186 spin_unlock_irqrestore(&runtime->lock, flags);
1187 return result;
1188}
1148EXPORT_SYMBOL(snd_rawmidi_transmit_ack); 1189EXPORT_SYMBOL(snd_rawmidi_transmit_ack);
1149 1190
1150/** 1191/**
@@ -1160,12 +1201,22 @@ EXPORT_SYMBOL(snd_rawmidi_transmit_ack);
1160int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, 1201int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
1161 unsigned char *buffer, int count) 1202 unsigned char *buffer, int count)
1162{ 1203{
1204 struct snd_rawmidi_runtime *runtime = substream->runtime;
1205 int result;
1206 unsigned long flags;
1207
1208 spin_lock_irqsave(&runtime->lock, flags);
1163 if (!substream->opened) 1209 if (!substream->opened)
1164 return -EBADFD; 1210 result = -EBADFD;
1165 count = snd_rawmidi_transmit_peek(substream, buffer, count); 1211 else {
1166 if (count < 0) 1212 count = __snd_rawmidi_transmit_peek(substream, buffer, count);
1167 return count; 1213 if (count <= 0)
1168 return snd_rawmidi_transmit_ack(substream, count); 1214 result = count;
1215 else
1216 result = __snd_rawmidi_transmit_ack(substream, count);
1217 }
1218 spin_unlock_irqrestore(&runtime->lock, flags);
1219 return result;
1169} 1220}
1170EXPORT_SYMBOL(snd_rawmidi_transmit); 1221EXPORT_SYMBOL(snd_rawmidi_transmit);
1171 1222
@@ -1177,8 +1228,9 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
1177 unsigned long flags; 1228 unsigned long flags;
1178 long count1, result; 1229 long count1, result;
1179 struct snd_rawmidi_runtime *runtime = substream->runtime; 1230 struct snd_rawmidi_runtime *runtime = substream->runtime;
1231 unsigned long appl_ptr;
1180 1232
1181 if (snd_BUG_ON(!kernelbuf && !userbuf)) 1233 if (!kernelbuf && !userbuf)
1182 return -EINVAL; 1234 return -EINVAL;
1183 if (snd_BUG_ON(!runtime->buffer)) 1235 if (snd_BUG_ON(!runtime->buffer))
1184 return -EINVAL; 1236 return -EINVAL;
@@ -1197,12 +1249,19 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
1197 count1 = count; 1249 count1 = count;
1198 if (count1 > (long)runtime->avail) 1250 if (count1 > (long)runtime->avail)
1199 count1 = runtime->avail; 1251 count1 = runtime->avail;
1252
1253 /* update runtime->appl_ptr before unlocking for userbuf */
1254 appl_ptr = runtime->appl_ptr;
1255 runtime->appl_ptr += count1;
1256 runtime->appl_ptr %= runtime->buffer_size;
1257 runtime->avail -= count1;
1258
1200 if (kernelbuf) 1259 if (kernelbuf)
1201 memcpy(runtime->buffer + runtime->appl_ptr, 1260 memcpy(runtime->buffer + appl_ptr,
1202 kernelbuf + result, count1); 1261 kernelbuf + result, count1);
1203 else if (userbuf) { 1262 else if (userbuf) {
1204 spin_unlock_irqrestore(&runtime->lock, flags); 1263 spin_unlock_irqrestore(&runtime->lock, flags);
1205 if (copy_from_user(runtime->buffer + runtime->appl_ptr, 1264 if (copy_from_user(runtime->buffer + appl_ptr,
1206 userbuf + result, count1)) { 1265 userbuf + result, count1)) {
1207 spin_lock_irqsave(&runtime->lock, flags); 1266 spin_lock_irqsave(&runtime->lock, flags);
1208 result = result > 0 ? result : -EFAULT; 1267 result = result > 0 ? result : -EFAULT;
@@ -1210,9 +1269,6 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
1210 } 1269 }
1211 spin_lock_irqsave(&runtime->lock, flags); 1270 spin_lock_irqsave(&runtime->lock, flags);
1212 } 1271 }
1213 runtime->appl_ptr += count1;
1214 runtime->appl_ptr %= runtime->buffer_size;
1215 runtime->avail -= count1;
1216 result += count1; 1272 result += count1;
1217 count -= count1; 1273 count -= count1;
1218 } 1274 }
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 13cfa815732d..58e79e02f217 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -678,6 +678,9 @@ static int deliver_to_subscribers(struct snd_seq_client *client,
678 else 678 else
679 down_read(&grp->list_mutex); 679 down_read(&grp->list_mutex);
680 list_for_each_entry(subs, &grp->list_head, src_list) { 680 list_for_each_entry(subs, &grp->list_head, src_list) {
681 /* both ports ready? */
682 if (atomic_read(&subs->ref_count) != 2)
683 continue;
681 event->dest = subs->info.dest; 684 event->dest = subs->info.dest;
682 if (subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) 685 if (subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP)
683 /* convert time according to flag with subscription */ 686 /* convert time according to flag with subscription */
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index 55170a20ae72..921fb2bd8fad 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -173,10 +173,6 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
173} 173}
174 174
175/* */ 175/* */
176enum group_type {
177 SRC_LIST, DEST_LIST
178};
179
180static int subscribe_port(struct snd_seq_client *client, 176static int subscribe_port(struct snd_seq_client *client,
181 struct snd_seq_client_port *port, 177 struct snd_seq_client_port *port,
182 struct snd_seq_port_subs_info *grp, 178 struct snd_seq_port_subs_info *grp,
@@ -203,6 +199,20 @@ static struct snd_seq_client_port *get_client_port(struct snd_seq_addr *addr,
203 return NULL; 199 return NULL;
204} 200}
205 201
202static void delete_and_unsubscribe_port(struct snd_seq_client *client,
203 struct snd_seq_client_port *port,
204 struct snd_seq_subscribers *subs,
205 bool is_src, bool ack);
206
207static inline struct snd_seq_subscribers *
208get_subscriber(struct list_head *p, bool is_src)
209{
210 if (is_src)
211 return list_entry(p, struct snd_seq_subscribers, src_list);
212 else
213 return list_entry(p, struct snd_seq_subscribers, dest_list);
214}
215
206/* 216/*
207 * remove all subscribers on the list 217 * remove all subscribers on the list
208 * this is called from port_delete, for each src and dest list. 218 * this is called from port_delete, for each src and dest list.
@@ -210,7 +220,7 @@ static struct snd_seq_client_port *get_client_port(struct snd_seq_addr *addr,
210static void clear_subscriber_list(struct snd_seq_client *client, 220static void clear_subscriber_list(struct snd_seq_client *client,
211 struct snd_seq_client_port *port, 221 struct snd_seq_client_port *port,
212 struct snd_seq_port_subs_info *grp, 222 struct snd_seq_port_subs_info *grp,
213 int grptype) 223 int is_src)
214{ 224{
215 struct list_head *p, *n; 225 struct list_head *p, *n;
216 226
@@ -219,15 +229,13 @@ static void clear_subscriber_list(struct snd_seq_client *client,
219 struct snd_seq_client *c; 229 struct snd_seq_client *c;
220 struct snd_seq_client_port *aport; 230 struct snd_seq_client_port *aport;
221 231
222 if (grptype == SRC_LIST) { 232 subs = get_subscriber(p, is_src);
223 subs = list_entry(p, struct snd_seq_subscribers, src_list); 233 if (is_src)
224 aport = get_client_port(&subs->info.dest, &c); 234 aport = get_client_port(&subs->info.dest, &c);
225 } else { 235 else
226 subs = list_entry(p, struct snd_seq_subscribers, dest_list);
227 aport = get_client_port(&subs->info.sender, &c); 236 aport = get_client_port(&subs->info.sender, &c);
228 } 237 delete_and_unsubscribe_port(client, port, subs, is_src, false);
229 list_del(p); 238
230 unsubscribe_port(client, port, grp, &subs->info, 0);
231 if (!aport) { 239 if (!aport) {
232 /* looks like the connected port is being deleted. 240 /* looks like the connected port is being deleted.
233 * we decrease the counter, and when both ports are deleted 241 * we decrease the counter, and when both ports are deleted
@@ -235,21 +243,14 @@ static void clear_subscriber_list(struct snd_seq_client *client,
235 */ 243 */
236 if (atomic_dec_and_test(&subs->ref_count)) 244 if (atomic_dec_and_test(&subs->ref_count))
237 kfree(subs); 245 kfree(subs);
238 } else { 246 continue;
239 /* ok we got the connected port */
240 struct snd_seq_port_subs_info *agrp;
241 agrp = (grptype == SRC_LIST) ? &aport->c_dest : &aport->c_src;
242 down_write(&agrp->list_mutex);
243 if (grptype == SRC_LIST)
244 list_del(&subs->dest_list);
245 else
246 list_del(&subs->src_list);
247 up_write(&agrp->list_mutex);
248 unsubscribe_port(c, aport, agrp, &subs->info, 1);
249 kfree(subs);
250 snd_seq_port_unlock(aport);
251 snd_seq_client_unlock(c);
252 } 247 }
248
249 /* ok we got the connected port */
250 delete_and_unsubscribe_port(c, aport, subs, !is_src, true);
251 kfree(subs);
252 snd_seq_port_unlock(aport);
253 snd_seq_client_unlock(c);
253 } 254 }
254} 255}
255 256
@@ -262,8 +263,8 @@ static int port_delete(struct snd_seq_client *client,
262 snd_use_lock_sync(&port->use_lock); 263 snd_use_lock_sync(&port->use_lock);
263 264
264 /* clear subscribers info */ 265 /* clear subscribers info */
265 clear_subscriber_list(client, port, &port->c_src, SRC_LIST); 266 clear_subscriber_list(client, port, &port->c_src, true);
266 clear_subscriber_list(client, port, &port->c_dest, DEST_LIST); 267 clear_subscriber_list(client, port, &port->c_dest, false);
267 268
268 if (port->private_free) 269 if (port->private_free)
269 port->private_free(port->private_data); 270 port->private_free(port->private_data);
@@ -479,85 +480,120 @@ static int match_subs_info(struct snd_seq_port_subscribe *r,
479 return 0; 480 return 0;
480} 481}
481 482
482 483static int check_and_subscribe_port(struct snd_seq_client *client,
483/* connect two ports */ 484 struct snd_seq_client_port *port,
484int snd_seq_port_connect(struct snd_seq_client *connector, 485 struct snd_seq_subscribers *subs,
485 struct snd_seq_client *src_client, 486 bool is_src, bool exclusive, bool ack)
486 struct snd_seq_client_port *src_port,
487 struct snd_seq_client *dest_client,
488 struct snd_seq_client_port *dest_port,
489 struct snd_seq_port_subscribe *info)
490{ 487{
491 struct snd_seq_port_subs_info *src = &src_port->c_src; 488 struct snd_seq_port_subs_info *grp;
492 struct snd_seq_port_subs_info *dest = &dest_port->c_dest; 489 struct list_head *p;
493 struct snd_seq_subscribers *subs, *s; 490 struct snd_seq_subscribers *s;
494 int err, src_called = 0; 491 int err;
495 unsigned long flags;
496 int exclusive;
497 492
498 subs = kzalloc(sizeof(*subs), GFP_KERNEL); 493 grp = is_src ? &port->c_src : &port->c_dest;
499 if (! subs)
500 return -ENOMEM;
501
502 subs->info = *info;
503 atomic_set(&subs->ref_count, 2);
504
505 down_write(&src->list_mutex);
506 down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING);
507
508 exclusive = info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE ? 1 : 0;
509 err = -EBUSY; 494 err = -EBUSY;
495 down_write(&grp->list_mutex);
510 if (exclusive) { 496 if (exclusive) {
511 if (! list_empty(&src->list_head) || ! list_empty(&dest->list_head)) 497 if (!list_empty(&grp->list_head))
512 goto __error; 498 goto __error;
513 } else { 499 } else {
514 if (src->exclusive || dest->exclusive) 500 if (grp->exclusive)
515 goto __error; 501 goto __error;
516 /* check whether already exists */ 502 /* check whether already exists */
517 list_for_each_entry(s, &src->list_head, src_list) { 503 list_for_each(p, &grp->list_head) {
518 if (match_subs_info(info, &s->info)) 504 s = get_subscriber(p, is_src);
519 goto __error; 505 if (match_subs_info(&subs->info, &s->info))
520 }
521 list_for_each_entry(s, &dest->list_head, dest_list) {
522 if (match_subs_info(info, &s->info))
523 goto __error; 506 goto __error;
524 } 507 }
525 } 508 }
526 509
527 if ((err = subscribe_port(src_client, src_port, src, info, 510 err = subscribe_port(client, port, grp, &subs->info, ack);
528 connector->number != src_client->number)) < 0) 511 if (err < 0) {
529 goto __error; 512 grp->exclusive = 0;
530 src_called = 1;
531
532 if ((err = subscribe_port(dest_client, dest_port, dest, info,
533 connector->number != dest_client->number)) < 0)
534 goto __error; 513 goto __error;
514 }
535 515
536 /* add to list */ 516 /* add to list */
537 write_lock_irqsave(&src->list_lock, flags); 517 write_lock_irq(&grp->list_lock);
538 // write_lock(&dest->list_lock); // no other lock yet 518 if (is_src)
539 list_add_tail(&subs->src_list, &src->list_head); 519 list_add_tail(&subs->src_list, &grp->list_head);
540 list_add_tail(&subs->dest_list, &dest->list_head); 520 else
541 // write_unlock(&dest->list_lock); // no other lock yet 521 list_add_tail(&subs->dest_list, &grp->list_head);
542 write_unlock_irqrestore(&src->list_lock, flags); 522 grp->exclusive = exclusive;
523 atomic_inc(&subs->ref_count);
524 write_unlock_irq(&grp->list_lock);
525 err = 0;
526
527 __error:
528 up_write(&grp->list_mutex);
529 return err;
530}
543 531
544 src->exclusive = dest->exclusive = exclusive; 532static void delete_and_unsubscribe_port(struct snd_seq_client *client,
533 struct snd_seq_client_port *port,
534 struct snd_seq_subscribers *subs,
535 bool is_src, bool ack)
536{
537 struct snd_seq_port_subs_info *grp;
538
539 grp = is_src ? &port->c_src : &port->c_dest;
540 down_write(&grp->list_mutex);
541 write_lock_irq(&grp->list_lock);
542 if (is_src)
543 list_del(&subs->src_list);
544 else
545 list_del(&subs->dest_list);
546 grp->exclusive = 0;
547 write_unlock_irq(&grp->list_lock);
548 up_write(&grp->list_mutex);
549
550 unsubscribe_port(client, port, grp, &subs->info, ack);
551}
552
553/* connect two ports */
554int snd_seq_port_connect(struct snd_seq_client *connector,
555 struct snd_seq_client *src_client,
556 struct snd_seq_client_port *src_port,
557 struct snd_seq_client *dest_client,
558 struct snd_seq_client_port *dest_port,
559 struct snd_seq_port_subscribe *info)
560{
561 struct snd_seq_subscribers *subs;
562 bool exclusive;
563 int err;
564
565 subs = kzalloc(sizeof(*subs), GFP_KERNEL);
566 if (!subs)
567 return -ENOMEM;
568
569 subs->info = *info;
570 atomic_set(&subs->ref_count, 0);
571 INIT_LIST_HEAD(&subs->src_list);
572 INIT_LIST_HEAD(&subs->dest_list);
573
574 exclusive = !!(info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE);
575
576 err = check_and_subscribe_port(src_client, src_port, subs, true,
577 exclusive,
578 connector->number != src_client->number);
579 if (err < 0)
580 goto error;
581 err = check_and_subscribe_port(dest_client, dest_port, subs, false,
582 exclusive,
583 connector->number != dest_client->number);
584 if (err < 0)
585 goto error_dest;
545 586
546 up_write(&dest->list_mutex);
547 up_write(&src->list_mutex);
548 return 0; 587 return 0;
549 588
550 __error: 589 error_dest:
551 if (src_called) 590 delete_and_unsubscribe_port(src_client, src_port, subs, true,
552 unsubscribe_port(src_client, src_port, src, info, 591 connector->number != src_client->number);
553 connector->number != src_client->number); 592 error:
554 kfree(subs); 593 kfree(subs);
555 up_write(&dest->list_mutex);
556 up_write(&src->list_mutex);
557 return err; 594 return err;
558} 595}
559 596
560
561/* remove the connection */ 597/* remove the connection */
562int snd_seq_port_disconnect(struct snd_seq_client *connector, 598int snd_seq_port_disconnect(struct snd_seq_client *connector,
563 struct snd_seq_client *src_client, 599 struct snd_seq_client *src_client,
@@ -567,37 +603,28 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector,
567 struct snd_seq_port_subscribe *info) 603 struct snd_seq_port_subscribe *info)
568{ 604{
569 struct snd_seq_port_subs_info *src = &src_port->c_src; 605 struct snd_seq_port_subs_info *src = &src_port->c_src;
570 struct snd_seq_port_subs_info *dest = &dest_port->c_dest;
571 struct snd_seq_subscribers *subs; 606 struct snd_seq_subscribers *subs;
572 int err = -ENOENT; 607 int err = -ENOENT;
573 unsigned long flags;
574 608
575 down_write(&src->list_mutex); 609 down_write(&src->list_mutex);
576 down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING);
577
578 /* look for the connection */ 610 /* look for the connection */
579 list_for_each_entry(subs, &src->list_head, src_list) { 611 list_for_each_entry(subs, &src->list_head, src_list) {
580 if (match_subs_info(info, &subs->info)) { 612 if (match_subs_info(info, &subs->info)) {
581 write_lock_irqsave(&src->list_lock, flags); 613 atomic_dec(&subs->ref_count); /* mark as not ready */
582 // write_lock(&dest->list_lock); // no lock yet
583 list_del(&subs->src_list);
584 list_del(&subs->dest_list);
585 // write_unlock(&dest->list_lock);
586 write_unlock_irqrestore(&src->list_lock, flags);
587 src->exclusive = dest->exclusive = 0;
588 unsubscribe_port(src_client, src_port, src, info,
589 connector->number != src_client->number);
590 unsubscribe_port(dest_client, dest_port, dest, info,
591 connector->number != dest_client->number);
592 kfree(subs);
593 err = 0; 614 err = 0;
594 break; 615 break;
595 } 616 }
596 } 617 }
597
598 up_write(&dest->list_mutex);
599 up_write(&src->list_mutex); 618 up_write(&src->list_mutex);
600 return err; 619 if (err < 0)
620 return err;
621
622 delete_and_unsubscribe_port(src_client, src_port, subs, true,
623 connector->number != src_client->number);
624 delete_and_unsubscribe_port(dest_client, dest_port, subs, false,
625 connector->number != dest_client->number);
626 kfree(subs);
627 return 0;
601} 628}
602 629
603 630
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index 82b220c769c1..293104926098 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -90,6 +90,9 @@ void snd_seq_timer_delete(struct snd_seq_timer **tmr)
90 90
91void snd_seq_timer_defaults(struct snd_seq_timer * tmr) 91void snd_seq_timer_defaults(struct snd_seq_timer * tmr)
92{ 92{
93 unsigned long flags;
94
95 spin_lock_irqsave(&tmr->lock, flags);
93 /* setup defaults */ 96 /* setup defaults */
94 tmr->ppq = 96; /* 96 PPQ */ 97 tmr->ppq = 96; /* 96 PPQ */
95 tmr->tempo = 500000; /* 120 BPM */ 98 tmr->tempo = 500000; /* 120 BPM */
@@ -105,21 +108,25 @@ void snd_seq_timer_defaults(struct snd_seq_timer * tmr)
105 tmr->preferred_resolution = seq_default_timer_resolution; 108 tmr->preferred_resolution = seq_default_timer_resolution;
106 109
107 tmr->skew = tmr->skew_base = SKEW_BASE; 110 tmr->skew = tmr->skew_base = SKEW_BASE;
111 spin_unlock_irqrestore(&tmr->lock, flags);
108} 112}
109 113
110void snd_seq_timer_reset(struct snd_seq_timer * tmr) 114static void seq_timer_reset(struct snd_seq_timer *tmr)
111{ 115{
112 unsigned long flags;
113
114 spin_lock_irqsave(&tmr->lock, flags);
115
116 /* reset time & songposition */ 116 /* reset time & songposition */
117 tmr->cur_time.tv_sec = 0; 117 tmr->cur_time.tv_sec = 0;
118 tmr->cur_time.tv_nsec = 0; 118 tmr->cur_time.tv_nsec = 0;
119 119
120 tmr->tick.cur_tick = 0; 120 tmr->tick.cur_tick = 0;
121 tmr->tick.fraction = 0; 121 tmr->tick.fraction = 0;
122}
123
124void snd_seq_timer_reset(struct snd_seq_timer *tmr)
125{
126 unsigned long flags;
122 127
128 spin_lock_irqsave(&tmr->lock, flags);
129 seq_timer_reset(tmr);
123 spin_unlock_irqrestore(&tmr->lock, flags); 130 spin_unlock_irqrestore(&tmr->lock, flags);
124} 131}
125 132
@@ -138,8 +145,11 @@ static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri,
138 tmr = q->timer; 145 tmr = q->timer;
139 if (tmr == NULL) 146 if (tmr == NULL)
140 return; 147 return;
141 if (!tmr->running) 148 spin_lock_irqsave(&tmr->lock, flags);
149 if (!tmr->running) {
150 spin_unlock_irqrestore(&tmr->lock, flags);
142 return; 151 return;
152 }
143 153
144 resolution *= ticks; 154 resolution *= ticks;
145 if (tmr->skew != tmr->skew_base) { 155 if (tmr->skew != tmr->skew_base) {
@@ -148,8 +158,6 @@ static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri,
148 (((resolution & 0xffff) * tmr->skew) >> 16); 158 (((resolution & 0xffff) * tmr->skew) >> 16);
149 } 159 }
150 160
151 spin_lock_irqsave(&tmr->lock, flags);
152
153 /* update timer */ 161 /* update timer */
154 snd_seq_inc_time_nsec(&tmr->cur_time, resolution); 162 snd_seq_inc_time_nsec(&tmr->cur_time, resolution);
155 163
@@ -296,26 +304,30 @@ int snd_seq_timer_open(struct snd_seq_queue *q)
296 t->callback = snd_seq_timer_interrupt; 304 t->callback = snd_seq_timer_interrupt;
297 t->callback_data = q; 305 t->callback_data = q;
298 t->flags |= SNDRV_TIMER_IFLG_AUTO; 306 t->flags |= SNDRV_TIMER_IFLG_AUTO;
307 spin_lock_irq(&tmr->lock);
299 tmr->timeri = t; 308 tmr->timeri = t;
309 spin_unlock_irq(&tmr->lock);
300 return 0; 310 return 0;
301} 311}
302 312
303int snd_seq_timer_close(struct snd_seq_queue *q) 313int snd_seq_timer_close(struct snd_seq_queue *q)
304{ 314{
305 struct snd_seq_timer *tmr; 315 struct snd_seq_timer *tmr;
316 struct snd_timer_instance *t;
306 317
307 tmr = q->timer; 318 tmr = q->timer;
308 if (snd_BUG_ON(!tmr)) 319 if (snd_BUG_ON(!tmr))
309 return -EINVAL; 320 return -EINVAL;
310 if (tmr->timeri) { 321 spin_lock_irq(&tmr->lock);
311 snd_timer_stop(tmr->timeri); 322 t = tmr->timeri;
312 snd_timer_close(tmr->timeri); 323 tmr->timeri = NULL;
313 tmr->timeri = NULL; 324 spin_unlock_irq(&tmr->lock);
314 } 325 if (t)
326 snd_timer_close(t);
315 return 0; 327 return 0;
316} 328}
317 329
318int snd_seq_timer_stop(struct snd_seq_timer * tmr) 330static int seq_timer_stop(struct snd_seq_timer *tmr)
319{ 331{
320 if (! tmr->timeri) 332 if (! tmr->timeri)
321 return -EINVAL; 333 return -EINVAL;
@@ -326,6 +338,17 @@ int snd_seq_timer_stop(struct snd_seq_timer * tmr)
326 return 0; 338 return 0;
327} 339}
328 340
341int snd_seq_timer_stop(struct snd_seq_timer *tmr)
342{
343 unsigned long flags;
344 int err;
345
346 spin_lock_irqsave(&tmr->lock, flags);
347 err = seq_timer_stop(tmr);
348 spin_unlock_irqrestore(&tmr->lock, flags);
349 return err;
350}
351
329static int initialize_timer(struct snd_seq_timer *tmr) 352static int initialize_timer(struct snd_seq_timer *tmr)
330{ 353{
331 struct snd_timer *t; 354 struct snd_timer *t;
@@ -358,13 +381,13 @@ static int initialize_timer(struct snd_seq_timer *tmr)
358 return 0; 381 return 0;
359} 382}
360 383
361int snd_seq_timer_start(struct snd_seq_timer * tmr) 384static int seq_timer_start(struct snd_seq_timer *tmr)
362{ 385{
363 if (! tmr->timeri) 386 if (! tmr->timeri)
364 return -EINVAL; 387 return -EINVAL;
365 if (tmr->running) 388 if (tmr->running)
366 snd_seq_timer_stop(tmr); 389 seq_timer_stop(tmr);
367 snd_seq_timer_reset(tmr); 390 seq_timer_reset(tmr);
368 if (initialize_timer(tmr) < 0) 391 if (initialize_timer(tmr) < 0)
369 return -EINVAL; 392 return -EINVAL;
370 snd_timer_start(tmr->timeri, tmr->ticks); 393 snd_timer_start(tmr->timeri, tmr->ticks);
@@ -373,14 +396,25 @@ int snd_seq_timer_start(struct snd_seq_timer * tmr)
373 return 0; 396 return 0;
374} 397}
375 398
376int snd_seq_timer_continue(struct snd_seq_timer * tmr) 399int snd_seq_timer_start(struct snd_seq_timer *tmr)
400{
401 unsigned long flags;
402 int err;
403
404 spin_lock_irqsave(&tmr->lock, flags);
405 err = seq_timer_start(tmr);
406 spin_unlock_irqrestore(&tmr->lock, flags);
407 return err;
408}
409
410static int seq_timer_continue(struct snd_seq_timer *tmr)
377{ 411{
378 if (! tmr->timeri) 412 if (! tmr->timeri)
379 return -EINVAL; 413 return -EINVAL;
380 if (tmr->running) 414 if (tmr->running)
381 return -EBUSY; 415 return -EBUSY;
382 if (! tmr->initialized) { 416 if (! tmr->initialized) {
383 snd_seq_timer_reset(tmr); 417 seq_timer_reset(tmr);
384 if (initialize_timer(tmr) < 0) 418 if (initialize_timer(tmr) < 0)
385 return -EINVAL; 419 return -EINVAL;
386 } 420 }
@@ -390,11 +424,24 @@ int snd_seq_timer_continue(struct snd_seq_timer * tmr)
390 return 0; 424 return 0;
391} 425}
392 426
427int snd_seq_timer_continue(struct snd_seq_timer *tmr)
428{
429 unsigned long flags;
430 int err;
431
432 spin_lock_irqsave(&tmr->lock, flags);
433 err = seq_timer_continue(tmr);
434 spin_unlock_irqrestore(&tmr->lock, flags);
435 return err;
436}
437
393/* return current 'real' time. use timeofday() to get better granularity. */ 438/* return current 'real' time. use timeofday() to get better granularity. */
394snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr) 439snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
395{ 440{
396 snd_seq_real_time_t cur_time; 441 snd_seq_real_time_t cur_time;
442 unsigned long flags;
397 443
444 spin_lock_irqsave(&tmr->lock, flags);
398 cur_time = tmr->cur_time; 445 cur_time = tmr->cur_time;
399 if (tmr->running) { 446 if (tmr->running) {
400 struct timeval tm; 447 struct timeval tm;
@@ -410,7 +457,7 @@ snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
410 } 457 }
411 snd_seq_sanity_real_time(&cur_time); 458 snd_seq_sanity_real_time(&cur_time);
412 } 459 }
413 460 spin_unlock_irqrestore(&tmr->lock, flags);
414 return cur_time; 461 return cur_time;
415} 462}
416 463
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index 3da2d48610b3..c82ed3e70506 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -155,21 +155,26 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
155 struct snd_virmidi *vmidi = substream->runtime->private_data; 155 struct snd_virmidi *vmidi = substream->runtime->private_data;
156 int count, res; 156 int count, res;
157 unsigned char buf[32], *pbuf; 157 unsigned char buf[32], *pbuf;
158 unsigned long flags;
158 159
159 if (up) { 160 if (up) {
160 vmidi->trigger = 1; 161 vmidi->trigger = 1;
161 if (vmidi->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH && 162 if (vmidi->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH &&
162 !(vmidi->rdev->flags & SNDRV_VIRMIDI_SUBSCRIBE)) { 163 !(vmidi->rdev->flags & SNDRV_VIRMIDI_SUBSCRIBE)) {
163 snd_rawmidi_transmit_ack(substream, substream->runtime->buffer_size - substream->runtime->avail); 164 while (snd_rawmidi_transmit(substream, buf,
164 return; /* ignored */ 165 sizeof(buf)) > 0) {
166 /* ignored */
167 }
168 return;
165 } 169 }
166 if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { 170 if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
167 if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) 171 if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
168 return; 172 return;
169 vmidi->event.type = SNDRV_SEQ_EVENT_NONE; 173 vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
170 } 174 }
175 spin_lock_irqsave(&substream->runtime->lock, flags);
171 while (1) { 176 while (1) {
172 count = snd_rawmidi_transmit_peek(substream, buf, sizeof(buf)); 177 count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
173 if (count <= 0) 178 if (count <= 0)
174 break; 179 break;
175 pbuf = buf; 180 pbuf = buf;
@@ -179,16 +184,18 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
179 snd_midi_event_reset_encode(vmidi->parser); 184 snd_midi_event_reset_encode(vmidi->parser);
180 continue; 185 continue;
181 } 186 }
182 snd_rawmidi_transmit_ack(substream, res); 187 __snd_rawmidi_transmit_ack(substream, res);
183 pbuf += res; 188 pbuf += res;
184 count -= res; 189 count -= res;
185 if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { 190 if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
186 if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) 191 if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
187 return; 192 goto out;
188 vmidi->event.type = SNDRV_SEQ_EVENT_NONE; 193 vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
189 } 194 }
190 } 195 }
191 } 196 }
197 out:
198 spin_unlock_irqrestore(&substream->runtime->lock, flags);
192 } else { 199 } else {
193 vmidi->trigger = 0; 200 vmidi->trigger = 0;
194 } 201 }
@@ -254,9 +261,13 @@ static int snd_virmidi_output_open(struct snd_rawmidi_substream *substream)
254 */ 261 */
255static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream) 262static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream)
256{ 263{
264 struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
257 struct snd_virmidi *vmidi = substream->runtime->private_data; 265 struct snd_virmidi *vmidi = substream->runtime->private_data;
258 snd_midi_event_free(vmidi->parser); 266
267 write_lock_irq(&rdev->filelist_lock);
259 list_del(&vmidi->list); 268 list_del(&vmidi->list);
269 write_unlock_irq(&rdev->filelist_lock);
270 snd_midi_event_free(vmidi->parser);
260 substream->runtime->private_data = NULL; 271 substream->runtime->private_data = NULL;
261 kfree(vmidi); 272 kfree(vmidi);
262 return 0; 273 return 0;
diff --git a/sound/core/timer.c b/sound/core/timer.c
index af1f68f7e315..9b513a05765a 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -451,6 +451,10 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri)
451 unsigned long flags; 451 unsigned long flags;
452 452
453 spin_lock_irqsave(&slave_active_lock, flags); 453 spin_lock_irqsave(&slave_active_lock, flags);
454 if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
455 spin_unlock_irqrestore(&slave_active_lock, flags);
456 return -EBUSY;
457 }
454 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; 458 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
455 if (timeri->master && timeri->timer) { 459 if (timeri->master && timeri->timer) {
456 spin_lock(&timeri->timer->lock); 460 spin_lock(&timeri->timer->lock);
@@ -475,7 +479,8 @@ int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
475 return -EINVAL; 479 return -EINVAL;
476 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { 480 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
477 result = snd_timer_start_slave(timeri); 481 result = snd_timer_start_slave(timeri);
478 snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); 482 if (result >= 0)
483 snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
479 return result; 484 return result;
480 } 485 }
481 timer = timeri->timer; 486 timer = timeri->timer;
@@ -484,11 +489,18 @@ int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
484 if (timer->card && timer->card->shutdown) 489 if (timer->card && timer->card->shutdown)
485 return -ENODEV; 490 return -ENODEV;
486 spin_lock_irqsave(&timer->lock, flags); 491 spin_lock_irqsave(&timer->lock, flags);
492 if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
493 SNDRV_TIMER_IFLG_START)) {
494 result = -EBUSY;
495 goto unlock;
496 }
487 timeri->ticks = timeri->cticks = ticks; 497 timeri->ticks = timeri->cticks = ticks;
488 timeri->pticks = 0; 498 timeri->pticks = 0;
489 result = snd_timer_start1(timer, timeri, ticks); 499 result = snd_timer_start1(timer, timeri, ticks);
500 unlock:
490 spin_unlock_irqrestore(&timer->lock, flags); 501 spin_unlock_irqrestore(&timer->lock, flags);
491 snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); 502 if (result >= 0)
503 snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
492 return result; 504 return result;
493} 505}
494 506
@@ -502,6 +514,10 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
502 514
503 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { 515 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
504 spin_lock_irqsave(&slave_active_lock, flags); 516 spin_lock_irqsave(&slave_active_lock, flags);
517 if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
518 spin_unlock_irqrestore(&slave_active_lock, flags);
519 return -EBUSY;
520 }
505 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; 521 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
506 list_del_init(&timeri->ack_list); 522 list_del_init(&timeri->ack_list);
507 list_del_init(&timeri->active_list); 523 list_del_init(&timeri->active_list);
@@ -512,6 +528,11 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
512 if (!timer) 528 if (!timer)
513 return -EINVAL; 529 return -EINVAL;
514 spin_lock_irqsave(&timer->lock, flags); 530 spin_lock_irqsave(&timer->lock, flags);
531 if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
532 SNDRV_TIMER_IFLG_START))) {
533 spin_unlock_irqrestore(&timer->lock, flags);
534 return -EBUSY;
535 }
515 list_del_init(&timeri->ack_list); 536 list_del_init(&timeri->ack_list);
516 list_del_init(&timeri->active_list); 537 list_del_init(&timeri->active_list);
517 if (timer->card && timer->card->shutdown) { 538 if (timer->card && timer->card->shutdown) {
@@ -581,10 +602,15 @@ int snd_timer_continue(struct snd_timer_instance *timeri)
581 if (timer->card && timer->card->shutdown) 602 if (timer->card && timer->card->shutdown)
582 return -ENODEV; 603 return -ENODEV;
583 spin_lock_irqsave(&timer->lock, flags); 604 spin_lock_irqsave(&timer->lock, flags);
605 if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
606 result = -EBUSY;
607 goto unlock;
608 }
584 if (!timeri->cticks) 609 if (!timeri->cticks)
585 timeri->cticks = 1; 610 timeri->cticks = 1;
586 timeri->pticks = 0; 611 timeri->pticks = 0;
587 result = snd_timer_start1(timer, timeri, timer->sticks); 612 result = snd_timer_start1(timer, timeri, timer->sticks);
613 unlock:
588 spin_unlock_irqrestore(&timer->lock, flags); 614 spin_unlock_irqrestore(&timer->lock, flags);
589 snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE); 615 snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE);
590 return result; 616 return result;
@@ -718,8 +744,8 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
718 ti->cticks = ti->ticks; 744 ti->cticks = ti->ticks;
719 } else { 745 } else {
720 ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING; 746 ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
721 if (--timer->running) 747 --timer->running;
722 list_del_init(&ti->active_list); 748 list_del_init(&ti->active_list);
723 } 749 }
724 if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || 750 if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
725 (ti->flags & SNDRV_TIMER_IFLG_FAST)) 751 (ti->flags & SNDRV_TIMER_IFLG_FAST))
@@ -1032,11 +1058,21 @@ static int snd_timer_s_stop(struct snd_timer * timer)
1032 return 0; 1058 return 0;
1033} 1059}
1034 1060
1061static int snd_timer_s_close(struct snd_timer *timer)
1062{
1063 struct snd_timer_system_private *priv;
1064
1065 priv = (struct snd_timer_system_private *)timer->private_data;
1066 del_timer_sync(&priv->tlist);
1067 return 0;
1068}
1069
1035static struct snd_timer_hardware snd_timer_system = 1070static struct snd_timer_hardware snd_timer_system =
1036{ 1071{
1037 .flags = SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET, 1072 .flags = SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET,
1038 .resolution = 1000000000L / HZ, 1073 .resolution = 1000000000L / HZ,
1039 .ticks = 10000000L, 1074 .ticks = 10000000L,
1075 .close = snd_timer_s_close,
1040 .start = snd_timer_s_start, 1076 .start = snd_timer_s_start,
1041 .stop = snd_timer_s_stop 1077 .stop = snd_timer_s_stop
1042}; 1078};
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 28e2f8b42f5e..891453451543 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1141,6 +1141,14 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
1141 emu->emu1010.firmware_thread = 1141 emu->emu1010.firmware_thread =
1142 kthread_create(emu1010_firmware_thread, emu, 1142 kthread_create(emu1010_firmware_thread, emu,
1143 "emu1010_firmware"); 1143 "emu1010_firmware");
1144 if (IS_ERR(emu->emu1010.firmware_thread)) {
1145 err = PTR_ERR(emu->emu1010.firmware_thread);
1146 emu->emu1010.firmware_thread = NULL;
1147 dev_info(emu->card->dev,
1148 "emu1010: Creating thread failed\n");
1149 return err;
1150 }
1151
1144 wake_up_process(emu->emu1010.firmware_thread); 1152 wake_up_process(emu->emu1010.firmware_thread);
1145 } 1153 }
1146 1154
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index a12ae8ac0914..c1c855a6c0af 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -614,6 +614,7 @@ enum {
614 CS4208_MAC_AUTO, 614 CS4208_MAC_AUTO,
615 CS4208_MBA6, 615 CS4208_MBA6,
616 CS4208_MBP11, 616 CS4208_MBP11,
617 CS4208_MACMINI,
617 CS4208_GPIO0, 618 CS4208_GPIO0,
618}; 619};
619 620
@@ -621,6 +622,7 @@ static const struct hda_model_fixup cs4208_models[] = {
621 { .id = CS4208_GPIO0, .name = "gpio0" }, 622 { .id = CS4208_GPIO0, .name = "gpio0" },
622 { .id = CS4208_MBA6, .name = "mba6" }, 623 { .id = CS4208_MBA6, .name = "mba6" },
623 { .id = CS4208_MBP11, .name = "mbp11" }, 624 { .id = CS4208_MBP11, .name = "mbp11" },
625 { .id = CS4208_MACMINI, .name = "macmini" },
624 {} 626 {}
625}; 627};
626 628
@@ -632,6 +634,7 @@ static const struct snd_pci_quirk cs4208_fixup_tbl[] = {
632/* codec SSID matching */ 634/* codec SSID matching */
633static const struct snd_pci_quirk cs4208_mac_fixup_tbl[] = { 635static const struct snd_pci_quirk cs4208_mac_fixup_tbl[] = {
634 SND_PCI_QUIRK(0x106b, 0x5e00, "MacBookPro 11,2", CS4208_MBP11), 636 SND_PCI_QUIRK(0x106b, 0x5e00, "MacBookPro 11,2", CS4208_MBP11),
637 SND_PCI_QUIRK(0x106b, 0x6c00, "MacMini 7,1", CS4208_MACMINI),
635 SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6), 638 SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6),
636 SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6), 639 SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6),
637 SND_PCI_QUIRK(0x106b, 0x7b00, "MacBookPro 12,1", CS4208_MBP11), 640 SND_PCI_QUIRK(0x106b, 0x7b00, "MacBookPro 12,1", CS4208_MBP11),
@@ -666,6 +669,24 @@ static void cs4208_fixup_mac(struct hda_codec *codec,
666 snd_hda_apply_fixup(codec, action); 669 snd_hda_apply_fixup(codec, action);
667} 670}
668 671
672/* MacMini 7,1 has the inverted jack detection */
673static void cs4208_fixup_macmini(struct hda_codec *codec,
674 const struct hda_fixup *fix, int action)
675{
676 static const struct hda_pintbl pincfgs[] = {
677 { 0x18, 0x00ab9150 }, /* mic (audio-in) jack: disable detect */
678 { 0x21, 0x004be140 }, /* SPDIF: disable detect */
679 { }
680 };
681
682 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
683 /* HP pin (0x10) has an inverted detection */
684 codec->inv_jack_detect = 1;
685 /* disable the bogus Mic and SPDIF jack detections */
686 snd_hda_apply_pincfgs(codec, pincfgs);
687 }
688}
689
669static int cs4208_spdif_sw_put(struct snd_kcontrol *kcontrol, 690static int cs4208_spdif_sw_put(struct snd_kcontrol *kcontrol,
670 struct snd_ctl_elem_value *ucontrol) 691 struct snd_ctl_elem_value *ucontrol)
671{ 692{
@@ -709,6 +730,12 @@ static const struct hda_fixup cs4208_fixups[] = {
709 .chained = true, 730 .chained = true,
710 .chain_id = CS4208_GPIO0, 731 .chain_id = CS4208_GPIO0,
711 }, 732 },
733 [CS4208_MACMINI] = {
734 .type = HDA_FIXUP_FUNC,
735 .v.func = cs4208_fixup_macmini,
736 .chained = true,
737 .chain_id = CS4208_GPIO0,
738 },
712 [CS4208_GPIO0] = { 739 [CS4208_GPIO0] = {
713 .type = HDA_FIXUP_FUNC, 740 .type = HDA_FIXUP_FUNC,
714 .v.func = cs4208_fixup_gpio0, 741 .v.func = cs4208_fixup_gpio0,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 33753244f48f..21992fb7035d 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -327,6 +327,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
327 case 0x10ec0292: 327 case 0x10ec0292:
328 alc_update_coef_idx(codec, 0x4, 1<<15, 0); 328 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
329 break; 329 break;
330 case 0x10ec0225:
330 case 0x10ec0233: 331 case 0x10ec0233:
331 case 0x10ec0255: 332 case 0x10ec0255:
332 case 0x10ec0256: 333 case 0x10ec0256:
@@ -900,6 +901,7 @@ static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
900 { 0x10ec0899, 0x1028, 0, "ALC3861" }, 901 { 0x10ec0899, 0x1028, 0, "ALC3861" },
901 { 0x10ec0298, 0x1028, 0, "ALC3266" }, 902 { 0x10ec0298, 0x1028, 0, "ALC3266" },
902 { 0x10ec0256, 0x1028, 0, "ALC3246" }, 903 { 0x10ec0256, 0x1028, 0, "ALC3246" },
904 { 0x10ec0225, 0x1028, 0, "ALC3253" },
903 { 0x10ec0670, 0x1025, 0, "ALC669X" }, 905 { 0x10ec0670, 0x1025, 0, "ALC669X" },
904 { 0x10ec0676, 0x1025, 0, "ALC679X" }, 906 { 0x10ec0676, 0x1025, 0, "ALC679X" },
905 { 0x10ec0282, 0x1043, 0, "ALC3229" }, 907 { 0x10ec0282, 0x1043, 0, "ALC3229" },
@@ -2651,6 +2653,7 @@ enum {
2651 ALC269_TYPE_ALC298, 2653 ALC269_TYPE_ALC298,
2652 ALC269_TYPE_ALC255, 2654 ALC269_TYPE_ALC255,
2653 ALC269_TYPE_ALC256, 2655 ALC269_TYPE_ALC256,
2656 ALC269_TYPE_ALC225,
2654}; 2657};
2655 2658
2656/* 2659/*
@@ -2680,6 +2683,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
2680 case ALC269_TYPE_ALC298: 2683 case ALC269_TYPE_ALC298:
2681 case ALC269_TYPE_ALC255: 2684 case ALC269_TYPE_ALC255:
2682 case ALC269_TYPE_ALC256: 2685 case ALC269_TYPE_ALC256:
2686 case ALC269_TYPE_ALC225:
2683 ssids = alc269_ssids; 2687 ssids = alc269_ssids;
2684 break; 2688 break;
2685 default: 2689 default:
@@ -3658,6 +3662,16 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
3658 WRITE_COEF(0xb7, 0x802b), 3662 WRITE_COEF(0xb7, 0x802b),
3659 {} 3663 {}
3660 }; 3664 };
3665 static struct coef_fw coef0225[] = {
3666 UPDATE_COEF(0x4a, 1<<8, 0),
3667 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
3668 UPDATE_COEF(0x63, 3<<14, 3<<14),
3669 UPDATE_COEF(0x4a, 3<<4, 2<<4),
3670 UPDATE_COEF(0x4a, 3<<10, 3<<10),
3671 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
3672 UPDATE_COEF(0x4a, 3<<10, 0),
3673 {}
3674 };
3661 3675
3662 switch (codec->core.vendor_id) { 3676 switch (codec->core.vendor_id) {
3663 case 0x10ec0255: 3677 case 0x10ec0255:
@@ -3682,6 +3696,9 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
3682 case 0x10ec0668: 3696 case 0x10ec0668:
3683 alc_process_coef_fw(codec, coef0668); 3697 alc_process_coef_fw(codec, coef0668);
3684 break; 3698 break;
3699 case 0x10ec0225:
3700 alc_process_coef_fw(codec, coef0225);
3701 break;
3685 } 3702 }
3686 codec_dbg(codec, "Headset jack set to unplugged mode.\n"); 3703 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
3687} 3704}
@@ -3727,6 +3744,13 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
3727 UPDATE_COEF(0xc3, 0, 1<<12), 3744 UPDATE_COEF(0xc3, 0, 1<<12),
3728 {} 3745 {}
3729 }; 3746 };
3747 static struct coef_fw coef0225[] = {
3748 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
3749 UPDATE_COEF(0x4a, 3<<4, 2<<4),
3750 UPDATE_COEF(0x63, 3<<14, 0),
3751 {}
3752 };
3753
3730 3754
3731 switch (codec->core.vendor_id) { 3755 switch (codec->core.vendor_id) {
3732 case 0x10ec0255: 3756 case 0x10ec0255:
@@ -3772,6 +3796,12 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
3772 alc_process_coef_fw(codec, coef0688); 3796 alc_process_coef_fw(codec, coef0688);
3773 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 3797 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3774 break; 3798 break;
3799 case 0x10ec0225:
3800 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
3801 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3802 alc_process_coef_fw(codec, coef0225);
3803 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3804 break;
3775 } 3805 }
3776 codec_dbg(codec, "Headset jack set to mic-in mode.\n"); 3806 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
3777} 3807}
@@ -3884,6 +3914,13 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
3884 WRITE_COEF(0xc3, 0x0000), 3914 WRITE_COEF(0xc3, 0x0000),
3885 {} 3915 {}
3886 }; 3916 };
3917 static struct coef_fw coef0225[] = {
3918 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
3919 UPDATE_COEF(0x49, 1<<8, 1<<8),
3920 UPDATE_COEF(0x4a, 7<<6, 7<<6),
3921 UPDATE_COEF(0x4a, 3<<4, 3<<4),
3922 {}
3923 };
3887 3924
3888 switch (codec->core.vendor_id) { 3925 switch (codec->core.vendor_id) {
3889 case 0x10ec0255: 3926 case 0x10ec0255:
@@ -3912,6 +3949,9 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
3912 case 0x10ec0668: 3949 case 0x10ec0668:
3913 alc_process_coef_fw(codec, coef0688); 3950 alc_process_coef_fw(codec, coef0688);
3914 break; 3951 break;
3952 case 0x10ec0225:
3953 alc_process_coef_fw(codec, coef0225);
3954 break;
3915 } 3955 }
3916 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); 3956 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
3917} 3957}
@@ -3955,6 +3995,13 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
3955 WRITE_COEF(0xc3, 0x0000), 3995 WRITE_COEF(0xc3, 0x0000),
3956 {} 3996 {}
3957 }; 3997 };
3998 static struct coef_fw coef0225[] = {
3999 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
4000 UPDATE_COEF(0x49, 1<<8, 1<<8),
4001 UPDATE_COEF(0x4a, 7<<6, 7<<6),
4002 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4003 {}
4004 };
3958 4005
3959 switch (codec->core.vendor_id) { 4006 switch (codec->core.vendor_id) {
3960 case 0x10ec0255: 4007 case 0x10ec0255:
@@ -3983,6 +4030,9 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
3983 case 0x10ec0668: 4030 case 0x10ec0668:
3984 alc_process_coef_fw(codec, coef0688); 4031 alc_process_coef_fw(codec, coef0688);
3985 break; 4032 break;
4033 case 0x10ec0225:
4034 alc_process_coef_fw(codec, coef0225);
4035 break;
3986 } 4036 }
3987 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); 4037 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
3988} 4038}
@@ -4014,6 +4064,11 @@ static void alc_determine_headset_type(struct hda_codec *codec)
4014 WRITE_COEF(0xc3, 0x0c00), 4064 WRITE_COEF(0xc3, 0x0c00),
4015 {} 4065 {}
4016 }; 4066 };
4067 static struct coef_fw coef0225[] = {
4068 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4069 UPDATE_COEF(0x49, 1<<8, 1<<8),
4070 {}
4071 };
4017 4072
4018 switch (codec->core.vendor_id) { 4073 switch (codec->core.vendor_id) {
4019 case 0x10ec0255: 4074 case 0x10ec0255:
@@ -4058,6 +4113,12 @@ static void alc_determine_headset_type(struct hda_codec *codec)
4058 val = alc_read_coef_idx(codec, 0xbe); 4113 val = alc_read_coef_idx(codec, 0xbe);
4059 is_ctia = (val & 0x1c02) == 0x1c02; 4114 is_ctia = (val & 0x1c02) == 0x1c02;
4060 break; 4115 break;
4116 case 0x10ec0225:
4117 alc_process_coef_fw(codec, coef0225);
4118 msleep(800);
4119 val = alc_read_coef_idx(codec, 0x46);
4120 is_ctia = (val & 0x00f0) == 0x00f0;
4121 break;
4061 } 4122 }
4062 4123
4063 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n", 4124 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
@@ -5560,6 +5621,9 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
5560 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"}, 5621 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
5561 {} 5622 {}
5562}; 5623};
5624#define ALC225_STANDARD_PINS \
5625 {0x12, 0xb7a60130}, \
5626 {0x21, 0x04211020}
5563 5627
5564#define ALC256_STANDARD_PINS \ 5628#define ALC256_STANDARD_PINS \
5565 {0x12, 0x90a60140}, \ 5629 {0x12, 0x90a60140}, \
@@ -5581,6 +5645,12 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
5581 {0x21, 0x03211020} 5645 {0x21, 0x03211020}
5582 5646
5583static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { 5647static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
5648 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5649 ALC225_STANDARD_PINS,
5650 {0x14, 0x901701a0}),
5651 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5652 ALC225_STANDARD_PINS,
5653 {0x14, 0x901701b0}),
5584 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, 5654 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
5585 {0x14, 0x90170110}, 5655 {0x14, 0x90170110},
5586 {0x21, 0x02211020}), 5656 {0x21, 0x02211020}),
@@ -5906,6 +5976,9 @@ static int patch_alc269(struct hda_codec *codec)
5906 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */ 5976 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
5907 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/ 5977 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
5908 break; 5978 break;
5979 case 0x10ec0225:
5980 spec->codec_variant = ALC269_TYPE_ALC225;
5981 break;
5909 } 5982 }
5910 5983
5911 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { 5984 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
@@ -6796,6 +6869,7 @@ static int patch_alc680(struct hda_codec *codec)
6796 */ 6869 */
6797static const struct hda_device_id snd_hda_id_realtek[] = { 6870static const struct hda_device_id snd_hda_id_realtek[] = {
6798 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269), 6871 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
6872 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
6799 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269), 6873 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
6800 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269), 6874 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
6801 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269), 6875 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index a75d9ce7d77a..4f6ce1cac8e2 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1121,6 +1121,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
1121 switch (chip->usb_id) { 1121 switch (chip->usb_id) {
1122 case USB_ID(0x045E, 0x075D): /* MS Lifecam Cinema */ 1122 case USB_ID(0x045E, 0x075D): /* MS Lifecam Cinema */
1123 case USB_ID(0x045E, 0x076D): /* MS Lifecam HD-5000 */ 1123 case USB_ID(0x045E, 0x076D): /* MS Lifecam HD-5000 */
1124 case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */
1124 case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */ 1125 case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */
1125 case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */ 1126 case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */
1126 case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ 1127 case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
@@ -1281,7 +1282,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
1281 case USB_ID(0x20b1, 0x3008): /* iFi Audio micro/nano iDSD */ 1282 case USB_ID(0x20b1, 0x3008): /* iFi Audio micro/nano iDSD */
1282 case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */ 1283 case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */
1283 case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */ 1284 case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */
1284 case USB_ID(0x22d8, 0x0416): /* OPPO HA-1*/ 1285 case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */
1285 if (fp->altsetting == 2) 1286 if (fp->altsetting == 2)
1286 return SNDRV_PCM_FMTBIT_DSD_U32_BE; 1287 return SNDRV_PCM_FMTBIT_DSD_U32_BE;
1287 break; 1288 break;
@@ -1290,6 +1291,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
1290 case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */ 1291 case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */
1291 case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */ 1292 case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */
1292 case USB_ID(0x20b1, 0x3023): /* Aune X1S 32BIT/384 DSD DAC */ 1293 case USB_ID(0x20b1, 0x3023): /* Aune X1S 32BIT/384 DSD DAC */
1294 case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */
1293 if (fp->altsetting == 3) 1295 if (fp->altsetting == 3)
1294 return SNDRV_PCM_FMTBIT_DSD_U32_BE; 1296 return SNDRV_PCM_FMTBIT_DSD_U32_BE;
1295 break; 1297 break;