aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/fsi.c
diff options
context:
space:
mode:
authorKuninori Morimoto <morimoto.kuninori@renesas.com>2010-03-25 06:15:51 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-03-26 07:16:27 -0400
commit4a942b457ee239eab04db8dd4d4c12ef6dc4a152 (patch)
tree283876fa1c5177c8f0533c9baa094ff6e15b3f31 /sound/soc/sh/fsi.c
parent10ea76cc25b6738eb2f7c58b3312e1ebc61f753e (diff)
ASoC: fsi: Add FIFO size calculate
Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/sh/fsi.c')
-rw-r--r--sound/soc/sh/fsi.c70
1 files changed, 43 insertions, 27 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 7c295df6e855..ae888651a77a 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -46,8 +46,9 @@
46#define MUTE 0x020C 46#define MUTE 0x020C
47#define CLK_RST 0x0210 47#define CLK_RST 0x0210
48#define SOFT_RST 0x0214 48#define SOFT_RST 0x0214
49#define FIFO_SZ 0x0218
49#define MREG_START INT_ST 50#define MREG_START INT_ST
50#define MREG_END SOFT_RST 51#define MREG_END FIFO_SZ
51 52
52/* DO_FMT */ 53/* DO_FMT */
53/* DI_FMT */ 54/* DI_FMT */
@@ -85,6 +86,11 @@
85#define IR (1 << 4) /* Interrupt Reset */ 86#define IR (1 << 4) /* Interrupt Reset */
86#define FSISR (1 << 0) /* Software Reset */ 87#define FSISR (1 << 0) /* Software Reset */
87 88
89/* FIFO_SZ */
90#define OUT_SZ_MASK 0x7
91#define BO_SZ_SHIFT 8
92#define AO_SZ_SHIFT 0
93
88#define FSI_RATES SNDRV_PCM_RATE_8000_96000 94#define FSI_RATES SNDRV_PCM_RATE_8000_96000
89 95
90#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 96#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
@@ -384,9 +390,42 @@ static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
384 fsi_master_mask_set(master, CLK_RST, val, 0); 390 fsi_master_mask_set(master, CLK_RST, val, 0);
385} 391}
386 392
387static void fsi_fifo_init(struct fsi_priv *fsi, int is_play) 393static void fsi_fifo_init(struct fsi_priv *fsi,
394 int is_play,
395 struct snd_soc_dai *dai)
388{ 396{
389 u32 ctrl; 397 struct fsi_master *master = fsi_get_master(fsi);
398 u32 ctrl, shift, i;
399
400 /* get on-chip RAM capacity */
401 shift = fsi_master_read(master, FIFO_SZ);
402 shift >>= fsi_is_port_a(fsi) ? AO_SZ_SHIFT : BO_SZ_SHIFT;
403 shift &= OUT_SZ_MASK;
404 fsi->fifo_max = 256 << shift;
405 dev_dbg(dai->dev, "fifo = %d words\n", fsi->fifo_max);
406
407 /*
408 * The maximum number of sample data varies depending
409 * on the number of channels selected for the format.
410 *
411 * FIFOs are used in 4-channel units in 3-channel mode
412 * and in 8-channel units in 5- to 7-channel mode
413 * meaning that more FIFOs than the required size of DPRAM
414 * are used.
415 *
416 * ex) if 256 words of DP-RAM is connected
417 * 1 channel: 256 (256 x 1 = 256)
418 * 2 channels: 128 (128 x 2 = 256)
419 * 3 channels: 64 ( 64 x 3 = 192)
420 * 4 channels: 64 ( 64 x 4 = 256)
421 * 5 channels: 32 ( 32 x 5 = 160)
422 * 6 channels: 32 ( 32 x 6 = 192)
423 * 7 channels: 32 ( 32 x 7 = 224)
424 * 8 channels: 32 ( 32 x 8 = 256)
425 */
426 for (i = 1; i < fsi->chan; i <<= 1)
427 fsi->fifo_max >>= 1;
428 dev_dbg(dai->dev, "%d channel %d store\n", fsi->chan, fsi->fifo_max);
390 429
391 ctrl = is_play ? DOFF_CTL : DIFF_CTL; 430 ctrl = is_play ? DOFF_CTL : DIFF_CTL;
392 431
@@ -689,29 +728,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
689 dev_err(dai->dev, "unknown format.\n"); 728 dev_err(dai->dev, "unknown format.\n");
690 return -EINVAL; 729 return -EINVAL;
691 } 730 }
692
693 switch (fsi->chan) {
694 case 1:
695 fsi->fifo_max = 256;
696 break;
697 case 2:
698 fsi->fifo_max = 128;
699 break;
700 case 3:
701 case 4:
702 fsi->fifo_max = 64;
703 break;
704 case 5:
705 case 6:
706 case 7:
707 case 8:
708 fsi->fifo_max = 32;
709 break;
710 default:
711 dev_err(dai->dev, "channel size error.\n");
712 return -EINVAL;
713 }
714
715 fsi_reg_write(fsi, reg, data); 731 fsi_reg_write(fsi, reg, data);
716 732
717 /* 733 /*
@@ -725,7 +741,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
725 fsi_irq_clear_status(fsi); 741 fsi_irq_clear_status(fsi);
726 742
727 /* fifo init */ 743 /* fifo init */
728 fsi_fifo_init(fsi, is_play); 744 fsi_fifo_init(fsi, is_play, dai);
729 745
730 return ret; 746 return ret;
731} 747}