Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 145007
b: refs/heads/master
c: 82075af
h: refs/heads/master
i:
  145005: e1e1fd7
  145003: 1d67600
  144999: c7a878d
  144991: b740203
v: v3
  • Loading branch information
David Brownell authored and Mark Brown committed May 15, 2009
1 parent 89477e8 commit a7d1391
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1ffafeb556d50de8039e14f1cbbe58e9e4549915
refs/heads/master: 82075af6cb9b4918ab52a7100425b09fae6aafe3
71 changes: 42 additions & 29 deletions trunk/sound/soc/davinci/davinci-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <sound/soc.h>

#include <asm/dma.h>
#include <mach/edma.h>

#include "davinci-pcm.h"

Expand Down Expand Up @@ -51,7 +52,7 @@ struct davinci_runtime_data {
spinlock_t lock;
int period; /* current DMA period */
int master_lch; /* Master DMA channel */
int slave_lch; /* Slave DMA channel */
int slave_lch; /* linked parameter RAM reload slot */
struct davinci_pcm_dma_params *params; /* DMA params */
};

Expand Down Expand Up @@ -90,18 +91,18 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
dst_bidx = data_type;
}

davinci_set_dma_src_params(lch, src, INCR, W8BIT);
davinci_set_dma_dest_params(lch, dst, INCR, W8BIT);
davinci_set_dma_src_index(lch, src_bidx, 0);
davinci_set_dma_dest_index(lch, dst_bidx, 0);
davinci_set_dma_transfer_params(lch, data_type, count, 1, 0, ASYNC);
edma_set_src(lch, src, INCR, W8BIT);
edma_set_dest(lch, dst, INCR, W8BIT);
edma_set_src_index(lch, src_bidx, 0);
edma_set_dest_index(lch, dst_bidx, 0);
edma_set_transfer_params(lch, data_type, count, 1, 0, ASYNC);

prtd->period++;
if (unlikely(prtd->period >= runtime->periods))
prtd->period = 0;
}

static void davinci_pcm_dma_irq(int lch, u16 ch_status, void *data)
static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data)
{
struct snd_pcm_substream *substream = data;
struct davinci_runtime_data *prtd = substream->runtime->private_data;
Expand All @@ -125,7 +126,7 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
struct davinci_runtime_data *prtd = substream->runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
int tcc = TCC_ANY;
struct edmacc_param p_ram;
int ret;

if (!dma_data)
Expand All @@ -134,22 +135,34 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
prtd->params = dma_data;

/* Request master DMA channel */
ret = davinci_request_dma(prtd->params->channel, prtd->params->name,
ret = edma_alloc_channel(prtd->params->channel,
davinci_pcm_dma_irq, substream,
&prtd->master_lch, &tcc, EVENTQ_0);
if (ret)
EVENTQ_0);
if (ret < 0)
return ret;
prtd->master_lch = ret;

/* Request slave DMA channel */
ret = davinci_request_dma(PARAM_ANY, "Link",
NULL, NULL, &prtd->slave_lch, &tcc, EVENTQ_0);
if (ret) {
davinci_free_dma(prtd->master_lch);
/* Request parameter RAM reload slot */
ret = edma_alloc_slot(EDMA_SLOT_ANY);
if (ret < 0) {
edma_free_channel(prtd->master_lch);
return ret;
}

/* Link slave DMA channel in loopback */
davinci_dma_link_lch(prtd->slave_lch, prtd->slave_lch);
prtd->slave_lch = ret;

/* Issue transfer completion IRQ when the channel completes a
* transfer, then always reload from the same slot (by a kind
* of loopback link). The completion IRQ handler will update
* the reload slot with a new buffer.
*
* REVISIT save p_ram here after setting up everything except
* the buffer and its length (ccnt) ... use it as a template
* so davinci_pcm_enqueue_dma() takes less time in IRQ.
*/
edma_read_slot(prtd->slave_lch, &p_ram);
p_ram.opt |= TCINTEN | EDMA_TCC(prtd->master_lch);
p_ram.link_bcntrld = prtd->slave_lch << 5;
edma_write_slot(prtd->slave_lch, &p_ram);

return 0;
}
Expand All @@ -165,12 +178,12 @@ static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
davinci_start_dma(prtd->master_lch);
edma_start(prtd->master_lch);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
davinci_stop_dma(prtd->master_lch);
edma_stop(prtd->master_lch);
break;
default:
ret = -EINVAL;
Expand All @@ -185,14 +198,14 @@ static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
{
struct davinci_runtime_data *prtd = substream->runtime->private_data;
struct paramentry_descriptor temp;
struct edmacc_param temp;

prtd->period = 0;
davinci_pcm_enqueue_dma(substream);

/* Get slave channel dma params for master channel startup */
davinci_get_dma_params(prtd->slave_lch, &temp);
davinci_set_dma_params(prtd->master_lch, &temp);
/* Copy self-linked parameter RAM entry into master channel */
edma_read_slot(prtd->slave_lch, &temp);
edma_write_slot(prtd->master_lch, &temp);

return 0;
}
Expand All @@ -208,7 +221,7 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream)

spin_lock(&prtd->lock);

davinci_dma_getposition(prtd->master_lch, &src, &dst);
edma_get_position(prtd->master_lch, &src, &dst);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
count = src - runtime->dma_addr;
else
Expand Down Expand Up @@ -253,10 +266,10 @@ static int davinci_pcm_close(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct davinci_runtime_data *prtd = runtime->private_data;

davinci_dma_unlink_lch(prtd->slave_lch, prtd->slave_lch);
edma_unlink(prtd->slave_lch);

davinci_free_dma(prtd->slave_lch);
davinci_free_dma(prtd->master_lch);
edma_free_slot(prtd->slave_lch);
edma_free_channel(prtd->master_lch);

kfree(prtd);

Expand Down

0 comments on commit a7d1391

Please sign in to comment.