Merge remote-tracking branch 'asoc/fix/rcar' into asoc-linus

This commit is contained in:
Mark Brown 2017-09-01 12:12:12 +01:00
commit 1a34ec4ab2
3 changed files with 44 additions and 16 deletions

View File

@ -610,6 +610,13 @@ void rsnd_adg_remove(struct rsnd_priv *priv)
{
struct device *dev = rsnd_priv_to_dev(priv);
struct device_node *np = dev->of_node;
struct rsnd_adg *adg = priv->adg;
struct clk *clk;
int i;
for_each_rsnd_clkout(clk, adg, i)
if (adg->clkout[i])
clk_unregister_fixed_rate(adg->clkout[i]);
of_clk_del_provider(np);

View File

@ -726,7 +726,6 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai,
case 2:
case 6:
case 8:
case 16:
/* TDM Extend Mode */
rsnd_rdai_channels_set(rdai, slots);
rsnd_rdai_ssi_lane_set(rdai, 1);
@ -740,7 +739,7 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai,
}
static unsigned int rsnd_soc_hw_channels_list[] = {
2, 6, 8, 16,
2, 6, 8,
};
static unsigned int rsnd_soc_hw_rate_list[] = {
@ -1017,7 +1016,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv,
drv->playback.rates = RSND_RATES;
drv->playback.formats = RSND_FMTS;
drv->playback.channels_min = 2;
drv->playback.channels_max = 16;
drv->playback.channels_max = 8;
drv->playback.stream_name = rdai->playback.name;
snprintf(rdai->capture.name, RSND_DAI_NAME_SIZE,
@ -1025,7 +1024,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv,
drv->capture.rates = RSND_RATES;
drv->capture.formats = RSND_FMTS;
drv->capture.channels_min = 2;
drv->capture.channels_max = 16;
drv->capture.channels_max = 8;
drv->capture.stream_name = rdai->capture.name;
rdai->playback.rdai = rdai;

View File

@ -72,6 +72,7 @@ struct rsnd_ssi {
u32 cr_own;
u32 cr_clk;
u32 cr_mode;
u32 cr_en;
u32 wsr;
int chan;
int rate;
@ -291,6 +292,16 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
if (ret < 0)
return ret;
/*
* SSI clock will be output contiguously
* by below settings.
* This means, rsnd_ssi_master_clk_start()
* and rsnd_ssi_register_setup() are necessary
* for SSI parent
*
* SSICR : FORCE, SCKD, SWSD
* SSIWSR : CONT
*/
ssi->cr_clk = FORCE | SWL_32 | SCKD | SWSD | CKDV(idx);
ssi->wsr = CONT;
ssi->rate = rate;
@ -393,7 +404,8 @@ static void rsnd_ssi_register_setup(struct rsnd_mod *mod)
rsnd_mod_write(mod, SSIWSR, ssi->wsr);
rsnd_mod_write(mod, SSICR, ssi->cr_own |
ssi->cr_clk |
ssi->cr_mode); /* without EN */
ssi->cr_mode |
ssi->cr_en);
}
static void rsnd_ssi_pointer_init(struct rsnd_mod *mod,
@ -544,6 +556,8 @@ static int rsnd_ssi_start(struct rsnd_mod *mod,
struct rsnd_dai_stream *io,
struct rsnd_priv *priv)
{
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
if (!rsnd_ssi_is_run_mods(mod, io))
return 0;
@ -554,7 +568,19 @@ static int rsnd_ssi_start(struct rsnd_mod *mod,
if (rsnd_ssi_multi_slaves_runtime(io))
return 0;
rsnd_mod_bset(mod, SSICR, EN, EN);
/*
* EN is for data output.
* SSI parent EN is not needed.
*/
if (rsnd_ssi_is_parent(mod, io))
return 0;
ssi->cr_en = EN;
rsnd_mod_write(mod, SSICR, ssi->cr_own |
ssi->cr_clk |
ssi->cr_mode |
ssi->cr_en);
return 0;
}
@ -569,13 +595,7 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
if (!rsnd_ssi_is_run_mods(mod, io))
return 0;
/*
* don't stop if not last user
* see also
* rsnd_ssi_start
* rsnd_ssi_interrupt
*/
if (ssi->usrcnt > 1)
if (rsnd_ssi_is_parent(mod, io))
return 0;
/*
@ -595,6 +615,8 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
rsnd_mod_write(mod, SSICR, cr); /* disabled all */
rsnd_ssi_status_check(mod, IIRQ);
ssi->cr_en = 0;
return 0;
}
@ -823,10 +845,10 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
struct rsnd_priv *priv)
{
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
struct rsnd_mod *pure_ssi_mod = rsnd_io_to_mod_ssi(io);
/* Do nothing for SSI parent mod */
if (ssi_parent_mod == mod)
/* Do nothing if non SSI (= SSI parent, multi SSI) mod */
if (pure_ssi_mod != mod)
return 0;
/* PIO will request IRQ again */