From 34157f7bec8276b4296cf2ec172fc13385ac8af7 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Feb 2017 21:58:34 +0100 Subject: [PATCH 01/10] ASoC: rsnd: drop useles self-assignments Coverity reported (CID 1397992) this self-assignment. I think the code stays readable even with the assignments removed. Signed-off-by: Wolfram Sang Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 948c5ec87980..72966bdd3daa 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -674,12 +674,10 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) /* set clock inversion */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_IF: - rdai->bit_clk_inv = rdai->bit_clk_inv; rdai->frm_clk_inv = !rdai->frm_clk_inv; break; case SND_SOC_DAIFMT_IB_NF: rdai->bit_clk_inv = !rdai->bit_clk_inv; - rdai->frm_clk_inv = rdai->frm_clk_inv; break; case SND_SOC_DAIFMT_IB_IF: rdai->bit_clk_inv = !rdai->bit_clk_inv; From 56d2c61d611a50e58dba521be1325dc90f9cc933 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 20 Feb 2017 22:05:07 +0100 Subject: [PATCH 02/10] ASoC: rsnd: check return value of init function Currently, this function cannot fail for the ADG case. Still, let's apply defensive programming techniques to make sure we fail gracefully whenever rsnd_mod_init() gets extended with another failure case. Reported by Coverity (CID 1397893). Signed-off-by: Wolfram Sang Signed-off-by: Mark Brown --- sound/soc/sh/rcar/adg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 85a33ac0a5c4..54146f66538c 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -564,6 +564,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv) struct rsnd_adg *adg; struct device *dev = rsnd_priv_to_dev(priv); struct device_node *np = dev->of_node; + int ret; adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); if (!adg) { @@ -571,8 +572,10 @@ int rsnd_adg_probe(struct rsnd_priv *priv) return -ENOMEM; } - rsnd_mod_init(priv, &adg->mod, &adg_ops, + ret = rsnd_mod_init(priv, &adg->mod, &adg_ops, NULL, NULL, 0, 0); + if (ret) + return ret; rsnd_adg_get_clkin(priv, adg); rsnd_adg_get_clkout(priv, adg); From dc2721564f6da549f6eb29ac5bca28d65beadcb7 Mon Sep 17 00:00:00 2001 From: Hiroyuki Yokoyama Date: Wed, 22 Mar 2017 05:43:35 +0000 Subject: [PATCH 03/10] ASoC: rcar: enable PCM RATE untile 192000 R-Car sound can handle untile 192000 rate. Signed-off-by: Hiroyuki Yokoyama Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 72966bdd3daa..3e852e00b277 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -96,7 +96,7 @@ #include #include "rsnd.h" -#define RSND_RATES SNDRV_PCM_RATE_8000_96000 +#define RSND_RATES SNDRV_PCM_RATE_8000_192000 #define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) static const struct of_device_id rsnd_of_match[] = { From 6b8530cc056efd4a11b034ca5b1e9f7e9563f553 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 22 Mar 2017 04:02:43 +0000 Subject: [PATCH 04/10] ASoC: rcar: ssi: don't set SSICR.CKDV = 000 with SSIWSR.CONT R-Car Datasheet is indicating "SSICR.CKDV = 000 is invalid when SSIWSR.WS_MODE = 1 or SSIWSR.CONT = 1". Current driver will set CONT, thus, we shouldn't use CKDV = 000. This patch fixup it. Reported-by: Hiroyuki Yokoyama Signed-off-by: Kuninori Morimoto Tested-by: Hiroyuki Yokoyama Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ssi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 411bda2387ad..135c5669f796 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -227,6 +227,15 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, */ for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) { + /* + * It will set SSIWSR.CONT here, but SSICR.CKDV = 000 + * with it is not allowed. (SSIWSR.WS_MODE with + * SSICR.CKDV = 000 is not allowed either). + * Skip it. See SSICR.CKDV + */ + if (j == 0) + continue; + /* * this driver is assuming that * system word is 32bit x chan From e0c4211854bfebd5507761a2bfddaa9e37074230 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 28 Mar 2017 02:31:23 +0000 Subject: [PATCH 05/10] ASoC: rcar: remove rsnd_kctrl_remove() Current rcar driver is trying to remove kctrl when remove time. But, 1) rcar driver can't/shouldn't remove before removing sound card driver, 2) sound card driver will call snd_ctl_dev_free() and removes all kctrls by snd_ctl_remove(). Thus, rsnd_kctrl_remove() is not necessary. Current implementation will get Oops when removing rcar driver after sound card. This patch fix this issue. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 9 --------- sound/soc/sh/rcar/dvc.c | 16 ---------------- sound/soc/sh/rcar/rsnd.h | 3 --- 3 files changed, 28 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 3e852e00b277..134fe2ea4d9e 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1039,15 +1039,6 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod, return 0; } -void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg) -{ - if (cfg->card && cfg->kctrl) - snd_ctl_remove(cfg->card, cfg->kctrl); - - cfg->card = NULL; - cfg->kctrl = NULL; -} - int rsnd_kctrl_new_m(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct snd_soc_pcm_runtime *rtd, diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index cf8f59cdd8d7..994fdb7d0034 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -218,21 +218,6 @@ static int rsnd_dvc_probe_(struct rsnd_mod *mod, return rsnd_cmd_attach(io, rsnd_mod_id(mod)); } -static int rsnd_dvc_remove_(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); - - rsnd_kctrl_remove(dvc->volume); - rsnd_kctrl_remove(dvc->mute); - rsnd_kctrl_remove(dvc->ren); - rsnd_kctrl_remove(dvc->rup); - rsnd_kctrl_remove(dvc->rdown); - - return 0; -} - static int rsnd_dvc_init(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) @@ -332,7 +317,6 @@ static struct rsnd_mod_ops rsnd_dvc_ops = { .name = DVC_NAME, .dma_req = rsnd_dvc_dma_req, .probe = rsnd_dvc_probe_, - .remove = rsnd_dvc_remove_, .init = rsnd_dvc_init, .quit = rsnd_dvc_quit, .pcm_new = rsnd_dvc_pcm_new, diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 7410ec0174db..81ef3f18834a 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -611,9 +611,6 @@ struct rsnd_kctrl_cfg_s { u32 val; }; -void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg); -#define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg)) - int rsnd_kctrl_new_m(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct snd_soc_pcm_runtime *rtd, From 32973dcf71ebee8806a6ee552665c5fad6857e16 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 6 Apr 2017 07:25:13 +0000 Subject: [PATCH 06/10] ASoC: rsnd: merge rsnd_kctrl_new_m/s/e into rsnd_kctrl_new() Current rsnd driver is using rsnd_kctrl_new_m/s/e function, but the differences are very few. This patch merge these rsnd_kctrl_new_m/s/e into rsnd_kctrl_new Signed-off-by: Kuninori Morimoto Tested-by: Hiroyuki Yokoyama Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 96 ++++++++++++++-------------------------- sound/soc/sh/rcar/dvc.c | 8 ++-- sound/soc/sh/rcar/rsnd.h | 50 ++++++++++----------- 3 files changed, 62 insertions(+), 92 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 35c96e4bbd64..f8eb9d3d1949 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1000,13 +1000,30 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, return change; } -static int __rsnd_kctrl_new(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct snd_soc_pcm_runtime *rtd, - const unsigned char *name, - struct rsnd_kctrl_cfg *cfg, - void (*update)(struct rsnd_dai_stream *io, - struct rsnd_mod *mod)) +struct rsnd_kctrl_cfg *rsnd_kctrl_init_m(struct rsnd_kctrl_cfg_m *cfg) +{ + cfg->cfg.val = cfg->val; + + return &cfg->cfg; +} + +struct rsnd_kctrl_cfg *rsnd_kctrl_init_s(struct rsnd_kctrl_cfg_s *cfg) +{ + cfg->cfg.val = &cfg->val; + + return &cfg->cfg; +} + +int rsnd_kctrl_new(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + void (*update)(struct rsnd_dai_stream *io, + struct rsnd_mod *mod), + struct rsnd_kctrl_cfg *cfg, + const char * const *texts, + int size, + u32 max) { struct snd_card *card = rtd->card->snd_card; struct snd_kcontrol *kctrl; @@ -1021,6 +1038,9 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod, }; int ret; + if (size > RSND_MAX_CHANNELS) + return -EINVAL; + kctrl = snd_ctl_new1(&knew, mod); if (!kctrl) return -ENOMEM; @@ -1029,65 +1049,17 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod, if (ret < 0) return ret; - cfg->update = update; - cfg->card = card; - cfg->kctrl = kctrl; - cfg->io = io; + cfg->texts = texts; + cfg->max = max; + cfg->size = size; + cfg->update = update; + cfg->card = card; + cfg->kctrl = kctrl; + cfg->io = io; return 0; } -int rsnd_kctrl_new_m(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct snd_soc_pcm_runtime *rtd, - const unsigned char *name, - void (*update)(struct rsnd_dai_stream *io, - struct rsnd_mod *mod), - struct rsnd_kctrl_cfg_m *_cfg, - int ch_size, - u32 max) -{ - if (ch_size > RSND_MAX_CHANNELS) - return -EINVAL; - - _cfg->cfg.max = max; - _cfg->cfg.size = ch_size; - _cfg->cfg.val = _cfg->val; - return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); -} - -int rsnd_kctrl_new_s(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct snd_soc_pcm_runtime *rtd, - const unsigned char *name, - void (*update)(struct rsnd_dai_stream *io, - struct rsnd_mod *mod), - struct rsnd_kctrl_cfg_s *_cfg, - u32 max) -{ - _cfg->cfg.max = max; - _cfg->cfg.size = 1; - _cfg->cfg.val = &_cfg->val; - return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); -} - -int rsnd_kctrl_new_e(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct snd_soc_pcm_runtime *rtd, - const unsigned char *name, - struct rsnd_kctrl_cfg_s *_cfg, - void (*update)(struct rsnd_dai_stream *io, - struct rsnd_mod *mod), - const char * const *texts, - u32 max) -{ - _cfg->cfg.max = max; - _cfg->cfg.size = 1; - _cfg->cfg.val = &_cfg->val; - _cfg->cfg.texts = texts; - return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); -} - /* * snd_soc_platform */ diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 994fdb7d0034..463de8360985 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -285,18 +285,18 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, ret = rsnd_kctrl_new_e(mod, io, rtd, is_play ? "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", - &dvc->rup, rsnd_dvc_volume_update, - dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); + &dvc->rup, + dvc_ramp_rate); if (ret < 0) return ret; ret = rsnd_kctrl_new_e(mod, io, rtd, is_play ? "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", - &dvc->rdown, rsnd_dvc_volume_update, - dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); + &dvc->rdown, + dvc_ramp_rate); if (ret < 0) return ret; diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 81ef3f18834a..3dc9e06f5943 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -611,32 +611,30 @@ struct rsnd_kctrl_cfg_s { u32 val; }; -int rsnd_kctrl_new_m(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct snd_soc_pcm_runtime *rtd, - const unsigned char *name, - void (*update)(struct rsnd_dai_stream *io, - struct rsnd_mod *mod), - struct rsnd_kctrl_cfg_m *_cfg, - int ch_size, - u32 max); -int rsnd_kctrl_new_s(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct snd_soc_pcm_runtime *rtd, - const unsigned char *name, - void (*update)(struct rsnd_dai_stream *io, - struct rsnd_mod *mod), - struct rsnd_kctrl_cfg_s *_cfg, - u32 max); -int rsnd_kctrl_new_e(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct snd_soc_pcm_runtime *rtd, - const unsigned char *name, - struct rsnd_kctrl_cfg_s *_cfg, - void (*update)(struct rsnd_dai_stream *io, - struct rsnd_mod *mod), - const char * const *texts, - u32 max); +struct rsnd_kctrl_cfg *rsnd_kctrl_init_m(struct rsnd_kctrl_cfg_m *cfg); +struct rsnd_kctrl_cfg *rsnd_kctrl_init_s(struct rsnd_kctrl_cfg_s *cfg); +int rsnd_kctrl_new(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + void (*update)(struct rsnd_dai_stream *io, + struct rsnd_mod *mod), + struct rsnd_kctrl_cfg *cfg, + const char * const *texts, + int size, + u32 max); + +#define rsnd_kctrl_new_m(mod, io, rtd, name, update, cfg, size, max) \ + rsnd_kctrl_new(mod, io, rtd, name, update, rsnd_kctrl_init_m(cfg), \ + NULL, size, max) + +#define rsnd_kctrl_new_s(mod, io, rtd, name, update, cfg, max) \ + rsnd_kctrl_new(mod, io, rtd, name, update, rsnd_kctrl_init_s(cfg), \ + NULL, 1, max) + +#define rsnd_kctrl_new_e(mod, io, rtd, name, update, cfg, texts) \ + rsnd_kctrl_new(mod, io, rtd, name, update, rsnd_kctrl_init_s(cfg), \ + texts, 1, ARRAY_SIZE(texts)) /* * R-Car SSI From 9ca5e57d78446c8bd42adff3dcae693703f91d9c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 19 Apr 2017 00:41:24 +0000 Subject: [PATCH 07/10] ASoC: rsnd: rsnd_mod_make_sure() is not under DEBUG rsnd_mod_make_sure() will be used any situation, thus, under DEBUG is not realistic. This patch move it to non DEBUG area Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 2 -- sound/soc/sh/rcar/rsnd.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index f8eb9d3d1949..1744015408c3 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -110,7 +110,6 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match); /* * rsnd_mod functions */ -#ifdef DEBUG void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) { if (mod->type != type) { @@ -121,7 +120,6 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) rsnd_mod_name(mod), rsnd_mod_id(mod)); } } -#endif char *rsnd_mod_name(struct rsnd_mod *mod) { diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 3dc9e06f5943..dbf4163427e8 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -727,8 +727,8 @@ void rsnd_cmd_remove(struct rsnd_priv *priv); int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id); struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id); -#ifdef DEBUG void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type); +#ifdef DEBUG #define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI) #define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC) #define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC) From 25165f79adc76b812bfb4d8f2ab120aafb28d0e6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 19 Apr 2017 00:45:52 +0000 Subject: [PATCH 08/10] ASoC: rsnd: enable clock-frequency for both 44.1kHz/48kHz Current clock-frequency allows only 1 clock, but ADG can handle both 44.1kHz/48kHz base clocks. This patch enables these. On Salvator-X board, AUDIO_CLKOUT which is generated by ADG is connected to ak4613 MCKI, and it should be synchronized with LRCK. Thus, we need both 44.1kHz/48kHz base clock-frequency. Otherwise, either one sounds strange in high frequency sound. Signed-off-by: Kuninori Morimoto Tested-by: Hiroyuki Yokoyama Signed-off-by: Mark Brown --- sound/soc/sh/rcar/adg.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 214a9ce90bb4..96fef91b480c 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -43,6 +43,7 @@ struct rsnd_adg { }; #define LRCLK_ASYNC (1 << 0) +#define AUDIO_OUT_48 (1 << 1) #define adg_mode_flags(adg) (adg->flags) #define for_each_rsnd_clk(pos, adg, i) \ @@ -364,7 +365,10 @@ found_clock: rsnd_adg_set_ssi_clk(ssi_mod, data); - if (!(adg_mode_flags(adg) & LRCLK_ASYNC)) { + if (adg_mode_flags(adg) & LRCLK_ASYNC) { + if (adg_mode_flags(adg) & AUDIO_OUT_48) + ckr = 0x80000000; + } else { if (0 == (rate % 8000)) ckr = 0x80000000; } @@ -427,11 +431,14 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, struct clk *clk; struct device *dev = rsnd_priv_to_dev(priv); struct device_node *np = dev->of_node; + struct property *prop; u32 ckr, rbgx, rbga, rbgb; - u32 rate, req_rate = 0, div; + u32 rate, div; +#define REQ_SIZE 2 + u32 req_rate[REQ_SIZE] = {}; uint32_t count = 0; unsigned long req_48kHz_rate, req_441kHz_rate; - int i; + int i, req_size; const char *parent_clk_name = NULL; static const char * const clkout_name[] = { [CLKOUT] = "audio_clkout", @@ -452,13 +459,18 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, * ADG supports BRRA/BRRB output only * this means all clkout0/1/2/3 will be same rate */ - of_property_read_u32(np, "clock-frequency", &req_rate); + prop = of_find_property(np, "clock-frequency", NULL);; + req_size = prop->length / sizeof(u32); + + of_property_read_u32_array(np, "clock-frequency", req_rate, req_size); req_48kHz_rate = 0; req_441kHz_rate = 0; - if (0 == (req_rate % 44100)) - req_441kHz_rate = req_rate; - if (0 == (req_rate % 48000)) - req_48kHz_rate = req_rate; + for (i = 0; i < req_size; i++) { + if (0 == (req_rate[i] % 44100)) + req_441kHz_rate = req_rate[i]; + if (0 == (req_rate[i] % 48000)) + req_48kHz_rate = req_rate[i]; + } /* * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC @@ -505,10 +517,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, rbgb = rbgx; adg->rbgb_rate_for_48khz = rate / div; ckr |= brg_table[i] << 16; - if (req_48kHz_rate) { + if (req_48kHz_rate) parent_clk_name = __clk_get_name(clk); - ckr |= 0x80000000; - } } } } @@ -523,7 +533,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, */ if (!count) { clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT], - parent_clk_name, 0, req_rate); + parent_clk_name, 0, req_rate[0]); if (!IS_ERR(clk)) { adg->clkout[CLKOUT] = clk; of_clk_add_provider(np, of_clk_src_simple_get, clk); @@ -536,7 +546,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, for (i = 0; i < CLKOUTMAX; i++) { clk = clk_register_fixed_rate(dev, clkout_name[i], parent_clk_name, 0, - req_rate); + req_rate[0]); adg->clkout[i] = ERR_PTR(-ENOENT); if (!IS_ERR(clk)) adg->clkout[i] = clk; @@ -551,6 +561,9 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, adg->rbga = rbga; adg->rbgb = rbgb; + if (req_rate[0] % 48000 == 0) + adg->flags = AUDIO_OUT_48; + for_each_rsnd_clkout(clk, adg, i) dev_dbg(dev, "clkout %d : %p : %ld\n", i, clk, clk_get_rate(clk)); dev_dbg(dev, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n", From 75f9e4adb56fbb8ffaab7d316f0c02df00e4b755 Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Fri, 21 Apr 2017 13:02:57 +0800 Subject: [PATCH 09/10] ASoC: rsnd: fix semicolon.cocci warnings sound/soc/sh/rcar/adg.c:462:54-55: Unneeded semicolon Remove unneeded semicolon. Generated by: scripts/coccinelle/misc/semicolon.cocci Signed-off-by: Fengguang Wu Acked-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/adg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 96fef91b480c..faa1a4f09766 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -459,7 +459,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, * ADG supports BRRA/BRRB output only * this means all clkout0/1/2/3 will be same rate */ - prop = of_find_property(np, "clock-frequency", NULL);; + prop = of_find_property(np, "clock-frequency", NULL); req_size = prop->length / sizeof(u32); of_property_read_u32_array(np, "clock-frequency", req_rate, req_size); From e8dffe6c2004278c588b3bb441a3dbe998a3f2e4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 21 Apr 2017 00:41:20 +0000 Subject: [PATCH 10/10] ASoC: rsnd: Fix possible NULL pointer dereference 25165f79adc76b812bfb4d8f2ab120aafb28d0e6 ("ASoC: rsnd: enable clock-frequency for both 44.1kHz/48kHz") supports both 44.1kHz/48kHz clock-frequency settings for ADG which will be used for AUDIO_OLKOUTn. But some board doesn't need it, thus, it is not mandatory. But, above patch didn't care about the case of "clock-frequency" DT property was not present. This patch ignores ADG settings if AUDIO_OLKOUTn was not used. Signed-off-by: Marek Vasut [Kuninori: tidyup not to break non AUDIO_OLKOUTn case] Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/adg.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index faa1a4f09766..66203d107a11 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -453,13 +453,18 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, [CLKI] = 0x2, }; - of_property_read_u32(np, "#clock-cells", &count); + ckr = 0; + rbga = 2; /* default 1/6 */ + rbgb = 2; /* default 1/6 */ /* * ADG supports BRRA/BRRB output only * this means all clkout0/1/2/3 will be same rate */ prop = of_find_property(np, "clock-frequency", NULL); + if (!prop) + goto rsnd_adg_get_clkout_end; + req_size = prop->length / sizeof(u32); of_property_read_u32_array(np, "clock-frequency", req_rate, req_size); @@ -472,6 +477,9 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, req_48kHz_rate = req_rate[i]; } + if (req_rate[0] % 48000 == 0) + adg->flags = AUDIO_OUT_48; + /* * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC * have 44.1kHz or 48kHz base clocks for now. @@ -481,9 +489,6 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, * rsnd_adg_ssi_clk_try_start() * rsnd_ssi_master_clk_start() */ - ckr = 0; - rbga = 2; /* default 1/6 */ - rbgb = 2; /* default 1/6 */ adg->rbga_rate_for_441khz = 0; adg->rbgb_rate_for_48khz = 0; for_each_rsnd_clk(clk, adg, i) { @@ -528,6 +533,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, * this means all clkout0/1/2/3 will be * same rate */ + of_property_read_u32(np, "#clock-cells", &count); /* * for clkout */ @@ -557,13 +563,11 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, &adg->onecell); } +rsnd_adg_get_clkout_end: adg->ckr = ckr; adg->rbga = rbga; adg->rbgb = rbgb; - if (req_rate[0] % 48000 == 0) - adg->flags = AUDIO_OUT_48; - for_each_rsnd_clkout(clk, adg, i) dev_dbg(dev, "clkout %d : %p : %ld\n", i, clk, clk_get_rate(clk)); dev_dbg(dev, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",