aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/fsi.c
diff options
context:
space:
mode:
authorKuninori Morimoto <morimoto.kuninori@renesas.com>2009-10-29 23:02:39 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-10-30 06:35:30 -0400
commit9ddc9aa910687a8787dbbdc53dcd48e738b197d9 (patch)
tree4573c0394bc9d4c568d0bd5c40e2736cf86816a9 /sound/soc/sh/fsi.c
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/soc/sh/fsi.c')
-rw-r--r--sound/soc/sh/fsi.c141
1 files changed, 20 insertions, 121 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 44123248b630..9742a280ba15 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -26,8 +26,6 @@
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/sh_fsi.h> 27#include <sound/sh_fsi.h>
28#include <asm/atomic.h> 28#include <asm/atomic.h>
29#include <asm/dma.h>
30#include <asm/dma-sh.h>
31 29
32#define DO_FMT 0x0000 30#define DO_FMT 0x0000
33#define DOFF_CTL 0x0004 31#define DOFF_CTL 0x0004
@@ -97,7 +95,6 @@ struct fsi_priv {
97 95
98 int fifo_max; 96 int fifo_max;
99 int chan; 97 int chan;
100 int dma_chan;
101 98
102 int byte_offset; 99 int byte_offset;
103 int period_len; 100 int period_len;
@@ -308,62 +305,6 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
308 return residue; 305 return residue;
309} 306}
310 307
311static int fsi_get_residue(struct fsi_priv *fsi, int is_play)
312{
313 int residue;
314 int width;
315 struct snd_pcm_runtime *runtime;
316
317 runtime = fsi->substream->runtime;
318
319 /* get 1 channel data width */
320 width = frames_to_bytes(runtime, 1) / fsi->chan;
321
322 if (2 == width)
323 residue = fsi_get_fifo_residue(fsi, is_play);
324 else
325 residue = get_dma_residue(fsi->dma_chan);
326
327 return residue;
328}
329
330/************************************************************************
331
332
333 basic dma function
334
335
336************************************************************************/
337#define PORTA_DMA 0
338#define PORTB_DMA 1
339
340static int fsi_get_dma_chan(void)
341{
342 if (0 != request_dma(PORTA_DMA, "fsia"))
343 return -EIO;
344
345 if (0 != request_dma(PORTB_DMA, "fsib")) {
346 free_dma(PORTA_DMA);
347 return -EIO;
348 }
349
350 master->fsia.dma_chan = PORTA_DMA;
351 master->fsib.dma_chan = PORTB_DMA;
352
353 return 0;
354}
355
356static void fsi_free_dma_chan(void)
357{
358 dma_wait_for_completion(PORTA_DMA);
359 dma_wait_for_completion(PORTB_DMA);
360 free_dma(PORTA_DMA);
361 free_dma(PORTB_DMA);
362
363 master->fsia.dma_chan = -1;
364 master->fsib.dma_chan = -1;
365}
366
367/************************************************************************ 308/************************************************************************
368 309
369 310
@@ -435,44 +376,6 @@ static void fsi_soft_all_reset(void)
435 mdelay(10); 376 mdelay(10);
436} 377}
437 378
438static void fsi_16data_push(struct fsi_priv *fsi,
439 struct snd_pcm_runtime *runtime,
440 int send)
441{
442 u16 *dma_start;
443 u32 snd;
444 int i;
445
446 /* get dma start position for FSI */
447 dma_start = (u16 *)runtime->dma_area;
448 dma_start += fsi->byte_offset / 2;
449
450 /*
451 * soft dma
452 * FSI can not use DMA when 16bpp
453 */
454 for (i = 0; i < send; i++) {
455 snd = (u32)dma_start[i];
456 fsi_reg_write(fsi, DODT, snd << 8);
457 }
458}
459
460static void fsi_32data_push(struct fsi_priv *fsi,
461 struct snd_pcm_runtime *runtime,
462 int send)
463{
464 u32 *dma_start;
465
466 /* get dma start position for FSI */
467 dma_start = (u32 *)runtime->dma_area;
468 dma_start += fsi->byte_offset / 4;
469
470 dma_wait_for_completion(fsi->dma_chan);
471 dma_configure_channel(fsi->dma_chan, (SM_INC|0x400|TS_32|TM_BUR));
472 dma_write(fsi->dma_chan, (u32)dma_start,
473 (u32)(fsi->base + DODT), send * 4);
474}
475
476/* playback interrupt */ 379/* playback interrupt */
477static int fsi_data_push(struct fsi_priv *fsi) 380static int fsi_data_push(struct fsi_priv *fsi)
478{ 381{
@@ -481,6 +384,8 @@ static int fsi_data_push(struct fsi_priv *fsi)
481 int send; 384 int send;
482 int fifo_free; 385 int fifo_free;
483 int width; 386 int width;
387 u8 *start;
388 int i;
484 389
485 if (!fsi || 390 if (!fsi ||
486 !fsi->substream || 391 !fsi->substream ||
@@ -515,12 +420,22 @@ static int fsi_data_push(struct fsi_priv *fsi)
515 if (fifo_free < send) 420 if (fifo_free < send)
516 send = fifo_free; 421 send = fifo_free;
517 422
518 if (2 == width) 423 start = runtime->dma_area;
519 fsi_16data_push(fsi, runtime, send); 424 start += fsi->byte_offset;
520 else if (4 == width) 425
521 fsi_32data_push(fsi, runtime, send); 426 switch (width) {
522 else 427 case 2:
428 for (i = 0; i < send; i++)
429 fsi_reg_write(fsi, DODT,
430 ((u32)*((u16 *)start + i) << 8));
431 break;
432 case 4:
433 for (i = 0; i < send; i++)
434 fsi_reg_write(fsi, DODT, *((u32 *)start + i));
435 break;
436 default:
523 return -EINVAL; 437 return -EINVAL;
438 }
524 439
525 fsi->byte_offset += send * width; 440 fsi->byte_offset += send * width;
526 441
@@ -664,8 +579,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
664 } 579 }
665 580
666 fsi_reg_write(fsi, reg, data); 581 fsi_reg_write(fsi, reg, data);
667 dev_dbg(dai->dev, "use %s format (%d channel) use %d DMAC\n",
668 msg, fsi->chan, fsi->dma_chan);
669 582
670 /* 583 /*
671 * clear clk reset if master mode 584 * clear clk reset if master mode
@@ -780,10 +693,9 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
780{ 693{
781 struct snd_pcm_runtime *runtime = substream->runtime; 694 struct snd_pcm_runtime *runtime = substream->runtime;
782 struct fsi_priv *fsi = fsi_get(substream); 695 struct fsi_priv *fsi = fsi_get(substream);
783 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
784 long location; 696 long location;
785 697
786 location = (fsi->byte_offset - 1) - fsi_get_residue(fsi, is_play); 698 location = (fsi->byte_offset - 1);
787 if (location < 0) 699 if (location < 0)
788 location = 0; 700 location = 0;
789 701
@@ -912,22 +824,13 @@ static int fsi_probe(struct platform_device *pdev)
912 master->fsia.base = master->base; 824 master->fsia.base = master->base;
913 master->fsib.base = master->base + 0x40; 825 master->fsib.base = master->base + 0x40;
914 826
915 master->fsia.dma_chan = -1;
916 master->fsib.dma_chan = -1;
917
918 ret = fsi_get_dma_chan();
919 if (ret < 0) {
920 dev_err(&pdev->dev, "cannot get dma api\n");
921 goto exit_iounmap;
922 }
923
924 /* FSI is based on SPU mstp */ 827 /* FSI is based on SPU mstp */
925 snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id); 828 snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id);
926 master->clk = clk_get(NULL, clk_name); 829 master->clk = clk_get(NULL, clk_name);
927 if (IS_ERR(master->clk)) { 830 if (IS_ERR(master->clk)) {
928 dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name); 831 dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name);
929 ret = -EIO; 832 ret = -EIO;
930 goto exit_free_dma; 833 goto exit_iounmap;
931 } 834 }
932 835
933 fsi_soc_dai[0].dev = &pdev->dev; 836 fsi_soc_dai[0].dev = &pdev->dev;
@@ -938,7 +841,7 @@ static int fsi_probe(struct platform_device *pdev)
938 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 841 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
939 if (ret) { 842 if (ret) {
940 dev_err(&pdev->dev, "irq request err\n"); 843 dev_err(&pdev->dev, "irq request err\n");
941 goto exit_free_dma; 844 goto exit_iounmap;
942 } 845 }
943 846
944 ret = snd_soc_register_platform(&fsi_soc_platform); 847 ret = snd_soc_register_platform(&fsi_soc_platform);
@@ -951,8 +854,6 @@ static int fsi_probe(struct platform_device *pdev)
951 854
952exit_free_irq: 855exit_free_irq:
953 free_irq(irq, master); 856 free_irq(irq, master);
954exit_free_dma:
955 fsi_free_dma_chan();
956exit_iounmap: 857exit_iounmap:
957 iounmap(master->base); 858 iounmap(master->base);
958exit_kfree: 859exit_kfree:
@@ -969,8 +870,6 @@ static int fsi_remove(struct platform_device *pdev)
969 870
970 clk_put(master->clk); 871 clk_put(master->clk);
971 872
972 fsi_free_dma_chan();
973
974 free_irq(master->irq, master); 873 free_irq(master->irq, master);
975 874
976 iounmap(master->base); 875 iounmap(master->base);