0001
0002
0003
0004
0005
0006
0007
0008 #include "./bebob.h"
0009
0010
0011 struct hw_info {
0012 u64 manufacturer;
0013 u32 protocol_ver;
0014 u32 bld_ver;
0015 u32 guid[2];
0016 u32 model_id;
0017 u32 model_rev;
0018 u64 fw_date;
0019 u64 fw_time;
0020 u32 fw_id;
0021 u32 fw_ver;
0022 u32 base_addr;
0023 u32 max_size;
0024 u64 bld_date;
0025 u64 bld_time;
0026
0027
0028
0029
0030
0031
0032 } __packed;
0033
0034 static void
0035 proc_read_hw_info(struct snd_info_entry *entry,
0036 struct snd_info_buffer *buffer)
0037 {
0038 struct snd_bebob *bebob = entry->private_data;
0039 struct hw_info *info;
0040
0041 info = kzalloc(sizeof(struct hw_info), GFP_KERNEL);
0042 if (info == NULL)
0043 return;
0044
0045 if (snd_bebob_read_block(bebob->unit, 0,
0046 info, sizeof(struct hw_info)) < 0)
0047 goto end;
0048
0049 snd_iprintf(buffer, "Manufacturer:\t%.8s\n",
0050 (char *)&info->manufacturer);
0051 snd_iprintf(buffer, "Protocol Ver:\t%d\n", info->protocol_ver);
0052 snd_iprintf(buffer, "Build Ver:\t%d\n", info->bld_ver);
0053 snd_iprintf(buffer, "GUID:\t\t0x%.8X%.8X\n",
0054 info->guid[0], info->guid[1]);
0055 snd_iprintf(buffer, "Model ID:\t0x%02X\n", info->model_id);
0056 snd_iprintf(buffer, "Model Rev:\t%d\n", info->model_rev);
0057 snd_iprintf(buffer, "Firmware Date:\t%.8s\n", (char *)&info->fw_date);
0058 snd_iprintf(buffer, "Firmware Time:\t%.8s\n", (char *)&info->fw_time);
0059 snd_iprintf(buffer, "Firmware ID:\t0x%X\n", info->fw_id);
0060 snd_iprintf(buffer, "Firmware Ver:\t%d\n", info->fw_ver);
0061 snd_iprintf(buffer, "Base Addr:\t0x%X\n", info->base_addr);
0062 snd_iprintf(buffer, "Max Size:\t%d\n", info->max_size);
0063 snd_iprintf(buffer, "Loader Date:\t%.8s\n", (char *)&info->bld_date);
0064 snd_iprintf(buffer, "Loader Time:\t%.8s\n", (char *)&info->bld_time);
0065
0066 end:
0067 kfree(info);
0068 }
0069
0070 static void
0071 proc_read_meters(struct snd_info_entry *entry,
0072 struct snd_info_buffer *buffer)
0073 {
0074 struct snd_bebob *bebob = entry->private_data;
0075 const struct snd_bebob_meter_spec *spec = bebob->spec->meter;
0076 u32 *buf;
0077 unsigned int i, c, channels, size;
0078
0079 if (spec == NULL)
0080 return;
0081
0082 channels = spec->num * 2;
0083 size = channels * sizeof(u32);
0084 buf = kmalloc(size, GFP_KERNEL);
0085 if (buf == NULL)
0086 return;
0087
0088 if (spec->get(bebob, buf, size) < 0)
0089 goto end;
0090
0091 for (i = 0, c = 1; i < channels; i++) {
0092 snd_iprintf(buffer, "%s %d:\t%d\n",
0093 spec->labels[i / 2], c++, buf[i]);
0094 if ((i + 1 < channels - 1) &&
0095 (strcmp(spec->labels[i / 2],
0096 spec->labels[(i + 1) / 2]) != 0))
0097 c = 1;
0098 }
0099 end:
0100 kfree(buf);
0101 }
0102
0103 static void
0104 proc_read_formation(struct snd_info_entry *entry,
0105 struct snd_info_buffer *buffer)
0106 {
0107 struct snd_bebob *bebob = entry->private_data;
0108 struct snd_bebob_stream_formation *formation;
0109 unsigned int i;
0110
0111 snd_iprintf(buffer, "Output Stream from device:\n");
0112 snd_iprintf(buffer, "\tRate\tPCM\tMIDI\n");
0113 formation = bebob->tx_stream_formations;
0114 for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; i++) {
0115 snd_iprintf(buffer,
0116 "\t%d\t%d\t%d\n", snd_bebob_rate_table[i],
0117 formation[i].pcm, formation[i].midi);
0118 }
0119
0120 snd_iprintf(buffer, "Input Stream to device:\n");
0121 snd_iprintf(buffer, "\tRate\tPCM\tMIDI\n");
0122 formation = bebob->rx_stream_formations;
0123 for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; i++) {
0124 snd_iprintf(buffer,
0125 "\t%d\t%d\t%d\n", snd_bebob_rate_table[i],
0126 formation[i].pcm, formation[i].midi);
0127 }
0128 }
0129
0130 static void
0131 proc_read_clock(struct snd_info_entry *entry,
0132 struct snd_info_buffer *buffer)
0133 {
0134 static const char *const clk_labels[] = {
0135 "Internal",
0136 "External",
0137 "SYT-Match",
0138 };
0139 struct snd_bebob *bebob = entry->private_data;
0140 const struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate;
0141 const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
0142 enum snd_bebob_clock_type src;
0143 unsigned int rate;
0144
0145 if (rate_spec->get(bebob, &rate) >= 0)
0146 snd_iprintf(buffer, "Sampling rate: %d\n", rate);
0147
0148 if (snd_bebob_stream_get_clock_src(bebob, &src) >= 0) {
0149 if (clk_spec)
0150 snd_iprintf(buffer, "Clock Source: %s\n",
0151 clk_labels[src]);
0152 else
0153 snd_iprintf(buffer, "Clock Source: %s (MSU-dest: %d)\n",
0154 clk_labels[src], bebob->sync_input_plug);
0155 }
0156 }
0157
0158 static void
0159 add_node(struct snd_bebob *bebob, struct snd_info_entry *root, const char *name,
0160 void (*op)(struct snd_info_entry *e, struct snd_info_buffer *b))
0161 {
0162 struct snd_info_entry *entry;
0163
0164 entry = snd_info_create_card_entry(bebob->card, name, root);
0165 if (entry)
0166 snd_info_set_text_ops(entry, bebob, op);
0167 }
0168
0169 void snd_bebob_proc_init(struct snd_bebob *bebob)
0170 {
0171 struct snd_info_entry *root;
0172
0173
0174
0175
0176
0177 root = snd_info_create_card_entry(bebob->card, "firewire",
0178 bebob->card->proc_root);
0179 if (root == NULL)
0180 return;
0181 root->mode = S_IFDIR | 0555;
0182
0183 add_node(bebob, root, "clock", proc_read_clock);
0184 add_node(bebob, root, "firmware", proc_read_hw_info);
0185 add_node(bebob, root, "formation", proc_read_formation);
0186
0187 if (bebob->spec->meter != NULL)
0188 add_node(bebob, root, "meter", proc_read_meters);
0189 }