Merge remote-tracking branch 'asoc/topic/pxa' into asoc-next
This commit is contained in:
Коммит
5388d48047
|
@ -0,0 +1,65 @@
|
|||
Device tree bindings for Marvell PXA SSP ports
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Must be one of
|
||||
mrvl,pxa25x-ssp
|
||||
mvrl,pxa25x-nssp
|
||||
mrvl,pxa27x-ssp
|
||||
mrvl,pxa3xx-ssp
|
||||
mvrl,pxa168-ssp
|
||||
mrvl,pxa910-ssp
|
||||
mrvl,ce4100-ssp
|
||||
mrvl,lpss-ssp
|
||||
|
||||
- reg: The memory base
|
||||
- dmas: Two dma phandles, one for rx, one for tx
|
||||
- dma-names: Must be "rx", "tx"
|
||||
|
||||
|
||||
Example for PXA3xx:
|
||||
|
||||
ssp0: ssp@41000000 {
|
||||
compatible = "mrvl,pxa3xx-ssp";
|
||||
reg = <0x41000000 0x40>;
|
||||
ssp-id = <1>;
|
||||
interrupts = <24>;
|
||||
clock-names = "pxa27x-ssp.0";
|
||||
dmas = <&dma 13
|
||||
&dma 14>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
||||
|
||||
ssp1: ssp@41700000 {
|
||||
compatible = "mrvl,pxa3xx-ssp";
|
||||
reg = <0x41700000 0x40>;
|
||||
ssp-id = <2>;
|
||||
interrupts = <16>;
|
||||
clock-names = "pxa27x-ssp.1";
|
||||
dmas = <&dma 15
|
||||
&dma 16>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
||||
|
||||
ssp2: ssp@41900000 {
|
||||
compatibl3 = "mrvl,pxa3xx-ssp";
|
||||
reg = <0x41900000 0x40>;
|
||||
ssp-id = <3>;
|
||||
interrupts = <0>;
|
||||
clock-names = "pxa27x-ssp.2";
|
||||
dmas = <&dma 66
|
||||
&dma 67>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
||||
|
||||
ssp3: ssp@41a00000 {
|
||||
compatible = "mrvl,pxa3xx-ssp";
|
||||
reg = <0x41a00000 0x40>;
|
||||
ssp-id = <4>;
|
||||
interrupts = <13>;
|
||||
clock-names = "pxa27x-ssp.3";
|
||||
dmas = <&dma 2
|
||||
&dma 3>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
Marvell PXA SSP CPU DAI bindings
|
||||
|
||||
Required properties:
|
||||
|
||||
compatible Must be "mrvl,pxa-ssp-dai"
|
||||
port A phandle reference to a PXA ssp upstream device
|
||||
|
||||
Example:
|
||||
|
||||
/* upstream device */
|
||||
|
||||
ssp0: ssp@41000000 {
|
||||
compatible = "mrvl,pxa3xx-ssp";
|
||||
reg = <0x41000000 0x40>;
|
||||
interrupts = <24>;
|
||||
clock-names = "pxa27x-ssp.0";
|
||||
dmas = <&dma 13
|
||||
&dma 14>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
||||
|
||||
/* DAI as user */
|
||||
|
||||
ssp_dai0: ssp_dai@0 {
|
||||
compatible = "mrvl,pxa-ssp-dai";
|
||||
port = <&ssp0>;
|
||||
};
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
DT bindings for ARM PXA2xx PCM platform driver
|
||||
|
||||
This is just a dummy driver that registers the PXA ASoC platform driver.
|
||||
It does not have any resources assigned.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible 'mrvl,pxa-pcm-audio'
|
||||
|
||||
Example:
|
||||
|
||||
pxa_pcm_audio: snd_soc_pxa_audio {
|
||||
compatible = "mrvl,pxa-pcm-audio";
|
||||
};
|
||||
|
|
@ -30,6 +30,8 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/pxa2xx_spi.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <mach/hardware.h>
|
||||
|
@ -60,6 +62,30 @@ struct ssp_device *pxa_ssp_request(int port, const char *label)
|
|||
}
|
||||
EXPORT_SYMBOL(pxa_ssp_request);
|
||||
|
||||
struct ssp_device *pxa_ssp_request_of(const struct device_node *of_node,
|
||||
const char *label)
|
||||
{
|
||||
struct ssp_device *ssp = NULL;
|
||||
|
||||
mutex_lock(&ssp_lock);
|
||||
|
||||
list_for_each_entry(ssp, &ssp_list, node) {
|
||||
if (ssp->of_node == of_node && ssp->use_count == 0) {
|
||||
ssp->use_count++;
|
||||
ssp->label = label;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&ssp_lock);
|
||||
|
||||
if (&ssp->node == &ssp_list)
|
||||
return NULL;
|
||||
|
||||
return ssp;
|
||||
}
|
||||
EXPORT_SYMBOL(pxa_ssp_request_of);
|
||||
|
||||
void pxa_ssp_free(struct ssp_device *ssp)
|
||||
{
|
||||
mutex_lock(&ssp_lock);
|
||||
|
@ -72,96 +98,126 @@ void pxa_ssp_free(struct ssp_device *ssp)
|
|||
}
|
||||
EXPORT_SYMBOL(pxa_ssp_free);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id pxa_ssp_of_ids[] = {
|
||||
{ .compatible = "mrvl,pxa25x-ssp", .data = (void *) PXA25x_SSP },
|
||||
{ .compatible = "mvrl,pxa25x-nssp", .data = (void *) PXA25x_NSSP },
|
||||
{ .compatible = "mrvl,pxa27x-ssp", .data = (void *) PXA27x_SSP },
|
||||
{ .compatible = "mrvl,pxa3xx-ssp", .data = (void *) PXA3xx_SSP },
|
||||
{ .compatible = "mvrl,pxa168-ssp", .data = (void *) PXA168_SSP },
|
||||
{ .compatible = "mrvl,pxa910-ssp", .data = (void *) PXA910_SSP },
|
||||
{ .compatible = "mrvl,ce4100-ssp", .data = (void *) CE4100_SSP },
|
||||
{ .compatible = "mrvl,lpss-ssp", .data = (void *) LPSS_SSP },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pxa_ssp_of_ids);
|
||||
#endif
|
||||
|
||||
static int pxa_ssp_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct platform_device_id *id = platform_get_device_id(pdev);
|
||||
struct resource *res;
|
||||
struct ssp_device *ssp;
|
||||
int ret = 0;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL);
|
||||
if (ssp == NULL) {
|
||||
dev_err(&pdev->dev, "failed to allocate memory");
|
||||
ssp = devm_kzalloc(dev, sizeof(struct ssp_device), GFP_KERNEL);
|
||||
if (ssp == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ssp->pdev = pdev;
|
||||
|
||||
ssp->clk = clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(ssp->clk)) {
|
||||
ret = PTR_ERR(ssp->clk);
|
||||
goto err_free;
|
||||
}
|
||||
ssp->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(ssp->clk))
|
||||
return PTR_ERR(ssp->clk);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "no SSP RX DRCMR defined\n");
|
||||
ret = -ENODEV;
|
||||
goto err_free_clk;
|
||||
}
|
||||
ssp->drcmr_rx = res->start;
|
||||
if (dev->of_node) {
|
||||
struct of_phandle_args dma_spec;
|
||||
struct device_node *np = dev->of_node;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "no SSP TX DRCMR defined\n");
|
||||
ret = -ENODEV;
|
||||
goto err_free_clk;
|
||||
/*
|
||||
* FIXME: we should allocate the DMA channel from this
|
||||
* context and pass the channel down to the ssp users.
|
||||
* For now, we lookup the rx and tx indices manually
|
||||
*/
|
||||
|
||||
/* rx */
|
||||
of_parse_phandle_with_args(np, "dmas", "#dma-cells",
|
||||
0, &dma_spec);
|
||||
ssp->drcmr_rx = dma_spec.args[0];
|
||||
of_node_put(dma_spec.np);
|
||||
|
||||
/* tx */
|
||||
of_parse_phandle_with_args(np, "dmas", "#dma-cells",
|
||||
1, &dma_spec);
|
||||
ssp->drcmr_tx = dma_spec.args[0];
|
||||
of_node_put(dma_spec.np);
|
||||
} else {
|
||||
res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(dev, "no SSP RX DRCMR defined\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
ssp->drcmr_rx = res->start;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
|
||||
if (res == NULL) {
|
||||
dev_err(dev, "no SSP TX DRCMR defined\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
ssp->drcmr_tx = res->start;
|
||||
}
|
||||
ssp->drcmr_tx = res->start;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "no memory resource defined\n");
|
||||
ret = -ENODEV;
|
||||
goto err_free_clk;
|
||||
dev_err(dev, "no memory resource defined\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
res = request_mem_region(res->start, resource_size(res),
|
||||
pdev->name);
|
||||
res = devm_request_mem_region(dev, res->start, resource_size(res),
|
||||
pdev->name);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "failed to request memory resource\n");
|
||||
ret = -EBUSY;
|
||||
goto err_free_clk;
|
||||
dev_err(dev, "failed to request memory resource\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ssp->phys_base = res->start;
|
||||
|
||||
ssp->mmio_base = ioremap(res->start, resource_size(res));
|
||||
ssp->mmio_base = devm_ioremap(dev, res->start, resource_size(res));
|
||||
if (ssp->mmio_base == NULL) {
|
||||
dev_err(&pdev->dev, "failed to ioremap() registers\n");
|
||||
ret = -ENODEV;
|
||||
goto err_free_mem;
|
||||
dev_err(dev, "failed to ioremap() registers\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ssp->irq = platform_get_irq(pdev, 0);
|
||||
if (ssp->irq < 0) {
|
||||
dev_err(&pdev->dev, "no IRQ resource defined\n");
|
||||
ret = -ENODEV;
|
||||
goto err_free_io;
|
||||
dev_err(dev, "no IRQ resource defined\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (dev->of_node) {
|
||||
const struct of_device_id *id =
|
||||
of_match_device(of_match_ptr(pxa_ssp_of_ids), dev);
|
||||
ssp->type = (int) id->data;
|
||||
} else {
|
||||
const struct platform_device_id *id =
|
||||
platform_get_device_id(pdev);
|
||||
ssp->type = (int) id->driver_data;
|
||||
|
||||
/* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id
|
||||
* starts from 0, do a translation here
|
||||
*/
|
||||
ssp->port_id = pdev->id + 1;
|
||||
}
|
||||
|
||||
/* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id
|
||||
* starts from 0, do a translation here
|
||||
*/
|
||||
ssp->port_id = pdev->id + 1;
|
||||
ssp->use_count = 0;
|
||||
ssp->type = (int)id->driver_data;
|
||||
ssp->of_node = dev->of_node;
|
||||
|
||||
mutex_lock(&ssp_lock);
|
||||
list_add(&ssp->node, &ssp_list);
|
||||
mutex_unlock(&ssp_lock);
|
||||
|
||||
platform_set_drvdata(pdev, ssp);
|
||||
return 0;
|
||||
|
||||
err_free_io:
|
||||
iounmap(ssp->mmio_base);
|
||||
err_free_mem:
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
err_free_clk:
|
||||
clk_put(ssp->clk);
|
||||
err_free:
|
||||
kfree(ssp);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pxa_ssp_remove(struct platform_device *pdev)
|
||||
|
@ -201,8 +257,9 @@ static struct platform_driver pxa_ssp_driver = {
|
|||
.probe = pxa_ssp_probe,
|
||||
.remove = pxa_ssp_remove,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pxa2xx-ssp",
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pxa2xx-ssp",
|
||||
.of_match_table = of_match_ptr(pxa_ssp_of_ids),
|
||||
},
|
||||
.id_table = ssp_id_table,
|
||||
};
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include <linux/list.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
|
||||
/*
|
||||
* SSP Serial Port Registers
|
||||
|
@ -190,6 +192,8 @@ struct ssp_device {
|
|||
int irq;
|
||||
int drcmr_rx;
|
||||
int drcmr_tx;
|
||||
|
||||
struct device_node *of_node;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -218,11 +222,18 @@ static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg)
|
|||
#ifdef CONFIG_ARCH_PXA
|
||||
struct ssp_device *pxa_ssp_request(int port, const char *label);
|
||||
void pxa_ssp_free(struct ssp_device *);
|
||||
struct ssp_device *pxa_ssp_request_of(const struct device_node *of_node,
|
||||
const char *label);
|
||||
#else
|
||||
static inline struct ssp_device *pxa_ssp_request(int port, const char *label)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline struct ssp_device *pxa_ssp_request_of(const struct device_node *n,
|
||||
const char *name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline void pxa_ssp_free(struct ssp_device *ssp) {}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -129,6 +129,7 @@ static struct snd_soc_dai_link brownstone_wm8994_dai[] = {
|
|||
/* audio machine driver */
|
||||
static struct snd_soc_card brownstone = {
|
||||
.name = "brownstone",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = brownstone_wm8994_dai,
|
||||
.num_links = ARRAY_SIZE(brownstone_wm8994_dai),
|
||||
|
||||
|
|
|
@ -56,8 +56,6 @@
|
|||
#include "pxa2xx-ac97.h"
|
||||
#include "../codecs/wm9713.h"
|
||||
|
||||
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
|
||||
|
||||
#define AC97_GPIO_PULL 0x58
|
||||
|
||||
/* Use GPIO8 for rear speaker amplifier */
|
||||
|
@ -133,10 +131,11 @@ static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
|
|||
unsigned short reg;
|
||||
|
||||
/* Add mioa701 specific widgets */
|
||||
snd_soc_dapm_new_controls(dapm, ARRAY_AND_SIZE(mioa701_dapm_widgets));
|
||||
snd_soc_dapm_new_controls(dapm, mioa701_dapm_widgets,
|
||||
ARRAY_SIZE(mioa701_dapm_widgets));
|
||||
|
||||
/* Set up mioa701 specific audio path audio_mapnects */
|
||||
snd_soc_dapm_add_routes(dapm, ARRAY_AND_SIZE(audio_map));
|
||||
snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
|
||||
|
||||
/* Prepare GPIO8 for rear speaker amplifier */
|
||||
reg = codec->driver->read(codec, AC97_GPIO_CFG);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/dmaengine.h>
|
||||
#include <linux/platform_data/dma-mmp_tdma.h>
|
||||
#include <linux/platform_data/mmp_audio.h>
|
||||
|
||||
#include <sound/pxa2xx-lib.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
|
@ -67,7 +68,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;
|
||||
|
||||
|
@ -80,10 +81,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,12 +27,15 @@
|
|||
#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"
|
||||
|
||||
/*
|
||||
|
@ -40,7 +43,7 @@
|
|||
*/
|
||||
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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -425,14 +428,12 @@ 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;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->sspa->mmio_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(priv->sspa->mmio_base))
|
||||
return PTR_ERR(priv->sspa->mmio_base);
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pxa2xx_ssp.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/dmaengine.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
|
||||
|
@ -30,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"
|
||||
|
@ -79,27 +81,13 @@ 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->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,
|
||||
|
@ -107,7 +95,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
|
|||
{
|
||||
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) {
|
||||
|
@ -115,10 +103,14 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
|
|||
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);
|
||||
|
||||
dma->filter_data = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
|
||||
&ssp->drcmr_tx : &ssp->drcmr_rx;
|
||||
|
||||
snd_soc_dai_set_dma_data(cpu_dai, substream, dma);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -559,7 +551,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);
|
||||
|
||||
|
@ -719,6 +711,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
|
||||
static int pxa_ssp_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct device *dev = dai->dev;
|
||||
struct ssp_priv *priv;
|
||||
int ret;
|
||||
|
||||
|
@ -726,10 +719,26 @@ static int pxa_ssp_probe(struct snd_soc_dai *dai)
|
|||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
|
||||
if (priv->ssp == NULL) {
|
||||
ret = -ENODEV;
|
||||
goto err_priv;
|
||||
if (dev->of_node) {
|
||||
struct device_node *ssp_handle;
|
||||
|
||||
ssp_handle = of_parse_phandle(dev->of_node, "port", 0);
|
||||
if (!ssp_handle) {
|
||||
dev_err(dev, "unable to get 'port' phandle\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
priv->ssp = pxa_ssp_request_of(ssp_handle, "SoC audio");
|
||||
if (priv->ssp == NULL) {
|
||||
ret = -ENODEV;
|
||||
goto err_priv;
|
||||
}
|
||||
} else {
|
||||
priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
|
||||
if (priv->ssp == NULL) {
|
||||
ret = -ENODEV;
|
||||
goto err_priv;
|
||||
}
|
||||
}
|
||||
|
||||
priv->dai_fmt = (unsigned int) -1;
|
||||
|
@ -798,6 +807,12 @@ static const struct snd_soc_component_driver pxa_ssp_component = {
|
|||
.name = "pxa-ssp",
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id pxa_ssp_of_ids[] = {
|
||||
{ .compatible = "mrvl,pxa-ssp-dai" },
|
||||
};
|
||||
#endif
|
||||
|
||||
static int asoc_ssp_probe(struct platform_device *pdev)
|
||||
{
|
||||
return snd_soc_register_component(&pdev->dev, &pxa_ssp_component,
|
||||
|
@ -812,8 +827,9 @@ static int asoc_ssp_remove(struct platform_device *pdev)
|
|||
|
||||
static struct platform_driver asoc_ssp_driver = {
|
||||
.driver = {
|
||||
.name = "pxa-ssp-dai",
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pxa-ssp-dai",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(pxa_ssp_of_ids),
|
||||
},
|
||||
|
||||
.probe = asoc_ssp_probe,
|
||||
|
|
|
@ -14,15 +14,16 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dmaengine.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/pxa2xx-lib.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/regs-ac97.h>
|
||||
#include <mach/dma.h>
|
||||
#include <mach/audio.h>
|
||||
|
||||
#include "pxa2xx-ac97.h"
|
||||
|
@ -48,44 +49,44 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
|
|||
.reset = pxa2xx_ac97_cold_reset,
|
||||
};
|
||||
|
||||
static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
|
||||
.name = "AC97 PCM Stereo out",
|
||||
.dev_addr = __PREG(PCDR),
|
||||
.drcmr = &DRCMR(12),
|
||||
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
|
||||
DCMD_BURST32 | DCMD_WIDTH4,
|
||||
static unsigned long pxa2xx_ac97_pcm_stereo_in_req = 12;
|
||||
static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = {
|
||||
.addr = __PREG(PCDR),
|
||||
.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
|
||||
.maxburst = 32,
|
||||
.filter_data = &pxa2xx_ac97_pcm_stereo_in_req,
|
||||
};
|
||||
|
||||
static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
|
||||
.name = "AC97 PCM Stereo in",
|
||||
.dev_addr = __PREG(PCDR),
|
||||
.drcmr = &DRCMR(11),
|
||||
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
|
||||
DCMD_BURST32 | DCMD_WIDTH4,
|
||||
static unsigned long pxa2xx_ac97_pcm_stereo_out_req = 11;
|
||||
static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = {
|
||||
.addr = __PREG(PCDR),
|
||||
.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
|
||||
.maxburst = 32,
|
||||
.filter_data = &pxa2xx_ac97_pcm_stereo_out_req,
|
||||
};
|
||||
|
||||
static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
|
||||
.name = "AC97 Aux PCM (Slot 5) Mono out",
|
||||
.dev_addr = __PREG(MODR),
|
||||
.drcmr = &DRCMR(10),
|
||||
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
|
||||
DCMD_BURST16 | DCMD_WIDTH2,
|
||||
static unsigned long pxa2xx_ac97_pcm_aux_mono_out_req = 10;
|
||||
static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = {
|
||||
.addr = __PREG(MODR),
|
||||
.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
|
||||
.maxburst = 16,
|
||||
.filter_data = &pxa2xx_ac97_pcm_aux_mono_out_req,
|
||||
};
|
||||
|
||||
static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
|
||||
.name = "AC97 Aux PCM (Slot 5) Mono in",
|
||||
.dev_addr = __PREG(MODR),
|
||||
.drcmr = &DRCMR(9),
|
||||
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
|
||||
DCMD_BURST16 | DCMD_WIDTH2,
|
||||
static unsigned long pxa2xx_ac97_pcm_aux_mono_in_req = 9;
|
||||
static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = {
|
||||
.addr = __PREG(MODR),
|
||||
.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
|
||||
.maxburst = 16,
|
||||
.filter_data = &pxa2xx_ac97_pcm_aux_mono_in_req,
|
||||
};
|
||||
|
||||
static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
|
||||
.name = "AC97 Mic PCM (Slot 6) Mono in",
|
||||
.dev_addr = __PREG(MCDR),
|
||||
.drcmr = &DRCMR(8),
|
||||
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
|
||||
DCMD_BURST16 | DCMD_WIDTH2,
|
||||
static unsigned long pxa2xx_ac97_pcm_aux_mic_mono_req = 8;
|
||||
static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = {
|
||||
.addr = __PREG(MCDR),
|
||||
.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
|
||||
.maxburst = 16,
|
||||
.filter_data = &pxa2xx_ac97_pcm_aux_mic_mono_req,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -119,7 +120,7 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
struct pxa2xx_pcm_dma_params *dma_data;
|
||||
struct snd_dmaengine_dai_dma_data *dma_data;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
dma_data = &pxa2xx_ac97_pcm_stereo_out;
|
||||
|
@ -135,7 +136,7 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
|
|||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
struct pxa2xx_pcm_dma_params *dma_data;
|
||||
struct snd_dmaengine_dai_dma_data *dma_data;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
#include <sound/initval.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/pxa2xx-lib.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/dma.h>
|
||||
#include <mach/audio.h>
|
||||
|
||||
#include "pxa2xx-i2s.h"
|
||||
|
@ -82,20 +82,20 @@ static struct pxa_i2s_port pxa_i2s;
|
|||
static struct clk *clk_i2s;
|
||||
static int clk_ena = 0;
|
||||
|
||||
static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
|
||||
.name = "I2S PCM Stereo out",
|
||||
.dev_addr = __PREG(SADR),
|
||||
.drcmr = &DRCMR(3),
|
||||
.dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
|
||||
DCMD_BURST32 | DCMD_WIDTH4,
|
||||
static unsigned long pxa2xx_i2s_pcm_stereo_out_req = 3;
|
||||
static struct snd_dmaengine_dai_dma_data pxa2xx_i2s_pcm_stereo_out = {
|
||||
.addr = __PREG(SADR),
|
||||
.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
|
||||
.maxburst = 32,
|
||||
.filter_data = &pxa2xx_i2s_pcm_stereo_out_req,
|
||||
};
|
||||
|
||||
static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = {
|
||||
.name = "I2S PCM Stereo in",
|
||||
.dev_addr = __PREG(SADR),
|
||||
.drcmr = &DRCMR(2),
|
||||
.dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
|
||||
DCMD_BURST32 | DCMD_WIDTH4,
|
||||
static unsigned long pxa2xx_i2s_pcm_stereo_in_req = 2;
|
||||
static struct snd_dmaengine_dai_dma_data pxa2xx_i2s_pcm_stereo_in = {
|
||||
.addr = __PREG(SADR),
|
||||
.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
|
||||
.maxburst = 32,
|
||||
.filter_data = &pxa2xx_i2s_pcm_stereo_in_req,
|
||||
};
|
||||
|
||||
static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
|
||||
|
@ -163,7 +163,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct pxa2xx_pcm_dma_params *dma_data;
|
||||
struct snd_dmaengine_dai_dma_data *dma_data;
|
||||
|
||||
BUG_ON(IS_ERR(clk_i2s));
|
||||
clk_prepare_enable(clk_i2s);
|
||||
|
|
|
@ -12,10 +12,13 @@
|
|||
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/pxa2xx-lib.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "../../arm/pxa2xx-pcm.h"
|
||||
|
||||
|
@ -25,7 +28,7 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct pxa2xx_runtime_data *prtd = runtime->private_data;
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct pxa2xx_pcm_dma_params *dma;
|
||||
struct snd_dmaengine_dai_dma_data *dma;
|
||||
int ret;
|
||||
|
||||
dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
|
@ -39,7 +42,7 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
* with different params */
|
||||
if (prtd->params == NULL) {
|
||||
prtd->params = dma;
|
||||
ret = pxa_request_dma(prtd->params->name, DMA_PRIO_LOW,
|
||||
ret = pxa_request_dma("name", DMA_PRIO_LOW,
|
||||
pxa2xx_pcm_dma_irq, substream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -47,7 +50,7 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
} else if (prtd->params != dma) {
|
||||
pxa_free_dma(prtd->dma_ch);
|
||||
prtd->params = dma;
|
||||
ret = pxa_request_dma(prtd->params->name, DMA_PRIO_LOW,
|
||||
ret = pxa_request_dma("name", DMA_PRIO_LOW,
|
||||
pxa2xx_pcm_dma_irq, substream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -131,10 +134,18 @@ static int pxa2xx_soc_platform_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id snd_soc_pxa_audio_match[] = {
|
||||
{ .compatible = "mrvl,pxa-pcm-audio" },
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct platform_driver pxa_pcm_driver = {
|
||||
.driver = {
|
||||
.name = "pxa-pcm-audio",
|
||||
.owner = THIS_MODULE,
|
||||
.name = "pxa-pcm-audio",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(snd_soc_pxa_audio_match),
|
||||
},
|
||||
|
||||
.probe = pxa2xx_soc_platform_probe,
|
||||
|
|
|
@ -122,6 +122,7 @@ static struct snd_soc_dai_link ttc_pm860x_hifi_dai[] = {
|
|||
/* ttc/td audio machine driver */
|
||||
static struct snd_soc_card ttc_dkb_card = {
|
||||
.name = "ttc-dkb-hifi",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = ttc_pm860x_hifi_dai,
|
||||
.num_links = ARRAY_SIZE(ttc_pm860x_hifi_dai),
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче