1 /*
2  * ff-proc.c - a part of driver for RME Fireface series
3  *
4  * Copyright (c) 2015-2017 Takashi Sakamoto
5  *
6  * Licensed under the terms of the GNU General Public License, version 2.
7  */
8 
9 #include "./ff.h"
10 
11 static void proc_dump_clock_config(struct snd_info_entry *entry,
12 				   struct snd_info_buffer *buffer)
13 {
14 	struct snd_ff *ff = entry->private_data;
15 	__le32 reg;
16 	u32 data;
17 	unsigned int rate;
18 	const char *src;
19 	int err;
20 
21 	err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST,
22 				 SND_FF_REG_CLOCK_CONFIG, &reg, sizeof(reg), 0);
23 	if (err < 0)
24 		return;
25 
26 	data = le32_to_cpu(reg);
27 
28 	snd_iprintf(buffer, "Output S/PDIF format: %s (Emphasis: %s)\n",
29 		    (data & 0x20) ? "Professional" : "Consumer",
30 		    (data & 0x40) ? "on" : "off");
31 
32 	snd_iprintf(buffer, "Optical output interface format: %s\n",
33 		    ((data >> 8) & 0x01) ? "S/PDIF" : "ADAT");
34 
35 	snd_iprintf(buffer, "Word output single speed: %s\n",
36 		    ((data >> 8) & 0x20) ? "on" : "off");
37 
38 	snd_iprintf(buffer, "S/PDIF input interface: %s\n",
39 		    ((data >> 8) & 0x02) ? "Optical" : "Coaxial");
40 
41 	switch ((data >> 1) & 0x03) {
42 	case 0x01:
43 		rate = 32000;
44 		break;
45 	case 0x00:
46 		rate = 44100;
47 		break;
48 	case 0x03:
49 		rate = 48000;
50 		break;
51 	case 0x02:
52 	default:
53 		return;
54 	}
55 
56 	if (data & 0x08)
57 		rate *= 2;
58 	else if (data & 0x10)
59 		rate *= 4;
60 
61 	snd_iprintf(buffer, "Sampling rate: %d\n", rate);
62 
63 	if (data & 0x01) {
64 		src = "Internal";
65 	} else {
66 		switch ((data >> 10) & 0x07) {
67 		case 0x00:
68 			src = "ADAT1";
69 			break;
70 		case 0x01:
71 			src = "ADAT2";
72 			break;
73 		case 0x03:
74 			src = "S/PDIF";
75 			break;
76 		case 0x04:
77 			src = "Word";
78 			break;
79 		case 0x05:
80 			src = "LTC";
81 			break;
82 		default:
83 			return;
84 		}
85 	}
86 
87 	snd_iprintf(buffer, "Sync to clock source: %s\n", src);
88 }
89 
90 static void proc_dump_sync_status(struct snd_info_entry *entry,
91 				  struct snd_info_buffer *buffer)
92 {
93 	struct snd_ff *ff = entry->private_data;
94 	__le32 reg;
95 	u32 data;
96 	int err;
97 
98 	err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
99 				 SND_FF_REG_SYNC_STATUS, &reg, sizeof(reg), 0);
100 	if (err < 0)
101 		return;
102 
103 	data = le32_to_cpu(reg);
104 
105 	snd_iprintf(buffer, "External source detection:\n");
106 
107 	snd_iprintf(buffer, "Word Clock:");
108 	if ((data >> 24) & 0x20) {
109 		if ((data >> 24) & 0x40)
110 			snd_iprintf(buffer, "sync\n");
111 		else
112 			snd_iprintf(buffer, "lock\n");
113 	} else {
114 		snd_iprintf(buffer, "none\n");
115 	}
116 
117 	snd_iprintf(buffer, "S/PDIF:");
118 	if ((data >> 16) & 0x10) {
119 		if ((data >> 16) & 0x04)
120 			snd_iprintf(buffer, "sync\n");
121 		else
122 			snd_iprintf(buffer, "lock\n");
123 	} else {
124 		snd_iprintf(buffer, "none\n");
125 	}
126 
127 	snd_iprintf(buffer, "ADAT1:");
128 	if ((data >> 8) & 0x04) {
129 		if ((data >> 8) & 0x10)
130 			snd_iprintf(buffer, "sync\n");
131 		else
132 			snd_iprintf(buffer, "lock\n");
133 	} else {
134 		snd_iprintf(buffer, "none\n");
135 	}
136 
137 	snd_iprintf(buffer, "ADAT2:");
138 	if ((data >> 8) & 0x08) {
139 		if ((data >> 8) & 0x20)
140 			snd_iprintf(buffer, "sync\n");
141 		else
142 			snd_iprintf(buffer, "lock\n");
143 	} else {
144 		snd_iprintf(buffer, "none\n");
145 	}
146 
147 	snd_iprintf(buffer, "\nUsed external source:\n");
148 
149 	if (((data >> 22) & 0x07) == 0x07) {
150 		snd_iprintf(buffer, "None\n");
151 	} else {
152 		switch ((data >> 22) & 0x07) {
153 		case 0x00:
154 			snd_iprintf(buffer, "ADAT1:");
155 			break;
156 		case 0x01:
157 			snd_iprintf(buffer, "ADAT2:");
158 			break;
159 		case 0x03:
160 			snd_iprintf(buffer, "S/PDIF:");
161 			break;
162 		case 0x04:
163 			snd_iprintf(buffer, "Word:");
164 			break;
165 		case 0x07:
166 			snd_iprintf(buffer, "Nothing:");
167 			break;
168 		case 0x02:
169 		case 0x05:
170 		case 0x06:
171 		default:
172 			snd_iprintf(buffer, "unknown:");
173 			break;
174 		}
175 
176 		if ((data >> 25) & 0x07) {
177 			switch ((data >> 25) & 0x07) {
178 			case 0x01:
179 				snd_iprintf(buffer, "32000\n");
180 				break;
181 			case 0x02:
182 				snd_iprintf(buffer, "44100\n");
183 				break;
184 			case 0x03:
185 				snd_iprintf(buffer, "48000\n");
186 				break;
187 			case 0x04:
188 				snd_iprintf(buffer, "64000\n");
189 				break;
190 			case 0x05:
191 				snd_iprintf(buffer, "88200\n");
192 				break;
193 			case 0x06:
194 				snd_iprintf(buffer, "96000\n");
195 				break;
196 			case 0x07:
197 				snd_iprintf(buffer, "128000\n");
198 				break;
199 			case 0x08:
200 				snd_iprintf(buffer, "176400\n");
201 				break;
202 			case 0x09:
203 				snd_iprintf(buffer, "192000\n");
204 				break;
205 			case 0x00:
206 				snd_iprintf(buffer, "unknown\n");
207 				break;
208 			}
209 		}
210 	}
211 
212 	snd_iprintf(buffer, "Multiplied:");
213 	snd_iprintf(buffer, "%d\n", (data & 0x3ff) * 250);
214 }
215 
216 static void add_node(struct snd_ff *ff, struct snd_info_entry *root,
217 		     const char *name,
218 		     void (*op)(struct snd_info_entry *e,
219 				struct snd_info_buffer *b))
220 {
221 	struct snd_info_entry *entry;
222 
223 	entry = snd_info_create_card_entry(ff->card, name, root);
224 	if (entry == NULL)
225 		return;
226 
227 	snd_info_set_text_ops(entry, ff, op);
228 	if (snd_info_register(entry) < 0)
229 		snd_info_free_entry(entry);
230 }
231 
232 void snd_ff_proc_init(struct snd_ff *ff)
233 {
234 	struct snd_info_entry *root;
235 
236 	/*
237 	 * All nodes are automatically removed at snd_card_disconnect(),
238 	 * by following to link list.
239 	 */
240 	root = snd_info_create_card_entry(ff->card, "firewire",
241 					  ff->card->proc_root);
242 	if (root == NULL)
243 		return;
244 	root->mode = S_IFDIR | 0555;
245 	if (snd_info_register(root) < 0) {
246 		snd_info_free_entry(root);
247 		return;
248 	}
249 
250 	add_node(ff, root, "clock-config", proc_dump_clock_config);
251 	add_node(ff, root, "sync-status", proc_dump_sync_status);
252 }
253