diff options
| author | Ajay Agarwal <ajaya@codeaurora.org> | 2019-01-08 19:26:44 +0530 |
|---|---|---|
| committer | Ajay Agarwal <ajaya@codeaurora.org> | 2019-01-09 10:16:50 +0530 |
| commit | b79ca632cb30fd9673b4d9459280317664726a72 (patch) | |
| tree | d1fd5f1450c555853ef99634f6a17f2a3c9f4843 | |
| parent | bf415bc503f97c20ab753de010f2420b4c25f9cc (diff) | |
Revert "usb: gadget: u_audio: remove cached period bytes value"
This reverts commit ad983d197d386070d172991e924b11ea12afd90e.
Required for clean picking of UAC opensource changes.
Change-Id: I5d59361d347616c29dc40dcded7e0b132faf42a4
Signed-off-by: Ajay Agarwal <ajaya@codeaurora.org>
| -rw-r--r-- | drivers/usb/gadget/function/u_audio.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index e9644137f720..717656e17afa 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -49,6 +49,8 @@ struct uac_rtd_params { void *rbuf; + size_t period_size; + unsigned max_psize; /* MaxPacketSize of endpoint */ struct uac_req *ureq; @@ -90,6 +92,7 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) unsigned pending; unsigned long flags; unsigned int hw_ptr; + bool update_alsa = false; int status = req->status; struct uac_req *ur = req->context; struct snd_pcm_substream *substream; @@ -142,6 +145,11 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) req->actual = req->length; } + pending = prm->hw_ptr % prm->period_size; + pending += req->actual; + if (pending >= prm->period_size) + update_alsa = true; + hw_ptr = prm->hw_ptr; spin_unlock_irqrestore(&prm->lock, flags); @@ -172,15 +180,14 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) spin_lock_irqsave(&prm->lock, flags); /* update hw_ptr after data is copied to memory */ prm->hw_ptr = (hw_ptr + req->actual) % runtime->dma_bytes; - hw_ptr = prm->hw_ptr; spin_unlock_irqrestore(&prm->lock, flags); - if ((hw_ptr % snd_pcm_lib_period_bytes(substream)) < req->actual) - snd_pcm_period_elapsed(substream); - exit: if (usb_ep_queue(ep, req, GFP_ATOMIC)) dev_err(uac->card->dev, "%d Error!\n", __LINE__); + + if (update_alsa) + snd_pcm_period_elapsed(substream); } static int uac_pcm_trigger(struct snd_pcm_substream *substream, int cmd) @@ -243,12 +250,35 @@ static snd_pcm_uframes_t uac_pcm_pointer(struct snd_pcm_substream *substream) static int uac_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { - return snd_pcm_lib_malloc_pages(substream, + struct snd_uac_chip *uac = snd_pcm_substream_chip(substream); + struct uac_rtd_params *prm; + int err; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + prm = &uac->p_prm; + else + prm = &uac->c_prm; + + err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); + if (err >= 0) + prm->period_size = params_period_bytes(hw_params); + + return err; } static int uac_pcm_hw_free(struct snd_pcm_substream *substream) { + struct snd_uac_chip *uac = snd_pcm_substream_chip(substream); + struct uac_rtd_params *prm; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + prm = &uac->p_prm; + else + prm = &uac->c_prm; + + prm->period_size = 0; + return snd_pcm_lib_free_pages(substream); } |
