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