aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyo Kataoka <ryo.kataoka.wt@renesas.com>2019-03-22 20:50:25 +0900
committerRyo Kataoka <ryo.kataoka.wt@renesas.com>2019-03-22 20:50:25 +0900
commit352918e939cd8eb409e1ec70a1f47f322a4ea0d9 (patch)
treee2023e1b898e5bd43e6b00cc71cf8e32f71aa386
parent046cd21658ae8228b58edd8f08fc97b567b1f3e2 (diff)
parentbe1a7ed785516c6d694f8451525d9e74deabb816 (diff)
downloadrenesas-bsp-352918e939cd8eb409e1ec70a1f47f322a4ea0d9.tar.gz
Merge branch 'rcar-3.9.2/audio.rc2' into v4.14.75-ltsi/rcar-3.9.3
* rcar-3.9.2/audio.rc2: ASoC: rsnd: fixup MIX kctrl registration ASoC: rsnd: tidyup registering method for rsnd_kctrl_new() ASoC: rsnd: fixup rsnd_ssi_master_clk_start() user count check ASoC: rsnd: update BSDSR/BSDISR handling
-rw-r--r--sound/soc/sh/rcar/core.c12
-rw-r--r--sound/soc/sh/rcar/dvc.c8
-rw-r--r--sound/soc/sh/rcar/src.c125
-rw-r--r--sound/soc/sh/rcar/ssi.c2
4 files changed, 128 insertions, 19 deletions
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 2361c20b5115f..27b647efa440a 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -1338,6 +1338,18 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,
};
int ret;
+ /*
+ * 1) Avoid duplicate register for DVC with MIX case
+ * 2) Allow duplicate register for MIX
+ * 3) re-register if card was rebinded
+ */
+ list_for_each_entry(kctrl, &card->controls, list) {
+ struct rsnd_kctrl_cfg *c = kctrl->private_data;
+
+ if (c == cfg)
+ return 0;
+ }
+
if (size > RSND_MAX_CHANNELS)
return -EINVAL;
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index dbe54f024d688..4d0da5c568fe4 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -44,11 +44,8 @@ struct rsnd_dvc {
struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */
struct rsnd_kctrl_cfg_s rup; /* Ramp Rate Up */
struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */
- u32 flags;
};
-#define KCTRL_INITIALIZED (1 << 0)
-
#define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id)
#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
@@ -231,9 +228,6 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
int channels = rsnd_rdai_channels_get(rdai);
int ret;
- if (rsnd_flags_has(dvc, KCTRL_INITIALIZED))
- return 0;
-
/* Volume */
ret = rsnd_kctrl_new_m(mod, io, rtd,
is_play ?
@@ -289,8 +283,6 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
if (ret < 0)
return ret;
- rsnd_flags_set(dvc, KCTRL_INITIALIZED);
-
return 0;
}
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index a727e71587b6e..c31cc99f71d2e 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -18,6 +18,7 @@
*/
#include "rsnd.h"
+#include <linux/sys_soc.h>
#define SRC_NAME "src"
@@ -173,20 +174,83 @@ static int rsnd_src_hw_params(struct rsnd_mod *mod,
return 0;
}
+const static u32 bsdsr_table_pattern1[] = {
+ 0x01800000, /* 6 - 1/6 */
+ 0x01000000, /* 6 - 1/4 */
+ 0x00c00000, /* 6 - 1/3 */
+ 0x00800000, /* 6 - 1/2 */
+ 0x00600000, /* 6 - 2/3 */
+ 0x00400000, /* 6 - 1 */
+};
+
+const static u32 bsdsr_table_pattern2[] = {
+ 0x02400000, /* 6 - 1/6 */
+ 0x01800000, /* 6 - 1/4 */
+ 0x01200000, /* 6 - 1/3 */
+ 0x00c00000, /* 6 - 1/2 */
+ 0x00900000, /* 6 - 2/3 */
+ 0x00600000, /* 6 - 1 */
+};
+
+const static u32 bsisr_table[] = {
+ 0x00100060, /* 6 - 1/6 */
+ 0x00100040, /* 6 - 1/4 */
+ 0x00100030, /* 6 - 1/3 */
+ 0x00100020, /* 6 - 1/2 */
+ 0x00100020, /* 6 - 2/3 */
+ 0x00100020, /* 6 - 1 */
+};
+
+const static u32 chan288888[] = {
+ 0x00000006, /* 1 to 2 */
+ 0x000001fe, /* 1 to 8 */
+ 0x000001fe, /* 1 to 8 */
+ 0x000001fe, /* 1 to 8 */
+ 0x000001fe, /* 1 to 8 */
+ 0x000001fe, /* 1 to 8 */
+};
+
+const static u32 chan244888[] = {
+ 0x00000006, /* 1 to 2 */
+ 0x0000001e, /* 1 to 4 */
+ 0x0000001e, /* 1 to 4 */
+ 0x000001fe, /* 1 to 8 */
+ 0x000001fe, /* 1 to 8 */
+ 0x000001fe, /* 1 to 8 */
+};
+
+const static u32 chan222222[] = {
+ 0x00000006, /* 1 to 2 */
+ 0x00000006, /* 1 to 2 */
+ 0x00000006, /* 1 to 2 */
+ 0x00000006, /* 1 to 2 */
+ 0x00000006, /* 1 to 2 */
+ 0x00000006, /* 1 to 2 */
+};
+
+static const struct soc_device_attribute ov_soc[] = {
+ { .soc_id = "r8a77990" }, /* E3 */
+ { /* sentinel */ }
+};
+
static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
struct rsnd_mod *mod)
{
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
struct device *dev = rsnd_priv_to_dev(priv);
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
+ const struct soc_device_attribute *soc = soc_device_match(ov_soc);
int is_play = rsnd_io_is_play(io);
int use_src = 0;
u32 fin, fout;
u32 ifscr, fsrate, adinr;
u32 cr, route;
- u32 bsdsr, bsisr;
u32 i_busif, o_busif, tmp;
+ const u32 *bsdsr_table;
+ const u32 *chptn;
uint ratio;
+ int chan;
+ int idx;
if (!runtime)
return;
@@ -194,6 +258,8 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
fin = rsnd_src_get_in_rate(priv, io);
fout = rsnd_src_get_out_rate(priv, io);
+ chan = rsnd_runtime_channel_original(io);
+
/* 6 - 1/6 are very enough ratio for SRC_BSDSR */
if (fin == fout)
ratio = 0;
@@ -212,8 +278,7 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
/*
* SRC_ADINR
*/
- adinr = rsnd_get_adinr_bit(mod, io) |
- rsnd_runtime_channel_original(io);
+ adinr = rsnd_get_adinr_bit(mod, io) | chan;
/*
* SRC_IFSCR / SRC_IFSVR
@@ -246,21 +311,56 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
/*
* SRC_BSDSR / SRC_BSISR
+ *
+ * see
+ * Combination of Register Setting Related to
+ * FSO/FSI Ratio and Channel, Latency
*/
switch (rsnd_mod_id(mod)) {
+ case 0:
+ chptn = chan288888;
+ bsdsr_table = bsdsr_table_pattern1;
+ break;
+ case 1:
+ case 3:
+ case 4:
+ chptn = chan244888;
+ bsdsr_table = bsdsr_table_pattern1;
+ break;
+ case 2:
+ case 9:
+ chptn = chan222222;
+ bsdsr_table = bsdsr_table_pattern1;
+ break;
case 5:
case 6:
case 7:
case 8:
- bsdsr = 0x02400000; /* 6 - 1/6 */
- bsisr = 0x00100060; /* 6 - 1/6 */
+ chptn = chan222222;
+ bsdsr_table = bsdsr_table_pattern2;
break;
default:
- bsdsr = 0x01800000; /* 6 - 1/6 */
- bsisr = 0x00100060 ;/* 6 - 1/6 */
- break;
+ goto convert_rate_err;
}
+ /*
+ * E3 need to overwrite
+ */
+ if (soc)
+ switch (rsnd_mod_id(mod)) {
+ case 0:
+ case 4:
+ chptn = chan222222;
+ }
+
+ for (idx = 0; idx < ARRAY_SIZE(chan222222); idx++)
+ if (chptn[idx] & (1 << chan))
+ break;
+
+ if (chan > 8 ||
+ idx >= ARRAY_SIZE(chan222222))
+ goto convert_rate_err;
+
/* BUSIF_MODE */
tmp = rsnd_get_busif_shift(io, mod);
i_busif = ( is_play ? tmp : 0) | 1;
@@ -273,8 +373,8 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
rsnd_mod_write(mod, SRC_IFSCR, ifscr);
rsnd_mod_write(mod, SRC_IFSVR, fsrate);
rsnd_mod_write(mod, SRC_SRCCR, cr);
- rsnd_mod_write(mod, SRC_BSDSR, bsdsr);
- rsnd_mod_write(mod, SRC_BSISR, bsisr);
+ rsnd_mod_write(mod, SRC_BSDSR, bsdsr_table[idx]);
+ rsnd_mod_write(mod, SRC_BSISR, bsisr_table[idx]);
rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */
rsnd_mod_write(mod, SRC_I_BUSIF_MODE, i_busif);
@@ -283,6 +383,11 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout);
+
+ return;
+
+convert_rate_err:
+ dev_err(dev, "unknown BSDSR/BSDIR settings\n");
}
static int rsnd_src_irq(struct rsnd_mod *mod,
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index a9d06925a6ce2..d9f02b096e2f6 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -287,7 +287,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
if (rsnd_ssi_is_multi_slave(mod, io))
return 0;
- if (ssi->usrcnt > 1) {
+ if (ssi->usrcnt > 0) {
if (ssi->rate != rate) {
dev_err(dev, "SSI parent/child should use same rate\n");
return -EINVAL;