1ad9697baSTakashi Sakamoto /* 2ad9697baSTakashi Sakamoto * bebob_proc.c - a part of driver for BeBoB based devices 3ad9697baSTakashi Sakamoto * 4ad9697baSTakashi Sakamoto * Copyright (c) 2013-2014 Takashi Sakamoto 5ad9697baSTakashi Sakamoto * 6ad9697baSTakashi Sakamoto * Licensed under the terms of the GNU General Public License, version 2. 7ad9697baSTakashi Sakamoto */ 8ad9697baSTakashi Sakamoto 9ad9697baSTakashi Sakamoto #include "./bebob.h" 10ad9697baSTakashi Sakamoto 11ad9697baSTakashi Sakamoto /* contents of information register */ 12ad9697baSTakashi Sakamoto struct hw_info { 13ad9697baSTakashi Sakamoto u64 manufacturer; 14ad9697baSTakashi Sakamoto u32 protocol_ver; 15ad9697baSTakashi Sakamoto u32 bld_ver; 16ad9697baSTakashi Sakamoto u32 guid[2]; 17ad9697baSTakashi Sakamoto u32 model_id; 18ad9697baSTakashi Sakamoto u32 model_rev; 19ad9697baSTakashi Sakamoto u64 fw_date; 20ad9697baSTakashi Sakamoto u64 fw_time; 21ad9697baSTakashi Sakamoto u32 fw_id; 22ad9697baSTakashi Sakamoto u32 fw_ver; 23ad9697baSTakashi Sakamoto u32 base_addr; 24ad9697baSTakashi Sakamoto u32 max_size; 25ad9697baSTakashi Sakamoto u64 bld_date; 26ad9697baSTakashi Sakamoto u64 bld_time; 27ad9697baSTakashi Sakamoto /* may not used in product 28ad9697baSTakashi Sakamoto u64 dbg_date; 29ad9697baSTakashi Sakamoto u64 dbg_time; 30ad9697baSTakashi Sakamoto u32 dbg_id; 31ad9697baSTakashi Sakamoto u32 dbg_version; 32ad9697baSTakashi Sakamoto */ 33ad9697baSTakashi Sakamoto } __packed; 34ad9697baSTakashi Sakamoto 35ad9697baSTakashi Sakamoto static void 36ad9697baSTakashi Sakamoto proc_read_hw_info(struct snd_info_entry *entry, 37ad9697baSTakashi Sakamoto struct snd_info_buffer *buffer) 38ad9697baSTakashi Sakamoto { 39ad9697baSTakashi Sakamoto struct snd_bebob *bebob = entry->private_data; 40ad9697baSTakashi Sakamoto struct hw_info *info; 41ad9697baSTakashi Sakamoto 42ad9697baSTakashi Sakamoto info = kzalloc(sizeof(struct hw_info), GFP_KERNEL); 43ad9697baSTakashi Sakamoto if (info == NULL) 44ad9697baSTakashi Sakamoto return; 45ad9697baSTakashi Sakamoto 46ad9697baSTakashi Sakamoto if (snd_bebob_read_block(bebob->unit, 0, 47ad9697baSTakashi Sakamoto info, sizeof(struct hw_info)) < 0) 48ad9697baSTakashi Sakamoto goto end; 49ad9697baSTakashi Sakamoto 50ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Manufacturer:\t%.8s\n", 51ad9697baSTakashi Sakamoto (char *)&info->manufacturer); 52ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Protocol Ver:\t%d\n", info->protocol_ver); 53ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Build Ver:\t%d\n", info->bld_ver); 54ad9697baSTakashi Sakamoto snd_iprintf(buffer, "GUID:\t\t0x%.8X%.8X\n", 55ad9697baSTakashi Sakamoto info->guid[0], info->guid[1]); 56ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Model ID:\t0x%02X\n", info->model_id); 57ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Model Rev:\t%d\n", info->model_rev); 58ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Firmware Date:\t%.8s\n", (char *)&info->fw_date); 59ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Firmware Time:\t%.8s\n", (char *)&info->fw_time); 60ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Firmware ID:\t0x%X\n", info->fw_id); 61ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Firmware Ver:\t%d\n", info->fw_ver); 62ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Base Addr:\t0x%X\n", info->base_addr); 63ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Max Size:\t%d\n", info->max_size); 64ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Loader Date:\t%.8s\n", (char *)&info->bld_date); 65ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Loader Time:\t%.8s\n", (char *)&info->bld_time); 66ad9697baSTakashi Sakamoto 67ad9697baSTakashi Sakamoto end: 68ad9697baSTakashi Sakamoto kfree(info); 69ad9697baSTakashi Sakamoto } 70ad9697baSTakashi Sakamoto 71ad9697baSTakashi Sakamoto static void 721fc9522aSTakashi Sakamoto proc_read_meters(struct snd_info_entry *entry, 731fc9522aSTakashi Sakamoto struct snd_info_buffer *buffer) 741fc9522aSTakashi Sakamoto { 751fc9522aSTakashi Sakamoto struct snd_bebob *bebob = entry->private_data; 766b9866c8SJulia Lawall const struct snd_bebob_meter_spec *spec = bebob->spec->meter; 771fc9522aSTakashi Sakamoto u32 *buf; 781fc9522aSTakashi Sakamoto unsigned int i, c, channels, size; 791fc9522aSTakashi Sakamoto 801fc9522aSTakashi Sakamoto if (spec == NULL) 811fc9522aSTakashi Sakamoto return; 821fc9522aSTakashi Sakamoto 831fc9522aSTakashi Sakamoto channels = spec->num * 2; 841fc9522aSTakashi Sakamoto size = channels * sizeof(u32); 851fc9522aSTakashi Sakamoto buf = kmalloc(size, GFP_KERNEL); 861fc9522aSTakashi Sakamoto if (buf == NULL) 871fc9522aSTakashi Sakamoto return; 881fc9522aSTakashi Sakamoto 891fc9522aSTakashi Sakamoto if (spec->get(bebob, buf, size) < 0) 901fc9522aSTakashi Sakamoto goto end; 911fc9522aSTakashi Sakamoto 921fc9522aSTakashi Sakamoto for (i = 0, c = 1; i < channels; i++) { 931fc9522aSTakashi Sakamoto snd_iprintf(buffer, "%s %d:\t%d\n", 941fc9522aSTakashi Sakamoto spec->labels[i / 2], c++, buf[i]); 951fc9522aSTakashi Sakamoto if ((i + 1 < channels - 1) && 961fc9522aSTakashi Sakamoto (strcmp(spec->labels[i / 2], 971fc9522aSTakashi Sakamoto spec->labels[(i + 1) / 2]) != 0)) 981fc9522aSTakashi Sakamoto c = 1; 991fc9522aSTakashi Sakamoto } 1001fc9522aSTakashi Sakamoto end: 1011fc9522aSTakashi Sakamoto kfree(buf); 1021fc9522aSTakashi Sakamoto } 1031fc9522aSTakashi Sakamoto 1041fc9522aSTakashi Sakamoto static void 105ad9697baSTakashi Sakamoto proc_read_formation(struct snd_info_entry *entry, 106ad9697baSTakashi Sakamoto struct snd_info_buffer *buffer) 107ad9697baSTakashi Sakamoto { 108ad9697baSTakashi Sakamoto struct snd_bebob *bebob = entry->private_data; 109ad9697baSTakashi Sakamoto struct snd_bebob_stream_formation *formation; 110ad9697baSTakashi Sakamoto unsigned int i; 111ad9697baSTakashi Sakamoto 112ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Output Stream from device:\n"); 113ad9697baSTakashi Sakamoto snd_iprintf(buffer, "\tRate\tPCM\tMIDI\n"); 114ad9697baSTakashi Sakamoto formation = bebob->tx_stream_formations; 115ad9697baSTakashi Sakamoto for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; i++) { 116ad9697baSTakashi Sakamoto snd_iprintf(buffer, 117ad9697baSTakashi Sakamoto "\t%d\t%d\t%d\n", snd_bebob_rate_table[i], 118ad9697baSTakashi Sakamoto formation[i].pcm, formation[i].midi); 119ad9697baSTakashi Sakamoto } 120ad9697baSTakashi Sakamoto 121ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Input Stream to device:\n"); 122ad9697baSTakashi Sakamoto snd_iprintf(buffer, "\tRate\tPCM\tMIDI\n"); 123ad9697baSTakashi Sakamoto formation = bebob->rx_stream_formations; 124ad9697baSTakashi Sakamoto for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; i++) { 125ad9697baSTakashi Sakamoto snd_iprintf(buffer, 126ad9697baSTakashi Sakamoto "\t%d\t%d\t%d\n", snd_bebob_rate_table[i], 127ad9697baSTakashi Sakamoto formation[i].pcm, formation[i].midi); 128ad9697baSTakashi Sakamoto } 129ad9697baSTakashi Sakamoto } 130ad9697baSTakashi Sakamoto 131ad9697baSTakashi Sakamoto static void 132ad9697baSTakashi Sakamoto proc_read_clock(struct snd_info_entry *entry, 133ad9697baSTakashi Sakamoto struct snd_info_buffer *buffer) 134ad9697baSTakashi Sakamoto { 1353e254b16STakashi Sakamoto static const char *const clk_labels[] = { 1363e254b16STakashi Sakamoto "Internal", 1373e254b16STakashi Sakamoto "External", 1383e254b16STakashi Sakamoto "SYT-Match", 1393e254b16STakashi Sakamoto }; 140ad9697baSTakashi Sakamoto struct snd_bebob *bebob = entry->private_data; 1416b9866c8SJulia Lawall const struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate; 1426b9866c8SJulia Lawall const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; 1433e254b16STakashi Sakamoto enum snd_bebob_clock_type src; 1443e254b16STakashi Sakamoto unsigned int rate; 145ad9697baSTakashi Sakamoto 1461fc9522aSTakashi Sakamoto if (rate_spec->get(bebob, &rate) >= 0) 147ad9697baSTakashi Sakamoto snd_iprintf(buffer, "Sampling rate: %d\n", rate); 148ad9697baSTakashi Sakamoto 1493e254b16STakashi Sakamoto if (snd_bebob_stream_get_clock_src(bebob, &src) >= 0) { 1503e254b16STakashi Sakamoto if (clk_spec) 1511fc9522aSTakashi Sakamoto snd_iprintf(buffer, "Clock Source: %s\n", 1523e254b16STakashi Sakamoto clk_labels[src]); 1533e254b16STakashi Sakamoto else 1541fc9522aSTakashi Sakamoto snd_iprintf(buffer, "Clock Source: %s (MSU-dest: %d)\n", 1553e254b16STakashi Sakamoto clk_labels[src], bebob->sync_input_plug); 156ad9697baSTakashi Sakamoto } 1571fc9522aSTakashi Sakamoto } 158ad9697baSTakashi Sakamoto 159ad9697baSTakashi Sakamoto static void 160ad9697baSTakashi Sakamoto add_node(struct snd_bebob *bebob, struct snd_info_entry *root, const char *name, 161ad9697baSTakashi Sakamoto void (*op)(struct snd_info_entry *e, struct snd_info_buffer *b)) 162ad9697baSTakashi Sakamoto { 163ad9697baSTakashi Sakamoto struct snd_info_entry *entry; 164ad9697baSTakashi Sakamoto 165ad9697baSTakashi Sakamoto entry = snd_info_create_card_entry(bebob->card, name, root); 1660c298bdcSTakashi Iwai if (entry) 167ad9697baSTakashi Sakamoto snd_info_set_text_ops(entry, bebob, op); 168ad9697baSTakashi Sakamoto } 169ad9697baSTakashi Sakamoto 170ad9697baSTakashi Sakamoto void snd_bebob_proc_init(struct snd_bebob *bebob) 171ad9697baSTakashi Sakamoto { 172ad9697baSTakashi Sakamoto struct snd_info_entry *root; 173ad9697baSTakashi Sakamoto 174ad9697baSTakashi Sakamoto /* 175ad9697baSTakashi Sakamoto * All nodes are automatically removed at snd_card_disconnect(), 176ad9697baSTakashi Sakamoto * by following to link list. 177ad9697baSTakashi Sakamoto */ 178ad9697baSTakashi Sakamoto root = snd_info_create_card_entry(bebob->card, "firewire", 179ad9697baSTakashi Sakamoto bebob->card->proc_root); 180ad9697baSTakashi Sakamoto if (root == NULL) 181ad9697baSTakashi Sakamoto return; 1826a73cf46SJoe Perches root->mode = S_IFDIR | 0555; 183ad9697baSTakashi Sakamoto 184ad9697baSTakashi Sakamoto add_node(bebob, root, "clock", proc_read_clock); 185ad9697baSTakashi Sakamoto add_node(bebob, root, "firmware", proc_read_hw_info); 186ad9697baSTakashi Sakamoto add_node(bebob, root, "formation", proc_read_formation); 1871fc9522aSTakashi Sakamoto 1881fc9522aSTakashi Sakamoto if (bebob->spec->meter != NULL) 1891fc9522aSTakashi Sakamoto add_node(bebob, root, "meter", proc_read_meters); 190ad9697baSTakashi Sakamoto } 191