2 * ALSA PCM interface for the TI DAVINCI processor
4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.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.
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/platform_device.h>
15 #include <linux/slab.h>
16 #include <linux/dma-mapping.h>
17 #include <linux/kernel.h>
19 #include <sound/core.h>
20 #include <sound/pcm.h>
21 #include <sound/pcm_params.h>
22 #include <sound/soc.h>
26 #include "davinci-pcm.h"
28 static struct snd_pcm_hardware davinci_pcm_hardware
= {
29 .info
= (SNDRV_PCM_INFO_INTERLEAVED
| SNDRV_PCM_INFO_BLOCK_TRANSFER
|
30 SNDRV_PCM_INFO_MMAP
| SNDRV_PCM_INFO_MMAP_VALID
|
31 SNDRV_PCM_INFO_PAUSE
),
32 .formats
= (SNDRV_PCM_FMTBIT_S16_LE
),
33 .rates
= (SNDRV_PCM_RATE_8000
| SNDRV_PCM_RATE_16000
|
34 SNDRV_PCM_RATE_22050
| SNDRV_PCM_RATE_32000
|
35 SNDRV_PCM_RATE_44100
| SNDRV_PCM_RATE_48000
|
36 SNDRV_PCM_RATE_88200
| SNDRV_PCM_RATE_96000
|
42 .buffer_bytes_max
= 128 * 1024,
43 .period_bytes_min
= 32,
44 .period_bytes_max
= 8 * 1024,
50 struct davinci_runtime_data
{
52 int period
; /* current DMA period */
53 int master_lch
; /* Master DMA channel */
54 int slave_lch
; /* Slave DMA channel */
55 struct davinci_pcm_dma_params
*params
; /* DMA params */
58 static void davinci_pcm_enqueue_dma(struct snd_pcm_substream
*substream
)
60 struct davinci_runtime_data
*prtd
= substream
->runtime
->private_data
;
61 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
62 int lch
= prtd
->slave_lch
;
63 unsigned int period_size
;
64 unsigned int dma_offset
;
67 unsigned short src_bidx
, dst_bidx
;
68 unsigned int data_type
;
71 period_size
= snd_pcm_lib_period_bytes(substream
);
72 dma_offset
= prtd
->period
* period_size
;
73 dma_pos
= runtime
->dma_addr
+ dma_offset
;
75 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
76 "dma_ptr = %x period_size=%x\n", lch
, dma_pos
, period_size
);
78 data_type
= prtd
->params
->data_type
;
79 count
= period_size
/ data_type
;
81 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
83 dst
= prtd
->params
->dma_addr
;
87 src
= prtd
->params
->dma_addr
;
93 davinci_set_dma_src_params(lch
, src
, INCR
, W8BIT
);
94 davinci_set_dma_dest_params(lch
, dst
, INCR
, W8BIT
);
95 davinci_set_dma_src_index(lch
, src_bidx
, 0);
96 davinci_set_dma_dest_index(lch
, dst_bidx
, 0);
97 davinci_set_dma_transfer_params(lch
, data_type
, count
, 1, 0, ASYNC
);
100 if (unlikely(prtd
->period
>= runtime
->periods
))
104 static void davinci_pcm_dma_irq(int lch
, u16 ch_status
, void *data
)
106 struct snd_pcm_substream
*substream
= data
;
107 struct davinci_runtime_data
*prtd
= substream
->runtime
->private_data
;
109 pr_debug("davinci_pcm: lch=%d, status=0x%x\n", lch
, ch_status
);
111 if (unlikely(ch_status
!= DMA_COMPLETE
))
114 if (snd_pcm_running(substream
)) {
115 snd_pcm_period_elapsed(substream
);
117 spin_lock(&prtd
->lock
);
118 davinci_pcm_enqueue_dma(substream
);
119 spin_unlock(&prtd
->lock
);
123 static int davinci_pcm_dma_request(struct snd_pcm_substream
*substream
)
125 struct davinci_runtime_data
*prtd
= substream
->runtime
->private_data
;
126 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
127 struct davinci_pcm_dma_params
*dma_data
= rtd
->dai
->cpu_dai
->dma_data
;
134 prtd
->params
= dma_data
;
136 /* Request master DMA channel */
137 ret
= davinci_request_dma(prtd
->params
->channel
, prtd
->params
->name
,
138 davinci_pcm_dma_irq
, substream
,
139 &prtd
->master_lch
, &tcc
, EVENTQ_0
);
143 /* Request slave DMA channel */
144 ret
= davinci_request_dma(PARAM_ANY
, "Link",
145 NULL
, NULL
, &prtd
->slave_lch
, &tcc
, EVENTQ_0
);
147 davinci_free_dma(prtd
->master_lch
);
151 /* Link slave DMA channel in loopback */
152 davinci_dma_link_lch(prtd
->slave_lch
, prtd
->slave_lch
);
157 static int davinci_pcm_trigger(struct snd_pcm_substream
*substream
, int cmd
)
159 struct davinci_runtime_data
*prtd
= substream
->runtime
->private_data
;
162 spin_lock(&prtd
->lock
);
165 case SNDRV_PCM_TRIGGER_START
:
166 case SNDRV_PCM_TRIGGER_RESUME
:
167 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
168 davinci_start_dma(prtd
->master_lch
);
170 case SNDRV_PCM_TRIGGER_STOP
:
171 case SNDRV_PCM_TRIGGER_SUSPEND
:
172 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
173 davinci_stop_dma(prtd
->master_lch
);
180 spin_unlock(&prtd
->lock
);
185 static int davinci_pcm_prepare(struct snd_pcm_substream
*substream
)
187 struct davinci_runtime_data
*prtd
= substream
->runtime
->private_data
;
188 struct paramentry_descriptor temp
;
191 davinci_pcm_enqueue_dma(substream
);
193 /* Get slave channel dma params for master channel startup */
194 davinci_get_dma_params(prtd
->slave_lch
, &temp
);
195 davinci_set_dma_params(prtd
->master_lch
, &temp
);
200 static snd_pcm_uframes_t
201 davinci_pcm_pointer(struct snd_pcm_substream
*substream
)
203 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
204 struct davinci_runtime_data
*prtd
= runtime
->private_data
;
209 spin_lock(&prtd
->lock
);
211 davinci_dma_getposition(prtd
->master_lch
, &src
, &dst
);
212 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
213 count
= src
- runtime
->dma_addr
;
215 count
= dst
- runtime
->dma_addr
;
217 spin_unlock(&prtd
->lock
);
219 offset
= bytes_to_frames(runtime
, count
);
220 if (offset
>= runtime
->buffer_size
)
226 static int davinci_pcm_open(struct snd_pcm_substream
*substream
)
228 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
229 struct davinci_runtime_data
*prtd
;
232 snd_soc_set_runtime_hwparams(substream
, &davinci_pcm_hardware
);
234 prtd
= kzalloc(sizeof(struct davinci_runtime_data
), GFP_KERNEL
);
238 spin_lock_init(&prtd
->lock
);
240 runtime
->private_data
= prtd
;
242 ret
= davinci_pcm_dma_request(substream
);
244 printk(KERN_ERR
"davinci_pcm: Failed to get dma channels\n");
251 static int davinci_pcm_close(struct snd_pcm_substream
*substream
)
253 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
254 struct davinci_runtime_data
*prtd
= runtime
->private_data
;
256 davinci_dma_unlink_lch(prtd
->slave_lch
, prtd
->slave_lch
);
258 davinci_free_dma(prtd
->slave_lch
);
259 davinci_free_dma(prtd
->master_lch
);
266 static int davinci_pcm_hw_params(struct snd_pcm_substream
*substream
,
267 struct snd_pcm_hw_params
*hw_params
)
269 return snd_pcm_lib_malloc_pages(substream
,
270 params_buffer_bytes(hw_params
));
273 static int davinci_pcm_hw_free(struct snd_pcm_substream
*substream
)
275 return snd_pcm_lib_free_pages(substream
);
278 static int davinci_pcm_mmap(struct snd_pcm_substream
*substream
,
279 struct vm_area_struct
*vma
)
281 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
283 return dma_mmap_writecombine(substream
->pcm
->card
->dev
, vma
,
289 static struct snd_pcm_ops davinci_pcm_ops
= {
290 .open
= davinci_pcm_open
,
291 .close
= davinci_pcm_close
,
292 .ioctl
= snd_pcm_lib_ioctl
,
293 .hw_params
= davinci_pcm_hw_params
,
294 .hw_free
= davinci_pcm_hw_free
,
295 .prepare
= davinci_pcm_prepare
,
296 .trigger
= davinci_pcm_trigger
,
297 .pointer
= davinci_pcm_pointer
,
298 .mmap
= davinci_pcm_mmap
,
301 static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm
*pcm
, int stream
)
303 struct snd_pcm_substream
*substream
= pcm
->streams
[stream
].substream
;
304 struct snd_dma_buffer
*buf
= &substream
->dma_buffer
;
305 size_t size
= davinci_pcm_hardware
.buffer_bytes_max
;
307 buf
->dev
.type
= SNDRV_DMA_TYPE_DEV
;
308 buf
->dev
.dev
= pcm
->card
->dev
;
309 buf
->private_data
= NULL
;
310 buf
->area
= dma_alloc_writecombine(pcm
->card
->dev
, size
,
311 &buf
->addr
, GFP_KERNEL
);
313 pr_debug("davinci_pcm: preallocate_dma_buffer: area=%p, addr=%p, "
314 "size=%d\n", (void *) buf
->area
, (void *) buf
->addr
, size
);
323 static void davinci_pcm_free(struct snd_pcm
*pcm
)
325 struct snd_pcm_substream
*substream
;
326 struct snd_dma_buffer
*buf
;
329 for (stream
= 0; stream
< 2; stream
++) {
330 substream
= pcm
->streams
[stream
].substream
;
334 buf
= &substream
->dma_buffer
;
338 dma_free_writecombine(pcm
->card
->dev
, buf
->bytes
,
339 buf
->area
, buf
->addr
);
344 static u64 davinci_pcm_dmamask
= 0xffffffff;
346 static int davinci_pcm_new(struct snd_card
*card
,
347 struct snd_soc_dai
*dai
, struct snd_pcm
*pcm
)
351 if (!card
->dev
->dma_mask
)
352 card
->dev
->dma_mask
= &davinci_pcm_dmamask
;
353 if (!card
->dev
->coherent_dma_mask
)
354 card
->dev
->coherent_dma_mask
= 0xffffffff;
356 if (dai
->playback
.channels_min
) {
357 ret
= davinci_pcm_preallocate_dma_buffer(pcm
,
358 SNDRV_PCM_STREAM_PLAYBACK
);
363 if (dai
->capture
.channels_min
) {
364 ret
= davinci_pcm_preallocate_dma_buffer(pcm
,
365 SNDRV_PCM_STREAM_CAPTURE
);
373 struct snd_soc_platform davinci_soc_platform
= {
374 .name
= "davinci-audio",
375 .pcm_ops
= &davinci_pcm_ops
,
376 .pcm_new
= davinci_pcm_new
,
377 .pcm_free
= davinci_pcm_free
,
379 EXPORT_SYMBOL_GPL(davinci_soc_platform
);
381 static int __init
davinci_soc_platform_init(void)
383 return snd_soc_register_platform(&davinci_soc_platform
);
385 module_init(davinci_soc_platform_init
);
387 static void __exit
davinci_soc_platform_exit(void)
389 snd_soc_unregister_platform(&davinci_soc_platform
);
391 module_exit(davinci_soc_platform_exit
);
393 MODULE_AUTHOR("Vladimir Barinov");
394 MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
395 MODULE_LICENSE("GPL");