0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/delay.h>
0009
0010 #include "ff.h"
0011
0012 #define LATTER_STF 0xffff00000004ULL
0013 #define LATTER_ISOC_CHANNELS 0xffff00000008ULL
0014 #define LATTER_ISOC_START 0xffff0000000cULL
0015 #define LATTER_FETCH_MODE 0xffff00000010ULL
0016 #define LATTER_SYNC_STATUS 0x0000801c0000ULL
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 static int parse_clock_bits(u32 data, unsigned int *rate,
0074 enum snd_ff_clock_src *src,
0075 enum snd_ff_unit_version unit_version)
0076 {
0077 static const struct {
0078 unsigned int rate;
0079 u32 flag;
0080 } *rate_entry, rate_entries[] = {
0081 { 32000, 0x00, },
0082 { 44100, 0x01, },
0083 { 48000, 0x02, },
0084 { 64000, 0x04, },
0085 { 88200, 0x05, },
0086 { 96000, 0x06, },
0087 { 128000, 0x08, },
0088 { 176400, 0x09, },
0089 { 192000, 0x0a, },
0090 };
0091 static const struct {
0092 enum snd_ff_clock_src src;
0093 u32 flag;
0094 } *clk_entry, *clk_entries, ucx_clk_entries[] = {
0095 { SND_FF_CLOCK_SRC_SPDIF, 0x00000200, },
0096 { SND_FF_CLOCK_SRC_ADAT1, 0x00000400, },
0097 { SND_FF_CLOCK_SRC_WORD, 0x00000600, },
0098 { SND_FF_CLOCK_SRC_INTERNAL, 0x00000e00, },
0099 }, ufx_ff802_clk_entries[] = {
0100 { SND_FF_CLOCK_SRC_WORD, 0x00000200, },
0101 { SND_FF_CLOCK_SRC_SPDIF, 0x00000400, },
0102 { SND_FF_CLOCK_SRC_ADAT1, 0x00000600, },
0103 { SND_FF_CLOCK_SRC_ADAT2, 0x00000800, },
0104 { SND_FF_CLOCK_SRC_INTERNAL, 0x00000e00, },
0105 };
0106 u32 rate_bits;
0107 unsigned int clk_entry_count;
0108 int i;
0109
0110 if (unit_version == SND_FF_UNIT_VERSION_UCX) {
0111 rate_bits = (data & 0x0f000000) >> 24;
0112 clk_entries = ucx_clk_entries;
0113 clk_entry_count = ARRAY_SIZE(ucx_clk_entries);
0114 } else {
0115 rate_bits = (data & 0xf0000000) >> 28;
0116 clk_entries = ufx_ff802_clk_entries;
0117 clk_entry_count = ARRAY_SIZE(ufx_ff802_clk_entries);
0118 }
0119
0120 for (i = 0; i < ARRAY_SIZE(rate_entries); ++i) {
0121 rate_entry = rate_entries + i;
0122 if (rate_bits == rate_entry->flag) {
0123 *rate = rate_entry->rate;
0124 break;
0125 }
0126 }
0127 if (i == ARRAY_SIZE(rate_entries))
0128 return -EIO;
0129
0130 for (i = 0; i < clk_entry_count; ++i) {
0131 clk_entry = clk_entries + i;
0132 if ((data & 0x000e00) == clk_entry->flag) {
0133 *src = clk_entry->src;
0134 break;
0135 }
0136 }
0137 if (i == clk_entry_count)
0138 return -EIO;
0139
0140 return 0;
0141 }
0142
0143 static int latter_get_clock(struct snd_ff *ff, unsigned int *rate,
0144 enum snd_ff_clock_src *src)
0145 {
0146 __le32 reg;
0147 u32 data;
0148 int err;
0149
0150 err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
0151 LATTER_SYNC_STATUS, ®, sizeof(reg), 0);
0152 if (err < 0)
0153 return err;
0154 data = le32_to_cpu(reg);
0155
0156 return parse_clock_bits(data, rate, src, ff->unit_version);
0157 }
0158
0159 static int latter_switch_fetching_mode(struct snd_ff *ff, bool enable)
0160 {
0161 u32 data;
0162 __le32 reg;
0163
0164 if (enable)
0165 data = 0x00000000;
0166 else
0167 data = 0xffffffff;
0168 reg = cpu_to_le32(data);
0169
0170 return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
0171 LATTER_FETCH_MODE, ®, sizeof(reg), 0);
0172 }
0173
0174 static int latter_allocate_resources(struct snd_ff *ff, unsigned int rate)
0175 {
0176 enum snd_ff_stream_mode mode;
0177 unsigned int code;
0178 __le32 reg;
0179 unsigned int count;
0180 int i;
0181 int err;
0182
0183
0184 if (rate % 48000 == 0)
0185 code = 0x04;
0186 else if (rate % 44100 == 0)
0187 code = 0x02;
0188 else if (rate % 32000 == 0)
0189 code = 0x00;
0190 else
0191 return -EINVAL;
0192
0193 if (rate >= 64000 && rate < 128000)
0194 code |= 0x08;
0195 else if (rate >= 128000)
0196 code |= 0x10;
0197
0198 reg = cpu_to_le32(code);
0199 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
0200 LATTER_STF, ®, sizeof(reg), 0);
0201 if (err < 0)
0202 return err;
0203
0204
0205 count = 0;
0206 while (count++ < 10) {
0207 unsigned int curr_rate;
0208 enum snd_ff_clock_src src;
0209
0210 err = latter_get_clock(ff, &curr_rate, &src);
0211 if (err < 0)
0212 return err;
0213
0214 if (curr_rate == rate)
0215 break;
0216 }
0217 if (count > 10)
0218 return -ETIMEDOUT;
0219
0220 for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); ++i) {
0221 if (rate == amdtp_rate_table[i])
0222 break;
0223 }
0224 if (i == ARRAY_SIZE(amdtp_rate_table))
0225 return -EINVAL;
0226
0227 err = snd_ff_stream_get_multiplier_mode(i, &mode);
0228 if (err < 0)
0229 return err;
0230
0231
0232 ff->tx_resources.channels_mask = 0x00000000000000ffuLL;
0233 err = fw_iso_resources_allocate(&ff->tx_resources,
0234 amdtp_stream_get_max_payload(&ff->tx_stream),
0235 fw_parent_device(ff->unit)->max_speed);
0236 if (err < 0)
0237 return err;
0238
0239
0240 ff->rx_resources.channels_mask = 0x00000000000000ffuLL;
0241 err = fw_iso_resources_allocate(&ff->rx_resources,
0242 amdtp_stream_get_max_payload(&ff->rx_stream),
0243 fw_parent_device(ff->unit)->max_speed);
0244 if (err < 0)
0245 fw_iso_resources_free(&ff->tx_resources);
0246
0247 return err;
0248 }
0249
0250 static int latter_begin_session(struct snd_ff *ff, unsigned int rate)
0251 {
0252 unsigned int generation = ff->rx_resources.generation;
0253 unsigned int flag;
0254 u32 data;
0255 __le32 reg;
0256 int err;
0257
0258 if (ff->unit_version == SND_FF_UNIT_VERSION_UCX) {
0259
0260
0261 if (rate >= 32000 && rate <= 48000)
0262 flag = 0x92;
0263 else if (rate >= 64000 && rate <= 96000)
0264 flag = 0x8e;
0265 else if (rate >= 128000 && rate <= 192000)
0266 flag = 0x8c;
0267 else
0268 return -EINVAL;
0269 } else {
0270
0271
0272
0273 if (rate >= 32000 && rate <= 48000)
0274 flag = 0x9e;
0275 else if (rate >= 64000 && rate <= 96000)
0276 flag = 0x96;
0277 else if (rate >= 128000 && rate <= 192000)
0278 flag = 0x8e;
0279 else
0280 return -EINVAL;
0281 }
0282
0283 if (generation != fw_parent_device(ff->unit)->card->generation) {
0284 err = fw_iso_resources_update(&ff->tx_resources);
0285 if (err < 0)
0286 return err;
0287
0288 err = fw_iso_resources_update(&ff->rx_resources);
0289 if (err < 0)
0290 return err;
0291 }
0292
0293 data = (ff->tx_resources.channel << 8) | ff->rx_resources.channel;
0294 reg = cpu_to_le32(data);
0295 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
0296 LATTER_ISOC_CHANNELS, ®, sizeof(reg), 0);
0297 if (err < 0)
0298 return err;
0299
0300 reg = cpu_to_le32(flag);
0301 return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
0302 LATTER_ISOC_START, ®, sizeof(reg), 0);
0303 }
0304
0305 static void latter_finish_session(struct snd_ff *ff)
0306 {
0307 __le32 reg;
0308
0309 reg = cpu_to_le32(0x00000000);
0310 snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
0311 LATTER_ISOC_START, ®, sizeof(reg), 0);
0312 }
0313
0314 static void latter_dump_status(struct snd_ff *ff, struct snd_info_buffer *buffer)
0315 {
0316 static const struct {
0317 char *const label;
0318 u32 locked_mask;
0319 u32 synced_mask;
0320 } *clk_entry, *clk_entries, ucx_clk_entries[] = {
0321 { "S/PDIF", 0x00000001, 0x00000010, },
0322 { "ADAT", 0x00000002, 0x00000020, },
0323 { "WDClk", 0x00000004, 0x00000040, },
0324 }, ufx_ff802_clk_entries[] = {
0325 { "WDClk", 0x00000001, 0x00000010, },
0326 { "AES/EBU", 0x00000002, 0x00000020, },
0327 { "ADAT-A", 0x00000004, 0x00000040, },
0328 { "ADAT-B", 0x00000008, 0x00000080, },
0329 };
0330 __le32 reg;
0331 u32 data;
0332 unsigned int rate;
0333 enum snd_ff_clock_src src;
0334 const char *label;
0335 unsigned int clk_entry_count;
0336 int i;
0337 int err;
0338
0339 err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
0340 LATTER_SYNC_STATUS, ®, sizeof(reg), 0);
0341 if (err < 0)
0342 return;
0343 data = le32_to_cpu(reg);
0344
0345 snd_iprintf(buffer, "External source detection:\n");
0346
0347 if (ff->unit_version == SND_FF_UNIT_VERSION_UCX) {
0348 clk_entries = ucx_clk_entries;
0349 clk_entry_count = ARRAY_SIZE(ucx_clk_entries);
0350 } else {
0351 clk_entries = ufx_ff802_clk_entries;
0352 clk_entry_count = ARRAY_SIZE(ufx_ff802_clk_entries);
0353 }
0354
0355 for (i = 0; i < clk_entry_count; ++i) {
0356 clk_entry = clk_entries + i;
0357 snd_iprintf(buffer, "%s: ", clk_entry->label);
0358 if (data & clk_entry->locked_mask) {
0359 if (data & clk_entry->synced_mask)
0360 snd_iprintf(buffer, "sync\n");
0361 else
0362 snd_iprintf(buffer, "lock\n");
0363 } else {
0364 snd_iprintf(buffer, "none\n");
0365 }
0366 }
0367
0368 err = parse_clock_bits(data, &rate, &src, ff->unit_version);
0369 if (err < 0)
0370 return;
0371 label = snd_ff_proc_get_clk_label(src);
0372 if (!label)
0373 return;
0374
0375 snd_iprintf(buffer, "Referred clock: %s %d\n", label, rate);
0376 }
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398 static void latter_handle_midi_msg(struct snd_ff *ff, unsigned int offset,
0399 __le32 *buf, size_t length)
0400 {
0401 u32 data = le32_to_cpu(*buf);
0402 unsigned int index = (data & 0x000000f0) >> 4;
0403 u8 byte[3];
0404 struct snd_rawmidi_substream *substream;
0405 unsigned int len;
0406
0407 if (index >= ff->spec->midi_in_ports)
0408 return;
0409
0410 switch (data & 0x0000000f) {
0411 case 0x00000008:
0412 case 0x00000009:
0413 case 0x0000000a:
0414 case 0x0000000b:
0415 case 0x0000000e:
0416 len = 3;
0417 break;
0418 case 0x0000000c:
0419 case 0x0000000d:
0420 len = 2;
0421 break;
0422 default:
0423 len = data & 0x00000003;
0424 if (len == 0)
0425 len = 3;
0426 break;
0427 }
0428
0429 byte[0] = (data & 0x0000ff00) >> 8;
0430 byte[1] = (data & 0x00ff0000) >> 16;
0431 byte[2] = (data & 0xff000000) >> 24;
0432
0433 substream = READ_ONCE(ff->tx_midi_substreams[index]);
0434 if (substream)
0435 snd_rawmidi_receive(substream, byte, len);
0436 }
0437
0438
0439
0440
0441
0442
0443 static inline int calculate_message_bytes(u8 status)
0444 {
0445 switch (status) {
0446 case 0xf6:
0447 case 0xf8:
0448 case 0xfa:
0449 case 0xfb:
0450 case 0xfc:
0451 case 0xfe:
0452 case 0xff:
0453 return 1;
0454 case 0xf1:
0455 case 0xf3:
0456 return 2;
0457 case 0xf2:
0458 return 3;
0459 case 0xf0:
0460 return 0;
0461 case 0xf7:
0462 break;
0463 case 0xf4:
0464 case 0xf5:
0465 case 0xf9:
0466 case 0xfd:
0467 break;
0468 default:
0469 switch (status & 0xf0) {
0470 case 0x80:
0471 case 0x90:
0472 case 0xa0:
0473 case 0xb0:
0474 case 0xe0:
0475 return 3;
0476 case 0xc0:
0477 case 0xd0:
0478 return 2;
0479 default:
0480 break;
0481 }
0482 break;
0483 }
0484
0485 return -EINVAL;
0486 }
0487
0488 static int latter_fill_midi_msg(struct snd_ff *ff,
0489 struct snd_rawmidi_substream *substream,
0490 unsigned int port)
0491 {
0492 u32 data = {0};
0493 u8 *buf = (u8 *)&data;
0494 int consumed;
0495
0496 buf[0] = port << 4;
0497 consumed = snd_rawmidi_transmit_peek(substream, buf + 1, 3);
0498 if (consumed <= 0)
0499 return consumed;
0500
0501 if (!ff->on_sysex[port]) {
0502 if (buf[1] != 0xf0) {
0503 if (consumed < calculate_message_bytes(buf[1]))
0504 return 0;
0505 } else {
0506
0507 ff->on_sysex[port] = true;
0508 }
0509
0510 buf[0] |= consumed;
0511 } else {
0512 if (buf[1] != 0xf7) {
0513 if (buf[2] == 0xf7 || buf[3] == 0xf7) {
0514
0515 consumed -= 1;
0516 }
0517
0518 buf[0] |= consumed;
0519 } else {
0520
0521 ff->on_sysex[port] = false;
0522 consumed = 1;
0523 buf[0] |= 0x0f;
0524 }
0525 }
0526
0527 ff->msg_buf[port][0] = cpu_to_le32(data);
0528 ff->rx_bytes[port] = consumed;
0529
0530 return 1;
0531 }
0532
0533 const struct snd_ff_protocol snd_ff_protocol_latter = {
0534 .handle_midi_msg = latter_handle_midi_msg,
0535 .fill_midi_msg = latter_fill_midi_msg,
0536 .get_clock = latter_get_clock,
0537 .switch_fetching_mode = latter_switch_fetching_mode,
0538 .allocate_resources = latter_allocate_resources,
0539 .begin_session = latter_begin_session,
0540 .finish_session = latter_finish_session,
0541 .dump_status = latter_dump_status,
0542 };