diff options
| -rw-r--r-- | include/sound/emu10k1.h | 1 | ||||
| -rw-r--r-- | sound/core/pcm_native.c | 4 | ||||
| -rw-r--r-- | sound/pci/emu10k1/emu10k1.c | 4 | ||||
| -rw-r--r-- | sound/pci/emu10k1/emupcm.c | 30 | ||||
| -rw-r--r-- | sound/pci/emu10k1/memory.c | 4 | ||||
| -rw-r--r-- | sound/pci/riptide/riptide.c | 11 |
6 files changed, 43 insertions, 11 deletions
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 6a664c3f7c1e..7dc97d12253c 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h | |||
| @@ -1707,6 +1707,7 @@ struct snd_emu10k1 { | |||
| 1707 | unsigned int card_type; /* EMU10K1_CARD_* */ | 1707 | unsigned int card_type; /* EMU10K1_CARD_* */ |
| 1708 | unsigned int ecard_ctrl; /* ecard control bits */ | 1708 | unsigned int ecard_ctrl; /* ecard control bits */ |
| 1709 | unsigned long dma_mask; /* PCI DMA mask */ | 1709 | unsigned long dma_mask; /* PCI DMA mask */ |
| 1710 | unsigned int delay_pcm_irq; /* in samples */ | ||
| 1710 | int max_cache_pages; /* max memory size / PAGE_SIZE */ | 1711 | int max_cache_pages; /* max memory size / PAGE_SIZE */ |
| 1711 | struct snd_dma_buffer silent_page; /* silent page */ | 1712 | struct snd_dma_buffer silent_page; /* silent page */ |
| 1712 | struct snd_dma_buffer ptb_pages; /* page table pages */ | 1713 | struct snd_dma_buffer ptb_pages; /* page table pages */ |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index a3b2a6479246..134fc6c2e08d 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
| @@ -978,6 +978,10 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push) | |||
| 978 | { | 978 | { |
| 979 | if (substream->runtime->trigger_master != substream) | 979 | if (substream->runtime->trigger_master != substream) |
| 980 | return 0; | 980 | return 0; |
| 981 | /* some drivers might use hw_ptr to recover from the pause - | ||
| 982 | update the hw_ptr now */ | ||
| 983 | if (push) | ||
| 984 | snd_pcm_update_hw_ptr(substream); | ||
| 981 | /* The jiffies check in snd_pcm_update_hw_ptr*() is done by | 985 | /* The jiffies check in snd_pcm_update_hw_ptr*() is done by |
| 982 | * a delta betwen the current jiffies, this gives a large enough | 986 | * a delta betwen the current jiffies, this gives a large enough |
| 983 | * delta, effectively to skip the check once. | 987 | * delta, effectively to skip the check once. |
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 4203782d7cb7..aff8387c45cf 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}; | |||
| 52 | static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; | 52 | static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; |
| 53 | static int enable_ir[SNDRV_CARDS]; | 53 | static int enable_ir[SNDRV_CARDS]; |
| 54 | static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */ | 54 | static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */ |
| 55 | static uint delay_pcm_irq[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; | ||
| 55 | 56 | ||
| 56 | module_param_array(index, int, NULL, 0444); | 57 | module_param_array(index, int, NULL, 0444); |
| 57 | MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard."); | 58 | MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard."); |
| @@ -73,6 +74,8 @@ module_param_array(enable_ir, bool, NULL, 0444); | |||
| 73 | MODULE_PARM_DESC(enable_ir, "Enable IR."); | 74 | MODULE_PARM_DESC(enable_ir, "Enable IR."); |
| 74 | module_param_array(subsystem, uint, NULL, 0444); | 75 | module_param_array(subsystem, uint, NULL, 0444); |
| 75 | MODULE_PARM_DESC(subsystem, "Force card subsystem model."); | 76 | MODULE_PARM_DESC(subsystem, "Force card subsystem model."); |
| 77 | module_param_array(delay_pcm_irq, uint, NULL, 0444); | ||
| 78 | MODULE_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 55b83ef73c63..622bace148e3 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 | ||
| 737 | static 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 | |||
| 735 | static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, | 754 | static 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 ffb1ddb8dc28..957a311514c8 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; |
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index f64fb7d988cb..ad5202efd7a9 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c | |||
| @@ -1224,15 +1224,14 @@ static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip) | |||
| 1224 | firmware.firmware.ASIC, firmware.firmware.CODEC, | 1224 | firmware.firmware.ASIC, firmware.firmware.CODEC, |
| 1225 | firmware.firmware.AUXDSP, firmware.firmware.PROG); | 1225 | firmware.firmware.AUXDSP, firmware.firmware.PROG); |
| 1226 | 1226 | ||
| 1227 | if (!chip) | ||
| 1228 | return 1; | ||
| 1229 | |||
| 1227 | for (i = 0; i < FIRMWARE_VERSIONS; i++) { | 1230 | for (i = 0; i < FIRMWARE_VERSIONS; i++) { |
| 1228 | if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware))) | 1231 | if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware))) |
| 1229 | break; | 1232 | return 1; /* OK */ |
| 1230 | } | ||
| 1231 | if (i >= FIRMWARE_VERSIONS) | ||
| 1232 | return 0; /* no match */ | ||
| 1233 | 1233 | ||
| 1234 | if (!chip) | 1234 | } |
| 1235 | return 1; /* OK */ | ||
| 1236 | 1235 | ||
| 1237 | snd_printdd("Writing Firmware\n"); | 1236 | snd_printdd("Writing Firmware\n"); |
| 1238 | if (!chip->fw_entry) { | 1237 | if (!chip->fw_entry) { |
