diff options
Diffstat (limited to 'sound/soc/pxa/pxa-ssp.c')
-rw-r--r-- | sound/soc/pxa/pxa-ssp.c | 76 |
1 files changed, 46 insertions, 30 deletions
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 6f4dd7543e82..a3119a00d8fa 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -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, |