xref: /openbmc/linux/sound/pci/ctxfi/ctpcm.c (revision 1fa6ac37)
1 /**
2  * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3  *
4  * This source file is released under GPL v2 license (no other versions).
5  * See the COPYING file included in the main directory of this source
6  * distribution for the license terms and conditions.
7  *
8  * @File	ctpcm.c
9  *
10  * @Brief
11  * This file contains the definition of the pcm device functions.
12  *
13  * @Author	Liu Chun
14  * @Date 	Apr 2 2008
15  *
16  */
17 
18 #include "ctpcm.h"
19 #include "cttimer.h"
20 #include <linux/slab.h>
21 #include <sound/pcm.h>
22 
23 /* Hardware descriptions for playback */
24 static struct snd_pcm_hardware ct_pcm_playback_hw = {
25 	.info			= (SNDRV_PCM_INFO_MMAP |
26 				   SNDRV_PCM_INFO_INTERLEAVED |
27 				   SNDRV_PCM_INFO_BLOCK_TRANSFER |
28 				   SNDRV_PCM_INFO_MMAP_VALID |
29 				   SNDRV_PCM_INFO_PAUSE),
30 	.formats		= (SNDRV_PCM_FMTBIT_U8 |
31 				   SNDRV_PCM_FMTBIT_S16_LE |
32 				   SNDRV_PCM_FMTBIT_S24_3LE |
33 				   SNDRV_PCM_FMTBIT_S32_LE |
34 				   SNDRV_PCM_FMTBIT_FLOAT_LE),
35 	.rates			= (SNDRV_PCM_RATE_CONTINUOUS |
36 				   SNDRV_PCM_RATE_8000_192000),
37 	.rate_min		= 8000,
38 	.rate_max		= 192000,
39 	.channels_min		= 1,
40 	.channels_max		= 2,
41 	.buffer_bytes_max	= (128*1024),
42 	.period_bytes_min	= (64),
43 	.period_bytes_max	= (128*1024),
44 	.periods_min		= 2,
45 	.periods_max		= 1024,
46 	.fifo_size		= 0,
47 };
48 
49 static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = {
50 	.info			= (SNDRV_PCM_INFO_MMAP |
51 				   SNDRV_PCM_INFO_INTERLEAVED |
52 				   SNDRV_PCM_INFO_BLOCK_TRANSFER |
53 				   SNDRV_PCM_INFO_MMAP_VALID |
54 				   SNDRV_PCM_INFO_PAUSE),
55 	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
56 	.rates			= (SNDRV_PCM_RATE_48000 |
57 				   SNDRV_PCM_RATE_44100 |
58 				   SNDRV_PCM_RATE_32000),
59 	.rate_min		= 32000,
60 	.rate_max		= 48000,
61 	.channels_min		= 2,
62 	.channels_max		= 2,
63 	.buffer_bytes_max	= (128*1024),
64 	.period_bytes_min	= (64),
65 	.period_bytes_max	= (128*1024),
66 	.periods_min		= 2,
67 	.periods_max		= 1024,
68 	.fifo_size		= 0,
69 };
70 
71 /* Hardware descriptions for capture */
72 static struct snd_pcm_hardware ct_pcm_capture_hw = {
73 	.info			= (SNDRV_PCM_INFO_MMAP |
74 				   SNDRV_PCM_INFO_INTERLEAVED |
75 				   SNDRV_PCM_INFO_BLOCK_TRANSFER |
76 				   SNDRV_PCM_INFO_PAUSE |
77 				   SNDRV_PCM_INFO_MMAP_VALID),
78 	.formats		= (SNDRV_PCM_FMTBIT_U8 |
79 				   SNDRV_PCM_FMTBIT_S16_LE |
80 				   SNDRV_PCM_FMTBIT_S24_3LE |
81 				   SNDRV_PCM_FMTBIT_S32_LE |
82 				   SNDRV_PCM_FMTBIT_FLOAT_LE),
83 	.rates			= (SNDRV_PCM_RATE_CONTINUOUS |
84 				   SNDRV_PCM_RATE_8000_96000),
85 	.rate_min		= 8000,
86 	.rate_max		= 96000,
87 	.channels_min		= 1,
88 	.channels_max		= 2,
89 	.buffer_bytes_max	= (128*1024),
90 	.period_bytes_min	= (384),
91 	.period_bytes_max	= (64*1024),
92 	.periods_min		= 2,
93 	.periods_max		= 1024,
94 	.fifo_size		= 0,
95 };
96 
97 static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm)
98 {
99 	struct ct_atc_pcm *apcm = atc_pcm;
100 
101 	if (!apcm->substream)
102 		return;
103 
104 	snd_pcm_period_elapsed(apcm->substream);
105 }
106 
107 static void ct_atc_pcm_free_substream(struct snd_pcm_runtime *runtime)
108 {
109 	struct ct_atc_pcm *apcm = runtime->private_data;
110 	struct ct_atc *atc = snd_pcm_substream_chip(apcm->substream);
111 
112 	atc->pcm_release_resources(atc, apcm);
113 	ct_timer_instance_free(apcm->timer);
114 	kfree(apcm);
115 	runtime->private_data = NULL;
116 }
117 
118 /* pcm playback operations */
119 static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
120 {
121 	struct ct_atc *atc = snd_pcm_substream_chip(substream);
122 	struct snd_pcm_runtime *runtime = substream->runtime;
123 	struct ct_atc_pcm *apcm;
124 	int err;
125 
126 	apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
127 	if (!apcm)
128 		return -ENOMEM;
129 
130 	apcm->substream = substream;
131 	apcm->interrupt = ct_atc_pcm_interrupt;
132 	runtime->private_data = apcm;
133 	runtime->private_free = ct_atc_pcm_free_substream;
134 	if (IEC958 == substream->pcm->device) {
135 		runtime->hw = ct_spdif_passthru_playback_hw;
136 		atc->spdif_out_passthru(atc, 1);
137 	} else {
138 		runtime->hw = ct_pcm_playback_hw;
139 		if (FRONT == substream->pcm->device)
140 			runtime->hw.channels_max = 8;
141 	}
142 
143 	err = snd_pcm_hw_constraint_integer(runtime,
144 					    SNDRV_PCM_HW_PARAM_PERIODS);
145 	if (err < 0) {
146 		kfree(apcm);
147 		return err;
148 	}
149 	err = snd_pcm_hw_constraint_minmax(runtime,
150 					   SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
151 					   1024, UINT_MAX);
152 	if (err < 0) {
153 		kfree(apcm);
154 		return err;
155 	}
156 
157 	apcm->timer = ct_timer_instance_new(atc->timer, apcm);
158 	if (!apcm->timer)
159 		return -ENOMEM;
160 
161 	return 0;
162 }
163 
164 static int ct_pcm_playback_close(struct snd_pcm_substream *substream)
165 {
166 	struct ct_atc *atc = snd_pcm_substream_chip(substream);
167 
168 	/* TODO: Notify mixer inactive. */
169 	if (IEC958 == substream->pcm->device)
170 		atc->spdif_out_passthru(atc, 0);
171 
172 	/* The ct_atc_pcm object will be freed by runtime->private_free */
173 
174 	return 0;
175 }
176 
177 static int ct_pcm_hw_params(struct snd_pcm_substream *substream,
178 				     struct snd_pcm_hw_params *hw_params)
179 {
180 	struct ct_atc *atc = snd_pcm_substream_chip(substream);
181 	struct ct_atc_pcm *apcm = substream->runtime->private_data;
182 	int err;
183 
184 	err = snd_pcm_lib_malloc_pages(substream,
185 					params_buffer_bytes(hw_params));
186 	if (err < 0)
187 		return err;
188 	/* clear previous resources */
189 	atc->pcm_release_resources(atc, apcm);
190 	return err;
191 }
192 
193 static int ct_pcm_hw_free(struct snd_pcm_substream *substream)
194 {
195 	struct ct_atc *atc = snd_pcm_substream_chip(substream);
196 	struct ct_atc_pcm *apcm = substream->runtime->private_data;
197 
198 	/* clear previous resources */
199 	atc->pcm_release_resources(atc, apcm);
200 	/* Free snd-allocated pages */
201 	return snd_pcm_lib_free_pages(substream);
202 }
203 
204 
205 static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream)
206 {
207 	int err;
208 	struct ct_atc *atc = snd_pcm_substream_chip(substream);
209 	struct snd_pcm_runtime *runtime = substream->runtime;
210 	struct ct_atc_pcm *apcm = runtime->private_data;
211 
212 	if (IEC958 == substream->pcm->device)
213 		err = atc->spdif_passthru_playback_prepare(atc, apcm);
214 	else
215 		err = atc->pcm_playback_prepare(atc, apcm);
216 
217 	if (err < 0) {
218 		printk(KERN_ERR "ctxfi: Preparing pcm playback failed!!!\n");
219 		return err;
220 	}
221 
222 	return 0;
223 }
224 
225 static int
226 ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
227 {
228 	struct ct_atc *atc = snd_pcm_substream_chip(substream);
229 	struct snd_pcm_runtime *runtime = substream->runtime;
230 	struct ct_atc_pcm *apcm = runtime->private_data;
231 
232 	switch (cmd) {
233 	case SNDRV_PCM_TRIGGER_START:
234 	case SNDRV_PCM_TRIGGER_RESUME:
235 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
236 		atc->pcm_playback_start(atc, apcm);
237 		break;
238 	case SNDRV_PCM_TRIGGER_STOP:
239 	case SNDRV_PCM_TRIGGER_SUSPEND:
240 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
241 		atc->pcm_playback_stop(atc, apcm);
242 		break;
243 	default:
244 		break;
245 	}
246 
247 	return 0;
248 }
249 
250 static snd_pcm_uframes_t
251 ct_pcm_playback_pointer(struct snd_pcm_substream *substream)
252 {
253 	unsigned long position;
254 	struct ct_atc *atc = snd_pcm_substream_chip(substream);
255 	struct snd_pcm_runtime *runtime = substream->runtime;
256 	struct ct_atc_pcm *apcm = runtime->private_data;
257 
258 	/* Read out playback position */
259 	position = atc->pcm_playback_position(atc, apcm);
260 	position = bytes_to_frames(runtime, position);
261 	if (position >= runtime->buffer_size)
262 		position = 0;
263 	return position;
264 }
265 
266 /* pcm capture operations */
267 static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
268 {
269 	struct ct_atc *atc = snd_pcm_substream_chip(substream);
270 	struct snd_pcm_runtime *runtime = substream->runtime;
271 	struct ct_atc_pcm *apcm;
272 	int err;
273 
274 	apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
275 	if (!apcm)
276 		return -ENOMEM;
277 
278 	apcm->started = 0;
279 	apcm->substream = substream;
280 	apcm->interrupt = ct_atc_pcm_interrupt;
281 	runtime->private_data = apcm;
282 	runtime->private_free = ct_atc_pcm_free_substream;
283 	runtime->hw = ct_pcm_capture_hw;
284 	runtime->hw.rate_max = atc->rsr * atc->msr;
285 
286 	err = snd_pcm_hw_constraint_integer(runtime,
287 					    SNDRV_PCM_HW_PARAM_PERIODS);
288 	if (err < 0) {
289 		kfree(apcm);
290 		return err;
291 	}
292 	err = snd_pcm_hw_constraint_minmax(runtime,
293 					   SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
294 					   1024, UINT_MAX);
295 	if (err < 0) {
296 		kfree(apcm);
297 		return err;
298 	}
299 
300 	apcm->timer = ct_timer_instance_new(atc->timer, apcm);
301 	if (!apcm->timer)
302 		return -ENOMEM;
303 
304 	return 0;
305 }
306 
307 static int ct_pcm_capture_close(struct snd_pcm_substream *substream)
308 {
309 	/* The ct_atc_pcm object will be freed by runtime->private_free */
310 	/* TODO: Notify mixer inactive. */
311 	return 0;
312 }
313 
314 static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream)
315 {
316 	int err;
317 	struct ct_atc *atc = snd_pcm_substream_chip(substream);
318 	struct snd_pcm_runtime *runtime = substream->runtime;
319 	struct ct_atc_pcm *apcm = runtime->private_data;
320 
321 	err = atc->pcm_capture_prepare(atc, apcm);
322 	if (err < 0) {
323 		printk(KERN_ERR "ctxfi: Preparing pcm capture failed!!!\n");
324 		return err;
325 	}
326 
327 	return 0;
328 }
329 
330 static int
331 ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
332 {
333 	struct ct_atc *atc = snd_pcm_substream_chip(substream);
334 	struct snd_pcm_runtime *runtime = substream->runtime;
335 	struct ct_atc_pcm *apcm = runtime->private_data;
336 
337 	switch (cmd) {
338 	case SNDRV_PCM_TRIGGER_START:
339 		atc->pcm_capture_start(atc, apcm);
340 		break;
341 	case SNDRV_PCM_TRIGGER_STOP:
342 		atc->pcm_capture_stop(atc, apcm);
343 		break;
344 	default:
345 		atc->pcm_capture_stop(atc, apcm);
346 		break;
347 	}
348 
349 	return 0;
350 }
351 
352 static snd_pcm_uframes_t
353 ct_pcm_capture_pointer(struct snd_pcm_substream *substream)
354 {
355 	unsigned long position;
356 	struct ct_atc *atc = snd_pcm_substream_chip(substream);
357 	struct snd_pcm_runtime *runtime = substream->runtime;
358 	struct ct_atc_pcm *apcm = runtime->private_data;
359 
360 	/* Read out playback position */
361 	position = atc->pcm_capture_position(atc, apcm);
362 	position = bytes_to_frames(runtime, position);
363 	if (position >= runtime->buffer_size)
364 		position = 0;
365 	return position;
366 }
367 
368 /* PCM operators for playback */
369 static struct snd_pcm_ops ct_pcm_playback_ops = {
370 	.open	 	= ct_pcm_playback_open,
371 	.close		= ct_pcm_playback_close,
372 	.ioctl		= snd_pcm_lib_ioctl,
373 	.hw_params	= ct_pcm_hw_params,
374 	.hw_free	= ct_pcm_hw_free,
375 	.prepare	= ct_pcm_playback_prepare,
376 	.trigger	= ct_pcm_playback_trigger,
377 	.pointer	= ct_pcm_playback_pointer,
378 	.page		= snd_pcm_sgbuf_ops_page,
379 };
380 
381 /* PCM operators for capture */
382 static struct snd_pcm_ops ct_pcm_capture_ops = {
383 	.open	 	= ct_pcm_capture_open,
384 	.close		= ct_pcm_capture_close,
385 	.ioctl		= snd_pcm_lib_ioctl,
386 	.hw_params	= ct_pcm_hw_params,
387 	.hw_free	= ct_pcm_hw_free,
388 	.prepare	= ct_pcm_capture_prepare,
389 	.trigger	= ct_pcm_capture_trigger,
390 	.pointer	= ct_pcm_capture_pointer,
391 	.page		= snd_pcm_sgbuf_ops_page,
392 };
393 
394 /* Create ALSA pcm device */
395 int ct_alsa_pcm_create(struct ct_atc *atc,
396 		       enum CTALSADEVS device,
397 		       const char *device_name)
398 {
399 	struct snd_pcm *pcm;
400 	int err;
401 	int playback_count, capture_count;
402 
403 	playback_count = (IEC958 == device) ? 1 : 8;
404 	capture_count = (FRONT == device) ? 1 : 0;
405 	err = snd_pcm_new(atc->card, "ctxfi", device,
406 			  playback_count, capture_count, &pcm);
407 	if (err < 0) {
408 		printk(KERN_ERR "ctxfi: snd_pcm_new failed!! Err=%d\n", err);
409 		return err;
410 	}
411 
412 	pcm->private_data = atc;
413 	pcm->info_flags = 0;
414 	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
415 	strlcpy(pcm->name, device_name, sizeof(pcm->name));
416 
417 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops);
418 
419 	if (FRONT == device)
420 		snd_pcm_set_ops(pcm,
421 				SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops);
422 
423 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
424 			snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
425 
426 #ifdef CONFIG_PM
427 	atc->pcms[device] = pcm;
428 #endif
429 
430 	return 0;
431 }
432