Skip to content

Commit b9cb90a

Browse files
committed
ASoC: rsnd: adjust convert rate in 1%
Merge series from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>: Renesas Synchronous SRC Mode has HW limitation to be used in 1% rate difference, but driver didn't care it. This patch-set adjust to it. Link: https://lore.kernel.org/r/87o6zi32ry.wl-kuninori.morimoto.gx@renesas.com
2 parents 0b06000 + 89f9cf1 commit b9cb90a

File tree

4 files changed

+95
-39
lines changed

4 files changed

+95
-39
lines changed

sound/soc/renesas/rcar/core.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,20 +1770,6 @@ int rsnd_kctrl_accept_anytime(struct rsnd_dai_stream *io)
17701770
return 1;
17711771
}
17721772

1773-
int rsnd_kctrl_accept_runtime(struct rsnd_dai_stream *io)
1774-
{
1775-
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
1776-
struct rsnd_priv *priv = rsnd_io_to_priv(io);
1777-
struct device *dev = rsnd_priv_to_dev(priv);
1778-
1779-
if (!runtime) {
1780-
dev_warn(dev, "Can't update kctrl when idle\n");
1781-
return 0;
1782-
}
1783-
1784-
return 1;
1785-
}
1786-
17871773
struct rsnd_kctrl_cfg *rsnd_kctrl_init_m(struct rsnd_kctrl_cfg_m *cfg)
17881774
{
17891775
cfg->cfg.val = cfg->val;

sound/soc/renesas/rcar/rsnd.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,6 @@ struct rsnd_kctrl_cfg_s {
742742
#define rsnd_kctrl_vals(x) ((x).val) /* = (x).cfg.val[0] */
743743

744744
int rsnd_kctrl_accept_anytime(struct rsnd_dai_stream *io);
745-
int rsnd_kctrl_accept_runtime(struct rsnd_dai_stream *io);
746745
struct rsnd_kctrl_cfg *rsnd_kctrl_init_m(struct rsnd_kctrl_cfg_m *cfg);
747746
struct rsnd_kctrl_cfg *rsnd_kctrl_init_s(struct rsnd_kctrl_cfg_s *cfg);
748747
int rsnd_kctrl_new(struct rsnd_mod *mod,

sound/soc/renesas/rcar/src.c

Lines changed: 93 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct rsnd_src {
3535
struct rsnd_mod *dma;
3636
struct rsnd_kctrl_cfg_s sen; /* sync convert enable */
3737
struct rsnd_kctrl_cfg_s sync; /* sync convert */
38+
u32 current_sync_rate;
3839
int irq;
3940
};
4041

@@ -100,7 +101,7 @@ static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io,
100101
if (!rsnd_src_sync_is_enabled(mod))
101102
return rsnd_io_converted_rate(io);
102103

103-
convert_rate = src->sync.val;
104+
convert_rate = src->current_sync_rate;
104105

105106
if (!convert_rate)
106107
convert_rate = rsnd_io_converted_rate(io);
@@ -201,13 +202,73 @@ static const u32 chan222222[] = {
201202
static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
202203
struct rsnd_mod *mod)
203204
{
205+
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
204206
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
205-
struct device *dev = rsnd_priv_to_dev(priv);
207+
struct rsnd_src *src = rsnd_mod_to_src(mod);
208+
u32 fin, fout, new_rate;
209+
int inc, cnt, rate;
210+
u64 base, val;
211+
212+
if (!runtime)
213+
return;
214+
215+
if (!rsnd_src_sync_is_enabled(mod))
216+
return;
217+
218+
fin = rsnd_src_get_in_rate(priv, io);
219+
fout = rsnd_src_get_out_rate(priv, io);
220+
221+
new_rate = src->sync.val;
222+
223+
if (!new_rate)
224+
new_rate = fout;
225+
226+
/* Do nothing if no diff */
227+
if (new_rate == src->current_sync_rate)
228+
return;
229+
230+
/*
231+
* SRCm_IFSVR::INTIFS can change within 1%
232+
* see
233+
* SRCm_IFSVR::INTIFS Note
234+
*/
235+
inc = fout / 100;
236+
cnt = abs(new_rate - fout) / inc;
237+
if (fout > new_rate)
238+
inc *= -1;
239+
240+
/*
241+
* After start running SRC, we can update only SRC_IFSVR
242+
* for Synchronous Mode
243+
*/
244+
base = (u64)0x0400000 * fin;
245+
rate = fout;
246+
for (int i = 0; i < cnt; i++) {
247+
val = base;
248+
rate += inc;
249+
do_div(val, rate);
250+
251+
rsnd_mod_write(mod, SRC_IFSVR, val);
252+
}
253+
val = base;
254+
do_div(val, new_rate);
255+
256+
rsnd_mod_write(mod, SRC_IFSVR, val);
257+
258+
/* update current_sync_rate */
259+
src->current_sync_rate = new_rate;
260+
}
261+
262+
static void rsnd_src_init_convert_rate(struct rsnd_dai_stream *io,
263+
struct rsnd_mod *mod)
264+
{
206265
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
266+
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
267+
struct device *dev = rsnd_priv_to_dev(priv);
207268
int is_play = rsnd_io_is_play(io);
208269
int use_src = 0;
209270
u32 fin, fout;
210-
u32 ifscr, fsrate, adinr;
271+
u32 ifscr, adinr;
211272
u32 cr, route;
212273
u32 i_busif, o_busif, tmp;
213274
const u32 *bsdsr_table;
@@ -245,26 +306,15 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
245306
adinr = rsnd_get_adinr_bit(mod, io) | chan;
246307

247308
/*
248-
* SRC_IFSCR / SRC_IFSVR
249-
*/
250-
ifscr = 0;
251-
fsrate = 0;
252-
if (use_src) {
253-
u64 n;
254-
255-
ifscr = 1;
256-
n = (u64)0x0400000 * fin;
257-
do_div(n, fout);
258-
fsrate = n;
259-
}
260-
261-
/*
309+
* SRC_IFSCR
262310
* SRC_SRCCR / SRC_ROUTE_MODE0
263311
*/
312+
ifscr = 0;
264313
cr = 0x00011110;
265314
route = 0x0;
266315
if (use_src) {
267316
route = 0x1;
317+
ifscr = 0x1;
268318

269319
if (rsnd_src_sync_is_enabled(mod)) {
270320
cr |= 0x1;
@@ -335,7 +385,6 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
335385
rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */
336386
rsnd_mod_write(mod, SRC_ADINR, adinr);
337387
rsnd_mod_write(mod, SRC_IFSCR, ifscr);
338-
rsnd_mod_write(mod, SRC_IFSVR, fsrate);
339388
rsnd_mod_write(mod, SRC_SRCCR, cr);
340389
rsnd_mod_write(mod, SRC_BSDSR, bsdsr_table[idx]);
341390
rsnd_mod_write(mod, SRC_BSISR, bsisr_table[idx]);
@@ -348,6 +397,9 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
348397

349398
rsnd_adg_set_src_timesel_gen2(mod, io, fin, fout);
350399

400+
/* update SRC_IFSVR */
401+
rsnd_src_set_convert_rate(io, mod);
402+
351403
return;
352404

353405
convert_rate_err:
@@ -467,15 +519,16 @@ static int rsnd_src_init(struct rsnd_mod *mod,
467519
int ret;
468520

469521
/* reset sync convert_rate */
470-
src->sync.val = 0;
522+
src->sync.val =
523+
src->current_sync_rate = 0;
471524

472525
ret = rsnd_mod_power_on(mod);
473526
if (ret < 0)
474527
return ret;
475528

476529
rsnd_src_activation(mod);
477530

478-
rsnd_src_set_convert_rate(io, mod);
531+
rsnd_src_init_convert_rate(io, mod);
479532

480533
rsnd_src_status_clear(mod);
481534

@@ -493,7 +546,8 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
493546
rsnd_mod_power_off(mod);
494547

495548
/* reset sync convert_rate */
496-
src->sync.val = 0;
549+
src->sync.val =
550+
src->current_sync_rate = 0;
497551

498552
return 0;
499553
}
@@ -531,6 +585,22 @@ static irqreturn_t rsnd_src_interrupt(int irq, void *data)
531585
return IRQ_HANDLED;
532586
}
533587

588+
static int rsnd_src_kctrl_accept_runtime(struct rsnd_dai_stream *io)
589+
{
590+
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
591+
592+
if (!runtime) {
593+
struct rsnd_priv *priv = rsnd_io_to_priv(io);
594+
struct device *dev = rsnd_priv_to_dev(priv);
595+
596+
dev_warn(dev, "\"SRC Out Rate\" can use during running\n");
597+
598+
return 0;
599+
}
600+
601+
return 1;
602+
}
603+
534604
static int rsnd_src_probe_(struct rsnd_mod *mod,
535605
struct rsnd_dai_stream *io,
536606
struct rsnd_priv *priv)
@@ -585,7 +655,7 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
585655
"SRC Out Rate Switch" :
586656
"SRC In Rate Switch",
587657
rsnd_kctrl_accept_anytime,
588-
rsnd_src_set_convert_rate,
658+
rsnd_src_init_convert_rate,
589659
&src->sen, 1);
590660
if (ret < 0)
591661
return ret;
@@ -594,7 +664,7 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
594664
rsnd_io_is_play(io) ?
595665
"SRC Out Rate" :
596666
"SRC In Rate",
597-
rsnd_kctrl_accept_runtime,
667+
rsnd_src_kctrl_accept_runtime,
598668
rsnd_src_set_convert_rate,
599669
&src->sync, 192000);
600670

sound/soc/renesas/rcar/ssi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
336336
return 0;
337337

338338
rate_err:
339-
dev_err(dev, "unsupported clock rate\n");
339+
dev_err(dev, "unsupported clock rate (%d)\n", rate);
340+
340341
return ret;
341342
}
342343

0 commit comments

Comments
 (0)