Commit cf0d135649784179c6599f831a01c57a42e31136
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge tag 'sound-3.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "Here includes a few patchset for fixing mostly HD-audio issues in addition to a patch assuring the compress API bytes alignment and a fix for the die-hard existing race condition at USB-audio disconnection. The volume looks big in Realtek HD-audio code, but it's just a translation of the fixup tables, and the actual changes are rather trivial" * tag 'sound-3.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda - restore BCLK M/N values when resuming HSW/BDW display controller ALSA: usb-audio: Fix races at disconnection and PCM closing ALSA: hda - Adjust speaker HPF and add LED support for HP Spectre 13 ALSA: hda - Make the pin quirk tables use the SND_HDA_PIN_QUIRK macro ALSA: hda - Make a SND_HDA_PIN_QUIRK macro ALSA: hda - Add pin quirk for Dell XPS 15 ALSA: hda - hdmi: call overridden init on resume ALSA: hda - Fix usage of "model" module parameter ALSA: compress: fix the struct alignment to 4 bytes
Showing 12 changed files Side-by-side Diff
- Documentation/sound/alsa/HD-Audio-Models.txt
- include/uapi/sound/compress_offload.h
- include/uapi/sound/compress_params.h
- sound/pci/hda/hda_auto_parser.c
- sound/pci/hda/hda_intel.c
- sound/pci/hda/hda_local.h
- sound/pci/hda/patch_hdmi.c
- sound/pci/hda/patch_realtek.c
- sound/pci/hda/patch_sigmatel.c
- sound/usb/card.c
- sound/usb/endpoint.c
- sound/usb/endpoint.h
Documentation/sound/alsa/HD-Audio-Models.txt
... | ... | @@ -286,6 +286,11 @@ |
286 | 286 | hp-inv-led HP with broken BIOS for inverted mute LED |
287 | 287 | auto BIOS setup (default) |
288 | 288 | |
289 | +STAC92HD95 | |
290 | +========== | |
291 | + hp-led LED support for HP laptops | |
292 | + hp-bass Bass HPF setup for HP Spectre 13 | |
293 | + | |
289 | 294 | STAC9872 |
290 | 295 | ======== |
291 | 296 | vaio VAIO laptop without SPDIF |
include/uapi/sound/compress_offload.h
... | ... | @@ -39,7 +39,7 @@ |
39 | 39 | struct snd_compressed_buffer { |
40 | 40 | __u32 fragment_size; |
41 | 41 | __u32 fragments; |
42 | -}; | |
42 | +} __attribute__((packed, aligned(4))); | |
43 | 43 | |
44 | 44 | /** |
45 | 45 | * struct snd_compr_params: compressed stream params |
... | ... | @@ -51,7 +51,7 @@ |
51 | 51 | struct snd_compressed_buffer buffer; |
52 | 52 | struct snd_codec codec; |
53 | 53 | __u8 no_wake_mode; |
54 | -}; | |
54 | +} __attribute__((packed, aligned(4))); | |
55 | 55 | |
56 | 56 | /** |
57 | 57 | * struct snd_compr_tstamp: timestamp descriptor |
... | ... | @@ -70,7 +70,7 @@ |
70 | 70 | __u32 pcm_frames; |
71 | 71 | __u32 pcm_io_frames; |
72 | 72 | __u32 sampling_rate; |
73 | -}; | |
73 | +} __attribute__((packed, aligned(4))); | |
74 | 74 | |
75 | 75 | /** |
76 | 76 | * struct snd_compr_avail: avail descriptor |
... | ... | @@ -80,7 +80,7 @@ |
80 | 80 | struct snd_compr_avail { |
81 | 81 | __u64 avail; |
82 | 82 | struct snd_compr_tstamp tstamp; |
83 | -} __attribute__((packed)); | |
83 | +} __attribute__((packed, aligned(4))); | |
84 | 84 | |
85 | 85 | enum snd_compr_direction { |
86 | 86 | SND_COMPRESS_PLAYBACK = 0, |
... | ... | @@ -107,7 +107,7 @@ |
107 | 107 | __u32 max_fragments; |
108 | 108 | __u32 codecs[MAX_NUM_CODECS]; |
109 | 109 | __u32 reserved[11]; |
110 | -}; | |
110 | +} __attribute__((packed, aligned(4))); | |
111 | 111 | |
112 | 112 | /** |
113 | 113 | * struct snd_compr_codec_caps: query capability of codec |
... | ... | @@ -119,7 +119,7 @@ |
119 | 119 | __u32 codec; |
120 | 120 | __u32 num_descriptors; |
121 | 121 | struct snd_codec_desc descriptor[MAX_NUM_CODEC_DESCRIPTORS]; |
122 | -}; | |
122 | +} __attribute__((packed, aligned(4))); | |
123 | 123 | |
124 | 124 | /** |
125 | 125 | * @SNDRV_COMPRESS_ENCODER_PADDING: no of samples appended by the encoder at the |
... | ... | @@ -140,7 +140,7 @@ |
140 | 140 | struct snd_compr_metadata { |
141 | 141 | __u32 key; |
142 | 142 | __u32 value[8]; |
143 | -}; | |
143 | +} __attribute__((packed, aligned(4))); | |
144 | 144 | |
145 | 145 | /** |
146 | 146 | * compress path ioctl definitions |
include/uapi/sound/compress_params.h
... | ... | @@ -268,7 +268,7 @@ |
268 | 268 | __u32 max_bit_rate; |
269 | 269 | __u32 min_bit_rate; |
270 | 270 | __u32 downmix; |
271 | -}; | |
271 | +} __attribute__((packed, aligned(4))); | |
272 | 272 | |
273 | 273 | |
274 | 274 | /** |
... | ... | @@ -284,7 +284,7 @@ |
284 | 284 | __u32 quant_bits; |
285 | 285 | __u32 start_region; |
286 | 286 | __u32 num_regions; |
287 | -}; | |
287 | +} __attribute__((packed, aligned(4))); | |
288 | 288 | |
289 | 289 | /** |
290 | 290 | * struct snd_enc_flac |
291 | 291 | |
... | ... | @@ -308,12 +308,12 @@ |
308 | 308 | struct snd_enc_flac { |
309 | 309 | __u32 num; |
310 | 310 | __u32 gain; |
311 | -}; | |
311 | +} __attribute__((packed, aligned(4))); | |
312 | 312 | |
313 | 313 | struct snd_enc_generic { |
314 | 314 | __u32 bw; /* encoder bandwidth */ |
315 | 315 | __s32 reserved[15]; |
316 | -}; | |
316 | +} __attribute__((packed, aligned(4))); | |
317 | 317 | |
318 | 318 | union snd_codec_options { |
319 | 319 | struct snd_enc_wma wma; |
... | ... | @@ -321,7 +321,7 @@ |
321 | 321 | struct snd_enc_real real; |
322 | 322 | struct snd_enc_flac flac; |
323 | 323 | struct snd_enc_generic generic; |
324 | -}; | |
324 | +} __attribute__((packed, aligned(4))); | |
325 | 325 | |
326 | 326 | /** struct snd_codec_desc - description of codec capabilities |
327 | 327 | * @max_ch: Maximum number of audio channels |
... | ... | @@ -358,7 +358,7 @@ |
358 | 358 | __u32 formats; |
359 | 359 | __u32 min_buffer; |
360 | 360 | __u32 reserved[15]; |
361 | -}; | |
361 | +} __attribute__((packed, aligned(4))); | |
362 | 362 | |
363 | 363 | /** struct snd_codec |
364 | 364 | * @id: Identifies the supported audio encoder/decoder. |
... | ... | @@ -399,7 +399,7 @@ |
399 | 399 | __u32 align; |
400 | 400 | union snd_codec_options options; |
401 | 401 | __u32 reserved[3]; |
402 | -}; | |
402 | +} __attribute__((packed, aligned(4))); | |
403 | 403 | |
404 | 404 | #endif |
sound/pci/hda/hda_auto_parser.c
sound/pci/hda/hda_intel.c
... | ... | @@ -288,6 +288,24 @@ |
288 | 288 | [AZX_DRIVER_GENERIC] = "HD-Audio Generic", |
289 | 289 | }; |
290 | 290 | |
291 | + | |
292 | +/* Intel HSW/BDW display HDA controller Extended Mode registers. | |
293 | + * EM4 (M value) and EM5 (N Value) are used to convert CDClk (Core Display | |
294 | + * Clock) to 24MHz BCLK: BCLK = CDCLK * M / N | |
295 | + * The values will be lost when the display power well is disabled. | |
296 | + */ | |
297 | +#define ICH6_REG_EM4 0x100c | |
298 | +#define ICH6_REG_EM5 0x1010 | |
299 | + | |
300 | +struct hda_intel { | |
301 | + struct azx chip; | |
302 | + | |
303 | + /* HSW/BDW display HDA controller to restore BCLK from CDCLK */ | |
304 | + unsigned int bclk_m; | |
305 | + unsigned int bclk_n; | |
306 | +}; | |
307 | + | |
308 | + | |
291 | 309 | #ifdef CONFIG_X86 |
292 | 310 | static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on) |
293 | 311 | { |
... | ... | @@ -580,6 +598,22 @@ |
580 | 598 | #define azx_del_card_list(chip) /* NOP */ |
581 | 599 | #endif /* CONFIG_PM */ |
582 | 600 | |
601 | +static void haswell_save_bclk(struct azx *chip) | |
602 | +{ | |
603 | + struct hda_intel *hda = container_of(chip, struct hda_intel, chip); | |
604 | + | |
605 | + hda->bclk_m = azx_readw(chip, EM4); | |
606 | + hda->bclk_n = azx_readw(chip, EM5); | |
607 | +} | |
608 | + | |
609 | +static void haswell_restore_bclk(struct azx *chip) | |
610 | +{ | |
611 | + struct hda_intel *hda = container_of(chip, struct hda_intel, chip); | |
612 | + | |
613 | + azx_writew(chip, EM4, hda->bclk_m); | |
614 | + azx_writew(chip, EM5, hda->bclk_n); | |
615 | +} | |
616 | + | |
583 | 617 | #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO) |
584 | 618 | /* |
585 | 619 | * power management |
... | ... | @@ -606,6 +640,13 @@ |
606 | 640 | free_irq(chip->irq, chip); |
607 | 641 | chip->irq = -1; |
608 | 642 | } |
643 | + | |
644 | + /* Save BCLK M/N values before they become invalid in D3. | |
645 | + * Will test if display power well can be released now. | |
646 | + */ | |
647 | + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | |
648 | + haswell_save_bclk(chip); | |
649 | + | |
609 | 650 | if (chip->msi) |
610 | 651 | pci_disable_msi(chip->pci); |
611 | 652 | pci_disable_device(pci); |
612 | 653 | |
... | ... | @@ -625,8 +666,10 @@ |
625 | 666 | if (chip->disabled) |
626 | 667 | return 0; |
627 | 668 | |
628 | - if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | |
669 | + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { | |
629 | 670 | hda_display_power(true); |
671 | + haswell_restore_bclk(chip); | |
672 | + } | |
630 | 673 | pci_set_power_state(pci, PCI_D0); |
631 | 674 | pci_restore_state(pci); |
632 | 675 | if (pci_enable_device(pci) < 0) { |
633 | 676 | |
... | ... | @@ -670,8 +713,10 @@ |
670 | 713 | azx_stop_chip(chip); |
671 | 714 | azx_enter_link_reset(chip); |
672 | 715 | azx_clear_irq_pending(chip); |
673 | - if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | |
716 | + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { | |
717 | + haswell_save_bclk(chip); | |
674 | 718 | hda_display_power(false); |
719 | + } | |
675 | 720 | return 0; |
676 | 721 | } |
677 | 722 | |
678 | 723 | |
... | ... | @@ -689,8 +734,10 @@ |
689 | 734 | if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) |
690 | 735 | return 0; |
691 | 736 | |
692 | - if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | |
737 | + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { | |
693 | 738 | hda_display_power(true); |
739 | + haswell_restore_bclk(chip); | |
740 | + } | |
694 | 741 | |
695 | 742 | /* Read STATESTS before controller reset */ |
696 | 743 | status = azx_readw(chip, STATESTS); |
... | ... | @@ -883,6 +930,8 @@ |
883 | 930 | static int azx_free(struct azx *chip) |
884 | 931 | { |
885 | 932 | struct pci_dev *pci = chip->pci; |
933 | + struct hda_intel *hda = container_of(chip, struct hda_intel, chip); | |
934 | + | |
886 | 935 | int i; |
887 | 936 | |
888 | 937 | if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) |
... | ... | @@ -930,7 +979,7 @@ |
930 | 979 | hda_display_power(false); |
931 | 980 | hda_i915_exit(); |
932 | 981 | } |
933 | - kfree(chip); | |
982 | + kfree(hda); | |
934 | 983 | |
935 | 984 | return 0; |
936 | 985 | } |
... | ... | @@ -1174,6 +1223,7 @@ |
1174 | 1223 | static struct snd_device_ops ops = { |
1175 | 1224 | .dev_free = azx_dev_free, |
1176 | 1225 | }; |
1226 | + struct hda_intel *hda; | |
1177 | 1227 | struct azx *chip; |
1178 | 1228 | int err; |
1179 | 1229 | |
1180 | 1230 | |
... | ... | @@ -1183,13 +1233,14 @@ |
1183 | 1233 | if (err < 0) |
1184 | 1234 | return err; |
1185 | 1235 | |
1186 | - chip = kzalloc(sizeof(*chip), GFP_KERNEL); | |
1187 | - if (!chip) { | |
1188 | - dev_err(card->dev, "Cannot allocate chip\n"); | |
1236 | + hda = kzalloc(sizeof(*hda), GFP_KERNEL); | |
1237 | + if (!hda) { | |
1238 | + dev_err(card->dev, "Cannot allocate hda\n"); | |
1189 | 1239 | pci_disable_device(pci); |
1190 | 1240 | return -ENOMEM; |
1191 | 1241 | } |
1192 | 1242 | |
1243 | + chip = &hda->chip; | |
1193 | 1244 | spin_lock_init(&chip->reg_lock); |
1194 | 1245 | mutex_init(&chip->open_mutex); |
1195 | 1246 | chip->card = card; |
sound/pci/hda/hda_local.h
... | ... | @@ -417,6 +417,27 @@ |
417 | 417 | int value; /* quirk value */ |
418 | 418 | }; |
419 | 419 | |
420 | +#ifdef CONFIG_SND_DEBUG_VERBOSE | |
421 | + | |
422 | +#define SND_HDA_PIN_QUIRK(_codec, _subvendor, _name, _value, _pins...) \ | |
423 | + { .codec = _codec,\ | |
424 | + .subvendor = _subvendor,\ | |
425 | + .name = _name,\ | |
426 | + .value = _value,\ | |
427 | + .pins = (const struct hda_pintbl[]) { _pins } \ | |
428 | + } | |
429 | +#else | |
430 | + | |
431 | +#define SND_HDA_PIN_QUIRK(_codec, _subvendor, _name, _value, _pins...) \ | |
432 | + { .codec = _codec,\ | |
433 | + .subvendor = _subvendor,\ | |
434 | + .value = _value,\ | |
435 | + .pins = (const struct hda_pintbl[]) { _pins } \ | |
436 | + } | |
437 | + | |
438 | +#endif | |
439 | + | |
440 | + | |
420 | 441 | /* fixup types */ |
421 | 442 | enum { |
422 | 443 | HDA_FIXUP_INVALID, |
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
... | ... | @@ -4962,228 +4962,129 @@ |
4962 | 4962 | }; |
4963 | 4963 | |
4964 | 4964 | static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { |
4965 | - { | |
4966 | - .codec = 0x10ec0255, | |
4967 | - .subvendor = 0x1028, | |
4968 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
4969 | - .name = "Dell", | |
4970 | -#endif | |
4971 | - .pins = (const struct hda_pintbl[]) { | |
4972 | - {0x12, 0x90a60140}, | |
4973 | - {0x14, 0x90170110}, | |
4974 | - {0x17, 0x40000000}, | |
4975 | - {0x18, 0x411111f0}, | |
4976 | - {0x19, 0x411111f0}, | |
4977 | - {0x1a, 0x411111f0}, | |
4978 | - {0x1b, 0x411111f0}, | |
4979 | - {0x1d, 0x40700001}, | |
4980 | - {0x1e, 0x411111f0}, | |
4981 | - {0x21, 0x02211020}, | |
4982 | - }, | |
4983 | - .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
4984 | - }, | |
4985 | - { | |
4986 | - .codec = 0x10ec0255, | |
4987 | - .subvendor = 0x1028, | |
4988 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
4989 | - .name = "Dell", | |
4990 | -#endif | |
4991 | - .pins = (const struct hda_pintbl[]) { | |
4992 | - {0x12, 0x90a60160}, | |
4993 | - {0x14, 0x90170120}, | |
4994 | - {0x17, 0x40000000}, | |
4995 | - {0x18, 0x411111f0}, | |
4996 | - {0x19, 0x411111f0}, | |
4997 | - {0x1a, 0x411111f0}, | |
4998 | - {0x1b, 0x411111f0}, | |
4999 | - {0x1d, 0x40700001}, | |
5000 | - {0x1e, 0x411111f0}, | |
5001 | - {0x21, 0x02211030}, | |
5002 | - }, | |
5003 | - .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5004 | - }, | |
5005 | - { | |
5006 | - .codec = 0x10ec0255, | |
5007 | - .subvendor = 0x1028, | |
5008 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
5009 | - .name = "Dell", | |
5010 | -#endif | |
5011 | - .pins = (const struct hda_pintbl[]) { | |
5012 | - {0x12, 0x90a60160}, | |
5013 | - {0x14, 0x90170120}, | |
5014 | - {0x17, 0x90170140}, | |
5015 | - {0x18, 0x40000000}, | |
5016 | - {0x19, 0x411111f0}, | |
5017 | - {0x1a, 0x411111f0}, | |
5018 | - {0x1b, 0x411111f0}, | |
5019 | - {0x1d, 0x41163b05}, | |
5020 | - {0x1e, 0x411111f0}, | |
5021 | - {0x21, 0x0321102f}, | |
5022 | - }, | |
5023 | - .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5024 | - }, | |
5025 | - { | |
5026 | - .codec = 0x10ec0255, | |
5027 | - .subvendor = 0x1028, | |
5028 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
5029 | - .name = "Dell", | |
5030 | -#endif | |
5031 | - .pins = (const struct hda_pintbl[]) { | |
5032 | - {0x12, 0x90a60160}, | |
5033 | - {0x14, 0x90170130}, | |
5034 | - {0x17, 0x40000000}, | |
5035 | - {0x18, 0x411111f0}, | |
5036 | - {0x19, 0x411111f0}, | |
5037 | - {0x1a, 0x411111f0}, | |
5038 | - {0x1b, 0x411111f0}, | |
5039 | - {0x1d, 0x40700001}, | |
5040 | - {0x1e, 0x411111f0}, | |
5041 | - {0x21, 0x02211040}, | |
5042 | - }, | |
5043 | - .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5044 | - }, | |
5045 | - { | |
5046 | - .codec = 0x10ec0255, | |
5047 | - .subvendor = 0x1028, | |
5048 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
5049 | - .name = "Dell", | |
5050 | -#endif | |
5051 | - .pins = (const struct hda_pintbl[]) { | |
5052 | - {0x12, 0x90a60160}, | |
5053 | - {0x14, 0x90170140}, | |
5054 | - {0x17, 0x40000000}, | |
5055 | - {0x18, 0x411111f0}, | |
5056 | - {0x19, 0x411111f0}, | |
5057 | - {0x1a, 0x411111f0}, | |
5058 | - {0x1b, 0x411111f0}, | |
5059 | - {0x1d, 0x40700001}, | |
5060 | - {0x1e, 0x411111f0}, | |
5061 | - {0x21, 0x02211050}, | |
5062 | - }, | |
5063 | - .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5064 | - }, | |
5065 | - { | |
5066 | - .codec = 0x10ec0255, | |
5067 | - .subvendor = 0x1028, | |
5068 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
5069 | - .name = "Dell", | |
5070 | -#endif | |
5071 | - .pins = (const struct hda_pintbl[]) { | |
5072 | - {0x12, 0x90a60170}, | |
5073 | - {0x14, 0x90170120}, | |
5074 | - {0x17, 0x40000000}, | |
5075 | - {0x18, 0x411111f0}, | |
5076 | - {0x19, 0x411111f0}, | |
5077 | - {0x1a, 0x411111f0}, | |
5078 | - {0x1b, 0x411111f0}, | |
5079 | - {0x1d, 0x40700001}, | |
5080 | - {0x1e, 0x411111f0}, | |
5081 | - {0x21, 0x02211030}, | |
5082 | - }, | |
5083 | - .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5084 | - }, | |
5085 | - { | |
5086 | - .codec = 0x10ec0255, | |
5087 | - .subvendor = 0x1028, | |
5088 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
5089 | - .name = "Dell", | |
5090 | -#endif | |
5091 | - .pins = (const struct hda_pintbl[]) { | |
5092 | - {0x12, 0x90a60170}, | |
5093 | - {0x14, 0x90170130}, | |
5094 | - {0x17, 0x40000000}, | |
5095 | - {0x18, 0x411111f0}, | |
5096 | - {0x19, 0x411111f0}, | |
5097 | - {0x1a, 0x411111f0}, | |
5098 | - {0x1b, 0x411111f0}, | |
5099 | - {0x1d, 0x40700001}, | |
5100 | - {0x1e, 0x411111f0}, | |
5101 | - {0x21, 0x02211040}, | |
5102 | - }, | |
5103 | - .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5104 | - }, | |
5105 | - { | |
5106 | - .codec = 0x10ec0283, | |
5107 | - .subvendor = 0x1028, | |
5108 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
5109 | - .name = "Dell", | |
5110 | -#endif | |
5111 | - .pins = (const struct hda_pintbl[]) { | |
5112 | - {0x12, 0x90a60130}, | |
5113 | - {0x14, 0x90170110}, | |
5114 | - {0x17, 0x40020008}, | |
5115 | - {0x18, 0x411111f0}, | |
5116 | - {0x19, 0x411111f0}, | |
5117 | - {0x1a, 0x411111f0}, | |
5118 | - {0x1b, 0x411111f0}, | |
5119 | - {0x1d, 0x40e00001}, | |
5120 | - {0x1e, 0x411111f0}, | |
5121 | - {0x21, 0x0321101f}, | |
5122 | - }, | |
5123 | - .value = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5124 | - }, | |
5125 | - { | |
5126 | - .codec = 0x10ec0283, | |
5127 | - .subvendor = 0x1028, | |
5128 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
5129 | - .name = "Dell", | |
5130 | -#endif | |
5131 | - .pins = (const struct hda_pintbl[]) { | |
5132 | - {0x12, 0x90a60160}, | |
5133 | - {0x14, 0x90170120}, | |
5134 | - {0x17, 0x40000000}, | |
5135 | - {0x18, 0x411111f0}, | |
5136 | - {0x19, 0x411111f0}, | |
5137 | - {0x1a, 0x411111f0}, | |
5138 | - {0x1b, 0x411111f0}, | |
5139 | - {0x1d, 0x40700001}, | |
5140 | - {0x1e, 0x411111f0}, | |
5141 | - {0x21, 0x02211030}, | |
5142 | - }, | |
5143 | - .value = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5144 | - }, | |
5145 | - { | |
5146 | - .codec = 0x10ec0292, | |
5147 | - .subvendor = 0x1028, | |
5148 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
5149 | - .name = "Dell", | |
5150 | -#endif | |
5151 | - .pins = (const struct hda_pintbl[]) { | |
5152 | - {0x12, 0x90a60140}, | |
5153 | - {0x13, 0x411111f0}, | |
5154 | - {0x14, 0x90170110}, | |
5155 | - {0x15, 0x0221401f}, | |
5156 | - {0x16, 0x411111f0}, | |
5157 | - {0x18, 0x411111f0}, | |
5158 | - {0x19, 0x411111f0}, | |
5159 | - {0x1a, 0x411111f0}, | |
5160 | - {0x1b, 0x411111f0}, | |
5161 | - {0x1d, 0x40700001}, | |
5162 | - {0x1e, 0x411111f0}, | |
5163 | - }, | |
5164 | - .value = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, | |
5165 | - }, | |
5166 | - { | |
5167 | - .codec = 0x10ec0293, | |
5168 | - .subvendor = 0x1028, | |
5169 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
5170 | - .name = "Dell", | |
5171 | -#endif | |
5172 | - .pins = (const struct hda_pintbl[]) { | |
5173 | - {0x12, 0x40000000}, | |
5174 | - {0x13, 0x90a60140}, | |
5175 | - {0x14, 0x90170110}, | |
5176 | - {0x15, 0x0221401f}, | |
5177 | - {0x16, 0x21014020}, | |
5178 | - {0x18, 0x411111f0}, | |
5179 | - {0x19, 0x21a19030}, | |
5180 | - {0x1a, 0x411111f0}, | |
5181 | - {0x1b, 0x411111f0}, | |
5182 | - {0x1d, 0x40700001}, | |
5183 | - {0x1e, 0x411111f0}, | |
5184 | - }, | |
5185 | - .value = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5186 | - }, | |
4965 | + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
4966 | + {0x12, 0x90a60140}, | |
4967 | + {0x14, 0x90170110}, | |
4968 | + {0x17, 0x40000000}, | |
4969 | + {0x18, 0x411111f0}, | |
4970 | + {0x19, 0x411111f0}, | |
4971 | + {0x1a, 0x411111f0}, | |
4972 | + {0x1b, 0x411111f0}, | |
4973 | + {0x1d, 0x40700001}, | |
4974 | + {0x1e, 0x411111f0}, | |
4975 | + {0x21, 0x02211020}), | |
4976 | + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
4977 | + {0x12, 0x90a60160}, | |
4978 | + {0x14, 0x90170120}, | |
4979 | + {0x17, 0x40000000}, | |
4980 | + {0x18, 0x411111f0}, | |
4981 | + {0x19, 0x411111f0}, | |
4982 | + {0x1a, 0x411111f0}, | |
4983 | + {0x1b, 0x411111f0}, | |
4984 | + {0x1d, 0x40700001}, | |
4985 | + {0x1e, 0x411111f0}, | |
4986 | + {0x21, 0x02211030}), | |
4987 | + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
4988 | + {0x12, 0x90a60160}, | |
4989 | + {0x14, 0x90170120}, | |
4990 | + {0x17, 0x90170140}, | |
4991 | + {0x18, 0x40000000}, | |
4992 | + {0x19, 0x411111f0}, | |
4993 | + {0x1a, 0x411111f0}, | |
4994 | + {0x1b, 0x411111f0}, | |
4995 | + {0x1d, 0x41163b05}, | |
4996 | + {0x1e, 0x411111f0}, | |
4997 | + {0x21, 0x0321102f}), | |
4998 | + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
4999 | + {0x12, 0x90a60160}, | |
5000 | + {0x14, 0x90170130}, | |
5001 | + {0x17, 0x40000000}, | |
5002 | + {0x18, 0x411111f0}, | |
5003 | + {0x19, 0x411111f0}, | |
5004 | + {0x1a, 0x411111f0}, | |
5005 | + {0x1b, 0x411111f0}, | |
5006 | + {0x1d, 0x40700001}, | |
5007 | + {0x1e, 0x411111f0}, | |
5008 | + {0x21, 0x02211040}), | |
5009 | + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5010 | + {0x12, 0x90a60160}, | |
5011 | + {0x14, 0x90170140}, | |
5012 | + {0x17, 0x40000000}, | |
5013 | + {0x18, 0x411111f0}, | |
5014 | + {0x19, 0x411111f0}, | |
5015 | + {0x1a, 0x411111f0}, | |
5016 | + {0x1b, 0x411111f0}, | |
5017 | + {0x1d, 0x40700001}, | |
5018 | + {0x1e, 0x411111f0}, | |
5019 | + {0x21, 0x02211050}), | |
5020 | + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5021 | + {0x12, 0x90a60170}, | |
5022 | + {0x14, 0x90170120}, | |
5023 | + {0x17, 0x40000000}, | |
5024 | + {0x18, 0x411111f0}, | |
5025 | + {0x19, 0x411111f0}, | |
5026 | + {0x1a, 0x411111f0}, | |
5027 | + {0x1b, 0x411111f0}, | |
5028 | + {0x1d, 0x40700001}, | |
5029 | + {0x1e, 0x411111f0}, | |
5030 | + {0x21, 0x02211030}), | |
5031 | + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5032 | + {0x12, 0x90a60170}, | |
5033 | + {0x14, 0x90170130}, | |
5034 | + {0x17, 0x40000000}, | |
5035 | + {0x18, 0x411111f0}, | |
5036 | + {0x19, 0x411111f0}, | |
5037 | + {0x1a, 0x411111f0}, | |
5038 | + {0x1b, 0x411111f0}, | |
5039 | + {0x1d, 0x40700001}, | |
5040 | + {0x1e, 0x411111f0}, | |
5041 | + {0x21, 0x02211040}), | |
5042 | + SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5043 | + {0x12, 0x90a60130}, | |
5044 | + {0x14, 0x90170110}, | |
5045 | + {0x17, 0x40020008}, | |
5046 | + {0x18, 0x411111f0}, | |
5047 | + {0x19, 0x411111f0}, | |
5048 | + {0x1a, 0x411111f0}, | |
5049 | + {0x1b, 0x411111f0}, | |
5050 | + {0x1d, 0x40e00001}, | |
5051 | + {0x1e, 0x411111f0}, | |
5052 | + {0x21, 0x0321101f}), | |
5053 | + SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5054 | + {0x12, 0x90a60160}, | |
5055 | + {0x14, 0x90170120}, | |
5056 | + {0x17, 0x40000000}, | |
5057 | + {0x18, 0x411111f0}, | |
5058 | + {0x19, 0x411111f0}, | |
5059 | + {0x1a, 0x411111f0}, | |
5060 | + {0x1b, 0x411111f0}, | |
5061 | + {0x1d, 0x40700001}, | |
5062 | + {0x1e, 0x411111f0}, | |
5063 | + {0x21, 0x02211030}), | |
5064 | + SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, | |
5065 | + {0x12, 0x90a60140}, | |
5066 | + {0x13, 0x411111f0}, | |
5067 | + {0x14, 0x90170110}, | |
5068 | + {0x15, 0x0221401f}, | |
5069 | + {0x16, 0x411111f0}, | |
5070 | + {0x18, 0x411111f0}, | |
5071 | + {0x19, 0x411111f0}, | |
5072 | + {0x1a, 0x411111f0}, | |
5073 | + {0x1b, 0x411111f0}, | |
5074 | + {0x1d, 0x40700001}, | |
5075 | + {0x1e, 0x411111f0}), | |
5076 | + SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, | |
5077 | + {0x12, 0x40000000}, | |
5078 | + {0x13, 0x90a60140}, | |
5079 | + {0x14, 0x90170110}, | |
5080 | + {0x15, 0x0221401f}, | |
5081 | + {0x16, 0x21014020}, | |
5082 | + {0x18, 0x411111f0}, | |
5083 | + {0x19, 0x21a19030}, | |
5084 | + {0x1a, 0x411111f0}, | |
5085 | + {0x1b, 0x411111f0}, | |
5086 | + {0x1d, 0x40700001}, | |
5087 | + {0x1e, 0x411111f0}), | |
5187 | 5088 | {} |
5188 | 5089 | }; |
5189 | 5090 | |
... | ... | @@ -6039,90 +5940,66 @@ |
6039 | 5940 | }; |
6040 | 5941 | |
6041 | 5942 | static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = { |
6042 | - { | |
6043 | - .codec = 0x10ec0668, | |
6044 | - .subvendor = 0x1028, | |
6045 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
6046 | - .name = "Dell", | |
6047 | -#endif | |
6048 | - .pins = (const struct hda_pintbl[]) { | |
6049 | - {0x12, 0x99a30130}, | |
6050 | - {0x14, 0x90170110}, | |
6051 | - {0x15, 0x0321101f}, | |
6052 | - {0x16, 0x03011020}, | |
6053 | - {0x18, 0x40000008}, | |
6054 | - {0x19, 0x411111f0}, | |
6055 | - {0x1a, 0x411111f0}, | |
6056 | - {0x1b, 0x411111f0}, | |
6057 | - {0x1d, 0x41000001}, | |
6058 | - {0x1e, 0x411111f0}, | |
6059 | - {0x1f, 0x411111f0}, | |
6060 | - }, | |
6061 | - .value = ALC668_FIXUP_AUTO_MUTE, | |
6062 | - }, | |
6063 | - { | |
6064 | - .codec = 0x10ec0668, | |
6065 | - .subvendor = 0x1028, | |
6066 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
6067 | - .name = "Dell", | |
6068 | -#endif | |
6069 | - .pins = (const struct hda_pintbl[]) { | |
6070 | - {0x12, 0x99a30140}, | |
6071 | - {0x14, 0x90170110}, | |
6072 | - {0x15, 0x0321101f}, | |
6073 | - {0x16, 0x03011020}, | |
6074 | - {0x18, 0x40000008}, | |
6075 | - {0x19, 0x411111f0}, | |
6076 | - {0x1a, 0x411111f0}, | |
6077 | - {0x1b, 0x411111f0}, | |
6078 | - {0x1d, 0x41000001}, | |
6079 | - {0x1e, 0x411111f0}, | |
6080 | - {0x1f, 0x411111f0}, | |
6081 | - }, | |
6082 | - .value = ALC668_FIXUP_AUTO_MUTE, | |
6083 | - }, | |
6084 | - { | |
6085 | - .codec = 0x10ec0668, | |
6086 | - .subvendor = 0x1028, | |
6087 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
6088 | - .name = "Dell", | |
6089 | -#endif | |
6090 | - .pins = (const struct hda_pintbl[]) { | |
6091 | - {0x12, 0x99a30150}, | |
6092 | - {0x14, 0x90170110}, | |
6093 | - {0x15, 0x0321101f}, | |
6094 | - {0x16, 0x03011020}, | |
6095 | - {0x18, 0x40000008}, | |
6096 | - {0x19, 0x411111f0}, | |
6097 | - {0x1a, 0x411111f0}, | |
6098 | - {0x1b, 0x411111f0}, | |
6099 | - {0x1d, 0x41000001}, | |
6100 | - {0x1e, 0x411111f0}, | |
6101 | - {0x1f, 0x411111f0}, | |
6102 | - }, | |
6103 | - .value = ALC668_FIXUP_AUTO_MUTE, | |
6104 | - }, | |
6105 | - { | |
6106 | - .codec = 0x10ec0668, | |
6107 | - .subvendor = 0x1028, | |
6108 | -#ifdef CONFIG_SND_DEBUG_VERBOSE | |
6109 | - .name = "Dell", | |
6110 | -#endif | |
6111 | - .pins = (const struct hda_pintbl[]) { | |
6112 | - {0x12, 0x411111f0}, | |
6113 | - {0x14, 0x90170110}, | |
6114 | - {0x15, 0x0321101f}, | |
6115 | - {0x16, 0x03011020}, | |
6116 | - {0x18, 0x40000008}, | |
6117 | - {0x19, 0x411111f0}, | |
6118 | - {0x1a, 0x411111f0}, | |
6119 | - {0x1b, 0x411111f0}, | |
6120 | - {0x1d, 0x41000001}, | |
6121 | - {0x1e, 0x411111f0}, | |
6122 | - {0x1f, 0x411111f0}, | |
6123 | - }, | |
6124 | - .value = ALC668_FIXUP_AUTO_MUTE, | |
6125 | - }, | |
5943 | + SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, | |
5944 | + {0x12, 0x99a30130}, | |
5945 | + {0x14, 0x90170110}, | |
5946 | + {0x15, 0x0321101f}, | |
5947 | + {0x16, 0x03011020}, | |
5948 | + {0x18, 0x40000008}, | |
5949 | + {0x19, 0x411111f0}, | |
5950 | + {0x1a, 0x411111f0}, | |
5951 | + {0x1b, 0x411111f0}, | |
5952 | + {0x1d, 0x41000001}, | |
5953 | + {0x1e, 0x411111f0}, | |
5954 | + {0x1f, 0x411111f0}), | |
5955 | + SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, | |
5956 | + {0x12, 0x99a30140}, | |
5957 | + {0x14, 0x90170110}, | |
5958 | + {0x15, 0x0321101f}, | |
5959 | + {0x16, 0x03011020}, | |
5960 | + {0x18, 0x40000008}, | |
5961 | + {0x19, 0x411111f0}, | |
5962 | + {0x1a, 0x411111f0}, | |
5963 | + {0x1b, 0x411111f0}, | |
5964 | + {0x1d, 0x41000001}, | |
5965 | + {0x1e, 0x411111f0}, | |
5966 | + {0x1f, 0x411111f0}), | |
5967 | + SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, | |
5968 | + {0x12, 0x99a30150}, | |
5969 | + {0x14, 0x90170110}, | |
5970 | + {0x15, 0x0321101f}, | |
5971 | + {0x16, 0x03011020}, | |
5972 | + {0x18, 0x40000008}, | |
5973 | + {0x19, 0x411111f0}, | |
5974 | + {0x1a, 0x411111f0}, | |
5975 | + {0x1b, 0x411111f0}, | |
5976 | + {0x1d, 0x41000001}, | |
5977 | + {0x1e, 0x411111f0}, | |
5978 | + {0x1f, 0x411111f0}), | |
5979 | + SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE, | |
5980 | + {0x12, 0x411111f0}, | |
5981 | + {0x14, 0x90170110}, | |
5982 | + {0x15, 0x0321101f}, | |
5983 | + {0x16, 0x03011020}, | |
5984 | + {0x18, 0x40000008}, | |
5985 | + {0x19, 0x411111f0}, | |
5986 | + {0x1a, 0x411111f0}, | |
5987 | + {0x1b, 0x411111f0}, | |
5988 | + {0x1d, 0x41000001}, | |
5989 | + {0x1e, 0x411111f0}, | |
5990 | + {0x1f, 0x411111f0}), | |
5991 | + SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE, | |
5992 | + {0x12, 0x90a60130}, | |
5993 | + {0x14, 0x90170110}, | |
5994 | + {0x15, 0x0321101f}, | |
5995 | + {0x16, 0x40000000}, | |
5996 | + {0x18, 0x411111f0}, | |
5997 | + {0x19, 0x411111f0}, | |
5998 | + {0x1a, 0x411111f0}, | |
5999 | + {0x1b, 0x411111f0}, | |
6000 | + {0x1d, 0x40d6832d}, | |
6001 | + {0x1e, 0x411111f0}, | |
6002 | + {0x1f, 0x411111f0}), | |
6126 | 6003 | {} |
6127 | 6004 | }; |
6128 | 6005 |
sound/pci/hda/patch_sigmatel.c
... | ... | @@ -122,6 +122,12 @@ |
122 | 122 | }; |
123 | 123 | |
124 | 124 | enum { |
125 | + STAC_92HD95_HP_LED, | |
126 | + STAC_92HD95_HP_BASS, | |
127 | + STAC_92HD95_MODELS | |
128 | +}; | |
129 | + | |
130 | +enum { | |
125 | 131 | STAC_925x_REF, |
126 | 132 | STAC_M1, |
127 | 133 | STAC_M1_2, |
... | ... | @@ -4128,6 +4134,48 @@ |
4128 | 4134 | {} /* terminator */ |
4129 | 4135 | }; |
4130 | 4136 | |
4137 | +static void stac92hd95_fixup_hp_led(struct hda_codec *codec, | |
4138 | + const struct hda_fixup *fix, int action) | |
4139 | +{ | |
4140 | + struct sigmatel_spec *spec = codec->spec; | |
4141 | + | |
4142 | + if (action != HDA_FIXUP_ACT_PRE_PROBE) | |
4143 | + return; | |
4144 | + | |
4145 | + if (find_mute_led_cfg(codec, spec->default_polarity)) | |
4146 | + codec_dbg(codec, "mute LED gpio %d polarity %d\n", | |
4147 | + spec->gpio_led, | |
4148 | + spec->gpio_led_polarity); | |
4149 | +} | |
4150 | + | |
4151 | +static const struct hda_fixup stac92hd95_fixups[] = { | |
4152 | + [STAC_92HD95_HP_LED] = { | |
4153 | + .type = HDA_FIXUP_FUNC, | |
4154 | + .v.func = stac92hd95_fixup_hp_led, | |
4155 | + }, | |
4156 | + [STAC_92HD95_HP_BASS] = { | |
4157 | + .type = HDA_FIXUP_VERBS, | |
4158 | + .v.verbs = (const struct hda_verb[]) { | |
4159 | + {0x1a, 0x795, 0x00}, /* HPF to 100Hz */ | |
4160 | + {} | |
4161 | + }, | |
4162 | + .chained = true, | |
4163 | + .chain_id = STAC_92HD95_HP_LED, | |
4164 | + }, | |
4165 | +}; | |
4166 | + | |
4167 | +static const struct snd_pci_quirk stac92hd95_fixup_tbl[] = { | |
4168 | + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1911, "HP Spectre 13", STAC_92HD95_HP_BASS), | |
4169 | + {} /* terminator */ | |
4170 | +}; | |
4171 | + | |
4172 | +static const struct hda_model_fixup stac92hd95_models[] = { | |
4173 | + { .id = STAC_92HD95_HP_LED, .name = "hp-led" }, | |
4174 | + { .id = STAC_92HD95_HP_BASS, .name = "hp-bass" }, | |
4175 | + {} | |
4176 | +}; | |
4177 | + | |
4178 | + | |
4131 | 4179 | static int stac_parse_auto_config(struct hda_codec *codec) |
4132 | 4180 | { |
4133 | 4181 | struct sigmatel_spec *spec = codec->spec; |
4134 | 4182 | |
... | ... | @@ -4580,10 +4628,16 @@ |
4580 | 4628 | spec->gen.beep_nid = 0x19; /* digital beep */ |
4581 | 4629 | spec->pwr_nids = stac92hd95_pwr_nids; |
4582 | 4630 | spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids); |
4583 | - spec->default_polarity = -1; /* no default cfg */ | |
4631 | + spec->default_polarity = 0; | |
4584 | 4632 | |
4585 | 4633 | codec->patch_ops = stac_patch_ops; |
4586 | 4634 | |
4635 | + snd_hda_pick_fixup(codec, stac92hd95_models, stac92hd95_fixup_tbl, | |
4636 | + stac92hd95_fixups); | |
4637 | + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | |
4638 | + | |
4639 | + stac_setup_gpio(codec); | |
4640 | + | |
4587 | 4641 | err = stac_parse_auto_config(codec); |
4588 | 4642 | if (err < 0) { |
4589 | 4643 | stac_free(codec); |
... | ... | @@ -4591,6 +4645,8 @@ |
4591 | 4645 | } |
4592 | 4646 | |
4593 | 4647 | codec->proc_widget_hook = stac92hd_proc_hook; |
4648 | + | |
4649 | + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | |
4594 | 4650 | |
4595 | 4651 | return 0; |
4596 | 4652 | } |
sound/usb/card.c
... | ... | @@ -307,6 +307,11 @@ |
307 | 307 | |
308 | 308 | static int snd_usb_audio_free(struct snd_usb_audio *chip) |
309 | 309 | { |
310 | + struct list_head *p, *n; | |
311 | + | |
312 | + list_for_each_safe(p, n, &chip->ep_list) | |
313 | + snd_usb_endpoint_free(p); | |
314 | + | |
310 | 315 | mutex_destroy(&chip->mutex); |
311 | 316 | kfree(chip); |
312 | 317 | return 0; |
... | ... | @@ -585,7 +590,7 @@ |
585 | 590 | struct snd_usb_audio *chip) |
586 | 591 | { |
587 | 592 | struct snd_card *card; |
588 | - struct list_head *p, *n; | |
593 | + struct list_head *p; | |
589 | 594 | |
590 | 595 | if (chip == (void *)-1L) |
591 | 596 | return; |
592 | 597 | |
... | ... | @@ -598,14 +603,16 @@ |
598 | 603 | mutex_lock(®ister_mutex); |
599 | 604 | chip->num_interfaces--; |
600 | 605 | if (chip->num_interfaces <= 0) { |
606 | + struct snd_usb_endpoint *ep; | |
607 | + | |
601 | 608 | snd_card_disconnect(card); |
602 | 609 | /* release the pcm resources */ |
603 | 610 | list_for_each(p, &chip->pcm_list) { |
604 | 611 | snd_usb_stream_disconnect(p); |
605 | 612 | } |
606 | 613 | /* release the endpoint resources */ |
607 | - list_for_each_safe(p, n, &chip->ep_list) { | |
608 | - snd_usb_endpoint_free(p); | |
614 | + list_for_each_entry(ep, &chip->ep_list, list) { | |
615 | + snd_usb_endpoint_release(ep); | |
609 | 616 | } |
610 | 617 | /* release the midi resources */ |
611 | 618 | list_for_each(p, &chip->midi_list) { |
sound/usb/endpoint.c
... | ... | @@ -987,19 +987,30 @@ |
987 | 987 | } |
988 | 988 | |
989 | 989 | /** |
990 | + * snd_usb_endpoint_release: Tear down an snd_usb_endpoint | |
991 | + * | |
992 | + * @ep: the endpoint to release | |
993 | + * | |
994 | + * This function does not care for the endpoint's use count but will tear | |
995 | + * down all the streaming URBs immediately. | |
996 | + */ | |
997 | +void snd_usb_endpoint_release(struct snd_usb_endpoint *ep) | |
998 | +{ | |
999 | + release_urbs(ep, 1); | |
1000 | +} | |
1001 | + | |
1002 | +/** | |
990 | 1003 | * snd_usb_endpoint_free: Free the resources of an snd_usb_endpoint |
991 | 1004 | * |
992 | 1005 | * @ep: the list header of the endpoint to free |
993 | 1006 | * |
994 | - * This function does not care for the endpoint's use count but will tear | |
995 | - * down all the streaming URBs immediately and free all resources. | |
1007 | + * This free all resources of the given ep. | |
996 | 1008 | */ |
997 | 1009 | void snd_usb_endpoint_free(struct list_head *head) |
998 | 1010 | { |
999 | 1011 | struct snd_usb_endpoint *ep; |
1000 | 1012 | |
1001 | 1013 | ep = list_entry(head, struct snd_usb_endpoint, list); |
1002 | - release_urbs(ep, 1); | |
1003 | 1014 | kfree(ep); |
1004 | 1015 | } |
1005 | 1016 |
sound/usb/endpoint.h
... | ... | @@ -23,6 +23,7 @@ |
23 | 23 | void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); |
24 | 24 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); |
25 | 25 | void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); |
26 | +void snd_usb_endpoint_release(struct snd_usb_endpoint *ep); | |
26 | 27 | void snd_usb_endpoint_free(struct list_head *head); |
27 | 28 | |
28 | 29 | int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep); |