Commit 1a34ec4a authored by Mark Brown's avatar Mark Brown

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

parents c8b24e23 e0936c34
...@@ -610,6 +610,13 @@ void rsnd_adg_remove(struct rsnd_priv *priv) ...@@ -610,6 +610,13 @@ void rsnd_adg_remove(struct rsnd_priv *priv)
{ {
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
struct device_node *np = dev->of_node; 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); of_clk_del_provider(np);
......
...@@ -726,7 +726,6 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai, ...@@ -726,7 +726,6 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai,
case 2: case 2:
case 6: case 6:
case 8: case 8:
case 16:
/* TDM Extend Mode */ /* TDM Extend Mode */
rsnd_rdai_channels_set(rdai, slots); rsnd_rdai_channels_set(rdai, slots);
rsnd_rdai_ssi_lane_set(rdai, 1); rsnd_rdai_ssi_lane_set(rdai, 1);
...@@ -740,7 +739,7 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai, ...@@ -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[] = { static unsigned int rsnd_soc_hw_channels_list[] = {
2, 6, 8, 16, 2, 6, 8,
}; };
static unsigned int rsnd_soc_hw_rate_list[] = { static unsigned int rsnd_soc_hw_rate_list[] = {
...@@ -1017,7 +1016,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, ...@@ -1017,7 +1016,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv,
drv->playback.rates = RSND_RATES; drv->playback.rates = RSND_RATES;
drv->playback.formats = RSND_FMTS; drv->playback.formats = RSND_FMTS;
drv->playback.channels_min = 2; drv->playback.channels_min = 2;
drv->playback.channels_max = 16; drv->playback.channels_max = 8;
drv->playback.stream_name = rdai->playback.name; drv->playback.stream_name = rdai->playback.name;
snprintf(rdai->capture.name, RSND_DAI_NAME_SIZE, snprintf(rdai->capture.name, RSND_DAI_NAME_SIZE,
...@@ -1025,7 +1024,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, ...@@ -1025,7 +1024,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv,
drv->capture.rates = RSND_RATES; drv->capture.rates = RSND_RATES;
drv->capture.formats = RSND_FMTS; drv->capture.formats = RSND_FMTS;
drv->capture.channels_min = 2; drv->capture.channels_min = 2;
drv->capture.channels_max = 16; drv->capture.channels_max = 8;
drv->capture.stream_name = rdai->capture.name; drv->capture.stream_name = rdai->capture.name;
rdai->playback.rdai = rdai; rdai->playback.rdai = rdai;
......
...@@ -72,6 +72,7 @@ struct rsnd_ssi { ...@@ -72,6 +72,7 @@ struct rsnd_ssi {
u32 cr_own; u32 cr_own;
u32 cr_clk; u32 cr_clk;
u32 cr_mode; u32 cr_mode;
u32 cr_en;
u32 wsr; u32 wsr;
int chan; int chan;
int rate; int rate;
...@@ -291,6 +292,16 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, ...@@ -291,6 +292,16 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
if (ret < 0) if (ret < 0)
return ret; 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->cr_clk = FORCE | SWL_32 | SCKD | SWSD | CKDV(idx);
ssi->wsr = CONT; ssi->wsr = CONT;
ssi->rate = rate; ssi->rate = rate;
...@@ -393,7 +404,8 @@ static void rsnd_ssi_register_setup(struct rsnd_mod *mod) ...@@ -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, SSIWSR, ssi->wsr);
rsnd_mod_write(mod, SSICR, ssi->cr_own | rsnd_mod_write(mod, SSICR, ssi->cr_own |
ssi->cr_clk | ssi->cr_clk |
ssi->cr_mode); /* without EN */ ssi->cr_mode |
ssi->cr_en);
} }
static void rsnd_ssi_pointer_init(struct rsnd_mod *mod, static void rsnd_ssi_pointer_init(struct rsnd_mod *mod,
...@@ -544,6 +556,8 @@ static int rsnd_ssi_start(struct rsnd_mod *mod, ...@@ -544,6 +556,8 @@ static int rsnd_ssi_start(struct rsnd_mod *mod,
struct rsnd_dai_stream *io, struct rsnd_dai_stream *io,
struct rsnd_priv *priv) struct rsnd_priv *priv)
{ {
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
if (!rsnd_ssi_is_run_mods(mod, io)) if (!rsnd_ssi_is_run_mods(mod, io))
return 0; return 0;
...@@ -554,7 +568,19 @@ static int rsnd_ssi_start(struct rsnd_mod *mod, ...@@ -554,7 +568,19 @@ static int rsnd_ssi_start(struct rsnd_mod *mod,
if (rsnd_ssi_multi_slaves_runtime(io)) if (rsnd_ssi_multi_slaves_runtime(io))
return 0; 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; return 0;
} }
...@@ -569,13 +595,7 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, ...@@ -569,13 +595,7 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
if (!rsnd_ssi_is_run_mods(mod, io)) if (!rsnd_ssi_is_run_mods(mod, io))
return 0; return 0;
/* if (rsnd_ssi_is_parent(mod, io))
* don't stop if not last user
* see also
* rsnd_ssi_start
* rsnd_ssi_interrupt
*/
if (ssi->usrcnt > 1)
return 0; return 0;
/* /*
...@@ -595,6 +615,8 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, ...@@ -595,6 +615,8 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
rsnd_mod_write(mod, SSICR, cr); /* disabled all */ rsnd_mod_write(mod, SSICR, cr); /* disabled all */
rsnd_ssi_status_check(mod, IIRQ); rsnd_ssi_status_check(mod, IIRQ);
ssi->cr_en = 0;
return 0; return 0;
} }
...@@ -823,10 +845,10 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, ...@@ -823,10 +845,10 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
struct rsnd_priv *priv) struct rsnd_priv *priv)
{ {
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 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 */ /* Do nothing if non SSI (= SSI parent, multi SSI) mod */
if (ssi_parent_mod == mod) if (pure_ssi_mod != mod)
return 0; return 0;
/* PIO will request IRQ again */ /* PIO will request IRQ again */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment