18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * digi00x-proc.c - a part of driver for Digidesign Digi 002/003 family 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2014-2015 Takashi Sakamoto 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include "digi00x.h" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_cistatic int get_optical_iface_mode(struct snd_dg00x *dg00x, 118c2ecf20Sopenharmony_ci enum snd_dg00x_optical_mode *mode) 128c2ecf20Sopenharmony_ci{ 138c2ecf20Sopenharmony_ci __be32 data; 148c2ecf20Sopenharmony_ci int err; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, 178c2ecf20Sopenharmony_ci DG00X_ADDR_BASE + DG00X_OFFSET_OPT_IFACE_MODE, 188c2ecf20Sopenharmony_ci &data, sizeof(data), 0); 198c2ecf20Sopenharmony_ci if (err >= 0) 208c2ecf20Sopenharmony_ci *mode = be32_to_cpu(data) & 0x01; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci return err; 238c2ecf20Sopenharmony_ci} 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic void proc_read_clock(struct snd_info_entry *entry, 268c2ecf20Sopenharmony_ci struct snd_info_buffer *buf) 278c2ecf20Sopenharmony_ci{ 288c2ecf20Sopenharmony_ci static const char *const source_name[] = { 298c2ecf20Sopenharmony_ci [SND_DG00X_CLOCK_INTERNAL] = "internal", 308c2ecf20Sopenharmony_ci [SND_DG00X_CLOCK_SPDIF] = "s/pdif", 318c2ecf20Sopenharmony_ci [SND_DG00X_CLOCK_ADAT] = "adat", 328c2ecf20Sopenharmony_ci [SND_DG00X_CLOCK_WORD] = "word clock", 338c2ecf20Sopenharmony_ci }; 348c2ecf20Sopenharmony_ci static const char *const optical_name[] = { 358c2ecf20Sopenharmony_ci [SND_DG00X_OPT_IFACE_MODE_ADAT] = "adat", 368c2ecf20Sopenharmony_ci [SND_DG00X_OPT_IFACE_MODE_SPDIF] = "s/pdif", 378c2ecf20Sopenharmony_ci }; 388c2ecf20Sopenharmony_ci struct snd_dg00x *dg00x = entry->private_data; 398c2ecf20Sopenharmony_ci enum snd_dg00x_optical_mode mode; 408c2ecf20Sopenharmony_ci unsigned int rate; 418c2ecf20Sopenharmony_ci enum snd_dg00x_clock clock; 428c2ecf20Sopenharmony_ci bool detect; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci if (get_optical_iface_mode(dg00x, &mode) < 0) 458c2ecf20Sopenharmony_ci return; 468c2ecf20Sopenharmony_ci if (snd_dg00x_stream_get_local_rate(dg00x, &rate) < 0) 478c2ecf20Sopenharmony_ci return; 488c2ecf20Sopenharmony_ci if (snd_dg00x_stream_get_clock(dg00x, &clock) < 0) 498c2ecf20Sopenharmony_ci return; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci snd_iprintf(buf, "Optical mode: %s\n", optical_name[mode]); 528c2ecf20Sopenharmony_ci snd_iprintf(buf, "Sampling Rate: %d\n", rate); 538c2ecf20Sopenharmony_ci snd_iprintf(buf, "Clock Source: %s\n", source_name[clock]); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci if (clock == SND_DG00X_CLOCK_INTERNAL) 568c2ecf20Sopenharmony_ci return; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci if (snd_dg00x_stream_check_external_clock(dg00x, &detect) < 0) 598c2ecf20Sopenharmony_ci return; 608c2ecf20Sopenharmony_ci snd_iprintf(buf, "External source: %s\n", detect ? "detected" : "not"); 618c2ecf20Sopenharmony_ci if (!detect) 628c2ecf20Sopenharmony_ci return; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci if (snd_dg00x_stream_get_external_rate(dg00x, &rate) >= 0) 658c2ecf20Sopenharmony_ci snd_iprintf(buf, "External sampling rate: %d\n", rate); 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_civoid snd_dg00x_proc_init(struct snd_dg00x *dg00x) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci struct snd_info_entry *root, *entry; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci /* 738c2ecf20Sopenharmony_ci * All nodes are automatically removed at snd_card_disconnect(), 748c2ecf20Sopenharmony_ci * by following to link list. 758c2ecf20Sopenharmony_ci */ 768c2ecf20Sopenharmony_ci root = snd_info_create_card_entry(dg00x->card, "firewire", 778c2ecf20Sopenharmony_ci dg00x->card->proc_root); 788c2ecf20Sopenharmony_ci if (root == NULL) 798c2ecf20Sopenharmony_ci return; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci root->mode = S_IFDIR | 0555; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci entry = snd_info_create_card_entry(dg00x->card, "clock", root); 848c2ecf20Sopenharmony_ci if (entry) 858c2ecf20Sopenharmony_ci snd_info_set_text_ops(entry, dg00x, proc_read_clock); 868c2ecf20Sopenharmony_ci} 87