USB: gadget: f_audio_source: Adjust packet timing to reduce glitches
Mike Lockwood [Sun, 27 May 2012 22:41:53 +0000 (15:41 -0700)]
Increase max packet size and clean up timing logic so we can better
recover from not getting an interrupt in time for a SOF.

Bug 1026047

Signed-off-by: Mike Lockwood <lockwood@google.com>
(cherry picked from commit 3d2096a7959d023bc31a3cf934c3d425de01c94f)

Signed-off-by: Rakesh Bodla <rbodla@nvidia.com>
Change-Id: I0a0a6f448e71e4a0c478bb44cadc54fa021e13e4
Reviewed-on: http://git-master/r/123344
Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>

drivers/usb/gadget/f_audio_source.c

index c762543..3ba7d75 100644 (file)
 /* Each frame is two 16 bit integers (one per channel) */
 #define BYTES_PER_FRAME 4
 #define FRAMES_PER_MSEC (SAMPLE_RATE / 1000)
-/* Add one to FRAMES_PER_MSEC to adjust for round-off above */
-#define IN_EP_MAX_PACKET_SIZE ((FRAMES_PER_MSEC + 1) * BYTES_PER_FRAME)
+
+#define IN_EP_MAX_PACKET_SIZE 256
 
 /* Number of requests to allocate */
-#define IN_EP_REQ_COUNT 16
+#define IN_EP_REQ_COUNT 4
 
 #define AUDIO_AC_INTERFACE     0
 #define AUDIO_AS_INTERFACE     1
@@ -339,13 +339,10 @@ static void audio_send(struct audio_dev *audio)
 
        runtime = audio->substream->runtime;
 
+       /* compute number of frames to send */
        now = ktime_get();
        msecs = ktime_to_ns(now) - ktime_to_ns(audio->start_time);
        do_div(msecs, 1000000);
-       /* Add a bit to msecs so we queue some extra requests in case
-        * we miss a few SOFs due to interrupts being disabled or CPU load.
-        */
-       msecs += IN_EP_REQ_COUNT/2;
        frames = msecs * SAMPLE_RATE;
        do_div(frames, 1000);
 
@@ -353,11 +350,15 @@ static void audio_send(struct audio_dev *audio)
         * If we get too far behind it is better to drop some frames than
         * to keep sending data too fast in an attempt to catch up.
         */
-       if (frames - audio->frames_sent > 2 * FRAMES_PER_MSEC * IN_EP_REQ_COUNT)
+       if (frames - audio->frames_sent > 10 * FRAMES_PER_MSEC)
                audio->frames_sent = frames - FRAMES_PER_MSEC;
 
        frames -= audio->frames_sent;
 
+       /* We need to send something to keep the pipeline going */
+       if (frames <= 0)
+               frames = FRAMES_PER_MSEC;
+
        while (frames > 0) {
                req = audio_req_get(audio);
                if (!req)