summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorRobert Marklund <robert.marklund@stericsson.com>2011-05-25 17:37:45 +0200
committerUlf Hansson <ulf.hansson@stericsson.com>2011-09-19 15:15:20 +0200
commit1f2da4feb098871ccf3b54aa6df14ae12b8b7ebe (patch)
treefac7b3e8c9df5e9f5a019a07d31f70aad284d628 /sound
parent882251d22413247fa39466bf19749089a2563257 (diff)
ux500-ASoC: Update ux500 driver to use dmaengine
ST-Ericsson Linux next: 342252 ST-Ericsson ID: 342253 ST-Ericsson FOSS-OUT ID: Trivial Signed-off-by: Robert Marklund <robert.marklund@stericsson.com> Change-Id: I6d0b04aaa9f3e0d170cb3dd2510960f606c4435f Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/24728 Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c26
-rw-r--r--sound/soc/ux500/ux500_msp_dai.h4
-rw-r--r--sound/soc/ux500/ux500_pcm.c35
-rw-r--r--sound/soc/ux500/ux500_pcm.h1
4 files changed, 30 insertions, 36 deletions
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 354a0edb8bf..78e78e1fc04 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -97,17 +97,15 @@ dma_addr_t ux500_msp_dai_i2s_get_pointer(int dai_idx, int stream_id)
}
int ux500_msp_dai_i2s_configure_sg(dma_addr_t dma_addr,
- int sg_len,
- int sg_size,
+ int period_cnt,
+ size_t period_len,
int dai_idx,
int stream_id)
{
struct ux500_platform_drvdata *drvdata = &platform_drvdata[dai_idx];
struct i2s_message message;
struct i2s_device *i2s_dev;
- int i;
int ret = 0;
- struct scatterlist *sg;
bool playback_req_valid =
(drvdata->playback_active &&
stream_id == SNDRV_PCM_STREAM_PLAYBACK);
@@ -115,11 +113,11 @@ int ux500_msp_dai_i2s_configure_sg(dma_addr_t dma_addr,
(drvdata->capture_active &&
stream_id == SNDRV_PCM_STREAM_CAPTURE);
- pr_debug("%s: Enter (MSP Index: %u, SG-length: %u, SG-size: %u).\n",
+ pr_debug("%s: Enter (MSP Index: %u, period-cnt: %u, period-len: %u).\n",
__func__,
dai_idx,
- sg_len,
- sg_size);
+ period_cnt,
+ period_len);
if (!playback_req_valid && !capture_req_valid) {
pr_err("%s: The I2S controller is not available."
@@ -131,19 +129,13 @@ int ux500_msp_dai_i2s_configure_sg(dma_addr_t dma_addr,
i2s_dev = drvdata->i2s;
- sg = kzalloc(sizeof(struct scatterlist) * sg_len, GFP_ATOMIC);
- sg_init_table(sg, sg_len);
- for (i = 0; i < sg_len; i++) {
- sg_dma_address(&sg[i]) = dma_addr + i * sg_size;
- sg_dma_len(&sg[i]) = sg_size;
- }
-
message.i2s_transfer_mode = I2S_TRANSFER_MODE_CYCLIC_DMA;
message.i2s_direction = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
I2S_DIRECTION_TX :
I2S_DIRECTION_RX;
- message.sg = sg;
- message.sg_len = sg_len;
+ message.buf_addr = dma_addr;
+ message.buf_len = period_cnt * period_len;
+ message.period_len = period_len;
ret = i2s_transfer(i2s_dev->controller, &message);
if (ret < 0) {
@@ -152,8 +144,6 @@ int ux500_msp_dai_i2s_configure_sg(dma_addr_t dma_addr,
dai_idx);
}
- kfree(sg);
-
return ret;
}
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
index 36aaa386c6a..64a23506bca 100644
--- a/sound/soc/ux500/ux500_msp_dai.h
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -67,8 +67,8 @@ extern struct snd_soc_dai ux500_msp_dai[UX500_NBR_OF_DAI];
bool ux500_msp_dai_i2s_get_underrun_status(int dai_idx);
dma_addr_t ux500_msp_dai_i2s_get_pointer(int dai_idx, int stream_id);
int ux500_msp_dai_i2s_configure_sg(dma_addr_t dma_addr,
- int sg_len,
- int sg_size,
+ int perod_cnt,
+ size_t period_len,
int dai_idx,
int stream_id);
int ux500_msp_dai_i2s_send_data(void *data, size_t bytes, int dai_idx);
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index 0556706776d..1372e8d6e3f 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -111,8 +111,17 @@ void ux500_pcm_dma_eot_handler(void *data)
runtime = substream->runtime;
private = substream->runtime->private_data;
- if (ux500_msp_dai_i2s_get_underrun_status(private->msp_id))
+ if (ux500_msp_dai_i2s_get_underrun_status(private->msp_id)) {
private->no_of_underruns++;
+ pr_debug("%s: Nr of underruns (%d)\n", __func__,
+ private->no_of_underruns);
+ }
+
+ /* calc the offset in the circular buffer */
+ private->offset += frames_to_bytes(runtime,
+ runtime->period_size);
+ private->offset %= frames_to_bytes(runtime,
+ runtime->period_size) * runtime->periods;
snd_pcm_period_elapsed(substream);
}
@@ -250,12 +259,12 @@ static int ux500_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
private->no_of_underruns = 0;
+ private->offset = 0;
ret = ux500_msp_dai_i2s_configure_sg(runtime->dma_addr,
- runtime->periods,
- frames_to_bytes(runtime,
- runtime->period_size),
- private->msp_id,
- stream_id);
+ runtime->periods,
+ frames_to_bytes(runtime, runtime->period_size),
+ private->msp_id,
+ stream_id);
if (ret) {
pr_err("%s: Failed to configure sg-list!\n", __func__);
return -EINVAL;
@@ -284,18 +293,12 @@ static int ux500_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
static snd_pcm_uframes_t ux500_pcm_pointer(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct ux500_pcm_private *private = substream->runtime->private_data;
- int stream_id = substream->pstr->stream;
- unsigned int offset;
- dma_addr_t addr;
-
- pr_debug("%s: Enter\n", __func__);
+ struct ux500_pcm_private *private = runtime->private_data;
- addr = ux500_msp_dai_i2s_get_pointer(private->msp_id, stream_id);
- offset = bytes_to_frames(runtime, addr - runtime->dma_addr);
- pr_debug("%s: Offset = %u\n", __func__, offset);
+ pr_debug("%s: dma_offset %d frame %ld\n", __func__, private->offset,
+ bytes_to_frames(substream->runtime, private->offset));
- return offset;
+ return bytes_to_frames(substream->runtime, private->offset);
}
static int ux500_pcm_mmap(struct snd_pcm_substream *substream,
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h
index de2df94fd97..50f46615275 100644
--- a/sound/soc/ux500/ux500_pcm.h
+++ b/sound/soc/ux500/ux500_pcm.h
@@ -36,6 +36,7 @@ struct ux500_pcm_private {
int msp_id;
int stream_id;
unsigned int no_of_underruns;
+ unsigned int offset;
};
void ux500_pcm_dma_eot_handler(void *data);