hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/sound/firewire/tascam/amdtp-tascam.c
....@@ -1,9 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * amdtp-tascam.c - a part of driver for TASCAM FireWire series
34 *
45 * Copyright (c) 2015 Takashi Sakamoto
5
- *
6
- * Licensed under the terms of the GNU General Public License, version 2.
76 */
87
98 #include <sound/pcm.h>
....@@ -33,19 +32,24 @@
3332 return amdtp_stream_set_parameters(s, rate, data_channels);
3433 }
3534
36
-static void write_pcm_s32(struct amdtp_stream *s,
37
- struct snd_pcm_substream *pcm,
38
- __be32 *buffer, unsigned int frames)
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)
3938 {
4039 struct amdtp_tscm *p = s->protocol;
40
+ unsigned int channels = p->pcm_channels;
4141 struct snd_pcm_runtime *runtime = pcm->runtime;
42
- unsigned int channels, remaining_frames, i, c;
42
+ unsigned int pcm_buffer_pointer;
43
+ int remaining_frames;
4344 const u32 *src;
45
+ int i, c;
4446
45
- channels = p->pcm_channels;
47
+ pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
48
+ pcm_buffer_pointer %= runtime->buffer_size;
49
+
4650 src = (void *)runtime->dma_area +
47
- frames_to_bytes(runtime, s->pcm_buffer_pointer);
48
- remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
51
+ frames_to_bytes(runtime, pcm_buffer_pointer);
52
+ remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
4953
5054 for (i = 0; i < frames; ++i) {
5155 for (c = 0; c < channels; ++c) {
....@@ -58,19 +62,24 @@
5862 }
5963 }
6064
61
-static void read_pcm_s32(struct amdtp_stream *s,
62
- struct snd_pcm_substream *pcm,
63
- __be32 *buffer, unsigned int frames)
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)
6468 {
6569 struct amdtp_tscm *p = s->protocol;
70
+ unsigned int channels = p->pcm_channels;
6671 struct snd_pcm_runtime *runtime = pcm->runtime;
67
- unsigned int channels, remaining_frames, i, c;
72
+ unsigned int pcm_buffer_pointer;
73
+ int remaining_frames;
6874 u32 *dst;
75
+ int i, c;
6976
70
- channels = p->pcm_channels;
77
+ pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
78
+ pcm_buffer_pointer %= runtime->buffer_size;
79
+
7180 dst = (void *)runtime->dma_area +
72
- frames_to_bytes(runtime, s->pcm_buffer_pointer);
73
- remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
81
+ frames_to_bytes(runtime, pcm_buffer_pointer);
82
+ remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
7483
7584 /* The first data channel is for event counter. */
7685 buffer += 1;
....@@ -117,65 +126,132 @@
117126 return amdtp_stream_add_pcm_hw_constraints(s, runtime);
118127 }
119128
120
-static unsigned int process_tx_data_blocks(struct amdtp_stream *s,
121
- __be32 *buffer,
122
- unsigned int data_blocks,
123
- unsigned int *syt)
129
+static void read_status_messages(struct amdtp_stream *s,
130
+ __be32 *buffer, unsigned int data_blocks)
124131 {
125
- struct snd_pcm_substream *pcm;
132
+ struct snd_tscm *tscm = container_of(s, struct snd_tscm, tx_stream);
133
+ bool used = READ_ONCE(tscm->hwdep->used);
134
+ int i;
126135
127
- pcm = READ_ONCE(s->pcm);
128
- if (data_blocks > 0 && pcm)
129
- read_pcm_s32(s, pcm, buffer, data_blocks);
136
+ for (i = 0; i < data_blocks; i++) {
137
+ unsigned int index;
138
+ __be32 before;
139
+ __be32 after;
130140
131
- /* A place holder for control messages. */
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];
132144
133
- return data_blocks;
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
+ unsigned long flag;
161
+
162
+ spin_lock_irqsave(&tscm->lock, flag);
163
+ entry->index = index;
164
+ entry->before = before;
165
+ entry->after = after;
166
+ if (++tscm->push_pos >= SND_TSCM_QUEUE_COUNT)
167
+ tscm->push_pos = 0;
168
+ spin_unlock_irqrestore(&tscm->lock, flag);
169
+
170
+ wake_up(&tscm->hwdep_wait);
171
+ }
172
+ }
173
+
174
+ tscm->state[index] = after;
175
+ buffer += s->data_block_quadlets;
176
+ }
134177 }
135178
136
-static unsigned int process_rx_data_blocks(struct amdtp_stream *s,
137
- __be32 *buffer,
138
- unsigned int data_blocks,
139
- unsigned int *syt)
179
+static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
180
+ const struct pkt_desc *descs,
181
+ unsigned int packets,
182
+ struct snd_pcm_substream *pcm)
140183 {
141
- struct snd_pcm_substream *pcm;
184
+ unsigned int pcm_frames = 0;
185
+ int i;
142186
143
- /* This field is not used. */
144
- *syt = 0x0000;
187
+ for (i = 0; i < packets; ++i) {
188
+ const struct pkt_desc *desc = descs + i;
189
+ __be32 *buf = desc->ctx_payload;
190
+ unsigned int data_blocks = desc->data_blocks;
145191
146
- pcm = READ_ONCE(s->pcm);
147
- if (pcm)
148
- write_pcm_s32(s, pcm, buffer, data_blocks);
149
- else
150
- write_pcm_silence(s, buffer, data_blocks);
192
+ if (pcm) {
193
+ read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
194
+ pcm_frames += data_blocks;
195
+ }
151196
152
- return data_blocks;
197
+ read_status_messages(s, buf, data_blocks);
198
+ }
199
+
200
+ return pcm_frames;
201
+}
202
+
203
+static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
204
+ const struct pkt_desc *descs,
205
+ unsigned int packets,
206
+ struct snd_pcm_substream *pcm)
207
+{
208
+ unsigned int pcm_frames = 0;
209
+ int i;
210
+
211
+ for (i = 0; i < packets; ++i) {
212
+ const struct pkt_desc *desc = descs + i;
213
+ __be32 *buf = desc->ctx_payload;
214
+ unsigned int data_blocks = desc->data_blocks;
215
+
216
+ if (pcm) {
217
+ write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
218
+ pcm_frames += data_blocks;
219
+ } else {
220
+ write_pcm_silence(s, buf, data_blocks);
221
+ }
222
+ }
223
+
224
+ return pcm_frames;
153225 }
154226
155227 int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit,
156228 enum amdtp_stream_direction dir, unsigned int pcm_channels)
157229 {
158
- amdtp_stream_process_data_blocks_t process_data_blocks;
230
+ amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
159231 struct amdtp_tscm *p;
160232 unsigned int fmt;
161233 int err;
162234
163235 if (dir == AMDTP_IN_STREAM) {
164236 fmt = AMDTP_FMT_TSCM_TX;
165
- process_data_blocks = process_tx_data_blocks;
237
+ process_ctx_payloads = process_ir_ctx_payloads;
166238 } else {
167239 fmt = AMDTP_FMT_TSCM_RX;
168
- process_data_blocks = process_rx_data_blocks;
240
+ process_ctx_payloads = process_it_ctx_payloads;
169241 }
170242
171243 err = amdtp_stream_init(s, unit, dir,
172
- CIP_NONBLOCKING | CIP_SKIP_DBC_ZERO_CHECK, fmt,
173
- process_data_blocks, sizeof(struct amdtp_tscm));
244
+ CIP_NONBLOCKING | CIP_SKIP_DBC_ZERO_CHECK, fmt,
245
+ process_ctx_payloads, sizeof(struct amdtp_tscm));
174246 if (err < 0)
175247 return 0;
176248
177
- /* Use fixed value for FDF field. */
178
- s->fdf = 0x00;
249
+ if (dir == AMDTP_OUT_STREAM) {
250
+ // Use fixed value for FDF field.
251
+ s->ctx_data.rx.fdf = 0x00;
252
+ // Not used.
253
+ s->ctx_data.rx.syt_override = 0x0000;
254
+ }
179255
180256 /* This protocol uses fixed number of data channels for PCM samples. */
181257 p = s->protocol;