summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-04-21 10:33:36 +0900
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-04-26 11:40:55 +0100
commit6a9ebad8214bba404255d1b209a038dc739c37b7 (patch)
treefa1358f9056069933a1ead5ee5551c1c34b716ab /sound
parent5debd6c14c302614764d7fcc8fe958c310c3d3b7 (diff)
ASoC: sh: fsi: add fsi_is_clk_master function
If FSI port is clock master, it use set_rate function which is callback from platform, and it is not necessary to call it if FSI port is clock slave. Current FSI driver called this callback if platform provide it. This patch modify it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Reviewed-by: Simon Horman <simon@horms.net> 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.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 23c0e83d4c1..5a2fdf3b84b 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -146,10 +146,12 @@ struct fsi_priv {
void __iomem *base;
struct fsi_master *master;
- int chan_num;
struct fsi_stream playback;
struct fsi_stream capture;
+ int chan_num:16;
+ int clk_master:1;
+
long rate;
};
@@ -244,6 +246,11 @@ static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
return fsi->master;
}
+static int fsi_is_clk_master(struct fsi_priv *fsi)
+{
+ return fsi->clk_master;
+}
+
static int fsi_is_port_a(struct fsi_priv *fsi)
{
return fsi->master->base == fsi->base;
@@ -793,14 +800,15 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
struct fsi_priv *fsi = fsi_get_priv(substream);
int is_play = fsi_is_play(substream);
struct fsi_master *master = fsi_get_master(fsi);
- set_rate_func set_rate;
+ set_rate_func set_rate = fsi_get_info_set_rate(master);
fsi_irq_disable(fsi, is_play);
- fsi_clk_ctrl(fsi, 0);
- set_rate = fsi_get_info_set_rate(master);
- if (set_rate && fsi->rate)
+ if (fsi_is_clk_master(fsi)) {
+ fsi_clk_ctrl(fsi, 0);
set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
+ }
+
fsi->rate = 0;
pm_runtime_put_sync(dai->dev);
@@ -876,6 +884,8 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
+ struct fsi_master *master = fsi_get_master(fsi);
+ set_rate_func set_rate = fsi_get_info_set_rate(master);
u32 flags = fsi_get_info_flags(fsi);
u32 data = 0;
int ret;
@@ -886,6 +896,7 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
data = DIMD | DOMD;
+ fsi->clk_master = 1;
break;
case SND_SOC_DAIFMT_CBS_CFS:
break;
@@ -893,6 +904,13 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
ret = -EINVAL;
goto set_fmt_exit;
}
+
+ if (fsi_is_clk_master(fsi) && !set_rate) {
+ dev_err(dai->dev, "platform doesn't have set_rate\n");
+ ret = -EINVAL;
+ goto set_fmt_exit;
+ }
+
fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
/* set format */
@@ -919,13 +937,12 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
{
struct fsi_priv *fsi = fsi_get_priv(substream);
struct fsi_master *master = fsi_get_master(fsi);
- set_rate_func set_rate;
+ set_rate_func set_rate = fsi_get_info_set_rate(master);
int fsi_ver = master->core->ver;
long rate = params_rate(params);
int ret;
- set_rate = fsi_get_info_set_rate(master);
- if (!set_rate)
+ if (!fsi_is_clk_master(fsi))
return 0;
ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);