summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorKuninori Morimoto <morimoto.kuninori@renesas.com>2009-10-30 12:02:39 +0900
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-10-30 10:35:30 +0000
commit9ddc9aa910687a8787dbbdc53dcd48e738b197d9 (patch)
tree4573c0394bc9d4c568d0bd5c40e2736cf86816a9 /sound
parent67e646cd7b51e1d5847fb506d4419d436ea25fda (diff)
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: Kuninori Morimoto <morimoto.kuninori@renesas.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/sh/Kconfig1
-rw-r--r--sound/soc/sh/fsi.c141
2 files changed, 20 insertions, 122 deletions
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 9154b4363db..9e697658655 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -23,7 +23,6 @@ config SND_SOC_SH4_SSI
config SND_SOC_SH4_FSI
tristate "SH4 FSI support"
depends on CPU_SUBTYPE_SH7724
- select SH_DMA
help
This option enables FSI sound support
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 44123248b63..9742a280ba1 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -26,8 +26,6 @@
#include <sound/pcm_params.h>
#include <sound/sh_fsi.h>
#include <asm/atomic.h>
-#include <asm/dma.h>
-#include <asm/dma-sh.h>
#define DO_FMT 0x0000
#define DOFF_CTL 0x0004
@@ -97,7 +95,6 @@ struct fsi_priv {
int fifo_max;
int chan;
- int dma_chan;
int byte_offset;
int period_len;
@@ -308,62 +305,6 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
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)
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 */
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 fifo_free;
int width;
+ u8 *start;
+ int i;
if (!fsi ||
!fsi->substream ||
@@ -515,12 +420,22 @@ static int fsi_data_push(struct fsi_priv *fsi)
if (fifo_free < send)
send = fifo_free;
- if (2 == width)
- fsi_16data_push(fsi, runtime, send);
- else if (4 == width)
- fsi_32data_push(fsi, runtime, send);
- else
+ start = runtime->dma_area;
+ start += fsi->byte_offset;
+
+ switch (width) {
+ 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;
+ }
fsi->byte_offset += send * width;
@@ -664,8 +579,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
}
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
@@ -780,10 +693,9 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsi_priv *fsi = fsi_get(substream);
- int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
long location;
- location = (fsi->byte_offset - 1) - fsi_get_residue(fsi, is_play);
+ location = (fsi->byte_offset - 1);
if (location < 0)
location = 0;
@@ -912,22 +824,13 @@ static int fsi_probe(struct platform_device *pdev)
master->fsia.base = master->base;
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 */
snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id);
master->clk = clk_get(NULL, clk_name);
if (IS_ERR(master->clk)) {
dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name);
ret = -EIO;
- goto exit_free_dma;
+ goto exit_iounmap;
}
fsi_soc_dai[0].dev = &pdev->dev;
@@ -938,7 +841,7 @@ static int fsi_probe(struct platform_device *pdev)
ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
if (ret) {
dev_err(&pdev->dev, "irq request err\n");
- goto exit_free_dma;
+ goto exit_iounmap;
}
ret = snd_soc_register_platform(&fsi_soc_platform);
@@ -951,8 +854,6 @@ static int fsi_probe(struct platform_device *pdev)
exit_free_irq:
free_irq(irq, master);
-exit_free_dma:
- fsi_free_dma_chan();
exit_iounmap:
iounmap(master->base);
exit_kfree:
@@ -969,8 +870,6 @@ static int fsi_remove(struct platform_device *pdev)
clk_put(master->clk);
- fsi_free_dma_chan();
-
free_irq(master->irq, master);
iounmap(master->base);