summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorAlan Tull <r80115@freescale.com>2012-03-16 12:26:48 -0500
committerAlan Tull <r80115@freescale.com>2012-03-21 10:05:45 -0500
commit7d90961ee1b1ec5fa4468a301e55e14d66014b76 (patch)
tree30661d44bea225aec1917eee7c277deca0ff771d /sound
parent236d123bde9e2dadd5f4e471d6f08ed9b36082e1 (diff)
ENGR00177098 HMDI mmap support in isr could underflow
Take out mmap functionality. Signed-off-by: Alan Tull <r80115@freescale.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/imx/imx-hdmi-dma.c102
1 files changed, 12 insertions, 90 deletions
diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c
index 930cc2cc5785..c8e88ff79e3b 100644
--- a/sound/soc/imx/imx-hdmi-dma.c
+++ b/sound/soc/imx/imx-hdmi-dma.c
@@ -39,8 +39,7 @@ struct imx_hdmi_dma_runtime_data {
struct snd_pcm_substream *tx_substream;
unsigned long buffer_bytes;
- struct snd_dma_buffer hw_buffer;
- unsigned long appl_bytes;
+ void *buf;
int period_time;
int periods;
@@ -148,7 +147,7 @@ static void dumprtd(struct imx_hdmi_dma_runtime_data *rtd)
pr_debug("period_bytes = %d\n", rtd->period_bytes);
pr_debug("dma period_bytes = %d\n", rtd->dma_period_bytes);
pr_debug("buffer_ratio = %d\n", rtd->buffer_ratio);
- pr_debug("hw dma buffer = 0x%08x\n", (int)rtd->hw_buffer.addr);
+ pr_debug("dma buf addr = 0x%08x\n", (int)rtd->buf);
pr_debug("dma buf size = %d\n", (int)rtd->buffer_bytes);
pr_debug("sample_rate = %d\n", (int)rtd->rate);
}
@@ -270,41 +269,10 @@ static void hdmi_dma_incr_frame_idx(struct imx_hdmi_dma_runtime_data *rtd)
rtd->frame_idx = 0;
}
-static void hdmi_dma_mmap_copy(struct snd_pcm_substream *substream,
- int offset, int count)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct imx_hdmi_dma_runtime_data *rtd = runtime->private_data;
- u32 *hw_buf, *dma_buf_u32;
- u16 *dma_buf_u16;
- int subframe_idx;
-
- /* dma_buffer is the mmapped buffer we are copying pcm from. */
- dma_buf_u16 = (u16 *)(runtime->dma_area + offset);
- dma_buf_u32 = (u32 *)(runtime->dma_area + offset);
-
- /* hw_buffer is the destination for pcm data plus frame info. */
- hw_buf = (u32 *)(rtd->hw_buffer.area + (offset * rtd->buffer_ratio));
-
- while (count > 0) {
- for (subframe_idx = 1 ; subframe_idx <= rtd->channels ; subframe_idx++) {
- if (rtd->sample_align == 2)
- *hw_buf++ = hdmi_dma_add_frame_info(rtd, *dma_buf_u16++, subframe_idx);
- else
- *hw_buf++ = hdmi_dma_add_frame_info(rtd, *dma_buf_u32++, subframe_idx);
-
- count -= rtd->sample_align;
- }
- hdmi_dma_incr_frame_idx(rtd);
- }
-}
-
static irqreturn_t hdmi_dma_isr(int irq, void *dev_id)
{
struct imx_hdmi_dma_runtime_data *rtd = dev_id;
struct snd_pcm_substream *substream = rtd->tx_substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long offset, count, space_to_end, appl_bytes;
unsigned int status;
unsigned long flags;
@@ -314,32 +282,14 @@ static irqreturn_t hdmi_dma_isr(int irq, void *dev_id)
status = hdmi_dma_get_irq_status();
hdmi_dma_clear_irq_status(status);
- if (runtime && runtime->dma_area && rtd->tx_active &&
- (status & HDMI_IH_AHBDMAAUD_STAT0_DONE)) {
+ if (rtd->tx_active && (status & HDMI_IH_AHBDMAAUD_STAT0_DONE)) {
rtd->offset += rtd->period_bytes;
rtd->offset %= rtd->period_bytes * rtd->periods;
- /* For mmap access, need to copy data from dma_buffer to hw_buffer
- * and add the frame info. */
- if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
- appl_bytes = frames_to_bytes(runtime,
- runtime->control->appl_ptr);
- count = appl_bytes - rtd->appl_bytes;
- offset = rtd->appl_bytes % rtd->buffer_bytes;
- space_to_end = rtd->buffer_bytes - offset;
-
- if (count <= space_to_end)
- hdmi_dma_mmap_copy(substream, offset, count);
- else {
- hdmi_dma_mmap_copy(substream, offset, space_to_end);
- hdmi_dma_mmap_copy(substream, 0, count - space_to_end);
- }
- rtd->appl_bytes = appl_bytes;
- }
-
snd_pcm_period_elapsed(substream);
- hdmi_dma_set_addr(rtd->hw_buffer.addr + (rtd->offset * rtd->buffer_ratio),
+ hdmi_dma_set_addr(substream->dma_buffer.addr +
+ (rtd->offset * rtd->buffer_ratio),
rtd->dma_period_bytes);
hdmi_dma_start();
@@ -514,8 +464,8 @@ static int hdmi_dma_copy(struct snd_pcm_substream *substream, int channel,
int subframe_idx;
u32 pcm_data;
- /* Copy pcm data from userspace and add frame info. Destination is hw_buffer. */
- hw_buf = (u32 *)(rtd->hw_buffer.area + (pos_bytes * rtd->buffer_ratio));
+ /* Copy pcm data from userspace and add frame info. */
+ hw_buf = (u32 *)(rtd->buf + (pos_bytes * rtd->buffer_ratio));
while (count > 0) {
for (subframe_idx = 1 ; subframe_idx <= rtd->channels ; subframe_idx++) {
@@ -550,6 +500,7 @@ static int hdmi_dma_hw_params(struct snd_pcm_substream *substream,
rtd->offset = 0;
rtd->period_time = HZ / (params_rate(params) / params_period_size(params));
+ rtd->buf = (unsigned int *)substream->dma_buffer.area;
switch (rtd->format) {
case SNDRV_PCM_FORMAT_S16_LE:
@@ -574,7 +525,7 @@ static int hdmi_dma_hw_params(struct snd_pcm_substream *substream,
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
hdmi_dma_configure_dma(rtd->channels);
- hdmi_dma_set_addr(rtd->hw_buffer.addr, rtd->dma_period_bytes);
+ hdmi_dma_set_addr(substream->dma_buffer.addr, rtd->dma_period_bytes);
dumprtd(rtd);
@@ -593,12 +544,6 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
rtd->frame_idx = 0;
- if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
- rtd->appl_bytes = frames_to_bytes(runtime,
- runtime->control->appl_ptr);
-
- hdmi_dma_mmap_copy(substream, 0, rtd->appl_bytes);
- }
dumpregs();
hdmi_dma_irq_mask(0);
hdmi_dma_priv->tx_active = true;
@@ -631,8 +576,6 @@ static snd_pcm_uframes_t hdmi_dma_pointer(struct snd_pcm_substream *substream)
static struct snd_pcm_hardware snd_imx_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE |
SNDRV_PCM_INFO_RESUME,
.formats = MXC_HDMI_FORMATS_PLAYBACK,
@@ -734,12 +677,9 @@ static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
{
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
struct snd_dma_buffer *buf = &substream->dma_buffer;
- struct snd_dma_buffer *hw_buffer = &hdmi_dma_priv->hw_buffer;
+ size_t size = HDMI_DMA_BUF_SIZE;
- /* The 'dma_buffer' is the buffer alsa knows about.
- * It contains only raw audio. */
- buf->area = dma_alloc_writecombine(pcm->card->dev,
- HDMI_DMA_BUF_SIZE / 2,
+ buf->area = dma_alloc_writecombine(pcm->card->dev, size,
&buf->addr, GFP_KERNEL);
if (!buf->area)
return -ENOMEM;
@@ -747,19 +687,10 @@ static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
buf->dev.type = SNDRV_DMA_TYPE_DEV;
buf->dev.dev = pcm->card->dev;
buf->private_data = NULL;
- buf->bytes = HDMI_DMA_BUF_SIZE / 2;
+ buf->bytes = size;
hdmi_dma_priv->tx_substream = substream;
- /* For mmap access, isr will copy from the dma_buffer to the hw_buffer */
- hw_buffer->area = dma_alloc_writecombine(pcm->card->dev,
- HDMI_DMA_BUF_SIZE,
- &hw_buffer->addr, GFP_KERNEL);
- if (!hw_buffer->area)
- return -ENOMEM;
-
- hw_buffer->bytes = HDMI_DMA_BUF_SIZE;
-
return 0;
}
@@ -790,7 +721,6 @@ static void imx_hdmi_dma_pcm_free(struct snd_pcm *pcm)
struct snd_dma_buffer *buf;
int stream;
- /* free each dma_buffer */
for (stream = 0; stream < 2; stream++) {
substream = pcm->streams[stream].substream;
if (!substream)
@@ -804,14 +734,6 @@ static void imx_hdmi_dma_pcm_free(struct snd_pcm *pcm)
buf->area, buf->addr);
buf->area = NULL;
}
-
- /* free the hw_buffer */
- buf = &hdmi_dma_priv->hw_buffer;
- if (buf->area) {
- dma_free_writecombine(pcm->card->dev, buf->bytes,
- buf->area, buf->addr);
- buf->area = NULL;
- }
}
static struct snd_soc_platform_driver imx_soc_platform_mx2 = {