Blame view

sound/soc/omap/omap-pcm.c 11.9 KB
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
1
2
3
4
5
  /*
   * omap-pcm.c  --  ALSA PCM interface for the OMAP SoC
   *
   * Copyright (C) 2008 Nokia Corporation
   *
7ec41ee5a   Jarkko Nikula   ASoC: omap: Updat...
6
   * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
1c7687b99   Peter Ujfalusi   ASoC: omap-pcm: U...
7
   *          Peter Ujfalusi <peter.ujfalusi@ti.com>
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * version 2 as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   * 02110-1301 USA
   *
   */
  
  #include <linux/dma-mapping.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
26
  #include <linux/slab.h>
da155d5b4   Paul Gortmaker   sound: Add module...
27
  #include <linux/module.h>
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
28
29
30
31
  #include <sound/core.h>
  #include <sound/pcm.h>
  #include <sound/pcm_params.h>
  #include <sound/soc.h>
ce491cf85   Tony Lindgren   omap: headers: Mo...
32
  #include <plat/dma.h>
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
33
34
35
36
37
38
39
  #include "omap-pcm.h"
  
  static const struct snd_pcm_hardware omap_pcm_hardware = {
  	.info			= SNDRV_PCM_INFO_MMAP |
  				  SNDRV_PCM_INFO_MMAP_VALID |
  				  SNDRV_PCM_INFO_INTERLEAVED |
  				  SNDRV_PCM_INFO_PAUSE |
b41738241   Peter Ujfalusi   ASoC: omap-pcm: P...
40
41
  				  SNDRV_PCM_INFO_RESUME |
  				  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
e17dd32f3   Misael Lopez Cruz   ASoC: OMAP: data_...
42
43
  	.formats		= SNDRV_PCM_FMTBIT_S16_LE |
  				  SNDRV_PCM_FMTBIT_S32_LE,
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  	.period_bytes_min	= 32,
  	.period_bytes_max	= 64 * 1024,
  	.periods_min		= 2,
  	.periods_max		= 255,
  	.buffer_bytes_max	= 128 * 1024,
  };
  
  struct omap_runtime_data {
  	spinlock_t			lock;
  	struct omap_pcm_dma_data	*dma_data;
  	int				dma_ch;
  	int				period_index;
  };
  
  static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
  {
  	struct snd_pcm_substream *substream = data;
  	struct snd_pcm_runtime *runtime = substream->runtime;
  	struct omap_runtime_data *prtd = runtime->private_data;
  	unsigned long flags;
b5442a75d   Janusz Krzysztofik   ASoC: OMAP: Fix c...
64
  	if ((cpu_is_omap1510())) {
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
65
  		/*
64844a6ac   Janusz Krzysztofik   ASoC: OMAP: Make ...
66
67
  		 * OMAP1510 doesn't fully support DMA progress counter
  		 * and there is no software emulation implemented yet,
b5442a75d   Janusz Krzysztofik   ASoC: OMAP: Fix c...
68
  		 * so have to maintain our own progress counters
64844a6ac   Janusz Krzysztofik   ASoC: OMAP: Make ...
69
  		 * that can be used by omap_pcm_pointer() instead.
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
70
71
  		 */
  		spin_lock_irqsave(&prtd->lock, flags);
471e3dec3   Janusz Krzysztofik   ASoC: OMAP: Enhan...
72
73
74
75
76
77
  		if ((stat == OMAP_DMA_LAST_IRQ) &&
  				(prtd->period_index == runtime->periods - 1)) {
  			/* we are in sync, do nothing */
  			spin_unlock_irqrestore(&prtd->lock, flags);
  			return;
  		}
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
78
  		if (prtd->period_index >= 0) {
471e3dec3   Janusz Krzysztofik   ASoC: OMAP: Enhan...
79
80
81
82
83
84
85
86
  			if (stat & OMAP_DMA_BLOCK_IRQ) {
  				/* end of buffer reached, loop back */
  				prtd->period_index = 0;
  			} else if (stat & OMAP_DMA_LAST_IRQ) {
  				/* update the counter for the last period */
  				prtd->period_index = runtime->periods - 1;
  			} else if (++prtd->period_index >= runtime->periods) {
  				/* end of buffer missed? loop back */
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
87
  				prtd->period_index = 0;
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  			}
  		}
  		spin_unlock_irqrestore(&prtd->lock, flags);
  	}
  
  	snd_pcm_period_elapsed(substream);
  }
  
  /* this may get called several times by oss emulation */
  static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
  			      struct snd_pcm_hw_params *params)
  {
  	struct snd_pcm_runtime *runtime = substream->runtime;
  	struct snd_soc_pcm_runtime *rtd = substream->private_data;
  	struct omap_runtime_data *prtd = runtime->private_data;
5f712b2b7   Daniel Mack   ALSA: ASoC: move ...
103
  	struct omap_pcm_dma_data *dma_data;
f0fba2ad1   Liam Girdwood   ASoC: multi-compo...
104

2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
105
  	int err = 0;
f0fba2ad1   Liam Girdwood   ASoC: multi-compo...
106
  	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
5f712b2b7   Daniel Mack   ALSA: ASoC: move ...
107

1b4246a1f   Joonyoung Shim   ASoC: OMAP: Add c...
108
109
  	/* return if this is a bufferless transfer e.g.
  	 * codec <--> BT codec or GSM modem -- lg FIXME */
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
110
  	if (!dma_data)
1b4246a1f   Joonyoung Shim   ASoC: OMAP: Add c...
111
  		return 0;
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
112
113
114
115
116
117
118
119
120
  
  	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
  	runtime->dma_bytes = params_buffer_bytes(params);
  
  	if (prtd->dma_data)
  		return 0;
  	prtd->dma_data = dma_data;
  	err = omap_request_dma(dma_data->dma_req, dma_data->name,
  			       omap_pcm_dma_irq, substream, &prtd->dma_ch);
64844a6ac   Janusz Krzysztofik   ASoC: OMAP: Make ...
121
  	if (!err) {
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
  		/*
  		 * Link channel with itself so DMA doesn't need any
  		 * reprogramming while looping the buffer
  		 */
  		omap_dma_link_lch(prtd->dma_ch, prtd->dma_ch);
  	}
  
  	return err;
  }
  
  static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
  {
  	struct snd_pcm_runtime *runtime = substream->runtime;
  	struct omap_runtime_data *prtd = runtime->private_data;
  
  	if (prtd->dma_data == NULL)
  		return 0;
64844a6ac   Janusz Krzysztofik   ASoC: OMAP: Make ...
139
  	omap_dma_unlink_lch(prtd->dma_ch, prtd->dma_ch);
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  	omap_free_dma(prtd->dma_ch);
  	prtd->dma_data = NULL;
  
  	snd_pcm_set_runtime_buffer(substream, NULL);
  
  	return 0;
  }
  
  static int omap_pcm_prepare(struct snd_pcm_substream *substream)
  {
  	struct snd_pcm_runtime *runtime = substream->runtime;
  	struct omap_runtime_data *prtd = runtime->private_data;
  	struct omap_pcm_dma_data *dma_data = prtd->dma_data;
  	struct omap_dma_channel_params dma_params;
e17dd32f3   Misael Lopez Cruz   ASoC: OMAP: data_...
154
  	int bytes;
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
155

1b4246a1f   Joonyoung Shim   ASoC: OMAP: Add c...
156
157
158
159
  	/* return if this is a bufferless transfer e.g.
  	 * codec <--> BT codec or GSM modem -- lg FIXME */
  	if (!prtd->dma_data)
  		return 0;
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
160
  	memset(&dma_params, 0, sizeof(dma_params));
e17dd32f3   Misael Lopez Cruz   ASoC: OMAP: data_...
161
  	dma_params.data_type			= dma_data->data_type;
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
162
  	dma_params.trigger			= dma_data->dma_req;
caebc0cb3   Eduardo Valentin   ASoC: OMAP: Use M...
163
  	dma_params.sync_mode			= dma_data->sync_mode;
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
164
165
166
167
168
169
  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  		dma_params.src_amode		= OMAP_DMA_AMODE_POST_INC;
  		dma_params.dst_amode		= OMAP_DMA_AMODE_CONSTANT;
  		dma_params.src_or_dst_synch	= OMAP_DMA_DST_SYNC;
  		dma_params.src_start		= runtime->dma_addr;
  		dma_params.dst_start		= dma_data->port_addr;
9d37484c8   Arun KS   ALSA: ASoC: Add d...
170
  		dma_params.dst_port		= OMAP_DMA_PORT_MPUI;
e17dd32f3   Misael Lopez Cruz   ASoC: OMAP: data_...
171
  		dma_params.dst_fi		= dma_data->packet_size;
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
172
173
174
175
176
177
  	} else {
  		dma_params.src_amode		= OMAP_DMA_AMODE_CONSTANT;
  		dma_params.dst_amode		= OMAP_DMA_AMODE_POST_INC;
  		dma_params.src_or_dst_synch	= OMAP_DMA_SRC_SYNC;
  		dma_params.src_start		= dma_data->port_addr;
  		dma_params.dst_start		= runtime->dma_addr;
9d37484c8   Arun KS   ALSA: ASoC: Add d...
178
  		dma_params.src_port		= OMAP_DMA_PORT_MPUI;
e17dd32f3   Misael Lopez Cruz   ASoC: OMAP: data_...
179
  		dma_params.src_fi		= dma_data->packet_size;
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
180
181
182
183
184
185
186
  	}
  	/*
  	 * Set DMA transfer frame size equal to ALSA period size and frame
  	 * count as no. of ALSA periods. Then with DMA frame interrupt enabled,
  	 * we can transfer the whole ALSA buffer with single DMA transfer but
  	 * still can get an interrupt at each period bounary
  	 */
e17dd32f3   Misael Lopez Cruz   ASoC: OMAP: data_...
187
188
  	bytes = snd_pcm_lib_period_bytes(substream);
  	dma_params.elem_count	= bytes >> dma_data->data_type;
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
189
190
  	dma_params.frame_count	= runtime->periods;
  	omap_set_dma_params(prtd->dma_ch, &dma_params);
b5442a75d   Janusz Krzysztofik   ASoC: OMAP: Fix c...
191
  	if ((cpu_is_omap1510()))
471e3dec3   Janusz Krzysztofik   ASoC: OMAP: Enhan...
192
193
  		omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
  			      OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
b41738241   Peter Ujfalusi   ASoC: omap-pcm: P...
194
  	else if (!substream->runtime->no_period_wakeup)
471e3dec3   Janusz Krzysztofik   ASoC: OMAP: Enhan...
195
  		omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
b1b6cffeb   Peter Ujfalusi   ASoC: omap-pcm: F...
196
197
198
199
200
201
202
203
  	else {
  		/*
  		 * No period wakeup:
  		 * we need to disable BLOCK_IRQ, which is enabled by the omap
  		 * dma core at request dma time.
  		 */
  		omap_disable_dma_irq(prtd->dma_ch, OMAP_DMA_BLOCK_IRQ);
  	}
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
204

4d187fb83   Janusz Krzysztofik   ASoC: OMAP: Don't...
205
206
207
208
209
210
  	if (!(cpu_class_is_omap1())) {
  		omap_set_dma_src_burst_mode(prtd->dma_ch,
  						OMAP_DMA_DATA_BURST_16);
  		omap_set_dma_dest_burst_mode(prtd->dma_ch,
  						OMAP_DMA_DATA_BURST_16);
  	}
9599d485c   Eduardo Valentin   ASoC: OMAP: Enabl...
211

2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
212
213
214
215
216
217
218
  	return 0;
  }
  
  static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
  {
  	struct snd_pcm_runtime *runtime = substream->runtime;
  	struct omap_runtime_data *prtd = runtime->private_data;
caebc0cb3   Eduardo Valentin   ASoC: OMAP: Use M...
219
  	struct omap_pcm_dma_data *dma_data = prtd->dma_data;
21dff4345   Eero Nurkkala   OMAP: ASoC: Fix s...
220
  	unsigned long flags;
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
221
  	int ret = 0;
21dff4345   Eero Nurkkala   OMAP: ASoC: Fix s...
222
  	spin_lock_irqsave(&prtd->lock, flags);
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
223
224
225
226
227
  	switch (cmd) {
  	case SNDRV_PCM_TRIGGER_START:
  	case SNDRV_PCM_TRIGGER_RESUME:
  	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  		prtd->period_index = 0;
caebc0cb3   Eduardo Valentin   ASoC: OMAP: Use M...
228
229
230
  		/* Configure McBSP internal buffer usage */
  		if (dma_data->set_threshold)
  			dma_data->set_threshold(substream);
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
231
232
233
234
235
236
237
238
239
240
241
242
  		omap_start_dma(prtd->dma_ch);
  		break;
  
  	case SNDRV_PCM_TRIGGER_STOP:
  	case SNDRV_PCM_TRIGGER_SUSPEND:
  	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  		prtd->period_index = -1;
  		omap_stop_dma(prtd->dma_ch);
  		break;
  	default:
  		ret = -EINVAL;
  	}
21dff4345   Eero Nurkkala   OMAP: ASoC: Fix s...
243
  	spin_unlock_irqrestore(&prtd->lock, flags);
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
244
245
246
247
248
249
250
251
252
253
  
  	return ret;
  }
  
  static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
  {
  	struct snd_pcm_runtime *runtime = substream->runtime;
  	struct omap_runtime_data *prtd = runtime->private_data;
  	dma_addr_t ptr;
  	snd_pcm_uframes_t offset;
b5442a75d   Janusz Krzysztofik   ASoC: OMAP: Fix c...
254
255
256
  	if (cpu_is_omap1510()) {
  		offset = prtd->period_index * runtime->period_size;
  	} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
257
  		ptr = omap_get_dma_dst_pos(prtd->dma_ch);
1bdd74199   Janusz Krzysztofik   ASoC: OMAP: fix O...
258
  		offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
b5442a75d   Janusz Krzysztofik   ASoC: OMAP: Fix c...
259
  	} else {
1bdd74199   Janusz Krzysztofik   ASoC: OMAP: fix O...
260
261
  		ptr = omap_get_dma_src_pos(prtd->dma_ch);
  		offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
b5442a75d   Janusz Krzysztofik   ASoC: OMAP: Fix c...
262
  	}
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
263

2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
  	if (offset >= runtime->buffer_size)
  		offset = 0;
  
  	return offset;
  }
  
  static int omap_pcm_open(struct snd_pcm_substream *substream)
  {
  	struct snd_pcm_runtime *runtime = substream->runtime;
  	struct omap_runtime_data *prtd;
  	int ret;
  
  	snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
  
  	/* Ensure that buffer size is a multiple of period size */
  	ret = snd_pcm_hw_constraint_integer(runtime,
  					    SNDRV_PCM_HW_PARAM_PERIODS);
  	if (ret < 0)
  		goto out;
19b3f3160   Stanley Miao   ALSA: Fix a Oops ...
283
  	prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
  	if (prtd == NULL) {
  		ret = -ENOMEM;
  		goto out;
  	}
  	spin_lock_init(&prtd->lock);
  	runtime->private_data = prtd;
  
  out:
  	return ret;
  }
  
  static int omap_pcm_close(struct snd_pcm_substream *substream)
  {
  	struct snd_pcm_runtime *runtime = substream->runtime;
  
  	kfree(runtime->private_data);
  	return 0;
  }
  
  static int omap_pcm_mmap(struct snd_pcm_substream *substream,
  	struct vm_area_struct *vma)
  {
  	struct snd_pcm_runtime *runtime = substream->runtime;
  
  	return dma_mmap_writecombine(substream->pcm->card->dev, vma,
  				     runtime->dma_area,
  				     runtime->dma_addr,
  				     runtime->dma_bytes);
  }
b2a19d023   Mark Brown   ASoC: Staticise P...
313
  static struct snd_pcm_ops omap_pcm_ops = {
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
314
315
316
317
318
319
320
321
322
323
  	.open		= omap_pcm_open,
  	.close		= omap_pcm_close,
  	.ioctl		= snd_pcm_lib_ioctl,
  	.hw_params	= omap_pcm_hw_params,
  	.hw_free	= omap_pcm_hw_free,
  	.prepare	= omap_pcm_prepare,
  	.trigger	= omap_pcm_trigger,
  	.pointer	= omap_pcm_pointer,
  	.mmap		= omap_pcm_mmap,
  };
a152ff24b   Eduardo Valentin   ASoC: OMAP: Make ...
324
  static u64 omap_pcm_dmamask = DMA_BIT_MASK(64);
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
  
  static int omap_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
  	int stream)
  {
  	struct snd_pcm_substream *substream = pcm->streams[stream].substream;
  	struct snd_dma_buffer *buf = &substream->dma_buffer;
  	size_t size = omap_pcm_hardware.buffer_bytes_max;
  
  	buf->dev.type = SNDRV_DMA_TYPE_DEV;
  	buf->dev.dev = pcm->card->dev;
  	buf->private_data = NULL;
  	buf->area = dma_alloc_writecombine(pcm->card->dev, size,
  					   &buf->addr, GFP_KERNEL);
  	if (!buf->area)
  		return -ENOMEM;
  
  	buf->bytes = size;
  	return 0;
  }
  
  static void omap_pcm_free_dma_buffers(struct snd_pcm *pcm)
  {
  	struct snd_pcm_substream *substream;
  	struct snd_dma_buffer *buf;
  	int stream;
  
  	for (stream = 0; stream < 2; stream++) {
  		substream = pcm->streams[stream].substream;
  		if (!substream)
  			continue;
  
  		buf = &substream->dma_buffer;
  		if (!buf->area)
  			continue;
  
  		dma_free_writecombine(pcm->card->dev, buf->bytes,
  				      buf->area, buf->addr);
  		buf->area = NULL;
  	}
  }
552d1ef6b   Liam Girdwood   ASoC: core - Opti...
365
  static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd)
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
366
  {
552d1ef6b   Liam Girdwood   ASoC: core - Opti...
367
  	struct snd_card *card = rtd->card->snd_card;
552d1ef6b   Liam Girdwood   ASoC: core - Opti...
368
  	struct snd_pcm *pcm = rtd->pcm;
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
369
370
371
372
373
  	int ret = 0;
  
  	if (!card->dev->dma_mask)
  		card->dev->dma_mask = &omap_pcm_dmamask;
  	if (!card->dev->coherent_dma_mask)
a152ff24b   Eduardo Valentin   ASoC: OMAP: Make ...
374
  		card->dev->coherent_dma_mask = DMA_BIT_MASK(64);
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
375

25e9e7565   Joachim Eastwood   ASoC: check for s...
376
  	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
377
378
379
380
381
  		ret = omap_pcm_preallocate_dma_buffer(pcm,
  			SNDRV_PCM_STREAM_PLAYBACK);
  		if (ret)
  			goto out;
  	}
25e9e7565   Joachim Eastwood   ASoC: check for s...
382
  	if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
383
384
385
386
387
388
389
390
391
  		ret = omap_pcm_preallocate_dma_buffer(pcm,
  			SNDRV_PCM_STREAM_CAPTURE);
  		if (ret)
  			goto out;
  	}
  
  out:
  	return ret;
  }
f0fba2ad1   Liam Girdwood   ASoC: multi-compo...
392
393
  static struct snd_soc_platform_driver omap_soc_platform = {
  	.ops		= &omap_pcm_ops,
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
394
395
396
  	.pcm_new	= omap_pcm_new,
  	.pcm_free	= omap_pcm_free_dma_buffers,
  };
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
397

f0fba2ad1   Liam Girdwood   ASoC: multi-compo...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
  static __devinit int omap_pcm_probe(struct platform_device *pdev)
  {
  	return snd_soc_register_platform(&pdev->dev,
  			&omap_soc_platform);
  }
  
  static int __devexit omap_pcm_remove(struct platform_device *pdev)
  {
  	snd_soc_unregister_platform(&pdev->dev);
  	return 0;
  }
  
  static struct platform_driver omap_pcm_driver = {
  	.driver = {
  			.name = "omap-pcm-audio",
  			.owner = THIS_MODULE,
  	},
  
  	.probe = omap_pcm_probe,
  	.remove = __devexit_p(omap_pcm_remove),
  };
beda5bf57   Axel Lin   ASoC: Convert oma...
419
  module_platform_driver(omap_pcm_driver);
958e792c7   Mark Brown   ASoC: Register pl...
420

7ec41ee5a   Jarkko Nikula   ASoC: omap: Updat...
421
  MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
2e74796a4   Jarkko Nikula   [ALSA] ASoC: Add ...
422
423
  MODULE_DESCRIPTION("OMAP PCM DMA module");
  MODULE_LICENSE("GPL");