1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * oxfw_proc.c - a part of driver for OXFW970/971 based devices
4 *
5 * Copyright (c) 2014 Takashi Sakamoto
6 */
7
8 #include "./oxfw.h"
9
proc_read_formation(struct snd_info_entry * entry,struct snd_info_buffer * buffer)10 static void proc_read_formation(struct snd_info_entry *entry,
11 struct snd_info_buffer *buffer)
12 {
13 struct snd_oxfw *oxfw = entry->private_data;
14 struct snd_oxfw_stream_formation formation, curr;
15 u8 *format;
16 char flag;
17 int i, err;
18
19 /* Show input. */
20 err = snd_oxfw_stream_get_current_formation(oxfw,
21 AVC_GENERAL_PLUG_DIR_IN,
22 &curr);
23 if (err < 0)
24 return;
25
26 snd_iprintf(buffer, "Input Stream to device:\n");
27 snd_iprintf(buffer, "\tRate\tPCM\tMIDI\n");
28 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
29 format = oxfw->rx_stream_formats[i];
30 if (format == NULL)
31 continue;
32
33 err = snd_oxfw_stream_parse_format(format, &formation);
34 if (err < 0)
35 continue;
36
37 if (memcmp(&formation, &curr, sizeof(curr)) == 0)
38 flag = '*';
39 else
40 flag = ' ';
41
42 snd_iprintf(buffer, "%c\t%d\t%d\t%d\n", flag,
43 formation.rate, formation.pcm, formation.midi);
44 }
45
46 if (!oxfw->has_output)
47 return;
48
49 /* Show output. */
50 err = snd_oxfw_stream_get_current_formation(oxfw,
51 AVC_GENERAL_PLUG_DIR_OUT,
52 &curr);
53 if (err < 0)
54 return;
55
56 snd_iprintf(buffer, "Output Stream from device:\n");
57 snd_iprintf(buffer, "\tRate\tPCM\tMIDI\n");
58 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
59 format = oxfw->tx_stream_formats[i];
60 if (format == NULL)
61 continue;
62
63 err = snd_oxfw_stream_parse_format(format, &formation);
64 if (err < 0)
65 continue;
66
67 if (memcmp(&formation, &curr, sizeof(curr)) == 0)
68 flag = '*';
69 else
70 flag = ' ';
71
72 snd_iprintf(buffer, "%c\t%d\t%d\t%d\n", flag,
73 formation.rate, formation.pcm, formation.midi);
74 }
75 }
76
add_node(struct snd_oxfw * oxfw,struct snd_info_entry * root,const char * name,void (* op)(struct snd_info_entry * e,struct snd_info_buffer * b))77 static void add_node(struct snd_oxfw *oxfw, struct snd_info_entry *root,
78 const char *name,
79 void (*op)(struct snd_info_entry *e,
80 struct snd_info_buffer *b))
81 {
82 struct snd_info_entry *entry;
83
84 entry = snd_info_create_card_entry(oxfw->card, name, root);
85 if (entry)
86 snd_info_set_text_ops(entry, oxfw, op);
87 }
88
snd_oxfw_proc_init(struct snd_oxfw * oxfw)89 void snd_oxfw_proc_init(struct snd_oxfw *oxfw)
90 {
91 struct snd_info_entry *root;
92
93 /*
94 * All nodes are automatically removed at snd_card_disconnect(),
95 * by following to link list.
96 */
97 root = snd_info_create_card_entry(oxfw->card, "firewire",
98 oxfw->card->proc_root);
99 if (root == NULL)
100 return;
101 root->mode = S_IFDIR | 0555;
102
103 add_node(oxfw, root, "formation", proc_read_formation);
104 }
105