Index: uspace/drv/audio/sb16/dsp.h
===================================================================
--- uspace/drv/audio/sb16/dsp.h	(revision 7a0a0f535dbc66c8d1fddd518c3964097180b4db)
+++ uspace/drv/audio/sb16/dsp.h	(revision 0687e1bc5c63116cad13f0ff8a18b9a655875a0d)
@@ -35,4 +35,6 @@
 #ifndef DRV_AUDIO_SB16_DSP_H
 #define DRV_AUDIO_SB16_DSP_H
+
+#include <libarch/ddi.h>
 
 #include "registers.h"
Index: uspace/drv/audio/sb16/mixer.c
===================================================================
--- uspace/drv/audio/sb16/mixer.c	(revision 7a0a0f535dbc66c8d1fddd518c3964097180b4db)
+++ uspace/drv/audio/sb16/mixer.c	(revision 0687e1bc5c63116cad13f0ff8a18b9a655875a0d)
@@ -27,7 +27,65 @@
  */
 
+#include <bool.h>
 #include <errno.h>
+#include <libarch/ddi.h>
 
 #include "mixer.h"
+
+#define CT_MIXER_RESET_ADDRESS 0x00
+
+typedef struct volume_item {
+	uint8_t address;
+	uint8_t channels;
+	const char *description;
+	unsigned min_value;
+	unsigned max_value;
+	unsigned shift;
+	bool same_reg;
+} volume_item_t;
+
+static const volume_item_t volume_ct1335[] = {
+	{ 0x02, 1, "Master", 0, 7, 1, true },
+	{ 0x06, 1, "MIDI", 0, 7, 1, true },
+	{ 0x08, 1, "CD", 0, 7, 1, true },
+	{ 0x0a, 1, "Voice", 0, 3, 1, true },
+};
+
+static const volume_item_t volume_ct1345[] = {
+	{ 0x04, 2, "Voice", 0, 7, 1, true },
+	{ 0x0a, 1, "Mic", 0, 3, 1, true },
+	{ 0x22, 2, "Master", 0, 7, 1, true },
+	{ 0x26, 2, "MIDI", 0, 7, 1, true },
+	{ 0x28, 2, "CD", 0, 7, 1, true },
+	{ 0x2e, 2, "Line", 0, 7, 1, true },
+};
+
+static const volume_item_t volume_ct1745[] = {
+	{ 0x30, 2, "Master", 0, 31, 3, false },
+	{ 0x32, 2, "Voice", 0, 31, 3, false },
+	{ 0x34, 2, "MIDI", 0, 31, 3, false },
+	{ 0x36, 2, "CD", 0, 31, 3, false },
+	{ 0x38, 2, "Line", 0, 31, 3, false },
+	{ 0x3a, 1, "Mic", 0, 31, 3, false },
+	{ 0x3b, 1, "PC Speaker", 0, 3, 6, false },
+	{ 0x3f, 2, "Input Gain", 0, 3, 6, false },
+	{ 0x41, 2, "Output Gain", 0, 3, 6, false },
+	{ 0x44, 2, "Treble", 0, 15, 4, false },
+	{ 0x46, 2, "Bass", 0, 15, 4, false },
+};
+
+static const struct {
+	size_t count;
+	const volume_item_t *table;
+} volume_table[] = {
+	[SB_MIXER_NONE] = { 0, NULL },
+	[SB_MIXER_UNKNOWN] = { 0, NULL },
+	[SB_MIXER_CT1335] = {
+	    sizeof(volume_ct1335) / sizeof(volume_item_t), volume_ct1335 },
+	[SB_MIXER_CT1345] = {
+	    sizeof(volume_ct1345) / sizeof(volume_item_t), volume_ct1345 },
+	[SB_MIXER_CT1745] = {
+	    sizeof(volume_ct1745) / sizeof(volume_item_t), volume_ct1745 },
+};
 
 const char * mixer_type_to_str(mixer_type_t type)
@@ -44,4 +102,11 @@
 int mixer_init(sb16_regs_t *regs, mixer_type_t type)
 {
+	if (type == SB_MIXER_UNKNOWN)
+		return ENOTSUP;
+
+	if (type != SB_MIXER_NONE) {
+		pio_write_8(&regs->mixer_address, CT_MIXER_RESET_ADDRESS);
+		pio_write_8(&regs->mixer_data, 1);
+	}
 	return EOK;
 }
@@ -49,19 +114,28 @@
 void mixer_load_volume_levels(sb16_regs_t *regs, mixer_type_t type)
 {
+	/* Default values are ok for now */
 }
 /*----------------------------------------------------------------------------*/
 void mixer_store_volume_levels(sb16_regs_t *regs, mixer_type_t type)
 {
+	/* Default values are ok for now */
 }
 /*----------------------------------------------------------------------------*/
-int mixer_get_control_item_count(sb16_regs_t *regs, mixer_type_t type)
+int mixer_get_control_item_count(mixer_type_t type)
 {
-	return 1;
+	return volume_table[type].count;
 }
 /*----------------------------------------------------------------------------*/
-int mixer_get_control_item_info(sb16_regs_t *regs, mixer_type_t type,
+int mixer_get_control_item_info(mixer_type_t type, unsigned index,
     const char** name, unsigned *channels)
 {
-	return ENOTSUP;
+	if (index > volume_table[type].count)
+		return ENOENT;
+
+	if (name)
+	    *name = volume_table[type].table[index].description;
+	if (channels)
+	    *channels = volume_table[type].table[index].channels;
+	return EOK;
 }
 /*----------------------------------------------------------------------------*/
Index: uspace/drv/audio/sb16/mixer.h
===================================================================
--- uspace/drv/audio/sb16/mixer.h	(revision 7a0a0f535dbc66c8d1fddd518c3964097180b4db)
+++ uspace/drv/audio/sb16/mixer.h	(revision 0687e1bc5c63116cad13f0ff8a18b9a655875a0d)
@@ -49,6 +49,6 @@
 void mixer_load_volume_levels(sb16_regs_t *regs, mixer_type_t type);
 void mixer_store_volume_levels(sb16_regs_t *regs, mixer_type_t type);
-int mixer_get_control_item_count(sb16_regs_t *regs, mixer_type_t type);
-int mixer_get_control_item_info(sb16_regs_t *regs, mixer_type_t type,
+int mixer_get_control_item_count(mixer_type_t type);
+int mixer_get_control_item_info(mixer_type_t type, unsigned index,
     const char** name, unsigned *channels);
 int mixer_set_volume_level(sb16_regs_t *regs, mixer_type_t type,
Index: uspace/drv/audio/sb16/sb16.c
===================================================================
--- uspace/drv/audio/sb16/sb16.c	(revision 7a0a0f535dbc66c8d1fddd518c3964097180b4db)
+++ uspace/drv/audio/sb16/sb16.c	(revision 0687e1bc5c63116cad13f0ff8a18b9a655875a0d)
@@ -29,5 +29,4 @@
 #include <errno.h>
 #include <str_error.h>
-#include <libarch/ddi.h>
 
 #include "ddf_log.h"
