sound: via82xx: deactivate DXS controls of inactive streams
Clemens Ladisch [Thu, 22 Oct 2009 07:04:09 +0000 (09:04 +0200)]
Activate the DXS volume controls only when the corresponding stream is
being used.  This makes the behaviour consistent with the other drivers
that have per-stream volume controls.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

sound/pci/via82xx.c

index 91683a3..8a332d2 100644 (file)
@@ -386,6 +386,7 @@ struct via82xx {
 
        struct snd_pcm *pcms[2];
        struct snd_rawmidi *rmidi;
+       struct snd_kcontrol *dxs_controls[4];
 
        struct snd_ac97_bus *ac97_bus;
        struct snd_ac97 *ac97;
@@ -1216,9 +1217,9 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
 
 
 /*
- * open callback for playback on via686 and via823x DSX
+ * open callback for playback on via686
  */
-static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
+static int snd_via686_playback_open(struct snd_pcm_substream *substream)
 {
        struct via82xx *chip = snd_pcm_substream_chip(substream);
        struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number];
@@ -1230,6 +1231,32 @@ static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
 }
 
 /*
+ * open callback for playback on via823x DXS
+ */
+static int snd_via8233_playback_open(struct snd_pcm_substream *substream)
+{
+       struct via82xx *chip = snd_pcm_substream_chip(substream);
+       struct viadev *viadev;
+       unsigned int stream;
+       int err;
+
+       viadev = &chip->devs[chip->playback_devno + substream->number];
+       if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
+               return err;
+       stream = viadev->reg_offset / 0x10;
+       if (chip->dxs_controls[stream]) {
+               chip->playback_volume[stream][0] = 0;
+               chip->playback_volume[stream][1] = 0;
+               chip->dxs_controls[stream]->vd[0].access &=
+                       ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+               snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
+                              SNDRV_CTL_EVENT_MASK_INFO,
+                              &chip->dxs_controls[stream]->id);
+       }
+       return 0;
+}
+
+/*
  * open callback for playback on via823x multi-channel
  */
 static int snd_via8233_multi_open(struct snd_pcm_substream *substream)
@@ -1302,10 +1329,26 @@ static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream)
        return 0;
 }
 
+static int snd_via8233_playback_close(struct snd_pcm_substream *substream)
+{
+       struct via82xx *chip = snd_pcm_substream_chip(substream);
+       struct viadev *viadev = substream->runtime->private_data;
+       unsigned int stream;
+
+       stream = viadev->reg_offset / 0x10;
+       if (chip->dxs_controls[stream]) {
+               chip->dxs_controls[stream]->vd[0].access |=
+                       SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+               snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO,
+                              &chip->dxs_controls[stream]->id);
+       }
+       return snd_via82xx_pcm_close(substream);
+}
+
 
 /* via686 playback callbacks */
 static struct snd_pcm_ops snd_via686_playback_ops = {
-       .open =         snd_via82xx_playback_open,
+       .open =         snd_via686_playback_open,
        .close =        snd_via82xx_pcm_close,
        .ioctl =        snd_pcm_lib_ioctl,
        .hw_params =    snd_via82xx_hw_params,
@@ -1331,8 +1374,8 @@ static struct snd_pcm_ops snd_via686_capture_ops = {
 
 /* via823x DSX playback callbacks */
 static struct snd_pcm_ops snd_via8233_playback_ops = {
-       .open =         snd_via82xx_playback_open,
-       .close =        snd_via82xx_pcm_close,
+       .open =         snd_via8233_playback_open,
+       .close =        snd_via8233_playback_close,
        .ioctl =        snd_pcm_lib_ioctl,
        .hw_params =    snd_via82xx_hw_params,
        .hw_free =      snd_via82xx_hw_free,
@@ -1709,8 +1752,9 @@ static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = {
        .device = 0,
        /* .subdevice set later */
        .name = "PCM Playback Volume",
-       .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
-                  SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+       .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+                 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+                 SNDRV_CTL_ELEM_ACCESS_INACTIVE,
        .info = snd_via8233_dxs_volume_info,
        .get = snd_via8233_dxs_volume_get,
        .put = snd_via8233_dxs_volume_put,
@@ -1948,6 +1992,7 @@ static int __devinit snd_via8233_init_misc(struct via82xx *chip)
                                err = snd_ctl_add(chip->card, kctl);
                                if (err < 0)
                                        return err;
+                               chip->dxs_controls[i] = kctl;
                        }
                }
        }