aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2010-07-12 23:13:14 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-07-13 07:35:39 -0400
commitccad7b44ccdc8341c1449bc5b864b42b197f8c2e (patch)
tree108725d49aaafe94b2b2be94e29b96d36b7ae637 /sound
parentd78541473d6c6126616bca2552282660faa41d43 (diff)
ASoC: fsi: Fixup for master mode
This patch add hw_params to snd_soc_dai_ops, because board specific set_rate is needed when FSI was used as master mode. This patch remove fsi_clk_ctrl from fsi_dai_startup, because clock should be disabled before set_rate. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/sh/fsi.c98
1 files changed, 92 insertions, 6 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index e551ca45f03e..a1ce6089177c 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -65,6 +65,10 @@
65#define ERR_UNDER 0x00000001 65#define ERR_UNDER 0x00000001
66#define ST_ERR (ERR_OVER | ERR_UNDER) 66#define ST_ERR (ERR_OVER | ERR_UNDER)
67 67
68/* CKG1 */
69#define ACKMD_MASK 0x00007000
70#define BPFMD_MASK 0x00000700
71
68/* CLK_RST */ 72/* CLK_RST */
69#define B_CLK 0x00000010 73#define B_CLK 0x00000010
70#define A_CLK 0x00000001 74#define A_CLK 0x00000001
@@ -734,12 +738,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
734 } 738 }
735 fsi_reg_write(fsi, reg, data); 739 fsi_reg_write(fsi, reg, data);
736 740
737 /*
738 * clear clk reset if master mode
739 */
740 if (is_master)
741 fsi_clk_ctrl(fsi, 1);
742
743 /* irq clear */ 741 /* irq clear */
744 fsi_irq_disable(fsi, is_play); 742 fsi_irq_disable(fsi, is_play);
745 fsi_irq_clear_status(fsi); 743 fsi_irq_clear_status(fsi);
@@ -786,10 +784,98 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
786 return ret; 784 return ret;
787} 785}
788 786
787static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
788 struct snd_pcm_hw_params *params,
789 struct snd_soc_dai *dai)
790{
791 struct fsi_priv *fsi = fsi_get_priv(substream);
792 struct fsi_master *master = fsi_get_master(fsi);
793 int (*set_rate)(int is_porta, int rate) = master->info->set_rate;
794 int fsi_ver = master->core->ver;
795 int is_play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
796 int ret;
797
798 /* if slave mode, set_rate is not needed */
799 if (!fsi_is_master_mode(fsi, is_play))
800 return 0;
801
802 /* it is error if no set_rate */
803 if (!set_rate)
804 return -EIO;
805
806 /* clock stop */
807 pm_runtime_put_sync(dai->dev);
808 fsi_clk_ctrl(fsi, 0);
809
810 ret = set_rate(fsi_is_port_a(fsi), params_rate(params));
811 if (ret > 0) {
812 u32 data = 0;
813
814 switch (ret & SH_FSI_ACKMD_MASK) {
815 default:
816 /* FALL THROUGH */
817 case SH_FSI_ACKMD_512:
818 data |= (0x0 << 12);
819 break;
820 case SH_FSI_ACKMD_256:
821 data |= (0x1 << 12);
822 break;
823 case SH_FSI_ACKMD_128:
824 data |= (0x2 << 12);
825 break;
826 case SH_FSI_ACKMD_64:
827 data |= (0x3 << 12);
828 break;
829 case SH_FSI_ACKMD_32:
830 if (fsi_ver < 2)
831 dev_err(dai->dev, "unsupported ACKMD\n");
832 else
833 data |= (0x4 << 12);
834 break;
835 }
836
837 switch (ret & SH_FSI_BPFMD_MASK) {
838 default:
839 /* FALL THROUGH */
840 case SH_FSI_BPFMD_32:
841 data |= (0x0 << 8);
842 break;
843 case SH_FSI_BPFMD_64:
844 data |= (0x1 << 8);
845 break;
846 case SH_FSI_BPFMD_128:
847 data |= (0x2 << 8);
848 break;
849 case SH_FSI_BPFMD_256:
850 data |= (0x3 << 8);
851 break;
852 case SH_FSI_BPFMD_512:
853 data |= (0x4 << 8);
854 break;
855 case SH_FSI_BPFMD_16:
856 if (fsi_ver < 2)
857 dev_err(dai->dev, "unsupported ACKMD\n");
858 else
859 data |= (0x7 << 8);
860 break;
861 }
862
863 fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
864 udelay(10);
865 fsi_clk_ctrl(fsi, 1);
866 ret = 0;
867 }
868 pm_runtime_get_sync(dai->dev);
869
870 return ret;
871
872}
873
789static struct snd_soc_dai_ops fsi_dai_ops = { 874static struct snd_soc_dai_ops fsi_dai_ops = {
790 .startup = fsi_dai_startup, 875 .startup = fsi_dai_startup,
791 .shutdown = fsi_dai_shutdown, 876 .shutdown = fsi_dai_shutdown,
792 .trigger = fsi_dai_trigger, 877 .trigger = fsi_dai_trigger,
878 .hw_params = fsi_dai_hw_params,
793}; 879};
794 880
795/************************************************************************ 881/************************************************************************