aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2015-02-20 05:27:12 -0500
committerMark Brown <broonie@kernel.org>2015-03-07 10:04:29 -0500
commit3c68565b6cb68b731b51eb21b59dce901002fc6e (patch)
treedf035445cb5cf2f5ea35af246e19154ee9af22a5 /sound
parent747c71b12ee8357e73a88eb25f569e2a20e80df3 (diff)
ASoC: rsnd: enable to care 1st / 2nd DMAC on rsnd_dma_xxx()
rsnd driver needs to care about Audio DAMC (via DMAEngine), Audio DMAC peri peri (via local method) on rsnd driver. This patch adds new rsnd_dma_ops and care it. 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.c78
-rw-r--r--sound/soc/sh/rcar/rsnd.h12
2 files changed, 65 insertions, 25 deletions
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 188b4634939c..c911c079fdd0 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -10,7 +10,7 @@
10 */ 10 */
11#include "rsnd.h" 11#include "rsnd.h"
12 12
13static void rsnd_dma_complete(void *data) 13static void rsnd_dmaen_complete(void *data)
14{ 14{
15 struct rsnd_dma *dma = (struct rsnd_dma *)data; 15 struct rsnd_dma *dma = (struct rsnd_dma *)data;
16 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 16 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
@@ -32,7 +32,7 @@ static void rsnd_dma_complete(void *data)
32} 32}
33 33
34#define DMA_NAME_SIZE 16 34#define DMA_NAME_SIZE 16
35static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) 35static int _rsnd_dmaen_of_name(char *dma_name, struct rsnd_mod *mod)
36{ 36{
37 if (mod) 37 if (mod)
38 return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d", 38 return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d",
@@ -42,23 +42,23 @@ static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod)
42 42
43} 43}
44 44
45static void rsnd_dma_of_name(struct rsnd_mod *mod_from, 45static void rsnd_dmaen_of_name(struct rsnd_mod *mod_from,
46 struct rsnd_mod *mod_to, 46 struct rsnd_mod *mod_to,
47 char *dma_name) 47 char *dma_name)
48{ 48{
49 int index = 0; 49 int index = 0;
50 50
51 index = _rsnd_dma_of_name(dma_name + index, mod_from); 51 index = _rsnd_dmaen_of_name(dma_name + index, mod_from);
52 *(dma_name + index++) = '_'; 52 *(dma_name + index++) = '_';
53 index = _rsnd_dma_of_name(dma_name + index, mod_to); 53 index = _rsnd_dmaen_of_name(dma_name + index, mod_to);
54} 54}
55 55
56void rsnd_dma_stop(struct rsnd_dma *dma) 56static void rsnd_dmaen_stop(struct rsnd_dma *dma)
57{ 57{
58 dmaengine_terminate_all(dma->chan); 58 dmaengine_terminate_all(dma->chan);
59} 59}
60 60
61void rsnd_dma_start(struct rsnd_dma *dma) 61static void rsnd_dmaen_start(struct rsnd_dma *dma)
62{ 62{
63 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 63 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
64 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 64 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
@@ -80,7 +80,7 @@ void rsnd_dma_start(struct rsnd_dma *dma)
80 return; 80 return;
81 } 81 }
82 82
83 desc->callback = rsnd_dma_complete; 83 desc->callback = rsnd_dmaen_complete;
84 desc->callback_param = dma; 84 desc->callback_param = dma;
85 85
86 if (dmaengine_submit(desc) < 0) { 86 if (dmaengine_submit(desc) < 0) {
@@ -91,22 +91,12 @@ void rsnd_dma_start(struct rsnd_dma *dma)
91 dma_async_issue_pending(dma->chan); 91 dma_async_issue_pending(dma->chan);
92} 92}
93 93
94static void rsnd_dma_of_path(struct rsnd_dma *dma, 94static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
95 int is_play, 95 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
96 struct rsnd_mod **mod_from,
97 struct rsnd_mod **mod_to);
98
99static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv,
100 struct rsnd_mod *mod,
101 int is_play, int is_from);
102
103int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id)
104{ 96{
105 struct device *dev = rsnd_priv_to_dev(priv); 97 struct device *dev = rsnd_priv_to_dev(priv);
106 struct dma_slave_config cfg = {}; 98 struct dma_slave_config cfg = {};
107 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 99 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
108 struct rsnd_mod *mod_from;
109 struct rsnd_mod *mod_to;
110 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 100 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
111 int is_play = rsnd_io_is_play(io); 101 int is_play = rsnd_io_is_play(io);
112 char dma_name[DMA_NAME_SIZE]; 102 char dma_name[DMA_NAME_SIZE];
@@ -121,12 +111,11 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id)
121 dma_cap_zero(mask); 111 dma_cap_zero(mask);
122 dma_cap_set(DMA_SLAVE, mask); 112 dma_cap_set(DMA_SLAVE, mask);
123 113
124 rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to); 114 rsnd_dmaen_of_name(mod_from, mod_to, dma_name);
125 rsnd_dma_of_name(mod_from, mod_to, dma_name);
126 115
127 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; 116 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
128 cfg.src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1); 117 cfg.src_addr = dma->src_addr;
129 cfg.dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0); 118 cfg.dst_addr = dma->dst_addr;
130 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 119 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
131 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 120 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
132 121
@@ -163,7 +152,7 @@ rsnd_dma_channel_err:
163 return -EAGAIN; 152 return -EAGAIN;
164} 153}
165 154
166void rsnd_dma_quit(struct rsnd_dma *dma) 155static void rsnd_dmaen_quit(struct rsnd_dma *dma)
167{ 156{
168 if (dma->chan) 157 if (dma->chan)
169 dma_release_channel(dma->chan); 158 dma_release_channel(dma->chan);
@@ -171,6 +160,13 @@ void rsnd_dma_quit(struct rsnd_dma *dma)
171 dma->chan = NULL; 160 dma->chan = NULL;
172} 161}
173 162
163static struct rsnd_dma_ops rsnd_dmaen_ops = {
164 .start = rsnd_dmaen_start,
165 .stop = rsnd_dmaen_stop,
166 .init = rsnd_dmaen_init,
167 .quit = rsnd_dmaen_quit,
168};
169
174/* 170/*
175 * DMA read/write register offset 171 * DMA read/write register offset
176 * 172 *
@@ -343,3 +339,35 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
343 } 339 }
344} 340}
345 341
342void rsnd_dma_stop(struct rsnd_dma *dma)
343{
344 dma->ops->stop(dma);
345}
346
347void rsnd_dma_start(struct rsnd_dma *dma)
348{
349 dma->ops->start(dma);
350}
351
352void rsnd_dma_quit(struct rsnd_dma *dma)
353{
354 dma->ops->quit(dma);
355}
356
357int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id)
358{
359 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
360 struct rsnd_mod *mod_from;
361 struct rsnd_mod *mod_to;
362 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
363 int is_play = rsnd_io_is_play(io);
364
365 rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to);
366
367 dma->src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1);
368 dma->dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0);
369
370 dma->ops = &rsnd_dmaen_ops;
371
372 return dma->ops->init(priv, dma, id, mod_from, mod_to);
373}
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index a73e94c1d785..c7299f74cf83 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -170,10 +170,22 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod);
170/* 170/*
171 * R-Car DMA 171 * R-Car DMA
172 */ 172 */
173struct rsnd_dma;
174struct rsnd_dma_ops {
175 void (*start)(struct rsnd_dma *dma);
176 void (*stop)(struct rsnd_dma *dma);
177 int (*init)(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
178 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
179 void (*quit)(struct rsnd_dma *dma);
180};
181
173struct rsnd_dma { 182struct rsnd_dma {
174 struct dma_chan *chan; 183 struct dma_chan *chan;
184 struct rsnd_dma_ops *ops;
175 enum dma_transfer_direction dir; 185 enum dma_transfer_direction dir;
176 dma_addr_t addr; 186 dma_addr_t addr;
187 dma_addr_t src_addr;
188 dma_addr_t dst_addr;
177}; 189};
178 190
179void rsnd_dma_start(struct rsnd_dma *dma); 191void rsnd_dma_start(struct rsnd_dma *dma);