2 * Generic TXx9 ACLC platform driver
4 * Copyright (C) 2009 Atsushi Nemoto
6 * Based on RBTX49xx patch from CELF patch archive.
7 * (C) Copyright TOSHIBA CORPORATION 2004-2006
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/platform_device.h>
17 #include <linux/scatterlist.h>
18 #include <linux/slab.h>
19 #include <linux/dmaengine.h>
20 #include <sound/core.h>
21 #include <sound/pcm.h>
22 #include <sound/pcm_params.h>
23 #include <sound/soc.h>
26 static struct txx9aclc_soc_device
{
27 struct txx9aclc_dmadata dmadata
[2];
28 } txx9aclc_soc_device
;
30 /* REVISIT: How to find txx9aclc_drvdata from snd_ac97? */
31 static struct txx9aclc_plat_drvdata
*txx9aclc_drvdata
;
33 static int txx9aclc_dma_init(struct txx9aclc_soc_device
*dev
,
34 struct txx9aclc_dmadata
*dmadata
);
36 static const struct snd_pcm_hardware txx9aclc_pcm_hardware
= {
38 * REVISIT: SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
39 * needs more works for noncoherent MIPS.
41 .info
= SNDRV_PCM_INFO_INTERLEAVED
|
42 SNDRV_PCM_INFO_BATCH
|
44 .period_bytes_min
= 1024,
45 .period_bytes_max
= 8 * 1024,
48 .buffer_bytes_max
= 32 * 1024,
51 static int txx9aclc_pcm_hw_params(struct snd_pcm_substream
*substream
,
52 struct snd_pcm_hw_params
*params
)
54 struct snd_soc_pcm_runtime
*rtd
= snd_pcm_substream_chip(substream
);
55 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
56 struct txx9aclc_dmadata
*dmadata
= runtime
->private_data
;
59 ret
= snd_pcm_lib_malloc_pages(substream
, params_buffer_bytes(params
));
63 dev_dbg(rtd
->platform
->dev
,
64 "runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd "
65 "runtime->min_align %ld\n",
66 (unsigned long)runtime
->dma_area
,
67 (unsigned long)runtime
->dma_addr
, runtime
->dma_bytes
,
69 dev_dbg(rtd
->platform
->dev
,
70 "periods %d period_bytes %d stream %d\n",
71 params_periods(params
), params_period_bytes(params
),
74 dmadata
->substream
= substream
;
79 static int txx9aclc_pcm_hw_free(struct snd_pcm_substream
*substream
)
81 return snd_pcm_lib_free_pages(substream
);
84 static int txx9aclc_pcm_prepare(struct snd_pcm_substream
*substream
)
86 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
87 struct txx9aclc_dmadata
*dmadata
= runtime
->private_data
;
89 dmadata
->dma_addr
= runtime
->dma_addr
;
90 dmadata
->buffer_bytes
= snd_pcm_lib_buffer_bytes(substream
);
91 dmadata
->period_bytes
= snd_pcm_lib_period_bytes(substream
);
93 if (dmadata
->buffer_bytes
== dmadata
->period_bytes
) {
94 dmadata
->frag_bytes
= dmadata
->period_bytes
>> 1;
97 dmadata
->frag_bytes
= dmadata
->period_bytes
;
98 dmadata
->frags
= dmadata
->buffer_bytes
/ dmadata
->period_bytes
;
100 dmadata
->frag_count
= 0;
105 static void txx9aclc_dma_complete(void *arg
)
107 struct txx9aclc_dmadata
*dmadata
= arg
;
110 /* dma completion handler cannot submit new operations */
111 spin_lock_irqsave(&dmadata
->dma_lock
, flags
);
112 if (dmadata
->frag_count
>= 0) {
114 if (!WARN_ON(dmadata
->dmacount
< 0))
115 tasklet_schedule(&dmadata
->tasklet
);
117 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
120 static struct dma_async_tx_descriptor
*
121 txx9aclc_dma_submit(struct txx9aclc_dmadata
*dmadata
, dma_addr_t buf_dma_addr
)
123 struct dma_chan
*chan
= dmadata
->dma_chan
;
124 struct dma_async_tx_descriptor
*desc
;
125 struct scatterlist sg
;
127 sg_init_table(&sg
, 1);
128 sg_set_page(&sg
, pfn_to_page(PFN_DOWN(buf_dma_addr
)),
129 dmadata
->frag_bytes
, buf_dma_addr
& (PAGE_SIZE
- 1));
130 sg_dma_address(&sg
) = buf_dma_addr
;
131 desc
= dmaengine_prep_slave_sg(chan
, &sg
, 1,
132 dmadata
->substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
?
133 DMA_MEM_TO_DEV
: DMA_DEV_TO_MEM
,
134 DMA_PREP_INTERRUPT
| DMA_CTRL_ACK
);
136 dev_err(&chan
->dev
->device
, "cannot prepare slave dma\n");
139 desc
->callback
= txx9aclc_dma_complete
;
140 desc
->callback_param
= dmadata
;
141 dmaengine_submit(desc
);
145 #define NR_DMA_CHAIN 2
147 static void txx9aclc_dma_tasklet(unsigned long data
)
149 struct txx9aclc_dmadata
*dmadata
= (struct txx9aclc_dmadata
*)data
;
150 struct dma_chan
*chan
= dmadata
->dma_chan
;
151 struct dma_async_tx_descriptor
*desc
;
152 struct snd_pcm_substream
*substream
= dmadata
->substream
;
153 u32 ctlbit
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
?
154 ACCTL_AUDODMA
: ACCTL_AUDIDMA
;
158 spin_lock_irqsave(&dmadata
->dma_lock
, flags
);
159 if (dmadata
->frag_count
< 0) {
160 struct txx9aclc_plat_drvdata
*drvdata
= txx9aclc_drvdata
;
161 void __iomem
*base
= drvdata
->base
;
163 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
164 dmaengine_terminate_all(chan
);
166 for (i
= 0; i
< NR_DMA_CHAIN
; i
++) {
167 desc
= txx9aclc_dma_submit(dmadata
,
168 dmadata
->dma_addr
+ i
* dmadata
->frag_bytes
);
172 dmadata
->dmacount
= NR_DMA_CHAIN
;
173 dma_async_issue_pending(chan
);
174 spin_lock_irqsave(&dmadata
->dma_lock
, flags
);
175 __raw_writel(ctlbit
, base
+ ACCTLEN
);
176 dmadata
->frag_count
= NR_DMA_CHAIN
% dmadata
->frags
;
177 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
180 if (WARN_ON(dmadata
->dmacount
>= NR_DMA_CHAIN
)) {
181 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
184 while (dmadata
->dmacount
< NR_DMA_CHAIN
) {
186 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
187 desc
= txx9aclc_dma_submit(dmadata
,
189 dmadata
->frag_count
* dmadata
->frag_bytes
);
192 dma_async_issue_pending(chan
);
194 spin_lock_irqsave(&dmadata
->dma_lock
, flags
);
195 dmadata
->frag_count
++;
196 dmadata
->frag_count
%= dmadata
->frags
;
197 dmadata
->pos
+= dmadata
->frag_bytes
;
198 dmadata
->pos
%= dmadata
->buffer_bytes
;
199 if ((dmadata
->frag_count
* dmadata
->frag_bytes
) %
200 dmadata
->period_bytes
== 0)
201 snd_pcm_period_elapsed(substream
);
203 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
206 static int txx9aclc_pcm_trigger(struct snd_pcm_substream
*substream
, int cmd
)
208 struct txx9aclc_dmadata
*dmadata
= substream
->runtime
->private_data
;
209 struct txx9aclc_plat_drvdata
*drvdata
= txx9aclc_drvdata
;
210 void __iomem
*base
= drvdata
->base
;
213 u32 ctlbit
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
?
214 ACCTL_AUDODMA
: ACCTL_AUDIDMA
;
216 spin_lock_irqsave(&dmadata
->dma_lock
, flags
);
218 case SNDRV_PCM_TRIGGER_START
:
219 dmadata
->frag_count
= -1;
220 tasklet_schedule(&dmadata
->tasklet
);
222 case SNDRV_PCM_TRIGGER_STOP
:
223 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
224 case SNDRV_PCM_TRIGGER_SUSPEND
:
225 __raw_writel(ctlbit
, base
+ ACCTLDIS
);
227 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
228 case SNDRV_PCM_TRIGGER_RESUME
:
229 __raw_writel(ctlbit
, base
+ ACCTLEN
);
234 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
238 static snd_pcm_uframes_t
239 txx9aclc_pcm_pointer(struct snd_pcm_substream
*substream
)
241 struct txx9aclc_dmadata
*dmadata
= substream
->runtime
->private_data
;
243 return bytes_to_frames(substream
->runtime
, dmadata
->pos
);
246 static int txx9aclc_pcm_open(struct snd_pcm_substream
*substream
)
248 struct txx9aclc_soc_device
*dev
= &txx9aclc_soc_device
;
249 struct txx9aclc_dmadata
*dmadata
= &dev
->dmadata
[substream
->stream
];
252 ret
= snd_soc_set_runtime_hwparams(substream
, &txx9aclc_pcm_hardware
);
255 /* ensure that buffer size is a multiple of period size */
256 ret
= snd_pcm_hw_constraint_integer(substream
->runtime
,
257 SNDRV_PCM_HW_PARAM_PERIODS
);
260 substream
->runtime
->private_data
= dmadata
;
264 static int txx9aclc_pcm_close(struct snd_pcm_substream
*substream
)
266 struct txx9aclc_dmadata
*dmadata
= substream
->runtime
->private_data
;
267 struct dma_chan
*chan
= dmadata
->dma_chan
;
269 dmadata
->frag_count
= -1;
270 dmaengine_terminate_all(chan
);
274 static const struct snd_pcm_ops txx9aclc_pcm_ops
= {
275 .open
= txx9aclc_pcm_open
,
276 .close
= txx9aclc_pcm_close
,
277 .ioctl
= snd_pcm_lib_ioctl
,
278 .hw_params
= txx9aclc_pcm_hw_params
,
279 .hw_free
= txx9aclc_pcm_hw_free
,
280 .prepare
= txx9aclc_pcm_prepare
,
281 .trigger
= txx9aclc_pcm_trigger
,
282 .pointer
= txx9aclc_pcm_pointer
,
285 static int txx9aclc_pcm_new(struct snd_soc_pcm_runtime
*rtd
)
287 struct snd_card
*card
= rtd
->card
->snd_card
;
288 struct snd_soc_dai
*dai
= rtd
->cpu_dai
;
289 struct snd_pcm
*pcm
= rtd
->pcm
;
290 struct platform_device
*pdev
= to_platform_device(rtd
->platform
->dev
);
291 struct txx9aclc_soc_device
*dev
;
296 /* at this point onwards the AC97 component has probed and this will be valid */
297 dev
= snd_soc_dai_get_drvdata(dai
);
299 dev
->dmadata
[0].stream
= SNDRV_PCM_STREAM_PLAYBACK
;
300 dev
->dmadata
[1].stream
= SNDRV_PCM_STREAM_CAPTURE
;
301 for (i
= 0; i
< 2; i
++) {
302 r
= platform_get_resource(pdev
, IORESOURCE_DMA
, i
);
307 dev
->dmadata
[i
].dma_res
= r
;
308 ret
= txx9aclc_dma_init(dev
, &dev
->dmadata
[i
]);
312 return snd_pcm_lib_preallocate_pages_for_all(pcm
, SNDRV_DMA_TYPE_DEV
,
313 card
->dev
, 64 * 1024, 4 * 1024 * 1024);
316 for (i
= 0; i
< 2; i
++) {
317 if (dev
->dmadata
[i
].dma_chan
)
318 dma_release_channel(dev
->dmadata
[i
].dma_chan
);
319 dev
->dmadata
[i
].dma_chan
= NULL
;
324 static bool filter(struct dma_chan
*chan
, void *param
)
326 struct txx9aclc_dmadata
*dmadata
= param
;
330 devname
= kasprintf(GFP_KERNEL
, "%s.%d", dmadata
->dma_res
->name
,
331 (int)dmadata
->dma_res
->start
);
332 if (strcmp(dev_name(chan
->device
->dev
), devname
) == 0) {
333 chan
->private = &dmadata
->dma_slave
;
340 static int txx9aclc_dma_init(struct txx9aclc_soc_device
*dev
,
341 struct txx9aclc_dmadata
*dmadata
)
343 struct txx9aclc_plat_drvdata
*drvdata
= txx9aclc_drvdata
;
344 struct txx9dmac_slave
*ds
= &dmadata
->dma_slave
;
347 spin_lock_init(&dmadata
->dma_lock
);
349 ds
->reg_width
= sizeof(u32
);
350 if (dmadata
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
351 ds
->tx_reg
= drvdata
->physbase
+ ACAUDODAT
;
355 ds
->rx_reg
= drvdata
->physbase
+ ACAUDIDAT
;
358 /* Try to grab a DMA channel */
360 dma_cap_set(DMA_SLAVE
, mask
);
361 dmadata
->dma_chan
= dma_request_channel(mask
, filter
, dmadata
);
362 if (!dmadata
->dma_chan
) {
364 "DMA channel for %s is not available\n",
365 dmadata
->stream
== SNDRV_PCM_STREAM_PLAYBACK
?
366 "playback" : "capture");
369 tasklet_init(&dmadata
->tasklet
, txx9aclc_dma_tasklet
,
370 (unsigned long)dmadata
);
374 static int txx9aclc_pcm_probe(struct snd_soc_platform
*platform
)
376 snd_soc_platform_set_drvdata(platform
, &txx9aclc_soc_device
);
380 static int txx9aclc_pcm_remove(struct snd_soc_platform
*platform
)
382 struct txx9aclc_soc_device
*dev
= snd_soc_platform_get_drvdata(platform
);
383 struct txx9aclc_plat_drvdata
*drvdata
= txx9aclc_drvdata
;
384 void __iomem
*base
= drvdata
->base
;
387 /* disable all FIFO DMAs */
388 __raw_writel(ACCTL_AUDODMA
| ACCTL_AUDIDMA
, base
+ ACCTLDIS
);
389 /* dummy R/W to clear pending DMAREQ if any */
390 __raw_writel(__raw_readl(base
+ ACAUDIDAT
), base
+ ACAUDODAT
);
392 for (i
= 0; i
< 2; i
++) {
393 struct txx9aclc_dmadata
*dmadata
= &dev
->dmadata
[i
];
394 struct dma_chan
*chan
= dmadata
->dma_chan
;
397 dmadata
->frag_count
= -1;
398 dmaengine_terminate_all(chan
);
399 dma_release_channel(chan
);
401 dev
->dmadata
[i
].dma_chan
= NULL
;
406 static const struct snd_soc_platform_driver txx9aclc_soc_platform
= {
407 .probe
= txx9aclc_pcm_probe
,
408 .remove
= txx9aclc_pcm_remove
,
409 .ops
= &txx9aclc_pcm_ops
,
410 .pcm_new
= txx9aclc_pcm_new
,
413 static int txx9aclc_soc_platform_probe(struct platform_device
*pdev
)
415 return devm_snd_soc_register_platform(&pdev
->dev
,
416 &txx9aclc_soc_platform
);
419 static struct platform_driver txx9aclc_pcm_driver
= {
421 .name
= "txx9aclc-pcm-audio",
424 .probe
= txx9aclc_soc_platform_probe
,
427 module_platform_driver(txx9aclc_pcm_driver
);
429 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
430 MODULE_DESCRIPTION("TXx9 ACLC Audio DMA driver");
431 MODULE_LICENSE("GPL");