Sound fixes for 3.7-rc5
Most of commits are for stable and regression fixes. Except for one fix for a regression in 3.7-rc4, there are all driver local changes, so nothing too much to worry. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJQm+fyAAoJEGwxgFQ9KSmk+VoP/jAxr9O8FXZj7mB7pl8nShSa 3ronGdTh/TTQbnql9+Rq7SYV6IBnEXqqun4lNZ1jB5SHrR7YUWHb3n1a0SDoYCG5 n9Ix3wpe9jezFhwI0QbVixjgxgk05li7YXPIlDYb2kTE38lbHefFqxBVwFPumZEs 5045RQVHQAQTZCUMyU3HASCZw90MxNsLtWLB8LwghwZ3fsJNlMC3y4d0NzmW5zlS /acd3eaZM1Uy1U0fsHJESUTivWPNToSldDVuoXutHVKx5jaPh8h9b0nG+5gt5FRs y3JB5KRLaI1xBR/uCJIfgnaYFAWGaAo6MEo/itRCjduuyk+opI0luweOsA+jTf1+ ykxuM+ER3arawullnIvn49dhqtdWn7aNZJWkhOiYXtzq9x15Ud3J4oOlmpH8optC xxCfpLdPVK3nzyrS1qKmOs35fOhtXQc6O5kLzs58nKl3WBq4oSTeAyxzXzw4nIYc 3b/4JjEozDsyHLT6UicZBdrKWUKDCU+CJCn1szjEJrpNhU22bQVDcRSJjpkfsBqt gngPMWu9vZygwpQ3yaxx29sFgb3btNdmjsKT89b0eQQ8Amsb9cesRhvVOHM3t+Wu DuBzokSLZPdBi6gAV0Oh70OJ+j6mB+S4LccNtA8TCSKPjW2U43yE9owYeVk27cYI 98yCKFnzjS2vheHQYSC1 =aTMq -----END PGP SIGNATURE----- Merge tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "Most of commits are for stable and regression fixes. Except for one fix for a regression in 3.7-rc4, there are all driver local changes, so nothing too much to worry." * tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: Fix card refcount unbalance ALSA: hda - Add new codec ALC668 and ALC900 (default name ALC1150) ALSA: hda - Improve HP depop when system enter to S3 ALSA: usb-audio: Fix crash at re-preparing the PCM stream ALSA: hdspm - Fix sync check reporting on RME RayDAT ALSA: hda - Add pin fixups for ASUS G75 ALSA: hda - Fix invalid connections in VT1802 codec ALSA: hda - Fix empty DAC filling in patch_via.c ALSA: hda - Force to reset IEC958 status bits for AD codecs ALSA: es1968: Add ESS vendor ID to pm_whitelist ALSA: HDA: Mark CS260x immutable structures const ALSA: HDA: Fix digital microphone on CS420x ALSA: hda: Cirrus: Fix coefficient index for beep configuration ALSA: hda - support Teradici 2200 host card audio ALSA: Fix typo in drivers sound
This commit is contained in:
Коммит
3f561834dc
|
@ -76,6 +76,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
|
|||
snd_card_unref(card);
|
||||
return -EFAULT;
|
||||
}
|
||||
snd_card_unref(card);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2454,6 +2454,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
|
|||
mutex_unlock(&pcm->open_mutex);
|
||||
if (err < 0)
|
||||
goto __error;
|
||||
snd_card_unref(pcm->card);
|
||||
return err;
|
||||
|
||||
__error:
|
||||
|
|
|
@ -2122,7 +2122,8 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file)
|
|||
pcm = snd_lookup_minor_data(iminor(inode),
|
||||
SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
|
||||
err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
|
||||
snd_card_unref(pcm->card);
|
||||
if (pcm)
|
||||
snd_card_unref(pcm->card);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -2135,7 +2136,8 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file)
|
|||
pcm = snd_lookup_minor_data(iminor(inode),
|
||||
SNDRV_DEVICE_TYPE_PCM_CAPTURE);
|
||||
err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
|
||||
snd_card_unref(pcm->card);
|
||||
if (pcm)
|
||||
snd_card_unref(pcm->card);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
|
|||
mreg = snd_minors[minor];
|
||||
if (mreg && mreg->type == type) {
|
||||
private_data = mreg->private_data;
|
||||
if (mreg->card_ptr)
|
||||
if (private_data && mreg->card_ptr)
|
||||
atomic_inc(&mreg->card_ptr->refcount);
|
||||
} else
|
||||
private_data = NULL;
|
||||
|
|
|
@ -54,7 +54,7 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type)
|
|||
mreg = snd_oss_minors[minor];
|
||||
if (mreg && mreg->type == type) {
|
||||
private_data = mreg->private_data;
|
||||
if (mreg->card_ptr)
|
||||
if (private_data && mreg->card_ptr)
|
||||
atomic_inc(&mreg->card_ptr->refcount);
|
||||
} else
|
||||
private_data = NULL;
|
||||
|
|
|
@ -426,7 +426,7 @@ static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = {
|
|||
},
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = "IEC958 Preample Capture Default",
|
||||
.name = "IEC958 Preamble Capture Default",
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ |
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
||||
.info = snd_ak4113_spdif_pinfo,
|
||||
|
|
|
@ -401,7 +401,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = {
|
|||
},
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = "IEC958 Preample Capture Default",
|
||||
.name = "IEC958 Preamble Capture Default",
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
||||
.info = snd_ak4114_spdif_pinfo,
|
||||
.get = snd_ak4114_spdif_pget,
|
||||
|
|
|
@ -380,7 +380,7 @@ static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = {
|
|||
},
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = "IEC958 Preample Capture Default",
|
||||
.name = "IEC958 Preamble Capture Default",
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
||||
.info = snd_ak4117_spdif_pinfo,
|
||||
.get = snd_ak4117_spdif_pget,
|
||||
|
|
|
@ -2655,6 +2655,8 @@ static struct ess_device_list pm_whitelist[] __devinitdata = {
|
|||
{ TYPE_MAESTRO2E, 0x1179 },
|
||||
{ TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */
|
||||
{ TYPE_MAESTRO2E, 0x1558 },
|
||||
{ TYPE_MAESTRO2E, 0x125d }, /* a PCI card, e.g. Terratec DMX */
|
||||
{ TYPE_MAESTRO2, 0x125d }, /* a PCI card, e.g. SF64-PCE2 */
|
||||
};
|
||||
|
||||
static struct ess_device_list mpu_blacklist[] __devinitdata = {
|
||||
|
|
|
@ -3563,6 +3563,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
|
|||
/* Teradici */
|
||||
{ PCI_DEVICE(0x6549, 0x1200),
|
||||
.driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
|
||||
{ PCI_DEVICE(0x6549, 0x2200),
|
||||
.driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
|
||||
/* Creative X-Fi (CA0110-IBG) */
|
||||
/* CTHDA chips */
|
||||
{ PCI_DEVICE(0x1102, 0x0010),
|
||||
|
|
|
@ -545,6 +545,7 @@ static int ad198x_build_pcms(struct hda_codec *codec)
|
|||
if (spec->multiout.dig_out_nid) {
|
||||
info++;
|
||||
codec->num_pcms++;
|
||||
codec->spdif_status_reset = 1;
|
||||
info->name = "AD198x Digital";
|
||||
info->pcm_type = HDA_PCM_TYPE_SPDIF;
|
||||
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
|
||||
|
|
|
@ -101,8 +101,8 @@ enum {
|
|||
#define CS420X_VENDOR_NID 0x11
|
||||
#define CS_DIG_OUT1_PIN_NID 0x10
|
||||
#define CS_DIG_OUT2_PIN_NID 0x15
|
||||
#define CS_DMIC1_PIN_NID 0x12
|
||||
#define CS_DMIC2_PIN_NID 0x0e
|
||||
#define CS_DMIC1_PIN_NID 0x0e
|
||||
#define CS_DMIC2_PIN_NID 0x12
|
||||
|
||||
/* coef indices */
|
||||
#define IDX_SPDIF_STAT 0x0000
|
||||
|
@ -1079,14 +1079,18 @@ static void init_input(struct hda_codec *codec)
|
|||
cs_automic(codec, NULL);
|
||||
|
||||
coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
|
||||
cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
|
||||
|
||||
coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG);
|
||||
if (is_active_pin(codec, CS_DMIC2_PIN_NID))
|
||||
coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */
|
||||
coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */
|
||||
if (is_active_pin(codec, CS_DMIC1_PIN_NID))
|
||||
coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off
|
||||
coef |= 1 << 3; /* DMIC1 2 chan on, GPIO0 off
|
||||
* No effect if SPDIF_OUT2 is
|
||||
* selected in IDX_SPDIF_CTL.
|
||||
*/
|
||||
cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
|
||||
|
||||
cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef);
|
||||
} else {
|
||||
if (spec->mic_detect)
|
||||
cs_automic(codec, NULL);
|
||||
|
@ -1107,7 +1111,7 @@ static const struct hda_verb cs_coef_init_verbs[] = {
|
|||
| 0x0400 /* Disable Coefficient Auto increment */
|
||||
)},
|
||||
/* Beep */
|
||||
{0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG},
|
||||
{0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG},
|
||||
{0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */
|
||||
|
||||
{} /* terminator */
|
||||
|
@ -1728,8 +1732,7 @@ static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol,
|
|||
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new cs421x_capture_source = {
|
||||
|
||||
static const struct snd_kcontrol_new cs421x_capture_source = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Capture Source",
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
|
||||
|
@ -1946,7 +1949,7 @@ static int cs421x_suspend(struct hda_codec *codec)
|
|||
}
|
||||
#endif
|
||||
|
||||
static struct hda_codec_ops cs421x_patch_ops = {
|
||||
static const struct hda_codec_ops cs421x_patch_ops = {
|
||||
.build_controls = cs421x_build_controls,
|
||||
.build_pcms = cs_build_pcms,
|
||||
.init = cs421x_init,
|
||||
|
|
|
@ -5840,7 +5840,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
|
|||
return alc_parse_auto_config(codec, alc269_ignore, ssids);
|
||||
}
|
||||
|
||||
static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
|
||||
static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
|
||||
{
|
||||
int val = alc_read_coef_idx(codec, 0x04);
|
||||
if (power_up)
|
||||
|
@ -5857,10 +5857,10 @@ static void alc269_shutup(struct hda_codec *codec)
|
|||
if (spec->codec_variant != ALC269_TYPE_ALC269VB)
|
||||
return;
|
||||
|
||||
if ((alc_get_coef0(codec) & 0x00ff) == 0x017)
|
||||
alc269_toggle_power_output(codec, 0);
|
||||
if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
|
||||
alc269_toggle_power_output(codec, 0);
|
||||
if (spec->codec_variant == ALC269_TYPE_ALC269VB)
|
||||
alc269vb_toggle_power_output(codec, 0);
|
||||
if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
|
||||
(alc_get_coef0(codec) & 0x00ff) == 0x018) {
|
||||
msleep(150);
|
||||
}
|
||||
}
|
||||
|
@ -5870,24 +5870,22 @@ static int alc269_resume(struct hda_codec *codec)
|
|||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
|
||||
if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
|
||||
if (spec->codec_variant == ALC269_TYPE_ALC269VB)
|
||||
alc269vb_toggle_power_output(codec, 0);
|
||||
if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
|
||||
(alc_get_coef0(codec) & 0x00ff) == 0x018) {
|
||||
alc269_toggle_power_output(codec, 0);
|
||||
msleep(150);
|
||||
}
|
||||
|
||||
codec->patch_ops.init(codec);
|
||||
|
||||
if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
|
||||
if (spec->codec_variant == ALC269_TYPE_ALC269VB)
|
||||
alc269vb_toggle_power_output(codec, 1);
|
||||
if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
|
||||
(alc_get_coef0(codec) & 0x00ff) == 0x017) {
|
||||
alc269_toggle_power_output(codec, 1);
|
||||
msleep(200);
|
||||
}
|
||||
|
||||
if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
|
||||
(alc_get_coef0(codec) & 0x00ff) == 0x018)
|
||||
alc269_toggle_power_output(codec, 1);
|
||||
|
||||
snd_hda_codec_resume_amp(codec);
|
||||
snd_hda_codec_resume_cache(codec);
|
||||
hda_call_check_power_status(codec, 0x01);
|
||||
|
@ -7079,6 +7077,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
|
|||
.patch = patch_alc662 },
|
||||
{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
|
||||
{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
|
||||
{ .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
|
||||
{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
|
||||
{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
|
||||
{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
|
||||
|
@ -7096,6 +7095,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
|
|||
{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
|
||||
{ .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
|
||||
{ .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
|
||||
{ .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 },
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
|
|
|
@ -1809,11 +1809,11 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec)
|
|||
{
|
||||
struct via_spec *spec = codec->spec;
|
||||
const struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||
int i, dac_num;
|
||||
int i;
|
||||
hda_nid_t nid;
|
||||
|
||||
spec->multiout.num_dacs = 0;
|
||||
spec->multiout.dac_nids = spec->private_dac_nids;
|
||||
dac_num = 0;
|
||||
for (i = 0; i < cfg->line_outs; i++) {
|
||||
hda_nid_t dac = 0;
|
||||
nid = cfg->line_out_pins[i];
|
||||
|
@ -1824,16 +1824,13 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec)
|
|||
if (!i && parse_output_path(codec, nid, dac, 1,
|
||||
&spec->out_mix_path))
|
||||
dac = spec->out_mix_path.path[0];
|
||||
if (dac) {
|
||||
spec->private_dac_nids[i] = dac;
|
||||
dac_num++;
|
||||
}
|
||||
if (dac)
|
||||
spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
|
||||
}
|
||||
if (!spec->out_path[0].depth && spec->out_mix_path.depth) {
|
||||
spec->out_path[0] = spec->out_mix_path;
|
||||
spec->out_mix_path.depth = 0;
|
||||
}
|
||||
spec->multiout.num_dacs = dac_num;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3628,6 +3625,7 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
|
|||
*/
|
||||
enum {
|
||||
VIA_FIXUP_INTMIC_BOOST,
|
||||
VIA_FIXUP_ASUS_G75,
|
||||
};
|
||||
|
||||
static void via_fixup_intmic_boost(struct hda_codec *codec,
|
||||
|
@ -3642,13 +3640,35 @@ static const struct hda_fixup via_fixups[] = {
|
|||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = via_fixup_intmic_boost,
|
||||
},
|
||||
[VIA_FIXUP_ASUS_G75] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
/* set 0x24 and 0x33 as speakers */
|
||||
{ 0x24, 0x991301f0 },
|
||||
{ 0x33, 0x991301f1 }, /* subwoofer */
|
||||
{ }
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk vt2002p_fixups[] = {
|
||||
SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75),
|
||||
SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST),
|
||||
{}
|
||||
};
|
||||
|
||||
/* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e
|
||||
* Replace this with mixer NID 0x1c
|
||||
*/
|
||||
static void fix_vt1802_connections(struct hda_codec *codec)
|
||||
{
|
||||
static hda_nid_t conn_24[] = { 0x14, 0x1c };
|
||||
static hda_nid_t conn_33[] = { 0x1c };
|
||||
|
||||
snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24);
|
||||
snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33);
|
||||
}
|
||||
|
||||
/* patch for vt2002P */
|
||||
static int patch_vt2002P(struct hda_codec *codec)
|
||||
{
|
||||
|
@ -3663,6 +3683,8 @@ static int patch_vt2002P(struct hda_codec *codec)
|
|||
spec->aa_mix_nid = 0x21;
|
||||
override_mic_boost(codec, 0x2b, 0, 3, 40);
|
||||
override_mic_boost(codec, 0x29, 0, 3, 40);
|
||||
if (spec->codec_type == VT1802)
|
||||
fix_vt1802_connections(codec);
|
||||
add_secret_dac_path(codec);
|
||||
|
||||
snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups);
|
||||
|
|
|
@ -3979,7 +3979,8 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
|
|||
case 8: /* SYNC IN */
|
||||
val = hdspm_sync_in_sync_check(hdspm); break;
|
||||
default:
|
||||
val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1);
|
||||
val = hdspm_s1_sync_check(hdspm,
|
||||
kcontrol->private_value-1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4899,7 +4900,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
|
|||
insel = "Coaxial";
|
||||
break;
|
||||
default:
|
||||
insel = "Unkown";
|
||||
insel = "Unknown";
|
||||
}
|
||||
|
||||
snd_iprintf(buffer,
|
||||
|
|
|
@ -763,7 +763,7 @@ static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai,
|
|||
if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) {
|
||||
cs42l52->sysclk = freq;
|
||||
} else {
|
||||
dev_err(codec->dev, "Invalid freq paramter\n");
|
||||
dev_err(codec->dev, "Invalid freq parameter\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -3722,7 +3722,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
|
|||
} while (count--);
|
||||
|
||||
if (count == 0)
|
||||
dev_warn(codec->dev, "No impedence range reported for jack\n");
|
||||
dev_warn(codec->dev, "No impedance range reported for jack\n");
|
||||
|
||||
#ifndef CONFIG_SND_SOC_WM8994_MODULE
|
||||
trace_snd_soc_jack_irq(dev_name(codec->dev));
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#define EP_FLAG_ACTIVATED 0
|
||||
#define EP_FLAG_RUNNING 1
|
||||
#define EP_FLAG_STOPPING 2
|
||||
|
||||
/*
|
||||
* snd_usb_endpoint is a model that abstracts everything related to an
|
||||
|
@ -502,10 +503,20 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep)
|
|||
if (alive)
|
||||
snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n",
|
||||
alive, ep->ep_num);
|
||||
clear_bit(EP_FLAG_STOPPING, &ep->flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sync the pending stop operation;
|
||||
* this function itself doesn't trigger the stop operation
|
||||
*/
|
||||
void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep)
|
||||
{
|
||||
if (ep && test_bit(EP_FLAG_STOPPING, &ep->flags))
|
||||
wait_clear_urbs(ep);
|
||||
}
|
||||
|
||||
/*
|
||||
* unlink active urbs.
|
||||
*/
|
||||
|
@ -918,6 +929,8 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
|
|||
|
||||
if (wait)
|
||||
wait_clear_urbs(ep);
|
||||
else
|
||||
set_bit(EP_FLAG_STOPPING, &ep->flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
|
|||
int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep);
|
||||
void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
|
||||
int force, int can_sleep, int wait);
|
||||
void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep);
|
||||
int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
|
||||
int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);
|
||||
void snd_usb_endpoint_free(struct list_head *head);
|
||||
|
|
|
@ -568,6 +568,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
|
|||
goto unlock;
|
||||
}
|
||||
|
||||
snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
|
||||
snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
|
||||
|
||||
ret = set_format(subs, subs->cur_audiofmt);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
|
|
Загрузка…
Ссылка в новой задаче