diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 762bb10..60ba558 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -268,8 +268,13 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 		card->shortname, chip->io, chip->irq);
 
 	// (4) Alloc components.
+	// snd_ac97_mixer and Vortex mixer.
+	if ((err = snd_vortex_mixer(chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
 	// ADB pcm.
-	if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_ADB)) < 0) {
+	if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_PCM)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -299,11 +304,6 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 		return err;
 	}
 #endif
-	// snd_ac97_mixer and Vortex mixer.
-	if ((err = snd_vortex_mixer(chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
 	if ((err = snd_vortex_midi(chip)) < 0) {
 		snd_card_free(card);
 		return err;
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index 02f6e08..196ca36 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -26,7 +26,7 @@
 #include <sound/mpu401.h>
 #include <sound/hwdep.h>
 #include <sound/ac97_codec.h>
-
+#include <sound/tlv.h>
 #endif
 
 #ifndef CHIP_AU8820
@@ -105,6 +105,7 @@
 #define MIX_SPDIF(x) (vortex->mixspdif[x])
 
 #define NR_WTPB 0x20		/* WT channels per each bank. */
+#define NR_PCM	0x10		/* Number of subdevices */
 
 /* Structs */
 typedef struct {
@@ -131,6 +132,14 @@ typedef struct {
 	struct snd_pcm_substream *substream;
 } stream_t;
 
+typedef struct {
+	struct snd_kcontrol *kctl;
+	int active;
+	int dma;
+	int vol[4];
+	int mixin[4];
+} pcm_vol_t; 
+
 typedef struct snd_vortex vortex_t;
 struct snd_vortex {
 	/* ALSA structs. */
@@ -169,6 +178,8 @@ struct snd_vortex {
 #endif
 
 	int isquad;		/* cache of extended ID codec flag. */
+	
+	pcm_vol_t pcm_mixer[NR_PCM];
 
 	/* Gameport stuff. */
 	struct gameport *gameport;
@@ -238,7 +249,7 @@ static int vortex_alsafmt_aspfmt(int alsafmt);
 /* Connection  stuff. */
 static void vortex_connect_default(vortex_t * vortex, int en);
 static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
-				 int dir, int type);
+		 int dir, int type, struct snd_pcm_substream *substream);
 static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
 				  int restype);
 #ifndef CHIP_AU8810
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 6933a27..a573758 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2050,8 +2050,6 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
 }
 
 /* Default Connections  */
-static int
-vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type);
 
 static void vortex_connect_default(vortex_t * vortex, int en)
 {
@@ -2111,10 +2109,12 @@ static void vortex_connect_default(vortex_t * vortex, int en)
   Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.
 */
 static int
-vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
+vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir,
+			int type, struct snd_pcm_substream *substream)
 {
 	stream_t *stream;
-	int i, en;
+	int i, en, subdev;
+	pcm_vol_t *p;
 	
 	if ((nr_ch == 3)
 	    || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
@@ -2250,6 +2250,18 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
 							      MIX_DEFIGAIN);
 #endif
 			}
+			if (stream->type == VORTEX_PCM_ADB) {
+				if (en) {
+					subdev = substream->number;
+					p = &vortex->pcm_mixer[subdev];
+					p->dma = dma;
+					for (i = 0; i < nr_ch; i++)
+						p->mixin[i] = mix[i];
+					ch_top = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
+					for (i = 0; i < ch_top; i++)
+						p->vol[i] = 0;
+				}	
+			}
 		}
 #ifndef CHIP_AU8820
 		else {
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 0488633..27a7b6d 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -122,6 +122,17 @@ static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
 	.mask = 0,
 };
 #endif
+
+static void vortex_notify_pcm_vol_change(struct snd_card *card,
+			struct snd_kcontrol *kctl, int activate)
+{
+	if (activate)
+		kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	else
+		kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &(kctl->id));
+}
+
 /* open callback */
 static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
 {
@@ -229,12 +240,12 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
 		if (stream != NULL)
 			vortex_adb_allocroute(chip, stream->dma,
 					      stream->nr_ch, stream->dir,
-					      stream->type);
+					      stream->type, substream);
 		/* Alloc routes. */
 		dma =
 		    vortex_adb_allocroute(chip, -1,
 					  params_channels(hw_params),
-					  substream->stream, type);
+					  substream->stream, type, substream);
 		if (dma < 0) {
 			spin_unlock_irq(&chip->lock);
 			return dma;
@@ -245,6 +256,11 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
 		vortex_adbdma_setbuffers(chip, dma,
 					 params_period_bytes(hw_params),
 					 params_periods(hw_params));
+		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
+			chip->pcm_mixer[substream->number].active = 1;
+			vortex_notify_pcm_vol_change(chip->card,
+				chip->pcm_mixer[substream->number].kctl, 1);
+		}
 	}
 #ifndef CHIP_AU8810
 	else {
@@ -274,10 +290,16 @@ static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
 	spin_lock_irq(&chip->lock);
 	// Delete audio routes.
 	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
-		if (stream != NULL)
+		if (stream != NULL) {
+			if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
+				chip->pcm_mixer[substream->number].active = 0;
+				vortex_notify_pcm_vol_change(chip->card,
+					chip->pcm_mixer[substream->number].kctl, 0);
+			}
 			vortex_adb_allocroute(chip, stream->dma,
 					      stream->nr_ch, stream->dir,
-					      stream->type);
+					      stream->type, substream);
+		}
 	}
 #ifndef CHIP_AU8810
 	else {
@@ -505,6 +527,82 @@ static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = {
 	},
 };
 
+/* PCM Volume control for subdevice */
+
+static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
+{
+	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
+	uinfo->value.integer.min = -64;
+	uinfo->value.integer.max = 8;
+	return 0;
+}
+
+static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	int i;
+	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
+	int subdev = kcontrol->id.subdevice;
+	pcm_vol_t *p = &vortex->pcm_mixer[subdev];
+	int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
+	for (i = 0; i < max_chn; i++)
+		ucontrol->value.integer.value[i] = p->vol[i];
+	return 0;
+}
+
+static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	int i;
+	int changed = 0;
+	int mixin;
+	u8 vol;
+	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
+	int subdev = kcontrol->id.subdevice;
+	pcm_vol_t *p = &vortex->pcm_mixer[subdev];
+	int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
+	for (i = 0; i < max_chn; i++) {
+		if (p->vol[i] != ucontrol->value.integer.value[i]) {
+			p->vol[i] = ucontrol->value.integer.value[i];
+			if (p->active) {
+				vol = p->vol[i];
+				switch(vortex->dma_adb[p->dma].nr_ch) {
+				case 1:
+					mixin = p->mixin[0];
+					break;
+				case 2:
+				default:
+					mixin = p->mixin[(i < 2) ? i : (i - 2)];
+					break;
+				case 4:
+					mixin = p->mixin[i];
+					break;
+				};
+				vortex_mix_setinputvolumebyte(vortex,
+						vortex->mixplayb[i], mixin, vol);
+			}
+			changed=1;
+		}
+	}
+	return changed;
+}
+
+static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -4800, 600);
+
+static struct snd_kcontrol_new snd_vortex_pcm_vol __devinitdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+	.name = "PCM Playback Volume",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+		SNDRV_CTL_ELEM_ACCESS_INACTIVE,
+	.info = snd_vortex_pcm_vol_info,
+	.get = snd_vortex_pcm_vol_get,
+	.put = snd_vortex_pcm_vol_put,
+	.tlv = { .p = vortex_pcm_vol_db_scale },
+};
+
 /* create a pcm device */
 static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
 {
@@ -554,5 +652,19 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
 				return err;
 		}
 	}
+	if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) {
+		for (i= 0; i < NR_PCM; i++) {
+			chip->pcm_mixer[i].active = 0;
+			chip->pcm_mixer[i].dma = -1;
+			kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip);
+			if (!kctl)
+				return -ENOMEM;
+			chip->pcm_mixer[i].kctl = kctl;
+			kctl->id.device = 0;
+			kctl->id.subdevice = i;
+			if ((err = snd_ctl_add(chip->card, kctl)) < 0)
+				return err;
+		}
+	}
 	return 0;
 }
