Unverified Commit f904f846 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next

parents 1cae4146 c409c2a9
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ Example 1. Sampling Rate Conversion
		label = "sound-card";
		prefix = "codec";
		routing = "codec Playback", "DAI0 Playback",
			"codec Playback", "DAI1 Playback";
			  "DAI0 Capture",   "codec Capture";
		convert-rate = <48000>;

		dais = <&cpu_port>;
@@ -79,7 +79,8 @@ Example 2. 2 CPU 1 Codec (Mixing)
		label = "sound-card";
		prefix = "codec";
		routing = "codec Playback", "DAI0 Playback",
			"codec Playback", "DAI1 Playback";
			  "codec Playback", "DAI1 Playback",
			  "DAI0 Capture",   "codec Capture";
		convert-rate = <48000>;

		dais = <&cpu_port0
+47 −25
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ struct rsnd_adg {

#define LRCLK_ASYNC	(1 << 0)
#define AUDIO_OUT_48	(1 << 1)
#define adg_mode_flags(adg)	(adg->flags)

#define for_each_rsnd_clk(pos, adg, i)		\
	for (i = 0;				\
@@ -58,6 +57,13 @@ struct rsnd_adg {
	     i++)
#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)

static const char * const clk_name[] = {
	[CLKA]	= "clk_a",
	[CLKB]	= "clk_b",
	[CLKC]	= "clk_c",
	[CLKI]	= "clk_i",
};

static u32 rsnd_adg_calculate_rbgx(unsigned long div)
{
	int i, ratio;
@@ -280,6 +286,7 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
	struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
	struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
	struct device *dev = rsnd_priv_to_dev(priv);
	int id = rsnd_mod_id(ssi_mod);
	int shift = (id % 4) * 8;
	u32 mask = 0xFF << shift;
@@ -306,12 +313,13 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
		rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL2, mask, val);
		break;
	}

	dev_dbg(dev, "AUDIO_CLK_SEL is 0x%x\n", val);
}

int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
{
	struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
	struct device *dev = rsnd_priv_to_dev(priv);
	struct clk *clk;
	int i;
	int sel_table[] = {
@@ -321,8 +329,6 @@ int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
		[CLKI] = 0x0,
	};

	dev_dbg(dev, "request clock = %d\n", rate);

	/*
	 * find suitable clock from
	 * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
@@ -366,8 +372,8 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)

	rsnd_adg_set_ssi_clk(ssi_mod, data);

	if (adg_mode_flags(adg) & LRCLK_ASYNC) {
		if (adg_mode_flags(adg) & AUDIO_OUT_48)
	if (rsnd_flags_has(adg, LRCLK_ASYNC)) {
		if (rsnd_flags_has(adg, AUDIO_OUT_48))
			ckr = 0x80000000;
	} else {
		if (0 == (rate % 8000))
@@ -378,9 +384,10 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
	rsnd_mod_write(adg_mod, BRRA,  adg->rbga);
	rsnd_mod_write(adg_mod, BRRB,  adg->rbgb);

	dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n",
		rsnd_mod_name(ssi_mod), rsnd_mod_id(ssi_mod),
		data, rate);
	dev_dbg(dev, "CLKOUT is based on BRG%c (= %dHz)\n",
		(ckr) ? 'B' : 'A',
		(ckr) ?	adg->rbgb_rate_for_48khz :
			adg->rbga_rate_for_441khz);

	return 0;
}
@@ -409,21 +416,12 @@ static void rsnd_adg_get_clkin(struct rsnd_priv *priv,
{
	struct device *dev = rsnd_priv_to_dev(priv);
	struct clk *clk;
	static const char * const clk_name[] = {
		[CLKA]	= "clk_a",
		[CLKB]	= "clk_b",
		[CLKC]	= "clk_c",
		[CLKI]	= "clk_i",
	};
	int i;

	for (i = 0; i < CLKMAX; i++) {
		clk = devm_clk_get(dev, clk_name[i]);
		adg->clk[i] = IS_ERR(clk) ? NULL : clk;
	}

	for_each_rsnd_clk(clk, adg, i)
		dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk));
}

static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
@@ -479,10 +477,10 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
	}

	if (req_rate[0] % 48000 == 0)
		adg->flags |= AUDIO_OUT_48;
		rsnd_flags_set(adg, AUDIO_OUT_48);

	if (of_get_property(np, "clkout-lr-asynchronous", NULL))
		adg->flags |= LRCLK_ASYNC;
		rsnd_flags_set(adg, LRCLK_ASYNC);

	/*
	 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
@@ -512,7 +510,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
				adg->rbga_rate_for_441khz = rate / div;
				ckr |= brg_table[i] << 20;
				if (req_441kHz_rate &&
				    !(adg_mode_flags(adg) & AUDIO_OUT_48))
				    !rsnd_flags_has(adg, AUDIO_OUT_48))
					parent_clk_name = __clk_get_name(clk);
			}
		}
@@ -528,7 +526,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
				adg->rbgb_rate_for_48khz = rate / div;
				ckr |= brg_table[i] << 16;
				if (req_48kHz_rate &&
				    (adg_mode_flags(adg) & AUDIO_OUT_48))
				    rsnd_flags_has(adg, AUDIO_OUT_48))
					parent_clk_name = __clk_get_name(clk);
			}
		}
@@ -572,12 +570,35 @@ rsnd_adg_get_clkout_end:
	adg->ckr = ckr;
	adg->rbga = rbga;
	adg->rbgb = rbgb;
}

#ifdef DEBUG
static void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct rsnd_adg *adg)
{
	struct device *dev = rsnd_priv_to_dev(priv);
	struct clk *clk;
	int i;

	for_each_rsnd_clk(clk, adg, i)
		dev_dbg(dev, "%s    : %p : %ld\n",
			clk_name[i], clk, clk_get_rate(clk));

	for_each_rsnd_clkout(clk, adg, i)
		dev_dbg(dev, "clkout %d : %p : %ld\n", i, clk, clk_get_rate(clk));
	dev_dbg(dev, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
		ckr, rbga, rbgb);
		adg->ckr, adg->rbga, adg->rbgb);
	dev_dbg(dev, "BRGA (for 44100 base) = %d\n", adg->rbga_rate_for_441khz);
	dev_dbg(dev, "BRGB (for 48000 base) = %d\n", adg->rbgb_rate_for_48khz);

	/*
	 * Actual CLKOUT will be exchanged in rsnd_adg_ssi_clk_try_start()
	 * by BRGCKR::BRGCKR_31
	 */
	for_each_rsnd_clkout(clk, adg, i)
		dev_dbg(dev, "clkout %d : %p : %ld\n", i,
			clk, clk_get_rate(clk));
}
#else
#define rsnd_adg_clk_dbg_info(priv, adg)
#endif

int rsnd_adg_probe(struct rsnd_priv *priv)
{
@@ -596,6 +617,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv)

	rsnd_adg_get_clkin(priv, adg);
	rsnd_adg_get_clkout(priv, adg);
	rsnd_adg_clk_dbg_info(priv, adg);

	priv->adg = adg;

+35 −16
Original line number Diff line number Diff line
@@ -121,14 +121,6 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
	}
}

char *rsnd_mod_name(struct rsnd_mod *mod)
{
	if (!mod || !mod->ops)
		return "unknown";

	return mod->ops->name;
}

struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io,
				  struct rsnd_mod *mod)
{
@@ -172,7 +164,6 @@ int rsnd_mod_init(struct rsnd_priv *priv,

void rsnd_mod_quit(struct rsnd_mod *mod)
{
	if (mod->clk)
	clk_unprepare(mod->clk);
	mod->clk = NULL;
}
@@ -200,7 +191,10 @@ void rsnd_mod_interrupt(struct rsnd_mod *mod,
int rsnd_io_is_working(struct rsnd_dai_stream *io)
{
	/* see rsnd_dai_stream_init/quit() */
	return !!io->substream;
	if (io->substream)
		return snd_pcm_running(io->substream);

	return 0;
}

int rsnd_runtime_channel_original(struct rsnd_dai_stream *io)
@@ -407,10 +401,8 @@ struct rsnd_mod *rsnd_mod_next(int *iterator,

	for (; *iterator < max; (*iterator)++) {
		type = (array) ? array[*iterator] : *iterator;
		mod = io->mod[type];
		if (!mod)
			continue;

		mod = rsnd_io_to_mod(io, type);
		if (mod)
			return mod;
	}

@@ -1242,6 +1234,33 @@ struct rsnd_kctrl_cfg *rsnd_kctrl_init_s(struct rsnd_kctrl_cfg_s *cfg)
	return &cfg->cfg;
}

const char * const volume_ramp_rate[] = {
	"128 dB/1 step",	 /* 00000 */
	"64 dB/1 step",		 /* 00001 */
	"32 dB/1 step",		 /* 00010 */
	"16 dB/1 step",		 /* 00011 */
	"8 dB/1 step",		 /* 00100 */
	"4 dB/1 step",		 /* 00101 */
	"2 dB/1 step",		 /* 00110 */
	"1 dB/1 step",		 /* 00111 */
	"0.5 dB/1 step",	 /* 01000 */
	"0.25 dB/1 step",	 /* 01001 */
	"0.125 dB/1 step",	 /* 01010 = VOLUME_RAMP_MAX_MIX */
	"0.125 dB/2 steps",	 /* 01011 */
	"0.125 dB/4 steps",	 /* 01100 */
	"0.125 dB/8 steps",	 /* 01101 */
	"0.125 dB/16 steps",	 /* 01110 */
	"0.125 dB/32 steps",	 /* 01111 */
	"0.125 dB/64 steps",	 /* 10000 */
	"0.125 dB/128 steps",	 /* 10001 */
	"0.125 dB/256 steps",	 /* 10010 */
	"0.125 dB/512 steps",	 /* 10011 */
	"0.125 dB/1024 steps",	 /* 10100 */
	"0.125 dB/2048 steps",	 /* 10101 */
	"0.125 dB/4096 steps",	 /* 10110 */
	"0.125 dB/8192 steps",	 /* 10111 = VOLUME_RAMP_MAX_DVC */
};

int rsnd_kctrl_new(struct rsnd_mod *mod,
		   struct rsnd_dai_stream *io,
		   struct snd_soc_pcm_runtime *rtd,
+48 −40
Original line number Diff line number Diff line
@@ -81,8 +81,11 @@ struct rsnd_ctu {
	struct rsnd_kctrl_cfg_m sv3;
	struct rsnd_kctrl_cfg_s reset;
	int channels;
	u32 flags;
};

#define KCTRL_INITIALIZED	(1 << 0)

#define rsnd_ctu_nr(priv) ((priv)->ctu_nr)
#define for_each_rsnd_ctu(pos, priv, i)					\
	for ((i) = 0;							\
@@ -130,7 +133,7 @@ static void rsnd_ctu_value_init(struct rsnd_dai_stream *io,
	int i;

	for (i = 0; i < RSND_MAX_CHANNELS; i++) {
		u32 val = ctu->pass.val[i];
		u32 val = rsnd_kctrl_valm(ctu->pass, i);

		cpmdr |= val << (28 - (i * 4));

@@ -147,44 +150,44 @@ static void rsnd_ctu_value_init(struct rsnd_dai_stream *io,
	rsnd_mod_write(mod, CTU_SCMDR, scmdr);

	if (scmdr > 0) {
		rsnd_mod_write(mod, CTU_SV00R, ctu->sv0.val[0]);
		rsnd_mod_write(mod, CTU_SV01R, ctu->sv0.val[1]);
		rsnd_mod_write(mod, CTU_SV02R, ctu->sv0.val[2]);
		rsnd_mod_write(mod, CTU_SV03R, ctu->sv0.val[3]);
		rsnd_mod_write(mod, CTU_SV04R, ctu->sv0.val[4]);
		rsnd_mod_write(mod, CTU_SV05R, ctu->sv0.val[5]);
		rsnd_mod_write(mod, CTU_SV06R, ctu->sv0.val[6]);
		rsnd_mod_write(mod, CTU_SV07R, ctu->sv0.val[7]);
		rsnd_mod_write(mod, CTU_SV00R, rsnd_kctrl_valm(ctu->sv0, 0));
		rsnd_mod_write(mod, CTU_SV01R, rsnd_kctrl_valm(ctu->sv0, 1));
		rsnd_mod_write(mod, CTU_SV02R, rsnd_kctrl_valm(ctu->sv0, 2));
		rsnd_mod_write(mod, CTU_SV03R, rsnd_kctrl_valm(ctu->sv0, 3));
		rsnd_mod_write(mod, CTU_SV04R, rsnd_kctrl_valm(ctu->sv0, 4));
		rsnd_mod_write(mod, CTU_SV05R, rsnd_kctrl_valm(ctu->sv0, 5));
		rsnd_mod_write(mod, CTU_SV06R, rsnd_kctrl_valm(ctu->sv0, 6));
		rsnd_mod_write(mod, CTU_SV07R, rsnd_kctrl_valm(ctu->sv0, 7));
	}
	if (scmdr > 1) {
		rsnd_mod_write(mod, CTU_SV10R, ctu->sv1.val[0]);
		rsnd_mod_write(mod, CTU_SV11R, ctu->sv1.val[1]);
		rsnd_mod_write(mod, CTU_SV12R, ctu->sv1.val[2]);
		rsnd_mod_write(mod, CTU_SV13R, ctu->sv1.val[3]);
		rsnd_mod_write(mod, CTU_SV14R, ctu->sv1.val[4]);
		rsnd_mod_write(mod, CTU_SV15R, ctu->sv1.val[5]);
		rsnd_mod_write(mod, CTU_SV16R, ctu->sv1.val[6]);
		rsnd_mod_write(mod, CTU_SV17R, ctu->sv1.val[7]);
		rsnd_mod_write(mod, CTU_SV10R, rsnd_kctrl_valm(ctu->sv1, 0));
		rsnd_mod_write(mod, CTU_SV11R, rsnd_kctrl_valm(ctu->sv1, 1));
		rsnd_mod_write(mod, CTU_SV12R, rsnd_kctrl_valm(ctu->sv1, 2));
		rsnd_mod_write(mod, CTU_SV13R, rsnd_kctrl_valm(ctu->sv1, 3));
		rsnd_mod_write(mod, CTU_SV14R, rsnd_kctrl_valm(ctu->sv1, 4));
		rsnd_mod_write(mod, CTU_SV15R, rsnd_kctrl_valm(ctu->sv1, 5));
		rsnd_mod_write(mod, CTU_SV16R, rsnd_kctrl_valm(ctu->sv1, 6));
		rsnd_mod_write(mod, CTU_SV17R, rsnd_kctrl_valm(ctu->sv1, 7));
	}
	if (scmdr > 2) {
		rsnd_mod_write(mod, CTU_SV20R, ctu->sv2.val[0]);
		rsnd_mod_write(mod, CTU_SV21R, ctu->sv2.val[1]);
		rsnd_mod_write(mod, CTU_SV22R, ctu->sv2.val[2]);
		rsnd_mod_write(mod, CTU_SV23R, ctu->sv2.val[3]);
		rsnd_mod_write(mod, CTU_SV24R, ctu->sv2.val[4]);
		rsnd_mod_write(mod, CTU_SV25R, ctu->sv2.val[5]);
		rsnd_mod_write(mod, CTU_SV26R, ctu->sv2.val[6]);
		rsnd_mod_write(mod, CTU_SV27R, ctu->sv2.val[7]);
		rsnd_mod_write(mod, CTU_SV20R, rsnd_kctrl_valm(ctu->sv2, 0));
		rsnd_mod_write(mod, CTU_SV21R, rsnd_kctrl_valm(ctu->sv2, 1));
		rsnd_mod_write(mod, CTU_SV22R, rsnd_kctrl_valm(ctu->sv2, 2));
		rsnd_mod_write(mod, CTU_SV23R, rsnd_kctrl_valm(ctu->sv2, 3));
		rsnd_mod_write(mod, CTU_SV24R, rsnd_kctrl_valm(ctu->sv2, 4));
		rsnd_mod_write(mod, CTU_SV25R, rsnd_kctrl_valm(ctu->sv2, 5));
		rsnd_mod_write(mod, CTU_SV26R, rsnd_kctrl_valm(ctu->sv2, 6));
		rsnd_mod_write(mod, CTU_SV27R, rsnd_kctrl_valm(ctu->sv2, 7));
	}
	if (scmdr > 3) {
		rsnd_mod_write(mod, CTU_SV30R, ctu->sv3.val[0]);
		rsnd_mod_write(mod, CTU_SV31R, ctu->sv3.val[1]);
		rsnd_mod_write(mod, CTU_SV32R, ctu->sv3.val[2]);
		rsnd_mod_write(mod, CTU_SV33R, ctu->sv3.val[3]);
		rsnd_mod_write(mod, CTU_SV34R, ctu->sv3.val[4]);
		rsnd_mod_write(mod, CTU_SV35R, ctu->sv3.val[5]);
		rsnd_mod_write(mod, CTU_SV36R, ctu->sv3.val[6]);
		rsnd_mod_write(mod, CTU_SV37R, ctu->sv3.val[7]);
		rsnd_mod_write(mod, CTU_SV30R, rsnd_kctrl_valm(ctu->sv3, 0));
		rsnd_mod_write(mod, CTU_SV31R, rsnd_kctrl_valm(ctu->sv3, 1));
		rsnd_mod_write(mod, CTU_SV32R, rsnd_kctrl_valm(ctu->sv3, 2));
		rsnd_mod_write(mod, CTU_SV33R, rsnd_kctrl_valm(ctu->sv3, 3));
		rsnd_mod_write(mod, CTU_SV34R, rsnd_kctrl_valm(ctu->sv3, 4));
		rsnd_mod_write(mod, CTU_SV35R, rsnd_kctrl_valm(ctu->sv3, 5));
		rsnd_mod_write(mod, CTU_SV36R, rsnd_kctrl_valm(ctu->sv3, 6));
		rsnd_mod_write(mod, CTU_SV37R, rsnd_kctrl_valm(ctu->sv3, 7));
	}

	rsnd_mod_write(mod, CTU_CTUIR, 0);
@@ -196,17 +199,17 @@ static void rsnd_ctu_value_reset(struct rsnd_dai_stream *io,
	struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod);
	int i;

	if (!ctu->reset.val)
	if (!rsnd_kctrl_vals(ctu->reset))
		return;

	for (i = 0; i < RSND_MAX_CHANNELS; i++) {
		ctu->pass.val[i] = 0;
		ctu->sv0.val[i] = 0;
		ctu->sv1.val[i] = 0;
		ctu->sv2.val[i] = 0;
		ctu->sv3.val[i] = 0;
		rsnd_kctrl_valm(ctu->pass, i) = 0;
		rsnd_kctrl_valm(ctu->sv0,  i) = 0;
		rsnd_kctrl_valm(ctu->sv1,  i) = 0;
		rsnd_kctrl_valm(ctu->sv2,  i) = 0;
		rsnd_kctrl_valm(ctu->sv3,  i) = 0;
	}
	ctu->reset.val = 0;
	rsnd_kctrl_vals(ctu->reset) = 0;
}

static int rsnd_ctu_init(struct rsnd_mod *mod,
@@ -277,6 +280,9 @@ static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
	struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod);
	int ret;

	if (rsnd_flags_has(ctu, KCTRL_INITIALIZED))
		return 0;

	/* CTU Pass */
	ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU Pass",
			       rsnd_kctrl_accept_anytime,
@@ -326,6 +332,8 @@ static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
			       rsnd_ctu_value_reset,
			       &ctu->reset, 1);

	rsnd_flags_set(ctu, KCTRL_INITIALIZED);

	return ret;
}

+50 −34
Original line number Diff line number Diff line
@@ -60,6 +60,14 @@ struct rsnd_dma_ctrl {
#define rsnd_dma_to_dmaen(dma)	(&(dma)->dma.en)
#define rsnd_dma_to_dmapp(dma)	(&(dma)->dma.pp)

/* for DEBUG */
static struct rsnd_mod_ops mem_ops = {
	.name = "mem",
};

static struct rsnd_mod mem = {
};

/*
 *		Audio DMAC
 */
@@ -211,11 +219,9 @@ static int rsnd_dmaen_nolock_start(struct rsnd_mod *mod,
						 dma->mod_from,
						 dma->mod_to);
	if (IS_ERR_OR_NULL(dmaen->chan)) {
		int ret = PTR_ERR(dmaen->chan);

		dmaen->chan = NULL;
		dev_err(dev, "can't get dma channel\n");
		return ret;
		return -EIO;
	}

	return 0;
@@ -747,13 +753,14 @@ static void rsnd_dma_of_path(struct rsnd_mod *this,
		rsnd_mod_name(this), rsnd_mod_id(this));
	for (i = 0; i <= idx; i++) {
		dev_dbg(dev, "  %s[%d]%s\n",
		       rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]),
			rsnd_mod_name(mod[i] ? mod[i] : &mem),
			rsnd_mod_id  (mod[i] ? mod[i] : &mem),
			(mod[i] == *mod_from) ? " from" :
			(mod[i] == *mod_to)   ? " to" : "");
	}
}

int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
static int rsnd_dma_alloc(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
			  struct rsnd_mod **dma_mod)
{
	struct rsnd_mod *mod_from = NULL;
@@ -761,6 +768,7 @@ int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
	struct rsnd_priv *priv = rsnd_io_to_priv(io);
	struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_dma *dma;
	struct rsnd_mod_ops *ops;
	enum rsnd_mod_type type;
	int (*attach)(struct rsnd_dai_stream *io, struct rsnd_dma *dma,
@@ -800,9 +808,6 @@ int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
		type	= RSND_MOD_AUDMA;
	}

	if (!(*dma_mod)) {
		struct rsnd_dma *dma;

	dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
	if (!dma)
		return -ENOMEM;
@@ -816,8 +821,10 @@ int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod,

	dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n",
		rsnd_mod_name(*dma_mod), rsnd_mod_id(*dma_mod),
			rsnd_mod_name(mod_from), rsnd_mod_id(mod_from),
			rsnd_mod_name(mod_to),   rsnd_mod_id(mod_to));
		rsnd_mod_name(mod_from ? mod_from : &mem),
		rsnd_mod_id  (mod_from ? mod_from : &mem),
		rsnd_mod_name(mod_to   ? mod_to   : &mem),
		rsnd_mod_id  (mod_to   ? mod_to   : &mem));

	ret = attach(io, dma, mod_from, mod_to);
	if (ret < 0)
@@ -827,13 +834,21 @@ int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
	dma->dst_addr = rsnd_dma_addr(io, mod_to,   is_play, 0);
	dma->mod_from = mod_from;
	dma->mod_to   = mod_to;

	return 0;
}

	ret = rsnd_dai_connect(*dma_mod, io, type);
int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
		    struct rsnd_mod **dma_mod)
{
	if (!(*dma_mod)) {
		int ret = rsnd_dma_alloc(io, mod, dma_mod);

		if (ret < 0)
			return ret;
	}

	return 0;
	return rsnd_dai_connect(*dma_mod, io, (*dma_mod)->type);
}

int rsnd_dma_probe(struct rsnd_priv *priv)
@@ -866,5 +881,6 @@ int rsnd_dma_probe(struct rsnd_priv *priv)

	priv->dma = dmac;

	return 0;
	/* dummy mem mod for debug */
	return rsnd_mod_init(NULL, &mem, &mem_ops, NULL, NULL, 0, 0);
}
Loading