Skip to content

Commit

Permalink
ASoC: imx: separate imx-pcm bits from imx-ssi driver
Browse files Browse the repository at this point in the history
Currently the imx-ssi.c[h] accommodates the imx-pcm common bits which
are shared between imx-pcm-dma-mx2 and imx-pcm-fiq drivers.  It assumes
that imx-pcm-dma-mx2 and imx-pcm-fiq will always be used together with
imx-ssi driver.  However this becomes untrue when we see that driver
sound/soc/fsl/fsl_ssi could possibly work with imx-pcm-dma-mx2 too.

The patch moves the imx-pcm common bits from imx-ssi.c[h] into new
files imx-pcm.c[h], and let imx-pcm-dma-mx2 and imx-pcm-fiq drivers
build it in, so that imx-pcm-dma-mx2 can work with no dependency on
imx-ssi driver.

Signed-off-by: Shawn Guo <[email protected]>
Acked-by: Sascha Hauer <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
  • Loading branch information
shawnguo2 authored and broonie committed Mar 6, 2012
1 parent af4872f commit 4762fba
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 109 deletions.
7 changes: 6 additions & 1 deletion sound/soc/imx/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ menuconfig SND_IMX_SOC

if SND_IMX_SOC

config SND_SOC_IMX_PCM
tristate

config SND_MXC_SOC_FIQ
select FIQ
tristate
select FIQ
select SND_SOC_IMX_PCM

config SND_MXC_SOC_MX2
select SND_SOC_DMAENGINE_PCM
tristate
select SND_SOC_IMX_PCM

config SND_SOC_IMX_AUDMUX
tristate
Expand Down
9 changes: 5 additions & 4 deletions sound/soc/imx/Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# i.MX Platform Support
snd-soc-imx-objs := imx-ssi.o
snd-soc-imx-fiq-objs := imx-pcm-fiq.o
snd-soc-imx-mx2-objs := imx-pcm-dma-mx2.o
snd-soc-imx-audmux-objs := imx-audmux.o

obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o
obj-$(CONFIG_SND_MXC_SOC_FIQ) += snd-soc-imx-fiq.o
obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.o
obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o

obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
snd-soc-imx-pcm-y := imx-pcm.o
snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_FIQ) += imx-pcm-fiq.o
snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_MX2) += imx-pcm-dma-mx2.o

# i.MX Machine Support
snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
snd-soc-phycore-ac97-objs := phycore-ac97.o
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/imx/imx-pcm-dma-mx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

#include <mach/dma.h>

#include "imx-ssi.h"
#include "imx-pcm.h"

static bool filter(struct dma_chan *chan, void *param)
{
Expand Down
105 changes: 105 additions & 0 deletions sound/soc/imx/imx-pcm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2009 Sascha Hauer <[email protected]>
*
* This code is based on code copyrighted by Freescale,
* Liam Girdwood, Javier Martin and probably others.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/

#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include "imx-pcm.h"

int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
{
struct snd_pcm_runtime *runtime = substream->runtime;
int ret;

ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);

pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
runtime->dma_area,
runtime->dma_addr,
runtime->dma_bytes);
return ret;
}
EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);

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;
size_t size = IMX_SSI_DMABUF_SIZE;

buf->dev.type = SNDRV_DMA_TYPE_DEV;
buf->dev.dev = pcm->card->dev;
buf->private_data = NULL;
buf->area = dma_alloc_writecombine(pcm->card->dev, size,
&buf->addr, GFP_KERNEL);
if (!buf->area)
return -ENOMEM;
buf->bytes = size;

return 0;
}

static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);

int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;

if (!card->dev->dma_mask)
card->dev->dma_mask = &imx_pcm_dmamask;
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = imx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}

if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = imx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
goto out;
}

out:
return ret;
}
EXPORT_SYMBOL_GPL(imx_pcm_new);

void imx_pcm_free(struct snd_pcm *pcm)
{
struct snd_pcm_substream *substream;
struct snd_dma_buffer *buf;
int stream;

for (stream = 0; stream < 2; stream++) {
substream = pcm->streams[stream].substream;
if (!substream)
continue;

buf = &substream->dma_buffer;
if (!buf->area)
continue;

dma_free_writecombine(pcm->card->dev, buf->bytes,
buf->area, buf->addr);
buf->area = NULL;
}
}
EXPORT_SYMBOL_GPL(imx_pcm_free);
32 changes: 32 additions & 0 deletions sound/soc/imx/imx-pcm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2009 Sascha Hauer <[email protected]>
*
* This code is based on code copyrighted by Freescale,
* Liam Girdwood, Javier Martin and probably others.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/

#ifndef _IMX_PCM_H
#define _IMX_PCM_H

/*
* Do not change this as the FIQ handler depends on this size
*/
#define IMX_SSI_DMABUF_SIZE (64 * 1024)

struct imx_pcm_dma_params {
int dma;
unsigned long dma_addr;
int burstsize;
};

int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma);
int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
void imx_pcm_free(struct snd_pcm *pcm);

#endif /* _IMX_PCM_H */
88 changes: 0 additions & 88 deletions sound/soc/imx/imx-ssi.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,94 +363,6 @@ static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
.trigger = imx_ssi_trigger,
};

int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
{
struct snd_pcm_runtime *runtime = substream->runtime;
int ret;

ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);

pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
runtime->dma_area,
runtime->dma_addr,
runtime->dma_bytes);
return ret;
}
EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);

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;
size_t size = IMX_SSI_DMABUF_SIZE;

buf->dev.type = SNDRV_DMA_TYPE_DEV;
buf->dev.dev = pcm->card->dev;
buf->private_data = NULL;
buf->area = dma_alloc_writecombine(pcm->card->dev, size,
&buf->addr, GFP_KERNEL);
if (!buf->area)
return -ENOMEM;
buf->bytes = size;

return 0;
}

static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);

int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
struct snd_pcm *pcm = rtd->pcm;
int ret = 0;

if (!card->dev->dma_mask)
card->dev->dma_mask = &imx_pcm_dmamask;
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = imx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}

if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = imx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
goto out;
}

out:
return ret;
}
EXPORT_SYMBOL_GPL(imx_pcm_new);

void imx_pcm_free(struct snd_pcm *pcm)
{
struct snd_pcm_substream *substream;
struct snd_dma_buffer *buf;
int stream;

for (stream = 0; stream < 2; stream++) {
substream = pcm->streams[stream].substream;
if (!substream)
continue;

buf = &substream->dma_buffer;
if (!buf->area)
continue;

dma_free_writecombine(pcm->card->dev, buf->bytes,
buf->area, buf->addr);
buf->area = NULL;
}
}
EXPORT_SYMBOL_GPL(imx_pcm_free);

static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
{
struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
Expand Down
16 changes: 1 addition & 15 deletions sound/soc/imx/imx-ssi.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,7 @@

#include <linux/dmaengine.h>
#include <mach/dma.h>

struct imx_pcm_dma_params {
int dma;
unsigned long dma_addr;
int burstsize;
};
#include "imx-pcm.h"

struct imx_ssi {
struct platform_device *ac97_dev;
Expand All @@ -218,13 +213,4 @@ struct imx_ssi {
struct platform_device *soc_platform_pdev_fiq;
};

int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
void imx_pcm_free(struct snd_pcm *pcm);

/*
* Do not change this as the FIQ handler depends on this size
*/
#define IMX_SSI_DMABUF_SIZE (64 * 1024)

#endif /* _IMX_SSI_H */

0 comments on commit 4762fba

Please sign in to comment.