net: dsa: mt7530: set CPU port to fallback mode
[linux/fpc-iii.git] / sound / pci / ctxfi / ctpcm.c
blobb36e37ae2b519b64bdf24e0b2ff9dd8ce11375f9
1 /**
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.
8 * @File ctpcm.c
10 * @Brief
11 * This file contains the definition of the pcm device functions.
13 * @Author Liu Chun
14 * @Date Apr 2 2008
18 #include "ctpcm.h"
19 #include "cttimer.h"
20 #include <linux/slab.h>
21 #include <sound/pcm.h>
23 /* Hardware descriptions for playback */
24 static const 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,
49 static const 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,
71 /* Hardware descriptions for capture */
72 static const 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,
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)
102 return;
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);
114 kfree(apcm);
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;
124 int err;
126 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
127 if (!apcm)
128 return -ENOMEM;
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;
141 err = snd_pcm_hw_constraint_integer(runtime,
142 SNDRV_PCM_HW_PARAM_PERIODS);
143 if (err < 0)
144 goto free_pcm;
146 err = snd_pcm_hw_constraint_minmax(runtime,
147 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
148 1024, UINT_MAX);
149 if (err < 0)
150 goto free_pcm;
152 apcm->timer = ct_timer_instance_new(atc->timer, apcm);
153 if (!apcm->timer) {
154 err = -ENOMEM;
155 goto free_pcm;
157 runtime->private_data = apcm;
158 runtime->private_free = ct_atc_pcm_free_substream;
160 return 0;
162 free_pcm:
163 kfree(apcm);
164 return err;
167 static int ct_pcm_playback_close(struct snd_pcm_substream *substream)
169 struct ct_atc *atc = snd_pcm_substream_chip(substream);
171 /* TODO: Notify mixer inactive. */
172 if (IEC958 == substream->pcm->device)
173 atc->spdif_out_passthru(atc, 0);
175 /* The ct_atc_pcm object will be freed by runtime->private_free */
177 return 0;
180 static int ct_pcm_hw_params(struct snd_pcm_substream *substream,
181 struct snd_pcm_hw_params *hw_params)
183 struct ct_atc *atc = snd_pcm_substream_chip(substream);
184 struct ct_atc_pcm *apcm = substream->runtime->private_data;
185 int err;
187 err = snd_pcm_lib_malloc_pages(substream,
188 params_buffer_bytes(hw_params));
189 if (err < 0)
190 return err;
191 /* clear previous resources */
192 atc->pcm_release_resources(atc, apcm);
193 return err;
196 static int ct_pcm_hw_free(struct snd_pcm_substream *substream)
198 struct ct_atc *atc = snd_pcm_substream_chip(substream);
199 struct ct_atc_pcm *apcm = substream->runtime->private_data;
201 /* clear previous resources */
202 atc->pcm_release_resources(atc, apcm);
203 /* Free snd-allocated pages */
204 return snd_pcm_lib_free_pages(substream);
208 static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream)
210 int err;
211 struct ct_atc *atc = snd_pcm_substream_chip(substream);
212 struct snd_pcm_runtime *runtime = substream->runtime;
213 struct ct_atc_pcm *apcm = runtime->private_data;
215 if (IEC958 == substream->pcm->device)
216 err = atc->spdif_passthru_playback_prepare(atc, apcm);
217 else
218 err = atc->pcm_playback_prepare(atc, apcm);
220 if (err < 0) {
221 dev_err(atc->card->dev,
222 "Preparing pcm playback failed!!!\n");
223 return err;
226 return 0;
229 static int
230 ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
232 struct ct_atc *atc = snd_pcm_substream_chip(substream);
233 struct snd_pcm_runtime *runtime = substream->runtime;
234 struct ct_atc_pcm *apcm = runtime->private_data;
236 switch (cmd) {
237 case SNDRV_PCM_TRIGGER_START:
238 case SNDRV_PCM_TRIGGER_RESUME:
239 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
240 atc->pcm_playback_start(atc, apcm);
241 break;
242 case SNDRV_PCM_TRIGGER_STOP:
243 case SNDRV_PCM_TRIGGER_SUSPEND:
244 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
245 atc->pcm_playback_stop(atc, apcm);
246 break;
247 default:
248 break;
251 return 0;
254 static snd_pcm_uframes_t
255 ct_pcm_playback_pointer(struct snd_pcm_substream *substream)
257 unsigned long position;
258 struct ct_atc *atc = snd_pcm_substream_chip(substream);
259 struct snd_pcm_runtime *runtime = substream->runtime;
260 struct ct_atc_pcm *apcm = runtime->private_data;
262 /* Read out playback position */
263 position = atc->pcm_playback_position(atc, apcm);
264 position = bytes_to_frames(runtime, position);
265 if (position >= runtime->buffer_size)
266 position = 0;
267 return position;
270 /* pcm capture operations */
271 static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
273 struct ct_atc *atc = snd_pcm_substream_chip(substream);
274 struct snd_pcm_runtime *runtime = substream->runtime;
275 struct ct_atc_pcm *apcm;
276 int err;
278 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
279 if (!apcm)
280 return -ENOMEM;
282 apcm->started = 0;
283 apcm->substream = substream;
284 apcm->interrupt = ct_atc_pcm_interrupt;
285 runtime->hw = ct_pcm_capture_hw;
286 runtime->hw.rate_max = atc->rsr * atc->msr;
288 err = snd_pcm_hw_constraint_integer(runtime,
289 SNDRV_PCM_HW_PARAM_PERIODS);
290 if (err < 0)
291 goto free_pcm;
293 err = snd_pcm_hw_constraint_minmax(runtime,
294 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
295 1024, UINT_MAX);
296 if (err < 0)
297 goto free_pcm;
299 apcm->timer = ct_timer_instance_new(atc->timer, apcm);
300 if (!apcm->timer) {
301 err = -ENOMEM;
302 goto free_pcm;
304 runtime->private_data = apcm;
305 runtime->private_free = ct_atc_pcm_free_substream;
307 return 0;
309 free_pcm:
310 kfree(apcm);
311 return err;
314 static int ct_pcm_capture_close(struct snd_pcm_substream *substream)
316 /* The ct_atc_pcm object will be freed by runtime->private_free */
317 /* TODO: Notify mixer inactive. */
318 return 0;
321 static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream)
323 int err;
324 struct ct_atc *atc = snd_pcm_substream_chip(substream);
325 struct snd_pcm_runtime *runtime = substream->runtime;
326 struct ct_atc_pcm *apcm = runtime->private_data;
328 err = atc->pcm_capture_prepare(atc, apcm);
329 if (err < 0) {
330 dev_err(atc->card->dev,
331 "Preparing pcm capture failed!!!\n");
332 return err;
335 return 0;
338 static int
339 ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
341 struct ct_atc *atc = snd_pcm_substream_chip(substream);
342 struct snd_pcm_runtime *runtime = substream->runtime;
343 struct ct_atc_pcm *apcm = runtime->private_data;
345 switch (cmd) {
346 case SNDRV_PCM_TRIGGER_START:
347 atc->pcm_capture_start(atc, apcm);
348 break;
349 case SNDRV_PCM_TRIGGER_STOP:
350 atc->pcm_capture_stop(atc, apcm);
351 break;
352 default:
353 atc->pcm_capture_stop(atc, apcm);
354 break;
357 return 0;
360 static snd_pcm_uframes_t
361 ct_pcm_capture_pointer(struct snd_pcm_substream *substream)
363 unsigned long position;
364 struct ct_atc *atc = snd_pcm_substream_chip(substream);
365 struct snd_pcm_runtime *runtime = substream->runtime;
366 struct ct_atc_pcm *apcm = runtime->private_data;
368 /* Read out playback position */
369 position = atc->pcm_capture_position(atc, apcm);
370 position = bytes_to_frames(runtime, position);
371 if (position >= runtime->buffer_size)
372 position = 0;
373 return position;
376 /* PCM operators for playback */
377 static const struct snd_pcm_ops ct_pcm_playback_ops = {
378 .open = ct_pcm_playback_open,
379 .close = ct_pcm_playback_close,
380 .ioctl = snd_pcm_lib_ioctl,
381 .hw_params = ct_pcm_hw_params,
382 .hw_free = ct_pcm_hw_free,
383 .prepare = ct_pcm_playback_prepare,
384 .trigger = ct_pcm_playback_trigger,
385 .pointer = ct_pcm_playback_pointer,
386 .page = snd_pcm_sgbuf_ops_page,
389 /* PCM operators for capture */
390 static const struct snd_pcm_ops ct_pcm_capture_ops = {
391 .open = ct_pcm_capture_open,
392 .close = ct_pcm_capture_close,
393 .ioctl = snd_pcm_lib_ioctl,
394 .hw_params = ct_pcm_hw_params,
395 .hw_free = ct_pcm_hw_free,
396 .prepare = ct_pcm_capture_prepare,
397 .trigger = ct_pcm_capture_trigger,
398 .pointer = ct_pcm_capture_pointer,
399 .page = snd_pcm_sgbuf_ops_page,
402 static const struct snd_pcm_chmap_elem surround_map[] = {
403 { .channels = 1,
404 .map = { SNDRV_CHMAP_MONO } },
405 { .channels = 2,
406 .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
410 static const struct snd_pcm_chmap_elem clfe_map[] = {
411 { .channels = 1,
412 .map = { SNDRV_CHMAP_MONO } },
413 { .channels = 2,
414 .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
418 static const struct snd_pcm_chmap_elem side_map[] = {
419 { .channels = 1,
420 .map = { SNDRV_CHMAP_MONO } },
421 { .channels = 2,
422 .map = { SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
426 /* Create ALSA pcm device */
427 int ct_alsa_pcm_create(struct ct_atc *atc,
428 enum CTALSADEVS device,
429 const char *device_name)
431 struct snd_pcm *pcm;
432 const struct snd_pcm_chmap_elem *map;
433 int chs;
434 int err;
435 int playback_count, capture_count;
437 playback_count = (IEC958 == device) ? 1 : 256;
438 capture_count = (FRONT == device) ? 1 : 0;
439 err = snd_pcm_new(atc->card, "ctxfi", device,
440 playback_count, capture_count, &pcm);
441 if (err < 0) {
442 dev_err(atc->card->dev, "snd_pcm_new failed!! Err=%d\n",
443 err);
444 return err;
447 pcm->private_data = atc;
448 pcm->info_flags = 0;
449 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
450 strlcpy(pcm->name, device_name, sizeof(pcm->name));
452 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops);
454 if (FRONT == device)
455 snd_pcm_set_ops(pcm,
456 SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops);
458 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
459 snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
461 chs = 2;
462 switch (device) {
463 case FRONT:
464 chs = 8;
465 map = snd_pcm_std_chmaps;
466 break;
467 case SURROUND:
468 map = surround_map;
469 break;
470 case CLFE:
471 map = clfe_map;
472 break;
473 case SIDE:
474 map = side_map;
475 break;
476 default:
477 map = snd_pcm_std_chmaps;
478 break;
480 err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, chs,
481 0, NULL);
482 if (err < 0)
483 return err;
485 #ifdef CONFIG_PM_SLEEP
486 atc->pcms[device] = pcm;
487 #endif
489 return 0;