Merge branch 'for-linus' into for-next

This commit is contained in:
Takashi Iwai 2021-08-30 08:04:04 +02:00
commit f7b82b1262
6 changed files with 24 additions and 3 deletions

View File

@ -1746,7 +1746,7 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream,
channels = params_channels(params);
frame_size = snd_pcm_format_size(format, channels);
if (frame_size > 0)
params->fifo_size /= (unsigned)frame_size;
params->fifo_size /= frame_size;
}
return 0;
}

View File

@ -68,6 +68,7 @@ static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
static bool ignore_ctl_error;
static bool autoclock = true;
static bool lowlatency = true;
static char *quirk_alias[SNDRV_CARDS];
static char *delayed_register[SNDRV_CARDS];
static bool implicit_fb[SNDRV_CARDS];
@ -93,6 +94,8 @@ MODULE_PARM_DESC(ignore_ctl_error,
"Ignore errors from USB controller for mixer interfaces.");
module_param(autoclock, bool, 0444);
MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (default: yes).");
module_param(lowlatency, bool, 0444);
MODULE_PARM_DESC(lowlatency, "Enable low latency playback (default: yes).");
module_param_array(quirk_alias, charp, NULL, 0444);
MODULE_PARM_DESC(quirk_alias, "Quirk aliases, e.g. 0123abcd:5678beef.");
module_param_array(delayed_register, charp, NULL, 0444);
@ -623,6 +626,7 @@ static int snd_usb_audio_create(struct usb_interface *intf,
chip->setup = device_setup[idx];
chip->generic_implicit_fb = implicit_fb[idx];
chip->autoclock = autoclock;
chip->lowlatency = lowlatency;
atomic_set(&chip->active, 1); /* avoid autopm during probing */
atomic_set(&chip->usage_count, 0);
atomic_set(&chip->shutdown, 0);

View File

@ -94,6 +94,7 @@ struct snd_usb_endpoint {
struct list_head ready_playback_urbs; /* playback URB FIFO for implicit fb */
unsigned int nurbs; /* # urbs */
unsigned int nominal_queue_size; /* total buffer sizes in URBs */
unsigned long active_mask; /* bitmask of active urbs */
unsigned long unlink_mask; /* bitmask of unlinked urbs */
char *syncbuf; /* sync buffer for all sync URBs */
@ -187,6 +188,7 @@ struct snd_usb_substream {
} dsd_dop;
bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */
bool early_playback_start; /* early start needed for playback? */
struct media_ctl *media_ctl;
};

View File

@ -1132,6 +1132,10 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep)
INIT_LIST_HEAD(&u->ready_list);
}
/* total buffer bytes of all URBs plus the next queue;
* referred in pcm.c
*/
ep->nominal_queue_size = maxsize * urb_packs * (ep->nurbs + 1);
return 0;
out_of_memory:

View File

@ -614,6 +614,15 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
subs->period_elapsed_pending = 0;
runtime->delay = 0;
/* check whether early start is needed for playback stream */
subs->early_playback_start =
subs->direction == SNDRV_PCM_STREAM_PLAYBACK &&
(!chip->lowlatency ||
(subs->data_endpoint->nominal_queue_size >= subs->buffer_bytes));
if (subs->early_playback_start)
ret = start_endpoints(subs);
unlock:
snd_usb_unlock_shutdown(chip);
return ret;
@ -1394,7 +1403,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
subs->trigger_tstamp_pending_update = false;
}
if (period_elapsed && !subs->running) {
if (period_elapsed && !subs->running && !subs->early_playback_start) {
subs->period_elapsed_pending = 1;
period_elapsed = 0;
}
@ -1448,7 +1457,8 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
prepare_playback_urb,
retire_playback_urb,
subs);
if (cmd == SNDRV_PCM_TRIGGER_START) {
if (!subs->early_playback_start &&
cmd == SNDRV_PCM_TRIGGER_START) {
err = start_endpoints(subs);
if (err < 0) {
snd_usb_endpoint_set_callback(subs->data_endpoint,

View File

@ -55,6 +55,7 @@ struct snd_usb_audio {
bool generic_implicit_fb; /* from the 'implicit_fb' module param */
bool autoclock; /* from the 'autoclock' module param */
bool lowlatency; /* from the 'lowlatency' module param */
struct usb_host_interface *ctrl_intf; /* the audio control interface */
struct media_device *media_dev;
struct media_intf_devnode *ctl_intf_media_devnode;