diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2015-02-20 05:27:12 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-03-07 10:04:29 -0500 |
commit | 3c68565b6cb68b731b51eb21b59dce901002fc6e (patch) | |
tree | df035445cb5cf2f5ea35af246e19154ee9af22a5 /sound | |
parent | 747c71b12ee8357e73a88eb25f569e2a20e80df3 (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.c | 78 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 12 |
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 | ||
13 | static void rsnd_dma_complete(void *data) | 13 | static 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 |
35 | static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) | 35 | static 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 | ||
45 | static void rsnd_dma_of_name(struct rsnd_mod *mod_from, | 45 | static 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 | ||
56 | void rsnd_dma_stop(struct rsnd_dma *dma) | 56 | static 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 | ||
61 | void rsnd_dma_start(struct rsnd_dma *dma) | 61 | static 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 | ||
94 | static void rsnd_dma_of_path(struct rsnd_dma *dma, | 94 | static 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 | |||
99 | static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv, | ||
100 | struct rsnd_mod *mod, | ||
101 | int is_play, int is_from); | ||
102 | |||
103 | int 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 | ||
166 | void rsnd_dma_quit(struct rsnd_dma *dma) | 155 | static 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 | ||
163 | static 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 | ||
342 | void rsnd_dma_stop(struct rsnd_dma *dma) | ||
343 | { | ||
344 | dma->ops->stop(dma); | ||
345 | } | ||
346 | |||
347 | void rsnd_dma_start(struct rsnd_dma *dma) | ||
348 | { | ||
349 | dma->ops->start(dma); | ||
350 | } | ||
351 | |||
352 | void rsnd_dma_quit(struct rsnd_dma *dma) | ||
353 | { | ||
354 | dma->ops->quit(dma); | ||
355 | } | ||
356 | |||
357 | int 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 | */ |
173 | struct rsnd_dma; | ||
174 | struct 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 | |||
173 | struct rsnd_dma { | 182 | struct 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 | ||
179 | void rsnd_dma_start(struct rsnd_dma *dma); | 191 | void rsnd_dma_start(struct rsnd_dma *dma); |