ASoC: fsl_sai: Fix channel swap issue on i.MX8MP
[platform/kernel/linux-starfive.git] / sound / firewire / amdtp-am824.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * AM824 format in Audio and Music Data Transmission Protocol (IEC 61883-6)
4  *
5  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
6  * Copyright (c) 2015 Takashi Sakamoto <o-takashi@sakamocchi.jp>
7  */
8
9 #include <linux/slab.h>
10
11 #include "amdtp-am824.h"
12
13 #define CIP_FMT_AM              0x10
14
15 /* "Clock-based rate control mode" is just supported. */
16 #define AMDTP_FDF_AM824         0x00
17
18 /*
19  * Nominally 3125 bytes/second, but the MIDI port's clock might be
20  * 1% too slow, and the bus clock 100 ppm too fast.
21  */
22 #define MIDI_BYTES_PER_SECOND   3093
23
24 /*
25  * Several devices look only at the first eight data blocks.
26  * In any case, this is more than enough for the MIDI data rate.
27  */
28 #define MAX_MIDI_RX_BLOCKS      8
29
30 struct amdtp_am824 {
31         struct snd_rawmidi_substream *midi[AM824_MAX_CHANNELS_FOR_MIDI * 8];
32         int midi_fifo_limit;
33         int midi_fifo_used[AM824_MAX_CHANNELS_FOR_MIDI * 8];
34         unsigned int pcm_channels;
35         unsigned int midi_ports;
36
37         u8 pcm_positions[AM824_MAX_CHANNELS_FOR_PCM];
38         u8 midi_position;
39 };
40
41 /**
42  * amdtp_am824_set_parameters - set stream parameters
43  * @s: the AMDTP stream to configure
44  * @rate: the sample rate
45  * @pcm_channels: the number of PCM samples in each data block, to be encoded
46  *                as AM824 multi-bit linear audio
47  * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
48  * @double_pcm_frames: one data block transfers two PCM frames
49  *
50  * The parameters must be set before the stream is started, and must not be
51  * changed while the stream is running.
52  */
53 int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate,
54                                unsigned int pcm_channels,
55                                unsigned int midi_ports,
56                                bool double_pcm_frames)
57 {
58         struct amdtp_am824 *p = s->protocol;
59         unsigned int midi_channels;
60         unsigned int pcm_frame_multiplier;
61         int i, err;
62
63         if (amdtp_stream_running(s))
64                 return -EINVAL;
65
66         if (pcm_channels > AM824_MAX_CHANNELS_FOR_PCM)
67                 return -EINVAL;
68
69         midi_channels = DIV_ROUND_UP(midi_ports, 8);
70         if (midi_channels > AM824_MAX_CHANNELS_FOR_MIDI)
71                 return -EINVAL;
72
73         if (WARN_ON(amdtp_stream_running(s)) ||
74             WARN_ON(pcm_channels > AM824_MAX_CHANNELS_FOR_PCM) ||
75             WARN_ON(midi_channels > AM824_MAX_CHANNELS_FOR_MIDI))
76                 return -EINVAL;
77
78         /*
79          * In IEC 61883-6, one data block represents one event. In ALSA, one
80          * event equals to one PCM frame. But Dice has a quirk at higher
81          * sampling rate to transfer two PCM frames in one data block.
82          */
83         if (double_pcm_frames)
84                 pcm_frame_multiplier = 2;
85         else
86                 pcm_frame_multiplier = 1;
87
88         err = amdtp_stream_set_parameters(s, rate, pcm_channels + midi_channels,
89                                           pcm_frame_multiplier);
90         if (err < 0)
91                 return err;
92
93         if (s->direction == AMDTP_OUT_STREAM)
94                 s->ctx_data.rx.fdf = AMDTP_FDF_AM824 | s->sfc;
95
96         p->pcm_channels = pcm_channels;
97         p->midi_ports = midi_ports;
98
99         /* init the position map for PCM and MIDI channels */
100         for (i = 0; i < pcm_channels; i++)
101                 p->pcm_positions[i] = i;
102         p->midi_position = p->pcm_channels;
103
104         /*
105          * We do not know the actual MIDI FIFO size of most devices.  Just
106          * assume two bytes, i.e., one byte can be received over the bus while
107          * the previous one is transmitted over MIDI.
108          * (The value here is adjusted for midi_ratelimit_per_packet().)
109          */
110         p->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1;
111
112         return 0;
113 }
114 EXPORT_SYMBOL_GPL(amdtp_am824_set_parameters);
115
116 /**
117  * amdtp_am824_set_pcm_position - set an index of data channel for a channel
118  *                                of PCM frame
119  * @s: the AMDTP stream
120  * @index: the index of data channel in an data block
121  * @position: the channel of PCM frame
122  */
123 void amdtp_am824_set_pcm_position(struct amdtp_stream *s, unsigned int index,
124                                  unsigned int position)
125 {
126         struct amdtp_am824 *p = s->protocol;
127
128         if (index < p->pcm_channels)
129                 p->pcm_positions[index] = position;
130 }
131 EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_position);
132
133 /**
134  * amdtp_am824_set_midi_position - set a index of data channel for MIDI
135  *                                 conformant data channel
136  * @s: the AMDTP stream
137  * @position: the index of data channel in an data block
138  */
139 void amdtp_am824_set_midi_position(struct amdtp_stream *s,
140                                    unsigned int position)
141 {
142         struct amdtp_am824 *p = s->protocol;
143
144         p->midi_position = position;
145 }
146 EXPORT_SYMBOL_GPL(amdtp_am824_set_midi_position);
147
148 static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
149                           __be32 *buffer, unsigned int frames,
150                           unsigned int pcm_frames)
151 {
152         struct amdtp_am824 *p = s->protocol;
153         unsigned int channels = p->pcm_channels;
154         struct snd_pcm_runtime *runtime = pcm->runtime;
155         unsigned int pcm_buffer_pointer;
156         int remaining_frames;
157         const u32 *src;
158         int i, c;
159
160         pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
161         pcm_buffer_pointer %= runtime->buffer_size;
162
163         src = (void *)runtime->dma_area +
164                                 frames_to_bytes(runtime, pcm_buffer_pointer);
165         remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
166
167         for (i = 0; i < frames; ++i) {
168                 for (c = 0; c < channels; ++c) {
169                         buffer[p->pcm_positions[c]] =
170                                         cpu_to_be32((*src >> 8) | 0x40000000);
171                         src++;
172                 }
173                 buffer += s->data_block_quadlets;
174                 if (--remaining_frames == 0)
175                         src = (void *)runtime->dma_area;
176         }
177 }
178
179 static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm,
180                          __be32 *buffer, unsigned int frames,
181                          unsigned int pcm_frames)
182 {
183         struct amdtp_am824 *p = s->protocol;
184         unsigned int channels = p->pcm_channels;
185         struct snd_pcm_runtime *runtime = pcm->runtime;
186         unsigned int pcm_buffer_pointer;
187         int remaining_frames;
188         u32 *dst;
189         int i, c;
190
191         pcm_buffer_pointer = s->pcm_buffer_pointer + pcm_frames;
192         pcm_buffer_pointer %= runtime->buffer_size;
193
194         dst  = (void *)runtime->dma_area +
195                                 frames_to_bytes(runtime, pcm_buffer_pointer);
196         remaining_frames = runtime->buffer_size - pcm_buffer_pointer;
197
198         for (i = 0; i < frames; ++i) {
199                 for (c = 0; c < channels; ++c) {
200                         *dst = be32_to_cpu(buffer[p->pcm_positions[c]]) << 8;
201                         dst++;
202                 }
203                 buffer += s->data_block_quadlets;
204                 if (--remaining_frames == 0)
205                         dst = (void *)runtime->dma_area;
206         }
207 }
208
209 static void write_pcm_silence(struct amdtp_stream *s,
210                               __be32 *buffer, unsigned int frames)
211 {
212         struct amdtp_am824 *p = s->protocol;
213         unsigned int i, c, channels = p->pcm_channels;
214
215         for (i = 0; i < frames; ++i) {
216                 for (c = 0; c < channels; ++c)
217                         buffer[p->pcm_positions[c]] = cpu_to_be32(0x40000000);
218                 buffer += s->data_block_quadlets;
219         }
220 }
221
222 /**
223  * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream
224  * @s:          the AMDTP stream for AM824 data block, must be initialized.
225  * @runtime:    the PCM substream runtime
226  *
227  */
228 int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s,
229                                        struct snd_pcm_runtime *runtime)
230 {
231         int err;
232
233         err = amdtp_stream_add_pcm_hw_constraints(s, runtime);
234         if (err < 0)
235                 return err;
236
237         /* AM824 in IEC 61883-6 can deliver 24bit data. */
238         return snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
239 }
240 EXPORT_SYMBOL_GPL(amdtp_am824_add_pcm_hw_constraints);
241
242 /**
243  * amdtp_am824_midi_trigger - start/stop playback/capture with a MIDI device
244  * @s: the AMDTP stream
245  * @port: index of MIDI port
246  * @midi: the MIDI device to be started, or %NULL to stop the current device
247  *
248  * Call this function on a running isochronous stream to enable the actual
249  * transmission of MIDI data.  This function should be called from the MIDI
250  * device's .trigger callback.
251  */
252 void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port,
253                               struct snd_rawmidi_substream *midi)
254 {
255         struct amdtp_am824 *p = s->protocol;
256
257         if (port < p->midi_ports)
258                 WRITE_ONCE(p->midi[port], midi);
259 }
260 EXPORT_SYMBOL_GPL(amdtp_am824_midi_trigger);
261
262 /*
263  * To avoid sending MIDI bytes at too high a rate, assume that the receiving
264  * device has a FIFO, and track how much it is filled.  This values increases
265  * by one whenever we send one byte in a packet, but the FIFO empties at
266  * a constant rate independent of our packet rate.  One packet has syt_interval
267  * samples, so the number of bytes that empty out of the FIFO, per packet(!),
268  * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate.  To avoid storing
269  * fractional values, the values in midi_fifo_used[] are measured in bytes
270  * multiplied by the sample rate.
271  */
272 static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port)
273 {
274         struct amdtp_am824 *p = s->protocol;
275         int used;
276
277         used = p->midi_fifo_used[port];
278         if (used == 0) /* common shortcut */
279                 return true;
280
281         used -= MIDI_BYTES_PER_SECOND * s->syt_interval;
282         used = max(used, 0);
283         p->midi_fifo_used[port] = used;
284
285         return used < p->midi_fifo_limit;
286 }
287
288 static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port)
289 {
290         struct amdtp_am824 *p = s->protocol;
291
292         p->midi_fifo_used[port] += amdtp_rate_table[s->sfc];
293 }
294
295 static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
296                         unsigned int frames, unsigned int data_block_counter)
297 {
298         struct amdtp_am824 *p = s->protocol;
299         unsigned int f, port;
300         u8 *b;
301
302         for (f = 0; f < frames; f++) {
303                 b = (u8 *)&buffer[p->midi_position];
304
305                 port = (data_block_counter + f) % 8;
306                 if (f < MAX_MIDI_RX_BLOCKS &&
307                     midi_ratelimit_per_packet(s, port) &&
308                     p->midi[port] != NULL &&
309                     snd_rawmidi_transmit(p->midi[port], &b[1], 1) == 1) {
310                         midi_rate_use_one_byte(s, port);
311                         b[0] = 0x81;
312                 } else {
313                         b[0] = 0x80;
314                         b[1] = 0;
315                 }
316                 b[2] = 0;
317                 b[3] = 0;
318
319                 buffer += s->data_block_quadlets;
320         }
321 }
322
323 static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
324                         unsigned int frames, unsigned int data_block_counter)
325 {
326         struct amdtp_am824 *p = s->protocol;
327         int len;
328         u8 *b;
329         int f;
330
331         for (f = 0; f < frames; f++) {
332                 unsigned int port = f;
333
334                 if (!(s->flags & CIP_UNALIGHED_DBC))
335                         port += data_block_counter;
336                 port %= 8;
337                 b = (u8 *)&buffer[p->midi_position];
338
339                 len = b[0] - 0x80;
340                 if ((1 <= len) &&  (len <= 3) && (p->midi[port]))
341                         snd_rawmidi_receive(p->midi[port], b + 1, len);
342
343                 buffer += s->data_block_quadlets;
344         }
345 }
346
347 static void process_it_ctx_payloads(struct amdtp_stream *s, const struct pkt_desc *desc,
348                                     unsigned int count, struct snd_pcm_substream *pcm)
349 {
350         struct amdtp_am824 *p = s->protocol;
351         unsigned int pcm_frames = 0;
352         int i;
353
354         for (i = 0; i < count; ++i) {
355                 __be32 *buf = desc->ctx_payload;
356                 unsigned int data_blocks = desc->data_blocks;
357
358                 if (pcm) {
359                         write_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
360                         pcm_frames += data_blocks * s->pcm_frame_multiplier;
361                 } else {
362                         write_pcm_silence(s, buf, data_blocks);
363                 }
364
365                 if (p->midi_ports) {
366                         write_midi_messages(s, buf, data_blocks,
367                                             desc->data_block_counter);
368                 }
369
370                 desc = amdtp_stream_next_packet_desc(s, desc);
371         }
372 }
373
374 static void process_ir_ctx_payloads(struct amdtp_stream *s, const struct pkt_desc *desc,
375                                     unsigned int count, struct snd_pcm_substream *pcm)
376 {
377         struct amdtp_am824 *p = s->protocol;
378         unsigned int pcm_frames = 0;
379         int i;
380
381         for (i = 0; i < count; ++i) {
382                 __be32 *buf = desc->ctx_payload;
383                 unsigned int data_blocks = desc->data_blocks;
384
385                 if (pcm) {
386                         read_pcm_s32(s, pcm, buf, data_blocks, pcm_frames);
387                         pcm_frames += data_blocks * s->pcm_frame_multiplier;
388                 }
389
390                 if (p->midi_ports) {
391                         read_midi_messages(s, buf, data_blocks,
392                                            desc->data_block_counter);
393                 }
394
395                 desc = amdtp_stream_next_packet_desc(s, desc);
396         }
397 }
398
399 /**
400  * amdtp_am824_init - initialize an AMDTP stream structure to handle AM824
401  *                    data block
402  * @s: the AMDTP stream to initialize
403  * @unit: the target of the stream
404  * @dir: the direction of stream
405  * @flags: the details of the streaming protocol consist of cip_flags enumeration-constants.
406  */
407 int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
408                      enum amdtp_stream_direction dir, unsigned int flags)
409 {
410         amdtp_stream_process_ctx_payloads_t process_ctx_payloads;
411
412         if (dir == AMDTP_IN_STREAM)
413                 process_ctx_payloads = process_ir_ctx_payloads;
414         else
415                 process_ctx_payloads = process_it_ctx_payloads;
416
417         return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
418                         process_ctx_payloads, sizeof(struct amdtp_am824));
419 }
420 EXPORT_SYMBOL_GPL(amdtp_am824_init);