ALSA: usb-audio: Apply 48kHz fixed rate playback for Jabra Evolve 65 headset
authorTakashi Iwai <tiwai@suse.de>
Tue, 11 Feb 2020 11:14:19 +0000 (12:14 +0100)
committerTakashi Iwai <tiwai@suse.de>
Tue, 11 Feb 2020 11:17:06 +0000 (12:17 +0100)
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>
sound/usb/format.c

index 9260136..50cb183 100644 (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;