]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - sound/firewire/bebob/bebob_focusrite.c
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[karo-tx-linux.git] / sound / firewire / bebob / bebob_focusrite.c
1 /*
2  * bebob_focusrite.c - a part of driver for BeBoB based devices
3  *
4  * Copyright (c) 2013-2014 Takashi Sakamoto
5  *
6  * Licensed under the terms of the GNU General Public License, version 2.
7  */
8
9 #include "./bebob.h"
10
11 #define ANA_IN  "Analog In"
12 #define DIG_IN  "Digital In"
13 #define ANA_OUT "Analog Out"
14 #define DIG_OUT "Digital Out"
15 #define STM_IN  "Stream In"
16
17 #define SAFFIRE_ADDRESS_BASE                    0x000100000000ULL
18
19 #define SAFFIRE_OFFSET_CLOCK_SOURCE             0x00f8
20 #define SAFFIREPRO_OFFSET_CLOCK_SOURCE          0x0174
21
22 /* whether sync to external device or not */
23 #define SAFFIRE_OFFSET_CLOCK_SYNC_EXT           0x013c
24 #define SAFFIRE_LE_OFFSET_CLOCK_SYNC_EXT        0x0432
25 #define SAFFIREPRO_OFFSET_CLOCK_SYNC_EXT        0x0164
26
27 #define SAFFIRE_CLOCK_SOURCE_INTERNAL           0
28 #define SAFFIRE_CLOCK_SOURCE_SPDIF              1
29
30 /* clock sources as returned from register of Saffire Pro 10 and 26 */
31 #define SAFFIREPRO_CLOCK_SOURCE_INTERNAL        0
32 #define SAFFIREPRO_CLOCK_SOURCE_SKIP            1 /* never used on hardware */
33 #define SAFFIREPRO_CLOCK_SOURCE_SPDIF           2
34 #define SAFFIREPRO_CLOCK_SOURCE_ADAT1           3 /* not used on s.pro. 10 */
35 #define SAFFIREPRO_CLOCK_SOURCE_ADAT2           4 /* not used on s.pro. 10 */
36 #define SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK       5
37 #define SAFFIREPRO_CLOCK_SOURCE_COUNT           6
38
39 /* S/PDIF, ADAT1, ADAT2 is enabled or not. three quadlets */
40 #define SAFFIREPRO_ENABLE_DIG_IFACES            0x01a4
41
42 /* saffirepro has its own parameter for sampling frequency */
43 #define SAFFIREPRO_RATE_NOREBOOT                0x01cc
44 /* index is the value for this register */
45 static const unsigned int rates[] = {
46         [0] = 0,
47         [1] = 44100,
48         [2] = 48000,
49         [3] = 88200,
50         [4] = 96000,
51         [5] = 176400,
52         [6] = 192000
53 };
54
55 /* saffire(no label)/saffire LE has metering */
56 #define SAFFIRE_OFFSET_METER                    0x0100
57 #define SAFFIRE_LE_OFFSET_METER                 0x0168
58
59 static inline int
60 saffire_read_block(struct snd_bebob *bebob, u64 offset,
61                    u32 *buf, unsigned int size)
62 {
63         unsigned int i;
64         int err;
65         __be32 *tmp = (__be32 *)buf;
66
67         err =  snd_fw_transaction(bebob->unit, TCODE_READ_BLOCK_REQUEST,
68                                   SAFFIRE_ADDRESS_BASE + offset,
69                                   tmp, size, 0);
70         if (err < 0)
71                 goto end;
72
73         for (i = 0; i < size / sizeof(u32); i++)
74                 buf[i] = be32_to_cpu(tmp[i]);
75 end:
76         return err;
77 }
78
79 static inline int
80 saffire_read_quad(struct snd_bebob *bebob, u64 offset, u32 *value)
81 {
82         int err;
83         __be32 tmp;
84
85         err = snd_fw_transaction(bebob->unit, TCODE_READ_QUADLET_REQUEST,
86                                  SAFFIRE_ADDRESS_BASE + offset,
87                                  &tmp, sizeof(__be32), 0);
88         if (err < 0)
89                 goto end;
90
91         *value = be32_to_cpu(tmp);
92 end:
93         return err;
94 }
95
96 static inline int
97 saffire_write_quad(struct snd_bebob *bebob, u64 offset, u32 value)
98 {
99         __be32 data = cpu_to_be32(value);
100
101         return snd_fw_transaction(bebob->unit, TCODE_WRITE_QUADLET_REQUEST,
102                                   SAFFIRE_ADDRESS_BASE + offset,
103                                   &data, sizeof(__be32), 0);
104 }
105
106 static enum snd_bebob_clock_type saffirepro_10_clk_src_types[] = {
107         SND_BEBOB_CLOCK_TYPE_INTERNAL,
108         SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* S/PDIF */
109         SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* Word Clock */
110 };
111 static enum snd_bebob_clock_type saffirepro_26_clk_src_types[] = {
112         SND_BEBOB_CLOCK_TYPE_INTERNAL,
113         SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* S/PDIF */
114         SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* ADAT1 */
115         SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* ADAT2 */
116         SND_BEBOB_CLOCK_TYPE_EXTERNAL,  /* Word Clock */
117 };
118 /* Value maps between registers and labels for SaffirePro 10/26. */
119 static const signed char saffirepro_clk_maps[][SAFFIREPRO_CLOCK_SOURCE_COUNT] = {
120         /* SaffirePro 10 */
121         [0] = {
122                 [SAFFIREPRO_CLOCK_SOURCE_INTERNAL]  =  0,
123                 [SAFFIREPRO_CLOCK_SOURCE_SKIP]      = -1, /* not supported */
124                 [SAFFIREPRO_CLOCK_SOURCE_SPDIF]     =  1,
125                 [SAFFIREPRO_CLOCK_SOURCE_ADAT1]     = -1, /* not supported */
126                 [SAFFIREPRO_CLOCK_SOURCE_ADAT2]     = -1, /* not supported */
127                 [SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK] =  2,
128         },
129         /* SaffirePro 26 */
130         [1] = {
131                 [SAFFIREPRO_CLOCK_SOURCE_INTERNAL]  =  0,
132                 [SAFFIREPRO_CLOCK_SOURCE_SKIP]      = -1, /* not supported */
133                 [SAFFIREPRO_CLOCK_SOURCE_SPDIF]     =  1,
134                 [SAFFIREPRO_CLOCK_SOURCE_ADAT1]     =  2,
135                 [SAFFIREPRO_CLOCK_SOURCE_ADAT2]     =  3,
136                 [SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK] =  4,
137         }
138 };
139
140 static int
141 saffirepro_both_clk_freq_get(struct snd_bebob *bebob, unsigned int *rate)
142 {
143         u32 id;
144         int err;
145
146         err = saffire_read_quad(bebob, SAFFIREPRO_RATE_NOREBOOT, &id);
147         if (err < 0)
148                 goto end;
149         if (id >= ARRAY_SIZE(rates))
150                 err = -EIO;
151         else
152                 *rate = rates[id];
153 end:
154         return err;
155 }
156 static int
157 saffirepro_both_clk_freq_set(struct snd_bebob *bebob, unsigned int rate)
158 {
159         u32 id;
160
161         for (id = 0; id < ARRAY_SIZE(rates); id++) {
162                 if (rates[id] == rate)
163                         break;
164         }
165         if (id == ARRAY_SIZE(rates))
166                 return -EINVAL;
167
168         return saffire_write_quad(bebob, SAFFIREPRO_RATE_NOREBOOT, id);
169 }
170
171 /*
172  * query hardware for current clock source, return our internally
173  * used clock index in *id, depending on hardware.
174  */
175 static int
176 saffirepro_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id)
177 {
178         int err;
179         u32 value;       /* clock source read from hw register */
180         const signed char *map;
181
182         err = saffire_read_quad(bebob, SAFFIREPRO_OFFSET_CLOCK_SOURCE, &value);
183         if (err < 0)
184                 goto end;
185
186         /* depending on hardware, use a different mapping */
187         if (bebob->spec->clock->types == saffirepro_10_clk_src_types)
188                 map = saffirepro_clk_maps[0];
189         else
190                 map = saffirepro_clk_maps[1];
191
192         /* In a case that this driver cannot handle the value of register. */
193         if (value >= SAFFIREPRO_CLOCK_SOURCE_COUNT || map[value] < 0) {
194                 err = -EIO;
195                 goto end;
196         }
197
198         *id = (unsigned int)map[value];
199 end:
200         return err;
201 }
202
203 struct snd_bebob_spec saffire_le_spec;
204 static enum snd_bebob_clock_type saffire_both_clk_src_types[] = {
205         SND_BEBOB_CLOCK_TYPE_INTERNAL,
206         SND_BEBOB_CLOCK_TYPE_EXTERNAL,
207 };
208 static int
209 saffire_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id)
210 {
211         int err;
212         u32 value;
213
214         err = saffire_read_quad(bebob, SAFFIRE_OFFSET_CLOCK_SOURCE, &value);
215         if (err >= 0)
216                 *id = 0xff & value;
217
218         return err;
219 };
220 static const char *const saffire_le_meter_labels[] = {
221         ANA_IN, ANA_IN, DIG_IN,
222         ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT,
223         STM_IN, STM_IN
224 };
225 static const char *const saffire_meter_labels[] = {
226         ANA_IN, ANA_IN,
227         STM_IN, STM_IN, STM_IN, STM_IN, STM_IN,
228 };
229 static int
230 saffire_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size)
231 {
232         struct snd_bebob_meter_spec *spec = bebob->spec->meter;
233         unsigned int channels;
234         u64 offset;
235         int err;
236
237         if (spec->labels == saffire_le_meter_labels)
238                 offset = SAFFIRE_LE_OFFSET_METER;
239         else
240                 offset = SAFFIRE_OFFSET_METER;
241
242         channels = spec->num * 2;
243         if (size < channels * sizeof(u32))
244                 return -EIO;
245
246         err = saffire_read_block(bebob, offset, buf, size);
247         if (err >= 0 && spec->labels == saffire_le_meter_labels) {
248                 swap(buf[1], buf[3]);
249                 swap(buf[2], buf[3]);
250                 swap(buf[3], buf[4]);
251
252                 swap(buf[7], buf[10]);
253                 swap(buf[8], buf[10]);
254                 swap(buf[9], buf[11]);
255                 swap(buf[11], buf[12]);
256
257                 swap(buf[15], buf[16]);
258         }
259
260         return err;
261 }
262
263 static struct snd_bebob_rate_spec saffirepro_both_rate_spec = {
264         .get    = &saffirepro_both_clk_freq_get,
265         .set    = &saffirepro_both_clk_freq_set,
266 };
267 /* Saffire Pro 26 I/O  */
268 static struct snd_bebob_clock_spec saffirepro_26_clk_spec = {
269         .num    = ARRAY_SIZE(saffirepro_26_clk_src_types),
270         .types  = saffirepro_26_clk_src_types,
271         .get    = &saffirepro_both_clk_src_get,
272 };
273 struct snd_bebob_spec saffirepro_26_spec = {
274         .clock  = &saffirepro_26_clk_spec,
275         .rate   = &saffirepro_both_rate_spec,
276         .meter  = NULL
277 };
278 /* Saffire Pro 10 I/O */
279 static struct snd_bebob_clock_spec saffirepro_10_clk_spec = {
280         .num    = ARRAY_SIZE(saffirepro_10_clk_src_types),
281         .types  = saffirepro_10_clk_src_types,
282         .get    = &saffirepro_both_clk_src_get,
283 };
284 struct snd_bebob_spec saffirepro_10_spec = {
285         .clock  = &saffirepro_10_clk_spec,
286         .rate   = &saffirepro_both_rate_spec,
287         .meter  = NULL
288 };
289
290 static struct snd_bebob_rate_spec saffire_both_rate_spec = {
291         .get    = &snd_bebob_stream_get_rate,
292         .set    = &snd_bebob_stream_set_rate,
293 };
294 static struct snd_bebob_clock_spec saffire_both_clk_spec = {
295         .num    = ARRAY_SIZE(saffire_both_clk_src_types),
296         .types  = saffire_both_clk_src_types,
297         .get    = &saffire_both_clk_src_get,
298 };
299 /* Saffire LE */
300 static struct snd_bebob_meter_spec saffire_le_meter_spec = {
301         .num    = ARRAY_SIZE(saffire_le_meter_labels),
302         .labels = saffire_le_meter_labels,
303         .get    = &saffire_meter_get,
304 };
305 struct snd_bebob_spec saffire_le_spec = {
306         .clock  = &saffire_both_clk_spec,
307         .rate   = &saffire_both_rate_spec,
308         .meter  = &saffire_le_meter_spec
309 };
310 /* Saffire */
311 static struct snd_bebob_meter_spec saffire_meter_spec = {
312         .num    = ARRAY_SIZE(saffire_meter_labels),
313         .labels = saffire_meter_labels,
314         .get    = &saffire_meter_get,
315 };
316 struct snd_bebob_spec saffire_spec = {
317         .clock  = &saffire_both_clk_spec,
318         .rate   = &saffire_both_rate_spec,
319         .meter  = &saffire_meter_spec
320 };