summaryrefslogtreecommitdiffstats
path: root/kernel/sound/soc/sh/rcar/dvc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sound/soc/sh/rcar/dvc.c')
-rw-r--r--kernel/sound/soc/sh/rcar/dvc.c103
1 files changed, 48 insertions, 55 deletions
diff --git a/kernel/sound/soc/sh/rcar/dvc.c b/kernel/sound/soc/sh/rcar/dvc.c
index e5fcb062a..58f690900 100644
--- a/kernel/sound/soc/sh/rcar/dvc.c
+++ b/kernel/sound/soc/sh/rcar/dvc.c
@@ -24,6 +24,7 @@ struct rsnd_dvc {
struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */
};
+#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
#define rsnd_dvc_of_node(priv) \
of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc")
@@ -63,7 +64,21 @@ static const char * const dvc_ramp_rate[] = {
"0.125 dB/8192 steps", /* 10111 */
};
-static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
+static void rsnd_dvc_soft_reset(struct rsnd_mod *mod)
+{
+ rsnd_mod_write(mod, DVC_SWRSR, 0);
+ rsnd_mod_write(mod, DVC_SWRSR, 1);
+}
+
+#define rsnd_dvc_initialize_lock(mod) __rsnd_dvc_initialize_lock(mod, 1)
+#define rsnd_dvc_initialize_unlock(mod) __rsnd_dvc_initialize_lock(mod, 0)
+static void __rsnd_dvc_initialize_lock(struct rsnd_mod *mod, u32 enable)
+{
+ rsnd_mod_write(mod, DVC_DVUIR, enable);
+}
+
+static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
+ struct rsnd_mod *mod)
{
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
u32 val[RSND_DVC_CHANNELS];
@@ -120,6 +135,7 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
}
static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
+ struct rsnd_dai_stream *io,
struct rsnd_priv *priv)
{
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
@@ -133,70 +149,50 @@ static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
return 0;
}
-static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
+static int rsnd_dvc_init(struct rsnd_mod *mod,
+ struct rsnd_dai_stream *io,
struct rsnd_priv *priv)
{
- struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod);
- struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
- struct device *dev = rsnd_priv_to_dev(priv);
- int dvc_id = rsnd_mod_id(dvc_mod);
- int src_id = rsnd_mod_id(src_mod);
- u32 route[] = {
- [0] = 0x30000,
- [1] = 0x30001,
- [2] = 0x40000,
- [3] = 0x10000,
- [4] = 0x20000,
- [5] = 0x40100
- };
-
- if (src_id >= ARRAY_SIZE(route)) {
- dev_err(dev, "DVC%d isn't connected to SRC%d\n", dvc_id, src_id);
- return -EINVAL;
- }
-
- rsnd_mod_hw_start(dvc_mod);
+ rsnd_mod_power_on(mod);
- /*
- * fixme
- * it doesn't support CTU/MIX
- */
- rsnd_mod_write(dvc_mod, CMD_ROUTE_SLCT, route[src_id]);
+ rsnd_dvc_soft_reset(mod);
- rsnd_mod_write(dvc_mod, DVC_SWRSR, 0);
- rsnd_mod_write(dvc_mod, DVC_SWRSR, 1);
+ rsnd_dvc_initialize_lock(mod);
- rsnd_mod_write(dvc_mod, DVC_DVUIR, 1);
+ rsnd_path_parse(priv, io);
- rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod));
+ rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io));
/* ch0/ch1 Volume */
- rsnd_dvc_volume_update(dvc_mod);
+ rsnd_dvc_volume_update(io, mod);
- rsnd_mod_write(dvc_mod, DVC_DVUIR, 0);
-
- rsnd_adg_set_cmd_timsel_gen2(dvc_mod, io);
+ rsnd_adg_set_cmd_timsel_gen2(mod, io);
return 0;
}
static int rsnd_dvc_quit(struct rsnd_mod *mod,
+ struct rsnd_dai_stream *io,
struct rsnd_priv *priv)
{
- rsnd_mod_hw_stop(mod);
+ rsnd_mod_power_off(mod);
return 0;
}
static int rsnd_dvc_start(struct rsnd_mod *mod,
+ struct rsnd_dai_stream *io,
struct rsnd_priv *priv)
{
+ rsnd_dvc_initialize_unlock(mod);
+
rsnd_mod_write(mod, CMD_CTRL, 0x10);
return 0;
}
static int rsnd_dvc_stop(struct rsnd_mod *mod,
+ struct rsnd_dai_stream *io,
struct rsnd_priv *priv)
{
rsnd_mod_write(mod, CMD_CTRL, 0);
@@ -205,15 +201,15 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod,
}
static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
+ struct rsnd_dai_stream *io,
struct snd_soc_pcm_runtime *rtd)
{
- struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
int is_play = rsnd_io_is_play(io);
int ret;
/* Volume */
- ret = rsnd_kctrl_new_m(mod, rtd,
+ ret = rsnd_kctrl_new_m(mod, io, rtd,
is_play ?
"DVC Out Playback Volume" : "DVC In Capture Volume",
rsnd_dvc_volume_update,
@@ -222,7 +218,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
return ret;
/* Mute */
- ret = rsnd_kctrl_new_m(mod, rtd,
+ ret = rsnd_kctrl_new_m(mod, io, rtd,
is_play ?
"DVC Out Mute Switch" : "DVC In Mute Switch",
rsnd_dvc_volume_update,
@@ -231,7 +227,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
return ret;
/* Ramp */
- ret = rsnd_kctrl_new_s(mod, rtd,
+ ret = rsnd_kctrl_new_s(mod, io, rtd,
is_play ?
"DVC Out Ramp Switch" : "DVC In Ramp Switch",
rsnd_dvc_volume_update,
@@ -239,7 +235,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
if (ret < 0)
return ret;
- ret = rsnd_kctrl_new_e(mod, rtd,
+ ret = rsnd_kctrl_new_e(mod, io, rtd,
is_play ?
"DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
&dvc->rup,
@@ -248,7 +244,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
if (ret < 0)
return ret;
- ret = rsnd_kctrl_new_e(mod, rtd,
+ ret = rsnd_kctrl_new_e(mod, io, rtd,
is_play ?
"DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
&dvc->rdown,
@@ -261,7 +257,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
return 0;
}
-static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_mod *mod)
+static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
+ struct rsnd_mod *mod)
{
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
@@ -285,7 +282,7 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
id = 0;
- return &((struct rsnd_dvc *)(priv->dvc) + id)->mod;
+ return rsnd_mod_get((struct rsnd_dvc *)(priv->dvc) + id);
}
static void rsnd_of_parse_dvc(struct platform_device *pdev,
@@ -335,23 +332,19 @@ int rsnd_dvc_probe(struct platform_device *pdev,
char name[RSND_DVC_NAME_SIZE];
int i, nr, ret;
+ /* This driver doesn't support Gen1 at this point */
+ if (rsnd_is_gen1(priv))
+ return 0;
+
rsnd_of_parse_dvc(pdev, of_data, priv);
nr = info->dvc_info_nr;
if (!nr)
return 0;
- /* This driver doesn't support Gen1 at this point */
- if (rsnd_is_gen1(priv)) {
- dev_warn(dev, "CMD is not supported on Gen1\n");
- return -EINVAL;
- }
-
dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL);
- if (!dvc) {
- dev_err(dev, "CMD allocate failed\n");
+ if (!dvc)
return -ENOMEM;
- }
priv->dvc_nr = nr;
priv->dvc = dvc;
@@ -366,7 +359,7 @@ int rsnd_dvc_probe(struct platform_device *pdev,
dvc->info = &info->dvc_info[i];
- ret = rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops,
+ ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
clk, RSND_MOD_DVC, i);
if (ret)
return ret;
@@ -382,6 +375,6 @@ void rsnd_dvc_remove(struct platform_device *pdev,
int i;
for_each_rsnd_dvc(dvc, priv, i) {
- rsnd_mod_quit(&dvc->mod);
+ rsnd_mod_quit(rsnd_mod_get(dvc));
}
}