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, 36 struct snd_pcm_substream *pcm, 37 __be32 *buffer, unsigned int frames) 38 { 39 struct amdtp_tscm *p = s->protocol; 40 struct snd_pcm_runtime *runtime = pcm->runtime; 41 unsigned int channels, remaining_frames, i, c; 42 const u32 *src; 43 44 channels = p->pcm_channels; 45 src = (void *)runtime->dma_area + 46 frames_to_bytes(runtime, s->pcm_buffer_pointer); 47 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; 48 49 for (i = 0; i < frames; ++i) { 50 for (c = 0; c < channels; ++c) { 51 buffer[c] = cpu_to_be32(*src); 52 src++; 53 } 54 buffer += s->data_block_quadlets; 55 if (--remaining_frames == 0) 56 src = (void *)runtime->dma_area; 57 } 58 } 59 60 static void read_pcm_s32(struct amdtp_stream *s, 61 struct snd_pcm_substream *pcm, 62 __be32 *buffer, unsigned int frames) 63 { 64 struct amdtp_tscm *p = s->protocol; 65 struct snd_pcm_runtime *runtime = pcm->runtime; 66 unsigned int channels, remaining_frames, i, c; 67 u32 *dst; 68 69 channels = p->pcm_channels; 70 dst = (void *)runtime->dma_area + 71 frames_to_bytes(runtime, s->pcm_buffer_pointer); 72 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; 73 74 /* The first data channel is for event counter. */ 75 buffer += 1; 76 77 for (i = 0; i < frames; ++i) { 78 for (c = 0; c < channels; ++c) { 79 *dst = be32_to_cpu(buffer[c]); 80 dst++; 81 } 82 buffer += s->data_block_quadlets; 83 if (--remaining_frames == 0) 84 dst = (void *)runtime->dma_area; 85 } 86 } 87 88 static void write_pcm_silence(struct amdtp_stream *s, __be32 *buffer, 89 unsigned int data_blocks) 90 { 91 struct amdtp_tscm *p = s->protocol; 92 unsigned int channels, i, c; 93 94 channels = p->pcm_channels; 95 96 for (i = 0; i < data_blocks; ++i) { 97 for (c = 0; c < channels; ++c) 98 buffer[c] = 0x00000000; 99 buffer += s->data_block_quadlets; 100 } 101 } 102 103 int amdtp_tscm_add_pcm_hw_constraints(struct amdtp_stream *s, 104 struct snd_pcm_runtime *runtime) 105 { 106 int err; 107 108 /* 109 * Our implementation allows this protocol to deliver 24 bit sample in 110 * 32bit data channel. 111 */ 112 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 113 if (err < 0) 114 return err; 115 116 return amdtp_stream_add_pcm_hw_constraints(s, runtime); 117 } 118 119 static void read_status_messages(struct amdtp_stream *s, 120 __be32 *buffer, unsigned int data_blocks) 121 { 122 struct snd_tscm *tscm = container_of(s, struct snd_tscm, tx_stream); 123 bool used = READ_ONCE(tscm->hwdep->used); 124 int i; 125 126 for (i = 0; i < data_blocks; i++) { 127 unsigned int index; 128 __be32 before; 129 __be32 after; 130 131 index = be32_to_cpu(buffer[0]) % SNDRV_FIREWIRE_TASCAM_STATE_COUNT; 132 before = tscm->state[index]; 133 after = buffer[s->data_block_quadlets - 1]; 134 135 if (used && index > 4 && index < 16) { 136 __be32 mask; 137 138 if (index == 5) 139 mask = cpu_to_be32(~0x0000ffff); 140 else if (index == 6) 141 mask = cpu_to_be32(~0x0000ffff); 142 else if (index == 8) 143 mask = cpu_to_be32(~0x000f0f00); 144 else 145 mask = cpu_to_be32(~0x00000000); 146 147 if ((before ^ after) & mask) { 148 struct snd_firewire_tascam_change *entry = 149 &tscm->queue[tscm->push_pos]; 150 151 spin_lock_irq(&tscm->lock); 152 entry->index = index; 153 entry->before = before; 154 entry->after = after; 155 if (++tscm->push_pos >= SND_TSCM_QUEUE_COUNT) 156 tscm->push_pos = 0; 157 spin_unlock_irq(&tscm->lock); 158 159 wake_up(&tscm->hwdep_wait); 160 } 161 } 162 163 tscm->state[index] = after; 164 buffer += s->data_block_quadlets; 165 } 166 } 167 168 static unsigned int process_tx_data_blocks(struct amdtp_stream *s, 169 __be32 *buffer, 170 unsigned int data_blocks, 171 unsigned int *syt) 172 { 173 struct snd_pcm_substream *pcm; 174 175 pcm = READ_ONCE(s->pcm); 176 if (data_blocks > 0 && pcm) 177 read_pcm_s32(s, pcm, buffer, data_blocks); 178 179 read_status_messages(s, buffer, data_blocks); 180 181 return data_blocks; 182 } 183 184 static unsigned int process_rx_data_blocks(struct amdtp_stream *s, 185 __be32 *buffer, 186 unsigned int data_blocks, 187 unsigned int *syt) 188 { 189 struct snd_pcm_substream *pcm; 190 191 /* This field is not used. */ 192 *syt = 0x0000; 193 194 pcm = READ_ONCE(s->pcm); 195 if (pcm) 196 write_pcm_s32(s, pcm, buffer, data_blocks); 197 else 198 write_pcm_silence(s, buffer, data_blocks); 199 200 return data_blocks; 201 } 202 203 int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit, 204 enum amdtp_stream_direction dir, unsigned int pcm_channels) 205 { 206 amdtp_stream_process_data_blocks_t process_data_blocks; 207 struct amdtp_tscm *p; 208 unsigned int fmt; 209 int err; 210 211 if (dir == AMDTP_IN_STREAM) { 212 fmt = AMDTP_FMT_TSCM_TX; 213 process_data_blocks = process_tx_data_blocks; 214 } else { 215 fmt = AMDTP_FMT_TSCM_RX; 216 process_data_blocks = process_rx_data_blocks; 217 } 218 219 err = amdtp_stream_init(s, unit, dir, 220 CIP_NONBLOCKING | CIP_SKIP_DBC_ZERO_CHECK, fmt, 221 process_data_blocks, sizeof(struct amdtp_tscm)); 222 if (err < 0) 223 return 0; 224 225 /* Use fixed value for FDF field. */ 226 s->ctx_data.rx.fdf = 0x00; 227 228 /* This protocol uses fixed number of data channels for PCM samples. */ 229 p = s->protocol; 230 p->pcm_channels = pcm_channels; 231 232 return 0; 233 } 234