diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-05-23 07:46:07 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-05-24 06:41:48 -0400 |
commit | 9478e0b60fb4a7adde72d4a86b826d396b607a61 (patch) | |
tree | 7b6175dd669a871ce6bf622d653e987df6a918b3 /sound | |
parent | 2e651bafa959c6e2620601c2c2e9b7c26f6a9c1a (diff) |
ASoC: sh: fsi: remove pm_runtime from fsi_dai_set_fmt.
pm_runtime_get/put_sync were used to access FSI register in fsi_dai_set_fmt
which is called when ALSA probe.
But this register value will disappear after pm_runtime_put_sync
if platform is supporting RuntimePM.
To solve this issue, this patch adds new variable for format,
and remove pm_runtime_get/put_sync from fsi_dai_set_fmt.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Acked-by: Liam Girdwood <lrg@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/sh/fsi.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index fec1a7dcf90b..a1081c755239 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -176,8 +176,12 @@ struct fsi_priv { | |||
176 | struct fsi_stream playback; | 176 | struct fsi_stream playback; |
177 | struct fsi_stream capture; | 177 | struct fsi_stream capture; |
178 | 178 | ||
179 | u32 do_fmt; | ||
180 | u32 di_fmt; | ||
181 | |||
179 | int chan_num:16; | 182 | int chan_num:16; |
180 | int clk_master:1; | 183 | int clk_master:1; |
184 | int spdif:1; | ||
181 | 185 | ||
182 | long rate; | 186 | long rate; |
183 | 187 | ||
@@ -298,6 +302,11 @@ static int fsi_is_port_a(struct fsi_priv *fsi) | |||
298 | return fsi->master->base == fsi->base; | 302 | return fsi->master->base == fsi->base; |
299 | } | 303 | } |
300 | 304 | ||
305 | static int fsi_is_spdif(struct fsi_priv *fsi) | ||
306 | { | ||
307 | return fsi->spdif; | ||
308 | } | ||
309 | |||
301 | static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream) | 310 | static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream) |
302 | { | 311 | { |
303 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 312 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
@@ -893,11 +902,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
893 | { | 902 | { |
894 | struct fsi_priv *fsi = fsi_get_priv(substream); | 903 | struct fsi_priv *fsi = fsi_get_priv(substream); |
895 | u32 flags = fsi_get_info_flags(fsi); | 904 | u32 flags = fsi_get_info_flags(fsi); |
896 | u32 data; | 905 | u32 data = 0; |
897 | int is_play = fsi_is_play(substream); | 906 | int is_play = fsi_is_play(substream); |
898 | 907 | ||
899 | pm_runtime_get_sync(dai->dev); | 908 | pm_runtime_get_sync(dai->dev); |
900 | 909 | ||
910 | /* clock setting */ | ||
911 | if (fsi_is_clk_master(fsi)) | ||
912 | data = DIMD | DOMD; | ||
913 | |||
914 | fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data); | ||
901 | 915 | ||
902 | /* clock inversion (CKG2) */ | 916 | /* clock inversion (CKG2) */ |
903 | data = 0; | 917 | data = 0; |
@@ -912,6 +926,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
912 | 926 | ||
913 | fsi_reg_write(fsi, CKG2, data); | 927 | fsi_reg_write(fsi, CKG2, data); |
914 | 928 | ||
929 | /* set format */ | ||
930 | fsi_reg_write(fsi, DO_FMT, fsi->do_fmt); | ||
931 | fsi_reg_write(fsi, DI_FMT, fsi->di_fmt); | ||
932 | |||
933 | /* spdif ? */ | ||
934 | if (fsi_is_spdif(fsi)) { | ||
935 | fsi_spdif_clk_ctrl(fsi, 1); | ||
936 | fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD); | ||
937 | } | ||
938 | |||
915 | /* irq clear */ | 939 | /* irq clear */ |
916 | fsi_irq_disable(fsi, is_play); | 940 | fsi_irq_disable(fsi, is_play); |
917 | fsi_irq_clear_status(fsi); | 941 | fsi_irq_clear_status(fsi); |
@@ -974,8 +998,8 @@ static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt) | |||
974 | return -EINVAL; | 998 | return -EINVAL; |
975 | } | 999 | } |
976 | 1000 | ||
977 | fsi_reg_write(fsi, DO_FMT, data); | 1001 | fsi->do_fmt = data; |
978 | fsi_reg_write(fsi, DI_FMT, data); | 1002 | fsi->di_fmt = data; |
979 | 1003 | ||
980 | return 0; | 1004 | return 0; |
981 | } | 1005 | } |
@@ -990,11 +1014,10 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi) | |||
990 | 1014 | ||
991 | data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; | 1015 | data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; |
992 | fsi->chan_num = 2; | 1016 | fsi->chan_num = 2; |
993 | fsi_spdif_clk_ctrl(fsi, 1); | 1017 | fsi->spdif = 1; |
994 | fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD); | ||
995 | 1018 | ||
996 | fsi_reg_write(fsi, DO_FMT, data); | 1019 | fsi->do_fmt = data; |
997 | fsi_reg_write(fsi, DI_FMT, data); | 1020 | fsi->di_fmt = data; |
998 | 1021 | ||
999 | return 0; | 1022 | return 0; |
1000 | } | 1023 | } |
@@ -1005,32 +1028,24 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
1005 | struct fsi_master *master = fsi_get_master(fsi); | 1028 | struct fsi_master *master = fsi_get_master(fsi); |
1006 | set_rate_func set_rate = fsi_get_info_set_rate(master); | 1029 | set_rate_func set_rate = fsi_get_info_set_rate(master); |
1007 | u32 flags = fsi_get_info_flags(fsi); | 1030 | u32 flags = fsi_get_info_flags(fsi); |
1008 | u32 data = 0; | ||
1009 | int ret; | 1031 | int ret; |
1010 | 1032 | ||
1011 | pm_runtime_get_sync(dai->dev); | ||
1012 | |||
1013 | /* set master/slave audio interface */ | 1033 | /* set master/slave audio interface */ |
1014 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 1034 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
1015 | case SND_SOC_DAIFMT_CBM_CFM: | 1035 | case SND_SOC_DAIFMT_CBM_CFM: |
1016 | data = DIMD | DOMD; | ||
1017 | fsi->clk_master = 1; | 1036 | fsi->clk_master = 1; |
1018 | break; | 1037 | break; |
1019 | case SND_SOC_DAIFMT_CBS_CFS: | 1038 | case SND_SOC_DAIFMT_CBS_CFS: |
1020 | break; | 1039 | break; |
1021 | default: | 1040 | default: |
1022 | ret = -EINVAL; | 1041 | return -EINVAL; |
1023 | goto set_fmt_exit; | ||
1024 | } | 1042 | } |
1025 | 1043 | ||
1026 | if (fsi_is_clk_master(fsi) && !set_rate) { | 1044 | if (fsi_is_clk_master(fsi) && !set_rate) { |
1027 | dev_err(dai->dev, "platform doesn't have set_rate\n"); | 1045 | dev_err(dai->dev, "platform doesn't have set_rate\n"); |
1028 | ret = -EINVAL; | 1046 | return -EINVAL; |
1029 | goto set_fmt_exit; | ||
1030 | } | 1047 | } |
1031 | 1048 | ||
1032 | fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data); | ||
1033 | |||
1034 | /* set format */ | 1049 | /* set format */ |
1035 | switch (flags & SH_FSI_FMT_MASK) { | 1050 | switch (flags & SH_FSI_FMT_MASK) { |
1036 | case SH_FSI_FMT_DAI: | 1051 | case SH_FSI_FMT_DAI: |
@@ -1043,9 +1058,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
1043 | ret = -EINVAL; | 1058 | ret = -EINVAL; |
1044 | } | 1059 | } |
1045 | 1060 | ||
1046 | set_fmt_exit: | ||
1047 | pm_runtime_put_sync(dai->dev); | ||
1048 | |||
1049 | return ret; | 1061 | return ret; |
1050 | } | 1062 | } |
1051 | 1063 | ||