]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - sound/pci/ctxfi/ctpcm.c
ALSA: ctxfi - Add prefix to debug prints
[linux-2.6.git] / sound / pci / ctxfi / ctpcm.c
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 <sound/pcm.h>
20
21 /* Hardware descriptions for playback */
22 static struct snd_pcm_hardware ct_pcm_playback_hw = {
23         .info                   = (SNDRV_PCM_INFO_MMAP |
24                                    SNDRV_PCM_INFO_INTERLEAVED |
25                                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
26                                    SNDRV_PCM_INFO_MMAP_VALID |
27                                    SNDRV_PCM_INFO_PAUSE),
28         .formats                = (SNDRV_PCM_FMTBIT_U8 |
29                                    SNDRV_PCM_FMTBIT_S8 |
30                                    SNDRV_PCM_FMTBIT_S16_LE |
31                                    SNDRV_PCM_FMTBIT_U16_LE |
32                                    SNDRV_PCM_FMTBIT_S24_3LE |
33                                    SNDRV_PCM_FMTBIT_S24_LE |
34                                    SNDRV_PCM_FMTBIT_S32_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            = 1,
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                                    SNDRV_PCM_FMTBIT_U16_LE),
57         .rates                  = (SNDRV_PCM_RATE_48000 |
58                                    SNDRV_PCM_RATE_44100 |
59                                    SNDRV_PCM_RATE_32000),
60         .rate_min               = 32000,
61         .rate_max               = 48000,
62         .channels_min           = 2,
63         .channels_max           = 2,
64         .buffer_bytes_max       = (128*1024),
65         .period_bytes_min       = (64),
66         .period_bytes_max       = (128*1024),
67         .periods_min            = 1,
68         .periods_max            = 1024,
69         .fifo_size              = 0,
70 };
71
72 /* Hardware descriptions for capture */
73 static struct snd_pcm_hardware ct_pcm_capture_hw = {
74         .info                   = (SNDRV_PCM_INFO_MMAP |
75                                    SNDRV_PCM_INFO_INTERLEAVED |
76                                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
77                                    SNDRV_PCM_INFO_PAUSE |
78                                    SNDRV_PCM_INFO_MMAP_VALID),
79         .formats                = (SNDRV_PCM_FMTBIT_U8 |
80                                    SNDRV_PCM_FMTBIT_S8 |
81                                    SNDRV_PCM_FMTBIT_S16_LE |
82                                    SNDRV_PCM_FMTBIT_U16_LE |
83                                    SNDRV_PCM_FMTBIT_S24_3LE |
84                                    SNDRV_PCM_FMTBIT_S24_LE |
85                                    SNDRV_PCM_FMTBIT_S32_LE),
86         .rates                  = (SNDRV_PCM_RATE_CONTINUOUS |
87                                    SNDRV_PCM_RATE_8000_96000),
88         .rate_min               = 8000,
89         .rate_max               = 96000,
90         .channels_min           = 1,
91         .channels_max           = 2,
92         .buffer_bytes_max       = (128*1024),
93         .period_bytes_min       = (384),
94         .period_bytes_max       = (64*1024),
95         .periods_min            = 2,
96         .periods_max            = 1024,
97         .fifo_size              = 0,
98 };
99
100 static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm)
101 {
102         struct ct_atc_pcm *apcm = atc_pcm;
103
104         if (NULL == apcm->substream)
105                 return;
106
107         snd_pcm_period_elapsed(apcm->substream);
108 }
109
110 static void ct_atc_pcm_free_substream(struct snd_pcm_runtime *runtime)
111 {
112         struct ct_atc_pcm *apcm = runtime->private_data;
113         struct ct_atc *atc = snd_pcm_substream_chip(apcm->substream);
114
115         atc->pcm_release_resources(atc, apcm);
116         kfree(apcm);
117         runtime->private_data = NULL;
118 }
119
120 /* pcm playback operations */
121 static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
122 {
123         struct ct_atc *atc = snd_pcm_substream_chip(substream);
124         struct snd_pcm_runtime *runtime = substream->runtime;
125         struct ct_atc_pcm *apcm;
126         int err;
127
128         apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
129         if (NULL == apcm)
130                 return -ENOMEM;
131
132         spin_lock_init(&apcm->timer_lock);
133         apcm->stop_timer = 0;
134         apcm->substream = substream;
135         apcm->interrupt = ct_atc_pcm_interrupt;
136         runtime->private_data = apcm;
137         runtime->private_free = ct_atc_pcm_free_substream;
138         if (IEC958 == substream->pcm->device) {
139                 runtime->hw = ct_spdif_passthru_playback_hw;
140                 atc->spdif_out_passthru(atc, 1);
141         } else {
142                 runtime->hw = ct_pcm_playback_hw;
143                 if (FRONT == substream->pcm->device)
144                         runtime->hw.channels_max = 8;
145         }
146
147         err = snd_pcm_hw_constraint_integer(runtime,
148                                             SNDRV_PCM_HW_PARAM_PERIODS);
149         if (err < 0) {
150                 kfree(apcm);
151                 return err;
152         }
153         err = snd_pcm_hw_constraint_minmax(runtime,
154                                            SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
155                                            1024, UINT_MAX);
156         if (err < 0) {
157                 kfree(apcm);
158                 return err;
159         }
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         return snd_pcm_lib_malloc_pages(substream,
181                                         params_buffer_bytes(hw_params));
182 }
183
184 static int ct_pcm_hw_free(struct snd_pcm_substream *substream)
185 {
186         /* Free snd-allocated pages */
187         return snd_pcm_lib_free_pages(substream);
188 }
189
190 static void ct_pcm_timer_callback(unsigned long data)
191 {
192         struct ct_atc_pcm *apcm = (struct ct_atc_pcm *)data;
193         struct snd_pcm_substream *substream = apcm->substream;
194         struct snd_pcm_runtime *runtime = substream->runtime;
195         unsigned int period_size = runtime->period_size;
196         unsigned int buffer_size = runtime->buffer_size;
197         unsigned long flags;
198         unsigned int position = 0, dist = 0, interval = 0;
199
200         position = substream->ops->pointer(substream);
201         dist = (position + buffer_size - apcm->position) % buffer_size;
202         if ((dist >= period_size) ||
203                 (position/period_size != apcm->position/period_size)) {
204                 apcm->interrupt(apcm);
205                 apcm->position = position;
206         }
207         /* Add extra HZ*5/1000 to avoid overrun issue when recording
208          * at 8kHz in 8-bit format or at 88kHz in 24-bit format. */
209         interval = ((period_size - (position % period_size))
210                    * HZ + (runtime->rate - 1)) / runtime->rate + HZ * 5 / 1000;
211         spin_lock_irqsave(&apcm->timer_lock, flags);
212         apcm->timer.expires = jiffies + interval;
213         if (!apcm->stop_timer)
214                 add_timer(&apcm->timer);
215
216         spin_unlock_irqrestore(&apcm->timer_lock, flags);
217 }
218
219 static int ct_pcm_timer_prepare(struct ct_atc_pcm *apcm)
220 {
221         unsigned long flags;
222
223         spin_lock_irqsave(&apcm->timer_lock, flags);
224         if (timer_pending(&apcm->timer)) {
225                 /* The timer has already been started. */
226                 spin_unlock_irqrestore(&apcm->timer_lock, flags);
227                 return 0;
228         }
229
230         init_timer(&apcm->timer);
231         apcm->timer.data = (unsigned long)apcm;
232         apcm->timer.function = ct_pcm_timer_callback;
233         spin_unlock_irqrestore(&apcm->timer_lock, flags);
234         apcm->position = 0;
235
236         return 0;
237 }
238
239 static int ct_pcm_timer_start(struct ct_atc_pcm *apcm)
240 {
241         struct snd_pcm_runtime *runtime = apcm->substream->runtime;
242         unsigned long flags;
243
244         spin_lock_irqsave(&apcm->timer_lock, flags);
245         if (timer_pending(&apcm->timer)) {
246                 /* The timer has already been started. */
247                 spin_unlock_irqrestore(&apcm->timer_lock, flags);
248                 return 0;
249         }
250
251         apcm->timer.expires = jiffies + (runtime->period_size * HZ +
252                                 (runtime->rate - 1)) / runtime->rate;
253         apcm->stop_timer = 0;
254         add_timer(&apcm->timer);
255         spin_unlock_irqrestore(&apcm->timer_lock, flags);
256
257         return 0;
258 }
259
260 static int ct_pcm_timer_stop(struct ct_atc_pcm *apcm)
261 {
262         unsigned long flags;
263
264         spin_lock_irqsave(&apcm->timer_lock, flags);
265         apcm->stop_timer = 1;
266         del_timer(&apcm->timer);
267         spin_unlock_irqrestore(&apcm->timer_lock, flags);
268
269         try_to_del_timer_sync(&apcm->timer);
270
271         return 0;
272 }
273
274 static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream)
275 {
276         int err;
277         struct ct_atc *atc = snd_pcm_substream_chip(substream);
278         struct snd_pcm_runtime *runtime = substream->runtime;
279         struct ct_atc_pcm *apcm = runtime->private_data;
280
281         if (IEC958 == substream->pcm->device)
282                 err = atc->spdif_passthru_playback_prepare(atc, apcm);
283         else
284                 err = atc->pcm_playback_prepare(atc, apcm);
285
286         if (err < 0) {
287                 printk(KERN_ERR "ctxfi: Preparing pcm playback failed!!!\n");
288                 return err;
289         }
290
291         ct_pcm_timer_prepare(apcm);
292
293         return 0;
294 }
295
296 static int
297 ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
298 {
299         struct ct_atc *atc = snd_pcm_substream_chip(substream);
300         struct snd_pcm_runtime *runtime = substream->runtime;
301         struct ct_atc_pcm *apcm = runtime->private_data;
302
303         switch (cmd) {
304         case SNDRV_PCM_TRIGGER_START:
305         case SNDRV_PCM_TRIGGER_RESUME:
306         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
307                 atc->pcm_playback_start(atc, apcm);
308                 ct_pcm_timer_start(apcm);
309                 break;
310         case SNDRV_PCM_TRIGGER_STOP:
311         case SNDRV_PCM_TRIGGER_SUSPEND:
312         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
313                 ct_pcm_timer_stop(apcm);
314                 atc->pcm_playback_stop(atc, apcm);
315                 break;
316         default:
317                 break;
318         }
319
320         return 0;
321 }
322
323 static snd_pcm_uframes_t
324 ct_pcm_playback_pointer(struct snd_pcm_substream *substream)
325 {
326         unsigned long position;
327         struct ct_atc *atc = snd_pcm_substream_chip(substream);
328         struct snd_pcm_runtime *runtime = substream->runtime;
329         struct ct_atc_pcm *apcm = runtime->private_data;
330
331         /* Read out playback position */
332         position = atc->pcm_playback_position(atc, apcm);
333         position = bytes_to_frames(runtime, position);
334         return position;
335 }
336
337 /* pcm capture operations */
338 static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
339 {
340         struct ct_atc *atc = snd_pcm_substream_chip(substream);
341         struct snd_pcm_runtime *runtime = substream->runtime;
342         struct ct_atc_pcm *apcm;
343         int err;
344
345         apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
346         if (NULL == apcm)
347                 return -ENOMEM;
348
349         spin_lock_init(&apcm->timer_lock);
350         apcm->started = 0;
351         apcm->stop_timer = 0;
352         apcm->substream = substream;
353         apcm->interrupt = ct_atc_pcm_interrupt;
354         runtime->private_data = apcm;
355         runtime->private_free = ct_atc_pcm_free_substream;
356         runtime->hw = ct_pcm_capture_hw;
357         runtime->hw.rate_max = atc->rsr * atc->msr;
358
359         err = snd_pcm_hw_constraint_integer(runtime,
360                                             SNDRV_PCM_HW_PARAM_PERIODS);
361         if (err < 0) {
362                 kfree(apcm);
363                 return err;
364         }
365         err = snd_pcm_hw_constraint_minmax(runtime,
366                                            SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
367                                            1024, UINT_MAX);
368         if (err < 0) {
369                 kfree(apcm);
370                 return err;
371         }
372
373         return 0;
374 }
375
376 static int ct_pcm_capture_close(struct snd_pcm_substream *substream)
377 {
378         /* The ct_atc_pcm object will be freed by runtime->private_free */
379         /* TODO: Notify mixer inactive. */
380         return 0;
381 }
382
383 static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream)
384 {
385         int err;
386         struct ct_atc *atc = snd_pcm_substream_chip(substream);
387         struct snd_pcm_runtime *runtime = substream->runtime;
388         struct ct_atc_pcm *apcm = runtime->private_data;
389
390         err = atc->pcm_capture_prepare(atc, apcm);
391         if (err < 0) {
392                 printk(KERN_ERR "ctxfi: Preparing pcm capture failed!!!\n");
393                 return err;
394         }
395
396         ct_pcm_timer_prepare(apcm);
397
398         return 0;
399 }
400
401 static int
402 ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
403 {
404         struct ct_atc *atc = snd_pcm_substream_chip(substream);
405         struct snd_pcm_runtime *runtime = substream->runtime;
406         struct ct_atc_pcm *apcm = runtime->private_data;
407
408         switch (cmd) {
409         case SNDRV_PCM_TRIGGER_START:
410                 atc->pcm_capture_start(atc, apcm);
411                 ct_pcm_timer_start(apcm);
412                 break;
413         case SNDRV_PCM_TRIGGER_STOP:
414                 ct_pcm_timer_stop(apcm);
415                 atc->pcm_capture_stop(atc, apcm);
416                 break;
417         default:
418                 ct_pcm_timer_stop(apcm);
419                 atc->pcm_capture_stop(atc, apcm);
420                 break;
421         }
422
423         return 0;
424 }
425
426 static snd_pcm_uframes_t
427 ct_pcm_capture_pointer(struct snd_pcm_substream *substream)
428 {
429         unsigned long position;
430         struct ct_atc *atc = snd_pcm_substream_chip(substream);
431         struct snd_pcm_runtime *runtime = substream->runtime;
432         struct ct_atc_pcm *apcm = runtime->private_data;
433
434         /* Read out playback position */
435         position = atc->pcm_capture_position(atc, apcm);
436         position = bytes_to_frames(runtime, position);
437         return position;
438 }
439
440 /* PCM operators for playback */
441 static struct snd_pcm_ops ct_pcm_playback_ops = {
442         .open           = ct_pcm_playback_open,
443         .close          = ct_pcm_playback_close,
444         .ioctl          = snd_pcm_lib_ioctl,
445         .hw_params      = ct_pcm_hw_params,
446         .hw_free        = ct_pcm_hw_free,
447         .prepare        = ct_pcm_playback_prepare,
448         .trigger        = ct_pcm_playback_trigger,
449         .pointer        = ct_pcm_playback_pointer,
450 };
451
452 /* PCM operators for capture */
453 static struct snd_pcm_ops ct_pcm_capture_ops = {
454         .open           = ct_pcm_capture_open,
455         .close          = ct_pcm_capture_close,
456         .ioctl          = snd_pcm_lib_ioctl,
457         .hw_params      = ct_pcm_hw_params,
458         .hw_free        = ct_pcm_hw_free,
459         .prepare        = ct_pcm_capture_prepare,
460         .trigger        = ct_pcm_capture_trigger,
461         .pointer        = ct_pcm_capture_pointer,
462 };
463
464 /* Create ALSA pcm device */
465 int ct_alsa_pcm_create(struct ct_atc *atc,
466                        enum CTALSADEVS device,
467                        const char *device_name)
468 {
469         struct snd_pcm *pcm;
470         int err;
471         int playback_count, capture_count;
472         char name[128];
473
474         strncpy(name, device_name, sizeof(name));
475         playback_count = (IEC958 == device) ? 1 : 8;
476         capture_count = (FRONT == device) ? 1 : 0;
477         err = snd_pcm_new(atc->card, name, device,
478                           playback_count, capture_count, &pcm);
479         if (err < 0) {
480                 printk(KERN_ERR "ctxfi: snd_pcm_new failed!! Err=%d\n", err);
481                 return err;
482         }
483
484         pcm->private_data = atc;
485         pcm->info_flags = 0;
486         pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
487         strcpy(pcm->name, device_name);
488
489         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops);
490
491         if (FRONT == device)
492                 snd_pcm_set_ops(pcm,
493                                 SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops);
494
495         snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
496                         snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
497
498         return 0;
499 }