This source file includes following definitions.
- ct_atc_pcm_interrupt
- ct_atc_pcm_free_substream
- ct_pcm_playback_open
- ct_pcm_playback_close
- ct_pcm_hw_params
- ct_pcm_hw_free
- ct_pcm_playback_prepare
- ct_pcm_playback_trigger
- ct_pcm_playback_pointer
- ct_pcm_capture_open
- ct_pcm_capture_close
- ct_pcm_capture_prepare
- ct_pcm_capture_trigger
- ct_pcm_capture_pointer
- ct_alsa_pcm_create
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include "ctpcm.h"
15 #include "cttimer.h"
16 #include <linux/slab.h>
17 #include <sound/pcm.h>
18
19
20 static const struct snd_pcm_hardware ct_pcm_playback_hw = {
21 .info = (SNDRV_PCM_INFO_MMAP |
22 SNDRV_PCM_INFO_INTERLEAVED |
23 SNDRV_PCM_INFO_BLOCK_TRANSFER |
24 SNDRV_PCM_INFO_MMAP_VALID |
25 SNDRV_PCM_INFO_PAUSE),
26 .formats = (SNDRV_PCM_FMTBIT_U8 |
27 SNDRV_PCM_FMTBIT_S16_LE |
28 SNDRV_PCM_FMTBIT_S24_3LE |
29 SNDRV_PCM_FMTBIT_S32_LE |
30 SNDRV_PCM_FMTBIT_FLOAT_LE),
31 .rates = (SNDRV_PCM_RATE_CONTINUOUS |
32 SNDRV_PCM_RATE_8000_192000),
33 .rate_min = 8000,
34 .rate_max = 192000,
35 .channels_min = 1,
36 .channels_max = 2,
37 .buffer_bytes_max = (128*1024),
38 .period_bytes_min = (64),
39 .period_bytes_max = (128*1024),
40 .periods_min = 2,
41 .periods_max = 1024,
42 .fifo_size = 0,
43 };
44
45 static const struct snd_pcm_hardware ct_spdif_passthru_playback_hw = {
46 .info = (SNDRV_PCM_INFO_MMAP |
47 SNDRV_PCM_INFO_INTERLEAVED |
48 SNDRV_PCM_INFO_BLOCK_TRANSFER |
49 SNDRV_PCM_INFO_MMAP_VALID |
50 SNDRV_PCM_INFO_PAUSE),
51 .formats = SNDRV_PCM_FMTBIT_S16_LE,
52 .rates = (SNDRV_PCM_RATE_48000 |
53 SNDRV_PCM_RATE_44100 |
54 SNDRV_PCM_RATE_32000),
55 .rate_min = 32000,
56 .rate_max = 48000,
57 .channels_min = 2,
58 .channels_max = 2,
59 .buffer_bytes_max = (128*1024),
60 .period_bytes_min = (64),
61 .period_bytes_max = (128*1024),
62 .periods_min = 2,
63 .periods_max = 1024,
64 .fifo_size = 0,
65 };
66
67
68 static const struct snd_pcm_hardware ct_pcm_capture_hw = {
69 .info = (SNDRV_PCM_INFO_MMAP |
70 SNDRV_PCM_INFO_INTERLEAVED |
71 SNDRV_PCM_INFO_BLOCK_TRANSFER |
72 SNDRV_PCM_INFO_PAUSE |
73 SNDRV_PCM_INFO_MMAP_VALID),
74 .formats = (SNDRV_PCM_FMTBIT_U8 |
75 SNDRV_PCM_FMTBIT_S16_LE |
76 SNDRV_PCM_FMTBIT_S24_3LE |
77 SNDRV_PCM_FMTBIT_S32_LE |
78 SNDRV_PCM_FMTBIT_FLOAT_LE),
79 .rates = (SNDRV_PCM_RATE_CONTINUOUS |
80 SNDRV_PCM_RATE_8000_96000),
81 .rate_min = 8000,
82 .rate_max = 96000,
83 .channels_min = 1,
84 .channels_max = 2,
85 .buffer_bytes_max = (128*1024),
86 .period_bytes_min = (384),
87 .period_bytes_max = (64*1024),
88 .periods_min = 2,
89 .periods_max = 1024,
90 .fifo_size = 0,
91 };
92
93 static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm)
94 {
95 struct ct_atc_pcm *apcm = atc_pcm;
96
97 if (!apcm->substream)
98 return;
99
100 snd_pcm_period_elapsed(apcm->substream);
101 }
102
103 static void ct_atc_pcm_free_substream(struct snd_pcm_runtime *runtime)
104 {
105 struct ct_atc_pcm *apcm = runtime->private_data;
106 struct ct_atc *atc = snd_pcm_substream_chip(apcm->substream);
107
108 atc->pcm_release_resources(atc, apcm);
109 ct_timer_instance_free(apcm->timer);
110 kfree(apcm);
111 runtime->private_data = NULL;
112 }
113
114
115 static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
116 {
117 struct ct_atc *atc = snd_pcm_substream_chip(substream);
118 struct snd_pcm_runtime *runtime = substream->runtime;
119 struct ct_atc_pcm *apcm;
120 int err;
121
122 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
123 if (!apcm)
124 return -ENOMEM;
125
126 apcm->substream = substream;
127 apcm->interrupt = ct_atc_pcm_interrupt;
128 if (IEC958 == substream->pcm->device) {
129 runtime->hw = ct_spdif_passthru_playback_hw;
130 atc->spdif_out_passthru(atc, 1);
131 } else {
132 runtime->hw = ct_pcm_playback_hw;
133 if (FRONT == substream->pcm->device)
134 runtime->hw.channels_max = 8;
135 }
136
137 err = snd_pcm_hw_constraint_integer(runtime,
138 SNDRV_PCM_HW_PARAM_PERIODS);
139 if (err < 0)
140 goto free_pcm;
141
142 err = snd_pcm_hw_constraint_minmax(runtime,
143 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
144 1024, UINT_MAX);
145 if (err < 0)
146 goto free_pcm;
147
148 apcm->timer = ct_timer_instance_new(atc->timer, apcm);
149 if (!apcm->timer) {
150 err = -ENOMEM;
151 goto free_pcm;
152 }
153 runtime->private_data = apcm;
154 runtime->private_free = ct_atc_pcm_free_substream;
155
156 return 0;
157
158 free_pcm:
159 kfree(apcm);
160 return err;
161 }
162
163 static int ct_pcm_playback_close(struct snd_pcm_substream *substream)
164 {
165 struct ct_atc *atc = snd_pcm_substream_chip(substream);
166
167
168 if (IEC958 == substream->pcm->device)
169 atc->spdif_out_passthru(atc, 0);
170
171
172
173 return 0;
174 }
175
176 static int ct_pcm_hw_params(struct snd_pcm_substream *substream,
177 struct snd_pcm_hw_params *hw_params)
178 {
179 struct ct_atc *atc = snd_pcm_substream_chip(substream);
180 struct ct_atc_pcm *apcm = substream->runtime->private_data;
181 int err;
182
183 err = snd_pcm_lib_malloc_pages(substream,
184 params_buffer_bytes(hw_params));
185 if (err < 0)
186 return err;
187
188 atc->pcm_release_resources(atc, apcm);
189 return err;
190 }
191
192 static int ct_pcm_hw_free(struct snd_pcm_substream *substream)
193 {
194 struct ct_atc *atc = snd_pcm_substream_chip(substream);
195 struct ct_atc_pcm *apcm = substream->runtime->private_data;
196
197
198 atc->pcm_release_resources(atc, apcm);
199
200 return snd_pcm_lib_free_pages(substream);
201 }
202
203
204 static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream)
205 {
206 int err;
207 struct ct_atc *atc = snd_pcm_substream_chip(substream);
208 struct snd_pcm_runtime *runtime = substream->runtime;
209 struct ct_atc_pcm *apcm = runtime->private_data;
210
211 if (IEC958 == substream->pcm->device)
212 err = atc->spdif_passthru_playback_prepare(atc, apcm);
213 else
214 err = atc->pcm_playback_prepare(atc, apcm);
215
216 if (err < 0) {
217 dev_err(atc->card->dev,
218 "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
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
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->hw = ct_pcm_capture_hw;
282 runtime->hw.rate_max = atc->rsr * atc->msr;
283
284 err = snd_pcm_hw_constraint_integer(runtime,
285 SNDRV_PCM_HW_PARAM_PERIODS);
286 if (err < 0)
287 goto free_pcm;
288
289 err = snd_pcm_hw_constraint_minmax(runtime,
290 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
291 1024, UINT_MAX);
292 if (err < 0)
293 goto free_pcm;
294
295 apcm->timer = ct_timer_instance_new(atc->timer, apcm);
296 if (!apcm->timer) {
297 err = -ENOMEM;
298 goto free_pcm;
299 }
300 runtime->private_data = apcm;
301 runtime->private_free = ct_atc_pcm_free_substream;
302
303 return 0;
304
305 free_pcm:
306 kfree(apcm);
307 return err;
308 }
309
310 static int ct_pcm_capture_close(struct snd_pcm_substream *substream)
311 {
312
313
314 return 0;
315 }
316
317 static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream)
318 {
319 int err;
320 struct ct_atc *atc = snd_pcm_substream_chip(substream);
321 struct snd_pcm_runtime *runtime = substream->runtime;
322 struct ct_atc_pcm *apcm = runtime->private_data;
323
324 err = atc->pcm_capture_prepare(atc, apcm);
325 if (err < 0) {
326 dev_err(atc->card->dev,
327 "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
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
373 static const 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
386 static const 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 static const struct snd_pcm_chmap_elem surround_map[] = {
399 { .channels = 1,
400 .map = { SNDRV_CHMAP_MONO } },
401 { .channels = 2,
402 .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
403 { }
404 };
405
406 static const struct snd_pcm_chmap_elem clfe_map[] = {
407 { .channels = 1,
408 .map = { SNDRV_CHMAP_MONO } },
409 { .channels = 2,
410 .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
411 { }
412 };
413
414 static const struct snd_pcm_chmap_elem side_map[] = {
415 { .channels = 1,
416 .map = { SNDRV_CHMAP_MONO } },
417 { .channels = 2,
418 .map = { SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
419 { }
420 };
421
422
423 int ct_alsa_pcm_create(struct ct_atc *atc,
424 enum CTALSADEVS device,
425 const char *device_name)
426 {
427 struct snd_pcm *pcm;
428 const struct snd_pcm_chmap_elem *map;
429 int chs;
430 int err;
431 int playback_count, capture_count;
432
433 playback_count = (IEC958 == device) ? 1 : 256;
434 capture_count = (FRONT == device) ? 1 : 0;
435 err = snd_pcm_new(atc->card, "ctxfi", device,
436 playback_count, capture_count, &pcm);
437 if (err < 0) {
438 dev_err(atc->card->dev, "snd_pcm_new failed!! Err=%d\n",
439 err);
440 return err;
441 }
442
443 pcm->private_data = atc;
444 pcm->info_flags = 0;
445 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
446 strlcpy(pcm->name, device_name, sizeof(pcm->name));
447
448 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops);
449
450 if (FRONT == device)
451 snd_pcm_set_ops(pcm,
452 SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops);
453
454 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
455 snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
456
457 chs = 2;
458 switch (device) {
459 case FRONT:
460 chs = 8;
461 map = snd_pcm_std_chmaps;
462 break;
463 case SURROUND:
464 map = surround_map;
465 break;
466 case CLFE:
467 map = clfe_map;
468 break;
469 case SIDE:
470 map = side_map;
471 break;
472 default:
473 map = snd_pcm_std_chmaps;
474 break;
475 }
476 err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, chs,
477 0, NULL);
478 if (err < 0)
479 return err;
480
481 #ifdef CONFIG_PM_SLEEP
482 atc->pcms[device] = pcm;
483 #endif
484
485 return 0;
486 }