Merge remote-tracking branch 'asoc/topic/dma' into asoc-next
This commit is contained in:
Коммит
38e8c895d3
|
@ -32,9 +32,6 @@ snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream)
|
|||
return DMA_DEV_TO_MEM;
|
||||
}
|
||||
|
||||
void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data);
|
||||
void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream);
|
||||
|
||||
int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
|
||||
const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
|
||||
int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
|
||||
|
@ -47,4 +44,28 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream);
|
|||
|
||||
struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
|
||||
|
||||
/**
|
||||
* struct snd_dmaengine_dai_dma_data - DAI DMA configuration data
|
||||
* @addr: Address of the DAI data source or destination register.
|
||||
* @addr_width: Width of the DAI data source or destination register.
|
||||
* @maxburst: Maximum number of words(note: words, as in units of the
|
||||
* src_addr_width member, not bytes) that can be send to or received from the
|
||||
* DAI in one burst.
|
||||
* @slave_id: Slave requester id for the DMA channel.
|
||||
* @filter_data: Custom DMA channel filter data, this will usually be used when
|
||||
* requesting the DMA channel.
|
||||
*/
|
||||
struct snd_dmaengine_dai_dma_data {
|
||||
dma_addr_t addr;
|
||||
enum dma_slave_buswidth addr_width;
|
||||
u32 maxburst;
|
||||
unsigned int slave_id;
|
||||
void *filter_data;
|
||||
};
|
||||
|
||||
void snd_dmaengine_pcm_set_config_from_dai_data(
|
||||
const struct snd_pcm_substream *substream,
|
||||
const struct snd_dmaengine_dai_dma_data *dma_data,
|
||||
struct dma_slave_config *config);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -67,9 +67,10 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = {
|
|||
static void atmel_pcm_dma_irq(u32 ssc_sr,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct atmel_pcm_dma_params *prtd;
|
||||
|
||||
prtd = snd_dmaengine_pcm_get_data(substream);
|
||||
prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
|
||||
if (ssc_sr & prtd->mask->ssc_error) {
|
||||
if (snd_pcm_running(substream))
|
||||
|
@ -104,15 +105,13 @@ static bool filter(struct dma_chan *chan, void *slave)
|
|||
}
|
||||
|
||||
static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
struct snd_pcm_hw_params *params, struct atmel_pcm_dma_params *prtd)
|
||||
{
|
||||
struct atmel_pcm_dma_params *prtd;
|
||||
struct ssc_device *ssc;
|
||||
struct dma_chan *dma_chan;
|
||||
struct dma_slave_config slave_config;
|
||||
int ret;
|
||||
|
||||
prtd = snd_dmaengine_pcm_get_data(substream);
|
||||
ssc = prtd->ssc;
|
||||
|
||||
ret = snd_hwparams_to_dma_slave_config(substream, params,
|
||||
|
@ -130,8 +129,6 @@ static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
|
|||
slave_config.src_maxburst = 1;
|
||||
}
|
||||
|
||||
slave_config.device_fc = false;
|
||||
|
||||
dma_chan = snd_dmaengine_pcm_get_chan(substream);
|
||||
if (dmaengine_slave_config(dma_chan, &slave_config)) {
|
||||
pr_err("atmel-pcm: failed to configure dma channel\n");
|
||||
|
@ -164,9 +161,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
snd_dmaengine_pcm_set_data(substream, prtd);
|
||||
|
||||
ret = atmel_pcm_configure_dma(substream, params);
|
||||
ret = atmel_pcm_configure_dma(substream, params, prtd);
|
||||
if (ret) {
|
||||
pr_err("atmel-pcm: failed to configure dmai\n");
|
||||
goto err;
|
||||
|
@ -182,9 +177,10 @@ err:
|
|||
|
||||
static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct atmel_pcm_dma_params *prtd;
|
||||
|
||||
prtd = snd_dmaengine_pcm_get_data(substream);
|
||||
prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
|
||||
ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error);
|
||||
ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable);
|
||||
|
@ -199,16 +195,9 @@ static int atmel_pcm_open(struct snd_pcm_substream *substream)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int atmel_pcm_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_dmaengine_pcm_close(substream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops atmel_pcm_ops = {
|
||||
.open = atmel_pcm_open,
|
||||
.close = atmel_pcm_close,
|
||||
.close = snd_dmaengine_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = atmel_pcm_hw_params,
|
||||
.prepare = atmel_pcm_dma_prepare,
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <sound/soc.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <mach/hardware.h>
|
||||
#include "ep93xx-pcm.h"
|
||||
|
||||
static int edb93xx_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <sound/soc.h>
|
||||
|
||||
#include <linux/platform_data/dma-ep93xx.h>
|
||||
#include "ep93xx-pcm.h"
|
||||
|
||||
/*
|
||||
* Per channel (1-4) registers.
|
||||
|
@ -101,14 +100,16 @@ struct ep93xx_ac97_info {
|
|||
/* currently ALSA only supports a single AC97 device */
|
||||
static struct ep93xx_ac97_info *ep93xx_ac97_info;
|
||||
|
||||
static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_out = {
|
||||
static struct ep93xx_dma_data ep93xx_ac97_pcm_out = {
|
||||
.name = "ac97-pcm-out",
|
||||
.dma_port = EP93XX_DMA_AAC1,
|
||||
.direction = DMA_MEM_TO_DEV,
|
||||
};
|
||||
|
||||
static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_in = {
|
||||
static struct ep93xx_dma_data ep93xx_ac97_pcm_in = {
|
||||
.name = "ac97-pcm-in",
|
||||
.dma_port = EP93XX_DMA_AAC1,
|
||||
.direction = DMA_DEV_TO_MEM,
|
||||
};
|
||||
|
||||
static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info,
|
||||
|
@ -316,7 +317,7 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
|
|||
static int ep93xx_ac97_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct ep93xx_pcm_dma_params *dma_data;
|
||||
struct ep93xx_dma_data *dma_data;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
dma_data = &ep93xx_ac97_pcm_out;
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include <mach/ep93xx-regs.h>
|
||||
#include <linux/platform_data/dma-ep93xx.h>
|
||||
|
||||
#include "ep93xx-pcm.h"
|
||||
|
||||
#define EP93XX_I2S_TXCLKCFG 0x00
|
||||
#define EP93XX_I2S_RXCLKCFG 0x04
|
||||
#define EP93XX_I2S_GLCTRL 0x0C
|
||||
|
@ -62,18 +60,20 @@ struct ep93xx_i2s_info {
|
|||
struct clk *mclk;
|
||||
struct clk *sclk;
|
||||
struct clk *lrclk;
|
||||
struct ep93xx_pcm_dma_params *dma_params;
|
||||
struct ep93xx_dma_data *dma_data;
|
||||
void __iomem *regs;
|
||||
};
|
||||
|
||||
struct ep93xx_pcm_dma_params ep93xx_i2s_dma_params[] = {
|
||||
struct ep93xx_dma_data ep93xx_i2s_dma_data[] = {
|
||||
[SNDRV_PCM_STREAM_PLAYBACK] = {
|
||||
.name = "i2s-pcm-out",
|
||||
.dma_port = EP93XX_DMA_I2S1,
|
||||
.port = EP93XX_DMA_I2S1,
|
||||
.direction = DMA_MEM_TO_DEV,
|
||||
},
|
||||
[SNDRV_PCM_STREAM_CAPTURE] = {
|
||||
.name = "i2s-pcm-in",
|
||||
.dma_port = EP93XX_DMA_I2S1,
|
||||
.port = EP93XX_DMA_I2S1,
|
||||
.direction = DMA_DEV_TO_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -147,7 +147,7 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
|
||||
snd_soc_dai_set_dma_data(cpu_dai, substream,
|
||||
&info->dma_params[substream->stream]);
|
||||
&info->dma_data[substream->stream]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -407,7 +407,7 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
dev_set_drvdata(&pdev->dev, info);
|
||||
info->dma_params = ep93xx_i2s_dma_params;
|
||||
info->dma_data = ep93xx_i2s_dma_data;
|
||||
|
||||
err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component,
|
||||
&ep93xx_i2s_dai, 1);
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
#include <mach/hardware.h>
|
||||
#include <mach/ep93xx-regs.h>
|
||||
|
||||
#include "ep93xx-pcm.h"
|
||||
|
||||
static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
|
@ -68,40 +66,11 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
|
|||
static int ep93xx_pcm_open(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct ep93xx_pcm_dma_params *dma_params;
|
||||
struct ep93xx_dma_data *dma_data;
|
||||
int ret;
|
||||
|
||||
snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware);
|
||||
|
||||
dma_data = kmalloc(sizeof(*dma_data), GFP_KERNEL);
|
||||
if (!dma_data)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream);
|
||||
dma_data->port = dma_params->dma_port;
|
||||
dma_data->name = dma_params->name;
|
||||
dma_data->direction = snd_pcm_substream_to_dma_direction(substream);
|
||||
|
||||
ret = snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, dma_data);
|
||||
if (ret) {
|
||||
kfree(dma_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
snd_dmaengine_pcm_set_data(substream, dma_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ep93xx_pcm_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
|
||||
|
||||
snd_dmaengine_pcm_close(substream);
|
||||
kfree(dma_data);
|
||||
return 0;
|
||||
return snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter,
|
||||
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
|
||||
}
|
||||
|
||||
static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
|
@ -131,7 +100,7 @@ static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream,
|
|||
|
||||
static struct snd_pcm_ops ep93xx_pcm_ops = {
|
||||
.open = ep93xx_pcm_open,
|
||||
.close = ep93xx_pcm_close,
|
||||
.close = snd_dmaengine_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = ep93xx_pcm_hw_params,
|
||||
.hw_free = ep93xx_pcm_hw_free,
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* sound/soc/ep93xx/ep93xx-pcm.h - EP93xx ALSA PCM interface
|
||||
*
|
||||
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
|
||||
* Copyright (C) 2006 Applied Data Systems
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _EP93XX_SND_SOC_PCM_H
|
||||
#define _EP93XX_SND_SOC_PCM_H
|
||||
|
||||
struct ep93xx_pcm_dma_params {
|
||||
char *name;
|
||||
int dma_port;
|
||||
};
|
||||
|
||||
#endif /* _EP93XX_SND_SOC_PCM_H */
|
|
@ -21,8 +21,6 @@
|
|||
#include <asm/mach-types.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include "ep93xx-pcm.h"
|
||||
|
||||
static struct snd_soc_dai_link simone_dai = {
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <mach/hardware.h>
|
||||
|
||||
#include "../codecs/tlv320aic23.h"
|
||||
#include "ep93xx-pcm.h"
|
||||
|
||||
#define CODEC_CLOCK 5644800
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <sound/pcm_params.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "fsl_ssi.h"
|
||||
#include "imx-pcm.h"
|
||||
|
@ -122,8 +123,10 @@ struct fsl_ssi_private {
|
|||
bool ssi_on_imx;
|
||||
struct clk *clk;
|
||||
struct platform_device *imx_pcm_pdev;
|
||||
struct imx_pcm_dma_params dma_params_tx;
|
||||
struct imx_pcm_dma_params dma_params_rx;
|
||||
struct snd_dmaengine_dai_dma_data dma_params_tx;
|
||||
struct snd_dmaengine_dai_dma_data dma_params_rx;
|
||||
struct imx_dma_data filter_data_tx;
|
||||
struct imx_dma_data filter_data_rx;
|
||||
|
||||
struct {
|
||||
unsigned int rfrc;
|
||||
|
@ -653,6 +656,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
|
|||
const uint32_t *iprop;
|
||||
struct resource res;
|
||||
char name[64];
|
||||
bool shared;
|
||||
|
||||
/* SSIs that are not connected on the board should have a
|
||||
* status = "disabled"
|
||||
|
@ -741,14 +745,18 @@ static int fsl_ssi_probe(struct platform_device *pdev)
|
|||
* We have burstsize be "fifo_depth - 2" to match the SSI
|
||||
* watermark setting in fsl_ssi_startup().
|
||||
*/
|
||||
ssi_private->dma_params_tx.burstsize =
|
||||
ssi_private->dma_params_tx.maxburst =
|
||||
ssi_private->fifo_depth - 2;
|
||||
ssi_private->dma_params_rx.burstsize =
|
||||
ssi_private->dma_params_rx.maxburst =
|
||||
ssi_private->fifo_depth - 2;
|
||||
ssi_private->dma_params_tx.dma_addr =
|
||||
ssi_private->dma_params_tx.addr =
|
||||
ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
|
||||
ssi_private->dma_params_rx.dma_addr =
|
||||
ssi_private->dma_params_rx.addr =
|
||||
ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
|
||||
ssi_private->dma_params_tx.filter_data =
|
||||
&ssi_private->filter_data_tx;
|
||||
ssi_private->dma_params_rx.filter_data =
|
||||
&ssi_private->filter_data_rx;
|
||||
/*
|
||||
* TODO: This is a temporary solution and should be changed
|
||||
* to use generic DMA binding later when the helplers get in.
|
||||
|
@ -759,14 +767,14 @@ static int fsl_ssi_probe(struct platform_device *pdev)
|
|||
dev_err(&pdev->dev, "could not get dma events\n");
|
||||
goto error_clk;
|
||||
}
|
||||
ssi_private->dma_params_tx.dma = dma_events[0];
|
||||
ssi_private->dma_params_rx.dma = dma_events[1];
|
||||
|
||||
ssi_private->dma_params_tx.shared_peripheral =
|
||||
of_device_is_compatible(of_get_parent(np),
|
||||
"fsl,spba-bus");
|
||||
ssi_private->dma_params_rx.shared_peripheral =
|
||||
ssi_private->dma_params_tx.shared_peripheral;
|
||||
shared = of_device_is_compatible(of_get_parent(np),
|
||||
"fsl,spba-bus");
|
||||
|
||||
imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx,
|
||||
dma_events[0], shared);
|
||||
imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
|
||||
dma_events[1], shared);
|
||||
}
|
||||
|
||||
/* Initialize the the device_attribute structure */
|
||||
|
|
|
@ -30,16 +30,16 @@
|
|||
#include <sound/soc.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include <linux/platform_data/dma-imx.h>
|
||||
|
||||
#include "imx-pcm.h"
|
||||
|
||||
static bool filter(struct dma_chan *chan, void *param)
|
||||
{
|
||||
struct snd_dmaengine_dai_dma_data *dma_data = param;
|
||||
|
||||
if (!imx_dma_is_general_purpose(chan))
|
||||
return false;
|
||||
|
||||
chan->private = param;
|
||||
chan->private = dma_data->filter_data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -49,25 +49,16 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
|
||||
struct imx_pcm_dma_params *dma_params;
|
||||
struct dma_slave_config slave_config;
|
||||
int ret;
|
||||
|
||||
dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
|
||||
ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
slave_config.device_fc = false;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
slave_config.dst_addr = dma_params->dma_addr;
|
||||
slave_config.dst_maxburst = dma_params->burstsize;
|
||||
} else {
|
||||
slave_config.src_addr = dma_params->dma_addr;
|
||||
slave_config.src_maxburst = dma_params->burstsize;
|
||||
}
|
||||
snd_dmaengine_pcm_set_config_from_dai_data(substream,
|
||||
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
|
||||
&slave_config);
|
||||
|
||||
ret = dmaengine_slave_config(chan, &slave_config);
|
||||
if (ret)
|
||||
|
@ -100,47 +91,16 @@ static struct snd_pcm_hardware snd_imx_hardware = {
|
|||
static int snd_imx_open(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct imx_pcm_dma_params *dma_params;
|
||||
struct imx_dma_data *dma_data;
|
||||
int ret;
|
||||
|
||||
snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
|
||||
|
||||
dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
|
||||
dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
|
||||
if (!dma_data)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_data->peripheral_type = dma_params->shared_peripheral ?
|
||||
IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI;
|
||||
dma_data->priority = DMA_PRIO_HIGH;
|
||||
dma_data->dma_request = dma_params->dma;
|
||||
|
||||
ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
|
||||
if (ret) {
|
||||
kfree(dma_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
snd_dmaengine_pcm_set_data(substream, dma_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_imx_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
|
||||
|
||||
snd_dmaengine_pcm_close(substream);
|
||||
kfree(dma_data);
|
||||
|
||||
return 0;
|
||||
return snd_dmaengine_pcm_open(substream, filter,
|
||||
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops imx_pcm_ops = {
|
||||
.open = snd_imx_open,
|
||||
.close = snd_imx_close,
|
||||
.close = snd_dmaengine_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = snd_imx_pcm_hw_params,
|
||||
.trigger = snd_dmaengine_pcm_trigger,
|
||||
|
|
|
@ -299,8 +299,8 @@ int imx_pcm_fiq_init(struct platform_device *pdev)
|
|||
|
||||
imx_ssi_fiq_base = (unsigned long)ssi->base;
|
||||
|
||||
ssi->dma_params_tx.burstsize = 4;
|
||||
ssi->dma_params_rx.burstsize = 6;
|
||||
ssi->dma_params_tx.maxburst = 4;
|
||||
ssi->dma_params_rx.maxburst = 6;
|
||||
|
||||
ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
|
||||
if (ret)
|
||||
|
|
|
@ -13,17 +13,24 @@
|
|||
#ifndef _IMX_PCM_H
|
||||
#define _IMX_PCM_H
|
||||
|
||||
#include <linux/platform_data/dma-imx.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;
|
||||
bool shared_peripheral; /* The peripheral is on SPBA bus */
|
||||
};
|
||||
static inline void
|
||||
imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data,
|
||||
int dma, bool shared)
|
||||
{
|
||||
dma_data->dma_request = dma;
|
||||
dma_data->priority = DMA_PRIO_HIGH;
|
||||
if (shared)
|
||||
dma_data->peripheral_type = IMX_DMATYPE_SSI_SP;
|
||||
else
|
||||
dma_data->peripheral_type = IMX_DMATYPE_SSI;
|
||||
}
|
||||
|
||||
int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
|
||||
struct vm_area_struct *vma);
|
||||
|
|
|
@ -236,7 +236,7 @@ static int imx_ssi_startup(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
struct imx_pcm_dma_params *dma_data;
|
||||
struct snd_dmaengine_dai_dma_data *dma_data;
|
||||
|
||||
/* Tx/Rx config */
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
|
@ -369,8 +369,8 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
|
|||
|
||||
snd_soc_dai_set_drvdata(dai, ssi);
|
||||
|
||||
val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
|
||||
SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
|
||||
val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.maxburst) |
|
||||
SSI_SFCSR_RFWM0(ssi->dma_params_rx.maxburst);
|
||||
writel(val, ssi->base + SSI_SFCSR);
|
||||
|
||||
return 0;
|
||||
|
@ -579,19 +579,26 @@ static int imx_ssi_probe(struct platform_device *pdev)
|
|||
|
||||
writel(0x0, ssi->base + SSI_SIER);
|
||||
|
||||
ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
|
||||
ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
|
||||
ssi->dma_params_rx.addr = res->start + SSI_SRX0;
|
||||
ssi->dma_params_tx.addr = res->start + SSI_STX0;
|
||||
|
||||
ssi->dma_params_tx.burstsize = 6;
|
||||
ssi->dma_params_rx.burstsize = 4;
|
||||
ssi->dma_params_tx.maxburst = 6;
|
||||
ssi->dma_params_rx.maxburst = 4;
|
||||
|
||||
ssi->dma_params_tx.filter_data = &ssi->filter_data_tx;
|
||||
ssi->dma_params_rx.filter_data = &ssi->filter_data_rx;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
|
||||
if (res)
|
||||
ssi->dma_params_tx.dma = res->start;
|
||||
if (res) {
|
||||
imx_pcm_dma_params_init_data(&ssi->filter_data_tx, res->start,
|
||||
false);
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0");
|
||||
if (res)
|
||||
ssi->dma_params_rx.dma = res->start;
|
||||
if (res) {
|
||||
imx_pcm_dma_params_init_data(&ssi->filter_data_rx, res->start,
|
||||
false);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, ssi);
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@
|
|||
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/platform_data/dma-imx.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
#include "imx-pcm.h"
|
||||
|
||||
struct imx_ssi {
|
||||
|
@ -204,8 +205,10 @@ struct imx_ssi {
|
|||
void (*ac97_reset) (struct snd_ac97 *ac97);
|
||||
void (*ac97_warm_reset)(struct snd_ac97 *ac97);
|
||||
|
||||
struct imx_pcm_dma_params dma_params_rx;
|
||||
struct imx_pcm_dma_params dma_params_tx;
|
||||
struct snd_dmaengine_dai_dma_data dma_params_rx;
|
||||
struct snd_dmaengine_dai_dma_data dma_params_tx;
|
||||
struct imx_dma_data filter_data_tx;
|
||||
struct imx_dma_data filter_data_rx;
|
||||
|
||||
int enabled;
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/fsl/mxs-dma.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/initval.h>
|
||||
|
@ -39,11 +38,6 @@
|
|||
|
||||
#include "mxs-pcm.h"
|
||||
|
||||
struct mxs_pcm_dma_data {
|
||||
struct mxs_dma_data dma_data;
|
||||
struct mxs_pcm_dma_params *dma_params;
|
||||
};
|
||||
|
||||
static struct snd_pcm_hardware snd_mxs_hardware = {
|
||||
.info = SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
|
@ -66,8 +60,7 @@ static struct snd_pcm_hardware snd_mxs_hardware = {
|
|||
|
||||
static bool filter(struct dma_chan *chan, void *param)
|
||||
{
|
||||
struct mxs_pcm_dma_data *pcm_dma_data = param;
|
||||
struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params;
|
||||
struct mxs_pcm_dma_params *dma_params = param;
|
||||
|
||||
if (!mxs_dma_is_apbx(chan))
|
||||
return false;
|
||||
|
@ -75,7 +68,7 @@ static bool filter(struct dma_chan *chan, void *param)
|
|||
if (chan->chan_id != dma_params->chan_num)
|
||||
return false;
|
||||
|
||||
chan->private = &pcm_dma_data->dma_data;
|
||||
chan->private = &dma_params->dma_data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -91,37 +84,11 @@ static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
static int snd_mxs_open(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct mxs_pcm_dma_data *pcm_dma_data;
|
||||
int ret;
|
||||
|
||||
pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL);
|
||||
if (pcm_dma_data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq;
|
||||
|
||||
ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data);
|
||||
if (ret) {
|
||||
kfree(pcm_dma_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
|
||||
|
||||
snd_dmaengine_pcm_set_data(substream, pcm_dma_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_mxs_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream);
|
||||
|
||||
snd_dmaengine_pcm_close(substream);
|
||||
kfree(pcm_dma_data);
|
||||
|
||||
return 0;
|
||||
return snd_dmaengine_pcm_open(substream, filter,
|
||||
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
|
||||
}
|
||||
|
||||
static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
|
||||
|
@ -137,7 +104,7 @@ static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
|
|||
|
||||
static struct snd_pcm_ops mxs_pcm_ops = {
|
||||
.open = snd_mxs_open,
|
||||
.close = snd_mxs_close,
|
||||
.close = snd_dmaengine_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = snd_mxs_pcm_hw_params,
|
||||
.trigger = snd_dmaengine_pcm_trigger,
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
#ifndef _MXS_PCM_H
|
||||
#define _MXS_PCM_H
|
||||
|
||||
#include <linux/fsl/mxs-dma.h>
|
||||
|
||||
struct mxs_pcm_dma_params {
|
||||
int chan_irq;
|
||||
struct mxs_dma_data dma_data;
|
||||
int chan_num;
|
||||
};
|
||||
|
||||
|
|
|
@ -757,9 +757,9 @@ static int mxs_saif_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
|
||||
if (saif->dma_param.chan_irq < 0) {
|
||||
ret = saif->dma_param.chan_irq;
|
||||
saif->dma_param.dma_data.chan_irq = platform_get_irq(pdev, 1);
|
||||
if (saif->dma_param.dma_data.chan_irq < 0) {
|
||||
ret = saif->dma_param.dma_data.chan_irq;
|
||||
dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <linux/platform_data/asoc-ti-mcbsp.h>
|
||||
|
||||
#include "omap-mcbsp.h"
|
||||
#include "omap-pcm.h"
|
||||
|
||||
#include "../codecs/tlv320aic23.h"
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include <linux/platform_data/asoc-ti-mcbsp.h>
|
||||
|
||||
#include "omap-mcbsp.h"
|
||||
#include "omap-pcm.h"
|
||||
#include "../codecs/cx20442.h"
|
||||
|
||||
|
||||
|
|
|
@ -1018,9 +1018,10 @@ int omap_mcbsp_init(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
/* RX DMA request number, and port address configuration */
|
||||
mcbsp->dma_data[1].name = "Audio Capture";
|
||||
mcbsp->dma_data[1].dma_req = res->start;
|
||||
mcbsp->dma_data[1].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 1);
|
||||
mcbsp->dma_req[1] = res->start;
|
||||
mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1];
|
||||
mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1);
|
||||
mcbsp->dma_data[1].maxburst = 4;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
|
||||
if (!res) {
|
||||
|
@ -1028,9 +1029,10 @@ int omap_mcbsp_init(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
/* TX DMA request number, and port address configuration */
|
||||
mcbsp->dma_data[0].name = "Audio Playback";
|
||||
mcbsp->dma_data[0].dma_req = res->start;
|
||||
mcbsp->dma_data[0].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 0);
|
||||
mcbsp->dma_req[0] = res->start;
|
||||
mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0];
|
||||
mcbsp->dma_data[0].addr = omap_mcbsp_dma_reg_params(mcbsp, 0);
|
||||
mcbsp->dma_data[0].maxburst = 4;
|
||||
|
||||
mcbsp->fclk = clk_get(&pdev->dev, "fck");
|
||||
if (IS_ERR(mcbsp->fclk)) {
|
||||
|
|
|
@ -24,14 +24,14 @@
|
|||
#ifndef __ASOC_MCBSP_H
|
||||
#define __ASOC_MCBSP_H
|
||||
|
||||
#include "omap-pcm.h"
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1
|
||||
#define mcbsp_omap1() 1
|
||||
#else
|
||||
#define mcbsp_omap1() 0
|
||||
#endif
|
||||
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
/* McBSP register numbers. Register address offset = num * reg_step */
|
||||
enum {
|
||||
/* Common registers */
|
||||
|
@ -312,7 +312,8 @@ struct omap_mcbsp {
|
|||
struct omap_mcbsp_platform_data *pdata;
|
||||
struct omap_mcbsp_st_data *st_data;
|
||||
struct omap_mcbsp_reg_cfg cfg_regs;
|
||||
struct omap_pcm_dma_data dma_data[2];
|
||||
struct snd_dmaengine_dai_dma_data dma_data[2];
|
||||
unsigned int dma_req[2];
|
||||
int dma_op_mode;
|
||||
u16 max_tx_thres;
|
||||
u16 max_rx_thres;
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include <linux/platform_data/asoc-ti-mcbsp.h>
|
||||
|
||||
#include "omap-mcbsp.h"
|
||||
#include "omap-pcm.h"
|
||||
|
||||
#define N810_HEADSET_AMP_GPIO 10
|
||||
#define N810_SPEAKER_AMP_GPIO 101
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
#include "omap-dmic.h"
|
||||
#include "omap-mcpdm.h"
|
||||
#include "omap-pcm.h"
|
||||
#include "../codecs/twl6040.h"
|
||||
|
||||
struct abe_twl6040 {
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
#include <sound/pcm_params.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "omap-pcm.h"
|
||||
#include "omap-dmic.h"
|
||||
|
||||
struct omap_dmic {
|
||||
|
@ -55,13 +55,9 @@ struct omap_dmic {
|
|||
u32 ch_enabled;
|
||||
bool active;
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
||||
/*
|
||||
* Stream DMA parameters
|
||||
*/
|
||||
static struct omap_pcm_dma_data omap_dmic_dai_dma_params = {
|
||||
.name = "DMIC capture",
|
||||
struct snd_dmaengine_dai_dma_data dma_data;
|
||||
unsigned int dma_req;
|
||||
};
|
||||
|
||||
static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
|
||||
|
@ -118,7 +114,7 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
|
|||
|
||||
mutex_unlock(&dmic->mutex);
|
||||
|
||||
snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
|
||||
snd_soc_dai_set_dma_data(dai, substream, &dmic->dma_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -203,7 +199,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
|
||||
struct omap_pcm_dma_data *dma_data;
|
||||
struct snd_dmaengine_dai_dma_data *dma_data;
|
||||
int channels;
|
||||
|
||||
dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params));
|
||||
|
@ -230,7 +226,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
/* packet size is threshold * channels */
|
||||
dma_data = snd_soc_dai_get_dma_data(dai, substream);
|
||||
dma_data->packet_size = dmic->threshold * channels;
|
||||
dma_data->maxburst = dmic->threshold * channels;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -480,7 +476,7 @@ static int asoc_dmic_probe(struct platform_device *pdev)
|
|||
ret = -ENODEV;
|
||||
goto err_put_clk;
|
||||
}
|
||||
omap_dmic_dai_dma_params.port_addr = res->start + OMAP_DMIC_DATA_REG;
|
||||
dmic->dma_data.addr = res->start + OMAP_DMIC_DATA_REG;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
|
||||
if (!res) {
|
||||
|
@ -488,7 +484,9 @@ static int asoc_dmic_probe(struct platform_device *pdev)
|
|||
ret = -ENODEV;
|
||||
goto err_put_clk;
|
||||
}
|
||||
omap_dmic_dai_dma_params.dma_req = res->start;
|
||||
|
||||
dmic->dma_req = res->start;
|
||||
dmic->dma_data.filter_data = &dmic->dma_req;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
|
||||
if (!res) {
|
||||
|
@ -497,19 +495,9 @@ static int asoc_dmic_probe(struct platform_device *pdev)
|
|||
goto err_put_clk;
|
||||
}
|
||||
|
||||
if (!devm_request_mem_region(&pdev->dev, res->start,
|
||||
resource_size(res), pdev->name)) {
|
||||
dev_err(dmic->dev, "memory region already claimed\n");
|
||||
ret = -ENODEV;
|
||||
goto err_put_clk;
|
||||
}
|
||||
|
||||
dmic->io_base = devm_ioremap(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!dmic->io_base) {
|
||||
ret = -ENOMEM;
|
||||
goto err_put_clk;
|
||||
}
|
||||
dmic->io_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(dmic->io_base))
|
||||
return PTR_ERR(dmic->io_base);
|
||||
|
||||
ret = snd_soc_register_component(&pdev->dev, &omap_dmic_component,
|
||||
&omap_dmic_dai, 1);
|
||||
|
|
|
@ -32,15 +32,16 @@
|
|||
#include <sound/soc.h>
|
||||
#include <sound/asound.h>
|
||||
#include <sound/asoundef.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "omap-pcm.h"
|
||||
#include "omap-hdmi.h"
|
||||
|
||||
#define DRV_NAME "omap-hdmi-audio-dai"
|
||||
|
||||
struct hdmi_priv {
|
||||
struct omap_pcm_dma_data dma_params;
|
||||
struct snd_dmaengine_dai_dma_data dma_data;
|
||||
unsigned int dma_req;
|
||||
struct omap_dss_audio dss_audio;
|
||||
struct snd_aes_iec958 iec;
|
||||
struct snd_cea_861_aud_if cea;
|
||||
|
@ -68,7 +69,7 @@ static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
snd_soc_dai_set_dma_data(dai, substream, &priv->dma_params);
|
||||
snd_soc_dai_set_dma_data(dai, substream, &priv->dma_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -88,25 +89,20 @@ static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
|
||||
struct snd_aes_iec958 *iec = &priv->iec;
|
||||
struct snd_cea_861_aud_if *cea = &priv->cea;
|
||||
struct omap_pcm_dma_data *dma_data;
|
||||
int err = 0;
|
||||
|
||||
dma_data = snd_soc_dai_get_dma_data(dai, substream);
|
||||
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
dma_data->packet_size = 16;
|
||||
priv->dma_data.maxburst = 16;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
dma_data->packet_size = 32;
|
||||
priv->dma_data.maxburst = 32;
|
||||
break;
|
||||
default:
|
||||
dev_err(dai->dev, "format not supported!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dma_data->data_type = 32;
|
||||
|
||||
/*
|
||||
* fill the IEC-60958 channel status word
|
||||
*/
|
||||
|
@ -287,8 +283,7 @@ static int omap_hdmi_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
hdmi_data->dma_params.port_addr = hdmi_rsrc->start
|
||||
+ OMAP_HDMI_AUDIO_DMA_PORT;
|
||||
hdmi_data->dma_data.addr = hdmi_rsrc->start + OMAP_HDMI_AUDIO_DMA_PORT;
|
||||
|
||||
hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0);
|
||||
if (!hdmi_rsrc) {
|
||||
|
@ -296,8 +291,9 @@ static int omap_hdmi_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
hdmi_data->dma_params.dma_req = hdmi_rsrc->start;
|
||||
hdmi_data->dma_params.name = "HDMI playback";
|
||||
hdmi_data->dma_req = hdmi_rsrc->start;
|
||||
hdmi_data->dma_data.filter_data = &hdmi_data->dma_req;
|
||||
hdmi_data->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
|
||||
/*
|
||||
* TODO: We assume that there is only one DSS HDMI device. Future
|
||||
|
|
|
@ -33,11 +33,11 @@
|
|||
#include <sound/pcm_params.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include <linux/platform_data/asoc-ti-mcbsp.h>
|
||||
#include "mcbsp.h"
|
||||
#include "omap-mcbsp.h"
|
||||
#include "omap-pcm.h"
|
||||
|
||||
#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
|
||||
|
||||
|
@ -62,24 +62,22 @@ enum {
|
|||
* Stream DMA parameters. DMA request line and port address are set runtime
|
||||
* since they are different between OMAP1 and later OMAPs
|
||||
*/
|
||||
static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
|
||||
static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream,
|
||||
unsigned int packet_size)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
struct omap_pcm_dma_data *dma_data;
|
||||
int words;
|
||||
|
||||
dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
|
||||
/*
|
||||
* Configure McBSP threshold based on either:
|
||||
* packet_size, when the sDMA is in packet mode, or based on the
|
||||
* period size in THRESHOLD mode, otherwise use McBSP threshold = 1
|
||||
* for mono streams.
|
||||
*/
|
||||
if (dma_data->packet_size)
|
||||
words = dma_data->packet_size;
|
||||
if (packet_size)
|
||||
words = packet_size;
|
||||
else
|
||||
words = 1;
|
||||
|
||||
|
@ -226,7 +224,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
|
||||
struct omap_pcm_dma_data *dma_data;
|
||||
struct snd_dmaengine_dai_dma_data *dma_data;
|
||||
int wlen, channels, wpf;
|
||||
int pkt_size = 0;
|
||||
unsigned int format, div, framesize, master;
|
||||
|
@ -245,7 +243,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
return -EINVAL;
|
||||
}
|
||||
if (mcbsp->pdata->buffer_size) {
|
||||
dma_data->set_threshold = omap_mcbsp_set_threshold;
|
||||
if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
|
||||
int period_words, max_thrsh;
|
||||
int divider = 0;
|
||||
|
@ -276,9 +273,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
/* Use packet mode for non mono streams */
|
||||
pkt_size = channels;
|
||||
}
|
||||
omap_mcbsp_set_threshold(substream, pkt_size);
|
||||
}
|
||||
|
||||
dma_data->packet_size = pkt_size;
|
||||
dma_data->maxburst = pkt_size;
|
||||
|
||||
if (mcbsp->configured) {
|
||||
/* McBSP already configured by another stream */
|
||||
|
|
|
@ -39,11 +39,14 @@
|
|||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "omap-mcpdm.h"
|
||||
#include "omap-pcm.h"
|
||||
|
||||
#define OMAP44XX_MCPDM_L3_BASE 0x49032000
|
||||
struct mcpdm_link_config {
|
||||
u32 link_mask; /* channel mask for the direction */
|
||||
u32 threshold; /* FIFO threshold */
|
||||
};
|
||||
|
||||
struct omap_mcpdm {
|
||||
struct device *dev;
|
||||
|
@ -53,29 +56,22 @@ struct omap_mcpdm {
|
|||
|
||||
struct mutex mutex;
|
||||
|
||||
/* channel data */
|
||||
u32 dn_channels;
|
||||
u32 up_channels;
|
||||
|
||||
/* McPDM FIFO thresholds */
|
||||
u32 dn_threshold;
|
||||
u32 up_threshold;
|
||||
/* Playback/Capture configuration */
|
||||
struct mcpdm_link_config config[2];
|
||||
|
||||
/* McPDM dn offsets for rx1, and 2 channels */
|
||||
u32 dn_rx_offset;
|
||||
|
||||
/* McPDM needs to be restarted due to runtime reconfiguration */
|
||||
bool restart;
|
||||
|
||||
struct snd_dmaengine_dai_dma_data dma_data[2];
|
||||
unsigned int dma_req[2];
|
||||
};
|
||||
|
||||
/*
|
||||
* Stream DMA parameters
|
||||
*/
|
||||
static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
|
||||
{
|
||||
.name = "Audio playback",
|
||||
},
|
||||
{
|
||||
.name = "Audio capture",
|
||||
},
|
||||
};
|
||||
|
||||
static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val)
|
||||
{
|
||||
|
@ -130,11 +126,12 @@ static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {}
|
|||
static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
|
||||
{
|
||||
u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
|
||||
u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask;
|
||||
|
||||
ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
|
||||
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
|
||||
|
||||
ctrl |= mcpdm->dn_channels | mcpdm->up_channels;
|
||||
ctrl |= link_mask;
|
||||
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
|
||||
|
||||
ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
|
||||
|
@ -148,11 +145,12 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
|
|||
static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm)
|
||||
{
|
||||
u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
|
||||
u32 link_mask = MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK;
|
||||
|
||||
ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
|
||||
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
|
||||
|
||||
ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels);
|
||||
ctrl &= ~(link_mask);
|
||||
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
|
||||
|
||||
ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
|
||||
|
@ -188,8 +186,10 @@ static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm)
|
|||
omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
|
||||
}
|
||||
|
||||
omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold);
|
||||
omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold);
|
||||
omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN,
|
||||
mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold);
|
||||
omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP,
|
||||
mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold);
|
||||
|
||||
omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET,
|
||||
MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE);
|
||||
|
@ -267,7 +267,7 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
|
|||
mutex_unlock(&mcpdm->mutex);
|
||||
|
||||
snd_soc_dai_set_dma_data(dai, substream,
|
||||
&omap_mcpdm_dai_dma_params[substream->stream]);
|
||||
&mcpdm->dma_data[substream->stream]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -283,6 +283,8 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
|
|||
if (omap_mcpdm_active(mcpdm)) {
|
||||
omap_mcpdm_stop(mcpdm);
|
||||
omap_mcpdm_close_streams(mcpdm);
|
||||
mcpdm->config[0].link_mask = 0;
|
||||
mcpdm->config[1].link_mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,7 +297,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
|
||||
int stream = substream->stream;
|
||||
struct omap_pcm_dma_data *dma_data;
|
||||
struct snd_dmaengine_dai_dma_data *dma_data;
|
||||
u32 threshold;
|
||||
int channels;
|
||||
int link_mask = 0;
|
||||
|
||||
|
@ -325,16 +328,32 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
dma_data = snd_soc_dai_get_dma_data(dai, substream);
|
||||
|
||||
threshold = mcpdm->config[stream].threshold;
|
||||
/* Configure McPDM channels, and DMA packet size */
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
mcpdm->dn_channels = link_mask << 3;
|
||||
dma_data->packet_size =
|
||||
(MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels;
|
||||
link_mask <<= 3;
|
||||
|
||||
/* If capture is not running assume a stereo stream to come */
|
||||
if (!mcpdm->config[!stream].link_mask)
|
||||
mcpdm->config[!stream].link_mask = 0x3;
|
||||
|
||||
dma_data->maxburst =
|
||||
(MCPDM_DN_THRES_MAX - threshold) * channels;
|
||||
} else {
|
||||
mcpdm->up_channels = link_mask << 0;
|
||||
dma_data->packet_size = mcpdm->up_threshold * channels;
|
||||
/* If playback is not running assume a stereo stream to come */
|
||||
if (!mcpdm->config[!stream].link_mask)
|
||||
mcpdm->config[!stream].link_mask = (0x3 << 3);
|
||||
|
||||
dma_data->maxburst = threshold * channels;
|
||||
}
|
||||
|
||||
/* Check if we need to restart McPDM with this stream */
|
||||
if (mcpdm->config[stream].link_mask &&
|
||||
mcpdm->config[stream].link_mask != link_mask)
|
||||
mcpdm->restart = true;
|
||||
|
||||
mcpdm->config[stream].link_mask = link_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -346,6 +365,11 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
|
|||
if (!omap_mcpdm_active(mcpdm)) {
|
||||
omap_mcpdm_start(mcpdm);
|
||||
omap_mcpdm_reg_dump(mcpdm);
|
||||
} else if (mcpdm->restart) {
|
||||
omap_mcpdm_stop(mcpdm);
|
||||
omap_mcpdm_start(mcpdm);
|
||||
mcpdm->restart = false;
|
||||
omap_mcpdm_reg_dump(mcpdm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -369,7 +393,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
|
|||
pm_runtime_get_sync(mcpdm->dev);
|
||||
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00);
|
||||
|
||||
ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler,
|
||||
ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler,
|
||||
0, "McPDM", (void *)mcpdm);
|
||||
|
||||
pm_runtime_put_sync(mcpdm->dev);
|
||||
|
@ -380,8 +404,9 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
|
|||
}
|
||||
|
||||
/* Configure McPDM threshold values */
|
||||
mcpdm->dn_threshold = 2;
|
||||
mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3;
|
||||
mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2;
|
||||
mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold =
|
||||
MCPDM_UP_THRES_MAX - 3;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -389,7 +414,6 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
|
|||
{
|
||||
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
free_irq(mcpdm->irq, (void *)mcpdm);
|
||||
pm_runtime_disable(mcpdm->dev);
|
||||
|
||||
return 0;
|
||||
|
@ -450,33 +474,30 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
|
|||
if (res == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
omap_mcpdm_dai_dma_params[0].port_addr = res->start + MCPDM_REG_DN_DATA;
|
||||
omap_mcpdm_dai_dma_params[1].port_addr = res->start + MCPDM_REG_UP_DATA;
|
||||
mcpdm->dma_data[0].addr = res->start + MCPDM_REG_DN_DATA;
|
||||
mcpdm->dma_data[1].addr = res->start + MCPDM_REG_UP_DATA;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link");
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
omap_mcpdm_dai_dma_params[0].dma_req = res->start;
|
||||
mcpdm->dma_req[0] = res->start;
|
||||
mcpdm->dma_data[0].filter_data = &mcpdm->dma_req[0];
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link");
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
omap_mcpdm_dai_dma_params[1].dma_req = res->start;
|
||||
mcpdm->dma_req[1] = res->start;
|
||||
mcpdm->dma_data[1].filter_data = &mcpdm->dma_req[1];
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
|
||||
if (res == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!devm_request_mem_region(&pdev->dev, res->start,
|
||||
resource_size(res), "McPDM"))
|
||||
return -EBUSY;
|
||||
|
||||
mcpdm->io_base = devm_ioremap(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!mcpdm->io_base)
|
||||
return -ENOMEM;
|
||||
mcpdm->io_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(mcpdm->io_base))
|
||||
return PTR_ERR(mcpdm->io_base);
|
||||
|
||||
mcpdm->irq = platform_get_irq(pdev, 0);
|
||||
if (mcpdm->irq < 0)
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
#include <sound/dmaengine_pcm.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "omap-pcm.h"
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1
|
||||
#define pcm_omap1510() cpu_is_omap1510()
|
||||
#else
|
||||
|
@ -56,25 +54,6 @@ static const struct snd_pcm_hardware omap_pcm_hardware = {
|
|||
.buffer_bytes_max = 128 * 1024,
|
||||
};
|
||||
|
||||
static int omap_pcm_get_dma_buswidth(int num_bits)
|
||||
{
|
||||
int buswidth;
|
||||
|
||||
switch (num_bits) {
|
||||
case 16:
|
||||
buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
break;
|
||||
case 32:
|
||||
buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
break;
|
||||
default:
|
||||
buswidth = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return buswidth;
|
||||
}
|
||||
|
||||
|
||||
/* this may get called several times by oss emulation */
|
||||
static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
|
@ -105,20 +84,9 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
/* Override the *_dma addr_width if requested by the DAI driver */
|
||||
if (dma_data->data_type) {
|
||||
int buswidth = omap_pcm_get_dma_buswidth(dma_data->data_type);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
config.dst_addr_width = buswidth;
|
||||
else
|
||||
config.src_addr_width = buswidth;
|
||||
}
|
||||
|
||||
config.src_addr = dma_data->port_addr;
|
||||
config.dst_addr = dma_data->port_addr;
|
||||
config.src_maxburst = dma_data->packet_size;
|
||||
config.dst_maxburst = dma_data->packet_size;
|
||||
snd_dmaengine_pcm_set_config_from_dai_data(substream,
|
||||
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
|
||||
&config);
|
||||
|
||||
return dmaengine_slave_config(chan, &config);
|
||||
}
|
||||
|
@ -129,37 +97,6 @@ static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct omap_pcm_dma_data *dma_data;
|
||||
int ret = 0;
|
||||
|
||||
dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
/* Configure McBSP internal buffer usage */
|
||||
if (dma_data->set_threshold)
|
||||
dma_data->set_threshold(substream);
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
ret = snd_dmaengine_pcm_trigger(substream, cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_pcm_uframes_t offset;
|
||||
|
@ -175,20 +112,14 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
|
|||
static int omap_pcm_open(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct omap_pcm_dma_data *dma_data;
|
||||
struct snd_dmaengine_dai_dma_data *dma_data;
|
||||
|
||||
snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
|
||||
|
||||
dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
|
||||
return snd_dmaengine_pcm_open(substream, omap_dma_filter_fn,
|
||||
&dma_data->dma_req);
|
||||
}
|
||||
|
||||
static int omap_pcm_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_dmaengine_pcm_close(substream);
|
||||
return 0;
|
||||
dma_data->filter_data);
|
||||
}
|
||||
|
||||
static int omap_pcm_mmap(struct snd_pcm_substream *substream,
|
||||
|
@ -204,11 +135,11 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream,
|
|||
|
||||
static struct snd_pcm_ops omap_pcm_ops = {
|
||||
.open = omap_pcm_open,
|
||||
.close = omap_pcm_close,
|
||||
.close = snd_dmaengine_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = omap_pcm_hw_params,
|
||||
.hw_free = omap_pcm_hw_free,
|
||||
.trigger = omap_pcm_trigger,
|
||||
.trigger = snd_dmaengine_pcm_trigger,
|
||||
.pointer = omap_pcm_pointer,
|
||||
.mmap = omap_pcm_mmap,
|
||||
};
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* omap-pcm.h
|
||||
*
|
||||
* Copyright (C) 2008 Nokia Corporation
|
||||
*
|
||||
* Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
|
||||
* Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OMAP_PCM_H__
|
||||
#define __OMAP_PCM_H__
|
||||
|
||||
struct snd_pcm_substream;
|
||||
|
||||
struct omap_pcm_dma_data {
|
||||
char *name; /* stream identifier */
|
||||
int dma_req; /* DMA request line */
|
||||
unsigned long port_addr; /* transmit/receive register */
|
||||
void (*set_threshold)(struct snd_pcm_substream *substream);
|
||||
int data_type; /* 8, 16, 32 (bits) or 0 to let omap-pcm
|
||||
* to decide the sDMA data type */
|
||||
int packet_size; /* packet size only in PACKET mode */
|
||||
};
|
||||
|
||||
#endif
|
|
@ -43,7 +43,6 @@
|
|||
#include <sound/jack.h>
|
||||
|
||||
#include "omap-mcbsp.h"
|
||||
#include "omap-pcm.h"
|
||||
|
||||
struct omap_twl4030 {
|
||||
int jack_detect; /* board can detect jack events */
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include <linux/platform_data/asoc-ti-mcbsp.h>
|
||||
|
||||
#include "omap-mcbsp.h"
|
||||
#include "omap-pcm.h"
|
||||
|
||||
#define OMAP3_PANDORA_DAC_POWER_GPIO 118
|
||||
#define OMAP3_PANDORA_AMP_POWER_GPIO 14
|
||||
|
@ -80,12 +79,18 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream,
|
|||
static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* The PCM1773 DAC datasheet requires 1ms delay between switching
|
||||
* VCC power on/off and /PD pin high/low
|
||||
*/
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
regulator_enable(omap3pandora_dac_reg);
|
||||
ret = regulator_enable(omap3pandora_dac_reg);
|
||||
if (ret) {
|
||||
dev_err(w->dapm->dev, "Failed to power DAC: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
mdelay(1);
|
||||
gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
|
||||
} else {
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include <linux/platform_data/asoc-ti-mcbsp.h>
|
||||
|
||||
#include "omap-mcbsp.h"
|
||||
#include "omap-pcm.h"
|
||||
#include "../codecs/tlv320aic23.h"
|
||||
|
||||
#define CODEC_CLOCK 12000000
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include <asm/mach-types.h>
|
||||
|
||||
#include "omap-mcbsp.h"
|
||||
#include "omap-pcm.h"
|
||||
|
||||
#define RX51_TVOUT_SEL_GPIO 40
|
||||
#define RX51_JACK_DETECT_GPIO 177
|
||||
|
|
|
@ -118,9 +118,8 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream)
|
|||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct platform_device *pdev = to_platform_device(rtd->platform->dev);
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct mmp_dma_data *dma_data;
|
||||
struct mmp_dma_data dma_data;
|
||||
struct resource *r;
|
||||
int ret;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream);
|
||||
if (!r)
|
||||
|
@ -128,33 +127,11 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream)
|
|||
|
||||
snd_soc_set_runtime_hwparams(substream,
|
||||
&mmp_pcm_hardware[substream->stream]);
|
||||
dma_data = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct mmp_dma_data), GFP_KERNEL);
|
||||
if (dma_data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_data->dma_res = r;
|
||||
dma_data->ssp_id = cpu_dai->id;
|
||||
dma_data.dma_res = r;
|
||||
dma_data.ssp_id = cpu_dai->id;
|
||||
|
||||
ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
|
||||
if (ret) {
|
||||
devm_kfree(&pdev->dev, dma_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
snd_dmaengine_pcm_set_data(substream, dma_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmp_pcm_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct mmp_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct platform_device *pdev = to_platform_device(rtd->platform->dev);
|
||||
|
||||
snd_dmaengine_pcm_close(substream);
|
||||
devm_kfree(&pdev->dev, dma_data);
|
||||
return 0;
|
||||
return snd_dmaengine_pcm_open(substream, filter, &dma_data);
|
||||
}
|
||||
|
||||
static int mmp_pcm_mmap(struct snd_pcm_substream *substream,
|
||||
|
@ -171,7 +148,7 @@ static int mmp_pcm_mmap(struct snd_pcm_substream *substream,
|
|||
|
||||
struct snd_pcm_ops mmp_pcm_ops = {
|
||||
.open = mmp_pcm_open,
|
||||
.close = mmp_pcm_close,
|
||||
.close = snd_dmaengine_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = mmp_pcm_hw_params,
|
||||
.trigger = snd_dmaengine_pcm_trigger,
|
||||
|
|
|
@ -33,8 +33,6 @@ struct dmaengine_pcm_runtime_data {
|
|||
dma_cookie_t cookie;
|
||||
|
||||
unsigned int pos;
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
||||
static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
|
||||
|
@ -43,33 +41,6 @@ static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
|
|||
return substream->runtime->private_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_dmaengine_pcm_set_data - Set dmaengine substream private data
|
||||
* @substream: PCM substream
|
||||
* @data: Data to set
|
||||
*/
|
||||
void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data)
|
||||
{
|
||||
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
|
||||
|
||||
prtd->data = data;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_data);
|
||||
|
||||
/**
|
||||
* snd_dmaengine_pcm_get_data - Get dmaeinge substream private data
|
||||
* @substream: PCM substream
|
||||
*
|
||||
* Returns the data previously set with snd_dmaengine_pcm_set_data
|
||||
*/
|
||||
void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
|
||||
|
||||
return prtd->data;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_data);
|
||||
|
||||
struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
|
||||
|
@ -118,10 +89,49 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
|
|||
slave_config->src_addr_width = buswidth;
|
||||
}
|
||||
|
||||
slave_config->device_fc = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config);
|
||||
|
||||
/**
|
||||
* snd_dmaengine_pcm_set_config_from_dai_data() - Initializes a dma slave config
|
||||
* using DAI DMA data.
|
||||
* @substream: PCM substream
|
||||
* @dma_data: DAI DMA data
|
||||
* @slave_config: DMA slave configuration
|
||||
*
|
||||
* Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width and
|
||||
* slave_id fields of the DMA slave config from the same fields of the DAI DMA
|
||||
* data struct. The src and dst fields will be initialized depending on the
|
||||
* direction of the substream. If the substream is a playback stream the dst
|
||||
* fields will be initialized, if it is a capture stream the src fields will be
|
||||
* initialized. The {dst,src}_addr_width field will only be initialized if the
|
||||
* addr_width field of the DAI DMA data struct is not equal to
|
||||
* DMA_SLAVE_BUSWIDTH_UNDEFINED.
|
||||
*/
|
||||
void snd_dmaengine_pcm_set_config_from_dai_data(
|
||||
const struct snd_pcm_substream *substream,
|
||||
const struct snd_dmaengine_dai_dma_data *dma_data,
|
||||
struct dma_slave_config *slave_config)
|
||||
{
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
slave_config->dst_addr = dma_data->addr;
|
||||
slave_config->dst_maxburst = dma_data->maxburst;
|
||||
if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
|
||||
slave_config->dst_addr_width = dma_data->addr_width;
|
||||
} else {
|
||||
slave_config->src_addr = dma_data->addr;
|
||||
slave_config->src_maxburst = dma_data->maxburst;
|
||||
if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
|
||||
slave_config->src_addr_width = dma_data->addr_width;
|
||||
}
|
||||
|
||||
slave_config->slave_id = dma_data->slave_id;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);
|
||||
|
||||
static void dmaengine_pcm_dma_complete(void *arg)
|
||||
{
|
||||
struct snd_pcm_substream *substream = arg;
|
||||
|
|
|
@ -64,21 +64,7 @@ static int spear_pcm_open(struct snd_pcm_substream *substream)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
snd_dmaengine_pcm_set_data(substream, dma_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spear_pcm_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
|
||||
snd_dmaengine_pcm_close(substream);
|
||||
|
||||
return 0;
|
||||
return snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data)
|
||||
}
|
||||
|
||||
static int spear_pcm_mmap(struct snd_pcm_substream *substream,
|
||||
|
@ -93,7 +79,7 @@ static int spear_pcm_mmap(struct snd_pcm_substream *substream,
|
|||
|
||||
static struct snd_pcm_ops spear_pcm_ops = {
|
||||
.open = spear_pcm_open,
|
||||
.close = spear_pcm_close,
|
||||
.close = snd_dmaengine_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = spear_pcm_hw_params,
|
||||
.hw_free = spear_pcm_hw_free,
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "tegra_asoc_utils.h"
|
||||
#include "tegra20_ac97.h"
|
||||
|
@ -393,14 +394,14 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1;
|
||||
ac97->capture_dma_data.wrap = 4;
|
||||
ac97->capture_dma_data.width = 32;
|
||||
ac97->capture_dma_data.req_sel = of_dma[1];
|
||||
ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
ac97->capture_dma_data.maxburst = 4;
|
||||
ac97->capture_dma_data.slave_id = of_dma[1];
|
||||
|
||||
ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1;
|
||||
ac97->playback_dma_data.wrap = 4;
|
||||
ac97->playback_dma_data.width = 32;
|
||||
ac97->playback_dma_data.req_sel = of_dma[1];
|
||||
ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
ac97->capture_dma_data.maxburst = 4;
|
||||
ac97->capture_dma_data.slave_id = of_dma[0];
|
||||
|
||||
ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component,
|
||||
&tegra20_ac97_dai, 1);
|
||||
|
|
|
@ -85,8 +85,8 @@
|
|||
|
||||
struct tegra20_ac97 {
|
||||
struct clk *clk_ac97;
|
||||
struct tegra_pcm_dma_params capture_dma_data;
|
||||
struct tegra_pcm_dma_params playback_dma_data;
|
||||
struct snd_dmaengine_dai_dma_data capture_dma_data;
|
||||
struct snd_dmaengine_dai_dma_data playback_dma_data;
|
||||
struct regmap *regmap;
|
||||
int reset_gpio;
|
||||
int sync_gpio;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "tegra20_i2s.h"
|
||||
|
||||
|
@ -407,14 +408,14 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2;
|
||||
i2s->capture_dma_data.wrap = 4;
|
||||
i2s->capture_dma_data.width = 32;
|
||||
i2s->capture_dma_data.req_sel = dma_ch;
|
||||
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
i2s->capture_dma_data.maxburst = 4;
|
||||
i2s->capture_dma_data.slave_id = dma_ch;
|
||||
|
||||
i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1;
|
||||
i2s->playback_dma_data.wrap = 4;
|
||||
i2s->playback_dma_data.width = 32;
|
||||
i2s->playback_dma_data.req_sel = dma_ch;
|
||||
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
i2s->playback_dma_data.maxburst = 4;
|
||||
i2s->playback_dma_data.slave_id = dma_ch;
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
if (!pm_runtime_enabled(&pdev->dev)) {
|
||||
|
|
|
@ -155,8 +155,8 @@
|
|||
struct tegra20_i2s {
|
||||
struct snd_soc_dai_driver dai;
|
||||
struct clk *clk_i2s;
|
||||
struct tegra_pcm_dma_params capture_dma_data;
|
||||
struct tegra_pcm_dma_params playback_dma_data;
|
||||
struct snd_dmaengine_dai_dma_data capture_dma_data;
|
||||
struct snd_dmaengine_dai_dma_data playback_dma_data;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "tegra20_spdif.h"
|
||||
|
||||
|
@ -322,9 +323,9 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT;
|
||||
spdif->playback_dma_data.wrap = 4;
|
||||
spdif->playback_dma_data.width = 32;
|
||||
spdif->playback_dma_data.req_sel = dmareq->start;
|
||||
spdif->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
spdif->capture_dma_data.maxburst = 4;
|
||||
spdif->playback_dma_data.slave_id = dmareq->start;
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
if (!pm_runtime_enabled(&pdev->dev)) {
|
||||
|
|
|
@ -462,8 +462,8 @@
|
|||
|
||||
struct tegra20_spdif {
|
||||
struct clk *clk_spdif_out;
|
||||
struct tegra_pcm_dma_params capture_dma_data;
|
||||
struct tegra_pcm_dma_params playback_dma_data;
|
||||
struct snd_dmaengine_dai_dma_data capture_dma_data;
|
||||
struct snd_dmaengine_dai_dma_data playback_dma_data;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
|
|
|
@ -95,8 +95,8 @@ static int tegra30_ahub_runtime_resume(struct device *dev)
|
|||
}
|
||||
|
||||
int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
|
||||
unsigned long *fiforeg,
|
||||
unsigned long *reqsel)
|
||||
dma_addr_t *fiforeg,
|
||||
unsigned int *reqsel)
|
||||
{
|
||||
int channel;
|
||||
u32 reg, val;
|
||||
|
@ -178,8 +178,8 @@ int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif)
|
|||
EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo);
|
||||
|
||||
int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
|
||||
unsigned long *fiforeg,
|
||||
unsigned long *reqsel)
|
||||
dma_addr_t *fiforeg,
|
||||
unsigned int *reqsel)
|
||||
{
|
||||
int channel;
|
||||
u32 reg, val;
|
||||
|
|
|
@ -451,15 +451,15 @@ enum tegra30_ahub_rxcif {
|
|||
};
|
||||
|
||||
extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
|
||||
unsigned long *fiforeg,
|
||||
unsigned long *reqsel);
|
||||
dma_addr_t *fiforeg,
|
||||
unsigned int *reqsel);
|
||||
extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
|
||||
extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
|
||||
extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif);
|
||||
|
||||
extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
|
||||
unsigned long *fiforeg,
|
||||
unsigned long *reqsel);
|
||||
dma_addr_t *fiforeg,
|
||||
unsigned int *reqsel);
|
||||
extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif);
|
||||
extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif);
|
||||
extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "tegra30_ahub.h"
|
||||
#include "tegra30_i2s.h"
|
||||
|
@ -80,17 +81,17 @@ static int tegra30_i2s_startup(struct snd_pcm_substream *substream,
|
|||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
|
||||
&i2s->playback_dma_data.addr,
|
||||
&i2s->playback_dma_data.req_sel);
|
||||
i2s->playback_dma_data.wrap = 4;
|
||||
i2s->playback_dma_data.width = 32;
|
||||
&i2s->playback_dma_data.slave_id);
|
||||
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
i2s->playback_dma_data.maxburst = 4;
|
||||
tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
|
||||
i2s->playback_fifo_cif);
|
||||
} else {
|
||||
ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
|
||||
&i2s->capture_dma_data.addr,
|
||||
&i2s->capture_dma_data.req_sel);
|
||||
i2s->capture_dma_data.wrap = 4;
|
||||
i2s->capture_dma_data.width = 32;
|
||||
&i2s->capture_dma_data.slave_id);
|
||||
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
i2s->capture_dma_data.maxburst = 4;
|
||||
tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
|
||||
i2s->capture_i2s_cif);
|
||||
}
|
||||
|
|
|
@ -231,10 +231,10 @@ struct tegra30_i2s {
|
|||
struct clk *clk_i2s;
|
||||
enum tegra30_ahub_txcif capture_i2s_cif;
|
||||
enum tegra30_ahub_rxcif capture_fifo_cif;
|
||||
struct tegra_pcm_dma_params capture_dma_data;
|
||||
struct snd_dmaengine_dai_dma_data capture_dma_data;
|
||||
enum tegra30_ahub_rxcif playback_i2s_cif;
|
||||
enum tegra30_ahub_txcif playback_fifo_cif;
|
||||
struct tegra_pcm_dma_params playback_dma_data;
|
||||
struct snd_dmaengine_dai_dma_data playback_dma_data;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
|
|
|
@ -73,24 +73,15 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_pcm_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_dmaengine_pcm_close(substream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct device *dev = rtd->platform->dev;
|
||||
struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
|
||||
struct tegra_pcm_dma_params *dmap;
|
||||
struct dma_slave_config slave_config;
|
||||
int ret;
|
||||
|
||||
dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
|
||||
ret = snd_hwparams_to_dma_slave_config(substream, params,
|
||||
&slave_config);
|
||||
if (ret) {
|
||||
|
@ -98,16 +89,9 @@ static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
slave_config.dst_addr = dmap->addr;
|
||||
slave_config.dst_maxburst = 4;
|
||||
} else {
|
||||
slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
slave_config.src_addr = dmap->addr;
|
||||
slave_config.src_maxburst = 4;
|
||||
}
|
||||
slave_config.slave_id = dmap->req_sel;
|
||||
snd_dmaengine_pcm_set_config_from_dai_data(substream,
|
||||
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
|
||||
&slave_config);
|
||||
|
||||
ret = dmaengine_slave_config(chan, &slave_config);
|
||||
if (ret < 0) {
|
||||
|
@ -138,7 +122,7 @@ static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
|
|||
|
||||
static struct snd_pcm_ops tegra_pcm_ops = {
|
||||
.open = tegra_pcm_open,
|
||||
.close = tegra_pcm_close,
|
||||
.close = snd_dmaengine_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = tegra_pcm_hw_params,
|
||||
.hw_free = tegra_pcm_hw_free,
|
||||
|
|
|
@ -31,13 +31,6 @@
|
|||
#ifndef __TEGRA_PCM_H__
|
||||
#define __TEGRA_PCM_H__
|
||||
|
||||
struct tegra_pcm_dma_params {
|
||||
unsigned long addr;
|
||||
unsigned long wrap;
|
||||
unsigned long width;
|
||||
unsigned long req_sel;
|
||||
};
|
||||
|
||||
int tegra_pcm_platform_register(struct device *dev);
|
||||
void tegra_pcm_platform_unregister(struct device *dev);
|
||||
|
||||
|
|
|
@ -28,28 +28,19 @@
|
|||
#include "ux500_msp_i2s.h"
|
||||
#include "ux500_pcm.h"
|
||||
|
||||
static struct snd_pcm_hardware ux500_pcm_hw_playback = {
|
||||
.info = SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
SNDRV_PCM_INFO_PAUSE,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_U16_LE |
|
||||
SNDRV_PCM_FMTBIT_S16_BE |
|
||||
SNDRV_PCM_FMTBIT_U16_BE,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK,
|
||||
.rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK,
|
||||
.channels_min = UX500_PLATFORM_MIN_CHANNELS,
|
||||
.channels_max = UX500_PLATFORM_MAX_CHANNELS,
|
||||
.buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
|
||||
.period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
|
||||
.period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
|
||||
.periods_min = UX500_PLATFORM_PERIODS_MIN,
|
||||
.periods_max = UX500_PLATFORM_PERIODS_MAX,
|
||||
};
|
||||
#define UX500_PLATFORM_MIN_RATE 8000
|
||||
#define UX500_PLATFORM_MAX_RATE 48000
|
||||
|
||||
static struct snd_pcm_hardware ux500_pcm_hw_capture = {
|
||||
#define UX500_PLATFORM_MIN_CHANNELS 1
|
||||
#define UX500_PLATFORM_MAX_CHANNELS 8
|
||||
|
||||
#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
|
||||
#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
|
||||
#define UX500_PLATFORM_PERIODS_MIN 2
|
||||
#define UX500_PLATFORM_PERIODS_MAX 48
|
||||
#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
|
||||
|
||||
static struct snd_pcm_hardware ux500_pcm_hw = {
|
||||
.info = SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
|
@ -59,8 +50,8 @@ static struct snd_pcm_hardware ux500_pcm_hw_capture = {
|
|||
SNDRV_PCM_FMTBIT_S16_BE |
|
||||
SNDRV_PCM_FMTBIT_U16_BE,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE,
|
||||
.rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE,
|
||||
.rate_min = UX500_PLATFORM_MIN_RATE,
|
||||
.rate_max = UX500_PLATFORM_MAX_RATE,
|
||||
.channels_min = UX500_PLATFORM_MIN_CHANNELS,
|
||||
.channels_max = UX500_PLATFORM_MAX_CHANNELS,
|
||||
.buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
|
||||
|
@ -90,8 +81,6 @@ static void ux500_pcm_dma_hw_free(struct device *dev,
|
|||
|
||||
static int ux500_pcm_open(struct snd_pcm_substream *substream)
|
||||
{
|
||||
int stream_id = substream->pstr->stream;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *dai = rtd->cpu_dai;
|
||||
struct device *dev = dai->dev;
|
||||
|
@ -104,26 +93,7 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream)
|
|||
snd_pcm_stream_str(substream));
|
||||
|
||||
dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__);
|
||||
if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
snd_soc_set_runtime_hwparams(substream,
|
||||
&ux500_pcm_hw_playback);
|
||||
else
|
||||
snd_soc_set_runtime_hwparams(substream,
|
||||
&ux500_pcm_hw_capture);
|
||||
|
||||
/* ensure that buffer size is a multiple of period size */
|
||||
ret = snd_pcm_hw_constraint_integer(runtime,
|
||||
SNDRV_PCM_HW_PARAM_PERIODS);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__,
|
||||
snd_pcm_stream_str(substream));
|
||||
runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||
ux500_pcm_hw_playback : ux500_pcm_hw_capture;
|
||||
snd_soc_set_runtime_hwparams(substream, &ux500_pcm_hw);
|
||||
|
||||
mem_data_width = STEDMA40_HALFWORD_WIDTH;
|
||||
|
||||
|
@ -164,20 +134,6 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream)
|
|||
return ret;
|
||||
}
|
||||
|
||||
snd_dmaengine_pcm_set_data(substream, dma_cfg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ux500_pcm_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *dai = rtd->cpu_dai;
|
||||
|
||||
dev_dbg(dai->dev, "%s: Enter\n", __func__);
|
||||
|
||||
snd_dmaengine_pcm_close(substream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -255,7 +211,7 @@ static int ux500_pcm_mmap(struct snd_pcm_substream *substream,
|
|||
|
||||
static struct snd_pcm_ops ux500_pcm_ops = {
|
||||
.open = ux500_pcm_open,
|
||||
.close = ux500_pcm_close,
|
||||
.close = snd_dmaengine_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = ux500_pcm_hw_params,
|
||||
.hw_free = ux500_pcm_hw_free,
|
||||
|
|
|
@ -18,20 +18,6 @@
|
|||
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000
|
||||
#define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000
|
||||
#define UX500_PLATFORM_MIN_RATE_CAPTURE 8000
|
||||
#define UX500_PLATFORM_MAX_RATE_CAPTURE 48000
|
||||
|
||||
#define UX500_PLATFORM_MIN_CHANNELS 1
|
||||
#define UX500_PLATFORM_MAX_CHANNELS 8
|
||||
|
||||
#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
|
||||
#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
|
||||
#define UX500_PLATFORM_PERIODS_MIN 2
|
||||
#define UX500_PLATFORM_PERIODS_MAX 48
|
||||
#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
|
||||
|
||||
int ux500_pcm_register_platform(struct platform_device *pdev);
|
||||
int ux500_pcm_unregister_platform(struct platform_device *pdev);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче