aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2015-02-20 05:29:13 -0500
committerMark Brown <broonie@kernel.org>2015-03-07 10:04:30 -0500
commit0d00a52182be985bfae67d407ee81fefe448a0fd (patch)
treed7bd4ac0adcab3d4c940e0e63f9753a23df8d8fc /sound
parentaaf4fce019ecd55a2d93b6111525deeef300f751 (diff)
ASoC: rsnd: use union with rsnd_dmaen / rsnd_dmapp
Renesas R-Car needs 2 DMACs.1st DMAC is DMAEngine, and 2nd DMAC is implemented as local code. These 2 DMACs are never shared. We can use union for these. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/sh/rcar/dma.c40
-rw-r--r--sound/soc/sh/rcar/rsnd.h16
2 files changed, 39 insertions, 17 deletions
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 3f1ea58ee144..b449763ebd43 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -76,11 +76,14 @@ static void rsnd_dmaen_of_name(struct rsnd_mod *mod_from,
76 76
77static void rsnd_dmaen_stop(struct rsnd_dma *dma) 77static void rsnd_dmaen_stop(struct rsnd_dma *dma)
78{ 78{
79 dmaengine_terminate_all(dma->chan); 79 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
80
81 dmaengine_terminate_all(dmaen->chan);
80} 82}
81 83
82static void rsnd_dmaen_start(struct rsnd_dma *dma) 84static void rsnd_dmaen_start(struct rsnd_dma *dma)
83{ 85{
86 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
84 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 87 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
85 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 88 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
86 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 89 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
@@ -89,7 +92,7 @@ static void rsnd_dmaen_start(struct rsnd_dma *dma)
89 struct dma_async_tx_descriptor *desc; 92 struct dma_async_tx_descriptor *desc;
90 int is_play = rsnd_io_is_play(io); 93 int is_play = rsnd_io_is_play(io);
91 94
92 desc = dmaengine_prep_dma_cyclic(dma->chan, 95 desc = dmaengine_prep_dma_cyclic(dmaen->chan,
93 substream->runtime->dma_addr, 96 substream->runtime->dma_addr,
94 snd_pcm_lib_buffer_bytes(substream), 97 snd_pcm_lib_buffer_bytes(substream),
95 snd_pcm_lib_period_bytes(substream), 98 snd_pcm_lib_period_bytes(substream),
@@ -109,12 +112,13 @@ static void rsnd_dmaen_start(struct rsnd_dma *dma)
109 return; 112 return;
110 } 113 }
111 114
112 dma_async_issue_pending(dma->chan); 115 dma_async_issue_pending(dmaen->chan);
113} 116}
114 117
115static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, 118static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
116 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) 119 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
117{ 120{
121 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
118 struct device *dev = rsnd_priv_to_dev(priv); 122 struct device *dev = rsnd_priv_to_dev(priv);
119 struct dma_slave_config cfg = {}; 123 struct dma_slave_config cfg = {};
120 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 124 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
@@ -124,7 +128,7 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
124 dma_cap_mask_t mask; 128 dma_cap_mask_t mask;
125 int ret; 129 int ret;
126 130
127 if (dma->chan) { 131 if (dmaen->chan) {
128 dev_err(dev, "it already has dma channel\n"); 132 dev_err(dev, "it already has dma channel\n");
129 return -EIO; 133 return -EIO;
130 } 134 }
@@ -145,15 +149,15 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
145 dev_dbg(dev, "dma : %s %pad -> %pad\n", 149 dev_dbg(dev, "dma : %s %pad -> %pad\n",
146 dma_name, &cfg.src_addr, &cfg.dst_addr); 150 dma_name, &cfg.src_addr, &cfg.dst_addr);
147 151
148 dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, 152 dmaen->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
149 (void *)id, dev, 153 (void *)id, dev,
150 dma_name); 154 dma_name);
151 if (!dma->chan) { 155 if (!dmaen->chan) {
152 dev_err(dev, "can't get dma channel\n"); 156 dev_err(dev, "can't get dma channel\n");
153 goto rsnd_dma_channel_err; 157 goto rsnd_dma_channel_err;
154 } 158 }
155 159
156 ret = dmaengine_slave_config(dma->chan, &cfg); 160 ret = dmaengine_slave_config(dmaen->chan, &cfg);
157 if (ret < 0) 161 if (ret < 0)
158 goto rsnd_dma_init_err; 162 goto rsnd_dma_init_err;
159 163
@@ -174,10 +178,12 @@ rsnd_dma_channel_err:
174 178
175static void rsnd_dmaen_quit(struct rsnd_dma *dma) 179static void rsnd_dmaen_quit(struct rsnd_dma *dma)
176{ 180{
177 if (dma->chan) 181 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
178 dma_release_channel(dma->chan); 182
183 if (dmaen->chan)
184 dma_release_channel(dmaen->chan);
179 185
180 dma->chan = NULL; 186 dmaen->chan = NULL;
181} 187}
182 188
183static struct rsnd_dma_ops rsnd_dmaen_ops = { 189static struct rsnd_dma_ops rsnd_dmaen_ops = {
@@ -257,7 +263,8 @@ static u32 rsnd_dmapp_get_chcr(struct rsnd_mod *mod_from,
257} 263}
258 264
259#define rsnd_dmapp_addr(dmac, dma, reg) \ 265#define rsnd_dmapp_addr(dmac, dma, reg) \
260 (dmac->base + 0x20 + (0x10 * dma->dmapp_id) + reg) 266 (dmac->base + 0x20 + reg + \
267 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
261static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg) 268static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
262{ 269{
263 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 270 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
@@ -294,28 +301,31 @@ static void rsnd_dmapp_stop(struct rsnd_dma *dma)
294 301
295static void rsnd_dmapp_start(struct rsnd_dma *dma) 302static void rsnd_dmapp_start(struct rsnd_dma *dma)
296{ 303{
304 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
305
297 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR); 306 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR);
298 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR); 307 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR);
299 rsnd_dmapp_write(dma, dma->chcr, PDMACHCR); 308 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
300} 309}
301 310
302static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, 311static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
303 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) 312 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
304{ 313{
314 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
305 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); 315 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
306 struct device *dev = rsnd_priv_to_dev(priv); 316 struct device *dev = rsnd_priv_to_dev(priv);
307 317
308 dev_dbg(dev, "Audio DMAC peri peri init\n"); 318 dev_dbg(dev, "Audio DMAC peri peri init\n");
309 319
310 dma->dmapp_id = dmac->dmapp_num; 320 dmapp->dmapp_id = dmac->dmapp_num;
311 dma->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE; 321 dmapp->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE;
312 322
313 dmac->dmapp_num++; 323 dmac->dmapp_num++;
314 324
315 rsnd_dmapp_stop(dma); 325 rsnd_dmapp_stop(dma);
316 326
317 dev_dbg(dev, "id/src/dst/chcr = %d/%x/%x/%08x\n", 327 dev_dbg(dev, "id/src/dst/chcr = %d/%x/%x/%08x\n",
318 dma->dmapp_id, dma->src_addr, dma->dst_addr, dma->chcr); 328 dmapp->dmapp_id, dma->src_addr, dma->dst_addr, dmapp->chcr);
319 329
320 return 0; 330 return 0;
321} 331}
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 5d65a4b96743..0d36e38ebbcf 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -179,14 +179,26 @@ struct rsnd_dma_ops {
179 void (*quit)(struct rsnd_dma *dma); 179 void (*quit)(struct rsnd_dma *dma);
180}; 180};
181 181
182struct rsnd_dma { 182struct rsnd_dmaen {
183 struct dma_chan *chan; 183 struct dma_chan *chan;
184 struct rsnd_dma_ops *ops; 184};
185
186struct rsnd_dmapp {
185 int dmapp_id; 187 int dmapp_id;
186 u32 chcr; 188 u32 chcr;
189};
190
191struct rsnd_dma {
192 struct rsnd_dma_ops *ops;
187 dma_addr_t src_addr; 193 dma_addr_t src_addr;
188 dma_addr_t dst_addr; 194 dma_addr_t dst_addr;
195 union {
196 struct rsnd_dmaen en;
197 struct rsnd_dmapp pp;
198 } dma;
189}; 199};
200#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
201#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
190 202
191void rsnd_dma_start(struct rsnd_dma *dma); 203void rsnd_dma_start(struct rsnd_dma *dma);
192void rsnd_dma_stop(struct rsnd_dma *dma); 204void rsnd_dma_stop(struct rsnd_dma *dma);