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