ALSA: usb-audio: Apply 48kHz fixed rate playback for Jabra Evolve 65 headset

Jabra Evolve 65 headset appears as if supporting lower rates than
48kHz, but it actually doesn't work but with 48kHz for playback.

This patch applies a workaround to enforce the 48kHz like LINE6
devices already did.  The workaround is put in a unified helper
function, set_fixed_rate(), to be called from both places now.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=206149
Link: https://lore.kernel.org/r/20200211111419.5895-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2020-02-11 12:14:19 +01:00
parent bb6d3fb354
commit 74f73476c3
1 changed files with 22 additions and 11 deletions

View File

@ -151,6 +151,19 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
return pcm_formats;
}
static int set_fixed_rate(struct audioformat *fp, int rate, int rate_bits)
{
kfree(fp->rate_table);
fp->rate_table = kmalloc(sizeof(int), GFP_KERNEL);
if (!fp->rate_table)
return -ENOMEM;
fp->nr_rates = 1;
fp->rate_min = rate;
fp->rate_max = rate;
fp->rates = rate_bits;
fp->rate_table[0] = rate;
return 0;
}
/*
* parse the format descriptor and stores the possible sample rates
@ -223,6 +236,14 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof
fp->rate_min = combine_triple(&fmt[offset + 1]);
fp->rate_max = combine_triple(&fmt[offset + 4]);
}
/* Jabra Evolve 65 headset */
if (chip->usb_id == USB_ID(0x0b0e, 0x030b)) {
/* only 48kHz for playback while keeping 16kHz for capture */
if (fp->nr_rates != 1)
return set_fixed_rate(fp, 48000, SNDRV_PCM_RATE_48000);
}
return 0;
}
@ -299,17 +320,7 @@ static int line6_parse_audio_format_rates_quirk(struct snd_usb_audio *chip,
case USB_ID(0x0e41, 0x4248): /* Line6 Helix >= fw 2.82 */
case USB_ID(0x0e41, 0x4249): /* Line6 Helix Rack >= fw 2.82 */
case USB_ID(0x0e41, 0x424a): /* Line6 Helix LT >= fw 2.82 */
/* supported rates: 48Khz */
kfree(fp->rate_table);
fp->rate_table = kmalloc(sizeof(int), GFP_KERNEL);
if (!fp->rate_table)
return -ENOMEM;
fp->nr_rates = 1;
fp->rate_min = 48000;
fp->rate_max = 48000;
fp->rates = SNDRV_PCM_RATE_48000;
fp->rate_table[0] = 48000;
return 0;
return set_fixed_rate(fp, 48000, SNDRV_PCM_RATE_48000);
}
return -ENODEV;