1 // SPDX-License-Identifier: GPL-2.0-only
3 * Generic TXx9 ACLC platform driver
5 * Copyright (C) 2009 Atsushi Nemoto
7 * Based on RBTX49xx patch from CELF patch archive.
8 * (C) Copyright TOSHIBA CORPORATION 2004-2006
11 #include <linux/module.h>
12 #include <linux/init.h>
13 #include <linux/platform_device.h>
14 #include <linux/scatterlist.h>
15 #include <linux/slab.h>
16 #include <linux/dmaengine.h>
17 #include <sound/core.h>
18 #include <sound/pcm.h>
19 #include <sound/pcm_params.h>
20 #include <sound/soc.h>
23 #define DRV_NAME "txx9aclc"
25 static struct txx9aclc_soc_device
{
26 struct txx9aclc_dmadata dmadata
[2];
27 } txx9aclc_soc_device
;
29 /* REVISIT: How to find txx9aclc_drvdata from snd_ac97? */
30 static struct txx9aclc_plat_drvdata
*txx9aclc_drvdata
;
32 static int txx9aclc_dma_init(struct txx9aclc_soc_device
*dev
,
33 struct txx9aclc_dmadata
*dmadata
);
35 static const struct snd_pcm_hardware txx9aclc_pcm_hardware
= {
37 * REVISIT: SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
38 * needs more works for noncoherent MIPS.
40 .info
= SNDRV_PCM_INFO_INTERLEAVED
|
41 SNDRV_PCM_INFO_BATCH
|
43 .period_bytes_min
= 1024,
44 .period_bytes_max
= 8 * 1024,
47 .buffer_bytes_max
= 32 * 1024,
50 static int txx9aclc_pcm_hw_params(struct snd_soc_component
*component
,
51 struct snd_pcm_substream
*substream
,
52 struct snd_pcm_hw_params
*params
)
54 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
55 struct txx9aclc_dmadata
*dmadata
= runtime
->private_data
;
57 dev_dbg(component
->dev
,
58 "runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd "
59 "runtime->min_align %ld\n",
60 (unsigned long)runtime
->dma_area
,
61 (unsigned long)runtime
->dma_addr
, runtime
->dma_bytes
,
63 dev_dbg(component
->dev
,
64 "periods %d period_bytes %d stream %d\n",
65 params_periods(params
), params_period_bytes(params
),
68 dmadata
->substream
= substream
;
73 static int txx9aclc_pcm_prepare(struct snd_soc_component
*component
,
74 struct snd_pcm_substream
*substream
)
76 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
77 struct txx9aclc_dmadata
*dmadata
= runtime
->private_data
;
79 dmadata
->dma_addr
= runtime
->dma_addr
;
80 dmadata
->buffer_bytes
= snd_pcm_lib_buffer_bytes(substream
);
81 dmadata
->period_bytes
= snd_pcm_lib_period_bytes(substream
);
83 if (dmadata
->buffer_bytes
== dmadata
->period_bytes
) {
84 dmadata
->frag_bytes
= dmadata
->period_bytes
>> 1;
87 dmadata
->frag_bytes
= dmadata
->period_bytes
;
88 dmadata
->frags
= dmadata
->buffer_bytes
/ dmadata
->period_bytes
;
90 dmadata
->frag_count
= 0;
95 static void txx9aclc_dma_complete(void *arg
)
97 struct txx9aclc_dmadata
*dmadata
= arg
;
100 /* dma completion handler cannot submit new operations */
101 spin_lock_irqsave(&dmadata
->dma_lock
, flags
);
102 if (dmadata
->frag_count
>= 0) {
104 if (!WARN_ON(dmadata
->dmacount
< 0))
105 queue_work(system_highpri_wq
, &dmadata
->work
);
107 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
110 static struct dma_async_tx_descriptor
*
111 txx9aclc_dma_submit(struct txx9aclc_dmadata
*dmadata
, dma_addr_t buf_dma_addr
)
113 struct dma_chan
*chan
= dmadata
->dma_chan
;
114 struct dma_async_tx_descriptor
*desc
;
115 struct scatterlist sg
;
117 sg_init_table(&sg
, 1);
118 sg_set_page(&sg
, pfn_to_page(PFN_DOWN(buf_dma_addr
)),
119 dmadata
->frag_bytes
, buf_dma_addr
& (PAGE_SIZE
- 1));
120 sg_dma_address(&sg
) = buf_dma_addr
;
121 desc
= dmaengine_prep_slave_sg(chan
, &sg
, 1,
122 dmadata
->substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
?
123 DMA_MEM_TO_DEV
: DMA_DEV_TO_MEM
,
124 DMA_PREP_INTERRUPT
| DMA_CTRL_ACK
);
126 dev_err(&chan
->dev
->device
, "cannot prepare slave dma\n");
129 desc
->callback
= txx9aclc_dma_complete
;
130 desc
->callback_param
= dmadata
;
131 dmaengine_submit(desc
);
135 #define NR_DMA_CHAIN 2
137 static void txx9aclc_dma_work(struct work_struct
*work
)
139 struct txx9aclc_dmadata
*dmadata
=
140 container_of(work
, struct txx9aclc_dmadata
, work
);
141 struct dma_chan
*chan
= dmadata
->dma_chan
;
142 struct dma_async_tx_descriptor
*desc
;
143 struct snd_pcm_substream
*substream
= dmadata
->substream
;
144 u32 ctlbit
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
?
145 ACCTL_AUDODMA
: ACCTL_AUDIDMA
;
149 spin_lock_irqsave(&dmadata
->dma_lock
, flags
);
150 if (dmadata
->frag_count
< 0) {
151 struct txx9aclc_plat_drvdata
*drvdata
= txx9aclc_drvdata
;
152 void __iomem
*base
= drvdata
->base
;
154 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
155 dmaengine_terminate_all(chan
);
157 for (i
= 0; i
< NR_DMA_CHAIN
; i
++) {
158 desc
= txx9aclc_dma_submit(dmadata
,
159 dmadata
->dma_addr
+ i
* dmadata
->frag_bytes
);
163 dmadata
->dmacount
= NR_DMA_CHAIN
;
164 dma_async_issue_pending(chan
);
165 spin_lock_irqsave(&dmadata
->dma_lock
, flags
);
166 __raw_writel(ctlbit
, base
+ ACCTLEN
);
167 dmadata
->frag_count
= NR_DMA_CHAIN
% dmadata
->frags
;
168 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
171 if (WARN_ON(dmadata
->dmacount
>= NR_DMA_CHAIN
)) {
172 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
175 while (dmadata
->dmacount
< NR_DMA_CHAIN
) {
177 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
178 desc
= txx9aclc_dma_submit(dmadata
,
180 dmadata
->frag_count
* dmadata
->frag_bytes
);
183 dma_async_issue_pending(chan
);
185 spin_lock_irqsave(&dmadata
->dma_lock
, flags
);
186 dmadata
->frag_count
++;
187 dmadata
->frag_count
%= dmadata
->frags
;
188 dmadata
->pos
+= dmadata
->frag_bytes
;
189 dmadata
->pos
%= dmadata
->buffer_bytes
;
190 if ((dmadata
->frag_count
* dmadata
->frag_bytes
) %
191 dmadata
->period_bytes
== 0)
192 snd_pcm_period_elapsed(substream
);
194 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
197 static int txx9aclc_pcm_trigger(struct snd_soc_component
*component
,
198 struct snd_pcm_substream
*substream
, int cmd
)
200 struct txx9aclc_dmadata
*dmadata
= substream
->runtime
->private_data
;
201 struct txx9aclc_plat_drvdata
*drvdata
= txx9aclc_drvdata
;
202 void __iomem
*base
= drvdata
->base
;
205 u32 ctlbit
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
?
206 ACCTL_AUDODMA
: ACCTL_AUDIDMA
;
208 spin_lock_irqsave(&dmadata
->dma_lock
, flags
);
210 case SNDRV_PCM_TRIGGER_START
:
211 dmadata
->frag_count
= -1;
212 queue_work(system_highpri_wq
, &dmadata
->work
);
214 case SNDRV_PCM_TRIGGER_STOP
:
215 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
216 case SNDRV_PCM_TRIGGER_SUSPEND
:
217 __raw_writel(ctlbit
, base
+ ACCTLDIS
);
219 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
220 case SNDRV_PCM_TRIGGER_RESUME
:
221 __raw_writel(ctlbit
, base
+ ACCTLEN
);
226 spin_unlock_irqrestore(&dmadata
->dma_lock
, flags
);
230 static snd_pcm_uframes_t
231 txx9aclc_pcm_pointer(struct snd_soc_component
*component
,
232 struct snd_pcm_substream
*substream
)
234 struct txx9aclc_dmadata
*dmadata
= substream
->runtime
->private_data
;
236 return bytes_to_frames(substream
->runtime
, dmadata
->pos
);
239 static int txx9aclc_pcm_open(struct snd_soc_component
*component
,
240 struct snd_pcm_substream
*substream
)
242 struct txx9aclc_soc_device
*dev
= &txx9aclc_soc_device
;
243 struct txx9aclc_dmadata
*dmadata
= &dev
->dmadata
[substream
->stream
];
246 ret
= snd_soc_set_runtime_hwparams(substream
, &txx9aclc_pcm_hardware
);
249 /* ensure that buffer size is a multiple of period size */
250 ret
= snd_pcm_hw_constraint_integer(substream
->runtime
,
251 SNDRV_PCM_HW_PARAM_PERIODS
);
254 substream
->runtime
->private_data
= dmadata
;
258 static int txx9aclc_pcm_close(struct snd_soc_component
*component
,
259 struct snd_pcm_substream
*substream
)
261 struct txx9aclc_dmadata
*dmadata
= substream
->runtime
->private_data
;
262 struct dma_chan
*chan
= dmadata
->dma_chan
;
264 dmadata
->frag_count
= -1;
265 dmaengine_terminate_all(chan
);
269 static int txx9aclc_pcm_new(struct snd_soc_component
*component
,
270 struct snd_soc_pcm_runtime
*rtd
)
272 struct snd_card
*card
= rtd
->card
->snd_card
;
273 struct snd_soc_dai
*dai
= asoc_rtd_to_cpu(rtd
, 0);
274 struct snd_pcm
*pcm
= rtd
->pcm
;
275 struct platform_device
*pdev
= to_platform_device(component
->dev
);
276 struct txx9aclc_soc_device
*dev
;
281 /* at this point onwards the AC97 component has probed and this will be valid */
282 dev
= snd_soc_dai_get_drvdata(dai
);
284 dev
->dmadata
[0].stream
= SNDRV_PCM_STREAM_PLAYBACK
;
285 dev
->dmadata
[1].stream
= SNDRV_PCM_STREAM_CAPTURE
;
286 for (i
= 0; i
< 2; i
++) {
287 r
= platform_get_resource(pdev
, IORESOURCE_DMA
, i
);
292 dev
->dmadata
[i
].dma_res
= r
;
293 ret
= txx9aclc_dma_init(dev
, &dev
->dmadata
[i
]);
298 snd_pcm_set_managed_buffer_all(pcm
, SNDRV_DMA_TYPE_DEV
,
299 card
->dev
, 64 * 1024, 4 * 1024 * 1024);
303 for (i
= 0; i
< 2; i
++) {
304 if (dev
->dmadata
[i
].dma_chan
)
305 dma_release_channel(dev
->dmadata
[i
].dma_chan
);
306 dev
->dmadata
[i
].dma_chan
= NULL
;
311 static bool filter(struct dma_chan
*chan
, void *param
)
313 struct txx9aclc_dmadata
*dmadata
= param
;
317 devname
= kasprintf(GFP_KERNEL
, "%s.%d", dmadata
->dma_res
->name
,
318 (int)dmadata
->dma_res
->start
);
319 if (strcmp(dev_name(chan
->device
->dev
), devname
) == 0) {
320 chan
->private = &dmadata
->dma_slave
;
327 static int txx9aclc_dma_init(struct txx9aclc_soc_device
*dev
,
328 struct txx9aclc_dmadata
*dmadata
)
330 struct txx9aclc_plat_drvdata
*drvdata
= txx9aclc_drvdata
;
331 struct txx9dmac_slave
*ds
= &dmadata
->dma_slave
;
334 spin_lock_init(&dmadata
->dma_lock
);
336 ds
->reg_width
= sizeof(u32
);
337 if (dmadata
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
338 ds
->tx_reg
= drvdata
->physbase
+ ACAUDODAT
;
342 ds
->rx_reg
= drvdata
->physbase
+ ACAUDIDAT
;
345 /* Try to grab a DMA channel */
347 dma_cap_set(DMA_SLAVE
, mask
);
348 dmadata
->dma_chan
= dma_request_channel(mask
, filter
, dmadata
);
349 if (!dmadata
->dma_chan
) {
351 "DMA channel for %s is not available\n",
352 dmadata
->stream
== SNDRV_PCM_STREAM_PLAYBACK
?
353 "playback" : "capture");
356 INIT_WORK(&dmadata
->work
, txx9aclc_dma_work
);
360 static int txx9aclc_pcm_probe(struct snd_soc_component
*component
)
362 snd_soc_component_set_drvdata(component
, &txx9aclc_soc_device
);
366 static void txx9aclc_pcm_remove(struct snd_soc_component
*component
)
368 struct txx9aclc_soc_device
*dev
= snd_soc_component_get_drvdata(component
);
369 struct txx9aclc_plat_drvdata
*drvdata
= txx9aclc_drvdata
;
370 void __iomem
*base
= drvdata
->base
;
373 /* disable all FIFO DMAs */
374 __raw_writel(ACCTL_AUDODMA
| ACCTL_AUDIDMA
, base
+ ACCTLDIS
);
375 /* dummy R/W to clear pending DMAREQ if any */
376 __raw_writel(__raw_readl(base
+ ACAUDIDAT
), base
+ ACAUDODAT
);
378 for (i
= 0; i
< 2; i
++) {
379 struct txx9aclc_dmadata
*dmadata
= &dev
->dmadata
[i
];
380 struct dma_chan
*chan
= dmadata
->dma_chan
;
383 dmadata
->frag_count
= -1;
384 dmaengine_terminate_all(chan
);
385 dma_release_channel(chan
);
387 dev
->dmadata
[i
].dma_chan
= NULL
;
391 static const struct snd_soc_component_driver txx9aclc_soc_component
= {
393 .probe
= txx9aclc_pcm_probe
,
394 .remove
= txx9aclc_pcm_remove
,
395 .open
= txx9aclc_pcm_open
,
396 .close
= txx9aclc_pcm_close
,
397 .hw_params
= txx9aclc_pcm_hw_params
,
398 .prepare
= txx9aclc_pcm_prepare
,
399 .trigger
= txx9aclc_pcm_trigger
,
400 .pointer
= txx9aclc_pcm_pointer
,
401 .pcm_construct
= txx9aclc_pcm_new
,
404 static int txx9aclc_soc_platform_probe(struct platform_device
*pdev
)
406 return devm_snd_soc_register_component(&pdev
->dev
,
407 &txx9aclc_soc_component
, NULL
, 0);
410 static struct platform_driver txx9aclc_pcm_driver
= {
412 .name
= "txx9aclc-pcm-audio",
415 .probe
= txx9aclc_soc_platform_probe
,
418 module_platform_driver(txx9aclc_pcm_driver
);
420 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
421 MODULE_DESCRIPTION("TXx9 ACLC Audio DMA driver");
422 MODULE_LICENSE("GPL");