Merge git://git.kernel.org/pub/scm/linux/kernel/git/hirofumi/fatfs-2.6
[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         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 }