aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ymfpci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ymfpci')
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c44
1 files changed, 40 insertions, 4 deletions
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 5bde816cd5c4..8b076932f4f5 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -171,6 +171,17 @@ static u32 snd_ymfpci_calc_lpfQ(u32 rate)
171 return val[0]; 171 return val[0];
172} 172}
173 173
174static void snd_ymfpci_pcm_441_volume_set(struct snd_ymfpci_pcm *ypcm)
175{
176 unsigned int value;
177 struct snd_ymfpci_pcm_mixer *mixer;
178
179 mixer = &ypcm->chip->pcm_mixer[ypcm->substream->number];
180 value = min_t(unsigned int, mixer->left, 0x7fff) >> 1;
181 value |= (min_t(unsigned int, mixer->right, 0x7fff) >> 1) << 16;
182 snd_ymfpci_writel(ypcm->chip, YDSXGR_BUF441OUTVOL, value);
183}
184
174/* 185/*
175 * Hardware start management 186 * Hardware start management
176 */ 187 */
@@ -282,6 +293,10 @@ static int snd_ymfpci_voice_free(struct snd_ymfpci *chip, struct snd_ymfpci_voic
282 snd_assert(pvoice != NULL, return -EINVAL); 293 snd_assert(pvoice != NULL, return -EINVAL);
283 snd_ymfpci_hw_stop(chip); 294 snd_ymfpci_hw_stop(chip);
284 spin_lock_irqsave(&chip->voice_lock, flags); 295 spin_lock_irqsave(&chip->voice_lock, flags);
296 if (pvoice->number == chip->src441_used) {
297 chip->src441_used = -1;
298 pvoice->ypcm->use_441_slot = 0;
299 }
285 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0; 300 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0;
286 pvoice->ypcm = NULL; 301 pvoice->ypcm = NULL;
287 pvoice->interrupt = NULL; 302 pvoice->interrupt = NULL;
@@ -386,7 +401,7 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
386 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 401 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
387 case SNDRV_PCM_TRIGGER_RESUME: 402 case SNDRV_PCM_TRIGGER_RESUME:
388 chip->ctrl_playback[ypcm->voices[0]->number + 1] = cpu_to_le32(ypcm->voices[0]->bank_addr); 403 chip->ctrl_playback[ypcm->voices[0]->number + 1] = cpu_to_le32(ypcm->voices[0]->bank_addr);
389 if (ypcm->voices[1] != NULL) 404 if (ypcm->voices[1] != NULL && !ypcm->use_441_slot)
390 chip->ctrl_playback[ypcm->voices[1]->number + 1] = cpu_to_le32(ypcm->voices[1]->bank_addr); 405 chip->ctrl_playback[ypcm->voices[1]->number + 1] = cpu_to_le32(ypcm->voices[1]->bank_addr);
391 ypcm->running = 1; 406 ypcm->running = 1;
392 break; 407 break;
@@ -394,7 +409,7 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
394 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 409 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
395 case SNDRV_PCM_TRIGGER_SUSPEND: 410 case SNDRV_PCM_TRIGGER_SUSPEND:
396 chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0; 411 chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0;
397 if (ypcm->voices[1] != NULL) 412 if (ypcm->voices[1] != NULL && !ypcm->use_441_slot)
398 chip->ctrl_playback[ypcm->voices[1]->number + 1] = 0; 413 chip->ctrl_playback[ypcm->voices[1]->number + 1] = 0;
399 ypcm->running = 0; 414 ypcm->running = 0;
400 break; 415 break;
@@ -481,6 +496,7 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
481 unsigned int nbank; 496 unsigned int nbank;
482 u32 vol_left, vol_right; 497 u32 vol_left, vol_right;
483 u8 use_left, use_right; 498 u8 use_left, use_right;
499 unsigned long flags;
484 500
485 snd_assert(voice != NULL, return); 501 snd_assert(voice != NULL, return);
486 if (runtime->channels == 1) { 502 if (runtime->channels == 1) {
@@ -499,11 +515,27 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
499 vol_left = cpu_to_le32(0x40000000); 515 vol_left = cpu_to_le32(0x40000000);
500 vol_right = cpu_to_le32(0x40000000); 516 vol_right = cpu_to_le32(0x40000000);
501 } 517 }
518 spin_lock_irqsave(&ypcm->chip->voice_lock, flags);
502 format = runtime->channels == 2 ? 0x00010000 : 0; 519 format = runtime->channels == 2 ? 0x00010000 : 0;
503 if (snd_pcm_format_width(runtime->format) == 8) 520 if (snd_pcm_format_width(runtime->format) == 8)
504 format |= 0x80000000; 521 format |= 0x80000000;
522 else if (ypcm->chip->device_id == PCI_DEVICE_ID_YAMAHA_754 &&
523 runtime->rate == 44100 && runtime->channels == 2 &&
524 voiceidx == 0 && (ypcm->chip->src441_used == -1 ||
525 ypcm->chip->src441_used == voice->number)) {
526 ypcm->chip->src441_used = voice->number;
527 ypcm->use_441_slot = 1;
528 format |= 0x10000000;
529 snd_ymfpci_pcm_441_volume_set(ypcm);
530 }
531 if (ypcm->chip->src441_used == voice->number &&
532 (format & 0x10000000) == 0) {
533 ypcm->chip->src441_used = -1;
534 ypcm->use_441_slot = 0;
535 }
505 if (runtime->channels == 2 && (voiceidx & 1) != 0) 536 if (runtime->channels == 2 && (voiceidx & 1) != 0)
506 format |= 1; 537 format |= 1;
538 spin_unlock_irqrestore(&ypcm->chip->voice_lock, flags);
507 for (nbank = 0; nbank < 2; nbank++) { 539 for (nbank = 0; nbank < 2; nbank++) {
508 bank = &voice->bank[nbank]; 540 bank = &voice->bank[nbank];
509 memset(bank, 0, sizeof(*bank)); 541 memset(bank, 0, sizeof(*bank));
@@ -1714,7 +1746,10 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol,
1714 spin_lock_irqsave(&chip->voice_lock, flags); 1746 spin_lock_irqsave(&chip->voice_lock, flags);
1715 if (substream->runtime && substream->runtime->private_data) { 1747 if (substream->runtime && substream->runtime->private_data) {
1716 struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; 1748 struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
1717 ypcm->update_pcm_vol = 2; 1749 if (!ypcm->use_441_slot)
1750 ypcm->update_pcm_vol = 2;
1751 else
1752 snd_ymfpci_pcm_441_volume_set(ypcm);
1718 } 1753 }
1719 spin_unlock_irqrestore(&chip->voice_lock, flags); 1754 spin_unlock_irqrestore(&chip->voice_lock, flags);
1720 return 1; 1755 return 1;
@@ -2253,7 +2288,7 @@ static int saved_regs_index[] = {
2253 YDSXGR_PRIADCLOOPVOL, 2288 YDSXGR_PRIADCLOOPVOL,
2254 YDSXGR_NATIVEDACINVOL, 2289 YDSXGR_NATIVEDACINVOL,
2255 YDSXGR_NATIVEDACOUTVOL, 2290 YDSXGR_NATIVEDACOUTVOL,
2256 // YDSXGR_BUF441OUTVOL, 2291 YDSXGR_BUF441OUTVOL,
2257 YDSXGR_NATIVEADCINVOL, 2292 YDSXGR_NATIVEADCINVOL,
2258 YDSXGR_SPDIFLOOPVOL, 2293 YDSXGR_SPDIFLOOPVOL,
2259 YDSXGR_SPDIFOUTVOL, 2294 YDSXGR_SPDIFOUTVOL,
@@ -2368,6 +2403,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
2368 chip->reg_area_phys = pci_resource_start(pci, 0); 2403 chip->reg_area_phys = pci_resource_start(pci, 0);
2369 chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000); 2404 chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000);
2370 pci_set_master(pci); 2405 pci_set_master(pci);
2406 chip->src441_used = -1;
2371 2407
2372 if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) { 2408 if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
2373 snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1); 2409 snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);