2 * Renesas R-Car Audio DMAC support
4 * Copyright (C) 2015 Renesas Electronics Corp.
5 * Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 #include <linux/delay.h>
12 #include <linux/of_dma.h>
16 * Audio DMAC peri peri register
23 #define PDMACHCR_DE (1 << 0)
27 struct dma_chan
*chan
;
39 struct rsnd_mod
*mod_from
;
40 struct rsnd_mod
*mod_to
;
49 struct rsnd_dma_ctrl
{
55 #define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
56 #define rsnd_mod_to_dma(_mod) container_of((_mod), struct rsnd_dma, mod)
57 #define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
58 #define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
61 static struct rsnd_mod_ops mem_ops
= {
65 static struct rsnd_mod mem
= {
71 static void __rsnd_dmaen_complete(struct rsnd_mod
*mod
,
72 struct rsnd_dai_stream
*io
)
74 struct rsnd_priv
*priv
= rsnd_mod_to_priv(mod
);
79 * Renesas sound Gen1 needs 1 DMAC,
81 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
82 * But, Audio-DMAC-peri-peri doesn't have interrupt,
83 * and this driver is assuming that here.
85 spin_lock_irqsave(&priv
->lock
, flags
);
87 if (rsnd_io_is_working(io
))
90 spin_unlock_irqrestore(&priv
->lock
, flags
);
93 rsnd_dai_period_elapsed(io
);
96 static void rsnd_dmaen_complete(void *data
)
98 struct rsnd_mod
*mod
= data
;
100 rsnd_mod_interrupt(mod
, __rsnd_dmaen_complete
);
103 static struct dma_chan
*rsnd_dmaen_request_channel(struct rsnd_dai_stream
*io
,
104 struct rsnd_mod
*mod_from
,
105 struct rsnd_mod
*mod_to
)
107 if ((!mod_from
&& !mod_to
) ||
108 (mod_from
&& mod_to
))
112 return rsnd_mod_dma_req(io
, mod_from
);
114 return rsnd_mod_dma_req(io
, mod_to
);
117 static int rsnd_dmaen_stop(struct rsnd_mod
*mod
,
118 struct rsnd_dai_stream
*io
,
119 struct rsnd_priv
*priv
)
121 struct rsnd_dma
*dma
= rsnd_mod_to_dma(mod
);
122 struct rsnd_dmaen
*dmaen
= rsnd_dma_to_dmaen(dma
);
125 dmaengine_terminate_all(dmaen
->chan
);
130 static int rsnd_dmaen_nolock_stop(struct rsnd_mod
*mod
,
131 struct rsnd_dai_stream
*io
,
132 struct rsnd_priv
*priv
)
134 struct rsnd_dma
*dma
= rsnd_mod_to_dma(mod
);
135 struct rsnd_dmaen
*dmaen
= rsnd_dma_to_dmaen(dma
);
138 * DMAEngine release uses mutex lock.
139 * Thus, it shouldn't be called under spinlock.
140 * Let's call it under nolock_start
143 dma_release_channel(dmaen
->chan
);
150 static int rsnd_dmaen_nolock_start(struct rsnd_mod
*mod
,
151 struct rsnd_dai_stream
*io
,
152 struct rsnd_priv
*priv
)
154 struct rsnd_dma
*dma
= rsnd_mod_to_dma(mod
);
155 struct rsnd_dmaen
*dmaen
= rsnd_dma_to_dmaen(dma
);
156 struct device
*dev
= rsnd_priv_to_dev(priv
);
159 dev_err(dev
, "it already has dma channel\n");
164 * DMAEngine request uses mutex lock.
165 * Thus, it shouldn't be called under spinlock.
166 * Let's call it under nolock_start
168 dmaen
->chan
= rsnd_dmaen_request_channel(io
,
171 if (IS_ERR_OR_NULL(dmaen
->chan
)) {
173 dev_err(dev
, "can't get dma channel\n");
180 static int rsnd_dmaen_start(struct rsnd_mod
*mod
,
181 struct rsnd_dai_stream
*io
,
182 struct rsnd_priv
*priv
)
184 struct rsnd_dma
*dma
= rsnd_mod_to_dma(mod
);
185 struct rsnd_dmaen
*dmaen
= rsnd_dma_to_dmaen(dma
);
186 struct snd_pcm_substream
*substream
= io
->substream
;
187 struct device
*dev
= rsnd_priv_to_dev(priv
);
188 struct dma_async_tx_descriptor
*desc
;
189 struct dma_slave_config cfg
= {};
190 int is_play
= rsnd_io_is_play(io
);
193 cfg
.direction
= is_play
? DMA_MEM_TO_DEV
: DMA_DEV_TO_MEM
;
194 cfg
.src_addr
= dma
->src_addr
;
195 cfg
.dst_addr
= dma
->dst_addr
;
196 cfg
.src_addr_width
= DMA_SLAVE_BUSWIDTH_4_BYTES
;
197 cfg
.dst_addr_width
= DMA_SLAVE_BUSWIDTH_4_BYTES
;
199 dev_dbg(dev
, "%s[%d] %pad -> %pad\n",
200 rsnd_mod_name(mod
), rsnd_mod_id(mod
),
201 &cfg
.src_addr
, &cfg
.dst_addr
);
203 ret
= dmaengine_slave_config(dmaen
->chan
, &cfg
);
207 desc
= dmaengine_prep_dma_cyclic(dmaen
->chan
,
208 substream
->runtime
->dma_addr
,
209 snd_pcm_lib_buffer_bytes(substream
),
210 snd_pcm_lib_period_bytes(substream
),
211 is_play
? DMA_MEM_TO_DEV
: DMA_DEV_TO_MEM
,
212 DMA_PREP_INTERRUPT
| DMA_CTRL_ACK
);
215 dev_err(dev
, "dmaengine_prep_slave_sg() fail\n");
219 desc
->callback
= rsnd_dmaen_complete
;
220 desc
->callback_param
= rsnd_mod_get(dma
);
222 dmaen
->dma_len
= snd_pcm_lib_buffer_bytes(substream
);
224 dmaen
->cookie
= dmaengine_submit(desc
);
225 if (dmaen
->cookie
< 0) {
226 dev_err(dev
, "dmaengine_submit() fail\n");
230 dma_async_issue_pending(dmaen
->chan
);
235 struct dma_chan
*rsnd_dma_request_channel(struct device_node
*of_node
,
236 struct rsnd_mod
*mod
, char *name
)
238 struct dma_chan
*chan
= NULL
;
239 struct device_node
*np
;
242 for_each_child_of_node(of_node
, np
) {
243 if (i
== rsnd_mod_id(mod
) && (!chan
))
244 chan
= of_dma_request_slave_channel(np
, name
);
248 /* It should call of_node_put(), since, it is rsnd_xxx_of_node() */
249 of_node_put(of_node
);
254 static int rsnd_dmaen_attach(struct rsnd_dai_stream
*io
,
255 struct rsnd_dma
*dma
,
256 struct rsnd_mod
*mod_from
, struct rsnd_mod
*mod_to
)
258 struct rsnd_priv
*priv
= rsnd_io_to_priv(io
);
259 struct rsnd_dma_ctrl
*dmac
= rsnd_priv_to_dmac(priv
);
260 struct dma_chan
*chan
;
262 /* try to get DMAEngine channel */
263 chan
= rsnd_dmaen_request_channel(io
, mod_from
, mod_to
);
264 if (IS_ERR_OR_NULL(chan
)) {
266 * DMA failed. try to PIO mode
268 * rsnd_ssi_fallback()
269 * rsnd_rdai_continuance_probe()
274 dma_release_channel(chan
);
281 static int rsnd_dmaen_pointer(struct rsnd_mod
*mod
,
282 struct rsnd_dai_stream
*io
,
283 snd_pcm_uframes_t
*pointer
)
285 struct snd_pcm_runtime
*runtime
= rsnd_io_to_runtime(io
);
286 struct rsnd_dma
*dma
= rsnd_mod_to_dma(mod
);
287 struct rsnd_dmaen
*dmaen
= rsnd_dma_to_dmaen(dma
);
288 struct dma_tx_state state
;
289 enum dma_status status
;
290 unsigned int pos
= 0;
292 status
= dmaengine_tx_status(dmaen
->chan
, dmaen
->cookie
, &state
);
293 if (status
== DMA_IN_PROGRESS
|| status
== DMA_PAUSED
) {
294 if (state
.residue
> 0 && state
.residue
<= dmaen
->dma_len
)
295 pos
= dmaen
->dma_len
- state
.residue
;
297 *pointer
= bytes_to_frames(runtime
, pos
);
302 static struct rsnd_mod_ops rsnd_dmaen_ops
= {
304 .nolock_start
= rsnd_dmaen_nolock_start
,
305 .nolock_stop
= rsnd_dmaen_nolock_stop
,
306 .start
= rsnd_dmaen_start
,
307 .stop
= rsnd_dmaen_stop
,
308 .pointer
= rsnd_dmaen_pointer
,
312 * Audio DMAC peri peri
314 static const u8 gen2_id_table_ssiu
[] = {
326 static const u8 gen2_id_table_scu
[] = {
327 0x2d, /* SCU_SRCI0 */
328 0x2e, /* SCU_SRCI1 */
329 0x2f, /* SCU_SRCI2 */
330 0x30, /* SCU_SRCI3 */
331 0x31, /* SCU_SRCI4 */
332 0x32, /* SCU_SRCI5 */
333 0x33, /* SCU_SRCI6 */
334 0x34, /* SCU_SRCI7 */
335 0x35, /* SCU_SRCI8 */
336 0x36, /* SCU_SRCI9 */
338 static const u8 gen2_id_table_cmd
[] = {
343 static u32
rsnd_dmapp_get_id(struct rsnd_dai_stream
*io
,
344 struct rsnd_mod
*mod
)
346 struct rsnd_mod
*ssi
= rsnd_io_to_mod_ssi(io
);
347 struct rsnd_mod
*src
= rsnd_io_to_mod_src(io
);
348 struct rsnd_mod
*dvc
= rsnd_io_to_mod_dvc(io
);
349 const u8
*entry
= NULL
;
350 int id
= rsnd_mod_id(mod
);
354 entry
= gen2_id_table_ssiu
;
355 size
= ARRAY_SIZE(gen2_id_table_ssiu
);
356 } else if (mod
== src
) {
357 entry
= gen2_id_table_scu
;
358 size
= ARRAY_SIZE(gen2_id_table_scu
);
359 } else if (mod
== dvc
) {
360 entry
= gen2_id_table_cmd
;
361 size
= ARRAY_SIZE(gen2_id_table_cmd
);
364 if ((!entry
) || (size
<= id
)) {
365 struct device
*dev
= rsnd_priv_to_dev(rsnd_io_to_priv(io
));
367 dev_err(dev
, "unknown connection (%s[%d])\n",
368 rsnd_mod_name(mod
), rsnd_mod_id(mod
));
370 /* use non-prohibited SRS number as error */
371 return 0x00; /* SSI00 */
377 static u32
rsnd_dmapp_get_chcr(struct rsnd_dai_stream
*io
,
378 struct rsnd_mod
*mod_from
,
379 struct rsnd_mod
*mod_to
)
381 return (rsnd_dmapp_get_id(io
, mod_from
) << 24) +
382 (rsnd_dmapp_get_id(io
, mod_to
) << 16);
385 #define rsnd_dmapp_addr(dmac, dma, reg) \
386 (dmac->base + 0x20 + reg + \
387 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
388 static void rsnd_dmapp_write(struct rsnd_dma
*dma
, u32 data
, u32 reg
)
390 struct rsnd_mod
*mod
= rsnd_mod_get(dma
);
391 struct rsnd_priv
*priv
= rsnd_mod_to_priv(mod
);
392 struct rsnd_dma_ctrl
*dmac
= rsnd_priv_to_dmac(priv
);
393 struct device
*dev
= rsnd_priv_to_dev(priv
);
395 dev_dbg(dev
, "w %p : %08x\n", rsnd_dmapp_addr(dmac
, dma
, reg
), data
);
397 iowrite32(data
, rsnd_dmapp_addr(dmac
, dma
, reg
));
400 static u32
rsnd_dmapp_read(struct rsnd_dma
*dma
, u32 reg
)
402 struct rsnd_mod
*mod
= rsnd_mod_get(dma
);
403 struct rsnd_priv
*priv
= rsnd_mod_to_priv(mod
);
404 struct rsnd_dma_ctrl
*dmac
= rsnd_priv_to_dmac(priv
);
406 return ioread32(rsnd_dmapp_addr(dmac
, dma
, reg
));
409 static void rsnd_dmapp_bset(struct rsnd_dma
*dma
, u32 data
, u32 mask
, u32 reg
)
411 struct rsnd_mod
*mod
= rsnd_mod_get(dma
);
412 struct rsnd_priv
*priv
= rsnd_mod_to_priv(mod
);
413 struct rsnd_dma_ctrl
*dmac
= rsnd_priv_to_dmac(priv
);
414 void __iomem
*addr
= rsnd_dmapp_addr(dmac
, dma
, reg
);
415 u32 val
= ioread32(addr
);
418 val
|= (data
& mask
);
420 iowrite32(val
, addr
);
423 static int rsnd_dmapp_stop(struct rsnd_mod
*mod
,
424 struct rsnd_dai_stream
*io
,
425 struct rsnd_priv
*priv
)
427 struct rsnd_dma
*dma
= rsnd_mod_to_dma(mod
);
430 rsnd_dmapp_bset(dma
, 0, PDMACHCR_DE
, PDMACHCR
);
432 for (i
= 0; i
< 1024; i
++) {
433 if (0 == (rsnd_dmapp_read(dma
, PDMACHCR
) & PDMACHCR_DE
))
441 static int rsnd_dmapp_start(struct rsnd_mod
*mod
,
442 struct rsnd_dai_stream
*io
,
443 struct rsnd_priv
*priv
)
445 struct rsnd_dma
*dma
= rsnd_mod_to_dma(mod
);
446 struct rsnd_dmapp
*dmapp
= rsnd_dma_to_dmapp(dma
);
448 rsnd_dmapp_write(dma
, dma
->src_addr
, PDMASAR
);
449 rsnd_dmapp_write(dma
, dma
->dst_addr
, PDMADAR
);
450 rsnd_dmapp_write(dma
, dmapp
->chcr
, PDMACHCR
);
455 static int rsnd_dmapp_attach(struct rsnd_dai_stream
*io
,
456 struct rsnd_dma
*dma
,
457 struct rsnd_mod
*mod_from
, struct rsnd_mod
*mod_to
)
459 struct rsnd_dmapp
*dmapp
= rsnd_dma_to_dmapp(dma
);
460 struct rsnd_priv
*priv
= rsnd_io_to_priv(io
);
461 struct rsnd_dma_ctrl
*dmac
= rsnd_priv_to_dmac(priv
);
462 struct device
*dev
= rsnd_priv_to_dev(priv
);
464 dmapp
->dmapp_id
= dmac
->dmapp_num
;
465 dmapp
->chcr
= rsnd_dmapp_get_chcr(io
, mod_from
, mod_to
) | PDMACHCR_DE
;
469 dev_dbg(dev
, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
470 dmapp
->dmapp_id
, &dma
->src_addr
, &dma
->dst_addr
, dmapp
->chcr
);
475 static struct rsnd_mod_ops rsnd_dmapp_ops
= {
477 .start
= rsnd_dmapp_start
,
478 .stop
= rsnd_dmapp_stop
,
479 .quit
= rsnd_dmapp_stop
,
483 * Common DMAC Interface
487 * DMA read/write register offset
489 * RSND_xxx_I_N for Audio DMAC input
490 * RSND_xxx_O_N for Audio DMAC output
491 * RSND_xxx_I_P for Audio DMAC peri peri input
492 * RSND_xxx_O_P for Audio DMAC peri peri output
495 * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
496 * SSI : 0xec541000 / 0xec241008 / 0xec24100c
497 * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
498 * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
499 * CMD : 0xec500000 / / 0xec008000 0xec308000
501 #define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
502 #define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
504 #define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
505 #define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
507 #define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
508 #define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
510 #define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
511 #define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))
513 #define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
514 #define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))
516 #define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
517 #define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
520 rsnd_gen2_dma_addr(struct rsnd_dai_stream
*io
,
521 struct rsnd_mod
*mod
,
522 int is_play
, int is_from
)
524 struct rsnd_priv
*priv
= rsnd_io_to_priv(io
);
525 struct device
*dev
= rsnd_priv_to_dev(priv
);
526 phys_addr_t ssi_reg
= rsnd_gen_get_phy_addr(priv
, RSND_GEN2_SSI
);
527 phys_addr_t src_reg
= rsnd_gen_get_phy_addr(priv
, RSND_GEN2_SCU
);
528 int is_ssi
= !!(rsnd_io_to_mod_ssi(io
) == mod
);
529 int use_src
= !!rsnd_io_to_mod_src(io
);
530 int use_cmd
= !!rsnd_io_to_mod_dvc(io
) ||
531 !!rsnd_io_to_mod_mix(io
) ||
532 !!rsnd_io_to_mod_ctu(io
);
533 int id
= rsnd_mod_id(mod
);
537 } dma_addrs
[3][2][3] = {
541 { RDMA_SRC_O_N(src
, id
), RDMA_SRC_I_P(src
, id
) },
542 { RDMA_CMD_O_N(src
, id
), RDMA_SRC_I_P(src
, id
) } },
545 { RDMA_SRC_O_P(src
, id
), RDMA_SRC_I_N(src
, id
) },
546 { RDMA_CMD_O_P(src
, id
), RDMA_SRC_I_N(src
, id
) } }
550 {{{ RDMA_SSI_O_N(ssi
, id
), 0 },
551 { RDMA_SSIU_O_P(ssi
, id
), 0 },
552 { RDMA_SSIU_O_P(ssi
, id
), 0 } },
554 {{ 0, RDMA_SSI_I_N(ssi
, id
) },
555 { 0, RDMA_SSIU_I_P(ssi
, id
) },
556 { 0, RDMA_SSIU_I_P(ssi
, id
) } }
560 {{{ RDMA_SSIU_O_N(ssi
, id
), 0 },
561 { RDMA_SSIU_O_P(ssi
, id
), 0 },
562 { RDMA_SSIU_O_P(ssi
, id
), 0 } },
564 {{ 0, RDMA_SSIU_I_N(ssi
, id
) },
565 { 0, RDMA_SSIU_I_P(ssi
, id
) },
566 { 0, RDMA_SSIU_I_P(ssi
, id
) } } },
569 /* it shouldn't happen */
570 if (use_cmd
&& !use_src
)
571 dev_err(dev
, "DVC is selected without SRC\n");
573 /* use SSIU or SSI ? */
574 if (is_ssi
&& rsnd_ssi_use_busif(io
))
578 dma_addrs
[is_ssi
][is_play
][use_src
+ use_cmd
].out_addr
:
579 dma_addrs
[is_ssi
][is_play
][use_src
+ use_cmd
].in_addr
;
582 static dma_addr_t
rsnd_dma_addr(struct rsnd_dai_stream
*io
,
583 struct rsnd_mod
*mod
,
584 int is_play
, int is_from
)
586 struct rsnd_priv
*priv
= rsnd_io_to_priv(io
);
589 * gen1 uses default DMA addr
591 if (rsnd_is_gen1(priv
))
597 return rsnd_gen2_dma_addr(io
, mod
, is_play
, is_from
);
600 #define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
601 static void rsnd_dma_of_path(struct rsnd_mod
*this,
602 struct rsnd_dai_stream
*io
,
604 struct rsnd_mod
**mod_from
,
605 struct rsnd_mod
**mod_to
)
607 struct rsnd_mod
*ssi
= rsnd_io_to_mod_ssi(io
);
608 struct rsnd_mod
*src
= rsnd_io_to_mod_src(io
);
609 struct rsnd_mod
*ctu
= rsnd_io_to_mod_ctu(io
);
610 struct rsnd_mod
*mix
= rsnd_io_to_mod_mix(io
);
611 struct rsnd_mod
*dvc
= rsnd_io_to_mod_dvc(io
);
612 struct rsnd_mod
*mod
[MOD_MAX
];
613 struct rsnd_mod
*mod_start
, *mod_end
;
614 struct rsnd_priv
*priv
= rsnd_mod_to_priv(this);
615 struct device
*dev
= rsnd_priv_to_dev(priv
);
622 for (i
= 0; i
< MOD_MAX
; i
++) {
624 nr
+= !!rsnd_io_to_mod(io
, i
);
629 * [S] -*-> SRC -o-> [E]
630 * [S] -*-> SRC -> DVC -o-> [E]
631 * [S] -*-> SRC -> CTU -> MIX -> DVC -o-> [E]
640 * -o-> Audio DMAC peri peri
642 mod_start
= (is_play
) ? NULL
: ssi
;
643 mod_end
= (is_play
) ? ssi
: NULL
;
646 mod
[idx
++] = mod_start
;
647 for (i
= 1; i
< nr
; i
++) {
666 * -------------+-----+-----+
670 if ((this == ssi
) == (is_play
)) {
671 *mod_from
= mod
[idx
- 1];
678 dev_dbg(dev
, "module connection (this is %s[%d])\n",
679 rsnd_mod_name(this), rsnd_mod_id(this));
680 for (i
= 0; i
<= idx
; i
++) {
681 dev_dbg(dev
, " %s[%d]%s\n",
682 rsnd_mod_name(mod
[i
] ? mod
[i
] : &mem
),
683 rsnd_mod_id (mod
[i
] ? mod
[i
] : &mem
),
684 (mod
[i
] == *mod_from
) ? " from" :
685 (mod
[i
] == *mod_to
) ? " to" : "");
689 static int rsnd_dma_alloc(struct rsnd_dai_stream
*io
, struct rsnd_mod
*mod
,
690 struct rsnd_mod
**dma_mod
)
692 struct rsnd_mod
*mod_from
= NULL
;
693 struct rsnd_mod
*mod_to
= NULL
;
694 struct rsnd_priv
*priv
= rsnd_io_to_priv(io
);
695 struct rsnd_dma_ctrl
*dmac
= rsnd_priv_to_dmac(priv
);
696 struct device
*dev
= rsnd_priv_to_dev(priv
);
697 struct rsnd_dma
*dma
;
698 struct rsnd_mod_ops
*ops
;
699 enum rsnd_mod_type type
;
700 int (*attach
)(struct rsnd_dai_stream
*io
, struct rsnd_dma
*dma
,
701 struct rsnd_mod
*mod_from
, struct rsnd_mod
*mod_to
);
702 int is_play
= rsnd_io_is_play(io
);
706 * DMA failed. try to PIO mode
708 * rsnd_ssi_fallback()
709 * rsnd_rdai_continuance_probe()
714 rsnd_dma_of_path(mod
, io
, is_play
, &mod_from
, &mod_to
);
717 if (mod_from
&& mod_to
) {
718 ops
= &rsnd_dmapp_ops
;
719 attach
= rsnd_dmapp_attach
;
720 dma_id
= dmac
->dmapp_num
;
721 type
= RSND_MOD_AUDMAPP
;
723 ops
= &rsnd_dmaen_ops
;
724 attach
= rsnd_dmaen_attach
;
725 dma_id
= dmac
->dmaen_num
;
726 type
= RSND_MOD_AUDMA
;
729 /* for Gen1, overwrite */
730 if (rsnd_is_gen1(priv
)) {
731 ops
= &rsnd_dmaen_ops
;
732 attach
= rsnd_dmaen_attach
;
733 dma_id
= dmac
->dmaen_num
;
734 type
= RSND_MOD_AUDMA
;
737 dma
= devm_kzalloc(dev
, sizeof(*dma
), GFP_KERNEL
);
741 *dma_mod
= rsnd_mod_get(dma
);
743 ret
= rsnd_mod_init(priv
, *dma_mod
, ops
, NULL
,
744 rsnd_mod_get_status
, type
, dma_id
);
748 dev_dbg(dev
, "%s[%d] %s[%d] -> %s[%d]\n",
749 rsnd_mod_name(*dma_mod
), rsnd_mod_id(*dma_mod
),
750 rsnd_mod_name(mod_from
? mod_from
: &mem
),
751 rsnd_mod_id (mod_from
? mod_from
: &mem
),
752 rsnd_mod_name(mod_to
? mod_to
: &mem
),
753 rsnd_mod_id (mod_to
? mod_to
: &mem
));
755 ret
= attach(io
, dma
, mod_from
, mod_to
);
759 dma
->src_addr
= rsnd_dma_addr(io
, mod_from
, is_play
, 1);
760 dma
->dst_addr
= rsnd_dma_addr(io
, mod_to
, is_play
, 0);
761 dma
->mod_from
= mod_from
;
762 dma
->mod_to
= mod_to
;
767 int rsnd_dma_attach(struct rsnd_dai_stream
*io
, struct rsnd_mod
*mod
,
768 struct rsnd_mod
**dma_mod
)
771 int ret
= rsnd_dma_alloc(io
, mod
, dma_mod
);
777 return rsnd_dai_connect(*dma_mod
, io
, (*dma_mod
)->type
);
780 int rsnd_dma_probe(struct rsnd_priv
*priv
)
782 struct platform_device
*pdev
= rsnd_priv_to_pdev(priv
);
783 struct device
*dev
= rsnd_priv_to_dev(priv
);
784 struct rsnd_dma_ctrl
*dmac
;
785 struct resource
*res
;
790 if (rsnd_is_gen1(priv
))
796 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "audmapp");
797 dmac
= devm_kzalloc(dev
, sizeof(*dmac
), GFP_KERNEL
);
799 dev_err(dev
, "dma allocate failed\n");
800 return 0; /* it will be PIO mode */
804 dmac
->base
= devm_ioremap_resource(dev
, res
);
805 if (IS_ERR(dmac
->base
))
806 return PTR_ERR(dmac
->base
);
810 /* dummy mem mod for debug */
811 return rsnd_mod_init(NULL
, &mem
, &mem_ops
, NULL
, NULL
, 0, 0);