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 /* '1' is absent, why... */ 31 #define SAFFIREPRO_CLOCK_SOURCE_INTERNAL 0 32 #define SAFFIREPRO_CLOCK_SOURCE_SPDIF 2 33 #define SAFFIREPRO_CLOCK_SOURCE_ADAT1 3 34 #define SAFFIREPRO_CLOCK_SOURCE_ADAT2 4 35 #define SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK 5 36 37 /* S/PDIF, ADAT1, ADAT2 is enabled or not. three quadlets */ 38 #define SAFFIREPRO_ENABLE_DIG_IFACES 0x01a4 39 40 /* saffirepro has its own parameter for sampling frequency */ 41 #define SAFFIREPRO_RATE_NOREBOOT 0x01cc 42 /* index is the value for this register */ 43 static const unsigned int rates[] = { 44 [0] = 0, 45 [1] = 44100, 46 [2] = 48000, 47 [3] = 88200, 48 [4] = 96000, 49 [5] = 176400, 50 [6] = 192000 51 }; 52 53 /* saffire(no label)/saffire LE has metering */ 54 #define SAFFIRE_OFFSET_METER 0x0100 55 #define SAFFIRE_LE_OFFSET_METER 0x0168 56 57 static inline int 58 saffire_read_block(struct snd_bebob *bebob, u64 offset, 59 u32 *buf, unsigned int size) 60 { 61 unsigned int i; 62 int err; 63 __be32 *tmp = (__be32 *)buf; 64 65 err = snd_fw_transaction(bebob->unit, TCODE_READ_BLOCK_REQUEST, 66 SAFFIRE_ADDRESS_BASE + offset, 67 tmp, size, 0); 68 if (err < 0) 69 goto end; 70 71 for (i = 0; i < size / sizeof(u32); i++) 72 buf[i] = be32_to_cpu(tmp[i]); 73 end: 74 return err; 75 } 76 77 static inline int 78 saffire_read_quad(struct snd_bebob *bebob, u64 offset, u32 *value) 79 { 80 int err; 81 __be32 tmp; 82 83 err = snd_fw_transaction(bebob->unit, TCODE_READ_QUADLET_REQUEST, 84 SAFFIRE_ADDRESS_BASE + offset, 85 &tmp, sizeof(__be32), 0); 86 if (err < 0) 87 goto end; 88 89 *value = be32_to_cpu(tmp); 90 end: 91 return err; 92 } 93 94 static inline int 95 saffire_write_quad(struct snd_bebob *bebob, u64 offset, u32 value) 96 { 97 __be32 data = cpu_to_be32(value); 98 99 return snd_fw_transaction(bebob->unit, TCODE_WRITE_QUADLET_REQUEST, 100 SAFFIRE_ADDRESS_BASE + offset, 101 &data, sizeof(__be32), 0); 102 } 103 104 static char *const saffirepro_26_clk_src_labels[] = { 105 SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "ADAT1", "ADAT2", "Word Clock" 106 }; 107 108 static char *const saffirepro_10_clk_src_labels[] = { 109 SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "Word Clock" 110 }; 111 static int 112 saffirepro_both_clk_freq_get(struct snd_bebob *bebob, unsigned int *rate) 113 { 114 u32 id; 115 int err; 116 117 err = saffire_read_quad(bebob, SAFFIREPRO_RATE_NOREBOOT, &id); 118 if (err < 0) 119 goto end; 120 if (id >= ARRAY_SIZE(rates)) 121 err = -EIO; 122 else 123 *rate = rates[id]; 124 end: 125 return err; 126 } 127 static int 128 saffirepro_both_clk_freq_set(struct snd_bebob *bebob, unsigned int rate) 129 { 130 u32 id; 131 132 for (id = 0; id < ARRAY_SIZE(rates); id++) { 133 if (rates[id] == rate) 134 break; 135 } 136 if (id == ARRAY_SIZE(rates)) 137 return -EINVAL; 138 139 return saffire_write_quad(bebob, SAFFIREPRO_RATE_NOREBOOT, id); 140 } 141 static int 142 saffirepro_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id) 143 { 144 int err; 145 u32 value; 146 147 err = saffire_read_quad(bebob, SAFFIREPRO_OFFSET_CLOCK_SOURCE, &value); 148 if (err < 0) 149 goto end; 150 151 if (bebob->spec->clock->labels == saffirepro_10_clk_src_labels) { 152 if (value == SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK) 153 *id = 2; 154 else if (value == SAFFIREPRO_CLOCK_SOURCE_SPDIF) 155 *id = 1; 156 } else if (value > 1) { 157 *id = value - 1; 158 } 159 end: 160 return err; 161 } 162 163 struct snd_bebob_spec saffire_le_spec; 164 static char *const saffire_both_clk_src_labels[] = { 165 SND_BEBOB_CLOCK_INTERNAL, "S/PDIF" 166 }; 167 static int 168 saffire_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id) 169 { 170 int err; 171 u32 value; 172 173 err = saffire_read_quad(bebob, SAFFIRE_OFFSET_CLOCK_SOURCE, &value); 174 if (err >= 0) 175 *id = 0xff & value; 176 177 return err; 178 }; 179 static char *const saffire_le_meter_labels[] = { 180 ANA_IN, ANA_IN, DIG_IN, 181 ANA_OUT, ANA_OUT, ANA_OUT, ANA_OUT, 182 STM_IN, STM_IN 183 }; 184 static char *const saffire_meter_labels[] = { 185 ANA_IN, ANA_IN, 186 STM_IN, STM_IN, STM_IN, STM_IN, STM_IN, 187 }; 188 static int 189 saffire_meter_get(struct snd_bebob *bebob, u32 *buf, unsigned int size) 190 { 191 struct snd_bebob_meter_spec *spec = bebob->spec->meter; 192 unsigned int channels; 193 u64 offset; 194 int err; 195 196 if (spec->labels == saffire_le_meter_labels) 197 offset = SAFFIRE_LE_OFFSET_METER; 198 else 199 offset = SAFFIRE_OFFSET_METER; 200 201 channels = spec->num * 2; 202 if (size < channels * sizeof(u32)) 203 return -EIO; 204 205 err = saffire_read_block(bebob, offset, buf, size); 206 if (err >= 0 && spec->labels == saffire_le_meter_labels) { 207 swap(buf[1], buf[3]); 208 swap(buf[2], buf[3]); 209 swap(buf[3], buf[4]); 210 211 swap(buf[7], buf[10]); 212 swap(buf[8], buf[10]); 213 swap(buf[9], buf[11]); 214 swap(buf[11], buf[12]); 215 216 swap(buf[15], buf[16]); 217 } 218 219 return err; 220 } 221 222 static struct snd_bebob_rate_spec saffirepro_both_rate_spec = { 223 .get = &saffirepro_both_clk_freq_get, 224 .set = &saffirepro_both_clk_freq_set, 225 }; 226 /* Saffire Pro 26 I/O */ 227 static struct snd_bebob_clock_spec saffirepro_26_clk_spec = { 228 .num = ARRAY_SIZE(saffirepro_26_clk_src_labels), 229 .labels = saffirepro_26_clk_src_labels, 230 .get = &saffirepro_both_clk_src_get, 231 }; 232 struct snd_bebob_spec saffirepro_26_spec = { 233 .clock = &saffirepro_26_clk_spec, 234 .rate = &saffirepro_both_rate_spec, 235 .meter = NULL 236 }; 237 /* Saffire Pro 10 I/O */ 238 static struct snd_bebob_clock_spec saffirepro_10_clk_spec = { 239 .num = ARRAY_SIZE(saffirepro_10_clk_src_labels), 240 .labels = saffirepro_10_clk_src_labels, 241 .get = &saffirepro_both_clk_src_get, 242 }; 243 struct snd_bebob_spec saffirepro_10_spec = { 244 .clock = &saffirepro_10_clk_spec, 245 .rate = &saffirepro_both_rate_spec, 246 .meter = NULL 247 }; 248 249 static struct snd_bebob_rate_spec saffire_both_rate_spec = { 250 .get = &snd_bebob_stream_get_rate, 251 .set = &snd_bebob_stream_set_rate, 252 }; 253 static struct snd_bebob_clock_spec saffire_both_clk_spec = { 254 .num = ARRAY_SIZE(saffire_both_clk_src_labels), 255 .labels = saffire_both_clk_src_labels, 256 .get = &saffire_both_clk_src_get, 257 }; 258 /* Saffire LE */ 259 static struct snd_bebob_meter_spec saffire_le_meter_spec = { 260 .num = ARRAY_SIZE(saffire_le_meter_labels), 261 .labels = saffire_le_meter_labels, 262 .get = &saffire_meter_get, 263 }; 264 struct snd_bebob_spec saffire_le_spec = { 265 .clock = &saffire_both_clk_spec, 266 .rate = &saffire_both_rate_spec, 267 .meter = &saffire_le_meter_spec 268 }; 269 /* Saffire */ 270 static struct snd_bebob_meter_spec saffire_meter_spec = { 271 .num = ARRAY_SIZE(saffire_meter_labels), 272 .labels = saffire_meter_labels, 273 .get = &saffire_meter_get, 274 }; 275 struct snd_bebob_spec saffire_spec = { 276 .clock = &saffire_both_clk_spec, 277 .rate = &saffire_both_rate_spec, 278 .meter = &saffire_meter_spec 279 }; 280