0001
0002
0003
0004
0005
0006
0007
0008 #include "emu8000_local.h"
0009
0010 #include <linux/sched/signal.h>
0011 #include <linux/init.h>
0012 #include <linux/slab.h>
0013 #include <sound/initval.h>
0014 #include <sound/pcm.h>
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 struct snd_emu8k_pcm {
0040 struct snd_emu8000 *emu;
0041 struct snd_pcm_substream *substream;
0042
0043 unsigned int allocated_bytes;
0044 struct snd_util_memblk *block;
0045 unsigned int offset;
0046 unsigned int buf_size;
0047 unsigned int period_size;
0048 unsigned int loop_start[2];
0049 unsigned int pitch;
0050 int panning[2];
0051 int last_ptr;
0052 int period_pos;
0053 int voices;
0054 unsigned int dram_opened: 1;
0055 unsigned int running: 1;
0056 unsigned int timer_running: 1;
0057 struct timer_list timer;
0058 spinlock_t timer_lock;
0059 };
0060
0061 #define LOOP_BLANK_SIZE 8
0062
0063
0064
0065
0066
0067 static int
0068 emu8k_open_dram_for_pcm(struct snd_emu8000 *emu, int channels)
0069 {
0070 int i;
0071
0072
0073 snd_emux_lock_voice(emu->emu, 0);
0074 if (channels > 1)
0075 snd_emux_lock_voice(emu->emu, 1);
0076
0077
0078 for (i = channels + 1; i < EMU8000_DRAM_VOICES; i++) {
0079 unsigned int mode = EMU8000_RAM_WRITE;
0080 snd_emux_lock_voice(emu->emu, i);
0081 #ifndef USE_NONINTERLEAVE
0082 if (channels > 1 && (i & 1) != 0)
0083 mode |= EMU8000_RAM_RIGHT;
0084 #endif
0085 snd_emu8000_dma_chan(emu, i, mode);
0086 }
0087
0088
0089 EMU8000_VTFT_WRITE(emu, 30, 0);
0090 EMU8000_PSST_WRITE(emu, 30, 0x1d8);
0091 EMU8000_CSL_WRITE(emu, 30, 0x1e0);
0092 EMU8000_CCCA_WRITE(emu, 30, 0x1d8);
0093 EMU8000_VTFT_WRITE(emu, 31, 0);
0094 EMU8000_PSST_WRITE(emu, 31, 0x1d8);
0095 EMU8000_CSL_WRITE(emu, 31, 0x1e0);
0096 EMU8000_CCCA_WRITE(emu, 31, 0x1d8);
0097
0098 return 0;
0099 }
0100
0101
0102
0103 static void
0104 snd_emu8000_write_wait(struct snd_emu8000 *emu, int can_schedule)
0105 {
0106 while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
0107 if (can_schedule) {
0108 schedule_timeout_interruptible(1);
0109 if (signal_pending(current))
0110 break;
0111 }
0112 }
0113 }
0114
0115
0116
0117
0118 static void
0119 emu8k_close_dram(struct snd_emu8000 *emu)
0120 {
0121 int i;
0122
0123 for (i = 0; i < 2; i++)
0124 snd_emux_unlock_voice(emu->emu, i);
0125 for (; i < EMU8000_DRAM_VOICES; i++) {
0126 snd_emu8000_dma_chan(emu, i, EMU8000_RAM_CLOSE);
0127 snd_emux_unlock_voice(emu->emu, i);
0128 }
0129 }
0130
0131
0132
0133
0134
0135 #define OFFSET_SAMPLERATE 1011119
0136 #define SAMPLERATE_RATIO 4096
0137
0138 static int calc_rate_offset(int hz)
0139 {
0140 return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);
0141 }
0142
0143
0144
0145
0146
0147 static const struct snd_pcm_hardware emu8k_pcm_hw = {
0148 #ifdef USE_NONINTERLEAVE
0149 .info = SNDRV_PCM_INFO_NONINTERLEAVED,
0150 #else
0151 .info = SNDRV_PCM_INFO_INTERLEAVED,
0152 #endif
0153 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0154 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
0155 .rate_min = 4000,
0156 .rate_max = 48000,
0157 .channels_min = 1,
0158 .channels_max = 2,
0159 .buffer_bytes_max = (128*1024),
0160 .period_bytes_min = 1024,
0161 .period_bytes_max = (128*1024),
0162 .periods_min = 2,
0163 .periods_max = 1024,
0164 .fifo_size = 0,
0165
0166 };
0167
0168
0169
0170
0171 static inline int emu8k_get_curpos(struct snd_emu8k_pcm *rec, int ch)
0172 {
0173 int val = EMU8000_CCCA_READ(rec->emu, ch) & 0xfffffff;
0174 val -= rec->loop_start[ch] - 1;
0175 return val;
0176 }
0177
0178
0179
0180
0181
0182
0183 static void emu8k_pcm_timer_func(struct timer_list *t)
0184 {
0185 struct snd_emu8k_pcm *rec = from_timer(rec, t, timer);
0186 int ptr, delta;
0187
0188 spin_lock(&rec->timer_lock);
0189
0190 ptr = emu8k_get_curpos(rec, 0);
0191 if (ptr < rec->last_ptr)
0192 delta = ptr + rec->buf_size - rec->last_ptr;
0193 else
0194 delta = ptr - rec->last_ptr;
0195 rec->period_pos += delta;
0196 rec->last_ptr = ptr;
0197
0198
0199 mod_timer(&rec->timer, jiffies + 1);
0200
0201
0202 if (rec->period_pos >= (int)rec->period_size) {
0203 rec->period_pos %= rec->period_size;
0204 spin_unlock(&rec->timer_lock);
0205 snd_pcm_period_elapsed(rec->substream);
0206 return;
0207 }
0208 spin_unlock(&rec->timer_lock);
0209 }
0210
0211
0212
0213
0214
0215
0216 static int emu8k_pcm_open(struct snd_pcm_substream *subs)
0217 {
0218 struct snd_emu8000 *emu = snd_pcm_substream_chip(subs);
0219 struct snd_emu8k_pcm *rec;
0220 struct snd_pcm_runtime *runtime = subs->runtime;
0221
0222 rec = kzalloc(sizeof(*rec), GFP_KERNEL);
0223 if (! rec)
0224 return -ENOMEM;
0225
0226 rec->emu = emu;
0227 rec->substream = subs;
0228 runtime->private_data = rec;
0229
0230 spin_lock_init(&rec->timer_lock);
0231 timer_setup(&rec->timer, emu8k_pcm_timer_func, 0);
0232
0233 runtime->hw = emu8k_pcm_hw;
0234 runtime->hw.buffer_bytes_max = emu->mem_size - LOOP_BLANK_SIZE * 3;
0235 runtime->hw.period_bytes_max = runtime->hw.buffer_bytes_max / 2;
0236
0237
0238 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
0239 (1000000 + HZ - 1) / HZ, UINT_MAX);
0240
0241 return 0;
0242 }
0243
0244 static int emu8k_pcm_close(struct snd_pcm_substream *subs)
0245 {
0246 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0247 kfree(rec);
0248 subs->runtime->private_data = NULL;
0249 return 0;
0250 }
0251
0252
0253
0254
0255 static int calc_pitch_target(int pitch)
0256 {
0257 int ptarget = 1 << (pitch >> 12);
0258 if (pitch & 0x800) ptarget += (ptarget * 0x102e) / 0x2710;
0259 if (pitch & 0x400) ptarget += (ptarget * 0x764) / 0x2710;
0260 if (pitch & 0x200) ptarget += (ptarget * 0x389) / 0x2710;
0261 ptarget += (ptarget >> 1);
0262 if (ptarget > 0xffff) ptarget = 0xffff;
0263 return ptarget;
0264 }
0265
0266
0267
0268
0269 static void setup_voice(struct snd_emu8k_pcm *rec, int ch)
0270 {
0271 struct snd_emu8000 *hw = rec->emu;
0272 unsigned int temp;
0273
0274
0275 EMU8000_DCYSUSV_WRITE(hw, ch, 0x0080);
0276 EMU8000_VTFT_WRITE(hw, ch, 0x0000FFFF);
0277 EMU8000_CVCF_WRITE(hw, ch, 0x0000FFFF);
0278 EMU8000_PTRX_WRITE(hw, ch, 0);
0279 EMU8000_CPF_WRITE(hw, ch, 0);
0280
0281
0282 EMU8000_IP_WRITE(hw, ch, rec->pitch);
0283
0284 EMU8000_ENVVAL_WRITE(hw, ch, 0x8000);
0285 EMU8000_ATKHLD_WRITE(hw, ch, 0x7f7f);
0286 EMU8000_DCYSUS_WRITE(hw, ch, 0x7f7f);
0287 EMU8000_ENVVOL_WRITE(hw, ch, 0x8000);
0288 EMU8000_ATKHLDV_WRITE(hw, ch, 0x7f7f);
0289
0290
0291
0292 EMU8000_PEFE_WRITE(hw, ch, 0x0);
0293
0294 EMU8000_LFO1VAL_WRITE(hw, ch, 0x8000);
0295 EMU8000_LFO2VAL_WRITE(hw, ch, 0x8000);
0296
0297 EMU8000_FMMOD_WRITE(hw, ch, 0);
0298
0299 EMU8000_TREMFRQ_WRITE(hw, ch, 0);
0300
0301 EMU8000_FM2FRQ2_WRITE(hw, ch, 0);
0302
0303 temp = rec->panning[ch];
0304 temp = (temp <<24) | ((unsigned int)rec->loop_start[ch] - 1);
0305 EMU8000_PSST_WRITE(hw, ch, temp);
0306
0307 temp = 0;
0308 temp = (temp << 24) | ((unsigned int)rec->loop_start[ch] + rec->buf_size - 1);
0309 EMU8000_CSL_WRITE(hw, ch, temp);
0310
0311 temp = 0;
0312 temp = (temp << 28) | ((unsigned int)rec->loop_start[ch] - 1);
0313 EMU8000_CCCA_WRITE(hw, ch, temp);
0314
0315 EMU8000_00A0_WRITE(hw, ch, 0);
0316 EMU8000_0080_WRITE(hw, ch, 0);
0317 }
0318
0319
0320
0321
0322 static void start_voice(struct snd_emu8k_pcm *rec, int ch)
0323 {
0324 unsigned long flags;
0325 struct snd_emu8000 *hw = rec->emu;
0326 unsigned int temp, aux;
0327 int pt = calc_pitch_target(rec->pitch);
0328
0329
0330 EMU8000_IFATN_WRITE(hw, ch, 0xff00);
0331 EMU8000_VTFT_WRITE(hw, ch, 0xffff);
0332 EMU8000_CVCF_WRITE(hw, ch, 0xffff);
0333
0334 EMU8000_DCYSUSV_WRITE(hw, ch, 0x7f7f);
0335
0336 temp = 0;
0337 if (rec->panning[ch] == 0)
0338 aux = 0xff;
0339 else
0340 aux = (-rec->panning[ch]) & 0xff;
0341 temp = (temp << 8) | (pt << 16) | aux;
0342 EMU8000_PTRX_WRITE(hw, ch, temp);
0343 EMU8000_CPF_WRITE(hw, ch, pt << 16);
0344
0345
0346 spin_lock_irqsave(&rec->timer_lock, flags);
0347 if (! rec->timer_running) {
0348 mod_timer(&rec->timer, jiffies + 1);
0349 rec->timer_running = 1;
0350 }
0351 spin_unlock_irqrestore(&rec->timer_lock, flags);
0352 }
0353
0354
0355
0356
0357 static void stop_voice(struct snd_emu8k_pcm *rec, int ch)
0358 {
0359 unsigned long flags;
0360 struct snd_emu8000 *hw = rec->emu;
0361
0362 EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F);
0363
0364
0365 spin_lock_irqsave(&rec->timer_lock, flags);
0366 if (rec->timer_running) {
0367 del_timer(&rec->timer);
0368 rec->timer_running = 0;
0369 }
0370 spin_unlock_irqrestore(&rec->timer_lock, flags);
0371 }
0372
0373 static int emu8k_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
0374 {
0375 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0376 int ch;
0377
0378 switch (cmd) {
0379 case SNDRV_PCM_TRIGGER_START:
0380 for (ch = 0; ch < rec->voices; ch++)
0381 start_voice(rec, ch);
0382 rec->running = 1;
0383 break;
0384 case SNDRV_PCM_TRIGGER_STOP:
0385 rec->running = 0;
0386 for (ch = 0; ch < rec->voices; ch++)
0387 stop_voice(rec, ch);
0388 break;
0389 default:
0390 return -EINVAL;
0391 }
0392 return 0;
0393 }
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405 #define CHECK_SCHEDULER() \
0406 do { \
0407 cond_resched();\
0408 if (signal_pending(current))\
0409 return -EAGAIN;\
0410 } while (0)
0411
0412 enum {
0413 COPY_USER, COPY_KERNEL, FILL_SILENCE,
0414 };
0415
0416 #define GET_VAL(sval, buf, mode) \
0417 do { \
0418 switch (mode) { \
0419 case FILL_SILENCE: \
0420 sval = 0; \
0421 break; \
0422 case COPY_KERNEL: \
0423 sval = *buf++; \
0424 break; \
0425 default: \
0426 if (get_user(sval, (unsigned short __user *)buf)) \
0427 return -EFAULT; \
0428 buf++; \
0429 break; \
0430 } \
0431 } while (0)
0432
0433 #ifdef USE_NONINTERLEAVE
0434
0435 #define LOOP_WRITE(rec, offset, _buf, count, mode) \
0436 do { \
0437 struct snd_emu8000 *emu = (rec)->emu; \
0438 unsigned short *buf = (__force unsigned short *)(_buf); \
0439 snd_emu8000_write_wait(emu, 1); \
0440 EMU8000_SMALW_WRITE(emu, offset); \
0441 while (count > 0) { \
0442 unsigned short sval; \
0443 CHECK_SCHEDULER(); \
0444 GET_VAL(sval, buf, mode); \
0445 EMU8000_SMLD_WRITE(emu, sval); \
0446 count--; \
0447 } \
0448 } while (0)
0449
0450
0451 static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
0452 int voice, unsigned long pos,
0453 void __user *src, unsigned long count)
0454 {
0455 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0456
0457
0458 pos = (pos << 1) + rec->loop_start[voice];
0459 count <<= 1;
0460 LOOP_WRITE(rec, pos, src, count, COPY_USER);
0461 return 0;
0462 }
0463
0464 static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs,
0465 int voice, unsigned long pos,
0466 void *src, unsigned long count)
0467 {
0468 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0469
0470
0471 pos = (pos << 1) + rec->loop_start[voice];
0472 count <<= 1;
0473 LOOP_WRITE(rec, pos, src, count, COPY_KERNEL);
0474 return 0;
0475 }
0476
0477
0478 static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
0479 int voice, unsigned long pos, unsigned long count)
0480 {
0481 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0482
0483
0484 pos = (pos << 1) + rec->loop_start[voice];
0485 count <<= 1;
0486 LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE);
0487 return 0;
0488 }
0489
0490 #else
0491
0492 #define LOOP_WRITE(rec, pos, _buf, count, mode) \
0493 do { \
0494 struct snd_emu8000 *emu = rec->emu; \
0495 unsigned short *buf = (__force unsigned short *)(_buf); \
0496 snd_emu8000_write_wait(emu, 1); \
0497 EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]); \
0498 if (rec->voices > 1) \
0499 EMU8000_SMARW_WRITE(emu, pos + rec->loop_start[1]); \
0500 while (count > 0) { \
0501 unsigned short sval; \
0502 CHECK_SCHEDULER(); \
0503 GET_VAL(sval, buf, mode); \
0504 EMU8000_SMLD_WRITE(emu, sval); \
0505 if (rec->voices > 1) { \
0506 CHECK_SCHEDULER(); \
0507 GET_VAL(sval, buf, mode); \
0508 EMU8000_SMRD_WRITE(emu, sval); \
0509 } \
0510 count--; \
0511 } \
0512 } while (0)
0513
0514
0515
0516
0517
0518
0519 static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
0520 int voice, unsigned long pos,
0521 void __user *src, unsigned long count)
0522 {
0523 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0524
0525
0526 pos = bytes_to_frames(subs->runtime, pos);
0527 count = bytes_to_frames(subs->runtime, count);
0528 LOOP_WRITE(rec, pos, src, count, COPY_USER);
0529 return 0;
0530 }
0531
0532 static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs,
0533 int voice, unsigned long pos,
0534 void *src, unsigned long count)
0535 {
0536 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0537
0538
0539 pos = bytes_to_frames(subs->runtime, pos);
0540 count = bytes_to_frames(subs->runtime, count);
0541 LOOP_WRITE(rec, pos, src, count, COPY_KERNEL);
0542 return 0;
0543 }
0544
0545 static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
0546 int voice, unsigned long pos, unsigned long count)
0547 {
0548 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0549
0550
0551 pos = bytes_to_frames(subs->runtime, pos);
0552 count = bytes_to_frames(subs->runtime, count);
0553 LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE);
0554 return 0;
0555 }
0556 #endif
0557
0558
0559
0560
0561
0562 static int emu8k_pcm_hw_params(struct snd_pcm_substream *subs,
0563 struct snd_pcm_hw_params *hw_params)
0564 {
0565 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0566
0567 if (rec->block) {
0568
0569 snd_util_mem_free(rec->emu->memhdr, rec->block);
0570 rec->block = NULL;
0571 }
0572
0573 rec->allocated_bytes = params_buffer_bytes(hw_params) + LOOP_BLANK_SIZE * 4;
0574 rec->block = snd_util_mem_alloc(rec->emu->memhdr, rec->allocated_bytes);
0575 if (! rec->block)
0576 return -ENOMEM;
0577 rec->offset = EMU8000_DRAM_OFFSET + (rec->block->offset >> 1);
0578
0579 subs->dma_buffer.bytes = params_buffer_bytes(hw_params);
0580
0581 return 0;
0582 }
0583
0584
0585
0586
0587 static int emu8k_pcm_hw_free(struct snd_pcm_substream *subs)
0588 {
0589 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0590
0591 if (rec->block) {
0592 int ch;
0593 for (ch = 0; ch < rec->voices; ch++)
0594 stop_voice(rec, ch);
0595 if (rec->dram_opened)
0596 emu8k_close_dram(rec->emu);
0597 snd_util_mem_free(rec->emu->memhdr, rec->block);
0598 rec->block = NULL;
0599 }
0600 return 0;
0601 }
0602
0603
0604
0605 static int emu8k_pcm_prepare(struct snd_pcm_substream *subs)
0606 {
0607 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0608
0609 rec->pitch = 0xe000 + calc_rate_offset(subs->runtime->rate);
0610 rec->last_ptr = 0;
0611 rec->period_pos = 0;
0612
0613 rec->buf_size = subs->runtime->buffer_size;
0614 rec->period_size = subs->runtime->period_size;
0615 rec->voices = subs->runtime->channels;
0616 rec->loop_start[0] = rec->offset + LOOP_BLANK_SIZE;
0617 if (rec->voices > 1)
0618 rec->loop_start[1] = rec->loop_start[0] + rec->buf_size + LOOP_BLANK_SIZE;
0619 if (rec->voices > 1) {
0620 rec->panning[0] = 0xff;
0621 rec->panning[1] = 0x00;
0622 } else
0623 rec->panning[0] = 0x80;
0624
0625 if (! rec->dram_opened) {
0626 int err, i, ch;
0627
0628 snd_emux_terminate_all(rec->emu->emu);
0629 err = emu8k_open_dram_for_pcm(rec->emu, rec->voices);
0630 if (err)
0631 return err;
0632 rec->dram_opened = 1;
0633
0634
0635 snd_emu8000_write_wait(rec->emu, 0);
0636 EMU8000_SMALW_WRITE(rec->emu, rec->offset);
0637 for (i = 0; i < LOOP_BLANK_SIZE; i++)
0638 EMU8000_SMLD_WRITE(rec->emu, 0);
0639 for (ch = 0; ch < rec->voices; ch++) {
0640 EMU8000_SMALW_WRITE(rec->emu, rec->loop_start[ch] + rec->buf_size);
0641 for (i = 0; i < LOOP_BLANK_SIZE; i++)
0642 EMU8000_SMLD_WRITE(rec->emu, 0);
0643 }
0644 }
0645
0646 setup_voice(rec, 0);
0647 if (rec->voices > 1)
0648 setup_voice(rec, 1);
0649 return 0;
0650 }
0651
0652 static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs)
0653 {
0654 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
0655 if (rec->running)
0656 return emu8k_get_curpos(rec, 0);
0657 return 0;
0658 }
0659
0660
0661 static const struct snd_pcm_ops emu8k_pcm_ops = {
0662 .open = emu8k_pcm_open,
0663 .close = emu8k_pcm_close,
0664 .hw_params = emu8k_pcm_hw_params,
0665 .hw_free = emu8k_pcm_hw_free,
0666 .prepare = emu8k_pcm_prepare,
0667 .trigger = emu8k_pcm_trigger,
0668 .pointer = emu8k_pcm_pointer,
0669 .copy_user = emu8k_pcm_copy,
0670 .copy_kernel = emu8k_pcm_copy_kernel,
0671 .fill_silence = emu8k_pcm_silence,
0672 };
0673
0674
0675 static void snd_emu8000_pcm_free(struct snd_pcm *pcm)
0676 {
0677 struct snd_emu8000 *emu = pcm->private_data;
0678 emu->pcm = NULL;
0679 }
0680
0681 int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index)
0682 {
0683 struct snd_pcm *pcm;
0684 int err;
0685
0686 err = snd_pcm_new(card, "Emu8000 PCM", index, 1, 0, &pcm);
0687 if (err < 0)
0688 return err;
0689 pcm->private_data = emu;
0690 pcm->private_free = snd_emu8000_pcm_free;
0691 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &emu8k_pcm_ops);
0692 emu->pcm = pcm;
0693
0694 snd_device_register(card, pcm);
0695
0696 return 0;
0697 }