1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * amdtp-tascam.c - a part of driver for TASCAM FireWire series 4 * 5 * Copyright (c) 2015 Takashi Sakamoto 6 */ 7 8 #include <sound/pcm.h> 9 #include "tascam.h" 10 11 #define AMDTP_FMT_TSCM_TX 0x1e 12 #define AMDTP_FMT_TSCM_RX 0x3e 13 14 struct amdtp_tscm { 15 unsigned int pcm_channels; 16 }; 17 18 int amdtp_tscm_set_parameters(struct amdtp_stream *s, unsigned int rate) 19 { 20 struct amdtp_tscm *p = s->protocol; 21 unsigned int data_channels; 22 23 if (amdtp_stream_running(s)) 24 return -EBUSY; 25 26 data_channels = p->pcm_channels; 27 28 /* Packets in in-stream have extra 2 data channels. */ 29 if (s->direction == AMDTP_IN_STREAM) 30 data_channels += 2; 31 32 return amdtp_stream_set_parameters(s, rate, data_channels); 33 } 34 35 static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, 36 __be32 *buffer, unsigned int frames, 37 unsigned int pcm_frames) 38 { 39 struct amdtp_tscm *p = s->protocol; 40 unsigned int channels = p->pcm_channels; 41 struct snd_pcm_runtime *runtime = pcm->runtime; 42 unsigned int pcm_buffer_pointer; 43 int remaining_frames; 44 const u32 *src; 45 int i, c; 46 47 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames; 48 pcm_buffer_pointer %= runtime->buffer_size; 49 50 src = (void *)runtime->dma_area + 51 frames_to_bytes(runtime, pcm_buffer_pointer); 52 remaining_frames = runtime->buffer_size - pcm_buffer_pointer; 53 54 for (i = 0; i < frames; ++i) { 55 for (c = 0; c < channels; ++c) { 56 buffer[c] = cpu_to_be32(*src); 57 src++; 58 } 59 buffer += s->data_block_quadlets; 60 if (--remaining_frames == 0) 61 src = (void *)runtime->dma_area; 62 } 63 } 64 65 static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, 66 __be32 *buffer, unsigned int frames, 67 unsigned int pcm_frames) 68 { 69 struct amdtp_tscm *p = s->protocol; 70 unsigned int channels = p->pcm_channels; 71 struct snd_pcm_runtime *runtime = pcm->runtime; 72 unsigned int pcm_buffer_pointer; 73 int remaining_frames; 74 u32 *dst; 75 int i, c; 76 77 pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames; 78 pcm_buffer_pointer %= runtime->buffer_size; 79 80 dst = (void *)runtime->dma_area + 81 frames_to_bytes(runtime, pcm_buffer_pointer); 82 remaining_frames = runtime->buffer_size - pcm_buffer_pointer; 83 84 /* The first data channel is for event counter. */ 85 buffer += 1; 86 87 for (i = 0; i < frames; ++i) { 88 for (c = 0; c < channels; ++c) { 89 *dst = be32_to_cpu(buffer[c]); 90 dst++; 91 } 92 buffer += s->data_block_quadlets; 93 if (--remaining_frames == 0) 94 dst = (void *)runtime->dma_area; 95 } 96 } 97 98 static void write_pcm_silence(struct amdtp_stream *s, __be32 *buffer, 99 unsigned int data_blocks) 100 { 101 struct amdtp_tscm *p = s->protocol; 102 unsigned int channels, i, c; 103 104 channels = p->pcm_channels; 105 106 for (i = 0; i < data_blocks; ++i) { 107 for (c = 0; c < channels; ++c) 108 buffer[c] = 0x00000000; 109 buffer += s->data_block_quadlets; 110 } 111 } 112 113 int amdtp_tscm_add_pcm_hw_constraints(struct amdtp_stream *s, 114 struct snd_pcm_runtime *runtime) 115 { 116 int err; 117 118 /* 119 * Our implementation allows this protocol to deliver 24 bit sample in 120 * 32bit data channel. 121 */ 122 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 123 if (err < 0) 124 return err; 125 126 return amdtp_stream_add_pcm_hw_constraints(s, runtime); 127 } 128 129 static void read_status_messages(struct amdtp_stream *s, 130 __be32 *buffer, unsigned int data_blocks) 131 { 132 struct snd_tscm *tscm = container_of(s, struct snd_tscm, tx_stream); 133 bool used = READ_ONCE(tscm->hwdep->used); 134 int i; 135 136 for (i = 0; i < data_blocks; i++) { 137 unsigned int index; 138 __be32 before; 139 __be32 after; 140 141 index = be32_to_cpu(buffer[0]) % SNDRV_FIREWIRE_TASCAM_STATE_COUNT; 142 before = tscm->state[index]; 143 after = buffer[s->data_block_quadlets - 1]; 144 145 if (used && index > 4 && index < 16) { 146 __be32 mask; 147 148 if (index == 5) 149 mask = cpu_to_be32(~0x0000ffff); 150 else if (index == 6) 151 mask = cpu_to_be32(~0x0000ffff); 152 else if (index == 8) 153 mask = cpu_to_be32(~0x000f0f00); 154 else 155 mask = cpu_to_be32(~0x00000000); 156 157 if ((before ^ after) & mask) { 158 struct snd_firewire_tascam_change *entry = 159 &tscm->queue[tscm->push_pos]; 160 161 spin_lock_irq(&tscm->lock); 162 entry->index = index; 163 entry->before = before; 164 entry->after = after; 165 if (++tscm->push_pos >= SND_TSCM_QUEUE_COUNT) 166 tscm->push_pos = 0; 167 spin_unlock_irq(&tscm->lock); 168 169 wake_up(&tscm->hwdep_wait); 170 } 171 } 172 173 tscm->state[index] = after; 174 buffer += s->data_block_quadlets; 175 } 176 } 177 178 static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s, 179 const struct pkt_desc *descs, 180 unsigned int packets, 181 struct snd_pcm_substream *pcm) 182 { 183 unsigned int pcm_frames = 0; 184 int i; 185 186 for (i = 0; i < packets; ++i) { 187 const struct pkt_desc *desc = descs + i; 188 __be32 *buf = desc->ctx_payload; 189 unsigned int data_blocks = desc->data_blocks; 190 191 if (pcm) { 192 read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames); 193 pcm_frames += data_blocks; 194 } 195 196 read_status_messages(s, buf, data_blocks); 197 } 198 199 return pcm_frames; 200 } 201 202 static unsigned int process_it_ctx_payloads(struct amdtp_stream *s, 203 const struct pkt_desc *descs, 204 unsigned int packets, 205 struct snd_pcm_substream *pcm) 206 { 207 unsigned int pcm_frames = 0; 208 int i; 209 210 for (i = 0; i < packets; ++i) { 211 const struct pkt_desc *desc = descs + i; 212 __be32 *buf = desc->ctx_payload; 213 unsigned int data_blocks = desc->data_blocks; 214 215 if (pcm) { 216 write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames); 217 pcm_frames += data_blocks; 218 } else { 219 write_pcm_silence(s, buf, data_blocks); 220 } 221 } 222 223 return pcm_frames; 224 } 225 226 int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit, 227 enum amdtp_stream_direction dir, unsigned int pcm_channels) 228 { 229 amdtp_stream_process_ctx_payloads_t process_ctx_payloads; 230 struct amdtp_tscm *p; 231 unsigned int fmt; 232 int err; 233 234 if (dir == AMDTP_IN_STREAM) { 235 fmt = AMDTP_FMT_TSCM_TX; 236 process_ctx_payloads = process_ir_ctx_payloads; 237 } else { 238 fmt = AMDTP_FMT_TSCM_RX; 239 process_ctx_payloads = process_it_ctx_payloads; 240 } 241 242 err = amdtp_stream_init(s, unit, dir, 243 CIP_NONBLOCKING | CIP_SKIP_DBC_ZERO_CHECK, fmt, 244 process_ctx_payloads, sizeof(struct amdtp_tscm)); 245 if (err < 0) 246 return 0; 247 248 if (dir == AMDTP_OUT_STREAM) { 249 // Use fixed value for FDF field. 250 s->ctx_data.rx.fdf = 0x00; 251 // Not used. 252 s->ctx_data.rx.syt_override = 0x0000; 253 } 254 255 /* This protocol uses fixed number of data channels for PCM samples. */ 256 p = s->protocol; 257 p->pcm_channels = pcm_channels; 258 259 return 0; 260 } 261