162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * digi00x-proc.c - a part of driver for Digidesign Digi 002/003 family 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2014-2015 Takashi Sakamoto 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include "digi00x.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_cistatic int get_optical_iface_mode(struct snd_dg00x *dg00x, 1162306a36Sopenharmony_ci enum snd_dg00x_optical_mode *mode) 1262306a36Sopenharmony_ci{ 1362306a36Sopenharmony_ci __be32 data; 1462306a36Sopenharmony_ci int err; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, 1762306a36Sopenharmony_ci DG00X_ADDR_BASE + DG00X_OFFSET_OPT_IFACE_MODE, 1862306a36Sopenharmony_ci &data, sizeof(data), 0); 1962306a36Sopenharmony_ci if (err >= 0) 2062306a36Sopenharmony_ci *mode = be32_to_cpu(data) & 0x01; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci return err; 2362306a36Sopenharmony_ci} 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic void proc_read_clock(struct snd_info_entry *entry, 2662306a36Sopenharmony_ci struct snd_info_buffer *buf) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci static const char *const source_name[] = { 2962306a36Sopenharmony_ci [SND_DG00X_CLOCK_INTERNAL] = "internal", 3062306a36Sopenharmony_ci [SND_DG00X_CLOCK_SPDIF] = "s/pdif", 3162306a36Sopenharmony_ci [SND_DG00X_CLOCK_ADAT] = "adat", 3262306a36Sopenharmony_ci [SND_DG00X_CLOCK_WORD] = "word clock", 3362306a36Sopenharmony_ci }; 3462306a36Sopenharmony_ci static const char *const optical_name[] = { 3562306a36Sopenharmony_ci [SND_DG00X_OPT_IFACE_MODE_ADAT] = "adat", 3662306a36Sopenharmony_ci [SND_DG00X_OPT_IFACE_MODE_SPDIF] = "s/pdif", 3762306a36Sopenharmony_ci }; 3862306a36Sopenharmony_ci struct snd_dg00x *dg00x = entry->private_data; 3962306a36Sopenharmony_ci enum snd_dg00x_optical_mode mode; 4062306a36Sopenharmony_ci unsigned int rate; 4162306a36Sopenharmony_ci enum snd_dg00x_clock clock; 4262306a36Sopenharmony_ci bool detect; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci if (get_optical_iface_mode(dg00x, &mode) < 0) 4562306a36Sopenharmony_ci return; 4662306a36Sopenharmony_ci if (snd_dg00x_stream_get_local_rate(dg00x, &rate) < 0) 4762306a36Sopenharmony_ci return; 4862306a36Sopenharmony_ci if (snd_dg00x_stream_get_clock(dg00x, &clock) < 0) 4962306a36Sopenharmony_ci return; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci snd_iprintf(buf, "Optical mode: %s\n", optical_name[mode]); 5262306a36Sopenharmony_ci snd_iprintf(buf, "Sampling Rate: %d\n", rate); 5362306a36Sopenharmony_ci snd_iprintf(buf, "Clock Source: %s\n", source_name[clock]); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci if (clock == SND_DG00X_CLOCK_INTERNAL) 5662306a36Sopenharmony_ci return; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci if (snd_dg00x_stream_check_external_clock(dg00x, &detect) < 0) 5962306a36Sopenharmony_ci return; 6062306a36Sopenharmony_ci snd_iprintf(buf, "External source: %s\n", detect ? "detected" : "not"); 6162306a36Sopenharmony_ci if (!detect) 6262306a36Sopenharmony_ci return; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci if (snd_dg00x_stream_get_external_rate(dg00x, &rate) >= 0) 6562306a36Sopenharmony_ci snd_iprintf(buf, "External sampling rate: %d\n", rate); 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_civoid snd_dg00x_proc_init(struct snd_dg00x *dg00x) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci struct snd_info_entry *root, *entry; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci /* 7362306a36Sopenharmony_ci * All nodes are automatically removed at snd_card_disconnect(), 7462306a36Sopenharmony_ci * by following to link list. 7562306a36Sopenharmony_ci */ 7662306a36Sopenharmony_ci root = snd_info_create_card_entry(dg00x->card, "firewire", 7762306a36Sopenharmony_ci dg00x->card->proc_root); 7862306a36Sopenharmony_ci if (root == NULL) 7962306a36Sopenharmony_ci return; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci root->mode = S_IFDIR | 0555; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci entry = snd_info_create_card_entry(dg00x->card, "clock", root); 8462306a36Sopenharmony_ci if (entry) 8562306a36Sopenharmony_ci snd_info_set_text_ops(entry, dg00x, proc_read_clock); 8662306a36Sopenharmony_ci} 87