diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2015-02-20 05:29:13 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-03-07 10:04:30 -0500 |
commit | 0d00a52182be985bfae67d407ee81fefe448a0fd (patch) | |
tree | d7bd4ac0adcab3d4c940e0e63f9753a23df8d8fc /sound | |
parent | aaf4fce019ecd55a2d93b6111525deeef300f751 (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.c | 40 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 16 |
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 | ||
77 | static void rsnd_dmaen_stop(struct rsnd_dma *dma) | 77 | static 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 | ||
82 | static void rsnd_dmaen_start(struct rsnd_dma *dma) | 84 | static 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 | ||
115 | static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | 118 | static 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 | ||
175 | static void rsnd_dmaen_quit(struct rsnd_dma *dma) | 179 | static 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 | ||
183 | static struct rsnd_dma_ops rsnd_dmaen_ops = { | 189 | static 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)) | ||
261 | static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg) | 268 | static 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 | ||
295 | static void rsnd_dmapp_start(struct rsnd_dma *dma) | 302 | static 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 | ||
302 | static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id, | 311 | static 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 | ||
182 | struct rsnd_dma { | 182 | struct rsnd_dmaen { |
183 | struct dma_chan *chan; | 183 | struct dma_chan *chan; |
184 | struct rsnd_dma_ops *ops; | 184 | }; |
185 | |||
186 | struct rsnd_dmapp { | ||
185 | int dmapp_id; | 187 | int dmapp_id; |
186 | u32 chcr; | 188 | u32 chcr; |
189 | }; | ||
190 | |||
191 | struct 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 | ||
191 | void rsnd_dma_start(struct rsnd_dma *dma); | 203 | void rsnd_dma_start(struct rsnd_dma *dma); |
192 | void rsnd_dma_stop(struct rsnd_dma *dma); | 204 | void rsnd_dma_stop(struct rsnd_dma *dma); |