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 DIV_ROUND_UP(1000000, 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 #define GET_VAL(sval, iter) \ 413 do { \ 414 if (!iter) \ 415 sval = 0; \ 416 else if (copy_from_iter(&sval, 2, iter) != 2) \ 417 return -EFAULT; \ 418 } while (0) 419 420 #ifdef USE_NONINTERLEAVE 421 422 #define LOOP_WRITE(rec, offset, iter, count) \ 423 do { \ 424 struct snd_emu8000 *emu = (rec)->emu; \ 425 snd_emu8000_write_wait(emu, 1); \ 426 EMU8000_SMALW_WRITE(emu, offset); \ 427 while (count > 0) { \ 428 unsigned short sval; \ 429 CHECK_SCHEDULER(); \ 430 GET_VAL(sval, iter); \ 431 EMU8000_SMLD_WRITE(emu, sval); \ 432 count--; \ 433 } \ 434 } while (0) 435 436 /* copy one channel block */ 437 static int emu8k_pcm_copy(struct snd_pcm_substream *subs, 438 int voice, unsigned long pos, 439 struct iov_iter *src, unsigned long count) 440 { 441 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 442 443 /* convert to word unit */ 444 pos = (pos << 1) + rec->loop_start[voice]; 445 count <<= 1; 446 LOOP_WRITE(rec, pos, src, count); 447 return 0; 448 } 449 450 /* make a channel block silence */ 451 static int emu8k_pcm_silence(struct snd_pcm_substream *subs, 452 int voice, unsigned long pos, unsigned long count) 453 { 454 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 455 456 /* convert to word unit */ 457 pos = (pos << 1) + rec->loop_start[voice]; 458 count <<= 1; 459 LOOP_WRITE(rec, pos, NULL, count); 460 return 0; 461 } 462 463 #else /* interleave */ 464 465 #define LOOP_WRITE(rec, pos, iter, count) \ 466 do { \ 467 struct snd_emu8000 *emu = rec->emu; \ 468 snd_emu8000_write_wait(emu, 1); \ 469 EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]); \ 470 if (rec->voices > 1) \ 471 EMU8000_SMARW_WRITE(emu, pos + rec->loop_start[1]); \ 472 while (count > 0) { \ 473 unsigned short sval; \ 474 CHECK_SCHEDULER(); \ 475 GET_VAL(sval, iter); \ 476 EMU8000_SMLD_WRITE(emu, sval); \ 477 if (rec->voices > 1) { \ 478 CHECK_SCHEDULER(); \ 479 GET_VAL(sval, iter); \ 480 EMU8000_SMRD_WRITE(emu, sval); \ 481 } \ 482 count--; \ 483 } \ 484 } while (0) 485 486 487 /* 488 * copy the interleaved data can be done easily by using 489 * DMA "left" and "right" channels on emu8k engine. 490 */ 491 static int emu8k_pcm_copy(struct snd_pcm_substream *subs, 492 int voice, unsigned long pos, 493 struct iov_iter *src, unsigned long count) 494 { 495 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 496 497 /* convert to frames */ 498 pos = bytes_to_frames(subs->runtime, pos); 499 count = bytes_to_frames(subs->runtime, count); 500 LOOP_WRITE(rec, pos, src, count); 501 return 0; 502 } 503 504 static int emu8k_pcm_silence(struct snd_pcm_substream *subs, 505 int voice, unsigned long pos, unsigned long count) 506 { 507 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 508 509 /* convert to frames */ 510 pos = bytes_to_frames(subs->runtime, pos); 511 count = bytes_to_frames(subs->runtime, count); 512 LOOP_WRITE(rec, pos, NULL, count); 513 return 0; 514 } 515 #endif 516 517 518 /* 519 * allocate a memory block 520 */ 521 static int emu8k_pcm_hw_params(struct snd_pcm_substream *subs, 522 struct snd_pcm_hw_params *hw_params) 523 { 524 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 525 526 if (rec->block) { 527 /* reallocation - release the old block */ 528 snd_util_mem_free(rec->emu->memhdr, rec->block); 529 rec->block = NULL; 530 } 531 532 rec->allocated_bytes = params_buffer_bytes(hw_params) + LOOP_BLANK_SIZE * 4; 533 rec->block = snd_util_mem_alloc(rec->emu->memhdr, rec->allocated_bytes); 534 if (! rec->block) 535 return -ENOMEM; 536 rec->offset = EMU8000_DRAM_OFFSET + (rec->block->offset >> 1); /* in word */ 537 /* at least dma_bytes must be set for non-interleaved mode */ 538 subs->dma_buffer.bytes = params_buffer_bytes(hw_params); 539 540 return 0; 541 } 542 543 /* 544 * free the memory block 545 */ 546 static int emu8k_pcm_hw_free(struct snd_pcm_substream *subs) 547 { 548 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 549 550 if (rec->block) { 551 int ch; 552 for (ch = 0; ch < rec->voices; ch++) 553 stop_voice(rec, ch); // to be sure 554 if (rec->dram_opened) 555 emu8k_close_dram(rec->emu); 556 snd_util_mem_free(rec->emu->memhdr, rec->block); 557 rec->block = NULL; 558 } 559 return 0; 560 } 561 562 /* 563 */ 564 static int emu8k_pcm_prepare(struct snd_pcm_substream *subs) 565 { 566 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 567 568 rec->pitch = 0xe000 + calc_rate_offset(subs->runtime->rate); 569 rec->last_ptr = 0; 570 rec->period_pos = 0; 571 572 rec->buf_size = subs->runtime->buffer_size; 573 rec->period_size = subs->runtime->period_size; 574 rec->voices = subs->runtime->channels; 575 rec->loop_start[0] = rec->offset + LOOP_BLANK_SIZE; 576 if (rec->voices > 1) 577 rec->loop_start[1] = rec->loop_start[0] + rec->buf_size + LOOP_BLANK_SIZE; 578 if (rec->voices > 1) { 579 rec->panning[0] = 0xff; 580 rec->panning[1] = 0x00; 581 } else 582 rec->panning[0] = 0x80; 583 584 if (! rec->dram_opened) { 585 int err, i, ch; 586 587 snd_emux_terminate_all(rec->emu->emu); 588 err = emu8k_open_dram_for_pcm(rec->emu, rec->voices); 589 if (err) 590 return err; 591 rec->dram_opened = 1; 592 593 /* clear loop blanks */ 594 snd_emu8000_write_wait(rec->emu, 0); 595 EMU8000_SMALW_WRITE(rec->emu, rec->offset); 596 for (i = 0; i < LOOP_BLANK_SIZE; i++) 597 EMU8000_SMLD_WRITE(rec->emu, 0); 598 for (ch = 0; ch < rec->voices; ch++) { 599 EMU8000_SMALW_WRITE(rec->emu, rec->loop_start[ch] + rec->buf_size); 600 for (i = 0; i < LOOP_BLANK_SIZE; i++) 601 EMU8000_SMLD_WRITE(rec->emu, 0); 602 } 603 } 604 605 setup_voice(rec, 0); 606 if (rec->voices > 1) 607 setup_voice(rec, 1); 608 return 0; 609 } 610 611 static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs) 612 { 613 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 614 if (rec->running) 615 return emu8k_get_curpos(rec, 0); 616 return 0; 617 } 618 619 620 static const struct snd_pcm_ops emu8k_pcm_ops = { 621 .open = emu8k_pcm_open, 622 .close = emu8k_pcm_close, 623 .hw_params = emu8k_pcm_hw_params, 624 .hw_free = emu8k_pcm_hw_free, 625 .prepare = emu8k_pcm_prepare, 626 .trigger = emu8k_pcm_trigger, 627 .pointer = emu8k_pcm_pointer, 628 .copy = emu8k_pcm_copy, 629 .fill_silence = emu8k_pcm_silence, 630 }; 631 632 633 static void snd_emu8000_pcm_free(struct snd_pcm *pcm) 634 { 635 struct snd_emu8000 *emu = pcm->private_data; 636 emu->pcm = NULL; 637 } 638 639 int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index) 640 { 641 struct snd_pcm *pcm; 642 int err; 643 644 err = snd_pcm_new(card, "Emu8000 PCM", index, 1, 0, &pcm); 645 if (err < 0) 646 return err; 647 pcm->private_data = emu; 648 pcm->private_free = snd_emu8000_pcm_free; 649 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &emu8k_pcm_ops); 650 emu->pcm = pcm; 651 652 snd_device_register(card, pcm); 653 654 return 0; 655 } 656