Index: uspace/drv/audio/sb16/mixer.c
===================================================================
--- uspace/drv/audio/sb16/mixer.c	(revision 5c1b3cdf711ad251494bf421532d7e53ecd912ee)
+++ uspace/drv/audio/sb16/mixer.c	(revision 1912b4519763bcbb573d6ccbc668efc042d978fa)
@@ -45,96 +45,69 @@
 } channel_t;
 
-typedef struct volume_item {
-	const char *description;
-	uint8_t channels;
-	const channel_t *channel_table;
-} volume_item_t;
-
 /* CT1335 channels */
 static const channel_t channels_table_ct1335[] = {
-	{ "Mono", 0x02, 1, 8, false }, /* Master, Mono, 3bit volume level */
-	{ "Mono", 0x06, 1, 8, false }, /* Midi, Mono, 3bit volume level */
-	{ "Mono", 0x08, 1, 8, false }, /* CD, Mono, 3bit volume level */
-	{ "Mono", 0x0a, 1, 4, false }, /* Voice, Mono, 2bit volume level */
+	{ "Master", 0x02, 1, 8, false }, /* Master, Mono, 3bit volume level */
+	{ "Midi", 0x06, 1, 8, false }, /* Midi, Mono, 3bit volume level */
+	{ "CD", 0x08, 1, 8, false }, /* CD, Mono, 3bit volume level */
+	{ "Voice", 0x0a, 1, 4, false }, /* Voice, Mono, 2bit volume level */
 };
 
 /* CT1345 channels */
 static const channel_t channels_table_ct1345[] = {
-	{ "Left", 0x22, 5, 8, true }, /* Master, Left, 3bit volume level */
-	{ "Right", 0x22, 1, 8, true }, /* Master, Right, 3bit volume level */
-	{ "Left", 0x26, 5, 8, true }, /* Midi, Left, 3bit volume level */
-	{ "Right", 0x26, 1, 8, true }, /* Midi, Right, 3bit volume level */
-	{ "Left", 0x28, 5, 8, true }, /* CD, Left, 3bit volume level */
-	{ "Right", 0x28, 1, 8, true }, /* CD, Right, 3bit volume level */
-	{ "Left", 0x2e, 5, 8, true }, /* Line, Left, 3bit volume level */
-	{ "Right", 0x2e, 1, 8, true }, /* Line, Right, 3bit volume level */
-	{ "Left", 0x04, 5, 8, true }, /* Voice, Left, 3bit volume level */
-	{ "Right", 0x04, 1, 8, true }, /* Voice, Right, 3bit volume level */
-	{ "Mono", 0x0a, 1, 4, false }, /* Mic, Mono, 2bit volume level */
+	{ "Master Left", 0x22, 5, 8, true }, /* Master, Left, 3bit volume level */
+	{ "Master Right", 0x22, 1, 8, true }, /* Master, Right, 3bit volume level */
+	{ "MIDI Left", 0x26, 5, 8, true }, /* Midi, Left, 3bit volume level */
+	{ "MIDI Right", 0x26, 1, 8, true }, /* Midi, Right, 3bit volume level */
+	{ "CD Left", 0x28, 5, 8, true }, /* CD, Left, 3bit volume level */
+	{ "CD Right", 0x28, 1, 8, true }, /* CD, Right, 3bit volume level */
+	{ "Line In Left", 0x2e, 5, 8, true }, /* Line, Left, 3bit volume level */
+	{ "Line In Right", 0x2e, 1, 8, true }, /* Line, Right, 3bit volume level */
+	{ "Voice Left", 0x04, 5, 8, true }, /* Voice, Left, 3bit volume level */
+	{ "Voice Right", 0x04, 1, 8, true }, /* Voice, Right, 3bit volume level */
+	{ "Mic", 0x0a, 1, 4, false }, /* Mic, Mono, 2bit volume level */
 };
 
 /* CT1745 channels */
 static const channel_t channels_table_ct1745[] = {
-	{ "Left", 0x30, 3, 32, false },  /* Master, Left, 5bit volume level */
-	{ "Right", 0x31, 3, 32, false }, /* Master, Right, 5bit volume level */
-	{ "Left", 0x32, 3, 32, false },  /* Voice, Left, 5bit volume level */
-	{ "Right", 0x33, 3, 32, false }, /* Voice, Right, 5bit volume level */
-	{ "Left", 0x34, 3, 32, false }, /* MIDI, Left, 5bit volume level */
-	{ "Right", 0x35, 3, 32, false }, /* MIDI, Right, 5bit volume level */
-	{ "Left", 0x36, 3, 32, false }, /* CD, Left, 5bit volume level */
-	{ "Right", 0x37, 3, 32, false }, /* CD, Right, 5bit volume level */
-	{ "Left", 0x38, 3, 32, false }, /* Line, Left, 5bit volume level */
-	{ "Right", 0x39, 3, 32, false }, /* Line, Right, 5bit volume level */
-	{ "Mono", 0x3a, 3, 32, false }, /* Mic, Mono, 5bit volume level */
-	{ "Mono", 0x3b, 6, 4, false }, /* PC speaker, Mono, 2bit level */
-	{ "Left", 0x3f, 6, 4, false }, /* Input Gain, Left, 2bit level */
-	{ "Right", 0x40, 6, 4, false }, /* Input Gain, Right, 2bit level */
-	{ "Left", 0x41, 6, 4, false }, /* Output Gain, Left, 2bit level */
-	{ "Right", 0x42, 6, 4, false }, /* Output Gain, Right, 2bit level */
-	{ "Left", 0x44, 4, 16, false }, /* Treble, Left, 4bit volume level */
-	{ "Right", 0x45, 4, 16, false }, /* Treble, Right, 4bit volume level */
-	{ "Left", 0x46, 4, 16, false }, /* Bass, Left, 4bit volume level */
-	{ "Right", 0x47, 4, 16, false }, /* Bass, Right, 4bit volume level */
-};
-
-static const volume_item_t volume_ct1335[] = {
-	{ "Master", 1, &channels_table_ct1335[0] },
-	{ "MIDI", 1, &channels_table_ct1335[1] },
-	{ "CD", 1, &channels_table_ct1335[2] },
-	{ "Voice", 1, &channels_table_ct1335[3] },
-};
-
-static const volume_item_t volume_ct1345[] = {
-	{ "Master", 2, &channels_table_ct1345[0] },
-	{ "Voice", 2, &channels_table_ct1345[8] },
-	{ "Mic", 1, &channels_table_ct1345[10] },
-	{ "MIDI", 2, &channels_table_ct1345[2] },
-	{ "CD", 2, &channels_table_ct1345[4] },
-	{ "Line", 2, &channels_table_ct1345[6] },
-};
-
-static const volume_item_t volume_ct1745[] = {
-	{ "Master", 2, &channels_table_ct1745[0] },
-	{ "Voice", 2, &channels_table_ct1745[2] },
-	{ "MIDI", 2, &channels_table_ct1745[4] },
-	{ "CD", 2, &channels_table_ct1745[6] },
-	{ "Line", 2, &channels_table_ct1745[8] },
-	{ "Mic", 1, &channels_table_ct1745[10] },
-	{ "PC Speaker", 1, &channels_table_ct1745[11] },
-	{ "Input Gain", 2, &channels_table_ct1745[12] },
-	{ "Output Gain", 2, &channels_table_ct1745[14] },
-	{ "Treble", 2, &channels_table_ct1745[16] },
-	{ "Bass", 2, &channels_table_ct1745[18] },
+	{ "Master Left", 0x30, 3, 32, false },  /* Master, Left, 5bit volume level */
+	{ "Master Right", 0x31, 3, 32, false }, /* Master, Right, 5bit volume level */
+	{ "Voice Left", 0x32, 3, 32, false },  /* Voice, Left, 5bit volume level */
+	{ "Voice Right", 0x33, 3, 32, false }, /* Voice, Right, 5bit volume level */
+	{ "MIDI Left", 0x34, 3, 32, false }, /* MIDI, Left, 5bit volume level */
+	{ "MIDI Right", 0x35, 3, 32, false }, /* MIDI, Right, 5bit volume level */
+	{ "CD Left", 0x36, 3, 32, false }, /* CD, Left, 5bit volume level */
+	{ "CD Right", 0x37, 3, 32, false }, /* CD, Right, 5bit volume level */
+	{ "Line In Left", 0x38, 3, 32, false }, /* Line, Left, 5bit volume level */
+	{ "Line In Right", 0x39, 3, 32, false }, /* Line, Right, 5bit volume level */
+	{ "Mic", 0x3a, 3, 32, false }, /* Mic, Mono, 5bit volume level */
+	{ "PC Speaker", 0x3b, 6, 4, false }, /* PC speaker, Mono, 2bit level */
+	{ "Input Gain Left", 0x3f, 6, 4, false }, /* Input Gain, Left, 2bit level */
+	{ "Input Gain Right", 0x40, 6, 4, false }, /* Input Gain, Right, 2bit level */
+	{ "Output Gain Left", 0x41, 6, 4, false }, /* Output Gain, Left, 2bit level */
+	{ "Output Gain Right", 0x42, 6, 4, false }, /* Output Gain, Right, 2bit level */
+	{ "Treble Left", 0x44, 4, 16, false }, /* Treble, Left, 4bit volume level */
+	{ "Treble Right", 0x45, 4, 16, false }, /* Treble, Right, 4bit volume level */
+	{ "Bass Left", 0x46, 4, 16, false }, /* Bass, Left, 4bit volume level */
+	{ "Bass Right", 0x47, 4, 16, false }, /* Bass, Right, 4bit volume level */
 };
 
 static const struct {
-	const volume_item_t *table;
+	const channel_t *table;
 	size_t count;
 } volume_table[] = {
 	[SB_MIXER_NONE] = { NULL, 0 },
 	[SB_MIXER_UNKNOWN] = { NULL, 0 },
-	[SB_MIXER_CT1335] = { volume_ct1335, ARRAY_SIZE(volume_ct1335) },
-	[SB_MIXER_CT1345] = { volume_ct1345, ARRAY_SIZE(volume_ct1345) },
-	[SB_MIXER_CT1745] = { volume_ct1745, ARRAY_SIZE(volume_ct1745) },
+	[SB_MIXER_CT1335] = {
+	    channels_table_ct1335,
+	    ARRAY_SIZE(channels_table_ct1335),
+	},
+	[SB_MIXER_CT1345] = {
+	    channels_table_ct1345,
+	    ARRAY_SIZE(channels_table_ct1345),
+	},
+	[SB_MIXER_CT1745] = {
+	    channels_table_ct1745,
+	    ARRAY_SIZE(channels_table_ct1745),
+	},
 };
 
@@ -177,85 +150,72 @@
 }
 
-int sb_mixer_get_control_item_info(const sb_mixer_t *mixer, unsigned index,
-    const char** name, unsigned *channels)
-{
-	assert(mixer);
-	if (index > volume_table[mixer->type].count)
+int sb_mixer_get_control_item_info(const sb_mixer_t *mixer, unsigned item,
+    const char** name, unsigned *levels)
+{
+	assert(mixer);
+	if (item > volume_table[mixer->type].count)
 		return ENOENT;
 
-	const volume_item_t *item = &volume_table[mixer->type].table[index];
+	const channel_t *ch = &volume_table[mixer->type].table[item];
 	if (name)
-		*name = item->description;
-	if (channels)
-		*channels = item->channels;
-	return EOK;
-}
-
-int sb_mixer_get_channel_info(const sb_mixer_t *mixer, unsigned index,
-    unsigned channel, const char **name, unsigned *levels)
-{
-	assert(mixer);
-	if (index > volume_table[mixer->type].count)
+		*name = ch->name;
+	if (levels)
+		*levels = ch->volume_levels;
+	return EOK;
+}
+
+/**
+ * Write new volume level from mixer registers.
+ * @param mixer SB Mixer to use.
+ * @param index Control item(channel) index.
+ * @param value New volume level.
+ * @return Error code.
+ */
+int sb_mixer_get_control_item_value(const sb_mixer_t *mixer, unsigned item,
+    unsigned *value)
+{
+	assert(mixer);
+	if (!value)
+		return EBADMEM;
+	if (item > volume_table[mixer->type].count)
 		return ENOENT;
 
-	const volume_item_t *item = &volume_table[mixer->type].table[index];
-	if (channel > item->channels)
+	const channel_t *chan = &volume_table[mixer->type].table[item];
+	pio_write_8(&mixer->regs->mixer_address, chan->address);
+	*value = (pio_read_8(&mixer->regs->mixer_data) >> chan->shift)
+	    & (chan->volume_levels - 1);
+	return EOK;
+}
+
+/**
+ * Write new volume level to mixer registers.
+ * @param mixer SB Mixer to use.
+ * @param index Control item(channel) index.
+ * @param value New volume level.
+ * @return Error code.
+ */
+int sb_mixer_set_control_item_value(const sb_mixer_t *mixer, unsigned item,
+    unsigned value)
+{
+	assert(mixer);
+	if (item > volume_table[mixer->type].count)
 		return ENOENT;
 
-	const channel_t *chan = &item->channel_table[channel];
-	if (name)
-		*name = chan->name;
-	if (levels)
-		*levels = chan->volume_levels;
-	return EOK;
-}
-
-int sb_mixer_set_volume_level(const sb_mixer_t *mixer,
-    unsigned index, unsigned channel, unsigned level)
-{
-	if (mixer->type == SB_MIXER_UNKNOWN || mixer->type == SB_MIXER_NONE)
-		return ENOTSUP;
-	if (index >= volume_table[mixer->type].count)
-		return ENOENT;
-	if (channel >= volume_table[mixer->type].table[index].channels)
-		return ENOENT;
-
-	const channel_t *chan =
-	    &volume_table[mixer->type].table[index].channel_table[channel];
-
-	if (level >= chan->volume_levels)
-		level = chan->volume_levels - 1;
+	const channel_t *chan = &volume_table[mixer->type].table[item];
+	if (value >= chan->volume_levels)
+		value = chan->volume_levels - 1;
 
 	pio_write_8(&mixer->regs->mixer_address, chan->address);
 
-	uint8_t value = 0;
+	uint8_t regv = 0;
 	if (chan->preserve_bits) {
-		value = pio_read_8(&mixer->regs->mixer_data);
-		value &= ~(uint8_t)((chan->volume_levels - 1) << chan->shift);
+		regv = pio_read_8(&mixer->regs->mixer_data);
+		regv &= ~(uint8_t)((chan->volume_levels - 1) << chan->shift);
 	}
 
-	value |= level << chan->shift;
-	pio_write_8(&mixer->regs->mixer_data, value);
-	ddf_log_note("Channel %s %s volume set to: %u.",
-	    volume_table[mixer->type].table[index].description,
-	    chan->name, level);
-	return EOK;
-}
-
-unsigned sb_mixer_get_volume_level(const sb_mixer_t *mixer, unsigned index,
-    unsigned channel)
-{
-	assert(mixer);
-	if (mixer->type == SB_MIXER_UNKNOWN
-	    || mixer->type == SB_MIXER_NONE
-	    || (index >= volume_table[mixer->type].count)
-	    || (channel >= volume_table[mixer->type].table[index].channels))
-		return 0;
-
-	const channel_t *chan =
-	    &volume_table[mixer->type].table[index].channel_table[channel];
-
-	pio_write_8(&mixer->regs->mixer_address, chan->address);
-	return (pio_read_8(&mixer->regs->mixer_data) >> chan->shift)
-	    & (chan->volume_levels - 1);
-}
+	regv |= value << chan->shift;
+	pio_write_8(&mixer->regs->mixer_data, regv);
+	ddf_log_note("Item %s new value is: %u.",
+	    volume_table[mixer->type].table[item].name, value);
+	return EOK;
+}
Index: uspace/drv/audio/sb16/mixer.h
===================================================================
--- uspace/drv/audio/sb16/mixer.h	(revision 5c1b3cdf711ad251494bf421532d7e53ecd912ee)
+++ uspace/drv/audio/sb16/mixer.h	(revision 1912b4519763bcbb573d6ccbc668efc042d978fa)
@@ -54,11 +54,9 @@
 int sb_mixer_get_control_item_count(const sb_mixer_t *mixer);
 int sb_mixer_get_control_item_info(const sb_mixer_t *mixer, unsigned index,
-    const char **name, unsigned *channels);
-int sb_mixer_get_channel_info(const sb_mixer_t *mixer, unsigned index,
-    unsigned channel, const char **name, unsigned *levels);
-int sb_mixer_set_volume_level(const sb_mixer_t *mixer,
-    unsigned item, unsigned channel, unsigned level);
-unsigned sb_mixer_get_volume_level(const sb_mixer_t *mixer,
-    unsigned item, unsigned channel);
+    const char **name, unsigned *levels);
+int sb_mixer_get_control_item_value(const sb_mixer_t *mixer, unsigned index,
+    unsigned *value);
+int sb_mixer_set_control_item_value(const sb_mixer_t *mixer, unsigned index,
+    unsigned value);
 #endif
 /**
Index: uspace/drv/audio/sb16/mixer_iface.c
===================================================================
--- uspace/drv/audio/sb16/mixer_iface.c	(revision 5c1b3cdf711ad251494bf421532d7e53ecd912ee)
+++ uspace/drv/audio/sb16/mixer_iface.c	(revision 1912b4519763bcbb573d6ccbc668efc042d978fa)
@@ -50,7 +50,7 @@
 	return EOK;
 }
-/*----------------------------------------------------------------------------*/
+
 static int sb_get_item_info(ddf_fun_t *fun, unsigned item, const char** name,
-    unsigned *channels)
+    unsigned *max_level)
 {
 	assert(fun);
@@ -58,53 +58,21 @@
 	assert(mixer);
 	return
-	    sb_mixer_get_control_item_info(mixer, item, name, channels);
+	    sb_mixer_get_control_item_info(mixer, item, name, max_level);
 }
-/*----------------------------------------------------------------------------*/
-static int sb_get_channel_info(ddf_fun_t *fun, unsigned item, unsigned channel,
-    const char** name, unsigned *levels)
+
+static int sb_set_item_level(ddf_fun_t *fun, unsigned item, unsigned value)
 {
 	assert(fun);
 	const sb_mixer_t *mixer = ddf_fun_data_get(fun);
 	assert(mixer);
-	return sb_mixer_get_channel_info(mixer, item, channel, name, levels);
+	return sb_mixer_set_control_item_value(mixer, item, value);
 }
-/*----------------------------------------------------------------------------*/
-static int sb_channel_mute_set(ddf_fun_t *fun, unsigned item, unsigned channel,
-    bool mute)
-{
-	return ENOTSUP;
-}
-/*----------------------------------------------------------------------------*/
-static int sb_channel_mute_get(ddf_fun_t *fun, unsigned item, unsigned channel,
-    bool *mute)
-{
-	*mute = false;
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static int sb_channel_volume_set(ddf_fun_t *fun, unsigned item, unsigned channel,
-    unsigned volume)
+
+static int sb_get_item_level(ddf_fun_t *fun, unsigned item, unsigned *value)
 {
 	assert(fun);
 	const sb_mixer_t *mixer = ddf_fun_data_get(fun);
 	assert(mixer);
-	return sb_mixer_set_volume_level(mixer, item, channel, volume);
-}
-/*----------------------------------------------------------------------------*/
-static int sb_channel_volume_get(ddf_fun_t *fun, unsigned item, unsigned channel,
-    unsigned *level, unsigned *max)
-{
-	assert(fun);
-	const sb_mixer_t *mixer = ddf_fun_data_get(fun);
-	assert(mixer);
-	unsigned levels;
-	const int ret =
-	    sb_mixer_get_channel_info(mixer, item, channel, NULL, &levels);
-	if (ret == EOK && max)
-		*max = --levels;
-	if (ret == EOK && level)
-		*level = sb_mixer_get_volume_level(mixer, item, channel);
-
-	return ret;
+	return sb_mixer_get_control_item_value(mixer, item, value);
 }
 
@@ -112,12 +80,7 @@
 	.get_info = sb_get_info,
 	.get_item_info = sb_get_item_info,
-	.get_channel_info = sb_get_channel_info,
 
-	.channel_mute_set = sb_channel_mute_set,
-	.channel_mute_get = sb_channel_mute_get,
-
-	.channel_volume_set = sb_channel_volume_set,
-	.channel_volume_get = sb_channel_volume_get,
-
+	.get_item_level = sb_get_item_level,
+	.set_item_level = sb_set_item_level,
 };
 /**
