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 = timer_container_of(rec, t, timer); 186 int ptr, delta; 187 bool period_elapsed = false; 188 189 scoped_guard(spinlock, &rec->timer_lock) { 190 /* update the current pointer */ 191 ptr = emu8k_get_curpos(rec, 0); 192 if (ptr < rec->last_ptr) 193 delta = ptr + rec->buf_size - rec->last_ptr; 194 else 195 delta = ptr - rec->last_ptr; 196 rec->period_pos += delta; 197 rec->last_ptr = ptr; 198 199 /* reprogram timer */ 200 mod_timer(&rec->timer, jiffies + 1); 201 202 /* update period */ 203 if (rec->period_pos >= (int)rec->period_size) { 204 rec->period_pos %= rec->period_size; 205 period_elapsed = true; 206 } 207 } 208 209 if (period_elapsed) 210 snd_pcm_period_elapsed(rec->substream); 211 } 212 213 214 /* 215 * open pcm 216 * creating an instance here 217 */ 218 static int emu8k_pcm_open(struct snd_pcm_substream *subs) 219 { 220 struct snd_emu8000 *emu = snd_pcm_substream_chip(subs); 221 struct snd_emu8k_pcm *rec; 222 struct snd_pcm_runtime *runtime = subs->runtime; 223 224 rec = kzalloc(sizeof(*rec), GFP_KERNEL); 225 if (! rec) 226 return -ENOMEM; 227 228 rec->emu = emu; 229 rec->substream = subs; 230 runtime->private_data = rec; 231 232 spin_lock_init(&rec->timer_lock); 233 timer_setup(&rec->timer, emu8k_pcm_timer_func, 0); 234 235 runtime->hw = emu8k_pcm_hw; 236 runtime->hw.buffer_bytes_max = emu->mem_size - LOOP_BLANK_SIZE * 3; 237 runtime->hw.period_bytes_max = runtime->hw.buffer_bytes_max / 2; 238 239 /* use timer to update periods.. (specified in msec) */ 240 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 241 DIV_ROUND_UP(1000000, HZ), UINT_MAX); 242 243 return 0; 244 } 245 246 static int emu8k_pcm_close(struct snd_pcm_substream *subs) 247 { 248 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 249 kfree(rec); 250 subs->runtime->private_data = NULL; 251 return 0; 252 } 253 254 /* 255 * calculate pitch target 256 */ 257 static int calc_pitch_target(int pitch) 258 { 259 int ptarget = 1 << (pitch >> 12); 260 if (pitch & 0x800) ptarget += (ptarget * 0x102e) / 0x2710; 261 if (pitch & 0x400) ptarget += (ptarget * 0x764) / 0x2710; 262 if (pitch & 0x200) ptarget += (ptarget * 0x389) / 0x2710; 263 ptarget += (ptarget >> 1); 264 if (ptarget > 0xffff) ptarget = 0xffff; 265 return ptarget; 266 } 267 268 /* 269 * set up the voice 270 */ 271 static void setup_voice(struct snd_emu8k_pcm *rec, int ch) 272 { 273 struct snd_emu8000 *hw = rec->emu; 274 unsigned int temp; 275 276 /* channel to be silent and idle */ 277 EMU8000_DCYSUSV_WRITE(hw, ch, 0x0080); 278 EMU8000_VTFT_WRITE(hw, ch, 0x0000FFFF); 279 EMU8000_CVCF_WRITE(hw, ch, 0x0000FFFF); 280 EMU8000_PTRX_WRITE(hw, ch, 0); 281 EMU8000_CPF_WRITE(hw, ch, 0); 282 283 /* pitch offset */ 284 EMU8000_IP_WRITE(hw, ch, rec->pitch); 285 /* set envelope parameters */ 286 EMU8000_ENVVAL_WRITE(hw, ch, 0x8000); 287 EMU8000_ATKHLD_WRITE(hw, ch, 0x7f7f); 288 EMU8000_DCYSUS_WRITE(hw, ch, 0x7f7f); 289 EMU8000_ENVVOL_WRITE(hw, ch, 0x8000); 290 EMU8000_ATKHLDV_WRITE(hw, ch, 0x7f7f); 291 /* decay/sustain parameter for volume envelope is used 292 for triggerg the voice */ 293 /* modulation envelope heights */ 294 EMU8000_PEFE_WRITE(hw, ch, 0x0); 295 /* lfo1/2 delay */ 296 EMU8000_LFO1VAL_WRITE(hw, ch, 0x8000); 297 EMU8000_LFO2VAL_WRITE(hw, ch, 0x8000); 298 /* lfo1 pitch & cutoff shift */ 299 EMU8000_FMMOD_WRITE(hw, ch, 0); 300 /* lfo1 volume & freq */ 301 EMU8000_TREMFRQ_WRITE(hw, ch, 0); 302 /* lfo2 pitch & freq */ 303 EMU8000_FM2FRQ2_WRITE(hw, ch, 0); 304 /* pan & loop start */ 305 temp = rec->panning[ch]; 306 temp = (temp <<24) | ((unsigned int)rec->loop_start[ch] - 1); 307 EMU8000_PSST_WRITE(hw, ch, temp); 308 /* chorus & loop end (chorus 8bit, MSB) */ 309 temp = 0; // chorus 310 temp = (temp << 24) | ((unsigned int)rec->loop_start[ch] + rec->buf_size - 1); 311 EMU8000_CSL_WRITE(hw, ch, temp); 312 /* Q & current address (Q 4bit value, MSB) */ 313 temp = 0; // filterQ 314 temp = (temp << 28) | ((unsigned int)rec->loop_start[ch] - 1); 315 EMU8000_CCCA_WRITE(hw, ch, temp); 316 /* clear unknown registers */ 317 EMU8000_00A0_WRITE(hw, ch, 0); 318 EMU8000_0080_WRITE(hw, ch, 0); 319 } 320 321 /* 322 * trigger the voice 323 */ 324 static void start_voice(struct snd_emu8k_pcm *rec, int ch) 325 { 326 struct snd_emu8000 *hw = rec->emu; 327 unsigned int temp, aux; 328 int pt = calc_pitch_target(rec->pitch); 329 330 /* cutoff and volume */ 331 EMU8000_IFATN_WRITE(hw, ch, 0xff00); 332 EMU8000_VTFT_WRITE(hw, ch, 0xffff); 333 EMU8000_CVCF_WRITE(hw, ch, 0xffff); 334 /* trigger envelope */ 335 EMU8000_DCYSUSV_WRITE(hw, ch, 0x7f7f); 336 /* set reverb and pitch target */ 337 temp = 0; // reverb 338 if (rec->panning[ch] == 0) 339 aux = 0xff; 340 else 341 aux = (-rec->panning[ch]) & 0xff; 342 temp = (temp << 8) | (pt << 16) | aux; 343 EMU8000_PTRX_WRITE(hw, ch, temp); 344 EMU8000_CPF_WRITE(hw, ch, pt << 16); 345 346 /* start timer */ 347 guard(spinlock_irqsave)(&rec->timer_lock); 348 if (! rec->timer_running) { 349 mod_timer(&rec->timer, jiffies + 1); 350 rec->timer_running = 1; 351 } 352 } 353 354 /* 355 * stop the voice immediately 356 */ 357 static void stop_voice(struct snd_emu8k_pcm *rec, int ch) 358 { 359 struct snd_emu8000 *hw = rec->emu; 360 361 EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F); 362 363 /* stop timer */ 364 guard(spinlock_irqsave)(&rec->timer_lock); 365 if (rec->timer_running) { 366 timer_delete(&rec->timer); 367 rec->timer_running = 0; 368 } 369 } 370 371 static int emu8k_pcm_trigger(struct snd_pcm_substream *subs, int cmd) 372 { 373 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 374 int ch; 375 376 switch (cmd) { 377 case SNDRV_PCM_TRIGGER_START: 378 for (ch = 0; ch < rec->voices; ch++) 379 start_voice(rec, ch); 380 rec->running = 1; 381 break; 382 case SNDRV_PCM_TRIGGER_STOP: 383 rec->running = 0; 384 for (ch = 0; ch < rec->voices; ch++) 385 stop_voice(rec, ch); 386 break; 387 default: 388 return -EINVAL; 389 } 390 return 0; 391 } 392 393 394 /* 395 * copy / silence ops 396 */ 397 398 /* 399 * this macro should be inserted in the copy/silence loops 400 * to reduce the latency. without this, the system will hang up 401 * during the whole loop. 402 */ 403 #define CHECK_SCHEDULER() \ 404 do { \ 405 cond_resched();\ 406 if (signal_pending(current))\ 407 return -EAGAIN;\ 408 } while (0) 409 410 #define GET_VAL(sval, iter) \ 411 do { \ 412 if (!iter) \ 413 sval = 0; \ 414 else if (copy_from_iter(&sval, 2, iter) != 2) \ 415 return -EFAULT; \ 416 } while (0) 417 418 #ifdef USE_NONINTERLEAVE 419 420 #define LOOP_WRITE(rec, offset, iter, count) \ 421 do { \ 422 struct snd_emu8000 *emu = (rec)->emu; \ 423 snd_emu8000_write_wait(emu, 1); \ 424 EMU8000_SMALW_WRITE(emu, offset); \ 425 while (count > 0) { \ 426 unsigned short sval; \ 427 CHECK_SCHEDULER(); \ 428 GET_VAL(sval, iter); \ 429 EMU8000_SMLD_WRITE(emu, sval); \ 430 count--; \ 431 } \ 432 } while (0) 433 434 /* copy one channel block */ 435 static int emu8k_pcm_copy(struct snd_pcm_substream *subs, 436 int voice, unsigned long pos, 437 struct iov_iter *src, unsigned long count) 438 { 439 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 440 441 /* convert to word unit */ 442 pos = (pos << 1) + rec->loop_start[voice]; 443 count <<= 1; 444 LOOP_WRITE(rec, pos, src, count); 445 return 0; 446 } 447 448 /* make a channel block silence */ 449 static int emu8k_pcm_silence(struct snd_pcm_substream *subs, 450 int voice, unsigned long pos, unsigned long count) 451 { 452 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 453 454 /* convert to word unit */ 455 pos = (pos << 1) + rec->loop_start[voice]; 456 count <<= 1; 457 LOOP_WRITE(rec, pos, NULL, count); 458 return 0; 459 } 460 461 #else /* interleave */ 462 463 #define LOOP_WRITE(rec, pos, iter, count) \ 464 do { \ 465 struct snd_emu8000 *emu = rec->emu; \ 466 snd_emu8000_write_wait(emu, 1); \ 467 EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]); \ 468 if (rec->voices > 1) \ 469 EMU8000_SMARW_WRITE(emu, pos + rec->loop_start[1]); \ 470 while (count > 0) { \ 471 unsigned short sval; \ 472 CHECK_SCHEDULER(); \ 473 GET_VAL(sval, iter); \ 474 EMU8000_SMLD_WRITE(emu, sval); \ 475 if (rec->voices > 1) { \ 476 CHECK_SCHEDULER(); \ 477 GET_VAL(sval, iter); \ 478 EMU8000_SMRD_WRITE(emu, sval); \ 479 } \ 480 count--; \ 481 } \ 482 } while (0) 483 484 485 /* 486 * copy the interleaved data can be done easily by using 487 * DMA "left" and "right" channels on emu8k engine. 488 */ 489 static int emu8k_pcm_copy(struct snd_pcm_substream *subs, 490 int voice, unsigned long pos, 491 struct iov_iter *src, unsigned long count) 492 { 493 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 494 495 /* convert to frames */ 496 pos = bytes_to_frames(subs->runtime, pos); 497 count = bytes_to_frames(subs->runtime, count); 498 LOOP_WRITE(rec, pos, src, count); 499 return 0; 500 } 501 502 static int emu8k_pcm_silence(struct snd_pcm_substream *subs, 503 int voice, unsigned long pos, unsigned long count) 504 { 505 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 506 507 /* convert to frames */ 508 pos = bytes_to_frames(subs->runtime, pos); 509 count = bytes_to_frames(subs->runtime, count); 510 LOOP_WRITE(rec, pos, NULL, count); 511 return 0; 512 } 513 #endif 514 515 516 /* 517 * allocate a memory block 518 */ 519 static int emu8k_pcm_hw_params(struct snd_pcm_substream *subs, 520 struct snd_pcm_hw_params *hw_params) 521 { 522 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 523 524 if (rec->block) { 525 /* reallocation - release the old block */ 526 snd_util_mem_free(rec->emu->memhdr, rec->block); 527 rec->block = NULL; 528 } 529 530 rec->allocated_bytes = params_buffer_bytes(hw_params) + LOOP_BLANK_SIZE * 4; 531 rec->block = snd_util_mem_alloc(rec->emu->memhdr, rec->allocated_bytes); 532 if (! rec->block) 533 return -ENOMEM; 534 rec->offset = EMU8000_DRAM_OFFSET + (rec->block->offset >> 1); /* in word */ 535 /* at least dma_bytes must be set for non-interleaved mode */ 536 subs->dma_buffer.bytes = params_buffer_bytes(hw_params); 537 538 return 0; 539 } 540 541 /* 542 * free the memory block 543 */ 544 static int emu8k_pcm_hw_free(struct snd_pcm_substream *subs) 545 { 546 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 547 548 if (rec->block) { 549 int ch; 550 for (ch = 0; ch < rec->voices; ch++) 551 stop_voice(rec, ch); // to be sure 552 if (rec->dram_opened) 553 emu8k_close_dram(rec->emu); 554 snd_util_mem_free(rec->emu->memhdr, rec->block); 555 rec->block = NULL; 556 } 557 return 0; 558 } 559 560 /* 561 */ 562 static int emu8k_pcm_prepare(struct snd_pcm_substream *subs) 563 { 564 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 565 566 rec->pitch = 0xe000 + calc_rate_offset(subs->runtime->rate); 567 rec->last_ptr = 0; 568 rec->period_pos = 0; 569 570 rec->buf_size = subs->runtime->buffer_size; 571 rec->period_size = subs->runtime->period_size; 572 rec->voices = subs->runtime->channels; 573 rec->loop_start[0] = rec->offset + LOOP_BLANK_SIZE; 574 if (rec->voices > 1) 575 rec->loop_start[1] = rec->loop_start[0] + rec->buf_size + LOOP_BLANK_SIZE; 576 if (rec->voices > 1) { 577 rec->panning[0] = 0xff; 578 rec->panning[1] = 0x00; 579 } else 580 rec->panning[0] = 0x80; 581 582 if (! rec->dram_opened) { 583 int err, i, ch; 584 585 snd_emux_terminate_all(rec->emu->emu); 586 err = emu8k_open_dram_for_pcm(rec->emu, rec->voices); 587 if (err) 588 return err; 589 rec->dram_opened = 1; 590 591 /* clear loop blanks */ 592 snd_emu8000_write_wait(rec->emu, 0); 593 EMU8000_SMALW_WRITE(rec->emu, rec->offset); 594 for (i = 0; i < LOOP_BLANK_SIZE; i++) 595 EMU8000_SMLD_WRITE(rec->emu, 0); 596 for (ch = 0; ch < rec->voices; ch++) { 597 EMU8000_SMALW_WRITE(rec->emu, rec->loop_start[ch] + rec->buf_size); 598 for (i = 0; i < LOOP_BLANK_SIZE; i++) 599 EMU8000_SMLD_WRITE(rec->emu, 0); 600 } 601 } 602 603 setup_voice(rec, 0); 604 if (rec->voices > 1) 605 setup_voice(rec, 1); 606 return 0; 607 } 608 609 static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs) 610 { 611 struct snd_emu8k_pcm *rec = subs->runtime->private_data; 612 if (rec->running) 613 return emu8k_get_curpos(rec, 0); 614 return 0; 615 } 616 617 618 static const struct snd_pcm_ops emu8k_pcm_ops = { 619 .open = emu8k_pcm_open, 620 .close = emu8k_pcm_close, 621 .hw_params = emu8k_pcm_hw_params, 622 .hw_free = emu8k_pcm_hw_free, 623 .prepare = emu8k_pcm_prepare, 624 .trigger = emu8k_pcm_trigger, 625 .pointer = emu8k_pcm_pointer, 626 .copy = emu8k_pcm_copy, 627 .fill_silence = emu8k_pcm_silence, 628 }; 629 630 631 static void snd_emu8000_pcm_free(struct snd_pcm *pcm) 632 { 633 struct snd_emu8000 *emu = pcm->private_data; 634 emu->pcm = NULL; 635 } 636 637 int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index) 638 { 639 struct snd_pcm *pcm; 640 int err; 641 642 err = snd_pcm_new(card, "Emu8000 PCM", index, 1, 0, &pcm); 643 if (err < 0) 644 return err; 645 pcm->private_data = emu; 646 pcm->private_free = snd_emu8000_pcm_free; 647 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &emu8k_pcm_ops); 648 emu->pcm = pcm; 649 650 snd_device_register(card, pcm); 651 652 return 0; 653 } 654