Commit 9ed1261e3e617d99b0eb74041d0337ff664e4f5b

Authored by Teru KAMOGASHIRA
Committed by Jaroslav Kysela
1 parent c577b8a16f

[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>

Showing 2 changed files with 43 additions and 5 deletions Side-by-side Diff

include/sound/ymfpci.h
... ... @@ -270,6 +270,7 @@
270 270 struct snd_pcm_substream *substream;
271 271 struct snd_ymfpci_voice *voices[2]; /* playback only */
272 272 unsigned int running: 1,
  273 + use_441_slot: 1,
273 274 output_front: 1,
274 275 output_rear: 1,
275 276 swap_rear: 1;
... ... @@ -324,6 +325,7 @@
324 325  
325 326 u32 active_bank;
326 327 struct snd_ymfpci_voice voices[64];
  328 + int src441_used;
327 329  
328 330 struct snd_ac97_bus *ac97_bus;
329 331 struct snd_ac97 *ac97;
... ... @@ -346,7 +348,7 @@
346 348 int mode_dup4ch;
347 349 int rear_opened;
348 350 int spdif_opened;
349   - struct {
  351 + struct snd_ymfpci_pcm_mixer {
350 352 u16 left;
351 353 u16 right;
352 354 struct snd_kcontrol *ctl;
sound/pci/ymfpci/ymfpci_main.c
... ... @@ -171,6 +171,17 @@
171 171 return val[0];
172 172 }
173 173  
  174 +static 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 186 * Hardware start management
176 187 */
... ... @@ -282,6 +293,10 @@
282 293 snd_assert(pvoice != NULL, return -EINVAL);
283 294 snd_ymfpci_hw_stop(chip);
284 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 300 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0;
286 301 pvoice->ypcm = NULL;
287 302 pvoice->interrupt = NULL;
... ... @@ -386,7 +401,7 @@
386 401 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
387 402 case SNDRV_PCM_TRIGGER_RESUME:
388 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 405 chip->ctrl_playback[ypcm->voices[1]->number + 1] = cpu_to_le32(ypcm->voices[1]->bank_addr);
391 406 ypcm->running = 1;
392 407 break;
... ... @@ -394,7 +409,7 @@
394 409 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
395 410 case SNDRV_PCM_TRIGGER_SUSPEND:
396 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 413 chip->ctrl_playback[ypcm->voices[1]->number + 1] = 0;
399 414 ypcm->running = 0;
400 415 break;
... ... @@ -481,6 +496,7 @@
481 496 unsigned int nbank;
482 497 u32 vol_left, vol_right;
483 498 u8 use_left, use_right;
  499 + unsigned long flags;
484 500  
485 501 snd_assert(voice != NULL, return);
486 502 if (runtime->channels == 1) {
487 503  
488 504  
... ... @@ -499,11 +515,27 @@
499 515 vol_left = cpu_to_le32(0x40000000);
500 516 vol_right = cpu_to_le32(0x40000000);
501 517 }
  518 + spin_lock_irqsave(&ypcm->chip->voice_lock, flags);
502 519 format = runtime->channels == 2 ? 0x00010000 : 0;
503 520 if (snd_pcm_format_width(runtime->format) == 8)
504 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 536 if (runtime->channels == 2 && (voiceidx & 1) != 0)
506 537 format |= 1;
  538 + spin_unlock_irqrestore(&ypcm->chip->voice_lock, flags);
507 539 for (nbank = 0; nbank < 2; nbank++) {
508 540 bank = &voice->bank[nbank];
509 541 memset(bank, 0, sizeof(*bank));
... ... @@ -1714,7 +1746,10 @@
1714 1746 spin_lock_irqsave(&chip->voice_lock, flags);
1715 1747 if (substream->runtime && substream->runtime->private_data) {
1716 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 1754 spin_unlock_irqrestore(&chip->voice_lock, flags);
1720 1755 return 1;
... ... @@ -2253,7 +2288,7 @@
2253 2288 YDSXGR_PRIADCLOOPVOL,
2254 2289 YDSXGR_NATIVEDACINVOL,
2255 2290 YDSXGR_NATIVEDACOUTVOL,
2256   - // YDSXGR_BUF441OUTVOL,
  2291 + YDSXGR_BUF441OUTVOL,
2257 2292 YDSXGR_NATIVEADCINVOL,
2258 2293 YDSXGR_SPDIFLOOPVOL,
2259 2294 YDSXGR_SPDIFOUTVOL,
... ... @@ -2368,6 +2403,7 @@
2368 2403 chip->reg_area_phys = pci_resource_start(pci, 0);
2369 2404 chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000);
2370 2405 pci_set_master(pci);
  2406 + chip->src441_used = -1;
2371 2407  
2372 2408 if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
2373 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);