source: trunk/target/linux/xburst/patches-3.2/0016-ASoC-JZ4740-Support-buffer-size-that-is-not-a-multip.patch @ 31218

Last change on this file since 31218 was 31218, checked in by mirko, 4 years ago

[target/xburst] level up target xburst to linux kernel version 3.2.1

Thanks to the qi-hardware project - especially to Lars, Maarten and Xiangfu

File size: 3.1 KB
  • sound/soc/jz4740/jz4740-pcm.c

    From 8a5087fe59e31efb8641e704058328997c3c8ff1 Mon Sep 17 00:00:00 2001
    From: Maarten ter Huurne <maarten@treewalker.org>
    Date: Wed, 10 Aug 2011 00:25:11 +0200
    Subject: [PATCH 16/21] ASoC: JZ4740: Support buffer size that is not a
     multiple of period size.
    
    This fixes glitches triggered by libao, which sets time-based intervals
    instead of byte-based intervals like SDL does.
    
    Thanks to Paul Cercueil for figuring out that the buffer size was causing
    the glitches and to Lars Clausen for helping me write the fix.
    ---
     sound/soc/jz4740/jz4740-pcm.c |   21 ++++++++++++++++++---
     1 files changed, 18 insertions(+), 3 deletions(-)
    
    diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c
    index d1989cd..1f9a005 100644
    a b  
    3131 
    3232struct jz4740_runtime_data { 
    3333        unsigned long dma_period; 
     34        unsigned long dma_period_left; 
    3435        dma_addr_t dma_start; 
    3536        dma_addr_t dma_pos; 
    3637        dma_addr_t dma_end; 
    static void jz4740_pcm_start_transfer(struct jz4740_runtime_data *prtd, 
    6768        if (prtd->dma_pos == prtd->dma_end) 
    6869                prtd->dma_pos = prtd->dma_start; 
    6970 
    70         if (prtd->dma_pos + prtd->dma_period > prtd->dma_end) 
     71        if (prtd->dma_period_left == 0) 
     72                prtd->dma_period_left = prtd->dma_period; 
     73 
     74        if (prtd->dma_pos + prtd->dma_period_left > prtd->dma_end) 
    7175                count = prtd->dma_end - prtd->dma_pos; 
    7276        else 
    73                 count = prtd->dma_period; 
     77                count = prtd->dma_period_left; 
    7478 
    7579        jz4740_dma_disable(prtd->dma); 
    7680 
    static void jz4740_pcm_start_transfer(struct jz4740_runtime_data *prtd, 
    8589        jz4740_dma_set_transfer_count(prtd->dma, count); 
    8690 
    8791        prtd->dma_pos += count; 
     92        prtd->dma_period_left -= count; 
    8893 
    8994        jz4740_dma_enable(prtd->dma); 
    9095} 
    static void jz4740_pcm_dma_transfer_done(struct jz4740_dma_chan *dma, int err, 
    96101        struct snd_pcm_runtime *runtime = substream->runtime; 
    97102        struct jz4740_runtime_data *prtd = runtime->private_data; 
    98103 
    99         snd_pcm_period_elapsed(substream); 
     104        if (prtd->dma_period_left == 0) 
     105                snd_pcm_period_elapsed(substream); 
    100106 
    101107        jz4740_pcm_start_transfer(prtd, substream); 
    102108} 
    static int jz4740_pcm_hw_params(struct snd_pcm_substream *substream, 
    133139        runtime->dma_bytes = params_buffer_bytes(params); 
    134140 
    135141        prtd->dma_period = params_period_bytes(params); 
     142        prtd->dma_period_left = 0; 
    136143        prtd->dma_start = runtime->dma_addr; 
    137144        prtd->dma_pos = prtd->dma_start; 
    138145        prtd->dma_end = prtd->dma_start + runtime->dma_bytes; 
    static int jz4740_pcm_prepare(struct snd_pcm_substream *substream) 
    160167        if (!prtd->dma) 
    161168                return -EBUSY; 
    162169 
     170        prtd->dma_period_left = 0; 
    163171        prtd->dma_pos = prtd->dma_start; 
    164172 
    165173        return 0; 
    static int jz4740_pcm_open(struct snd_pcm_substream *substream) 
    219227        if (prtd == NULL) 
    220228                return -ENOMEM; 
    221229 
     230        /* Force period and buffer size to be a multiple of the DMA transfer 
     231         * size, which is 16 bytes. */ 
     232        snd_pcm_hw_constraint_step(runtime, 0, 
     233                                   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 16); 
     234        snd_pcm_hw_constraint_step(runtime, 0, 
     235                                   SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16); 
     236 
    222237        snd_soc_set_runtime_hwparams(substream, &jz4740_pcm_hardware); 
    223238 
    224239        runtime->private_data = prtd; 
Note: See TracBrowser for help on using the repository browser.