Index: uspace/app/mixerctl/mixerctl.c
===================================================================
--- uspace/app/mixerctl/mixerctl.c	(revision 8a7d78cce508b3191513ec7eee495006eb933f36)
+++ uspace/app/mixerctl/mixerctl.c	(revision 1912b4519763bcbb573d6ccbc668efc042d978fa)
@@ -43,4 +43,8 @@
 #define DEFAULT_DEVICE "/hw/pci0/00:01.0/sb16/control"
 
+/**
+ * Print volume levels on all channels on all control items.
+ * @param exch IPC exchange
+ */
 static void print_levels(async_exch_t *exch)
 {
@@ -52,11 +56,11 @@
 		return;
 	}
-	printf("MIXER %s:\n", name);
+	printf("MIXER %s:\n\n", name);
 
 	for (unsigned i = 0; i < count; ++i) {
 		const char *name = NULL;
-		unsigned channels = 0;
-		const int ret =
-		    audio_mixer_get_item_info(exch, i, &name, &channels);
+		unsigned levels = 0, current = 0;
+		int ret =
+		    audio_mixer_get_item_info(exch, i, &name, &levels);
 		if (ret != EOK) {
 			printf("Failed to get item %u info: %s.\n",
@@ -64,37 +68,18 @@
 			continue;
 		}
-		for (unsigned j = 0; j < channels; ++j) {
-			const char *chan = NULL;
-			int ret = audio_mixer_get_channel_info(
-			    exch, i, j, &chan, NULL);
-			if (ret != EOK) {
-				printf(
-				    "Failed to get channel %u-%u info: %s.\n",
-				    i, j, str_error(ret));
-			}
-			unsigned level = 0, max = 0;
-			ret = audio_mixer_channel_volume_get(
-			    exch, i, j, &level, &max);
-			if (ret != EOK) {
-				printf("Failed to get channel %u-%u volume:"
-				    " %s.\n", i, j, str_error(ret));
-			}
-			bool mute = false;
-			ret = audio_mixer_channel_mute_get(
-			    exch, i, j, &mute);
-			if (ret != EOK) {
-				printf("Failed to get channel %u-%u mute"
-				    " status: %s.\n", i, j, str_error(ret));
-			}
+		ret = audio_mixer_get_item_level(exch, i, &current);
+		if (ret != EOK) {
+			printf("Failed to get item %u info: %s.\n",
+			    i, str_error(ret));
+			continue;
+		}
 
-			printf("\tChannel(%u/%u) %s %s volume: %u/%u%s.\n",
-			    i, j, name, chan, level, max, mute ? " (M)":"");
-			free(chan);
-		}
+		printf("Control item %u `%s' : %u/%u.\n",
+		    i, name, current, levels - 1);
 		free(name);
 
 	}
 }
-/*----------------------------------------------------------------------------*/
+
 static unsigned get_number(const char* str)
 {
@@ -103,43 +88,42 @@
 	return num;
 }
-/*----------------------------------------------------------------------------*/
-static void set_volume(async_exch_t *exch, int argc, char *argv[])
-{
-	assert(exch);
-	if (argc != 5 && argc != 6) {
-		printf("%s [device] setvolume item channel value\n", argv[0]);
-	}
-	unsigned params = argc == 6 ? 3 : 2;
-	const unsigned item = get_number(argv[params++]);
-	const unsigned channel = get_number(argv[params++]);
-	const unsigned value = get_number(argv[params]);
-	int ret = audio_mixer_channel_volume_set(exch, item, channel, value);
-	if (ret != EOK) {
-		printf("Failed to set mixer volume: %s.\n", str_error(ret));
-		return;
-	}
-	printf("Channel %u-%u volume set to %u.\n", item, channel, value);
-}
-/*----------------------------------------------------------------------------*/
-static void get_volume(async_exch_t *exch, int argc, char *argv[])
+
+static void set_level(async_exch_t *exch, int argc, char *argv[])
 {
 	assert(exch);
 	if (argc != 4 && argc != 5) {
-		printf("%s [device] getvolume item channel\n", argv[0]);
+		printf("%s [device] setlevel item value\n", argv[0]);
+		return;
 	}
 	unsigned params = argc == 5 ? 3 : 2;
 	const unsigned item = get_number(argv[params++]);
-	const unsigned channel = get_number(argv[params++]);
-	unsigned value = 0, max = 0;
-
-	int ret = audio_mixer_channel_volume_get(
-	    exch, item, channel, &value, &max);
+	const unsigned value = get_number(argv[params]);
+	int ret = audio_mixer_set_item_level(exch, item, value);
 	if (ret != EOK) {
-		printf("Failed to get mixer volume: %s.\n", str_error(ret));
+		printf("Failed to set item level: %s.\n", str_error(ret));
 		return;
 	}
-	printf("Channel %u-%u volume: %u/%u.\n", item, channel, value, max);
+	printf("Control item %u new level is %u.\n", item, value);
 }
-/*----------------------------------------------------------------------------*/
+
+static void get_level(async_exch_t *exch, int argc, char *argv[])
+{
+	assert(exch);
+	if (argc != 3 && argc != 4) {
+		printf("%s [device] getlevel item \n", argv[0]);
+		return;
+	}
+	unsigned params = argc == 4 ? 3 : 2;
+	const unsigned item = get_number(argv[params++]);
+	unsigned value = 0;
+
+	int ret = audio_mixer_get_item_level(exch, item, &value);
+	if (ret != EOK) {
+		printf("Failed to get item level: %s.\n", str_error(ret));
+		return;
+	}
+	printf("Control item %u level: %u.\n", item, value);
+}
+
 int main(int argc, char *argv[])
 {
@@ -147,13 +131,13 @@
 	void (*command)(async_exch_t *, int, char*[]) = NULL;
 
-	if (argc >= 2 && str_cmp(argv[1], "setvolume") == 0) {
-		command = set_volume;
-		if (argc == 6)
+	if (argc >= 2 && str_cmp(argv[1], "setlevel") == 0) {
+		command = set_level;
+		if (argc == 5)
 			device = argv[1];
 	}
 
-	if (argc >= 2 && str_cmp(argv[1], "getvolume") == 0) {
-		command = get_volume;
-		if (argc == 5)
+	if (argc >= 2 && str_cmp(argv[1], "getlevel") == 0) {
+		command = get_level;
+		if (argc == 4)
 			device = argv[1];
 	}
Index: uspace/drv/audio/sb16/mixer.c
===================================================================
--- uspace/drv/audio/sb16/mixer.c	(revision 8a7d78cce508b3191513ec7eee495006eb933f36)
+++ 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 8a7d78cce508b3191513ec7eee495006eb933f36)
+++ 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 8a7d78cce508b3191513ec7eee495006eb933f36)
+++ 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,
 };
 /**
Index: uspace/lib/drv/generic/remote_audio_mixer.c
===================================================================
--- uspace/lib/drv/generic/remote_audio_mixer.c	(revision 8a7d78cce508b3191513ec7eee495006eb933f36)
+++ uspace/lib/drv/generic/remote_audio_mixer.c	(revision 1912b4519763bcbb573d6ccbc668efc042d978fa)
@@ -65,51 +65,19 @@
 	IPC_M_AUDIO_MIXER_GET_ITEM_INFO,
 
-	/** Asks for channel name and number of volume levels.
+	/** Set new control item setting
 	 * Answer:
 	 * - ENOTSUP - call not supported
-	 * - ENOENT - no such channel
+	 * - ENOENT - no such control item
 	 * - EOK - call successful, info is valid
-	 * Answer arguments:
-	 * - Channel name
-	 * - Volume levels
 	 */
-	IPC_M_AUDIO_MIXER_GET_CHANNEL_INFO,
-
-	/** Set channel mute status
+	IPC_M_AUDIO_MIXER_SET_ITEM_LEVEL,
+
+	/** Get control item setting
 	 * Answer:
 	 * - ENOTSUP - call not supported
-	 * - ENOENT - no such channel
+	 * - ENOENT - no such control item
 	 * - EOK - call successful, info is valid
 	 */
-	IPC_M_AUDIO_MIXER_CHANNEL_MUTE_SET,
-
-	/** Get channel mute status
-	 * Answer:
-	 * - ENOTSUP - call not supported
-	 * - ENOENT - no such channel
-	 * - EOK - call successful, info is valid
-	 * Answer arguments:
-	 * - Channel mute status
-	 */
-	IPC_M_AUDIO_MIXER_CHANNEL_MUTE_GET,
-
-	/** Set channel volume level
-	 * Answer:
-	 * - ENOTSUP - call not supported
-	 * - ENOENT - no such channel
-	 * - EOK - call successful, info is valid
-	 */
-	IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_SET,
-
-	/** Get channel volume level
-	 * Answer:
-	 * - ENOTSUP - call not supported
-	 * - ENOENT - no such channel
-	 * - EOK - call successful, info is valid
-	 * Answer arguments:
-	 * - Channel volume level
-	 * - Channel maximum volume level
-	 */
-	IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_GET,
+	IPC_M_AUDIO_MIXER_GET_ITEM_LEVEL,
 } audio_mixer_iface_funcs_t;
 
@@ -162,11 +130,11 @@
  */
 int audio_mixer_get_item_info(async_exch_t *exch, unsigned item,
-    const char **name, unsigned *channels)
+    const char **name, unsigned *levels)
 {
 	if (!exch)
 		return EINVAL;
-	sysarg_t name_size, chans;
+	sysarg_t name_size, lvls;
 	const int ret = async_req_2_2(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE),
-	    IPC_M_AUDIO_MIXER_GET_ITEM_INFO, item, &name_size, &chans);
+	    IPC_M_AUDIO_MIXER_GET_ITEM_INFO, item, &name_size, &lvls);
 	if (ret == EOK && name) {
 		char *name_place = calloc(1, name_size);
@@ -185,125 +153,43 @@
 		*name = name_place;
 	}
-	if (ret == EOK && chans)
-		*channels = chans;
+	if (ret == EOK && levels)
+		*levels = lvls;
 	return ret;
 }
 
 /**
- * Query audio mixer for channel specific info (name and volume levels).
+ * Set control item to a new level.
  * @param[in] exch IPC exchange connected to the device.
- * @param[in] item TH control item controlling the channel.
- * @param[in] channel The channel.
- * @param[out] name Audio channel string identifier.
- * @param[out] volume_levels Number of volume levels.
+ * @param[in] item The control item controlling the channel.
+ * @param[in] level The new value.
  * @return Error code.
  */
-int audio_mixer_get_channel_info(async_exch_t *exch, unsigned item,
-    unsigned channel, const char **name, unsigned *volume_levels)
+int audio_mixer_set_item_level(async_exch_t *exch, unsigned item,
+    unsigned level)
 {
 	if (!exch)
 		return EINVAL;
-	sysarg_t name_size, levels;
-	const int ret = async_req_3_2(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE),
-	    IPC_M_AUDIO_MIXER_GET_CHANNEL_INFO, item, channel,
-	    &name_size, &levels);
-	if (ret == EOK && name) {
-		char *name_place = calloc(1, name_size);
-		if (!name_place) {
-			/* Make the other side fail
-			 * as it waits for read request */
-			async_data_read_start(exch, (void*)-1, 0);
-			return ENOMEM;
-		}
-		const int ret =
-		    async_data_read_start(exch, name_place, name_size);
-		if (ret != EOK) {
-			free(name_place);
-			return ret;
-		}
-		*name = name_place;
-	}
-	if (ret == EOK && volume_levels)
-		*volume_levels = levels;
-	return ret;
-}
-
-/**
- * Set MUTE status on an audio channel.
+	return async_req_3_0(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE),
+	    IPC_M_AUDIO_MIXER_SET_ITEM_LEVEL, item, level);
+}
+
+/**
+ * Get current level of a control item.
  * @param[in] exch IPC exchange connected to the device.
  * @param[in] item The control item controlling the channel.
  * @param[in] channel The channel index.
- * @param[in] mute_status A new MUTE status.
+ * @param[out] level Currently set value.
  * @return Error code.
  */
-int audio_mixer_channel_mute_set(async_exch_t *exch, unsigned item,
-    unsigned channel, bool mute_status)
+int audio_mixer_get_item_level(async_exch_t *exch, unsigned item,
+    unsigned *level)
 {
 	if (!exch)
 		return EINVAL;
-	return async_req_4_0(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE),
-	    IPC_M_AUDIO_MIXER_CHANNEL_MUTE_SET, item, channel, mute_status);
-}
-
-/**
- * Get MUTE status on an audio channel.
- * @param[in] exch IPC exchange connected to the device.
- * @param[in] item The control item controlling the channel.
- * @param[in] channel The channel index.
- * @param[out] mute_status Currently set MUTE status.
- * @return Error code.
- */
-int audio_mixer_channel_mute_get(async_exch_t *exch, unsigned item,
-    unsigned channel, bool *mute_status)
-{
-	if (!exch)
-		return EINVAL;
-	sysarg_t mute;
-	const int ret = async_req_3_1(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE),
-	    IPC_M_AUDIO_MIXER_CHANNEL_MUTE_GET, item, channel, &mute);
-	if (ret == EOK && mute_status)
-		*mute_status = (bool)mute;
-	return ret;
-}
-
-/**
- * Set VOLUME LEVEL on an audio channel.
- * @param[in] exch IPC exchange connected to the device.
- * @param[in] item The control item controlling the channel.
- * @param[in] channel The channel index.
- * @param[in] volume A new VOLUME LEVEL.
- * @return Error code.
- */
-int audio_mixer_channel_volume_set(async_exch_t *exch, unsigned item,
-    unsigned channel, unsigned volume)
-{
-	if (!exch)
-		return EINVAL;
-	return async_req_4_0(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE),
-	    IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_SET, item, channel, volume);
-}
-
-/**
- * Get VOLUME LEVEL on an audio channel.
- * @param[in] exch IPC exchange connected to the device.
- * @param[in] item The control item controlling the channel.
- * @param[in] channel The channel index.
- * @param[out] volume_current Currently set VOLUME LEVEL.
- * @param[out] volume_max Maximum VOLUME LEVEL.
- * @return Error code.
- */
-int audio_mixer_channel_volume_get(async_exch_t *exch, unsigned item,
-    unsigned channel, unsigned *volume_current, unsigned *volume_max)
-{
-	if (!exch)
-		return EINVAL;
-	sysarg_t current, max;
-	const int ret = async_req_3_2(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE),
-	    IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_GET, item, channel,
-	    &current, &max);
-	if (ret == EOK && volume_current)
-		*volume_current = current;
-	if (ret == EOK && volume_max)
-		*volume_max = max;
+	sysarg_t current;
+	const int ret = async_req_2_1(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE),
+	    IPC_M_AUDIO_MIXER_GET_ITEM_LEVEL, item, &current);
+	if (ret == EOK && level)
+		*level = current;
 	return ret;
 }
@@ -314,9 +200,6 @@
 static void remote_audio_mixer_get_info(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_audio_mixer_get_item_info(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_audio_mixer_get_channel_info(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_audio_mixer_channel_mute_set(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_audio_mixer_channel_mute_get(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_audio_mixer_channel_volume_set(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_audio_mixer_channel_volume_get(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_audio_mixer_get_item_level(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_audio_mixer_set_item_level(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 
 /** Remote audio mixer interface operations. */
@@ -324,9 +207,6 @@
 	[IPC_M_AUDIO_MIXER_GET_INFO] = remote_audio_mixer_get_info,
 	[IPC_M_AUDIO_MIXER_GET_ITEM_INFO] = remote_audio_mixer_get_item_info,
-	[IPC_M_AUDIO_MIXER_GET_CHANNEL_INFO] = remote_audio_mixer_get_channel_info,
-	[IPC_M_AUDIO_MIXER_CHANNEL_MUTE_SET] = remote_audio_mixer_channel_mute_set,
-	[IPC_M_AUDIO_MIXER_CHANNEL_MUTE_GET] = remote_audio_mixer_channel_mute_get,
-	[IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_SET] = remote_audio_mixer_channel_volume_set,
-	[IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_GET] = remote_audio_mixer_channel_volume_get,
+	[IPC_M_AUDIO_MIXER_GET_ITEM_LEVEL] = remote_audio_mixer_get_item_level,
+	[IPC_M_AUDIO_MIXER_SET_ITEM_LEVEL] = remote_audio_mixer_set_item_level,
 };
 
@@ -380,8 +260,8 @@
 	const unsigned item = DEV_IPC_GET_ARG1(*call);
 	const char *name = NULL;
-	unsigned channels = 0;
-	const int ret = mixer_iface->get_item_info(fun, item, &name, &channels);
+	unsigned values = 0;
+	const int ret = mixer_iface->get_item_info(fun, item, &name, &values);
 	const size_t name_size = name ? str_size(name) + 1 : 0;
-	async_answer_2(callid, ret, name_size, channels);
+	async_answer_2(callid, ret, name_size, values);
 	/* Send the name. */
 	if (ret == EOK && name_size > 0) {
@@ -400,103 +280,33 @@
 }
 
-void remote_audio_mixer_get_channel_info(
+void remote_audio_mixer_set_item_level(
     ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
 {
 	audio_mixer_iface_t *mixer_iface = iface;
 
-	if (!mixer_iface->get_channel_info) {
+	if (!mixer_iface->set_item_level) {
 		async_answer_0(callid, ENOTSUP);
 		return;
 	}
-
 	const unsigned item = DEV_IPC_GET_ARG1(*call);
-	const unsigned channel = DEV_IPC_GET_ARG2(*call);
-	const char *name = NULL;
-	unsigned levels = 0;
-	const int ret =
-	    mixer_iface->get_channel_info(fun, item, channel, &name, &levels);
-	const size_t name_size = name ? str_size(name) + 1 : 0;
-	async_answer_2(callid, ret, name_size, levels);
-	/* Send the name. */
-	if (ret == EOK && name_size > 0) {
-		size_t size;
-		ipc_callid_t name_id;
-		if (!async_data_read_receive(&name_id, &size)) {
-			async_answer_0(name_id, EPARTY);
-			return;
-		}
-		if (size != name_size) {
-			async_answer_0(name_id, ELIMIT);
-			return;
-		}
-		async_data_read_finalize(name_id, name, name_size);
-	}
-}
-
-void remote_audio_mixer_channel_mute_set(
+	const unsigned value = DEV_IPC_GET_ARG2(*call);
+	const int ret = mixer_iface->set_item_level(fun, item, value);
+	async_answer_0(callid, ret);
+}
+
+void remote_audio_mixer_get_item_level(
     ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
 {
 	audio_mixer_iface_t *mixer_iface = iface;
 
-	if (!mixer_iface->channel_mute_set) {
+	if (!mixer_iface->get_item_level) {
 		async_answer_0(callid, ENOTSUP);
 		return;
 	}
 	const unsigned item = DEV_IPC_GET_ARG1(*call);
-	const unsigned channel = DEV_IPC_GET_ARG2(*call);
-	const bool mute = DEV_IPC_GET_ARG3(*call);
-	const int ret = mixer_iface->channel_mute_set(fun, item, channel, mute);
-	async_answer_0(callid, ret);
-}
-
-void remote_audio_mixer_channel_mute_get(
-    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
-{
-	audio_mixer_iface_t *mixer_iface = iface;
-
-	if (!mixer_iface->channel_mute_get) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-	const unsigned item = DEV_IPC_GET_ARG1(*call);
-	const unsigned channel = DEV_IPC_GET_ARG2(*call);
-	bool mute = false;
+	unsigned current = 0;
 	const int ret =
-	    mixer_iface->channel_mute_get(fun, item, channel, &mute);
-	async_answer_1(callid, ret, mute);
-}
-
-void remote_audio_mixer_channel_volume_set(
-    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
-{
-	audio_mixer_iface_t *mixer_iface = iface;
-
-	if (!mixer_iface->channel_volume_set) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-	const unsigned item = DEV_IPC_GET_ARG1(*call);
-	const unsigned channel = DEV_IPC_GET_ARG2(*call);
-	const unsigned level = DEV_IPC_GET_ARG3(*call);
-	const int ret =
-	    mixer_iface->channel_volume_set(fun, item, channel, level);
-	async_answer_0(callid, ret);
-}
-
-void remote_audio_mixer_channel_volume_get(
-    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
-{
-	audio_mixer_iface_t *mixer_iface = iface;
-
-	if (!mixer_iface->channel_volume_get) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-	const unsigned item = DEV_IPC_GET_ARG1(*call);
-	const unsigned channel = DEV_IPC_GET_ARG2(*call);
-	unsigned current = 0, max = 0;
-	const int ret =
-	    mixer_iface->channel_volume_get(fun, item, channel, &current, &max);
-	async_answer_2(callid, ret, current, max);
+	    mixer_iface->get_item_level(fun, item, &current);
+	async_answer_1(callid, ret, current);
 }
 
Index: uspace/lib/drv/include/audio_mixer_iface.h
===================================================================
--- uspace/lib/drv/include/audio_mixer_iface.h	(revision 8a7d78cce508b3191513ec7eee495006eb933f36)
+++ uspace/lib/drv/include/audio_mixer_iface.h	(revision 1912b4519763bcbb573d6ccbc668efc042d978fa)
@@ -46,12 +46,6 @@
 int audio_mixer_get_item_info(async_exch_t *, unsigned,
     const char **, unsigned *);
-int audio_mixer_get_channel_info(async_exch_t *, unsigned, unsigned,
-    const char **, unsigned *);
-int audio_mixer_channel_mute_set(async_exch_t *, unsigned, unsigned, bool);
-int audio_mixer_channel_mute_get(async_exch_t *, unsigned, unsigned, bool *);
-int audio_mixer_channel_volume_set(async_exch_t *, unsigned, unsigned,
-    unsigned);
-int audio_mixer_channel_volume_get(async_exch_t *, unsigned, unsigned,
-    unsigned *, unsigned *);
+int audio_mixer_get_item_level(async_exch_t *, unsigned, unsigned *);
+int audio_mixer_set_item_level(async_exch_t *, unsigned, unsigned);
 
 
@@ -60,11 +54,6 @@
 	int (*get_info)(ddf_fun_t *, const char **, unsigned *);
 	int (*get_item_info)(ddf_fun_t *, unsigned, const char **, unsigned *);
-	int (*get_channel_info)(ddf_fun_t *, unsigned, unsigned,
-	    const char **, unsigned *);
-	int (*channel_mute_set)(ddf_fun_t *, unsigned, unsigned, bool);
-	int (*channel_mute_get)(ddf_fun_t *, unsigned, unsigned, bool *);
-	int (*channel_volume_set)(ddf_fun_t *, unsigned, unsigned, unsigned);
-	int (*channel_volume_get)(ddf_fun_t *, unsigned, unsigned,
-	    unsigned *, unsigned *);
+	int (*get_item_level)(ddf_fun_t *, unsigned, unsigned *);
+	int (*set_item_level)(ddf_fun_t *, unsigned, unsigned);
 } audio_mixer_iface_t;
 
