aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeru KAMOGASHIRA <teru@sodan.ecc.u-tokyo.ac.jp>2006-12-04 12:03:53 -0500
committerJaroslav Kysela <perex@suse.cz>2007-02-09 03:02:16 -0500
commit9ed1261e3e617d99b0eb74041d0337ff664e4f5b (patch)
treedf8006d93195edb21bb38f51ff94457e30cfc48f
parentc577b8a16fd19a33a8865ca6451287d284a0faf6 (diff)
[ALSA] Current driver does not utilize 44.1kHz high quality sampling rate converter.
Following patch will make the driver to use the 44.1kHz SRC automatically if the pcm source is 44.1kHz signed 16bit stereo. The SRC is available in YMF754 only. Signed-off-by: Teru KAMOGASHIRA <teru@sodan.ecc.u-tokyo.ac.jp> Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r--include/sound/ymfpci.h4
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c44
2 files changed, 43 insertions, 5 deletions
diff --git a/include/sound/ymfpci.h b/include/sound/ymfpci.h
index eef46faaee30..203d2b45b788 100644
--- a/include/sound/ymfpci.h
+++ b/include/sound/ymfpci.h
@@ -270,6 +270,7 @@ struct snd_ymfpci_pcm {
270 struct snd_pcm_substream *substream; 270 struct snd_pcm_substream *substream;
271 struct snd_ymfpci_voice *voices[2]; /* playback only */ 271 struct snd_ymfpci_voice *voices[2]; /* playback only */
272 unsigned int running: 1, 272 unsigned int running: 1,
273 use_441_slot: 1,
273 output_front: 1, 274 output_front: 1,
274 output_rear: 1, 275 output_rear: 1,
275 swap_rear: 1; 276 swap_rear: 1;
@@ -324,6 +325,7 @@ struct snd_ymfpci {
324 325
325 u32 active_bank; 326 u32 active_bank;
326 struct snd_ymfpci_voice voices[64]; 327 struct snd_ymfpci_voice voices[64];
328 int src441_used;
327 329
328 struct snd_ac97_bus *ac97_bus; 330 struct snd_ac97_bus *ac97_bus;
329 struct snd_ac97 *ac97; 331 struct snd_ac97 *ac97;
@@ -346,7 +348,7 @@ struct snd_ymfpci {
346 int mode_dup4ch; 348 int mode_dup4ch;
347 int rear_opened; 349 int rear_opened;
348 int spdif_opened; 350 int spdif_opened;
349 struct { 351 struct snd_ymfpci_pcm_mixer {
350 u16 left; 352 u16 left;
351 u16 right; 353 u16 right;
352 struct snd_kcontrol *ctl; 354 struct snd_kcontrol *ctl;
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);