// SPDX-License-Identifier: GPL-2.0-or-later
/*
*/
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/bitrev.h>
#include <linux/ratelimit.h>
#include <linux/usb.h>
#include <linux/usb/audio.h>
#include <linux/usb/audio-v2.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "usbaudio.h"
#include "card.h"
#include "quirks.h"
#include "endpoint.h"
#include "helper.h"
#include "pcm.h"
#include "clock.h"
#include "power.h"
#include "media.h"
#include "implicit.h"
#define SUBSTREAM_FLAG_DATA_EP_STARTED 0
#define SUBSTREAM_FLAG_SYNC_EP_STARTED 1
/* return the estimated delay based on USB frame counters */
static snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
struct snd_pcm_runtime *runtime)
{
unsigned int current_frame_number;
unsigned int frame_diff;
int est_delay;
int queued;
if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
queued = bytes_to_frames(runtime, subs->inflight_bytes);
if (!queued)
return 0;
} else if (!subs->running) {
return 0;
}
current_frame_number = usb_get_current_frame_number(subs->dev);
/*
* HCD implementations use different widths, use lower 8 bits.
* The delay will
|