Index: uspace/drv/audio/hdaudio/codec.c
===================================================================
--- uspace/drv/audio/hdaudio/codec.c	(revision 99cb9bfebb014147307d479faf5f7fc243842ddc)
+++ uspace/drv/audio/hdaudio/codec.c	(revision 159c722df07b0966d4101cc1bf3f08ae20b3e6ae)
@@ -279,5 +279,5 @@
 	uint32_t fmt;
 	/* 48 kHz, 16-bits, 1 channel */
-	fmt = fmt_bits_16 << fmt_bits_l;
+	fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l);
 
 	/* Configure converter */
Index: uspace/drv/audio/hdaudio/hdaudio.c
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.c	(revision 99cb9bfebb014147307d479faf5f7fc243842ddc)
+++ uspace/drv/audio/hdaudio/hdaudio.c	(revision 159c722df07b0966d4101cc1bf3f08ae20b3e6ae)
@@ -354,4 +354,14 @@
 	if (0) ddf_msg(LVL_NOTE, "## interrupt ##");
 //	ddf_msg(LVL_NOTE, "interrupt arg4=0x%x", (int)IPC_GET_ARG4(*icall));
+	if (IPC_GET_ARG3(*icall) != 0) {
+		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+/*		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);*/
+	}
 	hda_ctl_interrupt(hda->ctl);
 }
Index: uspace/drv/audio/hdaudio/hdaudio.h
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.h	(revision 99cb9bfebb014147307d479faf5f7fc243842ddc)
+++ uspace/drv/audio/hdaudio/hdaudio.h	(revision 159c722df07b0966d4101cc1bf3f08ae20b3e6ae)
@@ -45,4 +45,5 @@
 typedef struct hda {
 	async_sess_t *parent_sess;
+	async_sess_t *ev_sess;
 	ddf_fun_t *fun_pcm;
 	uint64_t rwbase;
Index: uspace/drv/audio/hdaudio/pcm_iface.c
===================================================================
--- uspace/drv/audio/hdaudio/pcm_iface.c	(revision 99cb9bfebb014147307d479faf5f7fc243842ddc)
+++ uspace/drv/audio/hdaudio/pcm_iface.c	(revision 159c722df07b0966d4101cc1bf3f08ae20b3e6ae)
@@ -43,4 +43,5 @@
 #include "hdactl.h"
 #include "hdaudio.h"
+#include "pcm_iface.h"
 #include "spec/fmt.h"
 #include "stream.h"
@@ -155,5 +156,5 @@
 	uint32_t fmt;
 	/* 48 kHz, 16-bits, 1 channel */
-	fmt = fmt_bits_16 << fmt_bits_l;
+	fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l);
 
 	ddf_msg(LVL_NOTE, "hda_get_buffer() - create stream");
@@ -165,5 +166,5 @@
 	/* XXX This is only one buffer */
 	*buffer = hda->pcm_stream->buf[0];
-	*size = hda->pcm_stream->bufsize;
+	*size = hda->pcm_stream->bufsize * hda->pcm_stream->nbuffers;
 
 	ddf_msg(LVL_NOTE, "hda_get_buffer() retturing EOK, buffer=%p, size=%zu",
@@ -180,12 +181,17 @@
 static int hda_set_event_session(ddf_fun_t *fun, async_sess_t *sess)
 {
+	hda_t *hda = fun_to_hda(fun);
+
 	ddf_msg(LVL_NOTE, "hda_set_event_session()");
-	return ENOTSUP;
+	hda->ev_sess = sess;
+	return EOK;
 }
 
 static async_sess_t *hda_get_event_session(ddf_fun_t *fun)
 {
+	hda_t *hda = fun_to_hda(fun);
+
 	ddf_msg(LVL_NOTE, "hda_get_event_session()");
-	return NULL;
+	return hda->ev_sess;
 }
 
@@ -215,4 +221,5 @@
 		return rc;
 
+	async_usleep(1000*1000);
 	hda_stream_start(hda->pcm_stream);
 	return EOK;
@@ -238,4 +245,18 @@
 }
 
+void hda_pcm_event(hda_t *hda, pcm_event_t event)
+{
+	async_exch_t *exchange;
+
+	if (hda->ev_sess == NULL) {
+		ddf_log_warning("No one listening for event %u", event);
+		return;
+	}
+
+	exchange = async_exchange_begin(hda->ev_sess);
+	async_msg_1(exchange, event, 0);
+	async_exchange_end(exchange);
+}
+
 /** @}
  */
Index: uspace/drv/audio/hdaudio/pcm_iface.h
===================================================================
--- uspace/drv/audio/hdaudio/pcm_iface.h	(revision 99cb9bfebb014147307d479faf5f7fc243842ddc)
+++ uspace/drv/audio/hdaudio/pcm_iface.h	(revision 159c722df07b0966d4101cc1bf3f08ae20b3e6ae)
@@ -38,5 +38,8 @@
 #include <audio_pcm_iface.h>
 
+#include "hdaudio.h"
+
 extern audio_pcm_iface_t hda_pcm_iface;
+extern void hda_pcm_event(hda_t *, pcm_event_t);
 
 #endif
Index: uspace/drv/audio/hdaudio/stream.c
===================================================================
--- uspace/drv/audio/hdaudio/stream.c	(revision 99cb9bfebb014147307d479faf5f7fc243842ddc)
+++ uspace/drv/audio/hdaudio/stream.c	(revision 159c722df07b0966d4101cc1bf3f08ae20b3e6ae)
@@ -54,8 +54,8 @@
 	uintptr_t buffer_phys;
 	size_t i;
-	size_t j, k;
+//	size_t j, k;
 	int rc;
 
-	stream->nbuffers = 2;
+	stream->nbuffers = 4;
 	stream->bufsize = 16384;
 
@@ -84,5 +84,5 @@
 
 	/* Allocate buffers */
-
+/*
 	for (i = 0; i < stream->nbuffers; i++) {
 		buffer = AS_AREA_ANY;
@@ -108,4 +108,33 @@
 		}
 	}
+*/
+//	async_usleep(1000*1000);
+	/* audio_pcm_iface requires a single contiguous buffer */
+	buffer = AS_AREA_ANY;
+	rc = dmamem_map_anonymous(stream->bufsize * stream->nbuffers,
+	    stream->hda->ctl->ok64bit ? 0 : DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE,
+	    0, &buffer_phys, &buffer);
+	if (rc != EOK) {
+		ddf_msg(LVL_NOTE, "dmamem_map_anon -> %d", rc);
+		goto error;
+	}
+
+	for (i = 0; i < stream->nbuffers; i++) {
+		stream->buf[i] = buffer + i * stream->bufsize;
+		stream->buf_phys[i] = buffer_phys + i * stream->bufsize;
+
+		ddf_msg(LVL_NOTE, "Stream buf phys=0x%llx virt=%p",
+		    (long long unsigned)(uintptr_t)stream->buf[i],
+		    (void *)stream->buf_phys[i]);
+/*		k = 0;
+		for (j = 0; j < stream->bufsize / 2; j++) {
+			int16_t *bp = stream->buf[i];
+			bp[j] = (k > 128) ? -10000 : 10000;
+			++k;
+			if (k >= 256)
+				k = 0;
+		}
+*/
+	}
 
 	/* Fill in BDL */
