Merge branch 'rbd-sysfs' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[pandora-kernel.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 "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         if (IEC958 == substream->pcm->device) {
133                 runtime->hw = ct_spdif_passthru_playback_hw;
134                 atc->spdif_out_passthru(atc, 1);
135         } else {
136                 runtime->hw = ct_pcm_playback_hw;
137                 if (FRONT == substream->pcm->device)
138                         runtime->hw.channels_max = 8;
139         }
140
141         err = snd_pcm_hw_constraint_integer(runtime,
142                                             SNDRV_PCM_HW_PARAM_PERIODS);
143         if (err < 0) {
144                 kfree(apcm);
145                 return err;
146         }
147         err = snd_pcm_hw_constraint_minmax(runtime,
148                                            SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
149                                            1024, UINT_MAX);
150         if (err < 0) {
151                 kfree(apcm);
152                 return err;
153         }
154
155         apcm->timer = ct_timer_instance_new(atc->timer, apcm);
156         if (!apcm->timer) {
157                 kfree(apcm);
158                 return -ENOMEM;
159         }
160         runtime->private_data = apcm;
161         runtime->private_free = ct_atc_pcm_free_substream;
162
163         return 0;
164 }
165
166 static int ct_pcm_playback_close(struct snd_pcm_substream *substream)
167 {
168         struct ct_atc *atc = snd_pcm_substream_chip(substream);
169
170         /* TODO: Notify mixer inactive. */
171         if (IEC958 == substream->pcm->device)
172                 atc->spdif_out_passthru(atc, 0);
173
174         /* The ct_atc_pcm object will be freed by runtime->private_free */
175
176         return 0;
177 }
178
179 static int ct_pcm_hw_params(struct snd_pcm_substream *substream,
180                                      struct snd_pcm_hw_params *hw_params)
181 {
182         struct ct_atc *atc = snd_pcm_substream_chip(substream);
183         struct ct_atc_pcm *apcm = substream->runtime->private_data;
184         int err;
185
186         err = snd_pcm_lib_malloc_pages(substream,
187                                         params_buffer_bytes(hw_params));
188         if (err < 0)
189                 return err;
190         /* clear previous resources */
191         atc->pcm_release_resources(atc, apcm);
192         return err;
193 }
194
195 static int ct_pcm_hw_free(struct snd_pcm_substream *substream)
196 {
197         struct ct_atc *atc = snd_pcm_substream_chip(substream);
198         struct ct_atc_pcm *apcm = substream->runtime->private_data;
199
200         /* clear previous resources */
201         atc->pcm_release_resources(atc, apcm);
202         /* Free snd-allocated pages */
203         return snd_pcm_lib_free_pages(substream);
204 }
205
206
207 static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream)
208 {
209         int err;
210         struct ct_atc *atc = snd_pcm_substream_chip(substream);
211         struct snd_pcm_runtime *runtime = substream->runtime;
212         struct ct_atc_pcm *apcm = runtime->private_data;
213
214         if (IEC958 == substream->pcm->device)
215                 err = atc->spdif_passthru_playback_prepare(atc, apcm);
216         else
217                 err = atc->pcm_playback_prepare(atc, apcm);
218
219         if (err < 0) {
220                 printk(KERN_ERR "ctxfi: Preparing pcm playback failed!!!\n");
221                 return err;
222         }
223
224         return 0;
225 }
226
227 static int
228 ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
229 {
230         struct ct_atc *atc = snd_pcm_substream_chip(substream);
231         struct snd_pcm_runtime *runtime = substream->runtime;
232         struct ct_atc_pcm *apcm = runtime->private_data;
233
234         switch (cmd) {
235         case SNDRV_PCM_TRIGGER_START:
236         case SNDRV_PCM_TRIGGER_RESUME:
237         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
238                 atc->pcm_playback_start(atc, apcm);
239                 break;
240         case SNDRV_PCM_TRIGGER_STOP:
241         case SNDRV_PCM_TRIGGER_SUSPEND:
242         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
243                 atc->pcm_playback_stop(atc, apcm);
244                 break;
245         default:
246                 break;
247         }
248
249         return 0;
250 }
251
252 static snd_pcm_uframes_t
253 ct_pcm_playback_pointer(struct snd_pcm_substream *substream)
254 {
255         unsigned long position;
256         struct ct_atc *atc = snd_pcm_substream_chip(substream);
257         struct snd_pcm_runtime *runtime = substream->runtime;
258         struct ct_atc_pcm *apcm = runtime->private_data;
259
260         /* Read out playback position */
261         position = atc->pcm_playback_position(atc, apcm);
262         position = bytes_to_frames(runtime, position);
263         if (position >= runtime->buffer_size)
264                 position = 0;
265         return position;
266 }
267
268 /* pcm capture operations */
269 static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
270 {
271         struct ct_atc *atc = snd_pcm_substream_chip(substream);
272         struct snd_pcm_runtime *runtime = substream->runtime;
273         struct ct_atc_pcm *apcm;
274         int err;
275
276         apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
277         if (!apcm)
278                 return -ENOMEM;
279
280         apcm->started = 0;
281         apcm->substream = substream;
282         apcm->interrupt = ct_atc_pcm_interrupt;
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                 kfree(apcm);
303                 return -ENOMEM;
304         }
305         runtime->private_data = apcm;
306         runtime->private_free = ct_atc_pcm_free_substream;
307
308         return 0;
309 }
310
311 static int ct_pcm_capture_close(struct snd_pcm_substream *substream)
312 {
313         /* The ct_atc_pcm object will be freed by runtime->private_free */
314         /* TODO: Notify mixer inactive. */
315         return 0;
316 }
317
318 static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream)
319 {
320         int err;
321         struct ct_atc *atc = snd_pcm_substream_chip(substream);
322         struct snd_pcm_runtime *runtime = substream->runtime;
323         struct ct_atc_pcm *apcm = runtime->private_data;
324
325         err = atc->pcm_capture_prepare(atc, apcm);
326         if (err < 0) {
327                 printk(KERN_ERR "ctxfi: Preparing pcm capture failed!!!\n");
328                 return err;
329         }
330
331         return 0;
332 }
333
334 static int
335 ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
336 {
337         struct ct_atc *atc = snd_pcm_substream_chip(substream);
338         struct snd_pcm_runtime *runtime = substream->runtime;
339         struct ct_atc_pcm *apcm = runtime->private_data;
340
341         switch (cmd) {
342         case SNDRV_PCM_TRIGGER_START:
343                 atc->pcm_capture_start(atc, apcm);
344                 break;
345         case SNDRV_PCM_TRIGGER_STOP:
346                 atc->pcm_capture_stop(atc, apcm);
347                 break;
348         default:
349                 atc->pcm_capture_stop(atc, apcm);
350                 break;
351         }
352
353         return 0;
354 }
355
356 static snd_pcm_uframes_t
357 ct_pcm_capture_pointer(struct snd_pcm_substream *substream)
358 {
359         unsigned long position;
360         struct ct_atc *atc = snd_pcm_substream_chip(substream);
361         struct snd_pcm_runtime *runtime = substream->runtime;
362         struct ct_atc_pcm *apcm = runtime->private_data;
363
364         /* Read out playback position */
365         position = atc->pcm_capture_position(atc, apcm);
366         position = bytes_to_frames(runtime, position);
367         if (position >= runtime->buffer_size)
368                 position = 0;
369         return position;
370 }
371
372 /* PCM operators for playback */
373 static struct snd_pcm_ops ct_pcm_playback_ops = {
374         .open           = ct_pcm_playback_open,
375         .close          = ct_pcm_playback_close,
376         .ioctl          = snd_pcm_lib_ioctl,
377         .hw_params      = ct_pcm_hw_params,
378         .hw_free        = ct_pcm_hw_free,
379         .prepare        = ct_pcm_playback_prepare,
380         .trigger        = ct_pcm_playback_trigger,
381         .pointer        = ct_pcm_playback_pointer,
382         .page           = snd_pcm_sgbuf_ops_page,
383 };
384
385 /* PCM operators for capture */
386 static struct snd_pcm_ops ct_pcm_capture_ops = {
387         .open           = ct_pcm_capture_open,
388         .close          = ct_pcm_capture_close,
389         .ioctl          = snd_pcm_lib_ioctl,
390         .hw_params      = ct_pcm_hw_params,
391         .hw_free        = ct_pcm_hw_free,
392         .prepare        = ct_pcm_capture_prepare,
393         .trigger        = ct_pcm_capture_trigger,
394         .pointer        = ct_pcm_capture_pointer,
395         .page           = snd_pcm_sgbuf_ops_page,
396 };
397
398 /* Create ALSA pcm device */
399 int ct_alsa_pcm_create(struct ct_atc *atc,
400                        enum CTALSADEVS device,
401                        const char *device_name)
402 {
403         struct snd_pcm *pcm;
404         int err;
405         int playback_count, capture_count;
406
407         playback_count = (IEC958 == device) ? 1 : 8;
408         capture_count = (FRONT == device) ? 1 : 0;
409         err = snd_pcm_new(atc->card, "ctxfi", device,
410                           playback_count, capture_count, &pcm);
411         if (err < 0) {
412                 printk(KERN_ERR "ctxfi: snd_pcm_new failed!! Err=%d\n", err);
413                 return err;
414         }
415
416         pcm->private_data = atc;
417         pcm->info_flags = 0;
418         pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
419         strlcpy(pcm->name, device_name, sizeof(pcm->name));
420
421         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops);
422
423         if (FRONT == device)
424                 snd_pcm_set_ops(pcm,
425                                 SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops);
426
427         snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
428                         snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
429
430 #ifdef CONFIG_PM
431         atc->pcms[device] = pcm;
432 #endif
433
434         return 0;
435 }