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