From 1fc9522a084f36d042298ef15893cf07d66a54bc Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Fri, 25 Apr 2014 22:45:21 +0900 Subject: ALSA: bebob: Prepare for device specific operations This commit is for some devices which have its own operations or quirks. Many functionality should be implemented in user land. Then this commit adds functionality related to stream such as sampling frequency or clock source. For help to debug, this commit adds the functionality to get metering information if it's available. To help these functionalities, this commit adds some AV/C commands defined in 'AV/C Audio Subunit Specification (1394TA). Signed-off-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/firewire/bebob/bebob_proc.c | 57 ++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 6 deletions(-) (limited to 'sound/firewire/bebob/bebob_proc.c') diff --git a/sound/firewire/bebob/bebob_proc.c b/sound/firewire/bebob/bebob_proc.c index c31ca4f42a58..335da64506e0 100644 --- a/sound/firewire/bebob/bebob_proc.c +++ b/sound/firewire/bebob/bebob_proc.c @@ -68,6 +68,39 @@ end: kfree(info); } +static void +proc_read_meters(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct snd_bebob *bebob = entry->private_data; + struct snd_bebob_meter_spec *spec = bebob->spec->meter; + u32 *buf; + unsigned int i, c, channels, size; + + if (spec == NULL) + return; + + channels = spec->num * 2; + size = channels * sizeof(u32); + buf = kmalloc(size, GFP_KERNEL); + if (buf == NULL) + return; + + if (spec->get(bebob, buf, size) < 0) + goto end; + + for (i = 0, c = 1; i < channels; i++) { + snd_iprintf(buffer, "%s %d:\t%d\n", + spec->labels[i / 2], c++, buf[i]); + if ((i + 1 < channels - 1) && + (strcmp(spec->labels[i / 2], + spec->labels[(i + 1) / 2]) != 0)) + c = 1; + } +end: + kfree(buf); +} + static void proc_read_formation(struct snd_info_entry *entry, struct snd_info_buffer *buffer) @@ -100,16 +133,25 @@ proc_read_clock(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct snd_bebob *bebob = entry->private_data; - unsigned int rate; + struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate; + struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; + unsigned int rate, id; bool internal; - if (snd_bebob_stream_get_rate(bebob, &rate) >= 0) + if (rate_spec->get(bebob, &rate) >= 0) snd_iprintf(buffer, "Sampling rate: %d\n", rate); - if (snd_bebob_stream_check_internal_clock(bebob, &internal) >= 0) - snd_iprintf(buffer, "Clock Source: %s (MSU-dest: %d)", - (internal) ? "Internal" : "External", - bebob->sync_input_plug); + if (clk_spec) { + if (clk_spec->get(bebob, &id) >= 0) + snd_iprintf(buffer, "Clock Source: %s\n", + clk_spec->labels[id]); + } else { + if (snd_bebob_stream_check_internal_clock(bebob, + &internal) >= 0) + snd_iprintf(buffer, "Clock Source: %s (MSU-dest: %d)\n", + (internal) ? "Internal" : "External", + bebob->sync_input_plug); + } } static void @@ -148,4 +190,7 @@ void snd_bebob_proc_init(struct snd_bebob *bebob) add_node(bebob, root, "clock", proc_read_clock); add_node(bebob, root, "firmware", proc_read_hw_info); add_node(bebob, root, "formation", proc_read_formation); + + if (bebob->spec->meter != NULL) + add_node(bebob, root, "meter", proc_read_meters); } -- cgit v1.2.3