Skip to content

Commit

Permalink
ASoC: pxa: use snd_dmaengine_dai_dma_data
Browse files Browse the repository at this point in the history
Use snd_dmaengine_dai_dma_data for passing the dma parameters from
clients to the pxa pcm lib. This does no functional change, it's just an
intermedia step to migrate the pxa bits over to dmaengine.

The calculation of dcmd is a transition hack which will be removed again
in a later patch. It's just there to make the transition more readable.

Signed-off-by: Daniel Mack <[email protected]>
Acked-by: Mark Brown <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
  • Loading branch information
zonque authored and broonie committed Aug 15, 2013
1 parent 2023c90 commit d65a145
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 113 deletions.
7 changes: 0 additions & 7 deletions include/sound/pxa2xx-lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@

/* PCM */

struct pxa2xx_pcm_dma_params {
char *name; /* stream identifier */
u32 dcmd; /* DMA descriptor dcmd field */
volatile u32 *drcmr; /* the DMA request channel to use */
u32 dev_addr; /* device physical address for DMA */
};

extern int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params);
extern int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream);
Expand Down
26 changes: 14 additions & 12 deletions sound/arm/pxa2xx-ac97.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/dmaengine.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include <sound/pxa2xx-lib.h>
#include <sound/dmaengine_pcm.h>

#include <mach/regs-ac97.h>
#include <mach/audio.h>
Expand All @@ -41,20 +43,20 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
.reset = pxa2xx_ac97_reset,
};

static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = {
.name = "AC97 PCM out",
.dev_addr = __PREG(PCDR),
.drcmr = &DRCMR(12),
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
DCMD_BURST32 | DCMD_WIDTH4,
static unsigned long pxa2xx_ac97_pcm_out_req = 12;
static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = {
.addr = __PREG(PCDR),
.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
.maxburst = 32,
.filter_data = &pxa2xx_ac97_pcm_out_req,
};

static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = {
.name = "AC97 PCM in",
.dev_addr = __PREG(PCDR),
.drcmr = &DRCMR(11),
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
DCMD_BURST32 | DCMD_WIDTH4,
static unsigned long pxa2xx_ac97_pcm_in_req = 11;
static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_in = {
.addr = __PREG(PCDR),
.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
.maxburst = 32,
.filter_data = &pxa2xx_ac97_pcm_in_req,
};

static struct snd_pcm *pxa2xx_ac97_pcm;
Expand Down
52 changes: 43 additions & 9 deletions sound/arm/pxa2xx-pcm-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/pxa2xx-lib.h>
#include <sound/dmaengine_pcm.h>

#include <mach/dma.h>

Expand Down Expand Up @@ -43,6 +45,35 @@ int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
size_t period = params_period_bytes(params);
pxa_dma_desc *dma_desc;
dma_addr_t dma_buff_phys, next_desc_phys;
u32 dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;

/* temporary transition hack */
switch (rtd->params->addr_width) {
case DMA_SLAVE_BUSWIDTH_1_BYTE:
dcmd |= DCMD_WIDTH1;
break;
case DMA_SLAVE_BUSWIDTH_2_BYTES:
dcmd |= DCMD_WIDTH2;
break;
case DMA_SLAVE_BUSWIDTH_4_BYTES:
dcmd |= DCMD_WIDTH4;
break;
default:
/* can't happen */
break;
}

switch (rtd->params->maxburst) {
case 8:
dcmd |= DCMD_BURST8;
break;
case 16:
dcmd |= DCMD_BURST16;
break;
case 32:
dcmd |= DCMD_BURST32;
break;
}

snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
runtime->dma_bytes = totsize;
Expand All @@ -55,14 +86,14 @@ int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
dma_desc->ddadr = next_desc_phys;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
dma_desc->dsadr = dma_buff_phys;
dma_desc->dtadr = rtd->params->dev_addr;
dma_desc->dtadr = rtd->params->addr;
} else {
dma_desc->dsadr = rtd->params->dev_addr;
dma_desc->dsadr = rtd->params->addr;
dma_desc->dtadr = dma_buff_phys;
}
if (period > totsize)
period = totsize;
dma_desc->dcmd = rtd->params->dcmd | period | DCMD_ENDIRQEN;
dma_desc->dcmd = dcmd | period | DCMD_ENDIRQEN;
dma_desc++;
dma_buff_phys += period;
} while (totsize -= period);
Expand All @@ -76,8 +107,10 @@ int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;

if (rtd && rtd->params && rtd->params->drcmr)
*rtd->params->drcmr = 0;
if (rtd && rtd->params && rtd->params->filter_data) {
unsigned long req = *(unsigned long *) rtd->params->filter_data;
DRCMR(req) = 0;
}

snd_pcm_set_runtime_buffer(substream, NULL);
return 0;
Expand Down Expand Up @@ -136,6 +169,7 @@ EXPORT_SYMBOL(pxa2xx_pcm_pointer);
int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
{
struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
unsigned long req;

if (!prtd || !prtd->params)
return 0;
Expand All @@ -146,7 +180,8 @@ int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
DCSR(prtd->dma_ch) &= ~DCSR_RUN;
DCSR(prtd->dma_ch) = 0;
DCMD(prtd->dma_ch) = 0;
*prtd->params->drcmr = prtd->dma_ch | DRCMR_MAPVLD;
req = *(unsigned long *) prtd->params->filter_data;
DRCMR(req) = prtd->dma_ch | DRCMR_MAPVLD;

return 0;
}
Expand All @@ -155,7 +190,6 @@ EXPORT_SYMBOL(__pxa2xx_pcm_prepare);
void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
{
struct snd_pcm_substream *substream = dev_id;
struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
int dcsr;

dcsr = DCSR(dma_ch);
Expand All @@ -164,8 +198,8 @@ void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
if (dcsr & DCSR_ENDINTR) {
snd_pcm_period_elapsed(substream);
} else {
printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
rtd->params->name, dma_ch, dcsr);
printk(KERN_ERR "DMA error on channel %d (DCSR=%#x)\n",
dma_ch, dcsr);
snd_pcm_stream_lock(substream);
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock(substream);
Expand Down
5 changes: 4 additions & 1 deletion sound/arm/pxa2xx-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
*/

#include <linux/module.h>
#include <linux/dmaengine.h>

#include <sound/core.h>
#include <sound/pxa2xx-lib.h>
#include <sound/dmaengine_pcm.h>

#include "pxa2xx-pcm.h"

Expand Down Expand Up @@ -40,7 +43,7 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)

rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
client->playback_params : client->capture_params;
ret = pxa_request_dma(rtd->params->name, DMA_PRIO_LOW,
ret = pxa_request_dma("dma", DMA_PRIO_LOW,
pxa2xx_pcm_dma_irq, substream);
if (ret < 0)
goto err2;
Expand Down
6 changes: 3 additions & 3 deletions sound/arm/pxa2xx-pcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@

struct pxa2xx_runtime_data {
int dma_ch;
struct pxa2xx_pcm_dma_params *params;
struct snd_dmaengine_dai_dma_data *params;
pxa_dma_desc *dma_desc_array;
dma_addr_t dma_desc_array_phys;
};

struct pxa2xx_pcm_client {
struct pxa2xx_pcm_dma_params *playback_params;
struct pxa2xx_pcm_dma_params *capture_params;
struct snd_dmaengine_dai_dma_data *playback_params;
struct snd_dmaengine_dai_dma_data *capture_params;
int (*startup)(struct snd_pcm_substream *);
void (*shutdown)(struct snd_pcm_substream *);
int (*prepare)(struct snd_pcm_substream *);
Expand Down
8 changes: 5 additions & 3 deletions sound/soc/pxa/mmp-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include <linux/dmaengine.h>
#include <linux/platform_data/dma-mmp_tdma.h>
#include <linux/platform_data/mmp_audio.h>
#include <linux/dmaengine.h>

#include <sound/pxa2xx-lib.h>
#include <sound/core.h>
#include <sound/pcm.h>
Expand Down Expand Up @@ -67,7 +69,7 @@ static int mmp_pcm_hw_params(struct snd_pcm_substream *substream,
{
struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct pxa2xx_pcm_dma_params *dma_params;
struct snd_dmaengine_dai_dma_data *dma_params;
struct dma_slave_config slave_config;
int ret;

Expand All @@ -80,10 +82,10 @@ static int mmp_pcm_hw_params(struct snd_pcm_substream *substream,
return ret;

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
slave_config.dst_addr = dma_params->dev_addr;
slave_config.dst_addr = dma_params->addr;
slave_config.dst_maxburst = 4;
} else {
slave_config.src_addr = dma_params->dev_addr;
slave_config.src_addr = dma_params->addr;
slave_config.src_maxburst = 4;
}

Expand Down
12 changes: 8 additions & 4 deletions sound/soc/pxa/mmp-sspa.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,23 @@
#include <linux/slab.h>
#include <linux/pxa2xx_ssp.h>
#include <linux/io.h>
#include <linux/dmaengine.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/initval.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/pxa2xx-lib.h>
#include <sound/dmaengine_pcm.h>
#include "mmp-sspa.h"

/*
* SSPA audio private data
*/
struct sspa_priv {
struct ssp_device *sspa;
struct pxa2xx_pcm_dma_params *dma_params;
struct snd_dmaengine_dai_dma_data *dma_params;
struct clk *audio_clk;
struct clk *sysclk;
int dai_fmt;
Expand Down Expand Up @@ -266,7 +269,7 @@ static int mmp_sspa_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai);
struct ssp_device *sspa = sspa_priv->sspa;
struct pxa2xx_pcm_dma_params *dma_params;
struct snd_dmaengine_dai_dma_data *dma_params;
u32 sspa_ctrl;

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
Expand Down Expand Up @@ -309,7 +312,7 @@ static int mmp_sspa_hw_params(struct snd_pcm_substream *substream,
}

dma_params = &sspa_priv->dma_params[substream->stream];
dma_params->dev_addr = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
dma_params->addr = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
(sspa->phys_base + SSPA_TXD) :
(sspa->phys_base + SSPA_RXD);
snd_soc_dai_set_dma_data(cpu_dai, substream, dma_params);
Expand Down Expand Up @@ -425,7 +428,8 @@ static int asoc_mmp_sspa_probe(struct platform_device *pdev)
return -ENOMEM;

priv->dma_params = devm_kzalloc(&pdev->dev,
2 * sizeof(struct pxa2xx_pcm_dma_params), GFP_KERNEL);
2 * sizeof(struct snd_dmaengine_dai_dma_data),
GFP_KERNEL);
if (priv->dma_params == NULL)
return -ENOMEM;

Expand Down
36 changes: 12 additions & 24 deletions sound/soc/pxa/pxa-ssp.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/io.h>
#include <linux/pxa2xx_ssp.h>
#include <linux/of.h>
#include <linux/dmaengine.h>

#include <asm/irq.h>

Expand All @@ -31,9 +32,9 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/pxa2xx-lib.h>
#include <sound/dmaengine_pcm.h>

#include <mach/hardware.h>
#include <mach/dma.h>

#include "../../arm/pxa2xx-pcm.h"
#include "pxa-ssp.h"
Expand Down Expand Up @@ -80,46 +81,33 @@ static void pxa_ssp_disable(struct ssp_device *ssp)
__raw_writel(sscr0, ssp->mmio_base + SSCR0);
}

struct pxa2xx_pcm_dma_data {
struct pxa2xx_pcm_dma_params params;
char name[20];
};

static void pxa_ssp_set_dma_params(struct ssp_device *ssp, int width4,
int out, struct pxa2xx_pcm_dma_params *dma_data)
int out, struct snd_dmaengine_dai_dma_data *dma)
{
struct pxa2xx_pcm_dma_data *dma;

dma = container_of(dma_data, struct pxa2xx_pcm_dma_data, params);

snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id,
width4 ? "32-bit" : "16-bit", out ? "out" : "in");

dma->params.name = dma->name;
dma->params.drcmr = &DRCMR(out ? ssp->drcmr_tx : ssp->drcmr_rx);
dma->params.dcmd = (out ? (DCMD_INCSRCADDR | DCMD_FLOWTRG) :
(DCMD_INCTRGADDR | DCMD_FLOWSRC)) |
(width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16;
dma->params.dev_addr = ssp->phys_base + SSDR;
dma->filter_data = out ? &ssp->drcmr_tx : &ssp->drcmr_rx;
dma->addr_width = width4 ? DMA_SLAVE_BUSWIDTH_4_BYTES :
DMA_SLAVE_BUSWIDTH_2_BYTES;
dma->maxburst = 16;
dma->addr = ssp->phys_base + SSDR;
}

static int pxa_ssp_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
struct ssp_device *ssp = priv->ssp;
struct pxa2xx_pcm_dma_data *dma;
struct snd_dmaengine_dai_dma_data *dma;
int ret = 0;

if (!cpu_dai->active) {
clk_enable(ssp->clk);
pxa_ssp_disable(ssp);
}

dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL);
dma = kzalloc(sizeof(struct snd_dmaengine_dai_dma_data), GFP_KERNEL);
if (!dma)
return -ENOMEM;
snd_soc_dai_set_dma_data(cpu_dai, substream, &dma->params);
snd_soc_dai_set_dma_data(cpu_dai, substream, dma);

return ret;
}
Expand Down Expand Up @@ -560,7 +548,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
u32 sspsp;
int width = snd_pcm_format_physical_width(params_format(params));
int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
struct pxa2xx_pcm_dma_params *dma_data;
struct snd_dmaengine_dai_dma_data *dma_data;

dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);

Expand Down
Loading

0 comments on commit d65a145

Please sign in to comment.