diff options
-rw-r--r-- | sound/soc/sh/rcar/core.c | 45 | ||||
-rw-r--r-- | sound/soc/sh/rcar/gen.c | 71 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 7 |
3 files changed, 64 insertions, 59 deletions
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 5149fe2dae9f..4435a31ecdad 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -239,8 +239,21 @@ static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) | |||
239 | 239 | ||
240 | } | 240 | } |
241 | 241 | ||
242 | static void rsnd_dma_of_name(struct rsnd_dma *dma, | 242 | static void rsnd_dma_of_name(struct rsnd_mod *mod_from, |
243 | int is_play, char *dma_name) | 243 | struct rsnd_mod *mod_to, |
244 | char *dma_name) | ||
245 | { | ||
246 | int index = 0; | ||
247 | |||
248 | index = _rsnd_dma_of_name(dma_name + index, mod_from); | ||
249 | *(dma_name + index++) = '_'; | ||
250 | index = _rsnd_dma_of_name(dma_name + index, mod_to); | ||
251 | } | ||
252 | |||
253 | static void rsnd_dma_of_path(struct rsnd_dma *dma, | ||
254 | int is_play, | ||
255 | struct rsnd_mod **mod_from, | ||
256 | struct rsnd_mod **mod_to) | ||
244 | { | 257 | { |
245 | struct rsnd_mod *this = rsnd_dma_to_mod(dma); | 258 | struct rsnd_mod *this = rsnd_dma_to_mod(dma); |
246 | struct rsnd_dai_stream *io = rsnd_mod_to_io(this); | 259 | struct rsnd_dai_stream *io = rsnd_mod_to_io(this); |
@@ -248,7 +261,6 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma, | |||
248 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); | 261 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); |
249 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); | 262 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); |
250 | struct rsnd_mod *mod[MOD_MAX]; | 263 | struct rsnd_mod *mod[MOD_MAX]; |
251 | struct rsnd_mod *src_mod, *dst_mod; | ||
252 | int i, index; | 264 | int i, index; |
253 | 265 | ||
254 | 266 | ||
@@ -285,17 +297,12 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma, | |||
285 | } | 297 | } |
286 | 298 | ||
287 | if (is_play) { | 299 | if (is_play) { |
288 | src_mod = mod[index - 1]; | 300 | *mod_from = mod[index - 1]; |
289 | dst_mod = mod[index]; | 301 | *mod_to = mod[index]; |
290 | } else { | 302 | } else { |
291 | src_mod = mod[index]; | 303 | *mod_from = mod[index]; |
292 | dst_mod = mod[index - 1]; | 304 | *mod_to = mod[index - 1]; |
293 | } | 305 | } |
294 | |||
295 | index = 0; | ||
296 | index = _rsnd_dma_of_name(dma_name + index, src_mod); | ||
297 | *(dma_name + index++) = '_'; | ||
298 | index = _rsnd_dma_of_name(dma_name + index, dst_mod); | ||
299 | } | 306 | } |
300 | 307 | ||
301 | int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, | 308 | int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, |
@@ -303,6 +310,8 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, | |||
303 | { | 310 | { |
304 | struct device *dev = rsnd_priv_to_dev(priv); | 311 | struct device *dev = rsnd_priv_to_dev(priv); |
305 | struct dma_slave_config cfg; | 312 | struct dma_slave_config cfg; |
313 | struct rsnd_mod *mod_from; | ||
314 | struct rsnd_mod *mod_to; | ||
306 | char dma_name[DMA_NAME_SIZE]; | 315 | char dma_name[DMA_NAME_SIZE]; |
307 | dma_cap_mask_t mask; | 316 | dma_cap_mask_t mask; |
308 | int ret; | 317 | int ret; |
@@ -315,10 +324,16 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, | |||
315 | dma_cap_zero(mask); | 324 | dma_cap_zero(mask); |
316 | dma_cap_set(DMA_SLAVE, mask); | 325 | dma_cap_set(DMA_SLAVE, mask); |
317 | 326 | ||
318 | rsnd_dma_of_name(dma, is_play, dma_name); | 327 | rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to); |
319 | rsnd_gen_dma_addr(priv, dma, &cfg, is_play, id); | 328 | rsnd_dma_of_name(mod_from, mod_to, dma_name); |
329 | |||
330 | cfg.slave_id = id; | ||
331 | cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; | ||
332 | cfg.src_addr = rsnd_gen_dma_addr(priv, mod_from, is_play, 1); | ||
333 | cfg.dst_addr = rsnd_gen_dma_addr(priv, mod_to, is_play, 0); | ||
320 | 334 | ||
321 | dev_dbg(dev, "dma name : %s\n", dma_name); | 335 | dev_dbg(dev, "dma : %s %pad -> %pad\n", |
336 | dma_name, &cfg.src_addr, &cfg.dst_addr); | ||
322 | 337 | ||
323 | dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, | 338 | dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, |
324 | (void *)id, dev, | 339 | (void *)id, dev, |
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 46677af6c748..73ce4c90efda 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c | |||
@@ -168,7 +168,7 @@ static int rsnd_gen_regmap_init(struct rsnd_priv *priv, | |||
168 | * SSI : 0xec541000 / 0xec241008 / 0xec24100c | 168 | * SSI : 0xec541000 / 0xec241008 / 0xec24100c |
169 | * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000 | 169 | * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000 |
170 | * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000 | 170 | * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000 |
171 | * CMD : 0xec500000 / 0xec008000 0xec308000 | 171 | * CMD : 0xec500000 / / 0xec008000 0xec308000 |
172 | */ | 172 | */ |
173 | #define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8) | 173 | #define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8) |
174 | #define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc) | 174 | #define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc) |
@@ -188,14 +188,13 @@ static int rsnd_gen_regmap_init(struct rsnd_priv *priv, | |||
188 | #define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i)) | 188 | #define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i)) |
189 | #define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) | 189 | #define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) |
190 | 190 | ||
191 | static void rsnd_gen2_dma_addr(struct rsnd_priv *priv, | 191 | static dma_addr_t |
192 | struct rsnd_dma *dma, | 192 | rsnd_gen2_dma_addr(struct rsnd_priv *priv, |
193 | struct dma_slave_config *cfg, | 193 | struct rsnd_mod *mod, |
194 | int is_play, int slave_id) | 194 | int is_play, int is_from) |
195 | { | 195 | { |
196 | struct platform_device *pdev = rsnd_priv_to_pdev(priv); | 196 | struct platform_device *pdev = rsnd_priv_to_pdev(priv); |
197 | struct device *dev = rsnd_priv_to_dev(priv); | 197 | struct device *dev = rsnd_priv_to_dev(priv); |
198 | struct rsnd_mod *mod = rsnd_dma_to_mod(dma); | ||
199 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 198 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
200 | dma_addr_t ssi_reg = platform_get_resource(pdev, | 199 | dma_addr_t ssi_reg = platform_get_resource(pdev, |
201 | IORESOURCE_MEM, RSND_GEN2_SSI)->start; | 200 | IORESOURCE_MEM, RSND_GEN2_SSI)->start; |
@@ -206,76 +205,68 @@ static void rsnd_gen2_dma_addr(struct rsnd_priv *priv, | |||
206 | int use_dvc = !!rsnd_io_to_mod_dvc(io); | 205 | int use_dvc = !!rsnd_io_to_mod_dvc(io); |
207 | int id = rsnd_mod_id(mod); | 206 | int id = rsnd_mod_id(mod); |
208 | struct dma_addr { | 207 | struct dma_addr { |
209 | dma_addr_t src_addr; | 208 | dma_addr_t out_addr; |
210 | dma_addr_t dst_addr; | 209 | dma_addr_t in_addr; |
211 | } dma_addrs[3][2][3] = { | 210 | } dma_addrs[3][2][3] = { |
212 | /* SRC */ | 211 | /* SRC */ |
213 | {{{ 0, 0 }, | 212 | {{{ 0, 0 }, |
214 | /* Capture */ | 213 | /* Capture */ |
215 | { RDMA_SRC_O_N(src, id), 0 }, | 214 | { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) }, |
216 | { RDMA_CMD_O_N(src, id), 0 } }, | 215 | { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } }, |
217 | /* Playback */ | 216 | /* Playback */ |
218 | {{ 0, 0, }, | 217 | {{ 0, 0, }, |
219 | { 0, RDMA_SRC_I_N(src, id) }, | 218 | { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) }, |
220 | { 0, RDMA_SRC_I_N(src, id) } } | 219 | { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } } |
221 | }, | 220 | }, |
222 | /* SSI */ | 221 | /* SSI */ |
223 | /* Capture */ | 222 | /* Capture */ |
224 | {{{ RDMA_SSI_O_N(ssi, id), 0 }, | 223 | {{{ RDMA_SSI_O_N(ssi, id), 0 }, |
225 | { 0, 0 }, | 224 | { RDMA_SSIU_O_P(ssi, id), 0 }, |
226 | { 0, 0 } }, | 225 | { RDMA_SSIU_O_P(ssi, id), 0 } }, |
227 | /* Playback */ | 226 | /* Playback */ |
228 | {{ 0, RDMA_SSI_I_N(ssi, id) }, | 227 | {{ 0, RDMA_SSI_I_N(ssi, id) }, |
229 | { 0, 0 }, | 228 | { 0, RDMA_SSIU_I_P(ssi, id) }, |
230 | { 0, 0 } } | 229 | { 0, RDMA_SSIU_I_P(ssi, id) } } |
231 | }, | 230 | }, |
232 | /* SSIU */ | 231 | /* SSIU */ |
233 | /* Capture */ | 232 | /* Capture */ |
234 | {{{ RDMA_SSIU_O_N(ssi, id), 0 }, | 233 | {{{ RDMA_SSIU_O_N(ssi, id), 0 }, |
235 | { RDMA_SSIU_O_P(ssi, id), RDMA_SRC_I_P(src, id) }, | 234 | { RDMA_SSIU_O_P(ssi, id), 0 }, |
236 | { RDMA_SSIU_O_P(ssi, id), RDMA_SRC_I_P(src, id) } }, | 235 | { RDMA_SSIU_O_P(ssi, id), 0 } }, |
237 | /* Playback */ | 236 | /* Playback */ |
238 | {{ 0, RDMA_SSIU_I_N(ssi, id) }, | 237 | {{ 0, RDMA_SSIU_I_N(ssi, id) }, |
239 | { RDMA_SRC_O_P(src, id), RDMA_SSIU_I_P(ssi, id) }, | 238 | { 0, RDMA_SSIU_I_P(ssi, id) }, |
240 | { RDMA_CMD_O_P(src, id), RDMA_SSIU_I_P(ssi, id) } } }, | 239 | { 0, RDMA_SSIU_I_P(ssi, id) } } }, |
241 | }; | 240 | }; |
242 | 241 | ||
243 | /* it shouldn't happen */ | 242 | /* it shouldn't happen */ |
244 | if (use_dvc & !use_src) { | 243 | if (use_dvc & !use_src) |
245 | dev_err(dev, "DVC is selected without SRC\n"); | 244 | dev_err(dev, "DVC is selected without SRC\n"); |
246 | return; | ||
247 | } | ||
248 | 245 | ||
249 | /* use SSIU or SSI ? */ | 246 | /* use SSIU or SSI ? */ |
250 | if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu"))) | 247 | if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu"))) |
251 | is_ssi++; | 248 | is_ssi++; |
252 | 249 | ||
253 | cfg->src_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].src_addr; | 250 | return (is_from) ? |
254 | cfg->dst_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].dst_addr; | 251 | dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr : |
255 | 252 | dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr; | |
256 | dev_dbg(dev, "dma%d addr - src : %x / dst : %x\n", | ||
257 | id, cfg->src_addr, cfg->dst_addr); | ||
258 | } | 253 | } |
259 | 254 | ||
260 | void rsnd_gen_dma_addr(struct rsnd_priv *priv, | 255 | dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv, |
261 | struct rsnd_dma *dma, | 256 | struct rsnd_mod *mod, |
262 | struct dma_slave_config *cfg, | 257 | int is_play, int is_from) |
263 | int is_play, int slave_id) | ||
264 | { | 258 | { |
265 | cfg->slave_id = slave_id; | ||
266 | cfg->src_addr = 0; | ||
267 | cfg->dst_addr = 0; | ||
268 | cfg->direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; | ||
269 | |||
270 | /* | 259 | /* |
271 | * gen1 uses default DMA addr | 260 | * gen1 uses default DMA addr |
272 | */ | 261 | */ |
273 | if (rsnd_is_gen1(priv)) | 262 | if (rsnd_is_gen1(priv)) |
274 | return; | 263 | return 0; |
275 | 264 | ||
276 | rsnd_gen2_dma_addr(priv, dma, cfg, is_play, slave_id); | 265 | if (!mod) |
277 | } | 266 | return 0; |
278 | 267 | ||
268 | return rsnd_gen2_dma_addr(priv, mod, is_play, is_from); | ||
269 | } | ||
279 | 270 | ||
280 | /* | 271 | /* |
281 | * Gen2 | 272 | * Gen2 |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 60b5e9260600..425b22ee6fb9 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -279,10 +279,9 @@ int rsnd_gen_probe(struct platform_device *pdev, | |||
279 | void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, | 279 | void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, |
280 | struct rsnd_mod *mod, | 280 | struct rsnd_mod *mod, |
281 | enum rsnd_reg reg); | 281 | enum rsnd_reg reg); |
282 | void rsnd_gen_dma_addr(struct rsnd_priv *priv, | 282 | dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv, |
283 | struct rsnd_dma *dma, | 283 | struct rsnd_mod *mod, |
284 | struct dma_slave_config *cfg, | 284 | int is_play, int is_from); |
285 | int is_play, int slave_id); | ||
286 | 285 | ||
287 | #define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1) | 286 | #define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1) |
288 | #define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2) | 287 | #define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2) |