diff options
author | Kuninori Morimoto <morimoto.kuninori@renesas.com> | 2010-03-25 06:15:51 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-03-26 07:16:27 -0400 |
commit | 4a942b457ee239eab04db8dd4d4c12ef6dc4a152 (patch) | |
tree | 283876fa1c5177c8f0533c9baa094ff6e15b3f31 /sound/soc/sh/fsi.c | |
parent | 10ea76cc25b6738eb2f7c58b3312e1ebc61f753e (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.c | 70 |
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 | ||
387 | static void fsi_fifo_init(struct fsi_priv *fsi, int is_play) | 393 | static 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 | } |