Commit 9ddc9aa9 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown

ASoC: sh: FSI: Remove DMA support

SuperH FSI device have the hardware limitation to use DMA.
If DMA is used, LCD output will be broken.
Maybe there are some solution. But I don't know how to do it now.
This patch remove DMA support and use soft transfer.
Signed-off-by: default avatarKuninori Morimoto <morimoto.kuninori@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 67e646cd
...@@ -23,7 +23,6 @@ config SND_SOC_SH4_SSI ...@@ -23,7 +23,6 @@ config SND_SOC_SH4_SSI
config SND_SOC_SH4_FSI config SND_SOC_SH4_FSI
tristate "SH4 FSI support" tristate "SH4 FSI support"
depends on CPU_SUBTYPE_SH7724 depends on CPU_SUBTYPE_SH7724
select SH_DMA
help help
This option enables FSI sound support This option enables FSI sound support
......
...@@ -26,8 +26,6 @@ ...@@ -26,8 +26,6 @@
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/sh_fsi.h> #include <sound/sh_fsi.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/dma.h>
#include <asm/dma-sh.h>
#define DO_FMT 0x0000 #define DO_FMT 0x0000
#define DOFF_CTL 0x0004 #define DOFF_CTL 0x0004
...@@ -97,7 +95,6 @@ struct fsi_priv { ...@@ -97,7 +95,6 @@ struct fsi_priv {
int fifo_max; int fifo_max;
int chan; int chan;
int dma_chan;
int byte_offset; int byte_offset;
int period_len; int period_len;
...@@ -308,62 +305,6 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play) ...@@ -308,62 +305,6 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
return residue; return residue;
} }
static int fsi_get_residue(struct fsi_priv *fsi, int is_play)
{
int residue;
int width;
struct snd_pcm_runtime *runtime;
runtime = fsi->substream->runtime;
/* get 1 channel data width */
width = frames_to_bytes(runtime, 1) / fsi->chan;
if (2 == width)
residue = fsi_get_fifo_residue(fsi, is_play);
else
residue = get_dma_residue(fsi->dma_chan);
return residue;
}
/************************************************************************
basic dma function
************************************************************************/
#define PORTA_DMA 0
#define PORTB_DMA 1
static int fsi_get_dma_chan(void)
{
if (0 != request_dma(PORTA_DMA, "fsia"))
return -EIO;
if (0 != request_dma(PORTB_DMA, "fsib")) {
free_dma(PORTA_DMA);
return -EIO;
}
master->fsia.dma_chan = PORTA_DMA;
master->fsib.dma_chan = PORTB_DMA;
return 0;
}
static void fsi_free_dma_chan(void)
{
dma_wait_for_completion(PORTA_DMA);
dma_wait_for_completion(PORTB_DMA);
free_dma(PORTA_DMA);
free_dma(PORTB_DMA);
master->fsia.dma_chan = -1;
master->fsib.dma_chan = -1;
}
/************************************************************************ /************************************************************************
...@@ -435,44 +376,6 @@ static void fsi_soft_all_reset(void) ...@@ -435,44 +376,6 @@ static void fsi_soft_all_reset(void)
mdelay(10); mdelay(10);
} }
static void fsi_16data_push(struct fsi_priv *fsi,
struct snd_pcm_runtime *runtime,
int send)
{
u16 *dma_start;
u32 snd;
int i;
/* get dma start position for FSI */
dma_start = (u16 *)runtime->dma_area;
dma_start += fsi->byte_offset / 2;
/*
* soft dma
* FSI can not use DMA when 16bpp
*/
for (i = 0; i < send; i++) {
snd = (u32)dma_start[i];
fsi_reg_write(fsi, DODT, snd << 8);
}
}
static void fsi_32data_push(struct fsi_priv *fsi,
struct snd_pcm_runtime *runtime,
int send)
{
u32 *dma_start;
/* get dma start position for FSI */
dma_start = (u32 *)runtime->dma_area;
dma_start += fsi->byte_offset / 4;
dma_wait_for_completion(fsi->dma_chan);
dma_configure_channel(fsi->dma_chan, (SM_INC|0x400|TS_32|TM_BUR));
dma_write(fsi->dma_chan, (u32)dma_start,
(u32)(fsi->base + DODT), send * 4);
}
/* playback interrupt */ /* playback interrupt */
static int fsi_data_push(struct fsi_priv *fsi) static int fsi_data_push(struct fsi_priv *fsi)
{ {
...@@ -481,6 +384,8 @@ static int fsi_data_push(struct fsi_priv *fsi) ...@@ -481,6 +384,8 @@ static int fsi_data_push(struct fsi_priv *fsi)
int send; int send;
int fifo_free; int fifo_free;
int width; int width;
u8 *start;
int i;
if (!fsi || if (!fsi ||
!fsi->substream || !fsi->substream ||
...@@ -515,12 +420,22 @@ static int fsi_data_push(struct fsi_priv *fsi) ...@@ -515,12 +420,22 @@ static int fsi_data_push(struct fsi_priv *fsi)
if (fifo_free < send) if (fifo_free < send)
send = fifo_free; send = fifo_free;
if (2 == width) start = runtime->dma_area;
fsi_16data_push(fsi, runtime, send); start += fsi->byte_offset;
else if (4 == width)
fsi_32data_push(fsi, runtime, send); switch (width) {
else case 2:
for (i = 0; i < send; i++)
fsi_reg_write(fsi, DODT,
((u32)*((u16 *)start + i) << 8));
break;
case 4:
for (i = 0; i < send; i++)
fsi_reg_write(fsi, DODT, *((u32 *)start + i));
break;
default:
return -EINVAL; return -EINVAL;
}
fsi->byte_offset += send * width; fsi->byte_offset += send * width;
...@@ -664,8 +579,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, ...@@ -664,8 +579,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
} }
fsi_reg_write(fsi, reg, data); fsi_reg_write(fsi, reg, data);
dev_dbg(dai->dev, "use %s format (%d channel) use %d DMAC\n",
msg, fsi->chan, fsi->dma_chan);
/* /*
* clear clk reset if master mode * clear clk reset if master mode
...@@ -780,10 +693,9 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) ...@@ -780,10 +693,9 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct fsi_priv *fsi = fsi_get(substream); struct fsi_priv *fsi = fsi_get(substream);
int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
long location; long location;
location = (fsi->byte_offset - 1) - fsi_get_residue(fsi, is_play); location = (fsi->byte_offset - 1);
if (location < 0) if (location < 0)
location = 0; location = 0;
...@@ -912,22 +824,13 @@ static int fsi_probe(struct platform_device *pdev) ...@@ -912,22 +824,13 @@ static int fsi_probe(struct platform_device *pdev)
master->fsia.base = master->base; master->fsia.base = master->base;
master->fsib.base = master->base + 0x40; master->fsib.base = master->base + 0x40;
master->fsia.dma_chan = -1;
master->fsib.dma_chan = -1;
ret = fsi_get_dma_chan();
if (ret < 0) {
dev_err(&pdev->dev, "cannot get dma api\n");
goto exit_iounmap;
}
/* FSI is based on SPU mstp */ /* FSI is based on SPU mstp */
snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id); snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id);
master->clk = clk_get(NULL, clk_name); master->clk = clk_get(NULL, clk_name);
if (IS_ERR(master->clk)) { if (IS_ERR(master->clk)) {
dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name); dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name);
ret = -EIO; ret = -EIO;
goto exit_free_dma; goto exit_iounmap;
} }
fsi_soc_dai[0].dev = &pdev->dev; fsi_soc_dai[0].dev = &pdev->dev;
...@@ -938,7 +841,7 @@ static int fsi_probe(struct platform_device *pdev) ...@@ -938,7 +841,7 @@ static int fsi_probe(struct platform_device *pdev)
ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
if (ret) { if (ret) {
dev_err(&pdev->dev, "irq request err\n"); dev_err(&pdev->dev, "irq request err\n");
goto exit_free_dma; goto exit_iounmap;
} }
ret = snd_soc_register_platform(&fsi_soc_platform); ret = snd_soc_register_platform(&fsi_soc_platform);
...@@ -951,8 +854,6 @@ static int fsi_probe(struct platform_device *pdev) ...@@ -951,8 +854,6 @@ static int fsi_probe(struct platform_device *pdev)
exit_free_irq: exit_free_irq:
free_irq(irq, master); free_irq(irq, master);
exit_free_dma:
fsi_free_dma_chan();
exit_iounmap: exit_iounmap:
iounmap(master->base); iounmap(master->base);
exit_kfree: exit_kfree:
...@@ -969,8 +870,6 @@ static int fsi_remove(struct platform_device *pdev) ...@@ -969,8 +870,6 @@ static int fsi_remove(struct platform_device *pdev)
clk_put(master->clk); clk_put(master->clk);
fsi_free_dma_chan();
free_irq(master->irq, master); free_irq(master->irq, master);
iounmap(master->base); iounmap(master->base);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment