Index: uspace/drv/audio/hdaudio/codec.c
===================================================================
--- uspace/drv/audio/hdaudio/codec.c	(revision c67195c10943f94e47093160e67d951a1e22aabf)
+++ uspace/drv/audio/hdaudio/codec.c	(revision 1e92bc3cc88d4455847afe91816a6ee1d5e5c7a0)
@@ -156,4 +156,76 @@
 }
 
+static int hda_set_out_amp_max(hda_codec_t *codec, uint8_t aw)
+{
+	uint32_t ampcaps;
+	uint32_t gmleft, gmright;
+	uint32_t offset;
+	int rc;
+
+	rc = hda_get_parameter(codec, aw,
+	    hda_out_amp_caps, &ampcaps);
+	if (rc != EOK)
+		goto error;
+
+	rc = hda_get_amp_gain_mute(codec, aw, 0x8000, &gmleft);
+	if (rc != EOK)
+		goto error;
+
+	rc = hda_get_amp_gain_mute(codec, aw, 0xc000, &gmright);
+	if (rc != EOK)
+		goto error;
+
+	ddf_msg(LVL_NOTE, "out amp caps 0x%x "
+	    "gain/mute: L:0x%x R:0x%x",
+	    ampcaps, gmleft, gmright);
+	offset = ampcaps & 0x7f;
+
+	rc = hda_set_amp_gain_mute(codec, aw, 0xb000 + offset);
+	if (rc != EOK)
+		goto error;
+
+	return EOK;
+error:
+	return rc;
+}
+
+static int hda_set_in_amp_max(hda_codec_t *codec, uint8_t aw)
+{
+	uint32_t ampcaps;
+	uint32_t gmleft, gmright;
+	uint32_t offset;
+	int i;
+	int rc;
+
+	rc = hda_get_parameter(codec, aw,
+	    hda_out_amp_caps, &ampcaps);
+	if (rc != EOK)
+		goto error;
+
+	ddf_msg(LVL_NOTE, "in amp caps 0x%x ", ampcaps);
+	offset = ampcaps & 0x7f;
+
+	for (i = 0; i < 15; i++) {
+		rc = hda_get_amp_gain_mute(codec, aw, 0x0000 + i, &gmleft);
+		if (rc != EOK)
+			goto error;
+
+		rc = hda_get_amp_gain_mute(codec, aw, 0x4000 + i, &gmright);
+		if (rc != EOK)
+			goto error;
+
+		ddf_msg(LVL_NOTE, "in:%d gain/mute: L:0x%x R:0x%x",
+		    i, gmleft, gmright);
+
+		rc = hda_set_amp_gain_mute(codec, aw, 0x7000 + (i << 8) + offset);
+		if (rc != EOK)
+			goto error;
+	}
+
+	return EOK;
+error:
+	return rc;
+}
+
 hda_codec_t *hda_codec_init(hda_t *hda, uint8_t address)
 {
@@ -218,31 +290,12 @@
 			} else if (awtype == awt_audio_output) {
 				codec->out_aw = aw;
+				codec->out_aw_list[codec->out_aw_num++] = aw;
 			}
 
-			if ((awcaps & BIT_V(uint32_t, awc_out_amp_present)) != 0) {
-				uint32_t ampcaps;
-				uint32_t gmleft, gmright;
-
-				rc = hda_get_parameter(codec, aw,
-				    hda_out_amp_caps, &ampcaps);
-				if (rc != EOK)
-					goto error;
-
-				rc = hda_get_amp_gain_mute(codec, aw, 0x8000, &gmleft);
-				if (rc != EOK)
-					goto error;
-
-				rc = hda_get_amp_gain_mute(codec, aw, 0xc000, &gmright);
-				if (rc != EOK)
-					goto error;
-
-				ddf_msg(LVL_NOTE, "out amp caps 0x%x "
-				    "gain/mute: L:0x%x R:0x%x",
-				    ampcaps, gmleft, gmright);
-
-				rc = hda_set_amp_gain_mute(codec, aw, 0xb04a);
-				if (rc != EOK)
-					goto error;
-			}
+			if ((awcaps & BIT_V(uint32_t, awc_out_amp_present)) != 0)
+				hda_set_out_amp_max(codec, aw);
+
+			if ((awcaps & BIT_V(uint32_t, awc_in_amp_present)) != 0)
+				hda_set_in_amp_max(codec, aw);
 		}
 	}
@@ -275,21 +328,27 @@
 {
 	int rc;
-
-	/* XXX Choose appropriate parameters */
-	uint32_t fmt;
-	/* 48 kHz, 16-bits, 1 channel */
-	fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l);
-
-	/* Configure converter */
-
-	ddf_msg(LVL_NOTE, "Configure converter format");
-	rc = hda_set_converter_fmt(codec, codec->out_aw, fmt);
-	if (rc != EOK)
-		goto error;
-
-	ddf_msg(LVL_NOTE, "Configure converter stream, channel");
-	rc = hda_set_converter_ctl(codec, codec->out_aw, sid, 0);
-	if (rc != EOK)
-		goto error;
+	int out_aw;
+	int i;
+
+	for (i = 0; i < codec->out_aw_num; i++) {
+		out_aw = codec->out_aw_list[i];
+
+		/* XXX Choose appropriate parameters */
+		uint32_t fmt;
+		/* 48 kHz, 16-bits, 1 channel */
+		fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l);
+
+		/* Configure converter */
+
+		ddf_msg(LVL_NOTE, "Configure converter format");
+		rc = hda_set_converter_fmt(codec, out_aw, fmt);
+		if (rc != EOK)
+			goto error;
+
+		ddf_msg(LVL_NOTE, "Configure converter stream, channel");
+		rc = hda_set_converter_ctl(codec, out_aw, sid, 0);
+		if (rc != EOK)
+			goto error;
+	}
 
 	return EOK;
Index: uspace/drv/audio/hdaudio/codec.h
===================================================================
--- uspace/drv/audio/hdaudio/codec.h	(revision c67195c10943f94e47093160e67d951a1e22aabf)
+++ uspace/drv/audio/hdaudio/codec.h	(revision 1e92bc3cc88d4455847afe91816a6ee1d5e5c7a0)
@@ -38,8 +38,13 @@
 #include "hdaudio.h"
 
+#define MAX_OUT_AW 256
+
 typedef struct hda_codec {
 	hda_t *hda;
 	uint8_t address;
 	uint8_t out_aw;
+	uint8_t out_aw_list[MAX_OUT_AW];
+	int out_aw_num;
+	int out_aw_sel;
 } hda_codec_t;
 
Index: uspace/drv/audio/hdaudio/hdactl.c
===================================================================
--- uspace/drv/audio/hdaudio/hdactl.c	(revision c67195c10943f94e47093160e67d951a1e22aabf)
+++ uspace/drv/audio/hdaudio/hdactl.c	(revision 1e92bc3cc88d4455847afe91816a6ee1d5e5c7a0)
@@ -55,4 +55,6 @@
 };
 
+static void hda_ctl_process_rirb(hda_ctl_t *);
+
 /** Perform set-reset handshake on a 16-bit register.
  *
@@ -407,18 +409,14 @@
 	int wcnt;
 
-	ddf_msg(LVL_NOTE, "hda_solrb_read()");
-	wcnt = 100;
-
-	ddf_msg(LVL_NOTE, "hda_solrb_read() - lock mutex");
+	ddf_msg(LVL_DEBUG, "hda_solrb_read()");
+
 	fibril_mutex_lock(&hda->ctl->solrb_lock);
 
 	while (count > 0) {
-		ddf_msg(LVL_NOTE, "hda_solrb_read() - while(1)");
 		while (count > 0 && hda->ctl->solrb_rp != hda->ctl->solrb_wp) {
-			ddf_msg(LVL_NOTE, "hda_solrb_read() - while(2)");
 			++hda->ctl->solrb_rp;
 			resp = hda->ctl->solrb[hda->ctl->solrb_rp];
 
-			ddf_msg(LVL_NOTE, "solrb RESPONSE resp=0x%x respex=0x%x",
+			ddf_msg(LVL_DEBUG2, "solrb RESPONSE resp=0x%x respex=0x%x",
 			    resp.resp, resp.respex);
 			if ((resp.respex & BIT_V(uint32_t, respex_unsol)) == 0) {
@@ -430,11 +428,8 @@
 
 		if (count > 0) {
-			ddf_msg(LVL_NOTE, "hda_solrb_read() - count > 0");
+			wcnt = 100;
 			while (wcnt > 0 && hda->ctl->solrb_wp == hda->ctl->solrb_rp) {
-				ddf_msg(LVL_NOTE, "hda_solrb_read() - while(3), wcnt=%d", wcnt);
 				fibril_mutex_unlock(&hda->ctl->solrb_lock);
-				ddf_msg(LVL_NOTE, "hda_solrb_read() - sleep");
 				async_usleep(10000);
-				ddf_msg(LVL_NOTE, "hda_solrb_read() - re-lock");
 				fibril_mutex_lock(&hda->ctl->solrb_lock);
 				--wcnt;
@@ -442,16 +437,12 @@
 
 			if (hda->ctl->solrb_wp == hda->ctl->solrb_rp) {
+				ddf_msg(LVL_NOTE, "hda_solrb_read() - last ditch effort process RIRB");
+				fibril_mutex_unlock(&hda->ctl->solrb_lock);
+				hda_ctl_process_rirb(hda->ctl);
+				fibril_mutex_lock(&hda->ctl->solrb_lock);
+			}
+
+			if (hda->ctl->solrb_wp == hda->ctl->solrb_rp) {
 				ddf_msg(LVL_NOTE, "hda_solrb_read() time out");
-				ddf_msg(LVL_NOTE, "corbwp=%d corbrp=%d",
-				    hda_reg16_read(&hda->regs->corbwp),
-				    hda_reg16_read(&hda->regs->corbrp));
-				ddf_msg(LVL_NOTE, "corbctl=0x%x, corbsts=0x%x",
-				    hda_reg8_read(&hda->regs->corbctl),
-				    hda_reg8_read(&hda->regs->corbsts));
-				ddf_msg(LVL_NOTE, "rirbwp=%d",
-				    hda_reg16_read(&hda->regs->rirbwp));
-				ddf_msg(LVL_NOTE, "rirbctl=0x%x, rirbsts=0x%x",
-				    hda_reg8_read(&hda->regs->rirbctl),
-				    hda_reg8_read(&hda->regs->rirbsts));
 				fibril_mutex_unlock(&hda->ctl->solrb_lock);
 				return ETIMEOUT;
@@ -461,5 +452,4 @@
 
 	fibril_mutex_unlock(&hda->ctl->solrb_lock);
-	ddf_msg(LVL_NOTE, "hda_solrb_read() success");
 	return EOK;
 }
@@ -613,5 +603,5 @@
 }
 
-void hda_ctl_interrupt(hda_ctl_t *ctl)
+static void hda_ctl_process_rirb(hda_ctl_t *ctl)
 {
 	hda_rirb_entry_t resp;
@@ -625,5 +615,5 @@
 		}
 
-		ddf_msg(LVL_NOTE, "writing to solrb");
+		ddf_msg(LVL_DEBUG2, "writing to solrb");
 		fibril_mutex_lock(&ctl->solrb_lock);
 		ctl->solrb_wp = (ctl->solrb_wp + 1) % softrb_entries;
@@ -634,4 +624,9 @@
 }
 
+void hda_ctl_interrupt(hda_ctl_t *ctl)
+{
+	hda_ctl_process_rirb(ctl);
+}
+
 /** @}
  */
Index: uspace/drv/audio/hdaudio/hdaudio.c
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.c	(revision c67195c10943f94e47093160e67d951a1e22aabf)
+++ uspace/drv/audio/hdaudio/hdaudio.c	(revision 1e92bc3cc88d4455847afe91816a6ee1d5e5c7a0)
@@ -37,4 +37,5 @@
 #include <ddi.h>
 #include <device/hw_res_parsed.h>
+#include <irc.h>
 #include <stdio.h>
 #include <errno.h>
@@ -255,4 +256,10 @@
 	ddf_msg(LVL_NOTE, "range0.base=%x", hdaudio_irq_pio_ranges[0].base);
 
+	rc = irc_enable_interrupt(res.irqs.irqs[0]);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed enabling interrupt. (%d)", rc);
+		goto error;
+	}
+
 	rc = register_interrupt_handler(dev, res.irqs.irqs[0],
 	    hdaudio_interrupt, &irq_code);
Index: uspace/drv/audio/hdaudio/pcm_iface.c
===================================================================
--- uspace/drv/audio/hdaudio/pcm_iface.c	(revision c67195c10943f94e47093160e67d951a1e22aabf)
+++ uspace/drv/audio/hdaudio/pcm_iface.c	(revision 1e92bc3cc88d4455847afe91816a6ee1d5e5c7a0)
@@ -256,5 +256,5 @@
 
 	if (hda->ev_sess == NULL) {
-		ddf_log_warning("No one listening for event %u", event);
+		if (0) ddf_log_warning("No one listening for event %u", event);
 		return;
 	}
