aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-11-06 14:31:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-11-06 14:31:32 -0500
commit3d5a08639fb0e83ca30d20142ec6c1e78d26caf1 (patch)
tree14ca4cd2241e11b158dd717194cff3c917fb3910
parent381e3554750930e0579aa06f78afc9d6215fc62a (diff)
parentf3f9185f3e49c748e952dd579357048a42e89398 (diff)
Merge tag 'sound-3.18-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "This update contains mostly only fixes for Realtek HD-audio codec driver in addition to a long-standing sysfs warning bug fix for USB-audio. One significant fix for Realtek codecs is the update of EAPD init codes. This avoids invalid COEF setups for some codec models and may fix "lost sound" in some cases. The rest are a bit high volume but only new quirks and ALC668-specific COEF tables" * tag 'sound-3.18-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda/realtek - Restore default value for ALC668 ALSA: usb-audio: Fix device_del() sysfs warnings at disconnect ALSA: hda - fix mute led problem for three HP laptops ALSA: hda/realtek - Update Initial AMP for EAPD control ALSA: hda - change three SSID quirks to one pin quirk ALSA: hda - Set GPIO 4 low for a few HP machines ALSA: hda - Add ultra dock support for Thinkpad X240.
-rw-r--r--sound/pci/hda/patch_realtek.c122
-rw-r--r--sound/usb/card.c9
2 files changed, 95 insertions, 36 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index c9cf248ce8ec..da03693099eb 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -291,18 +291,14 @@ static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
291/* additional initialization for ALC888 variants */ 291/* additional initialization for ALC888 variants */
292static void alc888_coef_init(struct hda_codec *codec) 292static void alc888_coef_init(struct hda_codec *codec)
293{ 293{
294 if (alc_get_coef0(codec) == 0x20) 294 switch (alc_get_coef0(codec) & 0x00f0) {
295 /* alc888S-VC */ 295 /* alc888-VA */
296 alc_write_coef_idx(codec, 7, 0x830); 296 case 0x00:
297 else 297 /* alc888-VB */
298 /* alc888-VB */ 298 case 0x10:
299 alc_write_coef_idx(codec, 7, 0x3030); 299 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
300} 300 break;
301 301 }
302/* additional initialization for ALC889 variants */
303static void alc889_coef_init(struct hda_codec *codec)
304{
305 alc_update_coef_idx(codec, 7, 0, 0x2010);
306} 302}
307 303
308/* turn on/off EAPD control (only if available) */ 304/* turn on/off EAPD control (only if available) */
@@ -359,25 +355,15 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
359 case 0x10ec0260: 355 case 0x10ec0260:
360 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010); 356 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
361 break; 357 break;
362 case 0x10ec0262:
363 case 0x10ec0880: 358 case 0x10ec0880:
364 case 0x10ec0882: 359 case 0x10ec0882:
365 case 0x10ec0883: 360 case 0x10ec0883:
366 case 0x10ec0885: 361 case 0x10ec0885:
367 case 0x10ec0887: 362 alc_update_coef_idx(codec, 7, 0, 0x2030);
368 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
369 case 0x10ec0900:
370 alc889_coef_init(codec);
371 break; 363 break;
372 case 0x10ec0888: 364 case 0x10ec0888:
373 alc888_coef_init(codec); 365 alc888_coef_init(codec);
374 break; 366 break;
375#if 0 /* XXX: This may cause the silent output on speaker on some machines */
376 case 0x10ec0267:
377 case 0x10ec0268:
378 alc_update_coef_idx(codec, 7, 0, 0x3000);
379 break;
380#endif /* XXX */
381 } 367 }
382 break; 368 break;
383 } 369 }
@@ -1710,7 +1696,7 @@ static void alc889_fixup_coef(struct hda_codec *codec,
1710{ 1696{
1711 if (action != HDA_FIXUP_ACT_INIT) 1697 if (action != HDA_FIXUP_ACT_INIT)
1712 return; 1698 return;
1713 alc889_coef_init(codec); 1699 alc_update_coef_idx(codec, 7, 0, 0x2030);
1714} 1700}
1715 1701
1716/* toggle speaker-output according to the hp-jack state */ 1702/* toggle speaker-output according to the hp-jack state */
@@ -3350,6 +3336,27 @@ static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
3350 } 3336 }
3351} 3337}
3352 3338
3339static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
3340 const struct hda_fixup *fix, int action)
3341{
3342 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */
3343 struct alc_spec *spec = codec->spec;
3344 static const struct hda_verb gpio_init[] = {
3345 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3346 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3347 {}
3348 };
3349
3350 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3351 spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook;
3352 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3353 spec->gpio_led = 0;
3354 spec->cap_mute_led_nid = 0x18;
3355 snd_hda_add_verbs(codec, gpio_init);
3356 codec->power_filter = led_power_filter;
3357 }
3358}
3359
3353static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, 3360static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
3354 const struct hda_fixup *fix, int action) 3361 const struct hda_fixup *fix, int action)
3355{ 3362{
@@ -4217,6 +4224,7 @@ enum {
4217 ALC283_FIXUP_BXBT2807_MIC, 4224 ALC283_FIXUP_BXBT2807_MIC,
4218 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, 4225 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
4219 ALC282_FIXUP_ASPIRE_V5_PINS, 4226 ALC282_FIXUP_ASPIRE_V5_PINS,
4227 ALC280_FIXUP_HP_GPIO4,
4220}; 4228};
4221 4229
4222static const struct hda_fixup alc269_fixups[] = { 4230static const struct hda_fixup alc269_fixups[] = {
@@ -4680,7 +4688,10 @@ static const struct hda_fixup alc269_fixups[] = {
4680 { }, 4688 { },
4681 }, 4689 },
4682 }, 4690 },
4683 4691 [ALC280_FIXUP_HP_GPIO4] = {
4692 .type = HDA_FIXUP_FUNC,
4693 .v.func = alc280_fixup_hp_gpio4,
4694 },
4684}; 4695};
4685 4696
4686static const struct snd_pci_quirk alc269_fixup_tbl[] = { 4697static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -4728,21 +4739,16 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4728 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 4739 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4729 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4740 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4730 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4741 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4731 SND_PCI_QUIRK(0x103c, 0x8004, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4732 /* ALC290 */ 4742 /* ALC290 */
4733 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4743 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4734 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4744 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4735 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4745 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4736 SND_PCI_QUIRK(0x103c, 0x2246, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4746 SND_PCI_QUIRK(0x103c, 0x2246, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4737 SND_PCI_QUIRK(0x103c, 0x2247, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4738 SND_PCI_QUIRK(0x103c, 0x2248, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4739 SND_PCI_QUIRK(0x103c, 0x2249, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4740 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4747 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4741 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4748 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4742 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4749 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4743 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4750 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4744 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4751 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4745 SND_PCI_QUIRK(0x103c, 0x2258, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4746 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4752 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4747 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4753 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4748 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 4754 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
@@ -4751,7 +4757,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4751 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 4757 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4752 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4758 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4753 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4759 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4754 SND_PCI_QUIRK(0x103c, 0x2277, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4755 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), 4760 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
4756 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 4761 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4757 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 4762 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
@@ -4804,7 +4809,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4804 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK), 4809 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
4805 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK), 4810 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
4806 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK), 4811 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
4807 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 4812 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
4808 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 4813 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4809 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), 4814 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
4810 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 4815 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -4984,6 +4989,19 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
4984 {0x17, 0x40000000}, 4989 {0x17, 0x40000000},
4985 {0x1d, 0x40700001}, 4990 {0x1d, 0x40700001},
4986 {0x21, 0x02211040}), 4991 {0x21, 0x02211040}),
4992 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
4993 {0x12, 0x90a60130},
4994 {0x13, 0x40000000},
4995 {0x14, 0x90170110},
4996 {0x15, 0x0421101f},
4997 {0x16, 0x411111f0},
4998 {0x17, 0x411111f0},
4999 {0x18, 0x411111f0},
5000 {0x19, 0x411111f0},
5001 {0x1a, 0x04a11020},
5002 {0x1b, 0x411111f0},
5003 {0x1d, 0x40748605},
5004 {0x1e, 0x411111f0}),
4987 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED, 5005 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
4988 {0x12, 0x90a60140}, 5006 {0x12, 0x90a60140},
4989 {0x13, 0x40000000}, 5007 {0x13, 0x40000000},
@@ -5651,6 +5669,35 @@ static void alc662_fixup_led_gpio1(struct hda_codec *codec,
5651 } 5669 }
5652} 5670}
5653 5671
5672static struct coef_fw alc668_coefs[] = {
5673 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
5674 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
5675 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
5676 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
5677 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
5678 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
5679 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
5680 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
5681 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
5682 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
5683 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
5684 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
5685 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
5686 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
5687 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
5688 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
5689 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
5690 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
5691 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
5692 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
5693 {}
5694};
5695
5696static void alc668_restore_default_value(struct hda_codec *codec)
5697{
5698 alc_process_coef_fw(codec, alc668_coefs);
5699}
5700
5654enum { 5701enum {
5655 ALC662_FIXUP_ASPIRE, 5702 ALC662_FIXUP_ASPIRE,
5656 ALC662_FIXUP_LED_GPIO1, 5703 ALC662_FIXUP_LED_GPIO1,
@@ -6118,8 +6165,15 @@ static int patch_alc662(struct hda_codec *codec)
6118 6165
6119 alc_fix_pll_init(codec, 0x20, 0x04, 15); 6166 alc_fix_pll_init(codec, 0x20, 0x04, 15);
6120 6167
6121 spec->init_hook = alc662_fill_coef; 6168 switch (codec->vendor_id) {
6122 alc662_fill_coef(codec); 6169 case 0x10ec0668:
6170 spec->init_hook = alc668_restore_default_value;
6171 break;
6172 default:
6173 spec->init_hook = alc662_fill_coef;
6174 alc662_fill_coef(codec);
6175 break;
6176 }
6123 6177
6124 snd_hda_pick_fixup(codec, alc662_fixup_models, 6178 snd_hda_pick_fixup(codec, alc662_fixup_models,
6125 alc662_fixup_tbl, alc662_fixups); 6179 alc662_fixup_tbl, alc662_fixups);
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 7ecd0e8a5c51..f61ebb17cc64 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -591,18 +591,19 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
591{ 591{
592 struct snd_card *card; 592 struct snd_card *card;
593 struct list_head *p; 593 struct list_head *p;
594 bool was_shutdown;
594 595
595 if (chip == (void *)-1L) 596 if (chip == (void *)-1L)
596 return; 597 return;
597 598
598 card = chip->card; 599 card = chip->card;
599 down_write(&chip->shutdown_rwsem); 600 down_write(&chip->shutdown_rwsem);
601 was_shutdown = chip->shutdown;
600 chip->shutdown = 1; 602 chip->shutdown = 1;
601 up_write(&chip->shutdown_rwsem); 603 up_write(&chip->shutdown_rwsem);
602 604
603 mutex_lock(&register_mutex); 605 mutex_lock(&register_mutex);
604 chip->num_interfaces--; 606 if (!was_shutdown) {
605 if (chip->num_interfaces <= 0) {
606 struct snd_usb_endpoint *ep; 607 struct snd_usb_endpoint *ep;
607 608
608 snd_card_disconnect(card); 609 snd_card_disconnect(card);
@@ -622,6 +623,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
622 list_for_each(p, &chip->mixer_list) { 623 list_for_each(p, &chip->mixer_list) {
623 snd_usb_mixer_disconnect(p); 624 snd_usb_mixer_disconnect(p);
624 } 625 }
626 }
627
628 chip->num_interfaces--;
629 if (chip->num_interfaces <= 0) {
625 usb_chip[chip->index] = NULL; 630 usb_chip[chip->index] = NULL;
626 mutex_unlock(&register_mutex); 631 mutex_unlock(&register_mutex);
627 snd_card_free_when_closed(card); 632 snd_card_free_when_closed(card);