diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/sound.c | 4 | ||||
-rw-r--r-- | sound/core/sound_oss.c | 2 | ||||
-rw-r--r-- | sound/isa/sb/emu8000.c | 11 | ||||
-rw-r--r-- | sound/oss/dev_table.c | 16 | ||||
-rw-r--r-- | sound/oss/sound_config.h | 2 | ||||
-rw-r--r-- | sound/oss/soundcard.c | 4 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 10 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_id.h | 2 | ||||
-rw-r--r-- | sound/pci/ac97/ac97_patch.c | 1 | ||||
-rw-r--r-- | sound/pci/atiixp.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 96 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 61 | ||||
-rw-r--r-- | sound/pci/riptide/riptide.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wm8350.c | 2 | ||||
-rw-r--r-- | sound/sound_core.c | 2 | ||||
-rw-r--r-- | sound/usb/usbaudio.c | 2 |
16 files changed, 170 insertions, 48 deletions
diff --git a/sound/core/sound.c b/sound/core/sound.c index 7872a02f6ca..563d1967a0a 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -468,5 +468,5 @@ static void __exit alsa_sound_exit(void) unregister_chrdev(major, "alsa"); } -module_init(alsa_sound_init) -module_exit(alsa_sound_exit) +subsys_initcall(alsa_sound_init); +module_exit(alsa_sound_exit); diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index 7fe12264ff8..0c164e5e432 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c @@ -93,7 +93,7 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) default: return -EINVAL; } - if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OSS_MINORS)) + if (minor < 0 || minor >= SNDRV_OSS_MINORS) return -EINVAL; return minor; } diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index 751762f1c59..0c40951b652 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c @@ -377,12 +377,13 @@ init_arrays(struct snd_emu8000 *emu) static void __devinit size_dram(struct snd_emu8000 *emu) { - int i, size; + int i, size, detected_size; if (emu->dram_checked) return; size = 0; + detected_size = 0; /* write out a magic number */ snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE); @@ -393,6 +394,8 @@ size_dram(struct snd_emu8000 *emu) while (size < EMU8000_MAX_DRAM) { + size += 512 * 1024; /* increment 512kbytes */ + /* Write a unique data on the test address. * if the address is out of range, the data is written on * 0x200000(=EMU8000_DRAM_OFFSET). Then the id word is @@ -414,7 +417,7 @@ size_dram(struct snd_emu8000 *emu) if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2) break; /* no memory at this address */ - size += 512 * 1024; /* increment 512kbytes */ + detected_size = size; snd_emu8000_read_wait(emu); @@ -442,9 +445,9 @@ size_dram(struct snd_emu8000 *emu) snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE); snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n", - emu->port1, size/1024); + emu->port1, detected_size/1024); - emu->mem_size = size; + emu->mem_size = detected_size; emu->dram_checked = 1; } diff --git a/sound/oss/dev_table.c b/sound/oss/dev_table.c index 08274c995d0..727bdb9ba2d 100644 --- a/sound/oss/dev_table.c +++ b/sound/oss/dev_table.c @@ -67,14 +67,15 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver, return -(EBUSY); } d = (struct audio_driver *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_driver))); - - if (sound_nblocks < 1024) - sound_nblocks++; + sound_nblocks++; + if (sound_nblocks >= MAX_MEM_BLOCKS) + sound_nblocks = MAX_MEM_BLOCKS - 1; op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_operations))); + sound_nblocks++; + if (sound_nblocks >= MAX_MEM_BLOCKS) + sound_nblocks = MAX_MEM_BLOCKS - 1; - if (sound_nblocks < 1024) - sound_nblocks++; if (d == NULL || op == NULL) { printk(KERN_ERR "Sound: Can't allocate driver for (%s)\n", name); sound_unload_audiodev(num); @@ -128,9 +129,10 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver, until you unload sound! */ op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct mixer_operations))); + sound_nblocks++; + if (sound_nblocks >= MAX_MEM_BLOCKS) + sound_nblocks = MAX_MEM_BLOCKS - 1; - if (sound_nblocks < 1024) - sound_nblocks++; if (op == NULL) { printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name); return -ENOMEM; diff --git a/sound/oss/sound_config.h b/sound/oss/sound_config.h index 55271fbe7f4..9d35c4c65b9 100644 --- a/sound/oss/sound_config.h +++ b/sound/oss/sound_config.h @@ -142,4 +142,6 @@ static inline int translate_mode(struct file *file) #define TIMER_ARMED 121234 #define TIMER_NOT_ARMED 1 +#define MAX_MEM_BLOCKS 1024 + #endif diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index 61aaedae6b7..c6253094388 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c @@ -56,7 +56,7 @@ /* * Table for permanently allocated memory (used when unloading the module) */ -void * sound_mem_blocks[1024]; +void * sound_mem_blocks[MAX_MEM_BLOCKS]; int sound_nblocks = 0; /* Persistent DMA buffers */ @@ -574,7 +574,7 @@ static int __init oss_init(void) NULL, "%s%d", dev_list[i].name, j); } - if (sound_nblocks >= 1024) + if (sound_nblocks >= MAX_MEM_BLOCKS - 1) printk(KERN_ERR "Sound warning: Deallocation table was too small.\n"); return 0; diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index c1192062300..a7630e9edf8 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -83,6 +83,7 @@ static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = { { 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL }, { 0x50534300, 0xffffff00, "Philips", NULL, NULL }, { 0x53494c00, 0xffffff00, "Silicon Laboratory", NULL, NULL }, +{ 0x53544d00, 0xffffff00, "STMicroelectronics", NULL, NULL }, { 0x54524100, 0xffffff00, "TriTech", NULL, NULL }, { 0x54584e00, 0xffffff00, "Texas Instruments", NULL, NULL }, { 0x56494100, 0xffffff00, "VIA Technologies", NULL, NULL }, @@ -161,6 +162,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix { 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL }, { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, +{ 0x53544d02, 0xffffffff, "ST7597", NULL, NULL }, { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, { 0x54524103, 0xffffffff, "TR28023", NULL, NULL }, { 0x54524106, 0xffffffff, "TR28026", NULL, NULL }, @@ -213,6 +215,14 @@ static int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg) { /* filter some registers for buggy codecs */ switch (ac97->id) { + case AC97_ID_ST_AC97_ID4: + if (reg == 0x08) + return 0; + /* fall through */ + case AC97_ID_ST7597: + if (reg == 0x22 || reg == 0x7a) + return 1; + /* fall through */ case AC97_ID_AK4540: case AC97_ID_AK4542: if (reg <= 0x1c || reg == 0x20 || reg == 0x26 || reg >= 0x7c) diff --git a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h index c129492c82b..d603147c4a9 100644 --- a/sound/pci/ac97/ac97_id.h +++ b/sound/pci/ac97/ac97_id.h @@ -62,3 +62,5 @@ #define AC97_ID_CM9761_78 0x434d4978 #define AC97_ID_CM9761_82 0x434d4982 #define AC97_ID_CM9761_83 0x434d4983 +#define AC97_ID_ST7597 0x53544d02 +#define AC97_ID_ST_AC97_ID4 0x53544d04 diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 139cf3b2b9d..d9266bae284 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -1870,6 +1870,7 @@ static unsigned int ad1981_jacks_blacklist[] = { 0x10140554, /* Thinkpad T42p/R50p */ 0x10140567, /* Thinkpad T43p 2668-G7U */ 0x10140581, /* Thinkpad X41-2527 */ + 0x10280160, /* Dell Dimension 2400 */ 0x104380b0, /* Asus A7V8X-MX */ 0x11790241, /* Toshiba Satellite A-15 S127 */ 0x144dc01a, /* Samsung NP-X20C004/SEG */ diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index d6752dff2a4..42b4fbbd8e2 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -297,6 +297,7 @@ static struct pci_device_id snd_atiixp_ids[] = { MODULE_DEVICE_TABLE(pci, snd_atiixp_ids); static struct snd_pci_quirk atiixp_quirks[] __devinitdata = { + SND_PCI_QUIRK(0x105b, 0x0c81, "Foxconn RC4107MA-RS2", 0), SND_PCI_QUIRK(0x15bd, 0x3100, "DFI RS482", 0), { } /* terminator */ }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c7465053d6b..3f92def752f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1230,6 +1230,8 @@ static void alc_init_auto_mic(struct hda_codec *codec) return; /* invalid entry */ } } + if (!ext || !fixed) + return; if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) return; /* no unsol support */ snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", @@ -4812,6 +4814,49 @@ static void fixup_automic_adc(struct hda_codec *codec) spec->auto_mic = 0; /* disable auto-mic to be sure */ } +/* choose the ADC/MUX containing the input pin and initialize the setup */ +static void fixup_single_adc(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t pin; + int i; + + /* search for the input pin; there must be only one */ + for (i = 0; i < AUTO_PIN_LAST; i++) { + if (spec->autocfg.input_pins[i]) { + pin = spec->autocfg.input_pins[i]; + break; + } + } + if (!pin) + return; + + /* set the default connection to that pin */ + for (i = 0; i < spec->num_adc_nids; i++) { + hda_nid_t cap = spec->capsrc_nids ? + spec->capsrc_nids[i] : spec->adc_nids[i]; + int idx; + + idx = get_connection_index(codec, cap, pin); + if (idx < 0) + continue; + /* use only this ADC */ + if (spec->capsrc_nids) + spec->capsrc_nids += i; + spec->adc_nids += i; + spec->num_adc_nids = 1; + /* select or unmute this route */ + if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { + snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, + HDA_AMP_MUTE, 0); + } else { + snd_hda_codec_write_cache(codec, cap, 0, + AC_VERB_SET_CONNECT_SEL, idx); + } + return; + } +} + static void set_capture_mixer(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -4824,14 +4869,15 @@ static void set_capture_mixer(struct hda_codec *codec) alc_capture_mixer3 }, }; if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { - int mux; - if (spec->auto_mic) { - mux = 0; + int mux = 0; + if (spec->auto_mic) fixup_automic_adc(codec); - } else if (spec->input_mux && spec->input_mux->num_items > 1) - mux = 1; - else - mux = 0; + else if (spec->input_mux) { + if (spec->input_mux->num_items > 1) + mux = 1; + else if (spec->input_mux->num_items == 1) + fixup_single_adc(codec); + } spec->cap_mixer = caps[mux][spec->num_adc_nids - 1]; } } @@ -7094,8 +7140,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = { HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT), - HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), + HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), @@ -7496,6 +7542,7 @@ static struct hda_verb alc885_mb5_init_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, + {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, /* Front Mic pin: input vref at 80% */ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, @@ -7680,6 +7727,27 @@ static void alc885_mbp3_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[0] = 0x14; } +static void alc885_mb5_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x14, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); + snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); + +} + +static void alc885_mb5_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + /* Headphone insertion or removal. */ + if ((res >> 26) == ALC880_HP_EVENT) + alc885_mb5_automute(codec); +} + static void alc885_imac91_automute(struct hda_codec *codec) { unsigned int present; @@ -9126,6 +9194,8 @@ static struct alc_config_preset alc882_presets[] = { .input_mux = &mb5_capture_source, .dig_out_nid = ALC882_DIGOUT_NID, .dig_in_nid = ALC882_DIGIN_NID, + .unsol_event = alc885_mb5_unsol_event, + .init_hook = alc885_mb5_automute, }, [ALC885_MACPRO] = { .mixers = { alc882_macpro_mixer }, @@ -11179,7 +11249,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, } #define alc262_auto_create_input_ctls \ - alc880_auto_create_input_ctls + alc882_auto_create_input_ctls /* * generic initialization of ADC, input mixers and output mixers @@ -14855,6 +14925,8 @@ static int patch_alc861(struct hda_codec *codec) spec->stream_digital_playback = &alc861_pcm_digital_playback; spec->stream_digital_capture = &alc861_pcm_digital_capture; + if (!spec->cap_mixer) + set_capture_mixer(codec); set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); spec->vmaster_nid = 0x03; @@ -15493,7 +15565,7 @@ static struct alc_config_preset alc861vd_presets[] = { static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { - return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0); + return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x22, 0); } @@ -17251,7 +17323,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", ALC662_3ST_6ch_DIG), - SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4), + SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", ALC662_3ST_6ch_DIG), diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 2291a839681..799ba257090 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4730,6 +4730,26 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) } } +static int hp_blike_system(u32 subsystem_id); + +static void set_hp_led_gpio(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + switch (codec->vendor_id) { + case 0x111d7608: + /* GPIO 0 */ + spec->gpio_led = 0x01; + break; + case 0x111d7600: + case 0x111d7601: + case 0x111d7602: + case 0x111d7603: + /* GPIO 3 */ + spec->gpio_led = 0x08; + break; + } +} + /* * This method searches for the mute LED GPIO configuration * provided as OEM string in SMBIOS. The format of that string @@ -4741,6 +4761,14 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) * * So, HP B-series like systems may have HP_Mute_LED_0 (current models) * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings + * + * + * The dv-series laptops don't seem to have the HP_Mute_LED* strings in + * SMBIOS - at least the ones I have seen do not have them - which include + * my own system (HP Pavilion dv6-1110ax) and my cousin's + * HP Pavilion dv9500t CTO. + * Need more information on whether it is true across the entire series. + * -- kunal */ static int find_mute_led_gpio(struct hda_codec *codec) { @@ -4751,28 +4779,27 @@ static int find_mute_led_gpio(struct hda_codec *codec) while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { if (sscanf(dev->name, "HP_Mute_LED_%d_%d", - &spec->gpio_led_polarity, - &spec->gpio_led) == 2) { + &spec->gpio_led_polarity, + &spec->gpio_led) == 2) { spec->gpio_led = 1 << spec->gpio_led; return 1; } if (sscanf(dev->name, "HP_Mute_LED_%d", - &spec->gpio_led_polarity) == 1) { - switch (codec->vendor_id) { - case 0x111d7608: - /* GPIO 0 */ - spec->gpio_led = 0x01; - return 1; - case 0x111d7600: - case 0x111d7601: - case 0x111d7602: - case 0x111d7603: - /* GPIO 3 */ - spec->gpio_led = 0x08; - return 1; - } + &spec->gpio_led_polarity) == 1) { + set_hp_led_gpio(codec); + return 1; } } + + /* + * Fallback case - if we don't find the DMI strings, + * we statically set the GPIO - if not a B-series system. + */ + if (!hp_blike_system(codec->subsystem_id)) { + set_hp_led_gpio(codec); + spec->gpio_led_polarity = 1; + return 1; + } } return 0; } @@ -5548,6 +5575,8 @@ again: spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e); + snd_printdd("Found board config: %d\n", spec->board_config); + switch (spec->board_config) { case STAC_HP_M4: /* enable internal microphone */ diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index b5ca02e2038..e66ef2b69b5 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -1058,7 +1058,7 @@ setsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int rate) rptr.retwords[2] != M && rptr.retwords[3] != N && i++ < MAX_WRITE_RETRY); - if (i == MAX_WRITE_RETRY) { + if (i > MAX_WRITE_RETRY) { snd_printdd("sent samplerate %d: %d failed\n", *intdec, rate); return -EIO; diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index ebbf11b653a..718ef912e75 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -925,7 +925,7 @@ static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) iface |= 0x3 << 8; break; case SND_SOC_DAIFMT_DSP_B: - iface |= 0x3 << 8; /* lg not sure which mode */ + iface |= 0x3 << 8 | WM8350_AIF_LRCLK_INV; break; default: return -EINVAL; diff --git a/sound/sound_core.c b/sound/sound_core.c index dbca7c909a3..7c2d677a2df 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -61,7 +61,7 @@ static void __exit cleanup_soundcore(void) class_destroy(sound_class); } -module_init(init_soundcore); +subsys_initcall(init_soundcore); module_exit(cleanup_soundcore); diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 4963defee18..9edef468497 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -1936,7 +1936,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) struct snd_usb_stream *as = snd_pcm_substream_chip(substream); struct snd_usb_substream *subs = &as->substream[direction]; - if (subs->interface >= 0) { + if (!as->chip->shutdown && subs->interface >= 0) { usb_set_interface(subs->dev, subs->interface, 0); subs->interface = -1; } |