summaryrefslogtreecommitdiffstats
path: root/sound/firewire
diff options
context:
space:
mode:
authorTakashi Iwai2015-09-29 12:52:07 +0200
committerTakashi Iwai2015-09-29 12:52:07 +0200
commitd8dfacf8b50c260d79864933ac82a8198a0908a9 (patch)
treeb172eb8643de7bd9f9439c58031b06c98116d86a /sound/firewire
parentALSA: usb-audio: harmless underflow in snd_audigy2nx_led_put() (diff)
parentALSA: firewire-lib: complete AM824 data block processing layer (diff)
downloadkernel-qcow2-linux-d8dfacf8b50c260d79864933ac82a8198a0908a9.tar.gz
kernel-qcow2-linux-d8dfacf8b50c260d79864933ac82a8198a0908a9.tar.xz
kernel-qcow2-linux-d8dfacf8b50c260d79864933ac82a8198a0908a9.zip
Merge branch 'topic/firewire-update' into for-next
Diffstat (limited to 'sound/firewire')
-rw-r--r--sound/firewire/Makefile2
-rw-r--r--sound/firewire/amdtp-am824.c465
-rw-r--r--sound/firewire/amdtp-am824.h52
-rw-r--r--sound/firewire/amdtp-stream.c (renamed from sound/firewire/amdtp.c)377
-rw-r--r--sound/firewire/amdtp-stream.h (renamed from sound/firewire/amdtp.h)116
-rw-r--r--sound/firewire/bebob/bebob.h2
-rw-r--r--sound/firewire/bebob/bebob_midi.c16
-rw-r--r--sound/firewire/bebob/bebob_pcm.c14
-rw-r--r--sound/firewire/bebob/bebob_stream.c34
-rw-r--r--sound/firewire/dice/dice-midi.c12
-rw-r--r--sound/firewire/dice/dice-pcm.c12
-rw-r--r--sound/firewire/dice/dice-stream.c22
-rw-r--r--sound/firewire/dice/dice.h2
-rw-r--r--sound/firewire/fcp.c2
-rw-r--r--sound/firewire/fireworks/fireworks.c12
-rw-r--r--sound/firewire/fireworks/fireworks.h2
-rw-r--r--sound/firewire/fireworks/fireworks_midi.c12
-rw-r--r--sound/firewire/fireworks/fireworks_pcm.c12
-rw-r--r--sound/firewire/fireworks/fireworks_stream.c8
-rw-r--r--sound/firewire/oxfw/oxfw-midi.c16
-rw-r--r--sound/firewire/oxfw/oxfw-pcm.c10
-rw-r--r--sound/firewire/oxfw/oxfw-stream.c11
-rw-r--r--sound/firewire/oxfw/oxfw.h2
23 files changed, 730 insertions, 483 deletions
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
index 8b37f084b2ab..6a8a71371efd 100644
--- a/sound/firewire/Makefile
+++ b/sound/firewire/Makefile
@@ -1,5 +1,5 @@
snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \
- fcp.o cmp.o amdtp.o
+ fcp.o cmp.o amdtp-stream.o amdtp-am824.o
snd-oxfw-objs := oxfw.o
snd-isight-objs := isight.o
snd-scs1x-objs := scs1x.o
diff --git a/sound/firewire/amdtp-am824.c b/sound/firewire/amdtp-am824.c
new file mode 100644
index 000000000000..fe4b83f65831
--- /dev/null
+++ b/sound/firewire/amdtp-am824.c
@@ -0,0 +1,465 @@
+/*
+ * AM824 format in Audio and Music Data Transmission Protocol (IEC 61883-6)
+ *
+ * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
+ * Copyright (c) 2015 Takashi Sakamoto <o-takashi@sakamocchi.jp>
+ *
+ * Licensed under the terms of the GNU General Public License, version 2.
+ */
+
+#include <linux/slab.h>
+
+#include "amdtp-am824.h"
+
+#define CIP_FMT_AM 0x10
+
+/* "Clock-based rate control mode" is just supported. */
+#define AMDTP_FDF_AM824 0x00
+
+/*
+ * Nominally 3125 bytes/second, but the MIDI port's clock might be
+ * 1% too slow, and the bus clock 100 ppm too fast.
+ */
+#define MIDI_BYTES_PER_SECOND 3093
+
+/*
+ * Several devices look only at the first eight data blocks.
+ * In any case, this is more than enough for the MIDI data rate.
+ */
+#define MAX_MIDI_RX_BLOCKS 8
+
+struct amdtp_am824 {
+ struct snd_rawmidi_substream *midi[AM824_MAX_CHANNELS_FOR_MIDI * 8];
+ int midi_fifo_limit;
+ int midi_fifo_used[AM824_MAX_CHANNELS_FOR_MIDI * 8];
+ unsigned int pcm_channels;
+ unsigned int midi_ports;
+
+ u8 pcm_positions[AM824_MAX_CHANNELS_FOR_PCM];
+ u8 midi_position;
+
+ void (*transfer_samples)(struct amdtp_stream *s,
+ struct snd_pcm_substream *pcm,
+ __be32 *buffer, unsigned int frames);
+
+ unsigned int frame_multiplier;
+};
+
+/**
+ * amdtp_am824_set_parameters - set stream parameters
+ * @s: the AMDTP stream to configure
+ * @rate: the sample rate
+ * @pcm_channels: the number of PCM samples in each data block, to be encoded
+ * as AM824 multi-bit linear audio
+ * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
+ * @double_pcm_frames: one data block transfers two PCM frames
+ *
+ * The parameters must be set before the stream is started, and must not be
+ * changed while the stream is running.
+ */
+int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate,
+ unsigned int pcm_channels,
+ unsigned int midi_ports,
+ bool double_pcm_frames)
+{
+ struct amdtp_am824 *p = s->protocol;
+ unsigned int midi_channels;
+ unsigned int i;
+ int err;
+
+ if (amdtp_stream_running(s))
+ return -EINVAL;
+
+ if (pcm_channels > AM824_MAX_CHANNELS_FOR_PCM)
+ return -EINVAL;
+
+ midi_channels = DIV_ROUND_UP(midi_ports, 8);
+ if (midi_channels > AM824_MAX_CHANNELS_FOR_MIDI)
+ return -EINVAL;
+
+ if (WARN_ON(amdtp_stream_running(s)) ||
+ WARN_ON(pcm_channels > AM824_MAX_CHANNELS_FOR_PCM) ||
+ WARN_ON(midi_channels > AM824_MAX_CHANNELS_FOR_MIDI))
+ return -EINVAL;
+
+ err = amdtp_stream_set_parameters(s, rate,
+ pcm_channels + midi_channels);
+ if (err < 0)
+ return err;
+
+ s->fdf = AMDTP_FDF_AM824 | s->sfc;
+
+ p->pcm_channels = pcm_channels;
+ p->midi_ports = midi_ports;
+
+ /*
+ * In IEC 61883-6, one data block represents one event. In ALSA, one
+ * event equals to one PCM frame. But Dice has a quirk at higher
+ * sampling rate to transfer two PCM frames in one data block.
+ */
+ if (double_pcm_frames)
+ p->frame_multiplier = 2;
+ else
+ p->frame_multiplier = 1;
+
+ /* init the position map for PCM and MIDI channels */
+ for (i = 0; i < pcm_channels; i++)
+ p->pcm_positions[i] = i;
+ p->midi_position = p->pcm_channels;
+
+ /*
+ * We do not know the actual MIDI FIFO size of most devices. Just
+ * assume two bytes, i.e., one byte can be received over the bus while
+ * the previous one is transmitted over MIDI.
+ * (The value here is adjusted for midi_ratelimit_per_packet().)
+ */
+ p->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(amdtp_am824_set_parameters);
+
+/**
+ * amdtp_am824_set_pcm_position - set an index of data channel for a channel
+ * of PCM frame
+ * @s: the AMDTP stream
+ * @index: the index of data channel in an data block
+ * @position: the channel of PCM frame
+ */
+void amdtp_am824_set_pcm_position(struct amdtp_stream *s, unsigned int index,
+ unsigned int position)
+{
+ struct amdtp_am824 *p = s->protocol;
+
+ if (index < p->pcm_channels)
+ p->pcm_positions[index] = position;
+}
+EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_position);
+
+/**
+ * amdtp_am824_set_midi_position - set a index of data channel for MIDI
+ * conformant data channel
+ * @s: the AMDTP stream
+ * @position: the index of data channel in an data block
+ */
+void amdtp_am824_set_midi_position(struct amdtp_stream *s,
+ unsigned int position)
+{
+ struct amdtp_am824 *p = s->protocol;
+
+ p->midi_position = position;
+}
+EXPORT_SYMBOL_GPL(amdtp_am824_set_midi_position);
+
+static void write_pcm_s32(struct amdtp_stream *s,
+ struct snd_pcm_substream *pcm,
+ __be32 *buffer, unsigned int frames)
+{
+ struct amdtp_am824 *p = s->protocol;
+ struct snd_pcm_runtime *runtime = pcm->runtime;
+ unsigned int channels, remaining_frames, i, c;
+ const u32 *src;
+
+ channels = p->pcm_channels;
+ src = (void *)runtime->dma_area +
+ frames_to_bytes(runtime, s->pcm_buffer_pointer);
+ remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
+
+ for (i = 0; i < frames; ++i) {
+ for (c = 0; c < channels; ++c) {
+ buffer[p->pcm_positions[c]] =
+ cpu_to_be32((*src >> 8) | 0x40000000);
+ src++;
+ }
+ buffer += s->data_block_quadlets;
+ if (--remaining_frames == 0)
+ src = (void *)runtime->dma_area;
+ }
+}
+
+static void write_pcm_s16(struct amdtp_stream *s,
+ struct snd_pcm_substream *pcm,
+ __be32 *buffer, unsigned int frames)
+{
+ struct amdtp_am824 *p = s->protocol;
+ struct snd_pcm_runtime *runtime = pcm->runtime;
+ unsigned int channels, remaining_frames, i, c;
+ const u16 *src;
+
+ channels = p->pcm_channels;
+ src = (void *)runtime->dma_area +
+ frames_to_bytes(runtime, s->pcm_buffer_pointer);
+ remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
+
+ for (i = 0; i < frames; ++i) {
+ for (c = 0; c < channels; ++c) {
+ buffer[p->pcm_positions[c]] =
+ cpu_to_be32((*src << 8) | 0x42000000);
+ src++;
+ }
+ buffer += s->data_block_quadlets;
+ if (--remaining_frames == 0)
+ src = (void *)runtime->dma_area;
+ }
+}
+
+static void read_pcm_s32(struct amdtp_stream *s,
+ struct snd_pcm_substream *pcm,
+ __be32 *buffer, unsigned int frames)
+{
+ struct amdtp_am824 *p = s->protocol;
+ struct snd_pcm_runtime *runtime = pcm->runtime;
+ unsigned int channels, remaining_frames, i, c;
+ u32 *dst;
+
+ channels = p->pcm_channels;
+ dst = (void *)runtime->dma_area +
+ frames_to_bytes(runtime, s->pcm_buffer_pointer);
+ remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
+
+ for (i = 0; i < frames; ++i) {
+ for (c = 0; c < channels; ++c) {
+ *dst = be32_to_cpu(buffer[p->pcm_positions[c]]) << 8;
+ dst++;
+ }
+ buffer += s->data_block_quadlets;
+ if (--remaining_frames == 0)
+ dst = (void *)runtime->dma_area;
+ }
+}
+
+static void write_pcm_silence(struct amdtp_stream *s,
+ __be32 *buffer, unsigned int frames)
+{
+ struct amdtp_am824 *p = s->protocol;
+ unsigned int i, c, channels = p->pcm_channels;
+
+ for (i = 0; i < frames; ++i) {
+ for (c = 0; c < channels; ++c)
+ buffer[p->pcm_positions[c]] = cpu_to_be32(0x40000000);
+ buffer += s->data_block_quadlets;
+ }
+}
+
+/**
+ * amdtp_am824_set_pcm_format - set the PCM format
+ * @s: the AMDTP stream to configure
+ * @format: the format of the ALSA PCM device
+ *
+ * The sample format must be set after the other parameters (rate/PCM channels/
+ * MIDI) and before the stream is started, and must not be changed while the
+ * stream is running.
+ */
+void amdtp_am824_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format)
+{
+ struct amdtp_am824 *p = s->protocol;
+
+ if (WARN_ON(amdtp_stream_pcm_running(s)))
+ return;
+
+ switch (format) {
+ default:
+ WARN_ON(1);
+ /* fall through */
+ case SNDRV_PCM_FORMAT_S16:
+ if (s->direction == AMDTP_OUT_STREAM) {
+ p->transfer_samples = write_pcm_s16;
+ break;
+ }
+ WARN_ON(1);
+ /* fall through */
+ case SNDRV_PCM_FORMAT_S32:
+ if (s->direction == AMDTP_OUT_STREAM)
+ p->transfer_samples = write_pcm_s32;
+ else
+ p->transfer_samples = read_pcm_s32;
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_format);
+
+/**
+ * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream
+ * @s: the AMDTP stream for AM824 data block, must be initialized.
+ * @runtime: the PCM substream runtime
+ *
+ */
+int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s,
+ struct snd_pcm_runtime *runtime)
+{
+ int err;
+
+ err = amdtp_stream_add_pcm_hw_constraints(s, runtime);
+ if (err < 0)
+ return err;
+
+ /* AM824 in IEC 61883-6 can deliver 24bit data. */
+ return snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+}
+EXPORT_SYMBOL_GPL(amdtp_am824_add_pcm_hw_constraints);
+
+/**
+ * amdtp_am824_midi_trigger - start/stop playback/capture with a MIDI device
+ * @s: the AMDTP stream
+ * @port: index of MIDI port
+ * @midi: the MIDI device to be started, or %NULL to stop the current device
+ *
+ * Call this function on a running isochronous stream to enable the actual
+ * transmission of MIDI data. This function should be called from the MIDI
+ * device's .trigger callback.
+ */
+void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port,
+ struct snd_rawmidi_substream *midi)
+{
+ struct amdtp_am824 *p = s->protocol;
+
+ if (port < p->midi_ports)
+ ACCESS_ONCE(p->midi[port]) = midi;
+}
+EXPORT_SYMBOL_GPL(amdtp_am824_midi_trigger);
+
+/*
+ * To avoid sending MIDI bytes at too high a rate, assume that the receiving
+ * device has a FIFO, and track how much it is filled. This values increases
+ * by one whenever we send one byte in a packet, but the FIFO empties at
+ * a constant rate independent of our packet rate. One packet has syt_interval
+ * samples, so the number of bytes that empty out of the FIFO, per packet(!),
+ * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate. To avoid storing
+ * fractional values, the values in midi_fifo_used[] are measured in bytes
+ * multiplied by the sample rate.
+ */
+static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port)
+{
+ struct amdtp_am824 *p = s->protocol;
+ int used;
+
+ used = p->midi_fifo_used[port];
+ if (used == 0) /* common shortcut */
+ return true;
+
+ used -= MIDI_BYTES_PER_SECOND * s->syt_interval;
+ used = max(used, 0);
+ p->midi_fifo_used[port] = used;
+
+ return used < p->midi_fifo_limit;
+}
+
+static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port)
+{
+ struct amdtp_am824 *p = s->protocol;
+
+ p->midi_fifo_used[port] += amdtp_rate_table[s->sfc];
+}
+
+static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
+ unsigned int frames)
+{
+ struct amdtp_am824 *p = s->protocol;
+ unsigned int f, port;
+ u8 *b;
+
+ for (f = 0; f < frames; f++) {
+ b = (u8 *)&buffer[p->midi_position];
+
+ port = (s->data_block_counter + f) % 8;
+ if (f < MAX_MIDI_RX_BLOCKS &&
+ midi_ratelimit_per_packet(s, port) &&
+ p->midi[port] != NULL &&
+ snd_rawmidi_transmit(p->midi[port], &b[1], 1) == 1) {
+ midi_rate_use_one_byte(s, port);
+ b[0] = 0x81;
+ } else {
+ b[0] = 0x80;
+ b[1] = 0;
+ }
+ b[2] = 0;
+ b[3] = 0;
+
+ buffer += s->data_block_quadlets;
+ }
+}
+
+static void read_midi_messages(struct amdtp_stream *s,
+ __be32 *buffer, unsigned int frames)
+{
+ struct amdtp_am824 *p = s->protocol;
+ unsigned int f, port;
+ int len;
+ u8 *b;
+
+ for (f = 0; f < frames; f++) {
+ port = (s->data_block_counter + f) % 8;
+ b = (u8 *)&buffer[p->midi_position];
+
+ len = b[0] - 0x80;
+ if ((1 <= len) && (len <= 3) && (p->midi[port]))
+ snd_rawmidi_receive(p->midi[port], b + 1, len);
+
+ buffer += s->data_block_quadlets;
+ }
+}
+
+unsigned int process_rx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
+ unsigned int data_blocks, unsigned int *syt)
+{
+ struct amdtp_am824 *p = s->protocol;
+ struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
+ unsigned int pcm_frames;
+
+ if (pcm) {
+ p->transfer_samples(s, pcm, buffer, data_blocks);
+ pcm_frames = data_blocks * p->frame_multiplier;
+ } else {
+ write_pcm_silence(s, buffer, data_blocks);
+ pcm_frames = 0;
+ }
+
+ if (p->midi_ports)
+ write_midi_messages(s, buffer, data_blocks);
+
+ return pcm_frames;
+}
+
+unsigned int process_tx_data_blocks(struct amdtp_stream *s, __be32 *buffer,
+ unsigned int data_blocks, unsigned int *syt)
+{
+ struct amdtp_am824 *p = s->protocol;
+ struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);
+ unsigned int pcm_frames;
+
+ if (pcm) {
+ p->transfer_samples(s, pcm, buffer, data_blocks);
+ pcm_frames = data_blocks * p->frame_multiplier;
+ } else {
+ pcm_frames = 0;
+ }
+
+ if (p->midi_ports)
+ read_midi_messages(s, buffer, data_blocks);
+
+ return pcm_frames;
+}
+
+/**
+ * amdtp_am824_init - initialize an AMDTP stream structure to handle AM824
+ * data block
+ * @s: the AMDTP stream to initialize
+ * @unit: the target of the stream
+ * @dir: the direction of stream
+ * @flags: the packet transmission method to use
+ */
+int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
+ enum amdtp_stream_direction dir, enum cip_flags flags)
+{
+ amdtp_stream_process_data_blocks_t process_data_blocks;
+
+ if (dir == AMDTP_IN_STREAM)
+ process_data_blocks = process_tx_data_blocks;
+ else
+ process_data_blocks = process_rx_data_blocks;
+
+ return amdtp_stream_init(s, unit, dir, flags, CIP_FMT_AM,
+ process_data_blocks,
+ sizeof(struct amdtp_am824));
+}
+EXPORT_SYMBOL_GPL(amdtp_am824_init);
diff --git a/sound/firewire/amdtp-am824.h b/sound/firewire/amdtp-am824.h
new file mode 100644
index 000000000000..73b07b3109db
--- /dev/null
+++ b/sound/firewire/amdtp-am824.h
@@ -0,0 +1,52 @@
+#ifndef SOUND_FIREWIRE_AMDTP_AM824_H_INCLUDED
+#define SOUND_FIREWIRE_AMDTP_AM824_H_INCLUDED
+
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+
+#include "amdtp-stream.h"
+
+#define AM824_IN_PCM_FORMAT_BITS SNDRV_PCM_FMTBIT_S32
+
+#define AM824_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \
+ SNDRV_PCM_FMTBIT_S32)
+
+/*
+ * This module supports maximum 64 PCM channels for one PCM stream
+ * This is for our convenience.
+ */
+#define AM824_MAX_CHANNELS_FOR_PCM 64
+
+/*
+ * AMDTP packet can include channels for MIDI conformant data.
+ * Each MIDI conformant data channel includes 8 MPX-MIDI data stream.
+ * Each MPX-MIDI data stream includes one data stream from/to MIDI ports.
+ *
+ * This module supports maximum 1 MIDI conformant data channels.
+ * Then this AMDTP packets can transfer maximum 8 MIDI data streams.
+ */
+#define AM824_MAX_CHANNELS_FOR_MIDI 1
+
+int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate,
+ unsigned int pcm_channels,
+ unsigned int midi_ports,
+ bool double_pcm_frames);
+
+void amdtp_am824_set_pcm_position(struct amdtp_stream *s, unsigned int index,
+ unsigned int position);
+
+void amdtp_am824_set_midi_position(struct amdtp_stream *s,
+ unsigned int position);
+
+int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s,
+ struct snd_pcm_runtime *runtime);
+
+void amdtp_am824_set_pcm_format(struct amdtp_stream *s,
+ snd_pcm_format_t format);
+
+void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port,
+ struct snd_rawmidi_substream *midi);
+
+int amdtp_am824_init(struct amdtp_stream *s, struct fw_unit *unit,
+ enum amdtp_stream_direction dir, enum cip_flags flags);
+#endif
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp-stream.c
index 2a153d260836..fa10b58a0957 100644
--- a/sound/firewire/amdtp.c
+++ b/sound/firewire/amdtp-stream.c
@@ -11,28 +11,14 @@
#include <linux/firewire.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/sched.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
-#include <sound/rawmidi.h>
-#include "amdtp.h"
+#include "amdtp-stream.h"
#define TICKS_PER_CYCLE 3072
#define CYCLES_PER_SECOND 8000
#define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND)
-/*
- * Nominally 3125 bytes/second, but the MIDI port's clock might be
- * 1% too slow, and the bus clock 100 ppm too fast.
- */
-#define MIDI_BYTES_PER_SECOND 3093
-
-/*
- * Several devices look only at the first eight data blocks.
- * In any case, this is more than enough for the MIDI data rate.
- */
-#define MAX_MIDI_RX_BLOCKS 8
-
#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 microseconds */
/* isochronous header parameters */
@@ -55,12 +41,8 @@
#define CIP_SYT_MASK 0x0000ffff
#define CIP_SYT_NO_INFO 0xffff
-/*
- * Audio and Music transfer protocol specific parameters
- * only "Clock-based rate control mode" is supported
- */
-#define CIP_FMT_AM (0x10 << CIP_FMT_SHIFT)
-#define AMDTP_FDF_AM824 (0 << (CIP_FDF_SHIFT + 3))
+/* Audio and Music transfer protocol specific parameters */
+#define CIP_FMT_AM 0x10
#define AMDTP_FDF_NO_DATA 0xff
/* TODO: make these configurable */
@@ -78,10 +60,23 @@ static void pcm_period_tasklet(unsigned long data);
* @unit: the target of the stream
* @dir: the direction of stream
* @flags: the packet transmission method to use
+ * @fmt: the value of fmt field in CIP header
+ * @process_data_blocks: callback handler to process data blocks
+ * @protocol_size: the size to allocate newly for protocol
*/
int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
- enum amdtp_stream_direction dir, enum cip_flags flags)
+ enum amdtp_stream_direction dir, enum cip_flags flags,
+ unsigned int fmt,
+ amdtp_stream_process_data_blocks_t process_data_blocks,
+ unsigned int protocol_size)
{
+ if (process_data_blocks == NULL)
+ return -EINVAL;
+
+ s->protocol = kzalloc(protocol_size, GFP_KERNEL);
+ if (!s->protocol)
+ return -ENOMEM;
+
s->unit = unit;
s->direction = dir;
s->flags = flags;
@@ -94,6 +89,9 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
s->callbacked = false;
s->sync_slave = NULL;
+ s->fmt = fmt;
+ s->process_data_blocks = process_data_blocks;
+
return 0;
}
EXPORT_SYMBOL(amdtp_stream_init);
@@ -105,6 +103,7 @@ EXPORT_SYMBOL(amdtp_stream_init);
void amdtp_stream_destroy(struct amdtp_stream *s)
{
WARN_ON(amdtp_stream_running(s));
+ kfree(s->protocol);
mutex_destroy(&s->mutex);
}
EXPORT_SYMBOL(amdtp_stream_destroy);
@@ -141,11 +140,6 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
{
int err;
- /* AM824 in IEC 61883-6 can deliver 24bit data */
- err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
- if (err < 0)
- goto end;
-
/*
* Currently firewire-lib processes 16 packets in one software
* interrupt callback. This equals to 2msec but actually the
@@ -190,39 +184,25 @@ EXPORT_SYMBOL(amdtp_stream_add_pcm_hw_constraints);
* amdtp_stream_set_parameters - set stream parameters
* @s: the AMDTP stream to configure
* @rate: the sample rate
- * @pcm_channels: the number of PCM samples in each data block, to be encoded
- * as AM824 multi-bit linear audio
- * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
+ * @data_block_quadlets: the size of a data block in quadlet unit
*
* The parameters must be set before the stream is started, and must not be
* changed while the stream is running.
*/
-void amdtp_stream_set_parameters(struct amdtp_stream *s,
- unsigned int rate,
- unsigned int pcm_channels,
- unsigned int midi_ports)
+int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate,
+ unsigned int data_block_quadlets)
{
- unsigned int i, sfc, midi_channels;
-
- midi_channels = DIV_ROUND_UP(midi_ports, 8);
-
- if (WARN_ON(amdtp_stream_running(s)) |
- WARN_ON(pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM) |
- WARN_ON(midi_channels > AMDTP_MAX_CHANNELS_FOR_MIDI))
- return;
+ unsigned int sfc;
- for (sfc = 0; sfc < ARRAY_SIZE(amdtp_rate_table); ++sfc)
+ for (sfc = 0; sfc < ARRAY_SIZE(amdtp_rate_table); ++sfc) {
if (amdtp_rate_table[sfc] == rate)
- goto sfc_found;
- WARN_ON(1);
- return;
+ break;
+ }
+ if (sfc == ARRAY_SIZE(amdtp_rate_table))
+ return -EINVAL;
-sfc_found:
- s->pcm_channels = pcm_channels;
s->sfc = sfc;
- s->data_block_quadlets = s->pcm_channels + midi_channels;
- s->midi_ports = midi_ports;
-
+ s->data_block_quadlets = data_block_quadlets;
s->syt_interval = amdtp_syt_intervals[sfc];
/* default buffering in the device */
@@ -231,18 +211,7 @@ sfc_found:
/* additional buffering needed to adjust for no-data packets */
s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate;
- /* init the position map for PCM and MIDI channels */
- for (i = 0; i < pcm_channels; i++)
- s->pcm_positions[i] = i;
- s->midi_position = s->pcm_channels;
-
- /*
- * We do not know the actual MIDI FIFO size of most devices. Just
- * assume two bytes, i.e., one byte can be received over the bus while
- * the previous one is transmitted over MIDI.
- * (The value here is adjusted for midi_ratelimit_per_packet().)
- */
- s->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1;
+ return 0;
}
EXPORT_SYMBOL(amdtp_stream_set_parameters);
@@ -264,52 +233,6 @@ unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s)
}
EXPORT_SYMBOL(amdtp_stream_get_max_payload);
-static void write_pcm_s16(struct amdtp_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames);
-static void write_pcm_s32(struct amdtp_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames);
-static void read_pcm_s32(struct amdtp_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames);
-
-/**
- * amdtp_stream_set_pcm_format - set the PCM format
- * @s: the AMDTP stream to configure
- * @format: the format of the ALSA PCM device
- *
- * The sample format must be set after the other parameters (rate/PCM channels/
- * MIDI) and before the stream is started, and must not be changed while the
- * stream is running.
- */
-void amdtp_stream_set_pcm_format(struct amdtp_stream *s,
- snd_pcm_format_t format)
-{
- if (WARN_ON(amdtp_stream_pcm_running(s)))
- return;
-
- switch (format) {
- default:
- WARN_ON(1);
- /* fall through */
- case SNDRV_PCM_FORMAT_S16:
- if (s->direction == AMDTP_OUT_STREAM) {
- s->transfer_samples = write_pcm_s16;
- break;
- }
- WARN_ON(1);
- /* fall through */
- case SNDRV_PCM_FORMAT_S32:
- if (s->direction == AMDTP_OUT_STREAM)
- s->transfer_samples = write_pcm_s32;
- else
- s->transfer_samples = read_pcm_s32;
- break;
- }
-}
-EXPORT_SYMBOL(amdtp_stream_set_pcm_format);
-
/**
* amdtp_stream_pcm_prepare - prepare PCM device for running
* @s: the AMDTP stream
@@ -412,182 +335,12 @@ static unsigned int calculate_syt(struct amdtp_stream *s,
}
}
-static void write_pcm_s32(struct amdtp_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames)
-{
- struct snd_pcm_runtime *runtime = pcm->runtime;
- unsigned int channels, remaining_frames, i, c;
- const u32 *src;
-
- channels = s->pcm_channels;
- src = (void *)runtime->dma_area +
- frames_to_bytes(runtime, s->pcm_buffer_pointer);
- remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
-
- for (i = 0; i < frames; ++i) {
- for (c = 0; c < channels; ++c) {
- buffer[s->pcm_positions[c]] =
- cpu_to_be32((*src >> 8) | 0x40000000);
- src++;
- }
- buffer += s->data_block_quadlets;
- if (--remaining_frames == 0)
- src = (void *)runtime->dma_area;
- }
-}
-
-static void write_pcm_s16(struct amdtp_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames)
-{
- struct snd_pcm_runtime *runtime = pcm->runtime;
- unsigned int channels, remaining_frames, i, c;
- const u16 *src;
-
- channels = s->pcm_channels;
- src = (void *)runtime->dma_area +
- frames_to_bytes(runtime, s->pcm_buffer_pointer);
- remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
-
- for (i = 0; i < frames; ++i) {
- for (c = 0; c < channels; ++c) {
- buffer[s->pcm_positions[c]] =
- cpu_to_be32((*src << 8) | 0x42000000);
- src++;
- }
- buffer += s->data_block_quadlets;
- if (--remaining_frames == 0)
- src = (void *)runtime->dma_area;
- }
-}
-
-static void read_pcm_s32(struct amdtp_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames)
-{
- struct snd_pcm_runtime *runtime = pcm->runtime;
- unsigned int channels, remaining_frames, i, c;
- u32 *dst;
-
- channels = s->pcm_channels;
- dst = (void *)runtime->dma_area +
- frames_to_bytes(runtime, s->pcm_buffer_pointer);
- remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
-
- for (i = 0; i < frames; ++i) {
- for (c = 0; c < channels; ++c) {
- *dst = be32_to_cpu(buffer[s->pcm_positions[c]]) << 8;
- dst++;
- }
- buffer += s->data_block_quadlets;
- if (--remaining_frames == 0)
- dst = (void *)runtime->dma_area;
- }
-}
-
-static void write_pcm_silence(struct amdtp_stream *s,
- __be32 *buffer, unsigned int frames)
-{
- unsigned int i, c;
-
- for (i = 0; i < frames; ++i) {
- for (c = 0; c < s->pcm_channels; ++c)
- buffer[s->pcm_positions[c]] = cpu_to_be32(0x40000000);
- buffer += s->data_block_quadlets;
- }
-}
-
-/*
- * To avoid sending MIDI bytes at too high a rate, assume that the receiving
- * device has a FIFO, and track how much it is filled. This values increases
- * by one whenever we send one byte in a packet, but the FIFO empties at
- * a constant rate independent of our packet rate. One packet has syt_interval
- * samples, so the number of bytes that empty out of the FIFO, per packet(!),
- * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate. To avoid storing
- * fractional values, the values in midi_fifo_used[] are measured in bytes
- * multiplied by the sample rate.
- */
-static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port)
-{
- int used;
-
- used = s->midi_fifo_used[port];
- if (used == 0) /* common shortcut */
- return true;
-
- used -= MIDI_BYTES_PER_SECOND * s->syt_interval;
- used = max(used, 0);
- s->midi_fifo_used[port] = used;
-
- return used < s->midi_fifo_limit;
-}
-
-static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port)
-{
- s->midi_fifo_used[port] += amdtp_rate_table[s->sfc];
-}
-
-static void write_midi_messages(struct amdtp_stream *s,
- __be32 *buffer, unsigned int frames)
-{
- unsigned int f, port;
- u8 *b;
-
- for (f = 0; f < frames; f++) {
- b = (u8 *)&buffer[s->midi_position];
-
- port = (s->data_block_counter + f) % 8;
- if (f < MAX_MIDI_RX_BLOCKS &&
- midi_ratelimit_per_packet(s, port) &&
- s->midi[port] != NULL &&
- snd_rawmidi_transmit(s->midi[port], &b[1], 1) == 1) {
- midi_rate_use_one_byte(s, port);
- b[0] = 0x81;
- } else {
- b[0] = 0x80;
- b[1] = 0;
- }
- b[2] = 0;
- b[3] = 0;
-
- buffer += s->data_block_quadlets;
- }
-}
-
-static void read_midi_messages(struct amdtp_stream *s,
- __be32 *buffer, unsigned int frames)
-{
- unsigned int f, port;
- int len;
- u8 *b;
-
- for (f = 0; f < frames; f++) {
- port = (s->data_block_counter + f) % 8;
- b = (u8 *)&buffer[s->midi_position];
-
- len = b[0] - 0x80;
- if ((1 <= len) && (len <= 3) && (s->midi[port]))
- snd_rawmidi_receive(s->midi[port], b + 1, len);
-
- buffer += s->data_block_quadlets;
- }
-}
-
static void update_pcm_pointers(struct amdtp_stream *s,
struct snd_pcm_substream *pcm,
unsigned int frames)
{
unsigned int ptr;
- /*
- * In IEC 61883-6, one data block represents one event. In ALSA, one
- * event equals to one PCM frame. But Dice has a quirk to transfer
- * two PCM frames in one data block.
- */
- if (s->double_pcm_frames)
- frames *= 2;
-
ptr = s->pcm_buffer_pointer + frames;
if (ptr >= pcm->runtime->buffer_size)
ptr -= pcm->runtime->buffer_size;
@@ -656,23 +409,19 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
{
__be32 *buffer;
unsigned int payload_length;
+ unsigned int pcm_frames;
struct snd_pcm_substream *pcm;
buffer = s->buffer.packets[s->packet_index].buffer;
+ pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt);
+
buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
(s->data_block_quadlets << CIP_DBS_SHIFT) |
s->data_block_counter);
- buffer[1] = cpu_to_be32(CIP_EOH | CIP_FMT_AM | AMDTP_FDF_AM824 |
- (s->sfc << CIP_FDF_SHIFT) | syt);
- buffer += 2;
-
- pcm = ACCESS_ONCE(s->pcm);
- if (pcm)
- s->transfer_samples(s, pcm, buffer, data_blocks);
- else
- write_pcm_silence(s, buffer, data_blocks);
- if (s->midi_ports)
- write_midi_messages(s, buffer, data_blocks);
+ buffer[1] = cpu_to_be32(CIP_EOH |
+ ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) |
+ ((s->fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) |
+ (syt & CIP_SYT_MASK));
s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
@@ -680,8 +429,9 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
if (queue_out_packet(s, payload_length, false) < 0)
return -EIO;
- if (pcm)
- update_pcm_pointers(s, pcm, data_blocks);
+ pcm = ACCESS_ONCE(s->pcm);
+ if (pcm && pcm_frames > 0)
+ update_pcm_pointers(s, pcm, pcm_frames);
/* No need to return the number of handled data blocks. */
return 0;
@@ -689,11 +439,13 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
static int handle_in_packet(struct amdtp_stream *s,
unsigned int payload_quadlets, __be32 *buffer,
- unsigned int *data_blocks)
+ unsigned int *data_blocks, unsigned int syt)
{
u32 cip_header[2];
+ unsigned int fmt, fdf;
unsigned int data_block_quadlets, data_block_counter, dbc_interval;
- struct snd_pcm_substream *pcm = NULL;
+ struct snd_pcm_substream *pcm;
+ unsigned int pcm_frames;
bool lost;
cip_header[0] = be32_to_cpu(buffer[0]);
@@ -704,19 +456,28 @@ static int handle_in_packet(struct amdtp_stream *s,
* For convenience, also check FMT field is AM824 or not.
*/
if (((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) ||
- ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH) ||
- ((cip_header[1] & CIP_FMT_MASK) != CIP_FMT_AM)) {
+ ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) {
dev_info_ratelimited(&s->unit->device,
"Invalid CIP header for AMDTP: %08X:%08X\n",
cip_header[0], cip_header[1]);
*data_blocks = 0;
+ pcm_frames = 0;
goto end;
}
+ /* Check valid protocol or not. */
+ fmt = (cip_header[1] & CIP_FMT_MASK) >> CIP_FMT_SHIFT;
+ if (fmt != s->fmt) {
+ dev_err(&s->unit->device,
+ "Detect unexpected protocol: %08x %08x\n",
+ cip_header[0], cip_header[1]);
+ return -EIO;
+ }
+
/* Calculate data blocks */
+ fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT;
if (payload_quadlets < 3 ||
- ((cip_header[1] & CIP_FDF_MASK) ==
- (AMDTP_FDF_NO_DATA << CIP_FDF_SHIFT))) {
+ (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) {
*data_blocks = 0;
} else {
data_block_quadlets =
@@ -763,16 +524,7 @@ static int handle_in_packet(struct amdtp_stream *s,
return -EIO;
}
- if (*data_blocks > 0) {
- buffer += 2;
-
- pcm = ACCESS_ONCE(s->pcm);
- if (pcm)
- s->transfer_samples(s, pcm, buffer, *data_blocks);
-
- if (s->midi_ports)
- read_midi_messages(s, buffer, *data_blocks);
- }
+ pcm_frames = s->process_data_blocks(s, buffer + 2, *data_blocks, &syt);
if (s->flags & CIP_DBC_IS_END_EVENT)
s->data_block_counter = data_block_counter;
@@ -783,8 +535,9 @@ end:
if (queue_in_packet(s) < 0)
return -EIO;
- if (pcm)
- update_pcm_pointers(s, pcm, *data_blocks);
+ pcm = ACCESS_ONCE(s->pcm);
+ if (pcm && pcm_frames > 0)
+ update_pcm_pointers(s, pcm, pcm_frames);
return 0;
}
@@ -854,15 +607,15 @@ static void in_stream_callback(struct fw_iso_context *context, u32 cycle,
break;
}
+ syt = be32_to_cpu(buffer[1]) & CIP_SYT_MASK;
if (handle_in_packet(s, payload_quadlets, buffer,
- &data_blocks) < 0) {
+ &data_blocks, syt) < 0) {
s->packet_index = -1;
break;
}
/* Process sync slave stream */
if (s->sync_slave && s->sync_slave->callbacked) {
- syt = be32_to_cpu(buffer[1]) & CIP_SYT_MASK;
if (handle_out_packet(s->sync_slave,
data_blocks, syt) < 0) {
s->packet_index = -1;
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp-stream.h
index b2cf9e75693b..8775704a3665 100644
--- a/sound/firewire/amdtp.h
+++ b/sound/firewire/amdtp-stream.h
@@ -4,6 +4,7 @@
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
#include <sound/asound.h>
#include "packets-buffer.h"
@@ -80,100 +81,78 @@ enum cip_sfc {
CIP_SFC_COUNT
};
-#define AMDTP_IN_PCM_FORMAT_BITS SNDRV_PCM_FMTBIT_S32
-
-#define AMDTP_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \
- SNDRV_PCM_FMTBIT_S32)
-
-
-/*
- * This module supports maximum 64 PCM channels for one PCM stream
- * This is for our convenience.
- */
-#define AMDTP_MAX_CHANNELS_FOR_PCM 64
-
-/*
- * AMDTP packet can include channels for MIDI conformant data.
- * Each MIDI conformant data channel includes 8 MPX-MIDI data stream.
- * Each MPX-MIDI data stream includes one data stream from/to MIDI ports.
- *
- * This module supports maximum 1 MIDI conformant data channels.
- * Then this AMDTP packets can transfer maximum 8 MIDI data streams.
- */
-#define AMDTP_MAX_CHANNELS_FOR_MIDI 1
-
struct fw_unit;
struct fw_iso_context;
struct snd_pcm_substream;
struct snd_pcm_runtime;
-struct snd_rawmidi_substream;
enum amdtp_stream_direction {
AMDTP_OUT_STREAM = 0,
AMDTP_IN_STREAM
};
+struct amdtp_stream;
+typedef unsigned int (*amdtp_stream_process_data_blocks_t)(
+ struct amdtp_stream *s,
+ __be32 *buffer,
+ unsigned int data_blocks,
+ unsigned int *syt);
struct amdtp_stream {
struct fw_unit *unit;
enum cip_flags flags;
enum amdtp_stream_direction direction;
- struct fw_iso_context *context;
struct mutex mutex;
- enum cip_sfc sfc;
- unsigned int data_block_quadlets;
- unsigned int pcm_channels;
- unsigned int midi_ports;
- void (*transfer_samples)(struct amdtp_stream *s,
- struct snd_pcm_substream *pcm,
- __be32 *buffer, unsigned int frames);
- u8 pcm_positions[AMDTP_MAX_CHANNELS_FOR_PCM];
- u8 midi_position;
-
- unsigned int syt_interval;
- unsigned int transfer_delay;
- unsigned int source_node_id_field;
+ /* For packet processing. */
+ struct fw_iso_context *context;
struct iso_packets_buffer buffer;
-
- struct snd_pcm_substream *pcm;
- struct tasklet_struct period_tasklet;
-
int packet_index;
+
+ /* For CIP headers. */
+ unsigned int source_node_id_field;
+ unsigned int data_block_quadlets;
unsigned int data_block_counter;
+ unsigned int fmt;
+ unsigned int fdf;
+ /* quirk: fixed interval of dbc between previos/current packets. */
+ unsigned int tx_dbc_interval;
+ /* quirk: indicate the value of dbc field in a first packet. */
+ unsigned int tx_first_dbc;
+ /* Internal flags. */
+ enum cip_sfc sfc;
+ unsigned int syt_interval;
+ unsigned int transfer_delay;
unsigned int data_block_state;
-
unsigned int last_syt_offset;
unsigned int syt_offset_state;
+ /* For a PCM substream processing. */
+ struct snd_pcm_substream *pcm;
+ struct tasklet_struct period_tasklet;
unsigned int pcm_buffer_pointer;
unsigned int pcm_period_pointer;
bool pointer_flush;
- bool double_pcm_frames;
-
- struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8];
- int midi_fifo_limit;
- int midi_fifo_used[AMDTP_MAX_CHANNELS_FOR_MIDI * 8];
-
- /* quirk: fixed interval of dbc between previos/current packets. */
- unsigned int tx_dbc_interval;
- /* quirk: indicate the value of dbc field in a first packet. */
- unsigned int tx_first_dbc;
+ /* To wait for first packet. */
bool callbacked;
wait_queue_head_t callback_wait;
struct amdtp_stream *sync_slave;
+
+ /* For backends to process data blocks. */
+ void *protocol;
+ amdtp_stream_process_data_blocks_t process_data_blocks;
};
int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
- enum amdtp_stream_direction dir,
- enum cip_flags flags);
+ enum amdtp_stream_direction dir, enum cip_flags flags,
+ unsigned int fmt,
+ amdtp_stream_process_data_blocks_t process_data_blocks,
+ unsigned int protocol_size);
void amdtp_stream_destroy(struct amdtp_stream *s);
-void amdtp_stream_set_parameters(struct amdtp_stream *s,
- unsigned int rate,
- unsigned int pcm_channels,
- unsigned int midi_ports);
+int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate,
+ unsigned int data_block_quadlets);
unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s);
int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed);
@@ -182,8 +161,7 @@ void amdtp_stream_stop(struct amdtp_stream *s);
int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
struct snd_pcm_runtime *runtime);
-void amdtp_stream_set_pcm_format(struct amdtp_stream *s,
- snd_pcm_format_t format);
+
void amdtp_stream_pcm_prepare(struct amdtp_stream *s);
unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s);
void amdtp_stream_pcm_abort(struct amdtp_stream *s);
@@ -240,24 +218,6 @@ static inline void amdtp_stream_pcm_trigger(struct amdtp_stream *s,
ACCESS_ONCE(s->pcm) = pcm;
}
-/**
- * amdtp_stream_midi_trigger - start/stop playback/capture with a MIDI device
- * @s: the AMDTP stream
- * @port: index of MIDI port
- * @midi: the MIDI device to be started, or %NULL to stop the current device
- *
- * Call this function on a running isochronous stream to enable the actual
- * transmission of MIDI data. This function should be called from the MIDI
- * device's .trigger callback.
- */
-static inline void amdtp_stream_midi_trigger(struct amdtp_stream *s,
- unsigned int port,
- struct snd_rawmidi_substream *midi)
-{
- if (port < s->midi_ports)
- ACCESS_ONCE(s->midi[port]) = midi;
-}
-
static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc)
{
return sfc & 1;
diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h
index d23caca7f369..d3c9d8de289b 100644
--- a/sound/firewire/bebob/bebob.h
+++ b/sound/firewire/bebob/bebob.h
@@ -31,7 +31,7 @@
#include "../fcp.h"
#include "../packets-buffer.h"
#include "../iso-resources.h"
-#include "../amdtp.h"
+#include "../amdtp-am824.h"
#include "../cmp.h"
/* basic register addresses on DM1000/DM1100/DM1500 */
diff --git a/sound/firewire/bebob/bebob_midi.c b/sound/firewire/bebob/bebob_midi.c
index 5681143925cd..90d95be499b0 100644
--- a/sound/firewire/bebob/bebob_midi.c
+++ b/sound/firewire/bebob/bebob_midi.c
@@ -72,11 +72,11 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
spin_lock_irqsave(&bebob->lock, flags);
if (up)
- amdtp_stream_midi_trigger(&bebob->tx_stream,
- substrm->number, substrm);
+ amdtp_am824_midi_trigger(&bebob->tx_stream,
+ substrm->number, substrm);
else
- amdtp_stream_midi_trigger(&bebob->tx_stream,
- substrm->number, NULL);
+ amdtp_am824_midi_trigger(&bebob->tx_stream,
+ substrm->number, NULL);
spin_unlock_irqrestore(&bebob->lock, flags);
}
@@ -89,11 +89,11 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
spin_lock_irqsave(&bebob->lock, flags);
if (up)
- amdtp_stream_midi_trigger(&bebob->rx_stream,
- substrm->number, substrm);
+ amdtp_am824_midi_trigger(&bebob->rx_stream,
+ substrm->number, substrm);
else
- amdtp_stream_midi_trigger(&bebob->rx_stream,
- substrm->number, NULL);
+ amdtp_am824_midi_trigger(&bebob->rx_stream,
+ substrm->number, NULL);
spin_unlock_irqrestore(&bebob->lock, flags);
}
diff --git a/sound/firewire/bebob/bebob_pcm.c b/sound/firewire/bebob/bebob_pcm.c
index c0f018a61fdc..2fdc1f10a2c7 100644
--- a/sound/firewire/bebob/bebob_pcm.c
+++ b/sound/firewire/bebob/bebob_pcm.c
@@ -122,11 +122,11 @@ pcm_init_hw_params(struct snd_bebob *bebob,
SNDRV_PCM_INFO_MMAP_VALID;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- runtime->hw.formats = AMDTP_IN_PCM_FORMAT_BITS;
+ runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS;
s = &bebob->tx_stream;
formations = bebob->tx_stream_formations;
} else {
- runtime->hw.formats = AMDTP_OUT_PCM_FORMAT_BITS;
+ runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS;
s = &bebob->rx_stream;
formations = bebob->rx_stream_formations;
}
@@ -146,7 +146,7 @@ pcm_init_hw_params(struct snd_bebob *bebob,
if (err < 0)
goto end;
- err = amdtp_stream_add_pcm_hw_constraints(s, runtime);
+ err = amdtp_am824_add_pcm_hw_constraints(s, runtime);
end:
return err;
}
@@ -220,8 +220,8 @@ pcm_capture_hw_params(struct snd_pcm_substream *substream,
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
atomic_inc(&bebob->substreams_counter);
- amdtp_stream_set_pcm_format(&bebob->tx_stream,
- params_format(hw_params));
+
+ amdtp_am824_set_pcm_format(&bebob->tx_stream, params_format(hw_params));
return 0;
}
@@ -239,8 +239,8 @@ pcm_playback_hw_params(struct snd_pcm_substream *substream,
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
atomic_inc(&bebob->substreams_counter);
- amdtp_stream_set_pcm_format(&bebob->rx_stream,
- params_format(hw_params));
+
+ amdtp_am824_set_pcm_format(&bebob->rx_stream, params_format(hw_params));
return 0;
}
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c
index 5be5242e1ed8..a2baa478d4ba 100644
--- a/sound/firewire/bebob/bebob_stream.c
+++ b/sound/firewire/bebob/bebob_stream.c
@@ -338,7 +338,7 @@ map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s)
err = -ENOSYS;
goto end;
}
- s->midi_position = stm_pos;
+ amdtp_am824_set_midi_position(s, stm_pos);
midi = stm_pos;
break;
/* for PCM data channel */
@@ -354,11 +354,12 @@ map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s)
case 0x09: /* Digital */
default:
location = pcm + sec_loc;
- if (location >= AMDTP_MAX_CHANNELS_FOR_PCM) {
+ if (location >= AM824_MAX_CHANNELS_FOR_PCM) {
err = -ENOSYS;
goto end;
}
- s->pcm_positions[location] = stm_pos;
+ amdtp_am824_set_pcm_position(s, location,
+ stm_pos);
break;
}
}
@@ -427,12 +428,19 @@ make_both_connections(struct snd_bebob *bebob, unsigned int rate)
index = get_formation_index(rate);
pcm_channels = bebob->tx_stream_formations[index].pcm;
midi_channels = bebob->tx_stream_formations[index].midi;
- amdtp_stream_set_parameters(&bebob->tx_stream,
- rate, pcm_channels, midi_channels * 8);
+ err = amdtp_am824_set_parameters(&bebob->tx_stream, rate,
+ pcm_channels, midi_channels * 8,
+ false);
+ if (err < 0)
+ goto end;
+
pcm_channels = bebob->rx_stream_formations[index].pcm;
midi_channels = bebob->rx_stream_formations[index].midi;
- amdtp_stream_set_parameters(&bebob->rx_stream,
- rate, pcm_channels, midi_channels * 8);
+ err = amdtp_am824_set_parameters(&bebob->rx_stream, rate,
+ pcm_channels, midi_channels * 8,
+ false);
+ if (err < 0)
+ goto end;
/* establish connections for both streams */
err = cmp_connection_establish(&bebob->out_conn,
@@ -530,8 +538,8 @@ int snd_bebob_stream_init_duplex(struct snd_bebob *bebob)
if (err < 0)
goto end;
- err = amdtp_stream_init(&bebob->tx_stream, bebob->unit,
- AMDTP_IN_STREAM, CIP_BLOCKING);
+ err = amdtp_am824_init(&bebob->tx_stream, bebob->unit,
+ AMDTP_IN_STREAM, CIP_BLOCKING);
if (err < 0) {
amdtp_stream_destroy(&bebob->tx_stream);
destroy_both_connections(bebob);
@@ -559,8 +567,8 @@ int snd_bebob_stream_init_duplex(struct snd_bebob *bebob)
if (bebob->maudio_special_quirk)
bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC;
- err = amdtp_stream_init(&bebob->rx_stream, bebob->unit,
- AMDTP_OUT_STREAM, CIP_BLOCKING);
+ err = amdtp_am824_init(&bebob->rx_stream, bebob->unit,
+ AMDTP_OUT_STREAM, CIP_BLOCKING);
if (err < 0) {
amdtp_stream_destroy(&bebob->tx_stream);
amdtp_stream_destroy(&bebob->rx_stream);
@@ -864,8 +872,8 @@ parse_stream_formation(u8 *buf, unsigned int len,
}
}
- if (formation[i].pcm > AMDTP_MAX_CHANNELS_FOR_PCM ||
- formation[i].midi > AMDTP_MAX_CHANNELS_FOR_MIDI)
+ if (formation[i].pcm > AM824_MAX_CHANNELS_FOR_PCM ||
+ formation[i].midi > AM824_MAX_CHANNELS_FOR_MIDI)
return -ENOSYS;
return 0;
diff --git a/sound/firewire/dice/dice-midi.c b/sound/firewire/dice/dice-midi.c
index fe43ce791f84..151b09f240f2 100644
--- a/sound/firewire/dice/dice-midi.c
+++ b/sound/firewire/dice/dice-midi.c
@@ -52,10 +52,10 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
spin_lock_irqsave(&dice->lock, flags);
if (up)
- amdtp_stream_midi_trigger(&dice->tx_stream,
+ amdtp_am824_midi_trigger(&dice->tx_stream,
substrm->number, substrm);
else
- amdtp_stream_midi_trigger(&dice->tx_stream,
+ amdtp_am824_midi_trigger(&dice->tx_stream,
substrm->number, NULL);
spin_unlock_irqrestore(&dice->lock, flags);
@@ -69,11 +69,11 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
spin_lock_irqsave(&dice->lock, flags);
if (up)
- amdtp_stream_midi_trigger(&dice->rx_stream,
- substrm->number, substrm);
+ amdtp_am824_midi_trigger(&dice->rx_stream,
+ substrm->number, substrm);
else
- amdtp_stream_midi_trigger(&dice->rx_stream,
- substrm->number, NULL);
+ amdtp_am824_midi_trigger(&dice->rx_stream,
+ substrm->number, NULL);
spin_unlock_irqrestore(&dice->lock, flags);
}
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c
index 4e67b1da0fe6..9b3431999fc8 100644
--- a/sound/firewire/dice/dice-pcm.c
+++ b/sound/firewire/dice/dice-pcm.c
@@ -133,11 +133,11 @@ static int init_hw_info(struct snd_dice *dice,
SNDRV_PCM_INFO_BLOCK_TRANSFER;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- hw->formats = AMDTP_IN_PCM_FORMAT_BITS;
+ hw->formats = AM824_IN_PCM_FORMAT_BITS;
stream = &dice->tx_stream;
pcm_channels = dice->tx_channels;
} else {
- hw->formats = AMDTP_OUT_PCM_FORMAT_BITS;
+ hw->formats = AM824_OUT_PCM_FORMAT_BITS;
stream = &dice->rx_stream;
pcm_channels = dice->rx_channels;
}
@@ -156,7 +156,7 @@ static int init_hw_info(struct snd_dice *dice,
if (err < 0)
goto end;
- err = amdtp_stream_add_pcm_hw_constraints(stream, runtime);
+ err = amdtp_am824_add_pcm_hw_constraints(stream, runtime);
end:
return err;
}
@@ -243,8 +243,7 @@ static int capture_hw_params(struct snd_pcm_substream *substream,
mutex_unlock(&dice->mutex);
}
- amdtp_stream_set_pcm_format(&dice->tx_stream,
- params_format(hw_params));
+ amdtp_am824_set_pcm_format(&dice->tx_stream, params_format(hw_params));
return 0;
}
@@ -265,8 +264,7 @@ static int playback_hw_params(struct snd_pcm_substream *substream,
mutex_unlock(&dice->mutex);
}
- amdtp_stream_set_pcm_format(&dice->rx_stream,
- params_format(hw_params));
+ amdtp_am824_set_pcm_format(&dice->rx_stream, params_format(hw_params));
return 0;
}
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index 07dbd01d7a6b..2108f7f1a764 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -100,6 +100,7 @@ static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,
{
struct fw_iso_resources *resources;
unsigned int i, mode, pcm_chs, midi_ports;
+ bool double_pcm_frames;
int err;
err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
@@ -125,21 +126,24 @@ static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,
* For this quirk, blocking mode is required and PCM buffer size should
* be aligned to SYT_INTERVAL.
*/
- if (mode > 1) {
+ double_pcm_frames = mode > 1;
+ if (double_pcm_frames) {
rate /= 2;
pcm_chs *= 2;
- stream->double_pcm_frames = true;
- } else {
- stream->double_pcm_frames = false;
}
- amdtp_stream_set_parameters(stream, rate, pcm_chs, midi_ports);
- if (mode > 1) {
+ err = amdtp_am824_set_parameters(stream, rate, pcm_chs, midi_ports,
+ double_pcm_frames);
+ if (err < 0)
+ goto end;
+
+ if (double_pcm_frames) {
pcm_chs /= 2;
for (i = 0; i < pcm_chs; i++) {
- stream->pcm_positions[i] = i * 2;
- stream->pcm_positions[i + pcm_chs] = i * 2 + 1;
+ amdtp_am824_set_pcm_position(stream, i, i * 2);
+ amdtp_am824_set_pcm_position(stream, i + pcm_chs,
+ i * 2 + 1);
}
}
@@ -302,7 +306,7 @@ static int init_stream(struct snd_dice *dice, struct amdtp_stream *stream)
goto end;
resources->channels_mask = 0x00000000ffffffffuLL;
- err = amdtp_stream_init(stream, dice->unit, dir, CIP_BLOCKING);
+ err = amdtp_am824_init(stream, dice->unit, dir, CIP_BLOCKING);
if (err < 0) {
amdtp_stream_destroy(stream);
fw_iso_resources_destroy(resources);
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index ecf5dc862235..101550ac1a24 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -34,7 +34,7 @@
#include <sound/pcm_params.h>
#include <sound/rawmidi.h>
-#include "../amdtp.h"
+#include "../amdtp-am824.h"
#include "../iso-resources.h"
#include "../lib.h"
#include "dice-interface.h"
diff --git a/sound/firewire/fcp.c b/sound/firewire/fcp.c
index 0619597e3a3f..cce19768f43d 100644
--- a/sound/firewire/fcp.c
+++ b/sound/firewire/fcp.c
@@ -17,7 +17,7 @@
#include <linux/delay.h>
#include "fcp.h"
#include "lib.h"
-#include "amdtp.h"
+#include "amdtp-stream.h"
#define CTS_AVC 0x00
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
index c94a432f7cc6..d5b19bc11e59 100644
--- a/sound/firewire/fireworks/fireworks.c
+++ b/sound/firewire/fireworks/fireworks.c
@@ -138,12 +138,12 @@ get_hardware_info(struct snd_efw *efw)
efw->midi_out_ports = hwinfo->midi_out_ports;
efw->midi_in_ports = hwinfo->midi_in_ports;
- if (hwinfo->amdtp_tx_pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM ||
- hwinfo->amdtp_tx_pcm_channels_2x > AMDTP_MAX_CHANNELS_FOR_PCM ||
- hwinfo->amdtp_tx_pcm_channels_4x > AMDTP_MAX_CHANNELS_FOR_PCM ||
- hwinfo->amdtp_rx_pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM ||
- hwinfo->amdtp_rx_pcm_channels_2x > AMDTP_MAX_CHANNELS_FOR_PCM ||
- hwinfo->amdtp_rx_pcm_channels_4x > AMDTP_MAX_CHANNELS_FOR_PCM) {
+ if (hwinfo->amdtp_tx_pcm_channels > AM824_MAX_CHANNELS_FOR_PCM ||
+ hwinfo->amdtp_tx_pcm_channels_2x > AM824_MAX_CHANNELS_FOR_PCM ||
+ hwinfo->amdtp_tx_pcm_channels_4x > AM824_MAX_CHANNELS_FOR_PCM ||
+ hwinfo->amdtp_rx_pcm_channels > AM824_MAX_CHANNELS_FOR_PCM ||
+ hwinfo->amdtp_rx_pcm_channels_2x > AM824_MAX_CHANNELS_FOR_PCM ||
+ hwinfo->amdtp_rx_pcm_channels_4x > AM824_MAX_CHANNELS_FOR_PCM) {
err = -ENOSYS;
goto end;
}
diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h
index 084d414b228c..c7cb7deafe48 100644
--- a/sound/firewire/fireworks/fireworks.h
+++ b/sound/firewire/fireworks/fireworks.h
@@ -29,7 +29,7 @@
#include "../packets-buffer.h"
#include "../iso-resources.h"
-#include "../amdtp.h"
+#include "../amdtp-am824.h"
#include "../cmp.h"
#include "../lib.h"
diff --git a/sound/firewire/fireworks/fireworks_midi.c b/sound/firewire/fireworks/fireworks_midi.c
index cf9c65260439..fba01bbba456 100644
--- a/sound/firewire/fireworks/fireworks_midi.c
+++ b/sound/firewire/fireworks/fireworks_midi.c
@@ -73,10 +73,10 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
spin_lock_irqsave(&efw->lock, flags);
if (up)
- amdtp_stream_midi_trigger(&efw->tx_stream,
+ amdtp_am824_midi_trigger(&efw->tx_stream,
substrm->number, substrm);
else
- amdtp_stream_midi_trigger(&efw->tx_stream,
+ amdtp_am824_midi_trigger(&efw->tx_stream,
substrm->number, NULL);
spin_unlock_irqrestore(&efw->lock, flags);
@@ -90,11 +90,11 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
spin_lock_irqsave(&efw->lock, flags);
if (up)
- amdtp_stream_midi_trigger(&efw->rx_stream,
- substrm->number, substrm);
+ amdtp_am824_midi_trigger(&efw->rx_stream,
+ substrm->number, substrm);
else
- amdtp_stream_midi_trigger(&efw->rx_stream,
- substrm->number, NULL);
+ amdtp_am824_midi_trigger(&efw->rx_stream,
+ substrm->number, NULL);
spin_unlock_irqrestore(&efw->lock, flags);
}
diff --git a/sound/firewire/fireworks/fireworks_pcm.c b/sound/firewire/fireworks/fireworks_pcm.c
index c30b2ffa8dfb..d27135bac513 100644
--- a/sound/firewire/fireworks/fireworks_pcm.c
+++ b/sound/firewire/fireworks/fireworks_pcm.c
@@ -159,11 +159,11 @@ pcm_init_hw_params(struct snd_efw *efw,
SNDRV_PCM_INFO_MMAP_VALID;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- runtime->hw.formats = AMDTP_IN_PCM_FORMAT_BITS;
+ runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS;
s = &efw->tx_stream;
pcm_channels = efw->pcm_capture_channels;
} else {
- runtime->hw.formats = AMDTP_OUT_PCM_FORMAT_BITS;
+ runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS;
s = &efw->rx_stream;
pcm_channels = efw->pcm_playback_channels;
}
@@ -187,7 +187,7 @@ pcm_init_hw_params(struct snd_efw *efw,
if (err < 0)
goto end;
- err = amdtp_stream_add_pcm_hw_constraints(s, runtime);
+ err = amdtp_am824_add_pcm_hw_constraints(s, runtime);
end:
return err;
}
@@ -253,7 +253,8 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
atomic_inc(&efw->capture_substreams);
- amdtp_stream_set_pcm_format(&efw->tx_stream, params_format(hw_params));
+
+ amdtp_am824_set_pcm_format(&efw->tx_stream, params_format(hw_params));
return 0;
}
@@ -270,7 +271,8 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
atomic_inc(&efw->playback_substreams);
- amdtp_stream_set_pcm_format(&efw->rx_stream, params_format(hw_params));
+
+ amdtp_am824_set_pcm_format(&efw->rx_stream, params_format(hw_params));
return 0;
}
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
index 7e353f1f7bff..759f6e3ed44a 100644
--- a/sound/firewire/fireworks/fireworks_stream.c
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -31,7 +31,7 @@ init_stream(struct snd_efw *efw, struct amdtp_stream *stream)
if (err < 0)
goto end;
- err = amdtp_stream_init(stream, efw->unit, s_dir, CIP_BLOCKING);
+ err = amdtp_am824_init(stream, efw->unit, s_dir, CIP_BLOCKING);
if (err < 0) {
amdtp_stream_destroy(stream);
cmp_connection_destroy(conn);
@@ -73,8 +73,10 @@ start_stream(struct snd_efw *efw, struct amdtp_stream *stream,
midi_ports = efw->midi_in_ports;
}
- amdtp_stream_set_parameters(stream, sampling_rate,
- pcm_channels, midi_ports);
+ err = amdtp_am824_set_parameters(stream, sampling_rate,
+ pcm_channels, midi_ports, false);
+ if (err < 0)
+ goto end;
/* establish connection via CMP */
err = cmp_connection_establish(conn,
diff --git a/sound/firewire/oxfw/oxfw-midi.c b/sound/firewire/oxfw/oxfw-midi.c
index 540a30338516..37a86cf69cbf 100644
--- a/sound/firewire/oxfw/oxfw-midi.c
+++ b/sound/firewire/oxfw/oxfw-midi.c
@@ -90,11 +90,11 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
spin_lock_irqsave(&oxfw->lock, flags);
if (up)
- amdtp_stream_midi_trigger(&oxfw->tx_stream,
- substrm->number, substrm);
+ amdtp_am824_midi_trigger(&oxfw->tx_stream,
+ substrm->number, substrm);
else
- amdtp_stream_midi_trigger(&oxfw->tx_stream,
- substrm->number, NULL);
+ amdtp_am824_midi_trigger(&oxfw->tx_stream,
+ substrm->number, NULL);
spin_unlock_irqrestore(&oxfw->lock, flags);
}
@@ -107,11 +107,11 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
spin_lock_irqsave(&oxfw->lock, flags);
if (up)
- amdtp_stream_midi_trigger(&oxfw->rx_stream,
- substrm->number, substrm);
+ amdtp_am824_midi_trigger(&oxfw->rx_stream,
+ substrm->number, substrm);
else
- amdtp_stream_midi_trigger(&oxfw->rx_stream,
- substrm->number, NULL);
+ amdtp_am824_midi_trigger(&oxfw->rx_stream,
+ substrm->number, NULL);
spin_unlock_irqrestore(&oxfw->lock, flags);
}
diff --git a/sound/firewire/oxfw/oxfw-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c
index 9c73930d0278..8d233417695d 100644
--- a/sound/firewire/oxfw/oxfw-pcm.c
+++ b/sound/firewire/oxfw/oxfw-pcm.c
@@ -134,11 +134,11 @@ static int init_hw_params(struct snd_oxfw *oxfw,
SNDRV_PCM_INFO_MMAP_VALID;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
- runtime->hw.formats = AMDTP_IN_PCM_FORMAT_BITS;
+ runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS;
stream = &oxfw->tx_stream;
formats = oxfw->tx_stream_formats;
} else {
- runtime->hw.formats = AMDTP_OUT_PCM_FORMAT_BITS;
+ runtime->hw.formats = AM824_OUT_PCM_FORMAT_BITS;
stream = &oxfw->rx_stream;
formats = oxfw->rx_stream_formats;
}
@@ -158,7 +158,7 @@ static int init_hw_params(struct snd_oxfw *oxfw,
if (err < 0)
goto end;
- err = amdtp_stream_add_pcm_hw_constraints(stream, runtime);
+ err = amdtp_am824_add_pcm_hw_constraints(stream, runtime);
end:
return err;
}
@@ -244,7 +244,7 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
mutex_unlock(&oxfw->mutex);
}
- amdtp_stream_set_pcm_format(&oxfw->tx_stream, params_format(hw_params));
+ amdtp_am824_set_pcm_format(&oxfw->tx_stream, params_format(hw_params));
return 0;
}
@@ -265,7 +265,7 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
mutex_unlock(&oxfw->mutex);
}
- amdtp_stream_set_pcm_format(&oxfw->rx_stream, params_format(hw_params));
+ amdtp_am824_set_pcm_format(&oxfw->rx_stream, params_format(hw_params));
return 0;
}
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c
index 863eb4ae7246..2c63058bd245 100644
--- a/sound/firewire/oxfw/oxfw-stream.c
+++ b/sound/firewire/oxfw/oxfw-stream.c
@@ -155,7 +155,10 @@ static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream,
err = -EINVAL;
goto end;
}
- amdtp_stream_set_parameters(stream, rate, pcm_channels, midi_ports);
+ err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports,
+ false);
+ if (err < 0)
+ goto end;
err = cmp_connection_establish(conn,
amdtp_stream_get_max_payload(stream));
@@ -225,7 +228,7 @@ int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw,
if (err < 0)
goto end;
- err = amdtp_stream_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING);
+ err = amdtp_am824_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING);
if (err < 0) {
amdtp_stream_destroy(stream);
cmp_connection_destroy(conn);
@@ -483,8 +486,8 @@ int snd_oxfw_stream_parse_format(u8 *format,
}
}
- if (formation->pcm > AMDTP_MAX_CHANNELS_FOR_PCM ||
- formation->midi > AMDTP_MAX_CHANNELS_FOR_MIDI)
+ if (formation->pcm > AM824_MAX_CHANNELS_FOR_PCM ||
+ formation->midi > AM824_MAX_CHANNELS_FOR_MIDI)
return -ENOSYS;
return 0;
diff --git a/sound/firewire/oxfw/oxfw.h b/sound/firewire/oxfw/oxfw.h
index 7b5dad819ca4..8392c424ad1d 100644
--- a/sound/firewire/oxfw/oxfw.h
+++ b/sound/firewire/oxfw/oxfw.h
@@ -28,7 +28,7 @@
#include "../fcp.h"
#include "../packets-buffer.h"
#include "../iso-resources.h"
-#include "../amdtp.h"
+#include "../amdtp-am824.h"
#include "../cmp.h"
struct device_info {