1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * pcm emulation on emu8000 wavetable 4 * 5 * Copyright (C) 2002 Takashi Iwai <tiwai@suse.de> 6 */ 7 8 #include "emu8000_local.h" 9 10 #include <linux/sched/signal.h> 11 #include <linux/init.h> 12 #include <linux/slab.h> 13 #include <sound/initval.h> 14 #include <sound/pcm.h> 15 16 /* 17 * define the following if you want to use this pcm with non-interleaved mode 18 */ 19 /* #define USE_NONINTERLEAVE */ 20 21 /* NOTE: for using the non-interleaved mode with alsa-lib, you have to set 22 * mmap_emulation flag to 1 in your .asoundrc, such like 23 * 24 * pcm.emu8k { 25 * type plug 26 * slave.pcm { 27 * type hw 28 * card 0 29 * device 1 30 * mmap_emulation 1 31 * } 32 * } 33 * 34 * besides, for the time being, the non-interleaved mode doesn't work well on 35 * alsa-lib... 36 */ 37 38 39 struct snd_emu8k_pcm { 40 struct snd_emu8000 *emu; 41 struct snd_pcm_substream *substream; 42 43 unsigned int allocated_bytes; 44 struct snd_util_memblk *block; 45 unsigned int offset; 46 unsigned int buf_size; 47 unsigned int period_size; 48 unsigned int loop_start[2]; 49 unsigned int pitch; 50 int panning[2]; 51 int last_ptr; 52 int period_pos; 53 int voices; 54 unsigned int dram_opened: 1; 55 unsigned int running: 1; 56 unsigned int timer_running: 1; 57 struct timer_list timer; 58 spinlock_t timer_lock; 59 }; 60 61 #define LOOP_BLANK_SIZE 8 62 63 64 /* 65 * open up channels for the simultaneous data transfer and playback 66 */ 67 static int 68 emu8k_open_dram_for_pcm(struct snd_emu8000 *emu, int channels) 69 { 70 int i; 71 72 /* reserve up to 2 voices for playback */ 73 snd_emux_lock_voice(emu->emu, 0); 74 if (channels > 1) 75 snd_emux_lock_voice(emu->emu, 1); 76 77 /* reserve 28 voices for loading */ 78 for (i = channels + 1; i < EMU8000_DRAM_VOICES; i++) { 79 unsigned int mode = EMU8000_RAM_WRITE; 80 snd_emux_lock_voice(emu->emu, i); 81 #ifndef USE_NONINTERLEAVE 82 if (channels > 1 && (i & 1) != 0) 83 mode |= EMU8000_RAM_RIGHT; 84 #endif 85 snd_emu8000_dma_chan(emu, i, mode); 86 } 87 88 /* assign voice 31 and 32 to ROM */ 89 EMU8000_VTFT_WRITE(emu, 30, 0); 90 EMU8000_PSST_WRITE(emu, 30, 0x1d8); 91 EMU8000_CSL_WRITE(emu, 30, 0x1e0); 92 EMU8000_CCCA_WRITE(emu, 30, 0x1d8); 93 EMU8000_VTFT_WRITE(emu, 31, 0); 94 EMU8000_PSST_WRITE(emu, 31, 0x1d8); 95 EMU8000_CSL_WRITE(emu, 31, 0x1e0); 96 EMU8000_CCCA_WRITE(emu, 31, 0x1d8); 97 98 return 0; 99 } 100 101 /* 102 */ 103 static void 104 snd_emu8000_write_wait(struct snd_emu8000 *emu, int can_schedule) 105 { 106 while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) { 107 if (can_schedule) { 108 schedule_timeout_interruptible(1); 109 if (signal_pending(current)) 110 break; 111 } 112 } 113 } 114 115 /* 116 * close all channels 117 */ 118 static void 119 emu8k_close_dram(struct snd_emu8000 *emu) 120 { 121 int i; 122 123 for (i = 0; i < 2; i++) 124 snd_emux_unlock_voice(emu->emu, i); 125 for (; i < EMU8000_DRAM_VOICES; i++) { 126 snd_emu8000_dma_chan(emu, i, EMU8000_RAM_CLOSE); 127 snd_emux_unlock_voice(emu->emu, i); 128 } 129 } 130 131 /* 132 * convert Hz to AWE32 rate offset (see emux/soundfont.c) 133 */ 134 135 #define OFFSET_SAMPLERATE 1011119 /* base = 44100 */ 136 #define SAMPLERATE_RATIO 4096 137 138 static int calc_rate_offset(int hz) 139 { 140 return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO); 141 } 142 143 144 /* 145 */ 146 147 static const struct snd_pcm_hardware emu8k_pcm_hw = { 148 #ifdef USE_NONINTERLEAVE 149 .info = SNDRV_PCM_INFO_NONINTERLEAVED, 150 #else 151 .info = SNDRV_PCM_INFO_INTERLEAVED, 152 #endif 153 .formats = SNDRV_PCM_FMTBIT_S16_LE, 154 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 155 .rate_min = 4000, 156 .rate_max = 48000, 157 .channels_min = 1, 158 .channels_max = 2, 159 .buffer_bytes_max = (128*1024), 160 .period_bytes_min = 1024, 161 .period_bytes_max = (128*1024), 162 .periods_min = 2, 163 .periods_max = 1024, 164 .fifo_size = 0, 165 166 }; 167 168 /* 169 * get the current position at the given channel from CCCA register 170 */ 171 static inline int emu8k_get_curpos(struct snd_emu8k_pcm *rec, int ch) 172 { 173 int val = EMU8000_CCCA_READ(rec->emu, ch) & 0xfffffff; 174 val -= rec->loop_start[ch] - 1; 175 return val; 176 } 177 178 179 /* 180 * timer interrupt handler 181 * check the current position and update the period if necessary. 182 */ 183 static void emu8k_pcm_timer_func(struct timer_list *t) 184 { 185 struct snd_emu8k_pcm *rec = from_timer(rec, t, timer); 186 int ptr, delta; 187 188 spin_lock(&rec->timer_lock); 189 /* update the current pointer */ 190 ptr = emu8k_get_curpos(rec, 0); 191 if (ptr < rec->last_ptr) 192 delta = ptr + rec->buf_size - rec->last_ptr; 193 else 194 delta = ptr - rec->last_ptr; 195 rec->period_pos += delta; 196 rec->last_ptr = ptr; 197 198 /* reprogram timer */ 199 mod_timer(&rec->timer, jiffies + 1); 200 201 /* update period */ 202 if (rec->period_pos >= (int)rec->period_size) { 203 rec->period_pos %= rec->period_size; 204 spin_unlock(&rec->timer_lock); 205 snd_pcm_period_elapsed(rec->substream); 206 return; 207 } 208 spin_unlock(&rec->timer_lock); 209 } 210 211 212 /* 213 * open pcm 214 * creating an instance here 215 */ 216 static int emu8k_pcm_open(struct snd_pcm_substream *subs) 217 { 218 struct snd_emu8000 *emu = snd_pcm_substream_chip(subs); 219 struct snd_emu8k_pcm *rec; 220 struct snd_pcm_runtime *runtime = subs->runtime; 221 222 rec = kzalloc(sizeof(*rec), GFP_KERNEL); 223 if (! rec) 224 return -ENOMEM; 225 226 rec->emu = emu; 227 rec->substream = subs; 228 runtime->private_data = rec; 229 230 spin_lock_init(&rec->timer_lock); 231 timer_setup(&rec->timer, emu8k_pcm_timer_func, 0); 232 233 runtime->hw = emu8k_pcm_hw; 234 runtime->hw.buffer_bytes_max = emu->mem_size - LOOP_BLANK_SIZE * 3; 235 runtime->hw.period_bytes_max = runtime->hw.buffer_bytes_max / 2; 236 237 /* use timer to update periods.. (specified in msec) */ 238 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 239 (1000000 + HZ - 1) / HZ, UINT_MAX); 240 241 return 0; 242 } 243 244 static int emu8k_pcm_close(struct snd_pcm_substream *subs) 245 { 246 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 247 kfree(rec); 248 subs->runtime->private_data = NULL; 249 return 0; 250 } 251 252 /* 253 * calculate pitch target 254 */ 255 static int calc_pitch_target(int pitch) 256 { 257 int ptarget = 1 << (pitch >> 12); 258 if (pitch & 0x800) ptarget += (ptarget * 0x102e) / 0x2710; 259 if (pitch & 0x400) ptarget += (ptarget * 0x764) / 0x2710; 260 if (pitch & 0x200) ptarget += (ptarget * 0x389) / 0x2710; 261 ptarget += (ptarget >> 1); 262 if (ptarget > 0xffff) ptarget = 0xffff; 263 return ptarget; 264 } 265 266 /* 267 * set up the voice 268 */ 269 static void setup_voice(struct snd_emu8k_pcm *rec, int ch) 270 { 271 struct snd_emu8000 *hw = rec->emu; 272 unsigned int temp; 273 274 /* channel to be silent and idle */ 275 EMU8000_DCYSUSV_WRITE(hw, ch, 0x0080); 276 EMU8000_VTFT_WRITE(hw, ch, 0x0000FFFF); 277 EMU8000_CVCF_WRITE(hw, ch, 0x0000FFFF); 278 EMU8000_PTRX_WRITE(hw, ch, 0); 279 EMU8000_CPF_WRITE(hw, ch, 0); 280 281 /* pitch offset */ 282 EMU8000_IP_WRITE(hw, ch, rec->pitch); 283 /* set envelope parameters */ 284 EMU8000_ENVVAL_WRITE(hw, ch, 0x8000); 285 EMU8000_ATKHLD_WRITE(hw, ch, 0x7f7f); 286 EMU8000_DCYSUS_WRITE(hw, ch, 0x7f7f); 287 EMU8000_ENVVOL_WRITE(hw, ch, 0x8000); 288 EMU8000_ATKHLDV_WRITE(hw, ch, 0x7f7f); 289 /* decay/sustain parameter for volume envelope is used 290 for triggerg the voice */ 291 /* modulation envelope heights */ 292 EMU8000_PEFE_WRITE(hw, ch, 0x0); 293 /* lfo1/2 delay */ 294 EMU8000_LFO1VAL_WRITE(hw, ch, 0x8000); 295 EMU8000_LFO2VAL_WRITE(hw, ch, 0x8000); 296 /* lfo1 pitch & cutoff shift */ 297 EMU8000_FMMOD_WRITE(hw, ch, 0); 298 /* lfo1 volume & freq */ 299 EMU8000_TREMFRQ_WRITE(hw, ch, 0); 300 /* lfo2 pitch & freq */ 301 EMU8000_FM2FRQ2_WRITE(hw, ch, 0); 302 /* pan & loop start */ 303 temp = rec->panning[ch]; 304 temp = (temp <<24) | ((unsigned int)rec->loop_start[ch] - 1); 305 EMU8000_PSST_WRITE(hw, ch, temp); 306 /* chorus & loop end (chorus 8bit, MSB) */ 307 temp = 0; // chorus 308 temp = (temp << 24) | ((unsigned int)rec->loop_start[ch] + rec->buf_size - 1); 309 EMU8000_CSL_WRITE(hw, ch, temp); 310 /* Q & current address (Q 4bit value, MSB) */ 311 temp = 0; // filterQ 312 temp = (temp << 28) | ((unsigned int)rec->loop_start[ch] - 1); 313 EMU8000_CCCA_WRITE(hw, ch, temp); 314 /* clear unknown registers */ 315 EMU8000_00A0_WRITE(hw, ch, 0); 316 EMU8000_0080_WRITE(hw, ch, 0); 317 } 318 319 /* 320 * trigger the voice 321 */ 322 static void start_voice(struct snd_emu8k_pcm *rec, int ch) 323 { 324 unsigned long flags; 325 struct snd_emu8000 *hw = rec->emu; 326 unsigned int temp, aux; 327 int pt = calc_pitch_target(rec->pitch); 328 329 /* cutoff and volume */ 330 EMU8000_IFATN_WRITE(hw, ch, 0xff00); 331 EMU8000_VTFT_WRITE(hw, ch, 0xffff); 332 EMU8000_CVCF_WRITE(hw, ch, 0xffff); 333 /* trigger envelope */ 334 EMU8000_DCYSUSV_WRITE(hw, ch, 0x7f7f); 335 /* set reverb and pitch target */ 336 temp = 0; // reverb 337 if (rec->panning[ch] == 0) 338 aux = 0xff; 339 else 340 aux = (-rec->panning[ch]) & 0xff; 341 temp = (temp << 8) | (pt << 16) | aux; 342 EMU8000_PTRX_WRITE(hw, ch, temp); 343 EMU8000_CPF_WRITE(hw, ch, pt << 16); 344 345 /* start timer */ 346 spin_lock_irqsave(&rec->timer_lock, flags); 347 if (! rec->timer_running) { 348 mod_timer(&rec->timer, jiffies + 1); 349 rec->timer_running = 1; 350 } 351 spin_unlock_irqrestore(&rec->timer_lock, flags); 352 } 353 354 /* 355 * stop the voice immediately 356 */ 357 static void stop_voice(struct snd_emu8k_pcm *rec, int ch) 358 { 359 unsigned long flags; 360 struct snd_emu8000 *hw = rec->emu; 361 362 EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F); 363 364 /* stop timer */ 365 spin_lock_irqsave(&rec->timer_lock, flags); 366 if (rec->timer_running) { 367 del_timer(&rec->timer); 368 rec->timer_running = 0; 369 } 370 spin_unlock_irqrestore(&rec->timer_lock, flags); 371 } 372 373 static int emu8k_pcm_trigger(struct snd_pcm_substream *subs, int cmd) 374 { 375 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 376 int ch; 377 378 switch (cmd) { 379 case SNDRV_PCM_TRIGGER_START: 380 for (ch = 0; ch < rec->voices; ch++) 381 start_voice(rec, ch); 382 rec->running = 1; 383 break; 384 case SNDRV_PCM_TRIGGER_STOP: 385 rec->running = 0; 386 for (ch = 0; ch < rec->voices; ch++) 387 stop_voice(rec, ch); 388 break; 389 default: 390 return -EINVAL; 391 } 392 return 0; 393 } 394 395 396 /* 397 * copy / silence ops 398 */ 399 400 /* 401 * this macro should be inserted in the copy/silence loops 402 * to reduce the latency. without this, the system will hang up 403 * during the whole loop. 404 */ 405 #define CHECK_SCHEDULER() \ 406 do { \ 407 cond_resched();\ 408 if (signal_pending(current))\ 409 return -EAGAIN;\ 410 } while (0) 411 412 enum { 413 COPY_USER, COPY_KERNEL, FILL_SILENCE, 414 }; 415 416 #define GET_VAL(sval, buf, mode) \ 417 do { \ 418 switch (mode) { \ 419 case FILL_SILENCE: \ 420 sval = 0; \ 421 break; \ 422 case COPY_KERNEL: \ 423 sval = *buf++; \ 424 break; \ 425 default: \ 426 if (get_user(sval, (unsigned short __user *)buf)) \ 427 return -EFAULT; \ 428 buf++; \ 429 break; \ 430 } \ 431 } while (0) 432 433 #ifdef USE_NONINTERLEAVE 434 435 #define LOOP_WRITE(rec, offset, _buf, count, mode) \ 436 do { \ 437 struct snd_emu8000 *emu = (rec)->emu; \ 438 unsigned short *buf = (unsigned short *)(_buf); \ 439 snd_emu8000_write_wait(emu, 1); \ 440 EMU8000_SMALW_WRITE(emu, offset); \ 441 while (count > 0) { \ 442 unsigned short sval; \ 443 CHECK_SCHEDULER(); \ 444 GET_VAL(sval, buf, mode); \ 445 EMU8000_SMLD_WRITE(emu, sval); \ 446 count--; \ 447 } \ 448 } while (0) 449 450 /* copy one channel block */ 451 static int emu8k_pcm_copy(struct snd_pcm_substream *subs, 452 int voice, unsigned long pos, 453 void __user *src, unsigned long count) 454 { 455 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 456 457 /* convert to word unit */ 458 pos = (pos << 1) + rec->loop_start[voice]; 459 count <<= 1; 460 LOOP_WRITE(rec, pos, src, count, COPY_USER); 461 return 0; 462 } 463 464 static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs, 465 int voice, unsigned long pos, 466 void *src, unsigned long count) 467 { 468 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 469 470 /* convert to word unit */ 471 pos = (pos << 1) + rec->loop_start[voice]; 472 count <<= 1; 473 LOOP_WRITE(rec, pos, src, count, COPY_KERNEL); 474 return 0; 475 } 476 477 /* make a channel block silence */ 478 static int emu8k_pcm_silence(struct snd_pcm_substream *subs, 479 int voice, unsigned long pos, unsigned long count) 480 { 481 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 482 483 /* convert to word unit */ 484 pos = (pos << 1) + rec->loop_start[voice]; 485 count <<= 1; 486 LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE); 487 return 0; 488 } 489 490 #else /* interleave */ 491 492 #define LOOP_WRITE(rec, pos, _buf, count, mode) \ 493 do { \ 494 struct snd_emu8000 *emu = rec->emu; \ 495 unsigned short *buf = (unsigned short *)(_buf); \ 496 snd_emu8000_write_wait(emu, 1); \ 497 EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]); \ 498 if (rec->voices > 1) \ 499 EMU8000_SMARW_WRITE(emu, pos + rec->loop_start[1]); \ 500 while (count > 0) { \ 501 unsigned short sval; \ 502 CHECK_SCHEDULER(); \ 503 GET_VAL(sval, buf, mode); \ 504 EMU8000_SMLD_WRITE(emu, sval); \ 505 if (rec->voices > 1) { \ 506 CHECK_SCHEDULER(); \ 507 GET_VAL(sval, buf, mode); \ 508 EMU8000_SMRD_WRITE(emu, sval); \ 509 } \ 510 count--; \ 511 } \ 512 } while (0) 513 514 515 /* 516 * copy the interleaved data can be done easily by using 517 * DMA "left" and "right" channels on emu8k engine. 518 */ 519 static int emu8k_pcm_copy(struct snd_pcm_substream *subs, 520 int voice, unsigned long pos, 521 void __user *src, unsigned long count) 522 { 523 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 524 525 /* convert to frames */ 526 pos = bytes_to_frames(subs->runtime, pos); 527 count = bytes_to_frames(subs->runtime, count); 528 LOOP_WRITE(rec, pos, src, count, COPY_USER); 529 return 0; 530 } 531 532 static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs, 533 int voice, unsigned long pos, 534 void *src, unsigned long count) 535 { 536 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 537 538 /* convert to frames */ 539 pos = bytes_to_frames(subs->runtime, pos); 540 count = bytes_to_frames(subs->runtime, count); 541 LOOP_WRITE(rec, pos, src, count, COPY_KERNEL); 542 return 0; 543 } 544 545 static int emu8k_pcm_silence(struct snd_pcm_substream *subs, 546 int voice, unsigned long pos, unsigned long count) 547 { 548 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 549 550 /* convert to frames */ 551 pos = bytes_to_frames(subs->runtime, pos); 552 count = bytes_to_frames(subs->runtime, count); 553 LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE); 554 return 0; 555 } 556 #endif 557 558 559 /* 560 * allocate a memory block 561 */ 562 static int emu8k_pcm_hw_params(struct snd_pcm_substream *subs, 563 struct snd_pcm_hw_params *hw_params) 564 { 565 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 566 567 if (rec->block) { 568 /* reallocation - release the old block */ 569 snd_util_mem_free(rec->emu->memhdr, rec->block); 570 rec->block = NULL; 571 } 572 573 rec->allocated_bytes = params_buffer_bytes(hw_params) + LOOP_BLANK_SIZE * 4; 574 rec->block = snd_util_mem_alloc(rec->emu->memhdr, rec->allocated_bytes); 575 if (! rec->block) 576 return -ENOMEM; 577 rec->offset = EMU8000_DRAM_OFFSET + (rec->block->offset >> 1); /* in word */ 578 /* at least dma_bytes must be set for non-interleaved mode */ 579 subs->dma_buffer.bytes = params_buffer_bytes(hw_params); 580 581 return 0; 582 } 583 584 /* 585 * free the memory block 586 */ 587 static int emu8k_pcm_hw_free(struct snd_pcm_substream *subs) 588 { 589 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 590 591 if (rec->block) { 592 int ch; 593 for (ch = 0; ch < rec->voices; ch++) 594 stop_voice(rec, ch); // to be sure 595 if (rec->dram_opened) 596 emu8k_close_dram(rec->emu); 597 snd_util_mem_free(rec->emu->memhdr, rec->block); 598 rec->block = NULL; 599 } 600 return 0; 601 } 602 603 /* 604 */ 605 static int emu8k_pcm_prepare(struct snd_pcm_substream *subs) 606 { 607 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 608 609 rec->pitch = 0xe000 + calc_rate_offset(subs->runtime->rate); 610 rec->last_ptr = 0; 611 rec->period_pos = 0; 612 613 rec->buf_size = subs->runtime->buffer_size; 614 rec->period_size = subs->runtime->period_size; 615 rec->voices = subs->runtime->channels; 616 rec->loop_start[0] = rec->offset + LOOP_BLANK_SIZE; 617 if (rec->voices > 1) 618 rec->loop_start[1] = rec->loop_start[0] + rec->buf_size + LOOP_BLANK_SIZE; 619 if (rec->voices > 1) { 620 rec->panning[0] = 0xff; 621 rec->panning[1] = 0x00; 622 } else 623 rec->panning[0] = 0x80; 624 625 if (! rec->dram_opened) { 626 int err, i, ch; 627 628 snd_emux_terminate_all(rec->emu->emu); 629 if ((err = emu8k_open_dram_for_pcm(rec->emu, rec->voices)) != 0) 630 return err; 631 rec->dram_opened = 1; 632 633 /* clear loop blanks */ 634 snd_emu8000_write_wait(rec->emu, 0); 635 EMU8000_SMALW_WRITE(rec->emu, rec->offset); 636 for (i = 0; i < LOOP_BLANK_SIZE; i++) 637 EMU8000_SMLD_WRITE(rec->emu, 0); 638 for (ch = 0; ch < rec->voices; ch++) { 639 EMU8000_SMALW_WRITE(rec->emu, rec->loop_start[ch] + rec->buf_size); 640 for (i = 0; i < LOOP_BLANK_SIZE; i++) 641 EMU8000_SMLD_WRITE(rec->emu, 0); 642 } 643 } 644 645 setup_voice(rec, 0); 646 if (rec->voices > 1) 647 setup_voice(rec, 1); 648 return 0; 649 } 650 651 static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs) 652 { 653 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 654 if (rec->running) 655 return emu8k_get_curpos(rec, 0); 656 return 0; 657 } 658 659 660 static const struct snd_pcm_ops emu8k_pcm_ops = { 661 .open = emu8k_pcm_open, 662 .close = emu8k_pcm_close, 663 .ioctl = snd_pcm_lib_ioctl, 664 .hw_params = emu8k_pcm_hw_params, 665 .hw_free = emu8k_pcm_hw_free, 666 .prepare = emu8k_pcm_prepare, 667 .trigger = emu8k_pcm_trigger, 668 .pointer = emu8k_pcm_pointer, 669 .copy_user = emu8k_pcm_copy, 670 .copy_kernel = emu8k_pcm_copy_kernel, 671 .fill_silence = emu8k_pcm_silence, 672 }; 673 674 675 static void snd_emu8000_pcm_free(struct snd_pcm *pcm) 676 { 677 struct snd_emu8000 *emu = pcm->private_data; 678 emu->pcm = NULL; 679 } 680 681 int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index) 682 { 683 struct snd_pcm *pcm; 684 int err; 685 686 if ((err = snd_pcm_new(card, "Emu8000 PCM", index, 1, 0, &pcm)) < 0) 687 return err; 688 pcm->private_data = emu; 689 pcm->private_free = snd_emu8000_pcm_free; 690 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &emu8k_pcm_ops); 691 emu->pcm = pcm; 692 693 snd_device_register(card, pcm); 694 695 return 0; 696 } 697