1 // SPDX-License-Identifier: GPL-2.0-only 2 /** 3 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. 4 * 5 * @File ctpcm.c 6 * 7 * @Brief 8 * This file contains the definition of the pcm device functions. 9 * 10 * @Author Liu Chun 11 * @Date Apr 2 2008 12 */ 13 14 #include "ctpcm.h" 15 #include "cttimer.h" 16 #include <linux/slab.h> 17 #include <sound/pcm.h> 18 19 /* Hardware descriptions for playback */ 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 /* Hardware descriptions for capture */ 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 /* pcm playback operations */ 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 /* TODO: Notify mixer inactive. */ 168 if (IEC958 == substream->pcm->device) 169 atc->spdif_out_passthru(atc, 0); 170 171 /* The ct_atc_pcm object will be freed by runtime->private_free */ 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 /* clear previous resources */ 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 /* clear previous resources */ 198 atc->pcm_release_resources(atc, apcm); 199 /* Free snd-allocated pages */ 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 /* 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->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 /* The ct_atc_pcm object will be freed by runtime->private_free */ 313 /* TODO: Notify mixer inactive. */ 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 /* Read out playback position */ 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 /* PCM operators for playback */ 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 /* PCM operators for capture */ 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 /* Create ALSA pcm device */ 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 } 487