aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sh')
-rw-r--r--sound/soc/sh/fsi.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 23c0e83d4c19..5a2fdf3b84b9 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -146,10 +146,12 @@ struct fsi_priv {
146 void __iomem *base; 146 void __iomem *base;
147 struct fsi_master *master; 147 struct fsi_master *master;
148 148
149 int chan_num;
150 struct fsi_stream playback; 149 struct fsi_stream playback;
151 struct fsi_stream capture; 150 struct fsi_stream capture;
152 151
152 int chan_num:16;
153 int clk_master:1;
154
153 long rate; 155 long rate;
154}; 156};
155 157
@@ -244,6 +246,11 @@ static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
244 return fsi->master; 246 return fsi->master;
245} 247}
246 248
249static int fsi_is_clk_master(struct fsi_priv *fsi)
250{
251 return fsi->clk_master;
252}
253
247static int fsi_is_port_a(struct fsi_priv *fsi) 254static int fsi_is_port_a(struct fsi_priv *fsi)
248{ 255{
249 return fsi->master->base == fsi->base; 256 return fsi->master->base == fsi->base;
@@ -793,14 +800,15 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
793 struct fsi_priv *fsi = fsi_get_priv(substream); 800 struct fsi_priv *fsi = fsi_get_priv(substream);
794 int is_play = fsi_is_play(substream); 801 int is_play = fsi_is_play(substream);
795 struct fsi_master *master = fsi_get_master(fsi); 802 struct fsi_master *master = fsi_get_master(fsi);
796 set_rate_func set_rate; 803 set_rate_func set_rate = fsi_get_info_set_rate(master);
797 804
798 fsi_irq_disable(fsi, is_play); 805 fsi_irq_disable(fsi, is_play);
799 fsi_clk_ctrl(fsi, 0);
800 806
801 set_rate = fsi_get_info_set_rate(master); 807 if (fsi_is_clk_master(fsi)) {
802 if (set_rate && fsi->rate) 808 fsi_clk_ctrl(fsi, 0);
803 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0); 809 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
810 }
811
804 fsi->rate = 0; 812 fsi->rate = 0;
805 813
806 pm_runtime_put_sync(dai->dev); 814 pm_runtime_put_sync(dai->dev);
@@ -876,6 +884,8 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
876static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 884static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
877{ 885{
878 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); 886 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
887 struct fsi_master *master = fsi_get_master(fsi);
888 set_rate_func set_rate = fsi_get_info_set_rate(master);
879 u32 flags = fsi_get_info_flags(fsi); 889 u32 flags = fsi_get_info_flags(fsi);
880 u32 data = 0; 890 u32 data = 0;
881 int ret; 891 int ret;
@@ -886,6 +896,7 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
886 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 896 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
887 case SND_SOC_DAIFMT_CBM_CFM: 897 case SND_SOC_DAIFMT_CBM_CFM:
888 data = DIMD | DOMD; 898 data = DIMD | DOMD;
899 fsi->clk_master = 1;
889 break; 900 break;
890 case SND_SOC_DAIFMT_CBS_CFS: 901 case SND_SOC_DAIFMT_CBS_CFS:
891 break; 902 break;
@@ -893,6 +904,13 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
893 ret = -EINVAL; 904 ret = -EINVAL;
894 goto set_fmt_exit; 905 goto set_fmt_exit;
895 } 906 }
907
908 if (fsi_is_clk_master(fsi) && !set_rate) {
909 dev_err(dai->dev, "platform doesn't have set_rate\n");
910 ret = -EINVAL;
911 goto set_fmt_exit;
912 }
913
896 fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data); 914 fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
897 915
898 /* set format */ 916 /* set format */
@@ -919,13 +937,12 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
919{ 937{
920 struct fsi_priv *fsi = fsi_get_priv(substream); 938 struct fsi_priv *fsi = fsi_get_priv(substream);
921 struct fsi_master *master = fsi_get_master(fsi); 939 struct fsi_master *master = fsi_get_master(fsi);
922 set_rate_func set_rate; 940 set_rate_func set_rate = fsi_get_info_set_rate(master);
923 int fsi_ver = master->core->ver; 941 int fsi_ver = master->core->ver;
924 long rate = params_rate(params); 942 long rate = params_rate(params);
925 int ret; 943 int ret;
926 944
927 set_rate = fsi_get_info_set_rate(master); 945 if (!fsi_is_clk_master(fsi))
928 if (!set_rate)
929 return 0; 946 return 0;
930 947
931 ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1); 948 ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);