2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
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.
11 * This file contains the definition of the pcm device functions.
20 #include <linux/slab.h>
21 #include <sound/pcm.h>
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
),
41 .buffer_bytes_max
= (128*1024),
42 .period_bytes_min
= (64),
43 .period_bytes_max
= (128*1024),
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
),
63 .buffer_bytes_max
= (128*1024),
64 .period_bytes_min
= (64),
65 .period_bytes_max
= (128*1024),
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
),
89 .buffer_bytes_max
= (128*1024),
90 .period_bytes_min
= (384),
91 .period_bytes_max
= (64*1024),
97 static void ct_atc_pcm_interrupt(struct ct_atc_pcm
*atc_pcm
)
99 struct ct_atc_pcm
*apcm
= atc_pcm
;
101 if (!apcm
->substream
)
104 snd_pcm_period_elapsed(apcm
->substream
);
107 static void ct_atc_pcm_free_substream(struct snd_pcm_runtime
*runtime
)
109 struct ct_atc_pcm
*apcm
= runtime
->private_data
;
110 struct ct_atc
*atc
= snd_pcm_substream_chip(apcm
->substream
);
112 atc
->pcm_release_resources(atc
, apcm
);
113 ct_timer_instance_free(apcm
->timer
);
115 runtime
->private_data
= NULL
;
118 /* pcm playback operations */
119 static int ct_pcm_playback_open(struct snd_pcm_substream
*substream
)
121 struct ct_atc
*atc
= snd_pcm_substream_chip(substream
);
122 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
123 struct ct_atc_pcm
*apcm
;
126 apcm
= kzalloc(sizeof(*apcm
), GFP_KERNEL
);
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);
138 runtime
->hw
= ct_pcm_playback_hw
;
139 if (FRONT
== substream
->pcm
->device
)
140 runtime
->hw
.channels_max
= 8;
143 err
= snd_pcm_hw_constraint_integer(runtime
,
144 SNDRV_PCM_HW_PARAM_PERIODS
);
149 err
= snd_pcm_hw_constraint_minmax(runtime
,
150 SNDRV_PCM_HW_PARAM_BUFFER_BYTES
,
157 apcm
->timer
= ct_timer_instance_new(atc
->timer
, apcm
);
164 static int ct_pcm_playback_close(struct snd_pcm_substream
*substream
)
166 struct ct_atc
*atc
= snd_pcm_substream_chip(substream
);
168 /* TODO: Notify mixer inactive. */
169 if (IEC958
== substream
->pcm
->device
)
170 atc
->spdif_out_passthru(atc
, 0);
172 /* The ct_atc_pcm object will be freed by runtime->private_free */
177 static int ct_pcm_hw_params(struct snd_pcm_substream
*substream
,
178 struct snd_pcm_hw_params
*hw_params
)
180 struct ct_atc
*atc
= snd_pcm_substream_chip(substream
);
181 struct ct_atc_pcm
*apcm
= substream
->runtime
->private_data
;
184 err
= snd_pcm_lib_malloc_pages(substream
,
185 params_buffer_bytes(hw_params
));
188 /* clear previous resources */
189 atc
->pcm_release_resources(atc
, apcm
);
193 static int ct_pcm_hw_free(struct snd_pcm_substream
*substream
)
195 struct ct_atc
*atc
= snd_pcm_substream_chip(substream
);
196 struct ct_atc_pcm
*apcm
= substream
->runtime
->private_data
;
198 /* clear previous resources */
199 atc
->pcm_release_resources(atc
, apcm
);
200 /* Free snd-allocated pages */
201 return snd_pcm_lib_free_pages(substream
);
205 static int ct_pcm_playback_prepare(struct snd_pcm_substream
*substream
)
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
;
212 if (IEC958
== substream
->pcm
->device
)
213 err
= atc
->spdif_passthru_playback_prepare(atc
, apcm
);
215 err
= atc
->pcm_playback_prepare(atc
, apcm
);
218 printk(KERN_ERR
"ctxfi: Preparing pcm playback failed!!!\n");
226 ct_pcm_playback_trigger(struct snd_pcm_substream
*substream
, int cmd
)
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
;
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
);
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
);
250 static snd_pcm_uframes_t
251 ct_pcm_playback_pointer(struct snd_pcm_substream
*substream
)
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
;
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
)
266 /* pcm capture operations */
267 static int ct_pcm_capture_open(struct snd_pcm_substream
*substream
)
269 struct ct_atc
*atc
= snd_pcm_substream_chip(substream
);
270 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
271 struct ct_atc_pcm
*apcm
;
274 apcm
= kzalloc(sizeof(*apcm
), GFP_KERNEL
);
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
;
286 err
= snd_pcm_hw_constraint_integer(runtime
,
287 SNDRV_PCM_HW_PARAM_PERIODS
);
292 err
= snd_pcm_hw_constraint_minmax(runtime
,
293 SNDRV_PCM_HW_PARAM_BUFFER_BYTES
,
300 apcm
->timer
= ct_timer_instance_new(atc
->timer
, apcm
);
307 static int ct_pcm_capture_close(struct snd_pcm_substream
*substream
)
309 /* The ct_atc_pcm object will be freed by runtime->private_free */
310 /* TODO: Notify mixer inactive. */
314 static int ct_pcm_capture_prepare(struct snd_pcm_substream
*substream
)
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
;
321 err
= atc
->pcm_capture_prepare(atc
, apcm
);
323 printk(KERN_ERR
"ctxfi: Preparing pcm capture failed!!!\n");
331 ct_pcm_capture_trigger(struct snd_pcm_substream
*substream
, int cmd
)
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
;
338 case SNDRV_PCM_TRIGGER_START
:
339 atc
->pcm_capture_start(atc
, apcm
);
341 case SNDRV_PCM_TRIGGER_STOP
:
342 atc
->pcm_capture_stop(atc
, apcm
);
345 atc
->pcm_capture_stop(atc
, apcm
);
352 static snd_pcm_uframes_t
353 ct_pcm_capture_pointer(struct snd_pcm_substream
*substream
)
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
;
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
)
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
,
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
,
394 /* Create ALSA pcm device */
395 int ct_alsa_pcm_create(struct ct_atc
*atc
,
396 enum CTALSADEVS device
,
397 const char *device_name
)
401 int playback_count
, capture_count
;
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
);
408 printk(KERN_ERR
"ctxfi: snd_pcm_new failed!! Err=%d\n", err
);
412 pcm
->private_data
= atc
;
414 pcm
->dev_subclass
= SNDRV_PCM_SUBCLASS_GENERIC_MIX
;
415 strlcpy(pcm
->name
, device_name
, sizeof(pcm
->name
));
417 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_PLAYBACK
, &ct_pcm_playback_ops
);
421 SNDRV_PCM_STREAM_CAPTURE
, &ct_pcm_capture_ops
);
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);
427 atc
->pcms
[device
] = pcm
;