2 * This is for Renesas R-Car Audio-DMAC-peri-peri.
4 * Copyright (C) 2014 Renesas Electronics Corporation
5 * Copyright (C) 2014 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7 * based on the drivers/dma/sh/shdma.c
9 * Copyright (C) 2011-2012 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
10 * Copyright (C) 2009 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
11 * Copyright (C) 2009 Renesas Solutions, Inc. All rights reserved.
12 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
14 * This is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
20 #include <linux/delay.h>
21 #include <linux/init.h>
22 #include <linux/module.h>
23 #include <linux/slab.h>
24 #include <linux/dmaengine.h>
25 #include <linux/platform_data/dma-rcar-audmapp.h>
26 #include <linux/platform_device.h>
27 #include <linux/shdma-base.h>
37 #define PDMACHCR_DE (1 << 0)
39 #define AUDMAPP_MAX_CHANNELS 29
41 /* Default MEMCPY transfer size = 2^2 = 4 bytes */
42 #define LOG2_DEFAULT_XFER_SIZE 2
43 #define AUDMAPP_SLAVE_NUMBER 256
44 #define AUDMAPP_LEN_MAX (16 * 1024 * 1024)
47 struct shdma_chan shdma_chan
;
48 struct audmapp_slave_config
*config
;
52 struct audmapp_device
{
53 struct shdma_dev shdma_dev
;
54 struct audmapp_pdata
*pdata
;
56 void __iomem
*chan_reg
;
59 #define to_chan(chan) container_of(chan, struct audmapp_chan, shdma_chan)
60 #define to_dev(chan) container_of(chan->shdma_chan.dma_chan.device, \
61 struct audmapp_device, shdma_dev.dma_dev)
63 static void audmapp_write(struct audmapp_chan
*auchan
, u32 data
, u32 reg
)
65 struct audmapp_device
*audev
= to_dev(auchan
);
66 struct device
*dev
= audev
->dev
;
68 dev_dbg(dev
, "w %p : %08x\n", auchan
->base
+ reg
, data
);
70 iowrite32(data
, auchan
->base
+ reg
);
73 static u32
audmapp_read(struct audmapp_chan
*auchan
, u32 reg
)
75 return ioread32(auchan
->base
+ reg
);
78 static void audmapp_halt(struct shdma_chan
*schan
)
80 struct audmapp_chan
*auchan
= to_chan(schan
);
83 audmapp_write(auchan
, 0, PDMACHCR
);
85 for (i
= 0; i
< 1024; i
++) {
86 if (0 == audmapp_read(auchan
, PDMACHCR
))
92 static void audmapp_start_xfer(struct shdma_chan
*schan
,
93 struct shdma_desc
*sdecs
)
95 struct audmapp_chan
*auchan
= to_chan(schan
);
96 struct audmapp_device
*audev
= to_dev(auchan
);
97 struct audmapp_slave_config
*cfg
= auchan
->config
;
98 struct device
*dev
= audev
->dev
;
99 u32 chcr
= cfg
->chcr
| PDMACHCR_DE
;
101 dev_dbg(dev
, "src/dst/chcr = %pad/%pad/%x\n",
102 &cfg
->src
, &cfg
->dst
, cfg
->chcr
);
104 audmapp_write(auchan
, cfg
->src
, PDMASAR
);
105 audmapp_write(auchan
, cfg
->dst
, PDMADAR
);
106 audmapp_write(auchan
, chcr
, PDMACHCR
);
109 static struct audmapp_slave_config
*
110 audmapp_find_slave(struct audmapp_chan
*auchan
, int slave_id
)
112 struct audmapp_device
*audev
= to_dev(auchan
);
113 struct audmapp_pdata
*pdata
= audev
->pdata
;
114 struct audmapp_slave_config
*cfg
;
117 if (slave_id
>= AUDMAPP_SLAVE_NUMBER
)
120 for (i
= 0, cfg
= pdata
->slave
; i
< pdata
->slave_num
; i
++, cfg
++)
121 if (cfg
->slave_id
== slave_id
)
127 static int audmapp_set_slave(struct shdma_chan
*schan
, int slave_id
,
128 dma_addr_t slave_addr
, bool try)
130 struct audmapp_chan
*auchan
= to_chan(schan
);
131 struct audmapp_slave_config
*cfg
=
132 audmapp_find_slave(auchan
, slave_id
);
139 auchan
->config
= cfg
;
144 static int audmapp_desc_setup(struct shdma_chan
*schan
,
145 struct shdma_desc
*sdecs
,
146 dma_addr_t src
, dma_addr_t dst
, size_t *len
)
148 struct audmapp_chan
*auchan
= to_chan(schan
);
149 struct audmapp_slave_config
*cfg
= auchan
->config
;
154 if (*len
> (size_t)AUDMAPP_LEN_MAX
)
155 *len
= (size_t)AUDMAPP_LEN_MAX
;
160 static void audmapp_setup_xfer(struct shdma_chan
*schan
,
165 static dma_addr_t
audmapp_slave_addr(struct shdma_chan
*schan
)
167 return 0; /* always fixed address */
170 static bool audmapp_channel_busy(struct shdma_chan
*schan
)
172 struct audmapp_chan
*auchan
= to_chan(schan
);
173 u32 chcr
= audmapp_read(auchan
, PDMACHCR
);
175 return chcr
& ~PDMACHCR_DE
;
178 static bool audmapp_desc_completed(struct shdma_chan
*schan
,
179 struct shdma_desc
*sdesc
)
184 static struct shdma_desc
*audmapp_embedded_desc(void *buf
, int i
)
186 return &((struct shdma_desc
*)buf
)[i
];
189 static const struct shdma_ops audmapp_shdma_ops
= {
190 .halt_channel
= audmapp_halt
,
191 .desc_setup
= audmapp_desc_setup
,
192 .set_slave
= audmapp_set_slave
,
193 .start_xfer
= audmapp_start_xfer
,
194 .embedded_desc
= audmapp_embedded_desc
,
195 .setup_xfer
= audmapp_setup_xfer
,
196 .slave_addr
= audmapp_slave_addr
,
197 .channel_busy
= audmapp_channel_busy
,
198 .desc_completed
= audmapp_desc_completed
,
201 static int audmapp_chan_probe(struct platform_device
*pdev
,
202 struct audmapp_device
*audev
, int id
)
204 struct shdma_dev
*sdev
= &audev
->shdma_dev
;
205 struct audmapp_chan
*auchan
;
206 struct shdma_chan
*schan
;
207 struct device
*dev
= audev
->dev
;
209 auchan
= devm_kzalloc(dev
, sizeof(*auchan
), GFP_KERNEL
);
213 schan
= &auchan
->shdma_chan
;
214 schan
->max_xfer_len
= AUDMAPP_LEN_MAX
;
216 shdma_chan_probe(sdev
, schan
, id
);
218 auchan
->base
= audev
->chan_reg
+ 0x20 + (0x10 * id
);
219 dev_dbg(dev
, "%02d : %p / %p", id
, auchan
->base
, audev
->chan_reg
);
224 static void audmapp_chan_remove(struct audmapp_device
*audev
)
226 struct dma_device
*dma_dev
= &audev
->shdma_dev
.dma_dev
;
227 struct shdma_chan
*schan
;
230 shdma_for_each_chan(schan
, &audev
->shdma_dev
, i
) {
232 shdma_chan_remove(schan
);
234 dma_dev
->chancnt
= 0;
237 static int audmapp_probe(struct platform_device
*pdev
)
239 struct audmapp_pdata
*pdata
= pdev
->dev
.platform_data
;
240 struct audmapp_device
*audev
;
241 struct shdma_dev
*sdev
;
242 struct dma_device
*dma_dev
;
243 struct resource
*res
;
249 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
251 audev
= devm_kzalloc(&pdev
->dev
, sizeof(*audev
), GFP_KERNEL
);
255 audev
->dev
= &pdev
->dev
;
256 audev
->pdata
= pdata
;
257 audev
->chan_reg
= devm_ioremap_resource(&pdev
->dev
, res
);
258 if (IS_ERR(audev
->chan_reg
))
259 return PTR_ERR(audev
->chan_reg
);
261 sdev
= &audev
->shdma_dev
;
262 sdev
->ops
= &audmapp_shdma_ops
;
263 sdev
->desc_size
= sizeof(struct shdma_desc
);
265 dma_dev
= &sdev
->dma_dev
;
266 dma_dev
->copy_align
= LOG2_DEFAULT_XFER_SIZE
;
267 dma_cap_set(DMA_SLAVE
, dma_dev
->cap_mask
);
269 err
= shdma_init(&pdev
->dev
, sdev
, AUDMAPP_MAX_CHANNELS
);
273 platform_set_drvdata(pdev
, audev
);
275 /* Create DMA Channel */
276 for (i
= 0; i
< AUDMAPP_MAX_CHANNELS
; i
++) {
277 err
= audmapp_chan_probe(pdev
, audev
, i
);
282 err
= dma_async_device_register(dma_dev
);
289 audmapp_chan_remove(audev
);
295 static int audmapp_remove(struct platform_device
*pdev
)
297 struct audmapp_device
*audev
= platform_get_drvdata(pdev
);
298 struct dma_device
*dma_dev
= &audev
->shdma_dev
.dma_dev
;
300 dma_async_device_unregister(dma_dev
);
302 audmapp_chan_remove(audev
);
303 shdma_cleanup(&audev
->shdma_dev
);
308 static struct platform_driver audmapp_driver
= {
309 .probe
= audmapp_probe
,
310 .remove
= audmapp_remove
,
312 .owner
= THIS_MODULE
,
313 .name
= "rcar-audmapp-engine",
316 module_platform_driver(audmapp_driver
);
318 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
319 MODULE_DESCRIPTION("Renesas R-Car Audio DMAC peri-peri driver");
320 MODULE_LICENSE("GPL");