summaryrefslogtreecommitdiffstats
path: root/sound/firewire/bebob/bebob_proc.c
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2014-04-25 22:45:21 +0900
committerTakashi Iwai <tiwai@suse.de>2014-05-26 14:31:15 +0200
commit1fc9522a084f36d042298ef15893cf07d66a54bc (patch)
tree7fe03c4b4b01fdc53ea9f8a98fae2add483ea373 /sound/firewire/bebob/bebob_proc.c
parent618eabeae711c56d376daa147c6a684116d68705 (diff)
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 <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire/bebob/bebob_proc.c')
-rw-r--r--sound/firewire/bebob/bebob_proc.c57
1 files changed, 51 insertions, 6 deletions
diff --git a/sound/firewire/bebob/bebob_proc.c b/sound/firewire/bebob/bebob_proc.c
index c31ca4f42a5..335da64506e 100644
--- a/sound/firewire/bebob/bebob_proc.c
+++ b/sound/firewire/bebob/bebob_proc.c
@@ -69,6 +69,39 @@ end:
}
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);
}