Index: uspace/drv/audio/hdaudio/hdactl.c
===================================================================
--- uspace/drv/audio/hdaudio/hdactl.c	(revision b22906299958259e374417ad80e4bf0a4e3063ec)
+++ uspace/drv/audio/hdaudio/hdactl.c	(revision 7978d1e7dd2d345124f5057ea7f3979ddcb6828a)
@@ -33,14 +33,206 @@
  */
 
+#include <as.h>
+#include <async.h>
+#include <bitops.h>
 #include <ddf/log.h>
+#include <ddi.h>
+#include <errno.h>
+#include <macros.h>
 #include <stdint.h>
 
 #include "hdactl.h"
 #include "regif.h"
-#include "hdaudio_regs.h"
+#include "spec/regs.h"
+
+enum {
+	ctrl_init_wait_max = 10,
+	codec_enum_wait_us = 512
+};
+
+/** Select an appropriate CORB/RIRB size.
+ *
+ * We always use the largest available size. In @a sizecap each of bits
+ * 0, 1, 2 determine whether one of the supported size (0 == 2 enries,
+ * 1 == 16 entries, 2 == 256 entries) is supported. @a *selsz is set to
+ * one of 0, 1, 2 on success.
+ *
+ * @param sizecap	CORB/RIRB Size Capability
+ * @param selsz		Place to store CORB/RIRB Size
+ * @return		EOK on success, EINVAL if sizecap has no valid bits set
+ *
+ */
+static int hda_rb_size_select(uint8_t sizecap, uint8_t *selsz)
+{
+	int i;
+
+	for (i = 2; i >= 0; --i) {
+		if ((sizecap & BIT_V(uint8_t, i)) != 0) {
+			*selsz = i;
+			return EOK;
+		}
+	}
+
+	return EINVAL;
+}
+
+static size_t hda_rb_entries(uint8_t selsz)
+{
+	switch (selsz) {
+	case 0:
+		return 2;
+	case 1:
+		return 16;
+	case 2:
+		return 256;
+	default:
+		assert(false);
+		return 0;
+	}
+}
+
+/** Initialize the CORB */
+static int hda_corb_init(hda_t *hda)
+{
+	uint8_t ctl;
+	uint8_t corbsz;
+	uint8_t sizecap;
+	uint8_t selsz;
+	bool ok64bit;
+	int rc;
+
+	ddf_msg(LVL_NOTE, "hda_corb_init()");
+
+	/* Stop CORB if not stopped. */
+	ctl = hda_reg8_read(&hda->regs->corbctl);
+	if ((ctl & BIT_V(uint8_t, corbctl_run)) != 0) {
+		ddf_msg(LVL_NOTE, "CORB is enabled, disabling first.");
+		hda_reg8_write(&hda->regs->corbctl, ctl & ~BIT_V(uint8_t,
+		    corbctl_run));
+	}
+
+	/* Determine CORB size and allocate CORB buffer */
+	corbsz = hda_reg8_read(&hda->regs->corbsize);
+	sizecap = BIT_RANGE_EXTRACT(uint8_t, corbsize_cap_h,
+	    corbsize_cap_l, corbsz);
+	rc = hda_rb_size_select(sizecap, &selsz);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Invalid CORB Size Capability");
+		goto error;
+	}
+	corbsz = corbsz & ~BIT_RANGE(uint8_t, corbsize_size_h, corbsize_size_l);
+	corbsz = corbsz | selsz;
+
+	ddf_msg(LVL_NOTE, "Setting CORB Size register to 0x%x", corbsz);
+	hda_reg8_write(&hda->regs->corbsize, corbsz);
+	hda->ctl->corb_entries = hda_rb_entries(selsz);
+
+	ddf_msg(LVL_NOTE, "Read GCAP");
+	uint16_t gcap = hda_reg16_read(&hda->regs->gcap);
+	ok64bit = (gcap & BIT_V(uint8_t, gcap_64ok)) != 0;
+	ddf_msg(LVL_NOTE, "GCAP: 0x%x (64OK=%d)", gcap, ok64bit);
+
+	/*
+	 * CORB must be aligned to 128 bytes. If 64OK is not set,
+	 * it must be within the 32-bit address space.
+	 */
+	hda->ctl->corb_virt = AS_AREA_ANY;
+	rc = dmamem_map_anonymous(hda->ctl->corb_entries * sizeof(uint32_t),
+	    ok64bit ? 0 : DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE, 0,
+	    &hda->ctl->corb_phys, &hda->ctl->corb_virt);
+
+	ddf_msg(LVL_NOTE, "Set CORB base registers");
+
+	/* Update CORB base registers */
+	hda_reg32_write(&hda->regs->corblbase, LOWER32(hda->ctl->corb_phys));
+	hda_reg32_write(&hda->regs->corbubase, UPPER32(hda->ctl->corb_phys));
+
+	ddf_msg(LVL_NOTE, "Rset CORB Read/Write pointers");
+
+	/* Reset CORB Read Pointer */
+	hda_reg16_write(&hda->regs->corbrp, BIT_V(uint16_t, corbrp_rst));
+
+	/* Reset CORB Write Poitner */
+	hda_reg16_write(&hda->regs->corbwp, 0);
+
+	ddf_msg(LVL_NOTE, "CORB initialized");
+	return EOK;
+error:
+	return EIO;
+}
+
+/** Initialize the RIRB */
+static int hda_rirb_init(hda_t *hda)
+{
+	uint8_t ctl;
+	uint8_t rirbsz;
+	uint8_t sizecap;
+	uint8_t selsz;
+	bool ok64bit;
+	int rc;
+
+	ddf_msg(LVL_NOTE, "hda_rirb_init()");
+
+	/* Stop RIRB if not stopped. */
+	ctl = hda_reg8_read(&hda->regs->rirbctl);
+	if ((ctl & BIT_V(uint8_t, rirbctl_run)) != 0) {
+		ddf_msg(LVL_NOTE, "RIRB is enabled, disabling first.");
+		hda_reg8_write(&hda->regs->corbctl, ctl & ~BIT_V(uint8_t,
+		    rirbctl_run));
+	}
+
+	/* Determine RIRB size and allocate RIRB buffer */
+	rirbsz = hda_reg8_read(&hda->regs->rirbsize);
+	sizecap = BIT_RANGE_EXTRACT(uint8_t, rirbsize_cap_h,
+	    rirbsize_cap_l, rirbsz);
+	rc = hda_rb_size_select(sizecap, &selsz);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Invalid RIRB Size Capability");
+		goto error;
+	}
+	rirbsz = rirbsz & ~BIT_RANGE(uint8_t, rirbsize_size_h, rirbsize_size_l);
+	rirbsz = rirbsz | selsz;
+
+	ddf_msg(LVL_NOTE, "Setting RIRB Size register to 0x%x", rirbsz);
+	hda_reg8_write(&hda->regs->rirbsize, rirbsz);
+	hda->ctl->rirb_entries = hda_rb_entries(selsz);
+
+	ddf_msg(LVL_NOTE, "Read GCAP");
+	uint16_t gcap = hda_reg16_read(&hda->regs->gcap);
+	ok64bit = (gcap & BIT_V(uint8_t, gcap_64ok)) != 0;
+	ddf_msg(LVL_NOTE, "GCAP: 0x%x (64OK=%d)", gcap, ok64bit);
+
+	/*
+	 * RIRB must be aligned to 128 bytes. If 64OK is not set,
+	 * it must be within the 32-bit address space.
+	 */
+	hda->ctl->rirb_virt = AS_AREA_ANY;
+	rc = dmamem_map_anonymous(hda->ctl->rirb_entries * sizeof(uint64_t),
+	    ok64bit ? 0 : DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE, 0,
+	    &hda->ctl->rirb_phys, &hda->ctl->rirb_virt);
+
+	ddf_msg(LVL_NOTE, "Set RIRB base registers");
+
+	/* Update RIRB base registers */
+	hda_reg32_write(&hda->regs->rirblbase, LOWER32(hda->ctl->rirb_phys));
+	hda_reg32_write(&hda->regs->rirbubase, UPPER32(hda->ctl->rirb_phys));
+
+	ddf_msg(LVL_NOTE, "Rset RIRB Write pointer");
+
+	/* Reset RIRB Write Pointer */
+	hda_reg16_write(&hda->regs->rirbwp, BIT_V(uint16_t, rirbwp_rst));
+
+	ddf_msg(LVL_NOTE, "RIRB initialized");
+	return EOK;
+error:
+	return EIO;
+}
 
 hda_ctl_t *hda_ctl_init(hda_t *hda)
 {
 	hda_ctl_t *ctl;
+	uint32_t gctl;
+	int cnt;
+	int rc;
 
 	ctl = calloc(1, sizeof(hda_ctl_t));
@@ -48,4 +240,6 @@
 		return NULL;
 
+	hda->ctl = ctl;
+
 	uint8_t vmaj = hda_reg8_read(&hda->regs->vmaj);
 	uint8_t vmin = hda_reg8_read(&hda->regs->vmin);
@@ -58,7 +252,55 @@
 	}
 
+	ddf_msg(LVL_NOTE, "reg 0x%zx STATESTS = 0x%x",
+	    (void *)&hda->regs->statests - (void *)hda->regs, hda_reg16_read(&hda->regs->statests));
+
+	gctl = hda_reg32_read(&hda->regs->gctl);
+	if ((gctl & BIT_V(uint32_t, gctl_crst)) != 0) {
+		ddf_msg(LVL_NOTE, "Controller not in reset. Resetting.");
+		hda_reg32_write(&hda->regs->gctl, gctl & ~BIT_V(uint32_t, gctl_crst));
+	}
+
+	ddf_msg(LVL_NOTE, "Taking controller out of reset.");
+	hda_reg32_write(&hda->regs->gctl, gctl | BIT_V(uint32_t, gctl_crst));
+
+	/* Wait for CRST to read as 1 */
+	cnt = ctrl_init_wait_max;
+	while (cnt > 0) {
+		gctl = hda_reg32_read(&hda->regs->gctl);
+		if ((gctl & BIT_V(uint32_t, gctl_crst)) != 0) {
+			ddf_msg(LVL_NOTE, "gctl=0x%x", gctl);
+			break;
+		}
+
+		ddf_msg(LVL_NOTE, "Waiting for controller to initialize.");
+		async_usleep(100*1000);
+		--cnt;
+	}
+
+	if (cnt == 0) {
+		ddf_msg(LVL_ERROR, "Timed out waiting for controller to come up.");
+		goto error;
+	}
+
+	ddf_msg(LVL_NOTE, "Controller is out of reset.");
+
+	/* Give codecs enough time to enumerate themselves */
+	async_usleep(codec_enum_wait_us);
+
+	ddf_msg(LVL_NOTE, "STATESTS = 0x%x",
+	    hda_reg16_read(&hda->regs->statests));
+
+	rc = hda_corb_init(hda);
+	if (rc != EOK)
+		goto error;
+
+	rc = hda_rirb_init(hda);
+	if (rc != EOK)
+		goto error;
+
 	return ctl;
 error:
 	free(ctl);
+	hda->ctl = NULL;
 	return NULL;
 }
Index: uspace/drv/audio/hdaudio/hdactl.h
===================================================================
--- uspace/drv/audio/hdaudio/hdactl.h	(revision b22906299958259e374417ad80e4bf0a4e3063ec)
+++ uspace/drv/audio/hdaudio/hdactl.h	(revision 7978d1e7dd2d345124f5057ea7f3979ddcb6828a)
@@ -39,5 +39,11 @@
 
 typedef struct hda_ctl {
-	
+	uintptr_t corb_phys;
+	void *corb_virt;
+	size_t corb_entries;
+
+	uintptr_t rirb_phys;
+	void *rirb_virt;
+	size_t rirb_entries;
 } hda_ctl_t;
 
Index: uspace/drv/audio/hdaudio/hdaudio.c
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.c	(revision b22906299958259e374417ad80e4bf0a4e3063ec)
+++ uspace/drv/audio/hdaudio/hdaudio.c	(revision 7978d1e7dd2d345124f5057ea7f3979ddcb6828a)
@@ -44,5 +44,5 @@
 #include "hdactl.h"
 #include "hdaudio.h"
-#include "hdaudio_regs.h"
+#include "spec/regs.h"
 
 #define NAME "hdaudio"
@@ -71,10 +71,8 @@
 	ddf_fun_t *fun_a;
 	hda_t *hda = NULL;
-	const char *dev_name;
 	hw_res_list_parsed_t res;
 	void *regs;
 	int rc;
 
-	dev_name = ddf_dev_get_name(dev);
 	ddf_msg(LVL_NOTE, "hda_dev_add()");
 
@@ -127,6 +125,5 @@
 	hda->regs = (hda_regs_t *)regs;
 
-	hda->ctl = hda_ctl_init(hda);
-	if (hda->ctl == NULL) {
+	if (hda_ctl_init(hda) == NULL) {
 		rc = EIO;
 		goto error;
@@ -151,6 +148,4 @@
 
 	ddf_fun_add_to_category(fun_a, "virtual");
-
-	ddf_msg(LVL_DEBUG, "Device `%s' accepted.", dev_name);
 	return EOK;
 error:
Index: uspace/drv/audio/hdaudio/hdaudio.h
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.h	(revision b22906299958259e374417ad80e4bf0a4e3063ec)
+++ uspace/drv/audio/hdaudio/hdaudio.h	(revision 7978d1e7dd2d345124f5057ea7f3979ddcb6828a)
@@ -30,5 +30,5 @@
  * @{
  */
-/** @file High Definition Audio controller
+/** @file High Definition Audio driver
  */
 
@@ -40,7 +40,7 @@
 #include <stdint.h>
 
-#include "hdaudio_regs.h"
+#include "spec/regs.h"
 
-/** High Definition Audio Controller */
+/** High Definition Audio driver instance */
 typedef struct {
 	async_sess_t *parent_sess;
Index: uspace/drv/audio/hdaudio/hdaudio.ma
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.ma	(revision b22906299958259e374417ad80e4bf0a4e3063ec)
+++ uspace/drv/audio/hdaudio/hdaudio.ma	(revision 7978d1e7dd2d345124f5057ea7f3979ddcb6828a)
@@ -1,1 +1,2 @@
+10 pci/ven=1002&dev=4383
 10 pci/ven=8086&dev=2668
Index: pace/drv/audio/hdaudio/hdaudio_regs.h
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio_regs.h	(revision b22906299958259e374417ad80e4bf0a4e3063ec)
+++ 	(revision )
@@ -1,162 +1,0 @@
-/*
- * Copyright (c) 2014 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup hdaudio
- * @{
- */
-/** @file High Definition Audio register interface
- */
-
-#ifndef HDAUDIO_REGS_H
-#define HDAUDIO_REGS_H
-
-#include <sys/types.h>
-
-/** Stream Descriptor registers */
-typedef struct {
-	/** Control */
-	uint16_t ctl;
-	/** Status */
-	uint8_t sts;
-	/** Link Position in Current Buffer */
-	uint32_t lpib;
-	/** Cyclic Buffer Length */
-	uint32_t cbl;
-	/** Last Valid Index */
-	uint16_t lvi;
-	/** Reserved */
-	uint8_t reserved1[2];
-	/** FIFO Size */
-	uint16_t fifod;
-	/** Format */
-	uint16_t fmt;
-	/** Reserved */
-	uint8_t reserved2[4];
-	/** Buffer Descriptor List Pointer - Lower */
-	uint32_t bdpl;
-	/** Buffer Descriptor List Pointer - Upper */ 
-	uint32_t bdpu;
-} hda_sdesc_regs_t;
-
-typedef struct {
-	/** Global Capabilities */
-	uint16_t gcap;
-	/** Minor Version */
-	uint8_t vmin;
-	/** Major Version */
-	uint8_t vmaj;
-	/** Output Payload Capability */
-	uint16_t outpay;
-	/** Input Payload Capability */
-	uint16_t inpay;
-	/** Global Control */
-	uint32_t gctl;
-	/** Wake Enable */
-	uint16_t wakeen;
-	/** State Change Status */
-	uint16_t statests;
-	/** Global Status */
-	uint16_t gsts;
-	/** Reserved */
-	uint8_t reserved1[6];
-	/** Output Stream Payload Capability */
-	uint16_t outstrmpay;
-	/** Input Stream Payload Capability */
-	uint16_t instrmpay;
-	/** Reserved */
-	uint8_t reserved2[4];
-	/** Interrupt Control */
-	uint32_t intctl;
-	/** Interrupt Status */
-	uint32_t intsts;
-	/** Reserved */
-	uint8_t reserved3[8];
-	/** Wall Clock Counter */
-	uint32_t walclk;
-	/** Reserved */
-	uint32_t reserved4[4];
-	/** CORB Lower Base Address */
-	uint32_t corblbase;
-	/** CORB Upper Base Address */
-	uint32_t corbubase;
-	/** CORB Write Pointer */
-	uint16_t corbwp;
-	/** CORB Read Pointer */
-	uint16_t corbrp;
-	/** CORB Control */
-	uint8_t corbctl;
-	/** CORB Status */
-	uint8_t corbsts;
-	/** CORB Size */
-	uint8_t corbsize;
-	/** Reserved */
-	uint8_t reserved5[1];
-	/** RIRB Lower Base Address */
-	uint32_t rirblbase;
-	/** RIRB Upper Base Address */
-	uint32_t rirbubase;
-	/** RIRB Write Pointer */
-	uint16_t rirbwp;
-	/** Response Interrupt Count */
-	uint16_t rintcnt;
-	/** RIRB Control */
-	uint8_t rirbctl;
-	/** RIRB Status */
-	uint8_t rirbsts;
-	/** RIRB Size */
-	uint8_t rirbsize;
-	/** Reserved */
-	uint8_t reserved6[1];
-	/** Immediate Command Output Interface */
-	uint32_t icoi;
-	/** Immediate Command Input Interface */
-	uint32_t icii;
-	/** Immediate Command Status */
-	uint32_t icis;
-	/** Reserved */
-	uint8_t reserved7[6];
-	/** DMA Position Buffer Lower Base */
-	uint32_t dpiblbase;
-	/** DMA Position Buffer Upper Base */
-	uint32_t dpibubase;
-	/** Reserved */
-	uint8_t reserved8[8];
-	/** Stream descriptor registers */
-	hda_sdesc_regs_t sdesc[64];
-	/** Fill up to 0x2030 */
-	uint8_t reserved9[6064];
-	/** Wall Clock Counter Alias */
-	uint32_t walclka;
-	/** Stream Descriptor Link Position in Current Buffer */
-	uint32_t sdlpiba[64];
-} hda_regs_t;
-
-#endif
-
-/** @}
- */
Index: uspace/drv/audio/hdaudio/spec/codec.h
===================================================================
--- uspace/drv/audio/hdaudio/spec/codec.h	(revision 7978d1e7dd2d345124f5057ea7f3979ddcb6828a)
+++ uspace/drv/audio/hdaudio/spec/codec.h	(revision 7978d1e7dd2d345124f5057ea7f3979ddcb6828a)
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup hdaudio
+ * @{
+ */
+/** @file High Definition Audio codec interface
+ */
+
+#ifndef SPEC_CODEC_H
+#define SPEC_CODEC_H
+
+typedef enum {
+	/** Get Parameter */
+	hda_get_param = 0xf00,
+	/** Connection Select Control / Get */
+	hda_conn_sel_get = 0xf01,
+	/** Connection Select Control / Set */
+	hda_conn_sel_set = 0x701,
+	/** Get Connection List Entry */
+	hda_clist_entry_get = 0xf02,
+	/** Processing State / Get */
+	hda_proc_state_get = 0xf03,
+	/** Processing State / Set */
+	hda_proc_state_set = 0x703,
+	/** Coefficient Index / Get */
+	hda_coef_index_get = 0xd,
+	/** Coefficient Index / Set */
+	hda_coef_index_set = 0x5,
+	/** Processing Coefficient / Get */
+	hda_proc_coef_get = 0xc,
+	/** Processing Coefficient / Set */
+	hda_proc_coef_set = 0x4,
+	/** Amplifier Gain/Mute / Get */
+	hda_amp_gain_mute_get = 0xb,
+	/** Amplifier Gain/Mute / Set */
+	hda_amp_gain_mute_set = 0x3,
+	/** Converter Format / Get */
+	hda_converter_fmt_get = 0xa,
+	/** Converter Format / Set */
+	hda_converter_fmt_set = 0x2,
+	/** S/PDIF Converter Control / Get */
+	hda_spdif_ctl_get = 0xf0d,
+	/** S/PDIF Converter Control / Set 1 */
+	hda_spdif_ctl_set1 = 0x70d,
+	/** S/PDIF Converter Control / Set 2 */
+	hda_spdif_ctl_set1 = 0x70e,
+	/** S/PDIF Converter Control / Set 3 */
+	hda_spdif_ctl_set1 = 0x73e,
+	/** S/PDIF Converter Control / Set 4 */
+	hda_spdif_ctl_set1 = 0x73f,
+	/** Power State / Get */
+	hda_power_state_get = 0xf05,
+	/** Power State / Set */
+	hda_power_state_set = 0x705,
+	/** Converter Control / Get */
+	hda_converter_ctl_get = 0xf06,
+	/** Converter Control / Set */
+	hda_converter_ctl_set = 0x706,
+	/** SDI Select / Get */
+	hda_sdi_select_get = 0xf04,
+	/** SDI Select / Set */
+	hda_sdi_select_set = 0x704,
+	/** Enable VRef / Get */
+	hda_enable_vref_get = 0xf07,
+	/** Enable VRef / Set */
+	hda_enable_vref_set = 0x707,
+	/** Connection Select Control / Get */
+	hda_conn_sel_get = 0xf08,
+	/** Connection Select Control / Set */
+	hda_conn_sel_set = 0x708
+} hda_verb_t;
+
+typedef enum {
+	/** Vendor ID */
+	hda_vendor_id = 0x00,
+	/** Revision ID */
+	hda_revision_id = 0x02,
+	/** Subordinate Node Count */
+	hda_sub_nc = 0x04,
+	/** Function Group Type */
+	hba_fgrp_type = 0x05,
+	/** Audio Function Group Capabilities */
+	hda_afg_caps = 0x08,
+	/** Audio Widget Capabilities */
+	hda_aw_caps = 0x09,
+	/** Supported PCM Size, Rates */
+	hda_supp_rates = 0x0a,
+	/** Supported Stream Formats */
+	hda_supp_formats = 0x0b,
+	/** Pin Capabilities */
+	hda_pin_caps = 0x0c,
+	/** Input Amplifier Capabilities */
+	hda_in_amp_caps = 0x0d,
+	/** Output Amplifier Capabilities */
+	hda_out_amp_caps = 0x12,
+	/** Connection List Length */
+	hda_clist_len = 0xe,
+	/** Supported Power States */
+	hda_supp_pwr_states = 0x0f,
+	/** Processing Capabilities */
+	hda_proc_caps = 0x10,
+	/** GP I/O Count */
+	hda_gpio_cnt = 0x11,
+	/** Volume Knob Capabilities */
+	hda_volk_nob_caps = 0x13
+} hda_param_id_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/audio/hdaudio/spec/regs.h
===================================================================
--- uspace/drv/audio/hdaudio/spec/regs.h	(revision 7978d1e7dd2d345124f5057ea7f3979ddcb6828a)
+++ uspace/drv/audio/hdaudio/spec/regs.h	(revision 7978d1e7dd2d345124f5057ea7f3979ddcb6828a)
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2014 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup hdaudio
+ * @{
+ */
+/** @file High Definition Audio register interface
+ */
+
+#ifndef SPEC_REGS_H
+#define SPEC_REGS_H
+
+#include <sys/types.h>
+
+/** Stream Descriptor registers */
+typedef struct {
+	/** Control */
+	uint16_t ctl;
+	/** Status */
+	uint8_t sts;
+	/** Link Position in Current Buffer */
+	uint32_t lpib;
+	/** Cyclic Buffer Length */
+	uint32_t cbl;
+	/** Last Valid Index */
+	uint16_t lvi;
+	/** Reserved */
+	uint8_t reserved1[2];
+	/** FIFO Size */
+	uint16_t fifod;
+	/** Format */
+	uint16_t fmt;
+	/** Reserved */
+	uint8_t reserved2[4];
+	/** Buffer Descriptor List Pointer - Lower */
+	uint32_t bdpl;
+	/** Buffer Descriptor List Pointer - Upper */ 
+	uint32_t bdpu;
+} hda_sdesc_regs_t;
+
+typedef struct {
+	/** Global Capabilities */
+	uint16_t gcap;
+	/** Minor Version */
+	uint8_t vmin;
+	/** Major Version */
+	uint8_t vmaj;
+	/** Output Payload Capability */
+	uint16_t outpay;
+	/** Input Payload Capability */
+	uint16_t inpay;
+	/** Global Control */
+	uint32_t gctl;
+	/** Wake Enable */
+	uint16_t wakeen;
+	/** State Change Status */
+	uint16_t statests;
+	/** Global Status */
+	uint16_t gsts;
+	/** Reserved */
+	uint8_t reserved1[6];
+	/** Output Stream Payload Capability */
+	uint16_t outstrmpay;
+	/** Input Stream Payload Capability */
+	uint16_t instrmpay;
+	/** Reserved */
+	uint8_t reserved2[4];
+	/** Interrupt Control */
+	uint32_t intctl;
+	/** Interrupt Status */
+	uint32_t intsts;
+	/** Reserved */
+	uint8_t reserved3[8];
+	/** Wall Clock Counter */
+	uint32_t walclk;
+	/** Reserved */
+	uint8_t reserved4[4];
+	/** Stream Synchronization */
+	uint32_t ssync;
+	/** Reserved */
+	uint8_t reserved5[4];
+	/** CORB Lower Base Address */
+	uint32_t corblbase;
+	/** CORB Upper Base Address */
+	uint32_t corbubase;
+	/** CORB Write Pointer */
+	uint16_t corbwp;
+	/** CORB Read Pointer */
+	uint16_t corbrp;
+	/** CORB Control */
+	uint8_t corbctl;
+	/** CORB Status */
+	uint8_t corbsts;
+	/** CORB Size */
+	uint8_t corbsize;
+	/** Reserved */
+	uint8_t reserved6[1];
+	/** RIRB Lower Base Address */
+	uint32_t rirblbase;
+	/** RIRB Upper Base Address */
+	uint32_t rirbubase;
+	/** RIRB Write Pointer */
+	uint16_t rirbwp;
+	/** Response Interrupt Count */
+	uint16_t rintcnt;
+	/** RIRB Control */
+	uint8_t rirbctl;
+	/** RIRB Status */
+	uint8_t rirbsts;
+	/** RIRB Size */
+	uint8_t rirbsize;
+	/** Reserved */
+	uint8_t reserved7[1];
+	/** Immediate Command Output Interface */
+	uint32_t icoi;
+	/** Immediate Command Input Interface */
+	uint32_t icii;
+	/** Immediate Command Status */
+	uint32_t icis;
+	/** Reserved */
+	uint8_t reserved8[6];
+	/** DMA Position Buffer Lower Base */
+	uint32_t dpiblbase;
+	/** DMA Position Buffer Upper Base */
+	uint32_t dpibubase;
+	/** Reserved */
+	uint8_t reserved9[8];
+	/** Stream descriptor registers */
+	hda_sdesc_regs_t sdesc[64];
+	/** Fill up to 0x2030 */
+	uint8_t reserved10[6064];
+	/** Wall Clock Counter Alias */
+	uint32_t walclka;
+	/** Stream Descriptor Link Position in Current Buffer */
+	uint32_t sdlpiba[64];
+} hda_regs_t;
+
+typedef enum {
+	/** Number of Output Streams Supported (H) */
+	gcap_oss_h = 15,
+	/** Number of Output Streams Supported (L) */
+	gcap_oss_l = 12,
+	/** Number of Input Streams Supported (H) */
+	gcap_iss_h = 11,
+	/** Number of Input Streams Supported (L) */
+	gcap_iss_l = 8,
+	/** Number of Bidirectional Streams Supported (H) */
+	gcap_bss_h = 7,
+	/** Number of Bidirectional Streams Supported (L) */
+	gcap_bss_l = 3,
+	/** Number of Serial Data Out Signals (H) */
+	gcap_nsdo_h = 2,
+	/** Number of Serial Data Out Signals (H) */
+	gcap_nsdo_l = 1,
+	/** 64 Bit Address Supported */
+	gcap_64ok = 0
+} hda_gcap_bits_t;
+
+typedef enum {
+	/** Accept Unsolicited Response Enable */
+	gctl_unsol = 8,
+	/** Flush Control */
+	gctl_fcntrl = 1,
+	/** Controller Reset */
+	gctl_crst = 0
+} hda_gctl_bits_t;
+
+typedef enum {
+	/** CORB Read Pointer Reset */
+	corbrp_rst = 15,
+	/** CORB Read Pointer (H) */
+	corbrp_rp_h = 7,
+	/** CORB Read Pointer (L) */
+	corbrp_rp_l = 0
+} hda_corbrp_bits_t;
+
+typedef enum {
+	/** Enable CORB DMA Engine */
+	corbctl_run = 1,
+	/** CORB Memory Error Interrupt Enable */
+	corbctl_meie = 0
+} hda_corbctl_bits_t;
+
+typedef enum {
+	/** CORB Size Capability (H) */
+	corbsize_cap_h = 7,
+	/** CORB Size Capability (L) */
+	corbsize_cap_l = 4,
+	/** CORB Size (H) */
+	corbsize_size_h = 1,
+	/** CORB Size (L) */
+	corbsize_size_l = 0
+} hda_corbsize_bits_t;
+
+typedef enum {
+	/** RIRB Write Pointer Reset */
+	rirbwp_rst = 15,
+	/** RIRB Write Pointer (H) */
+	rirbwp_wp_h = 7,
+	/** RIRB Write Pointer (L) */
+	rirbrp_wp_l = 0
+} hda_rirbwp_bits_t;
+
+typedef enum {
+	/** Response Overrun Interrupt Control */
+	rirbctl_oic = 2,
+	/** RIRB DMA Enable */
+	rirbctl_run = 1,
+	/** CORB Memory Error Interrupt Enable */
+	rirbctl_int = 0
+} hda_rirbctl_bits_t;
+
+typedef enum {
+	/** RIRB Size Capability (H) */
+	rirbsize_cap_h = 7,
+	/** RIRB Size Capability (L) */
+	rirbsize_cap_l = 4,
+	/** RIRB Size (H) */
+	rirbsize_size_h = 1,
+	/** RIRB Size (L) */
+	rirbsize_size_l = 0
+} hda_rirbsize_bits_t;
+
+#endif
+
+/** @}
+ */
