Loading Documentation/devicetree/bindings/sound/audio-graph-scu-card.txt +3 −2 Original line number Diff line number Diff line Loading @@ -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>; Loading Loading @@ -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 Loading sound/soc/sh/rcar/adg.c +47 −25 Original line number Diff line number Diff line Loading @@ -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; \ Loading @@ -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; Loading Loading @@ -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; Loading @@ -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[] = { Loading @@ -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. Loading Loading @@ -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)) Loading @@ -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; } Loading Loading @@ -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, Loading Loading @@ -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 Loading Loading @@ -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); } } Loading @@ -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); } } Loading Loading @@ -572,12 +570,35 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, 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) { Loading @@ -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; Loading sound/soc/sh/rcar/core.c +35 −16 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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) Loading Loading @@ -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; } Loading Loading @@ -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, Loading sound/soc/sh/rcar/ctu.c +48 −40 Original line number Diff line number Diff line Loading @@ -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; \ Loading Loading @@ -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)); Loading @@ -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); Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -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; } Loading sound/soc/sh/rcar/dma.c +50 −34 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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, Loading Loading @@ -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; Loading @@ -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) Loading @@ -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) Loading Loading @@ -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
Documentation/devicetree/bindings/sound/audio-graph-scu-card.txt +3 −2 Original line number Diff line number Diff line Loading @@ -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>; Loading Loading @@ -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 Loading
sound/soc/sh/rcar/adg.c +47 −25 Original line number Diff line number Diff line Loading @@ -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; \ Loading @@ -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; Loading Loading @@ -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; Loading @@ -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[] = { Loading @@ -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. Loading Loading @@ -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)) Loading @@ -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; } Loading Loading @@ -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, Loading Loading @@ -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 Loading Loading @@ -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); } } Loading @@ -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); } } Loading Loading @@ -572,12 +570,35 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv, 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) { Loading @@ -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; Loading
sound/soc/sh/rcar/core.c +35 −16 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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) Loading Loading @@ -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; } Loading Loading @@ -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, Loading
sound/soc/sh/rcar/ctu.c +48 −40 Original line number Diff line number Diff line Loading @@ -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; \ Loading Loading @@ -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)); Loading @@ -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); Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -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; } Loading
sound/soc/sh/rcar/dma.c +50 −34 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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, Loading Loading @@ -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; Loading @@ -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) Loading @@ -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) Loading Loading @@ -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); }