aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ymfpci
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2007-07-23 11:38:44 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:57:50 -0400
commit177a7cdbd1d88be5cbf957a2793a59ffa50cbef9 (patch)
tree639a747390b35fa8d1f7359b020faee466b2ba59 /sound/pci/ymfpci
parenteafe57084786d5711e434165297f13864697f9f9 (diff)
[ALSA] ymfpci: fix volume handling of the 44.1 kHz slot
The existing code for handling the 44.1 slot's volume has two problems: the volume is not affected by the 'Wave Playback Volume' mixer control, and the BUF441OUTVOL register, which is used to control the per- substream volume for this slot, uses a different scale than the gain fields of the other slots. This patch makes the BUF441OUTVOL register a shadow of the NATIVEDACOUTVOL register so that the Wave volume is consistent for all substreams. As a consequence of this, the per-substream PCM volume control gets no longer activated for the substream using this slot. The code for (de)activating the mixer control is moved from the open/close to the prepare/trigger_stop callbacks so that it is able to determine the substream's slot. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/ymfpci')
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c70
1 files changed, 46 insertions, 24 deletions
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 7fa57c9ecc5f..e33e4aa6855c 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -171,17 +171,6 @@ 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
185/* 174/*
186 * Hardware start management 175 * Hardware start management
187 */ 176 */
@@ -389,6 +378,7 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
389{ 378{
390 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); 379 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
391 struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; 380 struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
381 struct snd_kcontrol *kctl = NULL;
392 int result = 0; 382 int result = 0;
393 383
394 spin_lock(&chip->reg_lock); 384 spin_lock(&chip->reg_lock);
@@ -406,6 +396,11 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
406 ypcm->running = 1; 396 ypcm->running = 1;
407 break; 397 break;
408 case SNDRV_PCM_TRIGGER_STOP: 398 case SNDRV_PCM_TRIGGER_STOP:
399 if (substream->pcm == chip->pcm && !ypcm->use_441_slot) {
400 kctl = chip->pcm_mixer[substream->number].ctl;
401 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
402 }
403 /* fall through */
409 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 404 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
410 case SNDRV_PCM_TRIGGER_SUSPEND: 405 case SNDRV_PCM_TRIGGER_SUSPEND:
411 chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0; 406 chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0;
@@ -419,6 +414,8 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
419 } 414 }
420 __unlock: 415 __unlock:
421 spin_unlock(&chip->reg_lock); 416 spin_unlock(&chip->reg_lock);
417 if (kctl)
418 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
422 return result; 419 return result;
423} 420}
424static int snd_ymfpci_capture_trigger(struct snd_pcm_substream *substream, 421static int snd_ymfpci_capture_trigger(struct snd_pcm_substream *substream,
@@ -526,7 +523,6 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
526 ypcm->chip->src441_used = voice->number; 523 ypcm->chip->src441_used = voice->number;
527 ypcm->use_441_slot = 1; 524 ypcm->use_441_slot = 1;
528 format |= 0x10000000; 525 format |= 0x10000000;
529 snd_ymfpci_pcm_441_volume_set(ypcm);
530 } 526 }
531 if (ypcm->chip->src441_used == voice->number && 527 if (ypcm->chip->src441_used == voice->number &&
532 (format & 0x10000000) == 0) { 528 (format & 0x10000000) == 0) {
@@ -667,6 +663,7 @@ static int snd_ymfpci_playback_prepare(struct snd_pcm_substream *substream)
667 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); 663 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
668 struct snd_pcm_runtime *runtime = substream->runtime; 664 struct snd_pcm_runtime *runtime = substream->runtime;
669 struct snd_ymfpci_pcm *ypcm = runtime->private_data; 665 struct snd_ymfpci_pcm *ypcm = runtime->private_data;
666 struct snd_kcontrol *kctl;
670 unsigned int nvoice; 667 unsigned int nvoice;
671 668
672 ypcm->period_size = runtime->period_size; 669 ypcm->period_size = runtime->period_size;
@@ -676,6 +673,12 @@ static int snd_ymfpci_playback_prepare(struct snd_pcm_substream *substream)
676 for (nvoice = 0; nvoice < runtime->channels; nvoice++) 673 for (nvoice = 0; nvoice < runtime->channels; nvoice++)
677 snd_ymfpci_pcm_init_voice(ypcm, nvoice, runtime, 674 snd_ymfpci_pcm_init_voice(ypcm, nvoice, runtime,
678 substream->pcm == chip->pcm); 675 substream->pcm == chip->pcm);
676
677 if (substream->pcm == chip->pcm && !ypcm->use_441_slot) {
678 kctl = chip->pcm_mixer[substream->number].ctl;
679 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
680 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
681 }
679 return 0; 682 return 0;
680} 683}
681 684
@@ -926,7 +929,6 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream)
926 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); 929 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
927 struct snd_pcm_runtime *runtime = substream->runtime; 930 struct snd_pcm_runtime *runtime = substream->runtime;
928 struct snd_ymfpci_pcm *ypcm; 931 struct snd_ymfpci_pcm *ypcm;
929 struct snd_kcontrol *kctl;
930 int err; 932 int err;
931 933
932 if ((err = snd_ymfpci_playback_open_1(substream)) < 0) 934 if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
@@ -941,10 +943,6 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream)
941 chip->rear_opened++; 943 chip->rear_opened++;
942 } 944 }
943 spin_unlock_irq(&chip->reg_lock); 945 spin_unlock_irq(&chip->reg_lock);
944
945 kctl = chip->pcm_mixer[substream->number].ctl;
946 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
947 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
948 return 0; 946 return 0;
949} 947}
950 948
@@ -1039,7 +1037,6 @@ static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream)
1039{ 1037{
1040 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); 1038 struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
1041 struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; 1039 struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
1042 struct snd_kcontrol *kctl;
1043 1040
1044 spin_lock_irq(&chip->reg_lock); 1041 spin_lock_irq(&chip->reg_lock);
1045 if (ypcm->output_rear && chip->rear_opened > 0) { 1042 if (ypcm->output_rear && chip->rear_opened > 0) {
@@ -1047,9 +1044,6 @@ static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream)
1047 ymfpci_close_extension(chip); 1044 ymfpci_close_extension(chip);
1048 } 1045 }
1049 spin_unlock_irq(&chip->reg_lock); 1046 spin_unlock_irq(&chip->reg_lock);
1050 kctl = chip->pcm_mixer[substream->number].ctl;
1051 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1052 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
1053 return snd_ymfpci_playback_close_1(substream); 1047 return snd_ymfpci_playback_close_1(substream);
1054} 1048}
1055 1049
@@ -1552,6 +1546,26 @@ static int snd_ymfpci_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1552 return change; 1546 return change;
1553} 1547}
1554 1548
1549static int snd_ymfpci_put_nativedacvol(struct snd_kcontrol *kcontrol,
1550 struct snd_ctl_elem_value *ucontrol)
1551{
1552 struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
1553 unsigned int reg = YDSXGR_NATIVEDACOUTVOL;
1554 unsigned int reg2 = YDSXGR_BUF441OUTVOL;
1555 int change;
1556 unsigned int value, oval;
1557
1558 value = ucontrol->value.integer.value[0] & 0x3fff;
1559 value |= (ucontrol->value.integer.value[1] & 0x3fff) << 16;
1560 spin_lock_irq(&chip->reg_lock);
1561 oval = snd_ymfpci_readl(chip, reg);
1562 change = value != oval;
1563 snd_ymfpci_writel(chip, reg, value);
1564 snd_ymfpci_writel(chip, reg2, value);
1565 spin_unlock_irq(&chip->reg_lock);
1566 return change;
1567}
1568
1555/* 1569/*
1556 * 4ch duplication 1570 * 4ch duplication
1557 */ 1571 */
@@ -1576,7 +1590,17 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1576 1590
1577 1591
1578static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { 1592static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = {
1579YMFPCI_DOUBLE("Wave Playback Volume", 0, YDSXGR_NATIVEDACOUTVOL), 1593{
1594 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1595 .name = "Wave Playback Volume",
1596 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1597 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
1598 .info = snd_ymfpci_info_double,
1599 .get = snd_ymfpci_get_double,
1600 .put = snd_ymfpci_put_nativedacvol,
1601 .private_value = YDSXGR_NATIVEDACOUTVOL,
1602 .tlv = { .p = db_scale_native },
1603},
1580YMFPCI_DOUBLE("Wave Capture Volume", 0, YDSXGR_NATIVEDACLOOPVOL), 1604YMFPCI_DOUBLE("Wave Capture Volume", 0, YDSXGR_NATIVEDACLOOPVOL),
1581YMFPCI_DOUBLE("Digital Capture Volume", 0, YDSXGR_NATIVEDACINVOL), 1605YMFPCI_DOUBLE("Digital Capture Volume", 0, YDSXGR_NATIVEDACINVOL),
1582YMFPCI_DOUBLE("Digital Capture Volume", 1, YDSXGR_NATIVEADCINVOL), 1606YMFPCI_DOUBLE("Digital Capture Volume", 1, YDSXGR_NATIVEADCINVOL),
@@ -1719,8 +1743,6 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol,
1719 struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; 1743 struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
1720 if (!ypcm->use_441_slot) 1744 if (!ypcm->use_441_slot)
1721 ypcm->update_pcm_vol = 2; 1745 ypcm->update_pcm_vol = 2;
1722 else
1723 snd_ymfpci_pcm_441_volume_set(ypcm);
1724 } 1746 }
1725 spin_unlock_irqrestore(&chip->voice_lock, flags); 1747 spin_unlock_irqrestore(&chip->voice_lock, flags);
1726 return 1; 1748 return 1;