• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ff-protocol-ff400.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 <linux/delay.h>
10 #include "ff.h"
11 
12 #define FF400_STF		0x000080100500ull
13 #define FF400_RX_PACKET_FORMAT	0x000080100504ull
14 #define FF400_ISOC_COMM_START	0x000080100508ull
15 #define FF400_TX_PACKET_FORMAT	0x00008010050cull
16 #define FF400_ISOC_COMM_STOP	0x000080100510ull
17 #define FF400_SYNC_STATUS	0x0000801c0000ull
18 #define FF400_FETCH_PCM_FRAMES	0x0000801c0000ull	/* For block request. */
19 #define FF400_CLOCK_CONFIG	0x0000801c0004ull
20 
21 #define FF400_MIDI_HIGH_ADDR	0x0000801003f4ull
22 #define FF400_MIDI_RX_PORT_0	0x000080180000ull
23 #define FF400_MIDI_RX_PORT_1	0x000080190000ull
24 
ff400_get_clock(struct snd_ff * ff,unsigned int * rate,enum snd_ff_clock_src * src)25 static int ff400_get_clock(struct snd_ff *ff, unsigned int *rate,
26 			   enum snd_ff_clock_src *src)
27 {
28 	__le32 reg;
29 	u32 data;
30 	int err;
31 
32 	err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
33 				 FF400_CLOCK_CONFIG, &reg, sizeof(reg), 0);
34 	if (err < 0)
35 		return err;
36 	data = le32_to_cpu(reg);
37 
38 	/* Calculate sampling rate. */
39 	switch ((data >> 1) & 0x03) {
40 	case 0x01:
41 		*rate = 32000;
42 		break;
43 	case 0x00:
44 		*rate = 44100;
45 		break;
46 	case 0x03:
47 		*rate = 48000;
48 		break;
49 	case 0x02:
50 	default:
51 		return -EIO;
52 	}
53 
54 	if (data & 0x08)
55 		*rate *= 2;
56 	else if (data & 0x10)
57 		*rate *= 4;
58 
59 	/* Calculate source of clock. */
60 	if (data & 0x01) {
61 		*src = SND_FF_CLOCK_SRC_INTERNAL;
62 	} else {
63 		/* TODO: 0x00, 0x01, 0x02, 0x06, 0x07? */
64 		switch ((data >> 10) & 0x07) {
65 		case 0x03:
66 			*src = SND_FF_CLOCK_SRC_SPDIF;
67 			break;
68 		case 0x04:
69 			*src = SND_FF_CLOCK_SRC_WORD;
70 			break;
71 		case 0x05:
72 			*src = SND_FF_CLOCK_SRC_LTC;
73 			break;
74 		case 0x00:
75 		default:
76 			*src = SND_FF_CLOCK_SRC_ADAT;
77 			break;
78 		}
79 	}
80 
81 	return 0;
82 }
83 
ff400_begin_session(struct snd_ff * ff,unsigned int rate)84 static int ff400_begin_session(struct snd_ff *ff, unsigned int rate)
85 {
86 	__le32 reg;
87 	int i, err;
88 
89 	/* Check whether the given value is supported or not. */
90 	for (i = 0; i < CIP_SFC_COUNT; i++) {
91 		if (amdtp_rate_table[i] == rate)
92 			break;
93 	}
94 	if (i == CIP_SFC_COUNT)
95 		return -EINVAL;
96 
97 	/* Set the number of data blocks transferred in a second. */
98 	reg = cpu_to_le32(rate);
99 	err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
100 				 FF400_STF, &reg, sizeof(reg), 0);
101 	if (err < 0)
102 		return err;
103 
104 	msleep(100);
105 
106 	/*
107 	 * Set isochronous channel and the number of quadlets of received
108 	 * packets.
109 	 */
110 	reg = cpu_to_le32(((ff->rx_stream.data_block_quadlets << 3) << 8) |
111 			  ff->rx_resources.channel);
112 	err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
113 				 FF400_RX_PACKET_FORMAT, &reg, sizeof(reg), 0);
114 	if (err < 0)
115 		return err;
116 
117 	/*
118 	 * Set isochronous channel and the number of quadlets of transmitted
119 	 * packet.
120 	 */
121 	/* TODO: investigate the purpose of this 0x80. */
122 	reg = cpu_to_le32((0x80 << 24) |
123 			  (ff->tx_resources.channel << 5) |
124 			  (ff->tx_stream.data_block_quadlets));
125 	err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
126 				 FF400_TX_PACKET_FORMAT, &reg, sizeof(reg), 0);
127 	if (err < 0)
128 		return err;
129 
130 	/* Allow to transmit packets. */
131 	reg = cpu_to_le32(0x00000001);
132 	return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
133 				 FF400_ISOC_COMM_START, &reg, sizeof(reg), 0);
134 }
135 
ff400_finish_session(struct snd_ff * ff)136 static void ff400_finish_session(struct snd_ff *ff)
137 {
138 	__le32 reg;
139 
140 	reg = cpu_to_le32(0x80000000);
141 	snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
142 			   FF400_ISOC_COMM_STOP, &reg, sizeof(reg), 0);
143 }
144 
ff400_switch_fetching_mode(struct snd_ff * ff,bool enable)145 static int ff400_switch_fetching_mode(struct snd_ff *ff, bool enable)
146 {
147 	__le32 *reg;
148 	int i;
149 	int err;
150 
151 	reg = kcalloc(18, sizeof(__le32), GFP_KERNEL);
152 	if (reg == NULL)
153 		return -ENOMEM;
154 
155 	if (!enable) {
156 		/*
157 		 * Each quadlet is corresponding to data channels in a data
158 		 * blocks in reverse order. Precisely, quadlets for available
159 		 * data channels should be enabled. Here, I take second best
160 		 * to fetch PCM frames from all of data channels regardless of
161 		 * stf.
162 		 */
163 		for (i = 0; i < 18; ++i)
164 			reg[i] = cpu_to_le32(0x00000001);
165 	}
166 
167 	err = snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,
168 				 FF400_FETCH_PCM_FRAMES, reg,
169 				 sizeof(__le32) * 18, 0);
170 	kfree(reg);
171 	return err;
172 }
173 
ff400_dump_sync_status(struct snd_ff * ff,struct snd_info_buffer * buffer)174 static void ff400_dump_sync_status(struct snd_ff *ff,
175 				   struct snd_info_buffer *buffer)
176 {
177 	__le32 reg;
178 	u32 data;
179 	int err;
180 
181 	err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
182 				 FF400_SYNC_STATUS, &reg, sizeof(reg), 0);
183 	if (err < 0)
184 		return;
185 
186 	data = le32_to_cpu(reg);
187 
188 	snd_iprintf(buffer, "External source detection:\n");
189 
190 	snd_iprintf(buffer, "Word Clock:");
191 	if ((data >> 24) & 0x20) {
192 		if ((data >> 24) & 0x40)
193 			snd_iprintf(buffer, "sync\n");
194 		else
195 			snd_iprintf(buffer, "lock\n");
196 	} else {
197 		snd_iprintf(buffer, "none\n");
198 	}
199 
200 	snd_iprintf(buffer, "S/PDIF:");
201 	if ((data >> 16) & 0x10) {
202 		if ((data >> 16) & 0x04)
203 			snd_iprintf(buffer, "sync\n");
204 		else
205 			snd_iprintf(buffer, "lock\n");
206 	} else {
207 		snd_iprintf(buffer, "none\n");
208 	}
209 
210 	snd_iprintf(buffer, "ADAT:");
211 	if ((data >> 8) & 0x04) {
212 		if ((data >> 8) & 0x10)
213 			snd_iprintf(buffer, "sync\n");
214 		else
215 			snd_iprintf(buffer, "lock\n");
216 	} else {
217 		snd_iprintf(buffer, "none\n");
218 	}
219 
220 	snd_iprintf(buffer, "\nUsed external source:\n");
221 
222 	if (((data >> 22) & 0x07) == 0x07) {
223 		snd_iprintf(buffer, "None\n");
224 	} else {
225 		switch ((data >> 22) & 0x07) {
226 		case 0x00:
227 			snd_iprintf(buffer, "ADAT:");
228 			break;
229 		case 0x03:
230 			snd_iprintf(buffer, "S/PDIF:");
231 			break;
232 		case 0x04:
233 			snd_iprintf(buffer, "Word:");
234 			break;
235 		case 0x07:
236 			snd_iprintf(buffer, "Nothing:");
237 			break;
238 		case 0x01:
239 		case 0x02:
240 		case 0x05:
241 		case 0x06:
242 		default:
243 			snd_iprintf(buffer, "unknown:");
244 			break;
245 		}
246 
247 		if ((data >> 25) & 0x07) {
248 			switch ((data >> 25) & 0x07) {
249 			case 0x01:
250 				snd_iprintf(buffer, "32000\n");
251 				break;
252 			case 0x02:
253 				snd_iprintf(buffer, "44100\n");
254 				break;
255 			case 0x03:
256 				snd_iprintf(buffer, "48000\n");
257 				break;
258 			case 0x04:
259 				snd_iprintf(buffer, "64000\n");
260 				break;
261 			case 0x05:
262 				snd_iprintf(buffer, "88200\n");
263 				break;
264 			case 0x06:
265 				snd_iprintf(buffer, "96000\n");
266 				break;
267 			case 0x07:
268 				snd_iprintf(buffer, "128000\n");
269 				break;
270 			case 0x08:
271 				snd_iprintf(buffer, "176400\n");
272 				break;
273 			case 0x09:
274 				snd_iprintf(buffer, "192000\n");
275 				break;
276 			case 0x00:
277 				snd_iprintf(buffer, "unknown\n");
278 				break;
279 			}
280 		}
281 	}
282 
283 	snd_iprintf(buffer, "Multiplied:");
284 	snd_iprintf(buffer, "%d\n", (data & 0x3ff) * 250);
285 }
286 
ff400_dump_clock_config(struct snd_ff * ff,struct snd_info_buffer * buffer)287 static void ff400_dump_clock_config(struct snd_ff *ff,
288 				    struct snd_info_buffer *buffer)
289 {
290 	__le32 reg;
291 	u32 data;
292 	unsigned int rate;
293 	const char *src;
294 	int err;
295 
296 	err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST,
297 				 FF400_CLOCK_CONFIG, &reg, sizeof(reg), 0);
298 	if (err < 0)
299 		return;
300 
301 	data = le32_to_cpu(reg);
302 
303 	snd_iprintf(buffer, "Output S/PDIF format: %s (Emphasis: %s)\n",
304 		    (data & 0x20) ? "Professional" : "Consumer",
305 		    (data & 0x40) ? "on" : "off");
306 
307 	snd_iprintf(buffer, "Optical output interface format: %s\n",
308 		    ((data >> 8) & 0x01) ? "S/PDIF" : "ADAT");
309 
310 	snd_iprintf(buffer, "Word output single speed: %s\n",
311 		    ((data >> 8) & 0x20) ? "on" : "off");
312 
313 	snd_iprintf(buffer, "S/PDIF input interface: %s\n",
314 		    ((data >> 8) & 0x02) ? "Optical" : "Coaxial");
315 
316 	switch ((data >> 1) & 0x03) {
317 	case 0x01:
318 		rate = 32000;
319 		break;
320 	case 0x00:
321 		rate = 44100;
322 		break;
323 	case 0x03:
324 		rate = 48000;
325 		break;
326 	case 0x02:
327 	default:
328 		return;
329 	}
330 
331 	if (data & 0x08)
332 		rate *= 2;
333 	else if (data & 0x10)
334 		rate *= 4;
335 
336 	snd_iprintf(buffer, "Sampling rate: %d\n", rate);
337 
338 	if (data & 0x01) {
339 		src = "Internal";
340 	} else {
341 		switch ((data >> 10) & 0x07) {
342 		case 0x00:
343 			src = "ADAT";
344 			break;
345 		case 0x03:
346 			src = "S/PDIF";
347 			break;
348 		case 0x04:
349 			src = "Word";
350 			break;
351 		case 0x05:
352 			src = "LTC";
353 			break;
354 		default:
355 			return;
356 		}
357 	}
358 
359 	snd_iprintf(buffer, "Sync to clock source: %s\n", src);
360 }
361 
362 const struct snd_ff_protocol snd_ff_protocol_ff400 = {
363 	.get_clock		= ff400_get_clock,
364 	.begin_session		= ff400_begin_session,
365 	.finish_session		= ff400_finish_session,
366 	.switch_fetching_mode	= ff400_switch_fetching_mode,
367 
368 	.dump_sync_status	= ff400_dump_sync_status,
369 	.dump_clock_config	= ff400_dump_clock_config,
370 
371 	.midi_high_addr_reg	= FF400_MIDI_HIGH_ADDR,
372 	.midi_rx_port_0_reg	= FF400_MIDI_RX_PORT_0,
373 	.midi_rx_port_1_reg	= FF400_MIDI_RX_PORT_1,
374 };
375