| From fd385ea49d8cf5f906210177747267ff88d4bd29 Mon Sep 17 00:00:00 2001 |
| From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Date: Sun, 28 Jul 2013 18:58:29 -0700 |
| Subject: ASoC: rsnd: remove platform dai and add dai_id on platform setting |
| |
| Current rsnd driver is using struct rsnd_dai_platform_info |
| so that indicate sound DAI information (playback/capture SSI ID). |
| But, SSI settings were also required separately. |
| Thus, platform settings was very un-understandable. |
| This patch adds dai_id to SSI |
| settings, and removed rsnd_dai_platform_info. |
| |
| Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Signed-off-by: Mark Brown <broonie@linaro.org> |
| (cherry picked from commit 4b4dab82340d969521f4f86108441cb597c8595d) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| include/sound/rcar_snd.h | 18 ++++++++------- |
| sound/soc/sh/rcar/core.c | 60 +++++++++++++++++++++++++++++++++--------------- |
| sound/soc/sh/rcar/gen.c | 10 ++++---- |
| sound/soc/sh/rcar/rsnd.h | 3 +++ |
| sound/soc/sh/rcar/ssi.c | 22 ++++++++++++++++++ |
| 5 files changed, 82 insertions(+), 31 deletions(-) |
| |
| diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h |
| index 99d8dd029906..33233edd1664 100644 |
| --- a/include/sound/rcar_snd.h |
| +++ b/include/sound/rcar_snd.h |
| @@ -28,15 +28,24 @@ |
| /* |
| * flags |
| * |
| - * 0xA0000000 |
| + * 0xAB000000 |
| * |
| * A : clock sharing settings |
| + * B : SSI direction |
| */ |
| #define RSND_SSI_CLK_PIN_SHARE (1 << 31) |
| #define RSND_SSI_CLK_FROM_ADG (1 << 30) /* clock parent is master */ |
| #define RSND_SSI_SYNC (1 << 29) /* SSI34_sync etc */ |
| |
| +#define RSND_SSI_PLAY (1 << 24) |
| + |
| +#define RSND_SSI_SET(_dai_id, _pio_irq, _flags) \ |
| +{ .dai_id = _dai_id, .pio_irq = _pio_irq, .flags = _flags } |
| +#define RSND_SSI_UNUSED \ |
| +{ .dai_id = -1, .pio_irq = -1, .flags = 0 } |
| + |
| struct rsnd_ssi_platform_info { |
| + int dai_id; |
| int pio_irq; |
| u32 flags; |
| }; |
| @@ -45,11 +54,6 @@ struct rsnd_scu_platform_info { |
| u32 flags; |
| }; |
| |
| -struct rsnd_dai_platform_info { |
| - int ssi_id_playback; |
| - int ssi_id_capture; |
| -}; |
| - |
| /* |
| * flags |
| * |
| @@ -66,8 +70,6 @@ struct rcar_snd_info { |
| int ssi_info_nr; |
| struct rsnd_scu_platform_info *scu_info; |
| int scu_info_nr; |
| - struct rsnd_dai_platform_info *dai_info; |
| - int dai_info_nr; |
| int (*start)(int id); |
| int (*stop)(int id); |
| }; |
| diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c |
| index 9a5469d3f352..420d6df9c3d0 100644 |
| --- a/sound/soc/sh/rcar/core.c |
| +++ b/sound/soc/sh/rcar/core.c |
| @@ -219,6 +219,16 @@ int rsnd_dai_disconnect(struct rsnd_mod *mod) |
| return 0; |
| } |
| |
| +int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai) |
| +{ |
| + int id = rdai - priv->rdai; |
| + |
| + if ((id < 0) || (id >= rsnd_dai_nr(priv))) |
| + return -EINVAL; |
| + |
| + return id; |
| +} |
| + |
| struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id) |
| { |
| return priv->rdai + id; |
| @@ -315,9 +325,10 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, |
| struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai); |
| struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); |
| struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); |
| - struct rsnd_dai_platform_info *info = rsnd_dai_get_platform_info(rdai); |
| - int ssi_id = rsnd_dai_is_play(rdai, io) ? info->ssi_id_playback : |
| - info->ssi_id_capture; |
| + struct rsnd_mod *mod = rsnd_ssi_mod_get_frm_dai(priv, |
| + rsnd_dai_id(priv, rdai), |
| + rsnd_dai_is_play(rdai, io)); |
| + int ssi_id = rsnd_mod_id(mod); |
| int ret; |
| unsigned long flags; |
| |
| @@ -439,10 +450,24 @@ static int rsnd_dai_probe(struct platform_device *pdev, |
| { |
| struct snd_soc_dai_driver *drv; |
| struct rsnd_dai *rdai; |
| + struct rsnd_mod *pmod, *cmod; |
| struct device *dev = rsnd_priv_to_dev(priv); |
| - struct rsnd_dai_platform_info *dai_info; |
| - int dai_nr = info->dai_info_nr; |
| - int i, pid, cid; |
| + int dai_nr; |
| + int i; |
| + |
| + /* get max dai nr */ |
| + for (dai_nr = 0; dai_nr < 32; dai_nr++) { |
| + pmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 1); |
| + cmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 0); |
| + |
| + if (!pmod && !cmod) |
| + break; |
| + } |
| + |
| + if (!dai_nr) { |
| + dev_err(dev, "no dai\n"); |
| + return -EIO; |
| + } |
| |
| drv = devm_kzalloc(dev, sizeof(*drv) * dai_nr, GFP_KERNEL); |
| rdai = devm_kzalloc(dev, sizeof(*rdai) * dai_nr, GFP_KERNEL); |
| @@ -452,10 +477,9 @@ static int rsnd_dai_probe(struct platform_device *pdev, |
| } |
| |
| for (i = 0; i < dai_nr; i++) { |
| - dai_info = &info->dai_info[i]; |
| |
| - pid = dai_info->ssi_id_playback; |
| - cid = dai_info->ssi_id_capture; |
| + pmod = rsnd_ssi_mod_get_frm_dai(priv, i, 1); |
| + cmod = rsnd_ssi_mod_get_frm_dai(priv, i, 0); |
| |
| /* |
| * init rsnd_dai |
| @@ -463,8 +487,6 @@ static int rsnd_dai_probe(struct platform_device *pdev, |
| INIT_LIST_HEAD(&rdai[i].playback.head); |
| INIT_LIST_HEAD(&rdai[i].capture.head); |
| |
| - rdai[i].info = dai_info; |
| - |
| snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i); |
| |
| /* |
| @@ -472,20 +494,22 @@ static int rsnd_dai_probe(struct platform_device *pdev, |
| */ |
| drv[i].name = rdai[i].name; |
| drv[i].ops = &rsnd_soc_dai_ops; |
| - if (pid >= 0) { |
| + if (pmod) { |
| drv[i].playback.rates = RSND_RATES; |
| drv[i].playback.formats = RSND_FMTS; |
| drv[i].playback.channels_min = 2; |
| drv[i].playback.channels_max = 2; |
| } |
| - if (cid >= 0) { |
| + if (cmod) { |
| drv[i].capture.rates = RSND_RATES; |
| drv[i].capture.formats = RSND_FMTS; |
| drv[i].capture.channels_min = 2; |
| drv[i].capture.channels_max = 2; |
| } |
| |
| - dev_dbg(dev, "%s (%d, %d) probed", rdai[i].name, pid, cid); |
| + dev_dbg(dev, "%s (%s/%s)\n", rdai[i].name, |
| + pmod ? "play" : " -- ", |
| + cmod ? "capture" : " -- "); |
| } |
| |
| priv->dai_nr = dai_nr; |
| @@ -627,10 +651,6 @@ static int rsnd_probe(struct platform_device *pdev) |
| if (ret < 0) |
| return ret; |
| |
| - ret = rsnd_dai_probe(pdev, info, priv); |
| - if (ret < 0) |
| - return ret; |
| - |
| ret = rsnd_scu_probe(pdev, info, priv); |
| if (ret < 0) |
| return ret; |
| @@ -643,6 +663,10 @@ static int rsnd_probe(struct platform_device *pdev) |
| if (ret < 0) |
| return ret; |
| |
| + ret = rsnd_dai_probe(pdev, info, priv); |
| + if (ret < 0) |
| + return ret; |
| + |
| /* |
| * asoc register |
| */ |
| diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c |
| index 61232cd9908f..460c57eef267 100644 |
| --- a/sound/soc/sh/rcar/gen.c |
| +++ b/sound/soc/sh/rcar/gen.c |
| @@ -49,7 +49,6 @@ static int rsnd_gen1_path_init(struct rsnd_priv *priv, |
| struct rsnd_dai *rdai, |
| struct rsnd_dai_stream *io) |
| { |
| - struct rsnd_dai_platform_info *info = rsnd_dai_get_platform_info(rdai); |
| struct rsnd_mod *mod; |
| int ret; |
| int id; |
| @@ -67,10 +66,11 @@ static int rsnd_gen1_path_init(struct rsnd_priv *priv, |
| * Then, SSI id = SCU id here |
| */ |
| |
| - if (rsnd_dai_is_play(rdai, io)) |
| - id = info->ssi_id_playback; |
| - else |
| - id = info->ssi_id_capture; |
| + /* get SSI's ID */ |
| + mod = rsnd_ssi_mod_get_frm_dai(priv, |
| + rsnd_dai_id(priv, rdai), |
| + rsnd_dai_is_play(rdai, io)); |
| + id = rsnd_mod_id(mod); |
| |
| /* SSI */ |
| mod = rsnd_ssi_mod_get(priv, id); |
| diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h |
| index 0e7727cc41db..9243e387104c 100644 |
| --- a/sound/soc/sh/rcar/rsnd.h |
| +++ b/sound/soc/sh/rcar/rsnd.h |
| @@ -157,6 +157,7 @@ int rsnd_dai_disconnect(struct rsnd_mod *mod); |
| int rsnd_dai_connect(struct rsnd_dai *rdai, struct rsnd_mod *mod, |
| struct rsnd_dai_stream *io); |
| int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io); |
| +int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai); |
| #define rsnd_dai_get_platform_info(rdai) ((rdai)->info) |
| #define rsnd_io_to_runtime(io) ((io)->substream->runtime) |
| |
| @@ -254,5 +255,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, |
| void rsnd_ssi_remove(struct platform_device *pdev, |
| struct rsnd_priv *priv); |
| struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); |
| +struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, |
| + int dai_id, int is_play); |
| |
| #endif |
| diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c |
| index 061ac7e88309..c48a6c7cd08e 100644 |
| --- a/sound/soc/sh/rcar/ssi.c |
| +++ b/sound/soc/sh/rcar/ssi.c |
| @@ -87,6 +87,7 @@ struct rsnd_ssiu { |
| #define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent) |
| #define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master) |
| #define rsnd_ssi_mode_flags(p) ((p)->info->flags) |
| +#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) |
| #define rsnd_ssi_to_ssiu(ssi)\ |
| (((struct rsnd_ssiu *)((ssi) - rsnd_mod_id(&(ssi)->mod))) - 1) |
| |
| @@ -502,6 +503,27 @@ static struct rsnd_mod_ops rsnd_ssi_non_ops = { |
| /* |
| * ssi mod function |
| */ |
| +struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, |
| + int dai_id, int is_play) |
| +{ |
| + struct rsnd_ssi *ssi; |
| + int i, has_play; |
| + |
| + is_play = !!is_play; |
| + |
| + for_each_rsnd_ssi(ssi, priv, i) { |
| + if (rsnd_ssi_dai_id(ssi) != dai_id) |
| + continue; |
| + |
| + has_play = !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY); |
| + |
| + if (is_play == has_play) |
| + return &ssi->mod; |
| + } |
| + |
| + return NULL; |
| +} |
| + |
| struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) |
| { |
| BUG_ON(id < 0 || id >= rsnd_ssi_nr(priv)); |
| -- |
| 1.8.5.rc3 |
| |