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 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, 47 }; 48 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, 69 }; 70 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, 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 goto free_pcm; 145 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; 151 152 apcm->timer = ct_timer_instance_new(atc->timer, apcm); 153 if (!apcm->timer) { 154 err = -ENOMEM; 155 goto free_pcm; 156 } 157 runtime->private_data = apcm; 158 runtime->private_free = ct_atc_pcm_free_substream; 159 160 return 0; 161 162 free_pcm: 163 kfree(apcm); 164 return err; 165 } 166 167 static int ct_pcm_playback_close(struct snd_pcm_substream *substream) 168 { 169 struct ct_atc *atc = snd_pcm_substream_chip(substream); 170 171 /* TODO: Notify mixer inactive. */ 172 if (IEC958 == substream->pcm->device) 173 atc->spdif_out_passthru(atc, 0); 174 175 /* The ct_atc_pcm object will be freed by runtime->private_free */ 176 177 return 0; 178 } 179 180 static int ct_pcm_hw_params(struct snd_pcm_substream *substream, 181 struct snd_pcm_hw_params *hw_params) 182 { 183 struct ct_atc *atc = snd_pcm_substream_chip(substream); 184 struct ct_atc_pcm *apcm = substream->runtime->private_data; 185 int err; 186 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; 194 } 195 196 static int ct_pcm_hw_free(struct snd_pcm_substream *substream) 197 { 198 struct ct_atc *atc = snd_pcm_substream_chip(substream); 199 struct ct_atc_pcm *apcm = substream->runtime->private_data; 200 201 /* clear previous resources */ 202 atc->pcm_release_resources(atc, apcm); 203 /* Free snd-allocated pages */ 204 return snd_pcm_lib_free_pages(substream); 205 } 206 207 208 static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream) 209 { 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; 214 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); 219 220 if (err < 0) { 221 dev_err(atc->card->dev, 222 "Preparing pcm playback failed!!!\n"); 223 return err; 224 } 225 226 return 0; 227 } 228 229 static int 230 ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 231 { 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; 235 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; 249 } 250 251 return 0; 252 } 253 254 static snd_pcm_uframes_t 255 ct_pcm_playback_pointer(struct snd_pcm_substream *substream) 256 { 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; 261 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; 268 } 269 270 /* pcm capture operations */ 271 static int ct_pcm_capture_open(struct snd_pcm_substream *substream) 272 { 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; 277 278 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); 279 if (!apcm) 280 return -ENOMEM; 281 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; 287 288 err = snd_pcm_hw_constraint_integer(runtime, 289 SNDRV_PCM_HW_PARAM_PERIODS); 290 if (err < 0) 291 goto free_pcm; 292 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; 298 299 apcm->timer = ct_timer_instance_new(atc->timer, apcm); 300 if (!apcm->timer) { 301 err = -ENOMEM; 302 goto free_pcm; 303 } 304 runtime->private_data = apcm; 305 runtime->private_free = ct_atc_pcm_free_substream; 306 307 return 0; 308 309 free_pcm: 310 kfree(apcm); 311 return err; 312 } 313 314 static int ct_pcm_capture_close(struct snd_pcm_substream *substream) 315 { 316 /* The ct_atc_pcm object will be freed by runtime->private_free */ 317 /* TODO: Notify mixer inactive. */ 318 return 0; 319 } 320 321 static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream) 322 { 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; 327 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; 333 } 334 335 return 0; 336 } 337 338 static int 339 ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) 340 { 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; 344 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; 355 } 356 357 return 0; 358 } 359 360 static snd_pcm_uframes_t 361 ct_pcm_capture_pointer(struct snd_pcm_substream *substream) 362 { 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; 367 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; 374 } 375 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, 387 }; 388 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, 400 }; 401 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 } }, 407 { } 408 }; 409 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 } }, 415 { } 416 }; 417 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 } }, 423 { } 424 }; 425 426 /* Create ALSA pcm device */ 427 int ct_alsa_pcm_create(struct ct_atc *atc, 428 enum CTALSADEVS device, 429 const char *device_name) 430 { 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; 436 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; 445 } 446 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)); 451 452 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops); 453 454 if (FRONT == device) 455 snd_pcm_set_ops(pcm, 456 SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops); 457 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); 460 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; 479 } 480 err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, chs, 481 0, NULL); 482 if (err < 0) 483 return err; 484 485 #ifdef CONFIG_PM_SLEEP 486 atc->pcms[device] = pcm; 487 #endif 488 489 return 0; 490 } 491