ASoC: rsnd: add DVC support
This patch adds DVC (Digital Volume Controller) support which is member of CMD unit. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
68b6af3656
commit
bff58ea4f4
@ -56,9 +56,17 @@ struct rsnd_src_platform_info {
|
||||
int dma_id; /* for Gen2 SCU */
|
||||
};
|
||||
|
||||
/*
|
||||
* flags
|
||||
*/
|
||||
struct rsnd_dvc_platform_info {
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
struct rsnd_dai_path_info {
|
||||
struct rsnd_ssi_platform_info *ssi;
|
||||
struct rsnd_src_platform_info *src;
|
||||
struct rsnd_dvc_platform_info *dvc;
|
||||
};
|
||||
|
||||
struct rsnd_dai_platform_info {
|
||||
@ -83,6 +91,8 @@ struct rcar_snd_info {
|
||||
int ssi_info_nr;
|
||||
struct rsnd_src_platform_info *src_info;
|
||||
int src_info_nr;
|
||||
struct rsnd_dvc_platform_info *dvc_info;
|
||||
int dvc_info_nr;
|
||||
struct rsnd_dai_platform_info *dai_info;
|
||||
int dai_info_nr;
|
||||
int (*start)(int id);
|
||||
|
@ -1,2 +1,2 @@
|
||||
snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o
|
||||
snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o dvc.o
|
||||
obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o
|
@ -57,6 +57,24 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
|
||||
return (0x6 + ws) << 8;
|
||||
}
|
||||
|
||||
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai,
|
||||
struct rsnd_mod *mod,
|
||||
struct rsnd_dai_stream *io)
|
||||
{
|
||||
int id = rsnd_mod_id(mod);
|
||||
int shift = (id % 2) ? 16 : 0;
|
||||
u32 mask, val;
|
||||
|
||||
val = rsnd_adg_ssi_ws_timing_gen2(io);
|
||||
|
||||
val = val << shift;
|
||||
mask = 0xffff << shift;
|
||||
|
||||
rsnd_mod_bset(mod, CMDOUT_TIMSEL, mask, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai,
|
||||
struct rsnd_mod *mod,
|
||||
struct rsnd_dai_stream *io,
|
||||
|
@ -645,6 +645,11 @@ static int rsnd_path_init(struct rsnd_priv *priv,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* DVC */
|
||||
ret = rsnd_path_parse(priv, io, dvc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -869,6 +874,20 @@ static struct snd_pcm_ops rsnd_pcm_ops = {
|
||||
|
||||
static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct rsnd_priv *priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
|
||||
struct rsnd_dai *rdai;
|
||||
int i, ret;
|
||||
|
||||
for_each_rsnd_dai(rdai, priv, i) {
|
||||
ret = rsnd_dai_call(pcm_new, &rdai->playback, rdai, rtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rsnd_dai_call(pcm_new, &rdai->capture, rdai, rtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return snd_pcm_lib_preallocate_pages_for_all(
|
||||
rtd->pcm,
|
||||
SNDRV_DMA_TYPE_DEV,
|
||||
@ -908,6 +927,7 @@ static int rsnd_probe(struct platform_device *pdev)
|
||||
rsnd_gen_probe,
|
||||
rsnd_ssi_probe,
|
||||
rsnd_src_probe,
|
||||
rsnd_dvc_probe,
|
||||
rsnd_adg_probe,
|
||||
rsnd_dai_probe,
|
||||
};
|
||||
|
273
sound/soc/sh/rcar/dvc.c
Normal file
273
sound/soc/sh/rcar/dvc.c
Normal file
@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Renesas R-Car DVC support
|
||||
*
|
||||
* Copyright (C) 2014 Renesas Solutions Corp.
|
||||
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include "rsnd.h"
|
||||
|
||||
#define RSND_DVC_NAME_SIZE 16
|
||||
#define RSND_DVC_VOLUME_MAX 100
|
||||
#define RSND_DVC_VOLUME_NUM 2
|
||||
struct rsnd_dvc {
|
||||
struct rsnd_dvc_platform_info *info; /* rcar_snd.h */
|
||||
struct rsnd_mod mod;
|
||||
struct clk *clk;
|
||||
long volume[RSND_DVC_VOLUME_NUM];
|
||||
};
|
||||
|
||||
#define rsnd_mod_to_dvc(_mod) \
|
||||
container_of((_mod), struct rsnd_dvc, mod)
|
||||
|
||||
#define for_each_rsnd_dvc(pos, priv, i) \
|
||||
for ((i) = 0; \
|
||||
((i) < rsnd_dvc_nr(priv)) && \
|
||||
((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \
|
||||
i++)
|
||||
|
||||
static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
|
||||
{
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
|
||||
u32 max = (0x00800000 - 1);
|
||||
u32 vol[RSND_DVC_VOLUME_NUM];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RSND_DVC_VOLUME_NUM; i++)
|
||||
vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i];
|
||||
|
||||
rsnd_mod_write(mod, DVC_VOL0R, vol[0]);
|
||||
rsnd_mod_write(mod, DVC_VOL1R, vol[1]);
|
||||
}
|
||||
|
||||
static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(dvc_mod);
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod);
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(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;
|
||||
}
|
||||
|
||||
clk_prepare_enable(dvc->clk);
|
||||
|
||||
/*
|
||||
* fixme
|
||||
* it doesn't support CTU/MIX
|
||||
*/
|
||||
rsnd_mod_write(dvc_mod, CMD_ROUTE_SLCT, route[src_id]);
|
||||
|
||||
rsnd_mod_write(dvc_mod, DVC_SWRSR, 0);
|
||||
rsnd_mod_write(dvc_mod, DVC_SWRSR, 1);
|
||||
|
||||
rsnd_mod_write(dvc_mod, DVC_DVUIR, 1);
|
||||
|
||||
rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod));
|
||||
|
||||
/* enable Volume */
|
||||
rsnd_mod_write(dvc_mod, DVC_DVUCR, 0x100);
|
||||
|
||||
/* ch0/ch1 Volume */
|
||||
rsnd_dvc_volume_update(dvc_mod);
|
||||
|
||||
rsnd_mod_write(dvc_mod, DVC_DVUIR, 0);
|
||||
|
||||
rsnd_mod_write(dvc_mod, DVC_DVUER, 1);
|
||||
|
||||
rsnd_adg_set_cmd_timsel_gen2(rdai, dvc_mod, io);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_quit(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
|
||||
|
||||
clk_disable_unprepare(dvc->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_start(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
rsnd_mod_write(mod, CMD_CTRL, 0x10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_stop(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
rsnd_mod_write(mod, CMD_CTRL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = RSND_DVC_VOLUME_NUM;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = RSND_DVC_VOLUME_MAX;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct rsnd_mod *mod = snd_kcontrol_chip(kctrl);
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RSND_DVC_VOLUME_NUM; i++)
|
||||
ucontrol->value.integer.value[i] = dvc->volume[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct rsnd_mod *mod = snd_kcontrol_chip(kctrl);
|
||||
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
|
||||
int i, change = 0;
|
||||
|
||||
for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) {
|
||||
if (ucontrol->value.integer.value[i] < 0 ||
|
||||
ucontrol->value.integer.value[i] > RSND_DVC_VOLUME_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
change |= (ucontrol->value.integer.value[i] != dvc->volume[i]);
|
||||
}
|
||||
|
||||
if (change) {
|
||||
for (i = 0; i < RSND_DVC_VOLUME_NUM; i++)
|
||||
dvc->volume[i] = ucontrol->value.integer.value[i];
|
||||
|
||||
rsnd_dvc_volume_update(mod);
|
||||
}
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
struct snd_card *card = rtd->card->snd_card;
|
||||
struct snd_kcontrol *kctrl;
|
||||
static struct snd_kcontrol_new knew = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Playback Volume",
|
||||
.info = rsnd_dvc_volume_info,
|
||||
.get = rsnd_dvc_volume_get,
|
||||
.put = rsnd_dvc_volume_put,
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!rsnd_dai_is_play(rdai, io)) {
|
||||
dev_err(dev, "DVC%d is connected to Capture DAI\n",
|
||||
rsnd_mod_id(mod));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kctrl = snd_ctl_new1(&knew, mod);
|
||||
if (!kctrl)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = snd_ctl_add(card, kctrl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rsnd_mod_ops rsnd_dvc_ops = {
|
||||
.name = "dvc (gen2)",
|
||||
.init = rsnd_dvc_init,
|
||||
.quit = rsnd_dvc_quit,
|
||||
.start = rsnd_dvc_start,
|
||||
.stop = rsnd_dvc_stop,
|
||||
.pcm_new = rsnd_dvc_pcm_new,
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int rsnd_dvc_probe(struct platform_device *pdev,
|
||||
const struct rsnd_of_data *of_data,
|
||||
struct rsnd_priv *priv)
|
||||
{
|
||||
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
struct rsnd_dvc *dvc;
|
||||
struct clk *clk;
|
||||
char name[RSND_DVC_NAME_SIZE];
|
||||
int i, nr;
|
||||
|
||||
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");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
priv->dvc_nr = nr;
|
||||
priv->dvc = dvc;
|
||||
|
||||
for_each_rsnd_dvc(dvc, priv, i) {
|
||||
snprintf(name, RSND_DVC_NAME_SIZE, "dvc.%d", i);
|
||||
|
||||
clk = devm_clk_get(dev, name);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
dvc->info = &info->dvc_info[i];
|
||||
dvc->clk = clk;
|
||||
|
||||
rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, RSND_MOD_DVC, i);
|
||||
|
||||
dev_dbg(dev, "CMD%d probed\n", i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -181,6 +181,8 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_BUSIF_MODE, 0x0, 0x20),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_ROUTE_MODE0,0xc, 0x20),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_CTRL, 0x10, 0x20),
|
||||
RSND_GEN2_M_REG(gen, SCU, CMD_ROUTE_SLCT, 0x18c, 0x20),
|
||||
RSND_GEN2_M_REG(gen, SCU, CMD_CTRL, 0x190, 0x20),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_SWRSR, 0x200, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_SRCIR, 0x204, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_ADINR, 0x214, 0x40),
|
||||
@ -189,6 +191,14 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_SRCCR, 0x224, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_BSDSR, 0x22c, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SCU, SRC_BSISR, 0x238, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_SWRSR, 0xe00, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_DVUIR, 0xe04, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_ADINR, 0xe08, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_DVUCR, 0xe10, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_ZCMCR, 0xe14, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_VOL0R, 0xe28, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_VOL1R, 0xe2c, 0x100),
|
||||
RSND_GEN2_M_REG(gen, SCU, DVC_DVUER, 0xe48, 0x100),
|
||||
|
||||
RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00),
|
||||
RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04),
|
||||
@ -207,6 +217,7 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
|
||||
RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL2, 0x50),
|
||||
RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL3, 0x54),
|
||||
RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL4, 0x58),
|
||||
RSND_GEN2_S_REG(gen, ADG, CMDOUT_TIMSEL, 0x5c),
|
||||
|
||||
RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40),
|
||||
RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40),
|
||||
|
@ -44,6 +44,15 @@ enum rsnd_reg {
|
||||
RSND_REG_SRC_IFSCR,
|
||||
RSND_REG_SRC_IFSVR,
|
||||
RSND_REG_SRC_SRCCR,
|
||||
RSND_REG_CMD_ROUTE_SLCT,
|
||||
RSND_REG_DVC_SWRSR,
|
||||
RSND_REG_DVC_DVUIR,
|
||||
RSND_REG_DVC_ADINR,
|
||||
RSND_REG_DVC_DVUCR,
|
||||
RSND_REG_DVC_ZCMCR,
|
||||
RSND_REG_DVC_VOL0R,
|
||||
RSND_REG_DVC_VOL1R,
|
||||
RSND_REG_DVC_DVUER,
|
||||
|
||||
/* ADG */
|
||||
RSND_REG_BRRA,
|
||||
@ -79,6 +88,8 @@ enum rsnd_reg {
|
||||
RSND_REG_SHARE17,
|
||||
RSND_REG_SHARE18,
|
||||
RSND_REG_SHARE19,
|
||||
RSND_REG_SHARE20,
|
||||
RSND_REG_SHARE21,
|
||||
|
||||
RSND_REG_MAX,
|
||||
};
|
||||
@ -114,6 +125,8 @@ enum rsnd_reg {
|
||||
#define RSND_REG_SRCOUT_TIMSEL3 RSND_REG_SHARE17
|
||||
#define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18
|
||||
#define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19
|
||||
#define RSND_REG_CMD_CTRL RSND_REG_SHARE20
|
||||
#define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21
|
||||
|
||||
struct rsnd_of_data;
|
||||
struct rsnd_priv;
|
||||
@ -166,6 +179,7 @@ void rsnd_dma_quit(struct rsnd_priv *priv,
|
||||
enum rsnd_mod_type {
|
||||
RSND_MOD_SRC = 0,
|
||||
RSND_MOD_SSI,
|
||||
RSND_MOD_DVC,
|
||||
RSND_MOD_MAX,
|
||||
};
|
||||
|
||||
@ -183,6 +197,9 @@ struct rsnd_mod_ops {
|
||||
struct rsnd_dai *rdai);
|
||||
int (*stop)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai);
|
||||
int (*pcm_new)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct snd_soc_pcm_runtime *rtd);
|
||||
};
|
||||
|
||||
struct rsnd_dai_stream;
|
||||
@ -223,6 +240,7 @@ struct rsnd_dai_stream {
|
||||
};
|
||||
#define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI])
|
||||
#define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC])
|
||||
#define rsnd_io_to_mod_dvc(io) ((io)->mod[RSND_MOD_DVC])
|
||||
|
||||
struct rsnd_dai {
|
||||
char name[RSND_DAI_NAME_SIZE];
|
||||
@ -286,6 +304,9 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
|
||||
int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai,
|
||||
struct rsnd_mod *mod,
|
||||
struct rsnd_dai_stream *io);
|
||||
|
||||
/*
|
||||
* R-Car sound priv
|
||||
@ -322,6 +343,12 @@ struct rsnd_priv {
|
||||
void *ssi;
|
||||
int ssi_nr;
|
||||
|
||||
/*
|
||||
* below value will be filled on rsnd_dvc_probe()
|
||||
*/
|
||||
void *dvc;
|
||||
int dvc_nr;
|
||||
|
||||
/*
|
||||
* below value will be filled on rsnd_dai_probe()
|
||||
*/
|
||||
@ -374,4 +401,17 @@ int rsnd_ssi_probe(struct platform_device *pdev,
|
||||
struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
|
||||
int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
|
||||
|
||||
/*
|
||||
* R-Car DVC
|
||||
*/
|
||||
int rsnd_dvc_probe(struct platform_device *pdev,
|
||||
const struct rsnd_of_data *of_data,
|
||||
struct rsnd_priv *priv);
|
||||
void rsnd_dvc_remove(struct platform_device *pdev,
|
||||
struct rsnd_priv *priv);
|
||||
struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
|
||||
|
||||
#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -536,12 +536,14 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
|
||||
static int rsnd_src_start_gen2(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai)
|
||||
{
|
||||
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
|
||||
struct rsnd_src *src = rsnd_mod_to_src(mod);
|
||||
u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11;
|
||||
|
||||
rsnd_dma_start(rsnd_mod_to_dma(&src->mod));
|
||||
|
||||
rsnd_mod_write(mod, SSI_CTRL, 0x1);
|
||||
rsnd_mod_write(mod, SRC_CTRL, 0x11);
|
||||
rsnd_mod_write(mod, SRC_CTRL, val);
|
||||
|
||||
return rsnd_src_start(mod, rdai);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user