aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/emu10k1/emu10k1.c4
-rw-r--r--sound/pci/emu10k1/emupcm.c30
-rw-r--r--sound/pci/emu10k1/memory.c4
3 files changed, 33 insertions, 5 deletions
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 4203782d7cb..aff8387c45c 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -52,6 +52,7 @@ static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
52static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; 52static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
53static int enable_ir[SNDRV_CARDS]; 53static int enable_ir[SNDRV_CARDS];
54static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */ 54static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */
55static uint delay_pcm_irq[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
55 56
56module_param_array(index, int, NULL, 0444); 57module_param_array(index, int, NULL, 0444);
57MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard."); 58MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
@@ -73,6 +74,8 @@ module_param_array(enable_ir, bool, NULL, 0444);
73MODULE_PARM_DESC(enable_ir, "Enable IR."); 74MODULE_PARM_DESC(enable_ir, "Enable IR.");
74module_param_array(subsystem, uint, NULL, 0444); 75module_param_array(subsystem, uint, NULL, 0444);
75MODULE_PARM_DESC(subsystem, "Force card subsystem model."); 76MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
77module_param_array(delay_pcm_irq, uint, NULL, 0444);
78MODULE_PARM_DESC(delay_pcm_irq, "Delay PCM interrupt by specified number of samples (default 0).");
76/* 79/*
77 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 80 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
78 */ 81 */
@@ -127,6 +130,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
127 &emu)) < 0) 130 &emu)) < 0)
128 goto error; 131 goto error;
129 card->private_data = emu; 132 card->private_data = emu;
133 emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f;
130 if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) 134 if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0)
131 goto error; 135 goto error;
132 if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) 136 if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0)
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 55b83ef73c6..622bace148e 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -332,7 +332,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
332 evoice->epcm->ccca_start_addr = start_addr + ccis; 332 evoice->epcm->ccca_start_addr = start_addr + ccis;
333 if (extra) { 333 if (extra) {
334 start_addr += ccis; 334 start_addr += ccis;
335 end_addr += ccis; 335 end_addr += ccis + emu->delay_pcm_irq;
336 } 336 }
337 if (stereo && !extra) { 337 if (stereo && !extra) {
338 snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK); 338 snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK);
@@ -360,7 +360,9 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
360 /* Assumption that PT is already 0 so no harm overwriting */ 360 /* Assumption that PT is already 0 so no harm overwriting */
361 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]); 361 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
362 snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24)); 362 snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
363 snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24)); 363 snd_emu10k1_ptr_write(emu, PSST, voice,
364 (start_addr + (extra ? emu->delay_pcm_irq : 0)) |
365 (send_amount[2] << 24));
364 if (emu->card_capabilities->emu_model) 366 if (emu->card_capabilities->emu_model)
365 pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */ 367 pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
366 else 368 else
@@ -732,6 +734,23 @@ static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu, struct snd_
732 snd_emu10k1_ptr_write(emu, IP, voice, 0); 734 snd_emu10k1_ptr_write(emu, IP, voice, 0);
733} 735}
734 736
737static inline void snd_emu10k1_playback_mangle_extra(struct snd_emu10k1 *emu,
738 struct snd_emu10k1_pcm *epcm,
739 struct snd_pcm_substream *substream,
740 struct snd_pcm_runtime *runtime)
741{
742 unsigned int ptr, period_pos;
743
744 /* try to sychronize the current position for the interrupt
745 source voice */
746 period_pos = runtime->status->hw_ptr - runtime->hw_ptr_interrupt;
747 period_pos %= runtime->period_size;
748 ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->extra->number);
749 ptr &= ~0x00ffffff;
750 ptr |= epcm->ccca_start_addr + period_pos;
751 snd_emu10k1_ptr_write(emu, CCCA, epcm->extra->number, ptr);
752}
753
735static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, 754static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
736 int cmd) 755 int cmd)
737{ 756{
@@ -753,6 +772,8 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
753 /* follow thru */ 772 /* follow thru */
754 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 773 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
755 case SNDRV_PCM_TRIGGER_RESUME: 774 case SNDRV_PCM_TRIGGER_RESUME:
775 if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE)
776 snd_emu10k1_playback_mangle_extra(emu, epcm, substream, runtime);
756 mix = &emu->pcm_mixer[substream->number]; 777 mix = &emu->pcm_mixer[substream->number];
757 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix); 778 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
758 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix); 779 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
@@ -869,8 +890,9 @@ static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream *
869#endif 890#endif
870 /* 891 /*
871 printk(KERN_DEBUG 892 printk(KERN_DEBUG
872 "ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", 893 "ptr = 0x%lx, buffer_size = 0x%lx, period_size = 0x%lx\n",
873 ptr, runtime->buffer_size, runtime->period_size); 894 (long)ptr, (long)runtime->buffer_size,
895 (long)runtime->period_size);
874 */ 896 */
875 return ptr; 897 return ptr;
876} 898}
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index ffb1ddb8dc2..957a311514c 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -310,8 +310,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
310 if (snd_BUG_ON(!hdr)) 310 if (snd_BUG_ON(!hdr))
311 return NULL; 311 return NULL;
312 312
313 idx = runtime->period_size >= runtime->buffer_size ?
314 (emu->delay_pcm_irq * 2) : 0;
313 mutex_lock(&hdr->block_mutex); 315 mutex_lock(&hdr->block_mutex);
314 blk = search_empty(emu, runtime->dma_bytes); 316 blk = search_empty(emu, runtime->dma_bytes + idx);
315 if (blk == NULL) { 317 if (blk == NULL) {
316 mutex_unlock(&hdr->block_mutex); 318 mutex_unlock(&hdr->block_mutex);
317 return NULL; 319 return NULL;