@@ -157,6 +157,31 @@ find_substream_format(struct snd_usb_substream *subs,
157157 true, subs );
158158}
159159
160+ bool snd_usb_pcm_has_fixed_rate (struct snd_usb_substream * subs )
161+ {
162+ const struct audioformat * fp ;
163+ struct snd_usb_audio * chip = subs -> stream -> chip ;
164+ int rate = -1 ;
165+
166+ if (!(chip -> quirk_flags & QUIRK_FLAG_FIXED_RATE ))
167+ return false;
168+ list_for_each_entry (fp , & subs -> fmt_list , list ) {
169+ if (fp -> rates & SNDRV_PCM_RATE_CONTINUOUS )
170+ return false;
171+ if (fp -> nr_rates < 1 )
172+ continue ;
173+ if (fp -> nr_rates > 1 )
174+ return false;
175+ if (rate < 0 ) {
176+ rate = fp -> rate_table [0 ];
177+ continue ;
178+ }
179+ if (rate != fp -> rate_table [0 ])
180+ return false;
181+ }
182+ return true;
183+ }
184+
160185static int init_pitch_v1 (struct snd_usb_audio * chip , int ep )
161186{
162187 struct usb_device * dev = chip -> dev ;
@@ -450,12 +475,14 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
450475 struct snd_usb_audio * chip = subs -> stream -> chip ;
451476 const struct audioformat * fmt ;
452477 const struct audioformat * sync_fmt ;
478+ bool fixed_rate , sync_fixed_rate ;
453479 int ret ;
454480
455481 ret = snd_media_start_pipeline (subs );
456482 if (ret )
457483 return ret ;
458484
485+ fixed_rate = snd_usb_pcm_has_fixed_rate (subs );
459486 fmt = find_substream_format (subs , hw_params );
460487 if (!fmt ) {
461488 usb_audio_dbg (chip ,
@@ -469,7 +496,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
469496 if (fmt -> implicit_fb ) {
470497 sync_fmt = snd_usb_find_implicit_fb_sync_format (chip , fmt ,
471498 hw_params ,
472- !substream -> stream );
499+ !substream -> stream ,
500+ & sync_fixed_rate );
473501 if (!sync_fmt ) {
474502 usb_audio_dbg (chip ,
475503 "cannot find sync format: ep=0x%x, iface=%d:%d, format=%s, rate=%d, channels=%d\n" ,
@@ -482,6 +510,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
482510 }
483511 } else {
484512 sync_fmt = fmt ;
513+ sync_fixed_rate = fixed_rate ;
485514 }
486515
487516 ret = snd_usb_lock_shutdown (chip );
@@ -499,7 +528,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
499528 close_endpoints (chip , subs );
500529 }
501530
502- subs -> data_endpoint = snd_usb_endpoint_open (chip , fmt , hw_params , false);
531+ subs -> data_endpoint = snd_usb_endpoint_open (chip , fmt , hw_params , false, fixed_rate );
503532 if (!subs -> data_endpoint ) {
504533 ret = - EINVAL ;
505534 goto unlock ;
@@ -508,7 +537,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
508537 if (fmt -> sync_ep ) {
509538 subs -> sync_endpoint = snd_usb_endpoint_open (chip , sync_fmt ,
510539 hw_params ,
511- fmt == sync_fmt );
540+ fmt == sync_fmt ,
541+ sync_fixed_rate );
512542 if (!subs -> sync_endpoint ) {
513543 ret = - EINVAL ;
514544 goto unlock ;
0 commit comments