diff options
| -rw-r--r-- | Documentation/devicetree/bindings/sound/renesas,rsnd.txt | 1 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/core.c | 80 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/ssi.c | 6 |
3 files changed, 86 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index a44e9179faf5..8346cab046cd 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt | |||
| @@ -20,6 +20,7 @@ Required properties: | |||
| 20 | SSI subnode properties: | 20 | SSI subnode properties: |
| 21 | - interrupts : Should contain SSI interrupt for PIO transfer | 21 | - interrupts : Should contain SSI interrupt for PIO transfer |
| 22 | - shared-pin : if shared clock pin | 22 | - shared-pin : if shared clock pin |
| 23 | - pio-transfer : use PIO transfer mode | ||
| 23 | 24 | ||
| 24 | SRC subnode properties: | 25 | SRC subnode properties: |
| 25 | no properties at this point | 26 | no properties at this point |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 073a29354c85..cddb76d7d965 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
| @@ -256,11 +256,81 @@ int rsnd_dma_available(struct rsnd_dma *dma) | |||
| 256 | return !!dma->chan; | 256 | return !!dma->chan; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | #define DMA_NAME_SIZE 16 | ||
| 260 | #define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ | ||
| 261 | static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) | ||
| 262 | { | ||
| 263 | if (mod) | ||
| 264 | return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d", | ||
| 265 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | ||
| 266 | else | ||
| 267 | return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem"); | ||
| 268 | |||
| 269 | } | ||
| 270 | |||
| 271 | static void rsnd_dma_of_name(struct rsnd_dma *dma, | ||
| 272 | int is_play, char *dma_name) | ||
| 273 | { | ||
| 274 | struct rsnd_mod *this = rsnd_dma_to_mod(dma); | ||
| 275 | struct rsnd_dai_stream *io = rsnd_mod_to_io(this); | ||
| 276 | struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); | ||
| 277 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); | ||
| 278 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); | ||
| 279 | struct rsnd_mod *mod[MOD_MAX]; | ||
| 280 | struct rsnd_mod *src_mod, *dst_mod; | ||
| 281 | int i, index; | ||
| 282 | |||
| 283 | |||
| 284 | for (i = 0; i < MOD_MAX; i++) | ||
| 285 | mod[i] = NULL; | ||
| 286 | |||
| 287 | /* | ||
| 288 | * in play case... | ||
| 289 | * | ||
| 290 | * src -> dst | ||
| 291 | * | ||
| 292 | * mem -> SSI | ||
| 293 | * mem -> SRC -> SSI | ||
| 294 | * mem -> SRC -> DVC -> SSI | ||
| 295 | */ | ||
| 296 | mod[0] = NULL; /* for "mem" */ | ||
| 297 | index = 1; | ||
| 298 | for (i = 1; i < MOD_MAX; i++) { | ||
| 299 | if (!src) { | ||
| 300 | mod[i] = ssi; | ||
| 301 | break; | ||
| 302 | } else if (!dvc) { | ||
| 303 | mod[i] = src; | ||
| 304 | src = NULL; | ||
| 305 | } else { | ||
| 306 | mod[i] = dvc; | ||
| 307 | dvc = NULL; | ||
| 308 | } | ||
| 309 | |||
| 310 | if (mod[i] == this) | ||
| 311 | index = i; | ||
| 312 | } | ||
| 313 | |||
| 314 | if (is_play) { | ||
| 315 | src_mod = mod[index - 1]; | ||
| 316 | dst_mod = mod[index]; | ||
| 317 | } else { | ||
| 318 | src_mod = mod[index]; | ||
| 319 | dst_mod = mod[index + 1]; | ||
| 320 | } | ||
| 321 | |||
| 322 | index = 0; | ||
| 323 | index = _rsnd_dma_of_name(dma_name + index, src_mod); | ||
| 324 | *(dma_name + index++) = '_'; | ||
| 325 | index = _rsnd_dma_of_name(dma_name + index, dst_mod); | ||
| 326 | } | ||
| 327 | |||
| 259 | int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, | 328 | int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, |
| 260 | int is_play, int id) | 329 | int is_play, int id) |
| 261 | { | 330 | { |
| 262 | struct device *dev = rsnd_priv_to_dev(priv); | 331 | struct device *dev = rsnd_priv_to_dev(priv); |
| 263 | struct dma_slave_config cfg; | 332 | struct dma_slave_config cfg; |
| 333 | char dma_name[DMA_NAME_SIZE]; | ||
| 264 | dma_cap_mask_t mask; | 334 | dma_cap_mask_t mask; |
| 265 | int ret; | 335 | int ret; |
| 266 | 336 | ||
| @@ -272,9 +342,17 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, | |||
| 272 | dma_cap_zero(mask); | 342 | dma_cap_zero(mask); |
| 273 | dma_cap_set(DMA_SLAVE, mask); | 343 | dma_cap_set(DMA_SLAVE, mask); |
| 274 | 344 | ||
| 345 | if (dev->of_node) | ||
| 346 | rsnd_dma_of_name(dma, is_play, dma_name); | ||
| 347 | else | ||
| 348 | snprintf(dma_name, DMA_NAME_SIZE, | ||
| 349 | is_play ? "tx" : "rx"); | ||
| 350 | |||
| 351 | dev_dbg(dev, "dma name : %s\n", dma_name); | ||
| 352 | |||
| 275 | dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, | 353 | dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, |
| 276 | (void *)id, dev, | 354 | (void *)id, dev, |
| 277 | is_play ? "tx" : "rx"); | 355 | dma_name); |
| 278 | if (!dma->chan) { | 356 | if (!dma->chan) { |
| 279 | dev_err(dev, "can't get dma channel\n"); | 357 | dev_err(dev, "can't get dma channel\n"); |
| 280 | return -EIO; | 358 | return -EIO; |
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 2d94a62a6577..e0a4ba7271e7 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
| @@ -589,6 +589,12 @@ static void rsnd_of_parse_ssi(struct platform_device *pdev, | |||
| 589 | * irq | 589 | * irq |
| 590 | */ | 590 | */ |
| 591 | ssi_info->pio_irq = irq_of_parse_and_map(np, 0); | 591 | ssi_info->pio_irq = irq_of_parse_and_map(np, 0); |
| 592 | |||
| 593 | /* | ||
| 594 | * DMA | ||
| 595 | */ | ||
| 596 | ssi_info->dma_id = of_get_property(np, "pio-transfer", NULL) ? | ||
| 597 | 0 : 1; | ||
| 592 | } | 598 | } |
| 593 | 599 | ||
| 594 | rsnd_of_parse_ssi_end: | 600 | rsnd_of_parse_ssi_end: |
