forked from Minki/linux
ASoC: add Renesas R-Car module feature
Renesas R-Car series sound circuit consists of SSI and its peripheral. But this peripheral circuit is different between R-Car Generation1 (E1/M1/H1) and Generation2 (E2/M2/H2) (Actually, there are many difference in Generation1 chips) Gen1 series consists of SRU/SSI/ADG, and Gen2 series consists of SCU/SSIU/SSI/ADG. In order to control these by same method, these are treated as "mod" on this driver. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
1536a96889
commit
cdaa3cdfb4
@ -107,9 +107,74 @@
|
||||
priv->info->func(param))
|
||||
|
||||
|
||||
/*
|
||||
* rsnd_mod functions
|
||||
*/
|
||||
char *rsnd_mod_name(struct rsnd_mod *mod)
|
||||
{
|
||||
if (!mod || !mod->ops)
|
||||
return "unknown";
|
||||
|
||||
return mod->ops->name;
|
||||
}
|
||||
|
||||
void rsnd_mod_init(struct rsnd_priv *priv,
|
||||
struct rsnd_mod *mod,
|
||||
struct rsnd_mod_ops *ops,
|
||||
int id)
|
||||
{
|
||||
mod->priv = priv;
|
||||
mod->id = id;
|
||||
mod->ops = ops;
|
||||
INIT_LIST_HEAD(&mod->list);
|
||||
}
|
||||
|
||||
/*
|
||||
* rsnd_dai functions
|
||||
*/
|
||||
#define rsnd_dai_call(rdai, io, fn) \
|
||||
({ \
|
||||
struct rsnd_mod *mod, *n; \
|
||||
int ret = 0; \
|
||||
for_each_rsnd_mod(mod, n, io) { \
|
||||
ret = rsnd_mod_call(mod, fn, rdai, io); \
|
||||
if (ret < 0) \
|
||||
break; \
|
||||
} \
|
||||
ret; \
|
||||
})
|
||||
|
||||
int rsnd_dai_connect(struct rsnd_dai *rdai,
|
||||
struct rsnd_mod *mod,
|
||||
struct rsnd_dai_stream *io)
|
||||
{
|
||||
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
|
||||
struct device *dev = rsnd_priv_to_dev(priv);
|
||||
|
||||
if (!mod) {
|
||||
dev_err(dev, "NULL mod\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!list_empty(&mod->list)) {
|
||||
dev_err(dev, "%s%d is not empty\n",
|
||||
rsnd_mod_name(mod),
|
||||
rsnd_mod_id(mod));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
list_add_tail(&mod->list, &io->head);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rsnd_dai_disconnect(struct rsnd_mod *mod)
|
||||
{
|
||||
list_del_init(&mod->list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id)
|
||||
{
|
||||
return priv->rdai + id;
|
||||
@ -224,8 +289,23 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
ret = rsnd_dai_call(rdai, io, init);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
ret = rsnd_dai_call(rdai, io, start);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
ret = rsnd_dai_call(rdai, io, stop);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
ret = rsnd_dai_call(rdai, io, quit);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
||||
ret = rsnd_platform_call(priv, dai, stop, ssi_id);
|
||||
if (ret < 0)
|
||||
goto dai_trigger_end;
|
||||
|
@ -28,9 +28,52 @@
|
||||
* see gen1/gen2 for detail
|
||||
*/
|
||||
struct rsnd_priv;
|
||||
struct rsnd_mod;
|
||||
struct rsnd_dai;
|
||||
struct rsnd_dai_stream;
|
||||
|
||||
/*
|
||||
* R-Car sound mod
|
||||
*/
|
||||
|
||||
struct rsnd_mod_ops {
|
||||
char *name;
|
||||
int (*init)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
int (*quit)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
int (*start)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
int (*stop)(struct rsnd_mod *mod,
|
||||
struct rsnd_dai *rdai,
|
||||
struct rsnd_dai_stream *io);
|
||||
};
|
||||
|
||||
struct rsnd_mod {
|
||||
int id;
|
||||
struct rsnd_priv *priv;
|
||||
struct rsnd_mod_ops *ops;
|
||||
struct list_head list; /* connect to rsnd_dai playback/capture */
|
||||
};
|
||||
|
||||
#define rsnd_mod_to_priv(mod) ((mod)->priv)
|
||||
#define rsnd_mod_id(mod) ((mod)->id)
|
||||
#define for_each_rsnd_mod(pos, n, io) \
|
||||
list_for_each_entry_safe(pos, n, &(io)->head, list)
|
||||
#define rsnd_mod_call(mod, func, rdai, io) \
|
||||
(!(mod) ? -ENODEV : \
|
||||
!((mod)->ops->func) ? 0 : \
|
||||
(mod)->ops->func(mod, rdai, io))
|
||||
|
||||
void rsnd_mod_init(struct rsnd_priv *priv,
|
||||
struct rsnd_mod *mod,
|
||||
struct rsnd_mod_ops *ops,
|
||||
int id);
|
||||
char *rsnd_mod_name(struct rsnd_mod *mod);
|
||||
|
||||
/*
|
||||
* R-Car sound DAI
|
||||
*/
|
||||
@ -64,6 +107,9 @@ struct rsnd_dai {
|
||||
i++, (rdai) = rsnd_dai_get(priv, i))
|
||||
|
||||
struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id);
|
||||
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);
|
||||
#define rsnd_dai_get_platform_info(rdai) ((rdai)->info)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user