Commit | Line | Data |
---|---|---|
da607e19 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
927f17dc TS |
2 | /* |
3 | * digi00x-proc.c - a part of driver for Digidesign Digi 002/003 family | |
4 | * | |
5 | * Copyright (c) 2014-2015 Takashi Sakamoto | |
927f17dc TS |
6 | */ |
7 | ||
8 | #include "digi00x.h" | |
9 | ||
10 | static 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 | ||
25 | static 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 | ||
68 | void 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 | ||
6a73cf46 | 81 | root->mode = S_IFDIR | 0555; |
927f17dc TS |
82 | |
83 | entry = snd_info_create_card_entry(dg00x->card, "clock", root); | |
0c298bdc TI |
84 | if (entry) |
85 | snd_info_set_text_ops(entry, dg00x, proc_read_clock); | |
927f17dc | 86 | } |