cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

digi00x-proc.c (2308B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * digi00x-proc.c - a part of driver for Digidesign Digi 002/003 family
      4 *
      5 * Copyright (c) 2014-2015 Takashi Sakamoto
      6 */
      7
      8#include "digi00x.h"
      9
     10static int get_optical_iface_mode(struct snd_dg00x *dg00x,
     11				  enum snd_dg00x_optical_mode *mode)
     12{
     13	__be32 data;
     14	int err;
     15
     16	err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST,
     17				 DG00X_ADDR_BASE + DG00X_OFFSET_OPT_IFACE_MODE,
     18				 &data, sizeof(data), 0);
     19	if (err >= 0)
     20		*mode = be32_to_cpu(data) & 0x01;
     21
     22	return err;
     23}
     24
     25static void proc_read_clock(struct snd_info_entry *entry,
     26			    struct snd_info_buffer *buf)
     27{
     28	static const char *const source_name[] = {
     29		[SND_DG00X_CLOCK_INTERNAL] = "internal",
     30		[SND_DG00X_CLOCK_SPDIF] = "s/pdif",
     31		[SND_DG00X_CLOCK_ADAT] = "adat",
     32		[SND_DG00X_CLOCK_WORD] = "word clock",
     33	};
     34	static const char *const optical_name[] = {
     35		[SND_DG00X_OPT_IFACE_MODE_ADAT] = "adat",
     36		[SND_DG00X_OPT_IFACE_MODE_SPDIF] = "s/pdif",
     37	};
     38	struct snd_dg00x *dg00x = entry->private_data;
     39	enum snd_dg00x_optical_mode mode;
     40	unsigned int rate;
     41	enum snd_dg00x_clock clock;
     42	bool detect;
     43
     44	if (get_optical_iface_mode(dg00x, &mode) < 0)
     45		return;
     46	if (snd_dg00x_stream_get_local_rate(dg00x, &rate) < 0)
     47		return;
     48	if (snd_dg00x_stream_get_clock(dg00x, &clock) < 0)
     49		return;
     50
     51	snd_iprintf(buf, "Optical mode: %s\n", optical_name[mode]);
     52	snd_iprintf(buf, "Sampling Rate: %d\n", rate);
     53	snd_iprintf(buf, "Clock Source: %s\n", source_name[clock]);
     54
     55	if (clock == SND_DG00X_CLOCK_INTERNAL)
     56		return;
     57
     58	if (snd_dg00x_stream_check_external_clock(dg00x, &detect) < 0)
     59		return;
     60	snd_iprintf(buf, "External source: %s\n", detect ? "detected" : "not");
     61	if (!detect)
     62		return;
     63
     64	if (snd_dg00x_stream_get_external_rate(dg00x, &rate) >= 0)
     65		snd_iprintf(buf, "External sampling rate: %d\n", rate);
     66}
     67
     68void snd_dg00x_proc_init(struct snd_dg00x *dg00x)
     69{
     70	struct snd_info_entry *root, *entry;
     71
     72	/*
     73	 * All nodes are automatically removed at snd_card_disconnect(),
     74	 * by following to link list.
     75	 */
     76	root = snd_info_create_card_entry(dg00x->card, "firewire",
     77					  dg00x->card->proc_root);
     78	if (root == NULL)
     79		return;
     80
     81	root->mode = S_IFDIR | 0555;
     82
     83	entry = snd_info_create_card_entry(dg00x->card, "clock", root);
     84	if (entry)
     85		snd_info_set_text_ops(entry, dg00x, proc_read_clock);
     86}