mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-06 06:37:59 +00:00
ASoC: rsnd: Get correct SCU ID
Current rsnd driver is assuming that SCU/SRU ID is same as SSIU/SSI ID, because Gen1 can't select it. But, Gen2 can select it. The SCU/SRU/SSIU/SSI pair depends on the platform. This patch get correct SCU ID from platform info. To keep compatible, it still assuming SCU ID = SSI ID if platform doesn't have info Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
78f13d0c5a
commit
389933d9f6
5 changed files with 72 additions and 20 deletions
|
@ -70,6 +70,7 @@ struct rsnd_scu_platform_info {
|
||||||
|
|
||||||
struct rsnd_dai_path_info {
|
struct rsnd_dai_path_info {
|
||||||
struct rsnd_ssi_platform_info *ssi;
|
struct rsnd_ssi_platform_info *ssi;
|
||||||
|
struct rsnd_scu_platform_info *scu;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rsnd_dai_platform_info {
|
struct rsnd_dai_platform_info {
|
||||||
|
|
|
@ -107,6 +107,11 @@
|
||||||
(!(priv->info->func) ? 0 : \
|
(!(priv->info->func) ? 0 : \
|
||||||
priv->info->func(param))
|
priv->info->func(param))
|
||||||
|
|
||||||
|
#define rsnd_is_enable_path(io, name) \
|
||||||
|
((io)->info ? (io)->info->name : NULL)
|
||||||
|
#define rsnd_info_id(priv, io, name) \
|
||||||
|
((io)->info->name - priv->info->name##_info)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rsnd_mod functions
|
* rsnd_mod functions
|
||||||
*/
|
*/
|
||||||
|
@ -572,8 +577,10 @@ static int rsnd_path_init(struct rsnd_priv *priv,
|
||||||
struct rsnd_dai_stream *io)
|
struct rsnd_dai_stream *io)
|
||||||
{
|
{
|
||||||
struct rsnd_mod *mod;
|
struct rsnd_mod *mod;
|
||||||
|
struct rsnd_dai_platform_info *dai_info = rdai->info;
|
||||||
int ret;
|
int ret;
|
||||||
int id;
|
int ssi_id = -1;
|
||||||
|
int scu_id = -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gen1 is created by SRU/SSI, and this SRU is base module of
|
* Gen1 is created by SRU/SSI, and this SRU is base module of
|
||||||
|
@ -584,29 +591,35 @@ static int rsnd_path_init(struct rsnd_priv *priv,
|
||||||
*
|
*
|
||||||
* Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
|
* Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
|
||||||
* using fixed path.
|
* using fixed path.
|
||||||
*
|
|
||||||
* Then, SSI id = SCU id here
|
|
||||||
*/
|
*/
|
||||||
/* get SSI's ID */
|
if (dai_info) {
|
||||||
mod = rsnd_ssi_mod_get_frm_dai(priv,
|
if (rsnd_is_enable_path(io, ssi))
|
||||||
rsnd_dai_id(priv, rdai),
|
ssi_id = rsnd_info_id(priv, io, ssi);
|
||||||
rsnd_dai_is_play(rdai, io));
|
if (rsnd_is_enable_path(io, scu))
|
||||||
if (!mod)
|
scu_id = rsnd_info_id(priv, io, scu);
|
||||||
return 0;
|
} else {
|
||||||
id = rsnd_mod_id(mod);
|
/* get SSI's ID */
|
||||||
|
mod = rsnd_ssi_mod_get_frm_dai(priv,
|
||||||
|
rsnd_dai_id(priv, rdai),
|
||||||
|
rsnd_dai_is_play(rdai, io));
|
||||||
|
if (!mod)
|
||||||
|
return 0;
|
||||||
|
ssi_id = scu_id = rsnd_mod_id(mod);
|
||||||
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
/* SCU */
|
/* SCU */
|
||||||
mod = rsnd_scu_mod_get(priv, id);
|
if (scu_id >= 0) {
|
||||||
if (mod) {
|
mod = rsnd_scu_mod_get(priv, scu_id);
|
||||||
ret = rsnd_dai_connect(mod, io);
|
ret = rsnd_dai_connect(mod, io);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SSI */
|
/* SSI */
|
||||||
mod = rsnd_ssi_mod_get(priv, id);
|
if (ssi_id >= 0) {
|
||||||
if (mod) {
|
mod = rsnd_ssi_mod_get(priv, ssi_id);
|
||||||
ret = rsnd_dai_connect(mod, io);
|
ret = rsnd_dai_connect(mod, io);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -699,6 +712,9 @@ static int rsnd_dai_probe(struct platform_device *pdev,
|
||||||
drv[i].playback.formats = RSND_FMTS;
|
drv[i].playback.formats = RSND_FMTS;
|
||||||
drv[i].playback.channels_min = 2;
|
drv[i].playback.channels_min = 2;
|
||||||
drv[i].playback.channels_max = 2;
|
drv[i].playback.channels_max = 2;
|
||||||
|
|
||||||
|
if (info->dai_info)
|
||||||
|
rdai[i].playback.info = &info->dai_info[i].playback;
|
||||||
rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
|
rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
|
||||||
}
|
}
|
||||||
if (cmod) {
|
if (cmod) {
|
||||||
|
@ -706,6 +722,9 @@ static int rsnd_dai_probe(struct platform_device *pdev,
|
||||||
drv[i].capture.formats = RSND_FMTS;
|
drv[i].capture.formats = RSND_FMTS;
|
||||||
drv[i].capture.channels_min = 2;
|
drv[i].capture.channels_min = 2;
|
||||||
drv[i].capture.channels_max = 2;
|
drv[i].capture.channels_max = 2;
|
||||||
|
|
||||||
|
if (info->dai_info)
|
||||||
|
rdai[i].capture.info = &info->dai_info[i].capture;
|
||||||
rsnd_path_init(priv, &rdai[i], &rdai[i].capture);
|
rsnd_path_init(priv, &rdai[i], &rdai[i].capture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -211,6 +211,7 @@ char *rsnd_mod_name(struct rsnd_mod *mod);
|
||||||
struct rsnd_dai_stream {
|
struct rsnd_dai_stream {
|
||||||
struct snd_pcm_substream *substream;
|
struct snd_pcm_substream *substream;
|
||||||
struct rsnd_mod *mod[RSND_MOD_MAX];
|
struct rsnd_mod *mod[RSND_MOD_MAX];
|
||||||
|
struct rsnd_dai_path_info *info; /* rcar_snd.h */
|
||||||
int byte_pos;
|
int byte_pos;
|
||||||
int period_pos;
|
int period_pos;
|
||||||
int byte_per_period;
|
int byte_per_period;
|
||||||
|
@ -328,6 +329,19 @@ struct rsnd_priv {
|
||||||
#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags)
|
#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags)
|
||||||
#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags)
|
#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags)
|
||||||
|
|
||||||
|
#define rsnd_info_is_playback(priv, type) \
|
||||||
|
({ \
|
||||||
|
struct rcar_snd_info *info = rsnd_priv_to_info(priv); \
|
||||||
|
int i, is_play = 0; \
|
||||||
|
for (i = 0; i < info->dai_info_nr; i++) { \
|
||||||
|
if (info->dai_info[i].playback.type == (type)->info) { \
|
||||||
|
is_play = 1; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
is_play; \
|
||||||
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* R-Car SCU
|
* R-Car SCU
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -620,6 +620,9 @@ int rsnd_scu_probe(struct platform_device *pdev,
|
||||||
* init SCU
|
* init SCU
|
||||||
*/
|
*/
|
||||||
nr = info->scu_info_nr;
|
nr = info->scu_info_nr;
|
||||||
|
if (!nr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
scu = devm_kzalloc(dev, sizeof(*scu) * nr, GFP_KERNEL);
|
scu = devm_kzalloc(dev, sizeof(*scu) * nr, GFP_KERNEL);
|
||||||
if (!scu) {
|
if (!scu) {
|
||||||
dev_err(dev, "SCU allocate failed\n");
|
dev_err(dev, "SCU allocate failed\n");
|
||||||
|
@ -644,11 +647,19 @@ int rsnd_scu_probe(struct platform_device *pdev,
|
||||||
if (rsnd_is_gen1(priv))
|
if (rsnd_is_gen1(priv))
|
||||||
ops = &rsnd_scu_gen1_ops;
|
ops = &rsnd_scu_gen1_ops;
|
||||||
if (rsnd_is_gen2(priv)) {
|
if (rsnd_is_gen2(priv)) {
|
||||||
struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, i);
|
int ret;
|
||||||
int ret = rsnd_dma_init(priv,
|
int is_play;
|
||||||
rsnd_mod_to_dma(&scu->mod),
|
|
||||||
rsnd_ssi_is_play(ssi),
|
if (info->dai_info) {
|
||||||
scu->info->dma_id);
|
is_play = rsnd_info_is_playback(priv, scu);
|
||||||
|
} else {
|
||||||
|
struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, i);
|
||||||
|
is_play = rsnd_ssi_is_play(ssi);
|
||||||
|
}
|
||||||
|
ret = rsnd_dma_init(priv,
|
||||||
|
rsnd_mod_to_dma(&scu->mod),
|
||||||
|
is_play,
|
||||||
|
scu->info->dma_id);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
|
@ -567,9 +567,16 @@ int rsnd_ssi_probe(struct platform_device *pdev,
|
||||||
* SSI DMA case
|
* SSI DMA case
|
||||||
*/
|
*/
|
||||||
if (pinfo->dma_id > 0) {
|
if (pinfo->dma_id > 0) {
|
||||||
|
int is_play;
|
||||||
|
|
||||||
|
if (info->dai_info)
|
||||||
|
is_play = rsnd_info_is_playback(priv, ssi);
|
||||||
|
else
|
||||||
|
is_play = rsnd_ssi_is_play(&ssi->mod);
|
||||||
|
|
||||||
ret = rsnd_dma_init(
|
ret = rsnd_dma_init(
|
||||||
priv, rsnd_mod_to_dma(&ssi->mod),
|
priv, rsnd_mod_to_dma(&ssi->mod),
|
||||||
rsnd_ssi_is_play(&ssi->mod),
|
is_play,
|
||||||
pinfo->dma_id);
|
pinfo->dma_id);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
dev_info(dev, "SSI DMA failed. try PIO transter\n");
|
dev_info(dev, "SSI DMA failed. try PIO transter\n");
|
||||||
|
|
Loading…
Add table
Reference in a new issue