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 <sound/pcm.h> 21 22 /* Hardware descriptions for playback */ 23 static struct snd_pcm_hardware ct_pcm_playback_hw = { 24 .info = (SNDRV_PCM_INFO_MMAP | 25 SNDRV_PCM_INFO_INTERLEAVED | 26 SNDRV_PCM_INFO_BLOCK_TRANSFER | 27 SNDRV_PCM_INFO_MMAP_VALID | 28 SNDRV_PCM_INFO_PAUSE), 29 .formats = (SNDRV_PCM_FMTBIT_U8 | 30 SNDRV_PCM_FMTBIT_S16_LE | 31 SNDRV_PCM_FMTBIT_S24_3LE | 32 SNDRV_PCM_FMTBIT_S32_LE | 33 SNDRV_PCM_FMTBIT_FLOAT_LE), 34 .rates = (SNDRV_PCM_RATE_CONTINUOUS | 35 SNDRV_PCM_RATE_8000_192000), 36 .rate_min = 8000, 37 .rate_max = 192000, 38 .channels_min = 1, 39 .channels_max = 2, 40 .buffer_bytes_max = (128*1024), 41 .period_bytes_min = (64), 42 .period_bytes_max = (128*1024), 43 .periods_min = 2, 44 .periods_max = 1024, 45 .fifo_size = 0, 46 }; 47 48 static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = { 49 .info = (SNDRV_PCM_INFO_MMAP | 50 SNDRV_PCM_INFO_INTERLEAVED | 51 SNDRV_PCM_INFO_BLOCK_TRANSFER | 52 SNDRV_PCM_INFO_MMAP_VALID | 53 SNDRV_PCM_INFO_PAUSE), 54 .formats = SNDRV_PCM_FMTBIT_S16_LE, 55 .rates = (SNDRV_PCM_RATE_48000 | 56 SNDRV_PCM_RATE_44100 | 57 SNDRV_PCM_RATE_32000), 58 .rate_min = 32000, 59 .rate_max = 48000, 60 .channels_min = 2, 61 .channels_max = 2, 62 .buffer_bytes_max = (128*1024), 63 .period_bytes_min = (64), 64 .period_bytes_max = (128*1024), 65 .periods_min = 2, 66 .periods_max = 1024, 67 .fifo_size = 0, 68 }; 69 70 /* Hardware descriptions for capture */ 71 static struct snd_pcm_hardware ct_pcm_capture_hw = { 72 .info = (SNDRV_PCM_INFO_MMAP | 73 SNDRV_PCM_INFO_INTERLEAVED | 74 SNDRV_PCM_INFO_BLOCK_TRANSFER | 75 SNDRV_PCM_INFO_PAUSE | 76 SNDRV_PCM_INFO_MMAP_VALID), 77 .formats = (SNDRV_PCM_FMTBIT_U8 | 78 SNDRV_PCM_FMTBIT_S16_LE | 79 SNDRV_PCM_FMTBIT_S24_3LE | 80 SNDRV_PCM_FMTBIT_S32_LE | 81 SNDRV_PCM_FMTBIT_FLOAT_LE), 82 .rates = (SNDRV_PCM_RATE_CONTINUOUS | 83 SNDRV_PCM_RATE_8000_96000), 84 .rate_min = 8000, 85 .rate_max = 96000, 86 .channels_min = 1, 87 .channels_max = 2, 88 .buffer_bytes_max = (128*1024), 89 .period_bytes_min = (384), 90 .period_bytes_max = (64*1024), 91 .periods_min = 2, 92 .periods_max = 1024, 93 .fifo_size = 0, 94 }; 95 96 static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm) 97 { 98 struct ct_atc_pcm *apcm = atc_pcm; 99 100 if (!apcm->substream) 101 return; 102 103 snd_pcm_period_elapsed(apcm->substream); 104 } 105 106 static void ct_atc_pcm_free_substream(struct snd_pcm_runtime *runtime) 107 { 108 struct ct_atc_pcm *apcm = runtime->private_data; 109 struct ct_atc *atc = snd_pcm_substream_chip(apcm->substream); 110 111 atc->pcm_release_resources(atc, apcm); 112 ct_timer_instance_free(apcm->timer); 113 kfree(apcm); 114 runtime->private_data = NULL; 115 } 116 117 /* pcm playback operations */ 118 static int ct_pcm_playback_open(struct snd_pcm_substream *substream) 119 { 120 struct ct_atc *atc = snd_pcm_substream_chip(substream); 121 struct snd_pcm_runtime *runtime = substream->runtime; 122 struct ct_atc_pcm *apcm; 123 int err; 124 125 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); 126 if (!apcm) 127 return -ENOMEM; 128 129 apcm->substream = substream; 130 apcm->interrupt = ct_atc_pcm_interrupt; 131 runtime->private_data = apcm; 132 runtime->private_free = ct_atc_pcm_free_substream; 133 if (IEC958 == substream->pcm->device) { 134 runtime->hw = ct_spdif_passthru_playback_hw; 135 atc->spdif_out_passthru(atc, 1); 136 } else { 137 runtime->hw = ct_pcm_playback_hw; 138 if (FRONT == substream->pcm->device) 139 runtime->hw.channels_max = 8; 140 } 141 142 err = snd_pcm_hw_constraint_integer(runtime, 143 SNDRV_PCM_HW_PARAM_PERIODS); 144 if (err < 0) { 145 kfree(apcm); 146 return err; 147 } 148 err = snd_pcm_hw_constraint_minmax(runtime, 149 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 150 1024, UINT_MAX); 151 if (err < 0) { 152 kfree(apcm); 153 return err; 154 } 155 156 apcm->timer = ct_timer_instance_new(atc->timer, apcm); 157 if (!apcm->timer) 158 return -ENOMEM; 159 160 return 0; 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 printk(KERN_ERR "ctxfi: Preparing pcm playback failed!!!\n"); 218 return err; 219 } 220 221 return 0; 222 } 223 224 static int 225 ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 226 { 227 struct ct_atc *atc = snd_pcm_substream_chip(substream); 228 struct snd_pcm_runtime *runtime = substream->runtime; 229 struct ct_atc_pcm *apcm = runtime->private_data; 230 231 switch (cmd) { 232 case SNDRV_PCM_TRIGGER_START: 233 case SNDRV_PCM_TRIGGER_RESUME: 234 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 235 atc->pcm_playback_start(atc, apcm); 236 break; 237 case SNDRV_PCM_TRIGGER_STOP: 238 case SNDRV_PCM_TRIGGER_SUSPEND: 239 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 240 atc->pcm_playback_stop(atc, apcm); 241 break; 242 default: 243 break; 244 } 245 246 return 0; 247 } 248 249 static snd_pcm_uframes_t 250 ct_pcm_playback_pointer(struct snd_pcm_substream *substream) 251 { 252 unsigned long position; 253 struct ct_atc *atc = snd_pcm_substream_chip(substream); 254 struct snd_pcm_runtime *runtime = substream->runtime; 255 struct ct_atc_pcm *apcm = runtime->private_data; 256 257 /* Read out playback position */ 258 position = atc->pcm_playback_position(atc, apcm); 259 position = bytes_to_frames(runtime, position); 260 if (position >= runtime->buffer_size) 261 position = 0; 262 return position; 263 } 264 265 /* pcm capture operations */ 266 static int ct_pcm_capture_open(struct snd_pcm_substream *substream) 267 { 268 struct ct_atc *atc = snd_pcm_substream_chip(substream); 269 struct snd_pcm_runtime *runtime = substream->runtime; 270 struct ct_atc_pcm *apcm; 271 int err; 272 273 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); 274 if (!apcm) 275 return -ENOMEM; 276 277 apcm->started = 0; 278 apcm->substream = substream; 279 apcm->interrupt = ct_atc_pcm_interrupt; 280 runtime->private_data = apcm; 281 runtime->private_free = ct_atc_pcm_free_substream; 282 runtime->hw = ct_pcm_capture_hw; 283 runtime->hw.rate_max = atc->rsr * atc->msr; 284 285 err = snd_pcm_hw_constraint_integer(runtime, 286 SNDRV_PCM_HW_PARAM_PERIODS); 287 if (err < 0) { 288 kfree(apcm); 289 return err; 290 } 291 err = snd_pcm_hw_constraint_minmax(runtime, 292 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 293 1024, UINT_MAX); 294 if (err < 0) { 295 kfree(apcm); 296 return err; 297 } 298 299 apcm->timer = ct_timer_instance_new(atc->timer, apcm); 300 if (!apcm->timer) 301 return -ENOMEM; 302 303 return 0; 304 } 305 306 static int ct_pcm_capture_close(struct snd_pcm_substream *substream) 307 { 308 /* The ct_atc_pcm object will be freed by runtime->private_free */ 309 /* TODO: Notify mixer inactive. */ 310 return 0; 311 } 312 313 static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream) 314 { 315 int err; 316 struct ct_atc *atc = snd_pcm_substream_chip(substream); 317 struct snd_pcm_runtime *runtime = substream->runtime; 318 struct ct_atc_pcm *apcm = runtime->private_data; 319 320 err = atc->pcm_capture_prepare(atc, apcm); 321 if (err < 0) { 322 printk(KERN_ERR "ctxfi: Preparing pcm capture failed!!!\n"); 323 return err; 324 } 325 326 return 0; 327 } 328 329 static int 330 ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) 331 { 332 struct ct_atc *atc = snd_pcm_substream_chip(substream); 333 struct snd_pcm_runtime *runtime = substream->runtime; 334 struct ct_atc_pcm *apcm = runtime->private_data; 335 336 switch (cmd) { 337 case SNDRV_PCM_TRIGGER_START: 338 atc->pcm_capture_start(atc, apcm); 339 break; 340 case SNDRV_PCM_TRIGGER_STOP: 341 atc->pcm_capture_stop(atc, apcm); 342 break; 343 default: 344 atc->pcm_capture_stop(atc, apcm); 345 break; 346 } 347 348 return 0; 349 } 350 351 static snd_pcm_uframes_t 352 ct_pcm_capture_pointer(struct snd_pcm_substream *substream) 353 { 354 unsigned long position; 355 struct ct_atc *atc = snd_pcm_substream_chip(substream); 356 struct snd_pcm_runtime *runtime = substream->runtime; 357 struct ct_atc_pcm *apcm = runtime->private_data; 358 359 /* Read out playback position */ 360 position = atc->pcm_capture_position(atc, apcm); 361 position = bytes_to_frames(runtime, position); 362 if (position >= runtime->buffer_size) 363 position = 0; 364 return position; 365 } 366 367 /* PCM operators for playback */ 368 static struct snd_pcm_ops ct_pcm_playback_ops = { 369 .open = ct_pcm_playback_open, 370 .close = ct_pcm_playback_close, 371 .ioctl = snd_pcm_lib_ioctl, 372 .hw_params = ct_pcm_hw_params, 373 .hw_free = ct_pcm_hw_free, 374 .prepare = ct_pcm_playback_prepare, 375 .trigger = ct_pcm_playback_trigger, 376 .pointer = ct_pcm_playback_pointer, 377 .page = snd_pcm_sgbuf_ops_page, 378 }; 379 380 /* PCM operators for capture */ 381 static struct snd_pcm_ops ct_pcm_capture_ops = { 382 .open = ct_pcm_capture_open, 383 .close = ct_pcm_capture_close, 384 .ioctl = snd_pcm_lib_ioctl, 385 .hw_params = ct_pcm_hw_params, 386 .hw_free = ct_pcm_hw_free, 387 .prepare = ct_pcm_capture_prepare, 388 .trigger = ct_pcm_capture_trigger, 389 .pointer = ct_pcm_capture_pointer, 390 .page = snd_pcm_sgbuf_ops_page, 391 }; 392 393 /* Create ALSA pcm device */ 394 int ct_alsa_pcm_create(struct ct_atc *atc, 395 enum CTALSADEVS device, 396 const char *device_name) 397 { 398 struct snd_pcm *pcm; 399 int err; 400 int playback_count, capture_count; 401 402 playback_count = (IEC958 == device) ? 1 : 8; 403 capture_count = (FRONT == device) ? 1 : 0; 404 err = snd_pcm_new(atc->card, "ctxfi", device, 405 playback_count, capture_count, &pcm); 406 if (err < 0) { 407 printk(KERN_ERR "ctxfi: snd_pcm_new failed!! Err=%d\n", err); 408 return err; 409 } 410 411 pcm->private_data = atc; 412 pcm->info_flags = 0; 413 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; 414 strlcpy(pcm->name, device_name, sizeof(pcm->name)); 415 416 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops); 417 418 if (FRONT == device) 419 snd_pcm_set_ops(pcm, 420 SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops); 421 422 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 423 snd_dma_pci_data(atc->pci), 128*1024, 128*1024); 424 425 #ifdef CONFIG_PM 426 atc->pcms[device] = pcm; 427 #endif 428 429 return 0; 430 } 431