Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+489 -185
+4
include/sound/rawmidi.h
··· 167 167 int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count); 168 168 int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, 169 169 unsigned char *buffer, int count); 170 + int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, 171 + unsigned char *buffer, int count); 172 + int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, 173 + int count); 170 174 171 175 /* main midi functions */ 172 176
+15 -6
sound/core/oss/pcm_oss.c
··· 835 835 return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL); 836 836 } 837 837 838 - static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) 838 + static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, 839 + bool trylock) 839 840 { 840 841 struct snd_pcm_runtime *runtime = substream->runtime; 841 842 struct snd_pcm_hw_params *params, *sparams; ··· 850 849 struct snd_mask sformat_mask; 851 850 struct snd_mask mask; 852 851 853 - if (mutex_lock_interruptible(&runtime->oss.params_lock)) 852 + if (trylock) { 853 + if (!(mutex_trylock(&runtime->oss.params_lock))) 854 + return -EAGAIN; 855 + } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) 854 856 return -EINTR; 855 857 sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); 856 858 params = kmalloc(sizeof(*params), GFP_KERNEL); ··· 1096 1092 if (asubstream == NULL) 1097 1093 asubstream = substream; 1098 1094 if (substream->runtime->oss.params) { 1099 - err = snd_pcm_oss_change_params(substream); 1095 + err = snd_pcm_oss_change_params(substream, false); 1100 1096 if (err < 0) 1101 1097 return err; 1102 1098 } ··· 1136 1132 return 0; 1137 1133 runtime = substream->runtime; 1138 1134 if (runtime->oss.params) { 1139 - err = snd_pcm_oss_change_params(substream); 1135 + err = snd_pcm_oss_change_params(substream, false); 1140 1136 if (err < 0) 1141 1137 return err; 1142 1138 } ··· 2167 2163 runtime = substream->runtime; 2168 2164 2169 2165 if (runtime->oss.params && 2170 - (err = snd_pcm_oss_change_params(substream)) < 0) 2166 + (err = snd_pcm_oss_change_params(substream, false)) < 0) 2171 2167 return err; 2172 2168 2173 2169 info.fragsize = runtime->oss.period_bytes; ··· 2808 2804 return -EIO; 2809 2805 2810 2806 if (runtime->oss.params) { 2811 - if ((err = snd_pcm_oss_change_params(substream)) < 0) 2807 + /* use mutex_trylock() for params_lock for avoiding a deadlock 2808 + * between mmap_sem and params_lock taken by 2809 + * copy_from/to_user() in snd_pcm_oss_write/read() 2810 + */ 2811 + err = snd_pcm_oss_change_params(substream, true); 2812 + if (err < 0) 2812 2813 return err; 2813 2814 } 2814 2815 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
+101 -45
sound/core/rawmidi.c
··· 942 942 unsigned long flags; 943 943 long result = 0, count1; 944 944 struct snd_rawmidi_runtime *runtime = substream->runtime; 945 + unsigned long appl_ptr; 945 946 947 + spin_lock_irqsave(&runtime->lock, flags); 946 948 while (count > 0 && runtime->avail) { 947 949 count1 = runtime->buffer_size - runtime->appl_ptr; 948 950 if (count1 > count) 949 951 count1 = count; 950 - spin_lock_irqsave(&runtime->lock, flags); 951 952 if (count1 > (int)runtime->avail) 952 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 961 if (kernelbuf) 954 - memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1); 962 + memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1); 955 963 if (userbuf) { 956 964 spin_unlock_irqrestore(&runtime->lock, flags); 957 965 if (copy_to_user(userbuf + result, 958 - runtime->buffer + runtime->appl_ptr, count1)) { 966 + runtime->buffer + appl_ptr, count1)) { 959 967 return result > 0 ? result : -EFAULT; 960 968 } 961 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 971 result += count1; 968 972 count -= count1; 969 973 } 974 + spin_unlock_irqrestore(&runtime->lock, flags); 970 975 return result; 971 976 } 972 977 ··· 1060 1055 EXPORT_SYMBOL(snd_rawmidi_transmit_empty); 1061 1056 1062 1057 /** 1063 - * snd_rawmidi_transmit_peek - copy data from the internal buffer 1058 + * __snd_rawmidi_transmit_peek - copy data from the internal buffer 1064 1059 * @substream: the rawmidi substream 1065 1060 * @buffer: the buffer pointer 1066 1061 * @count: data size to transfer 1067 1062 * 1068 - * Copies data from the internal output buffer to the given buffer. 1069 - * 1070 - * Call this in the interrupt handler when the midi output is ready, 1071 - * and call snd_rawmidi_transmit_ack() after the transmission is 1072 - * finished. 1073 - * 1074 - * Return: The size of copied data, or a negative error code on failure. 1063 + * This is a variant of snd_rawmidi_transmit_peek() without spinlock. 1075 1064 */ 1076 - int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, 1065 + int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, 1077 1066 unsigned char *buffer, int count) 1078 1067 { 1079 - unsigned long flags; 1080 1068 int result, count1; 1081 1069 struct snd_rawmidi_runtime *runtime = substream->runtime; 1082 1070 ··· 1079 1081 return -EINVAL; 1080 1082 } 1081 1083 result = 0; 1082 - spin_lock_irqsave(&runtime->lock, flags); 1083 1084 if (runtime->avail >= runtime->buffer_size) { 1084 1085 /* warning: lowlevel layer MUST trigger down the hardware */ 1085 1086 goto __skip; ··· 1103 1106 } 1104 1107 } 1105 1108 __skip: 1109 + return result; 1110 + } 1111 + EXPORT_SYMBOL(__snd_rawmidi_transmit_peek); 1112 + 1113 + /** 1114 + * snd_rawmidi_transmit_peek - copy data from the internal buffer 1115 + * @substream: the rawmidi substream 1116 + * @buffer: the buffer pointer 1117 + * @count: data size to transfer 1118 + * 1119 + * Copies data from the internal output buffer to the given buffer. 1120 + * 1121 + * Call this in the interrupt handler when the midi output is ready, 1122 + * and call snd_rawmidi_transmit_ack() after the transmission is 1123 + * finished. 1124 + * 1125 + * Return: The size of copied data, or a negative error code on failure. 1126 + */ 1127 + int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, 1128 + unsigned char *buffer, int count) 1129 + { 1130 + struct snd_rawmidi_runtime *runtime = substream->runtime; 1131 + int result; 1132 + unsigned long flags; 1133 + 1134 + spin_lock_irqsave(&runtime->lock, flags); 1135 + result = __snd_rawmidi_transmit_peek(substream, buffer, count); 1106 1136 spin_unlock_irqrestore(&runtime->lock, flags); 1107 1137 return result; 1108 1138 } 1109 1139 EXPORT_SYMBOL(snd_rawmidi_transmit_peek); 1140 + 1141 + /** 1142 + * __snd_rawmidi_transmit_ack - acknowledge the transmission 1143 + * @substream: the rawmidi substream 1144 + * @count: the transferred count 1145 + * 1146 + * This is a variant of __snd_rawmidi_transmit_ack() without spinlock. 1147 + */ 1148 + int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) 1149 + { 1150 + struct snd_rawmidi_runtime *runtime = substream->runtime; 1151 + 1152 + if (runtime->buffer == NULL) { 1153 + rmidi_dbg(substream->rmidi, 1154 + "snd_rawmidi_transmit_ack: output is not active!!!\n"); 1155 + return -EINVAL; 1156 + } 1157 + snd_BUG_ON(runtime->avail + count > runtime->buffer_size); 1158 + runtime->hw_ptr += count; 1159 + runtime->hw_ptr %= runtime->buffer_size; 1160 + runtime->avail += count; 1161 + substream->bytes += count; 1162 + if (count > 0) { 1163 + if (runtime->drain || snd_rawmidi_ready(substream)) 1164 + wake_up(&runtime->sleep); 1165 + } 1166 + return count; 1167 + } 1168 + EXPORT_SYMBOL(__snd_rawmidi_transmit_ack); 1110 1169 1111 1170 /** 1112 1171 * snd_rawmidi_transmit_ack - acknowledge the transmission ··· 1177 1124 */ 1178 1125 int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) 1179 1126 { 1180 - unsigned long flags; 1181 1127 struct snd_rawmidi_runtime *runtime = substream->runtime; 1128 + int result; 1129 + unsigned long flags; 1182 1130 1183 - if (runtime->buffer == NULL) { 1184 - rmidi_dbg(substream->rmidi, 1185 - "snd_rawmidi_transmit_ack: output is not active!!!\n"); 1186 - return -EINVAL; 1187 - } 1188 1131 spin_lock_irqsave(&runtime->lock, flags); 1189 - snd_BUG_ON(runtime->avail + count > runtime->buffer_size); 1190 - runtime->hw_ptr += count; 1191 - runtime->hw_ptr %= runtime->buffer_size; 1192 - runtime->avail += count; 1193 - substream->bytes += count; 1194 - if (count > 0) { 1195 - if (runtime->drain || snd_rawmidi_ready(substream)) 1196 - wake_up(&runtime->sleep); 1197 - } 1132 + result = __snd_rawmidi_transmit_ack(substream, count); 1198 1133 spin_unlock_irqrestore(&runtime->lock, flags); 1199 - return count; 1134 + return result; 1200 1135 } 1201 1136 EXPORT_SYMBOL(snd_rawmidi_transmit_ack); 1202 1137 ··· 1201 1160 int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, 1202 1161 unsigned char *buffer, int count) 1203 1162 { 1163 + struct snd_rawmidi_runtime *runtime = substream->runtime; 1164 + int result; 1165 + unsigned long flags; 1166 + 1167 + spin_lock_irqsave(&runtime->lock, flags); 1204 1168 if (!substream->opened) 1205 - return -EBADFD; 1206 - count = snd_rawmidi_transmit_peek(substream, buffer, count); 1207 - if (count < 0) 1208 - return count; 1209 - return snd_rawmidi_transmit_ack(substream, count); 1169 + result = -EBADFD; 1170 + else { 1171 + count = __snd_rawmidi_transmit_peek(substream, buffer, count); 1172 + if (count <= 0) 1173 + result = count; 1174 + else 1175 + result = __snd_rawmidi_transmit_ack(substream, count); 1176 + } 1177 + spin_unlock_irqrestore(&runtime->lock, flags); 1178 + return result; 1210 1179 } 1211 1180 EXPORT_SYMBOL(snd_rawmidi_transmit); 1212 1181 ··· 1228 1177 unsigned long flags; 1229 1178 long count1, result; 1230 1179 struct snd_rawmidi_runtime *runtime = substream->runtime; 1180 + unsigned long appl_ptr; 1231 1181 1232 - if (snd_BUG_ON(!kernelbuf && !userbuf)) 1182 + if (!kernelbuf && !userbuf) 1233 1183 return -EINVAL; 1234 1184 if (snd_BUG_ON(!runtime->buffer)) 1235 1185 return -EINVAL; ··· 1249 1197 count1 = count; 1250 1198 if (count1 > (long)runtime->avail) 1251 1199 count1 = runtime->avail; 1200 + 1201 + /* update runtime->appl_ptr before unlocking for userbuf */ 1202 + appl_ptr = runtime->appl_ptr; 1203 + runtime->appl_ptr += count1; 1204 + runtime->appl_ptr %= runtime->buffer_size; 1205 + runtime->avail -= count1; 1206 + 1252 1207 if (kernelbuf) 1253 - memcpy(runtime->buffer + runtime->appl_ptr, 1208 + memcpy(runtime->buffer + appl_ptr, 1254 1209 kernelbuf + result, count1); 1255 1210 else if (userbuf) { 1256 1211 spin_unlock_irqrestore(&runtime->lock, flags); 1257 - if (copy_from_user(runtime->buffer + runtime->appl_ptr, 1212 + if (copy_from_user(runtime->buffer + appl_ptr, 1258 1213 userbuf + result, count1)) { 1259 1214 spin_lock_irqsave(&runtime->lock, flags); 1260 1215 result = result > 0 ? result : -EFAULT; ··· 1269 1210 } 1270 1211 spin_lock_irqsave(&runtime->lock, flags); 1271 1212 } 1272 - runtime->appl_ptr += count1; 1273 - runtime->appl_ptr %= runtime->buffer_size; 1274 - runtime->avail -= count1; 1275 1213 result += count1; 1276 1214 count -= count1; 1277 1215 }
+3
sound/core/seq/seq_clientmgr.c
··· 678 678 else 679 679 down_read(&grp->list_mutex); 680 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 684 event->dest = subs->info.dest; 682 685 if (subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) 683 686 /* convert time according to flag with subscription */
+130 -103
sound/core/seq/seq_ports.c
··· 173 173 } 174 174 175 175 /* */ 176 - enum group_type { 177 - SRC_LIST, DEST_LIST 178 - }; 179 - 180 176 static int subscribe_port(struct snd_seq_client *client, 181 177 struct snd_seq_client_port *port, 182 178 struct snd_seq_port_subs_info *grp, ··· 199 203 return NULL; 200 204 } 201 205 206 + static void delete_and_unsubscribe_port(struct snd_seq_client *client, 207 + struct snd_seq_client_port *port, 208 + struct snd_seq_subscribers *subs, 209 + bool is_src, bool ack); 210 + 211 + static inline struct snd_seq_subscribers * 212 + get_subscriber(struct list_head *p, bool is_src) 213 + { 214 + if (is_src) 215 + return list_entry(p, struct snd_seq_subscribers, src_list); 216 + else 217 + return list_entry(p, struct snd_seq_subscribers, dest_list); 218 + } 219 + 202 220 /* 203 221 * remove all subscribers on the list 204 222 * this is called from port_delete, for each src and dest list. ··· 220 210 static void clear_subscriber_list(struct snd_seq_client *client, 221 211 struct snd_seq_client_port *port, 222 212 struct snd_seq_port_subs_info *grp, 223 - int grptype) 213 + int is_src) 224 214 { 225 215 struct list_head *p, *n; 226 216 ··· 229 219 struct snd_seq_client *c; 230 220 struct snd_seq_client_port *aport; 231 221 232 - if (grptype == SRC_LIST) { 233 - subs = list_entry(p, struct snd_seq_subscribers, src_list); 222 + subs = get_subscriber(p, is_src); 223 + if (is_src) 234 224 aport = get_client_port(&subs->info.dest, &c); 235 - } else { 236 - subs = list_entry(p, struct snd_seq_subscribers, dest_list); 225 + else 237 226 aport = get_client_port(&subs->info.sender, &c); 238 - } 239 - list_del(p); 240 - unsubscribe_port(client, port, grp, &subs->info, 0); 227 + delete_and_unsubscribe_port(client, port, subs, is_src, false); 228 + 241 229 if (!aport) { 242 230 /* looks like the connected port is being deleted. 243 231 * we decrease the counter, and when both ports are deleted ··· 243 235 */ 244 236 if (atomic_dec_and_test(&subs->ref_count)) 245 237 kfree(subs); 246 - } else { 247 - /* ok we got the connected port */ 248 - struct snd_seq_port_subs_info *agrp; 249 - agrp = (grptype == SRC_LIST) ? &aport->c_dest : &aport->c_src; 250 - down_write(&agrp->list_mutex); 251 - if (grptype == SRC_LIST) 252 - list_del(&subs->dest_list); 253 - else 254 - list_del(&subs->src_list); 255 - up_write(&agrp->list_mutex); 256 - unsubscribe_port(c, aport, agrp, &subs->info, 1); 257 - kfree(subs); 258 - snd_seq_port_unlock(aport); 259 - snd_seq_client_unlock(c); 238 + continue; 260 239 } 240 + 241 + /* ok we got the connected port */ 242 + delete_and_unsubscribe_port(c, aport, subs, !is_src, true); 243 + kfree(subs); 244 + snd_seq_port_unlock(aport); 245 + snd_seq_client_unlock(c); 261 246 } 262 247 } 263 248 ··· 263 262 snd_use_lock_sync(&port->use_lock); 264 263 265 264 /* clear subscribers info */ 266 - clear_subscriber_list(client, port, &port->c_src, SRC_LIST); 267 - clear_subscriber_list(client, port, &port->c_dest, DEST_LIST); 265 + clear_subscriber_list(client, port, &port->c_src, true); 266 + clear_subscriber_list(client, port, &port->c_dest, false); 268 267 269 268 if (port->private_free) 270 269 port->private_free(port->private_data); ··· 480 479 return 0; 481 480 } 482 481 482 + static int check_and_subscribe_port(struct snd_seq_client *client, 483 + struct snd_seq_client_port *port, 484 + struct snd_seq_subscribers *subs, 485 + bool is_src, bool exclusive, bool ack) 486 + { 487 + struct snd_seq_port_subs_info *grp; 488 + struct list_head *p; 489 + struct snd_seq_subscribers *s; 490 + int err; 491 + 492 + grp = is_src ? &port->c_src : &port->c_dest; 493 + err = -EBUSY; 494 + down_write(&grp->list_mutex); 495 + if (exclusive) { 496 + if (!list_empty(&grp->list_head)) 497 + goto __error; 498 + } else { 499 + if (grp->exclusive) 500 + goto __error; 501 + /* check whether already exists */ 502 + list_for_each(p, &grp->list_head) { 503 + s = get_subscriber(p, is_src); 504 + if (match_subs_info(&subs->info, &s->info)) 505 + goto __error; 506 + } 507 + } 508 + 509 + err = subscribe_port(client, port, grp, &subs->info, ack); 510 + if (err < 0) { 511 + grp->exclusive = 0; 512 + goto __error; 513 + } 514 + 515 + /* add to list */ 516 + write_lock_irq(&grp->list_lock); 517 + if (is_src) 518 + list_add_tail(&subs->src_list, &grp->list_head); 519 + else 520 + list_add_tail(&subs->dest_list, &grp->list_head); 521 + grp->exclusive = exclusive; 522 + atomic_inc(&subs->ref_count); 523 + write_unlock_irq(&grp->list_lock); 524 + err = 0; 525 + 526 + __error: 527 + up_write(&grp->list_mutex); 528 + return err; 529 + } 530 + 531 + static void delete_and_unsubscribe_port(struct snd_seq_client *client, 532 + struct snd_seq_client_port *port, 533 + struct snd_seq_subscribers *subs, 534 + bool is_src, bool ack) 535 + { 536 + struct snd_seq_port_subs_info *grp; 537 + 538 + grp = is_src ? &port->c_src : &port->c_dest; 539 + down_write(&grp->list_mutex); 540 + write_lock_irq(&grp->list_lock); 541 + if (is_src) 542 + list_del(&subs->src_list); 543 + else 544 + list_del(&subs->dest_list); 545 + grp->exclusive = 0; 546 + write_unlock_irq(&grp->list_lock); 547 + up_write(&grp->list_mutex); 548 + 549 + unsubscribe_port(client, port, grp, &subs->info, ack); 550 + } 483 551 484 552 /* connect two ports */ 485 553 int snd_seq_port_connect(struct snd_seq_client *connector, ··· 558 488 struct snd_seq_client_port *dest_port, 559 489 struct snd_seq_port_subscribe *info) 560 490 { 561 - struct snd_seq_port_subs_info *src = &src_port->c_src; 562 - struct snd_seq_port_subs_info *dest = &dest_port->c_dest; 563 - struct snd_seq_subscribers *subs, *s; 564 - int err, src_called = 0; 565 - unsigned long flags; 566 - int exclusive; 491 + struct snd_seq_subscribers *subs; 492 + bool exclusive; 493 + int err; 567 494 568 495 subs = kzalloc(sizeof(*subs), GFP_KERNEL); 569 - if (! subs) 496 + if (!subs) 570 497 return -ENOMEM; 571 498 572 499 subs->info = *info; 573 - atomic_set(&subs->ref_count, 2); 500 + atomic_set(&subs->ref_count, 0); 501 + INIT_LIST_HEAD(&subs->src_list); 502 + INIT_LIST_HEAD(&subs->dest_list); 574 503 575 - down_write(&src->list_mutex); 576 - down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING); 504 + exclusive = !!(info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE); 577 505 578 - exclusive = info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE ? 1 : 0; 579 - err = -EBUSY; 580 - if (exclusive) { 581 - if (! list_empty(&src->list_head) || ! list_empty(&dest->list_head)) 582 - goto __error; 583 - } else { 584 - if (src->exclusive || dest->exclusive) 585 - goto __error; 586 - /* check whether already exists */ 587 - list_for_each_entry(s, &src->list_head, src_list) { 588 - if (match_subs_info(info, &s->info)) 589 - goto __error; 590 - } 591 - list_for_each_entry(s, &dest->list_head, dest_list) { 592 - if (match_subs_info(info, &s->info)) 593 - goto __error; 594 - } 595 - } 506 + err = check_and_subscribe_port(src_client, src_port, subs, true, 507 + exclusive, 508 + connector->number != src_client->number); 509 + if (err < 0) 510 + goto error; 511 + err = check_and_subscribe_port(dest_client, dest_port, subs, false, 512 + exclusive, 513 + connector->number != dest_client->number); 514 + if (err < 0) 515 + goto error_dest; 596 516 597 - if ((err = subscribe_port(src_client, src_port, src, info, 598 - connector->number != src_client->number)) < 0) 599 - goto __error; 600 - src_called = 1; 601 - 602 - if ((err = subscribe_port(dest_client, dest_port, dest, info, 603 - connector->number != dest_client->number)) < 0) 604 - goto __error; 605 - 606 - /* add to list */ 607 - write_lock_irqsave(&src->list_lock, flags); 608 - // write_lock(&dest->list_lock); // no other lock yet 609 - list_add_tail(&subs->src_list, &src->list_head); 610 - list_add_tail(&subs->dest_list, &dest->list_head); 611 - // write_unlock(&dest->list_lock); // no other lock yet 612 - write_unlock_irqrestore(&src->list_lock, flags); 613 - 614 - src->exclusive = dest->exclusive = exclusive; 615 - 616 - up_write(&dest->list_mutex); 617 - up_write(&src->list_mutex); 618 517 return 0; 619 518 620 - __error: 621 - if (src_called) 622 - unsubscribe_port(src_client, src_port, src, info, 623 - connector->number != src_client->number); 519 + error_dest: 520 + delete_and_unsubscribe_port(src_client, src_port, subs, true, 521 + connector->number != src_client->number); 522 + error: 624 523 kfree(subs); 625 - up_write(&dest->list_mutex); 626 - up_write(&src->list_mutex); 627 524 return err; 628 525 } 629 - 630 526 631 527 /* remove the connection */ 632 528 int snd_seq_port_disconnect(struct snd_seq_client *connector, ··· 603 567 struct snd_seq_port_subscribe *info) 604 568 { 605 569 struct snd_seq_port_subs_info *src = &src_port->c_src; 606 - struct snd_seq_port_subs_info *dest = &dest_port->c_dest; 607 570 struct snd_seq_subscribers *subs; 608 571 int err = -ENOENT; 609 - unsigned long flags; 610 572 611 573 down_write(&src->list_mutex); 612 - down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING); 613 - 614 574 /* look for the connection */ 615 575 list_for_each_entry(subs, &src->list_head, src_list) { 616 576 if (match_subs_info(info, &subs->info)) { 617 - write_lock_irqsave(&src->list_lock, flags); 618 - // write_lock(&dest->list_lock); // no lock yet 619 - list_del(&subs->src_list); 620 - list_del(&subs->dest_list); 621 - // write_unlock(&dest->list_lock); 622 - write_unlock_irqrestore(&src->list_lock, flags); 623 - src->exclusive = dest->exclusive = 0; 624 - unsubscribe_port(src_client, src_port, src, info, 625 - connector->number != src_client->number); 626 - unsubscribe_port(dest_client, dest_port, dest, info, 627 - connector->number != dest_client->number); 628 - kfree(subs); 577 + atomic_dec(&subs->ref_count); /* mark as not ready */ 629 578 err = 0; 630 579 break; 631 580 } 632 581 } 633 - 634 - up_write(&dest->list_mutex); 635 582 up_write(&src->list_mutex); 636 - return err; 583 + if (err < 0) 584 + return err; 585 + 586 + delete_and_unsubscribe_port(src_client, src_port, subs, true, 587 + connector->number != src_client->number); 588 + delete_and_unsubscribe_port(dest_client, dest_port, subs, false, 589 + connector->number != dest_client->number); 590 + kfree(subs); 591 + return 0; 637 592 } 638 593 639 594
+67 -20
sound/core/seq/seq_timer.c
··· 90 90 91 91 void snd_seq_timer_defaults(struct snd_seq_timer * tmr) 92 92 { 93 + unsigned long flags; 94 + 95 + spin_lock_irqsave(&tmr->lock, flags); 93 96 /* setup defaults */ 94 97 tmr->ppq = 96; /* 96 PPQ */ 95 98 tmr->tempo = 500000; /* 120 BPM */ ··· 108 105 tmr->preferred_resolution = seq_default_timer_resolution; 109 106 110 107 tmr->skew = tmr->skew_base = SKEW_BASE; 108 + spin_unlock_irqrestore(&tmr->lock, flags); 111 109 } 112 110 113 - void snd_seq_timer_reset(struct snd_seq_timer * tmr) 111 + static void seq_timer_reset(struct snd_seq_timer *tmr) 114 112 { 115 - unsigned long flags; 116 - 117 - spin_lock_irqsave(&tmr->lock, flags); 118 - 119 113 /* reset time & songposition */ 120 114 tmr->cur_time.tv_sec = 0; 121 115 tmr->cur_time.tv_nsec = 0; 122 116 123 117 tmr->tick.cur_tick = 0; 124 118 tmr->tick.fraction = 0; 119 + } 125 120 121 + void snd_seq_timer_reset(struct snd_seq_timer *tmr) 122 + { 123 + unsigned long flags; 124 + 125 + spin_lock_irqsave(&tmr->lock, flags); 126 + seq_timer_reset(tmr); 126 127 spin_unlock_irqrestore(&tmr->lock, flags); 127 128 } 128 129 ··· 145 138 tmr = q->timer; 146 139 if (tmr == NULL) 147 140 return; 148 - if (!tmr->running) 141 + spin_lock_irqsave(&tmr->lock, flags); 142 + if (!tmr->running) { 143 + spin_unlock_irqrestore(&tmr->lock, flags); 149 144 return; 145 + } 150 146 151 147 resolution *= ticks; 152 148 if (tmr->skew != tmr->skew_base) { ··· 157 147 resolution = (resolution >> 16) * tmr->skew + 158 148 (((resolution & 0xffff) * tmr->skew) >> 16); 159 149 } 160 - 161 - spin_lock_irqsave(&tmr->lock, flags); 162 150 163 151 /* update timer */ 164 152 snd_seq_inc_time_nsec(&tmr->cur_time, resolution); ··· 304 296 t->callback = snd_seq_timer_interrupt; 305 297 t->callback_data = q; 306 298 t->flags |= SNDRV_TIMER_IFLG_AUTO; 299 + spin_lock_irq(&tmr->lock); 307 300 tmr->timeri = t; 301 + spin_unlock_irq(&tmr->lock); 308 302 return 0; 309 303 } 310 304 311 305 int snd_seq_timer_close(struct snd_seq_queue *q) 312 306 { 313 307 struct snd_seq_timer *tmr; 308 + struct snd_timer_instance *t; 314 309 315 310 tmr = q->timer; 316 311 if (snd_BUG_ON(!tmr)) 317 312 return -EINVAL; 318 - if (tmr->timeri) { 319 - snd_timer_stop(tmr->timeri); 320 - snd_timer_close(tmr->timeri); 321 - tmr->timeri = NULL; 322 - } 313 + spin_lock_irq(&tmr->lock); 314 + t = tmr->timeri; 315 + tmr->timeri = NULL; 316 + spin_unlock_irq(&tmr->lock); 317 + if (t) 318 + snd_timer_close(t); 323 319 return 0; 324 320 } 325 321 326 - int snd_seq_timer_stop(struct snd_seq_timer * tmr) 322 + static int seq_timer_stop(struct snd_seq_timer *tmr) 327 323 { 328 324 if (! tmr->timeri) 329 325 return -EINVAL; ··· 336 324 tmr->running = 0; 337 325 snd_timer_pause(tmr->timeri); 338 326 return 0; 327 + } 328 + 329 + int snd_seq_timer_stop(struct snd_seq_timer *tmr) 330 + { 331 + unsigned long flags; 332 + int err; 333 + 334 + spin_lock_irqsave(&tmr->lock, flags); 335 + err = seq_timer_stop(tmr); 336 + spin_unlock_irqrestore(&tmr->lock, flags); 337 + return err; 339 338 } 340 339 341 340 static int initialize_timer(struct snd_seq_timer *tmr) ··· 381 358 return 0; 382 359 } 383 360 384 - int snd_seq_timer_start(struct snd_seq_timer * tmr) 361 + static int seq_timer_start(struct snd_seq_timer *tmr) 385 362 { 386 363 if (! tmr->timeri) 387 364 return -EINVAL; 388 365 if (tmr->running) 389 - snd_seq_timer_stop(tmr); 390 - snd_seq_timer_reset(tmr); 366 + seq_timer_stop(tmr); 367 + seq_timer_reset(tmr); 391 368 if (initialize_timer(tmr) < 0) 392 369 return -EINVAL; 393 370 snd_timer_start(tmr->timeri, tmr->ticks); ··· 396 373 return 0; 397 374 } 398 375 399 - int snd_seq_timer_continue(struct snd_seq_timer * tmr) 376 + int snd_seq_timer_start(struct snd_seq_timer *tmr) 377 + { 378 + unsigned long flags; 379 + int err; 380 + 381 + spin_lock_irqsave(&tmr->lock, flags); 382 + err = seq_timer_start(tmr); 383 + spin_unlock_irqrestore(&tmr->lock, flags); 384 + return err; 385 + } 386 + 387 + static int seq_timer_continue(struct snd_seq_timer *tmr) 400 388 { 401 389 if (! tmr->timeri) 402 390 return -EINVAL; 403 391 if (tmr->running) 404 392 return -EBUSY; 405 393 if (! tmr->initialized) { 406 - snd_seq_timer_reset(tmr); 394 + seq_timer_reset(tmr); 407 395 if (initialize_timer(tmr) < 0) 408 396 return -EINVAL; 409 397 } ··· 424 390 return 0; 425 391 } 426 392 393 + int snd_seq_timer_continue(struct snd_seq_timer *tmr) 394 + { 395 + unsigned long flags; 396 + int err; 397 + 398 + spin_lock_irqsave(&tmr->lock, flags); 399 + err = seq_timer_continue(tmr); 400 + spin_unlock_irqrestore(&tmr->lock, flags); 401 + return err; 402 + } 403 + 427 404 /* return current 'real' time. use timeofday() to get better granularity. */ 428 405 snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr) 429 406 { 430 407 snd_seq_real_time_t cur_time; 408 + unsigned long flags; 431 409 410 + spin_lock_irqsave(&tmr->lock, flags); 432 411 cur_time = tmr->cur_time; 433 412 if (tmr->running) { 434 413 struct timeval tm; ··· 457 410 } 458 411 snd_seq_sanity_real_time(&cur_time); 459 412 } 460 - 413 + spin_unlock_irqrestore(&tmr->lock, flags); 461 414 return cur_time; 462 415 } 463 416
+17 -6
sound/core/seq/seq_virmidi.c
··· 155 155 struct snd_virmidi *vmidi = substream->runtime->private_data; 156 156 int count, res; 157 157 unsigned char buf[32], *pbuf; 158 + unsigned long flags; 158 159 159 160 if (up) { 160 161 vmidi->trigger = 1; 161 162 if (vmidi->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH && 162 163 !(vmidi->rdev->flags & SNDRV_VIRMIDI_SUBSCRIBE)) { 163 - snd_rawmidi_transmit_ack(substream, substream->runtime->buffer_size - substream->runtime->avail); 164 - return; /* ignored */ 164 + while (snd_rawmidi_transmit(substream, buf, 165 + sizeof(buf)) > 0) { 166 + /* ignored */ 167 + } 168 + return; 165 169 } 166 170 if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { 167 171 if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) 168 172 return; 169 173 vmidi->event.type = SNDRV_SEQ_EVENT_NONE; 170 174 } 175 + spin_lock_irqsave(&substream->runtime->lock, flags); 171 176 while (1) { 172 - count = snd_rawmidi_transmit_peek(substream, buf, sizeof(buf)); 177 + count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf)); 173 178 if (count <= 0) 174 179 break; 175 180 pbuf = buf; ··· 184 179 snd_midi_event_reset_encode(vmidi->parser); 185 180 continue; 186 181 } 187 - snd_rawmidi_transmit_ack(substream, res); 182 + __snd_rawmidi_transmit_ack(substream, res); 188 183 pbuf += res; 189 184 count -= res; 190 185 if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { 191 186 if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) 192 - return; 187 + goto out; 193 188 vmidi->event.type = SNDRV_SEQ_EVENT_NONE; 194 189 } 195 190 } 196 191 } 192 + out: 193 + spin_unlock_irqrestore(&substream->runtime->lock, flags); 197 194 } else { 198 195 vmidi->trigger = 0; 199 196 } ··· 261 254 */ 262 255 static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream) 263 256 { 257 + struct snd_virmidi_dev *rdev = substream->rmidi->private_data; 264 258 struct snd_virmidi *vmidi = substream->runtime->private_data; 265 - snd_midi_event_free(vmidi->parser); 259 + 260 + write_lock_irq(&rdev->filelist_lock); 266 261 list_del(&vmidi->list); 262 + write_unlock_irq(&rdev->filelist_lock); 263 + snd_midi_event_free(vmidi->parser); 267 264 substream->runtime->private_data = NULL; 268 265 kfree(vmidi); 269 266 return 0;
+40 -4
sound/core/timer.c
··· 451 451 unsigned long flags; 452 452 453 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 458 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; 455 459 if (timeri->master && timeri->timer) { 456 460 spin_lock(&timeri->timer->lock); ··· 479 475 return -EINVAL; 480 476 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { 481 477 result = snd_timer_start_slave(timeri); 482 - snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); 478 + if (result >= 0) 479 + snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); 483 480 return result; 484 481 } 485 482 timer = timeri->timer; ··· 489 484 if (timer->card && timer->card->shutdown) 490 485 return -ENODEV; 491 486 spin_lock_irqsave(&timer->lock, flags); 487 + if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | 488 + SNDRV_TIMER_IFLG_START)) { 489 + result = -EBUSY; 490 + goto unlock; 491 + } 492 492 timeri->ticks = timeri->cticks = ticks; 493 493 timeri->pticks = 0; 494 494 result = snd_timer_start1(timer, timeri, ticks); 495 + unlock: 495 496 spin_unlock_irqrestore(&timer->lock, flags); 496 - snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); 497 + if (result >= 0) 498 + snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); 497 499 return result; 498 500 } 499 501 ··· 514 502 515 503 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { 516 504 spin_lock_irqsave(&slave_active_lock, flags); 505 + if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) { 506 + spin_unlock_irqrestore(&slave_active_lock, flags); 507 + return -EBUSY; 508 + } 517 509 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; 518 510 list_del_init(&timeri->ack_list); 519 511 list_del_init(&timeri->active_list); ··· 528 512 if (!timer) 529 513 return -EINVAL; 530 514 spin_lock_irqsave(&timer->lock, flags); 515 + if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | 516 + SNDRV_TIMER_IFLG_START))) { 517 + spin_unlock_irqrestore(&timer->lock, flags); 518 + return -EBUSY; 519 + } 531 520 list_del_init(&timeri->ack_list); 532 521 list_del_init(&timeri->active_list); 533 522 if (timer->card && timer->card->shutdown) { ··· 602 581 if (timer->card && timer->card->shutdown) 603 582 return -ENODEV; 604 583 spin_lock_irqsave(&timer->lock, flags); 584 + if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) { 585 + result = -EBUSY; 586 + goto unlock; 587 + } 605 588 if (!timeri->cticks) 606 589 timeri->cticks = 1; 607 590 timeri->pticks = 0; 608 591 result = snd_timer_start1(timer, timeri, timer->sticks); 592 + unlock: 609 593 spin_unlock_irqrestore(&timer->lock, flags); 610 594 snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE); 611 595 return result; ··· 744 718 ti->cticks = ti->ticks; 745 719 } else { 746 720 ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING; 747 - if (--timer->running) 748 - list_del_init(&ti->active_list); 721 + --timer->running; 722 + list_del_init(&ti->active_list); 749 723 } 750 724 if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || 751 725 (ti->flags & SNDRV_TIMER_IFLG_FAST)) ··· 1058 1032 return 0; 1059 1033 } 1060 1034 1035 + static int snd_timer_s_close(struct snd_timer *timer) 1036 + { 1037 + struct snd_timer_system_private *priv; 1038 + 1039 + priv = (struct snd_timer_system_private *)timer->private_data; 1040 + del_timer_sync(&priv->tlist); 1041 + return 0; 1042 + } 1043 + 1061 1044 static struct snd_timer_hardware snd_timer_system = 1062 1045 { 1063 1046 .flags = SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET, 1064 1047 .resolution = 1000000000L / HZ, 1065 1048 .ticks = 10000000L, 1049 + .close = snd_timer_s_close, 1066 1050 .start = snd_timer_s_start, 1067 1051 .stop = snd_timer_s_stop 1068 1052 };
+8
sound/pci/emu10k1/emu10k1_main.c
··· 1141 1141 emu->emu1010.firmware_thread = 1142 1142 kthread_create(emu1010_firmware_thread, emu, 1143 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 1152 wake_up_process(emu->emu1010.firmware_thread); 1145 1153 } 1146 1154
+27
sound/pci/hda/patch_cirrus.c
··· 614 614 CS4208_MAC_AUTO, 615 615 CS4208_MBA6, 616 616 CS4208_MBP11, 617 + CS4208_MACMINI, 617 618 CS4208_GPIO0, 618 619 }; 619 620 ··· 622 621 { .id = CS4208_GPIO0, .name = "gpio0" }, 623 622 { .id = CS4208_MBA6, .name = "mba6" }, 624 623 { .id = CS4208_MBP11, .name = "mbp11" }, 624 + { .id = CS4208_MACMINI, .name = "macmini" }, 625 625 {} 626 626 }; 627 627 ··· 634 632 /* codec SSID matching */ 635 633 static const struct snd_pci_quirk cs4208_mac_fixup_tbl[] = { 636 634 SND_PCI_QUIRK(0x106b, 0x5e00, "MacBookPro 11,2", CS4208_MBP11), 635 + SND_PCI_QUIRK(0x106b, 0x6c00, "MacMini 7,1", CS4208_MACMINI), 637 636 SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6), 638 637 SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6), 639 638 SND_PCI_QUIRK(0x106b, 0x7b00, "MacBookPro 12,1", CS4208_MBP11), ··· 667 664 if (codec->fixup_id == HDA_FIXUP_ID_NOT_SET) 668 665 codec->fixup_id = CS4208_GPIO0; /* default fixup */ 669 666 snd_hda_apply_fixup(codec, action); 667 + } 668 + 669 + /* MacMini 7,1 has the inverted jack detection */ 670 + static void cs4208_fixup_macmini(struct hda_codec *codec, 671 + const struct hda_fixup *fix, int action) 672 + { 673 + static const struct hda_pintbl pincfgs[] = { 674 + { 0x18, 0x00ab9150 }, /* mic (audio-in) jack: disable detect */ 675 + { 0x21, 0x004be140 }, /* SPDIF: disable detect */ 676 + { } 677 + }; 678 + 679 + if (action == HDA_FIXUP_ACT_PRE_PROBE) { 680 + /* HP pin (0x10) has an inverted detection */ 681 + codec->inv_jack_detect = 1; 682 + /* disable the bogus Mic and SPDIF jack detections */ 683 + snd_hda_apply_pincfgs(codec, pincfgs); 684 + } 670 685 } 671 686 672 687 static int cs4208_spdif_sw_put(struct snd_kcontrol *kcontrol, ··· 727 706 [CS4208_MBP11] = { 728 707 .type = HDA_FIXUP_FUNC, 729 708 .v.func = cs4208_fixup_spdif_switch, 709 + .chained = true, 710 + .chain_id = CS4208_GPIO0, 711 + }, 712 + [CS4208_MACMINI] = { 713 + .type = HDA_FIXUP_FUNC, 714 + .v.func = cs4208_fixup_macmini, 730 715 .chained = true, 731 716 .chain_id = CS4208_GPIO0, 732 717 },
+74
sound/pci/hda/patch_realtek.c
··· 327 327 case 0x10ec0292: 328 328 alc_update_coef_idx(codec, 0x4, 1<<15, 0); 329 329 break; 330 + case 0x10ec0225: 330 331 case 0x10ec0233: 331 332 case 0x10ec0255: 332 333 case 0x10ec0256: ··· 901 900 { 0x10ec0899, 0x1028, 0, "ALC3861" }, 902 901 { 0x10ec0298, 0x1028, 0, "ALC3266" }, 903 902 { 0x10ec0256, 0x1028, 0, "ALC3246" }, 903 + { 0x10ec0225, 0x1028, 0, "ALC3253" }, 904 904 { 0x10ec0670, 0x1025, 0, "ALC669X" }, 905 905 { 0x10ec0676, 0x1025, 0, "ALC679X" }, 906 906 { 0x10ec0282, 0x1043, 0, "ALC3229" }, ··· 2653 2651 ALC269_TYPE_ALC298, 2654 2652 ALC269_TYPE_ALC255, 2655 2653 ALC269_TYPE_ALC256, 2654 + ALC269_TYPE_ALC225, 2656 2655 }; 2657 2656 2658 2657 /* ··· 2683 2680 case ALC269_TYPE_ALC298: 2684 2681 case ALC269_TYPE_ALC255: 2685 2682 case ALC269_TYPE_ALC256: 2683 + case ALC269_TYPE_ALC225: 2686 2684 ssids = alc269_ssids; 2687 2685 break; 2688 2686 default: ··· 3662 3658 WRITE_COEF(0xb7, 0x802b), 3663 3659 {} 3664 3660 }; 3661 + static struct coef_fw coef0225[] = { 3662 + UPDATE_COEF(0x4a, 1<<8, 0), 3663 + UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), 3664 + UPDATE_COEF(0x63, 3<<14, 3<<14), 3665 + UPDATE_COEF(0x4a, 3<<4, 2<<4), 3666 + UPDATE_COEF(0x4a, 3<<10, 3<<10), 3667 + UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10), 3668 + UPDATE_COEF(0x4a, 3<<10, 0), 3669 + {} 3670 + }; 3665 3671 3666 3672 switch (codec->core.vendor_id) { 3667 3673 case 0x10ec0255: ··· 3695 3681 break; 3696 3682 case 0x10ec0668: 3697 3683 alc_process_coef_fw(codec, coef0668); 3684 + break; 3685 + case 0x10ec0225: 3686 + alc_process_coef_fw(codec, coef0225); 3698 3687 break; 3699 3688 } 3700 3689 codec_dbg(codec, "Headset jack set to unplugged mode.\n"); ··· 3744 3727 UPDATE_COEF(0xc3, 0, 1<<12), 3745 3728 {} 3746 3729 }; 3730 + static struct coef_fw coef0225[] = { 3731 + UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), 3732 + UPDATE_COEF(0x4a, 3<<4, 2<<4), 3733 + UPDATE_COEF(0x63, 3<<14, 0), 3734 + {} 3735 + }; 3736 + 3747 3737 3748 3738 switch (codec->core.vendor_id) { 3749 3739 case 0x10ec0255: ··· 3794 3770 alc_write_coef_idx(codec, 0x11, 0x0001); 3795 3771 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 3796 3772 alc_process_coef_fw(codec, coef0688); 3773 + snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 3774 + break; 3775 + case 0x10ec0225: 3776 + alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10); 3777 + snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); 3778 + alc_process_coef_fw(codec, coef0225); 3797 3779 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); 3798 3780 break; 3799 3781 } ··· 3914 3884 WRITE_COEF(0xc3, 0x0000), 3915 3885 {} 3916 3886 }; 3887 + static struct coef_fw coef0225[] = { 3888 + UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10), 3889 + UPDATE_COEF(0x49, 1<<8, 1<<8), 3890 + UPDATE_COEF(0x4a, 7<<6, 7<<6), 3891 + UPDATE_COEF(0x4a, 3<<4, 3<<4), 3892 + {} 3893 + }; 3917 3894 3918 3895 switch (codec->core.vendor_id) { 3919 3896 case 0x10ec0255: ··· 3948 3911 break; 3949 3912 case 0x10ec0668: 3950 3913 alc_process_coef_fw(codec, coef0688); 3914 + break; 3915 + case 0x10ec0225: 3916 + alc_process_coef_fw(codec, coef0225); 3951 3917 break; 3952 3918 } 3953 3919 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); ··· 3995 3955 WRITE_COEF(0xc3, 0x0000), 3996 3956 {} 3997 3957 }; 3958 + static struct coef_fw coef0225[] = { 3959 + UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10), 3960 + UPDATE_COEF(0x49, 1<<8, 1<<8), 3961 + UPDATE_COEF(0x4a, 7<<6, 7<<6), 3962 + UPDATE_COEF(0x4a, 3<<4, 3<<4), 3963 + {} 3964 + }; 3998 3965 3999 3966 switch (codec->core.vendor_id) { 4000 3967 case 0x10ec0255: ··· 4029 3982 break; 4030 3983 case 0x10ec0668: 4031 3984 alc_process_coef_fw(codec, coef0688); 3985 + break; 3986 + case 0x10ec0225: 3987 + alc_process_coef_fw(codec, coef0225); 4032 3988 break; 4033 3989 } 4034 3990 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); ··· 4062 4012 WRITE_COEF(0xb7, 0x802b), 4063 4013 WRITE_COEF(0x15, 0x0d60), 4064 4014 WRITE_COEF(0xc3, 0x0c00), 4015 + {} 4016 + }; 4017 + static struct coef_fw coef0225[] = { 4018 + UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10), 4019 + UPDATE_COEF(0x49, 1<<8, 1<<8), 4065 4020 {} 4066 4021 }; 4067 4022 ··· 4112 4057 msleep(300); 4113 4058 val = alc_read_coef_idx(codec, 0xbe); 4114 4059 is_ctia = (val & 0x1c02) == 0x1c02; 4060 + break; 4061 + case 0x10ec0225: 4062 + alc_process_coef_fw(codec, coef0225); 4063 + msleep(800); 4064 + val = alc_read_coef_idx(codec, 0x46); 4065 + is_ctia = (val & 0x00f0) == 0x00f0; 4115 4066 break; 4116 4067 } 4117 4068 ··· 5621 5560 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"}, 5622 5561 {} 5623 5562 }; 5563 + #define ALC225_STANDARD_PINS \ 5564 + {0x12, 0xb7a60130}, \ 5565 + {0x21, 0x04211020} 5624 5566 5625 5567 #define ALC256_STANDARD_PINS \ 5626 5568 {0x12, 0x90a60140}, \ ··· 5645 5581 {0x21, 0x03211020} 5646 5582 5647 5583 static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { 5584 + SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, 5585 + ALC225_STANDARD_PINS, 5586 + {0x14, 0x901701a0}), 5587 + SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, 5588 + ALC225_STANDARD_PINS, 5589 + {0x14, 0x901701b0}), 5648 5590 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, 5649 5591 {0x14, 0x90170110}, 5650 5592 {0x21, 0x02211020}), ··· 5975 5905 spec->codec_variant = ALC269_TYPE_ALC256; 5976 5906 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */ 5977 5907 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/ 5908 + break; 5909 + case 0x10ec0225: 5910 + spec->codec_variant = ALC269_TYPE_ALC225; 5978 5911 break; 5979 5912 } 5980 5913 ··· 6869 6796 */ 6870 6797 static const struct hda_device_id snd_hda_id_realtek[] = { 6871 6798 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269), 6799 + HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269), 6872 6800 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269), 6873 6801 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269), 6874 6802 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
+3 -1
sound/usb/quirks.c
··· 1121 1121 switch (chip->usb_id) { 1122 1122 case USB_ID(0x045E, 0x075D): /* MS Lifecam Cinema */ 1123 1123 case USB_ID(0x045E, 0x076D): /* MS Lifecam HD-5000 */ 1124 + case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */ 1124 1125 case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */ 1125 1126 case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */ 1126 1127 case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ ··· 1282 1281 case USB_ID(0x20b1, 0x3008): /* iFi Audio micro/nano iDSD */ 1283 1282 case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */ 1284 1283 case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */ 1285 - case USB_ID(0x22d8, 0x0416): /* OPPO HA-1*/ 1284 + case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */ 1286 1285 if (fp->altsetting == 2) 1287 1286 return SNDRV_PCM_FMTBIT_DSD_U32_BE; 1288 1287 break; ··· 1291 1290 case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */ 1292 1291 case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */ 1293 1292 case USB_ID(0x20b1, 0x3023): /* Aune X1S 32BIT/384 DSD DAC */ 1293 + case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */ 1294 1294 if (fp->altsetting == 3) 1295 1295 return SNDRV_PCM_FMTBIT_DSD_U32_BE; 1296 1296 break;