summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/firewire/Kconfig1
-rw-r--r--sound/firewire/fireface/Makefile3
-rw-r--r--sound/firewire/fireface/ff-protocol-ff800.c27
-rw-r--r--sound/firewire/fireface/ff.c51
-rw-r--r--sound/firewire/fireface/ff.h1
5 files changed, 70 insertions, 13 deletions
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index 44cedb65bb88..052e00590259 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -162,5 +162,6 @@ config SND_FIREFACE
help
Say Y here to include support for RME fireface series.
* Fireface 400
+ * Fireface 800
endif # SND_FIREWIRE
diff --git a/sound/firewire/fireface/Makefile b/sound/firewire/fireface/Makefile
index 8f807284ba54..79a7d6d99d72 100644
--- a/sound/firewire/fireface/Makefile
+++ b/sound/firewire/fireface/Makefile
@@ -1,3 +1,4 @@
snd-fireface-objs := ff.o ff-transaction.o ff-midi.o ff-proc.o amdtp-ff.o \
- ff-stream.o ff-pcm.o ff-hwdep.o ff-protocol-ff400.o
+ ff-stream.o ff-pcm.o ff-hwdep.o ff-protocol-ff400.o \
+ ff-protocol-ff800.o
obj-$(CONFIG_SND_FIREFACE) += snd-fireface.o
diff --git a/sound/firewire/fireface/ff-protocol-ff800.c b/sound/firewire/fireface/ff-protocol-ff800.c
new file mode 100644
index 000000000000..d24439734304
--- /dev/null
+++ b/sound/firewire/fireface/ff-protocol-ff800.c
@@ -0,0 +1,27 @@
+/*
+ * ff-protocol-ff800.c - a part of driver for RME Fireface series
+ *
+ * Copyright (c) 2018 Takashi Sakamoto
+ *
+ * Licensed under the terms of the GNU General Public License, version 2.
+ */
+
+#include "ff.h"
+
+static void ff800_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length)
+{
+ int i;
+
+ for (i = 0; i < length / 4; i++) {
+ u8 byte = le32_to_cpu(buf[i]) & 0xff;
+ struct snd_rawmidi_substream *substream;
+
+ substream = READ_ONCE(ff->tx_midi_substreams[0]);
+ if (substream)
+ snd_rawmidi_receive(substream, &byte, 1);
+ }
+}
+
+const struct snd_ff_protocol snd_ff_protocol_ff800 = {
+ .handle_midi_msg = ff800_handle_midi_msg,
+};
diff --git a/sound/firewire/fireface/ff.c b/sound/firewire/fireface/ff.c
index 2ce5e115b0eb..d486984c0e5b 100644
--- a/sound/firewire/fireface/ff.c
+++ b/sound/firewire/fireface/ff.c
@@ -31,7 +31,8 @@ static void ff_card_free(struct snd_card *card)
{
struct snd_ff *ff = card->private_data;
- snd_ff_stream_destroy_duplex(ff);
+ if (ff->spec->protocol->begin_session)
+ snd_ff_stream_destroy_duplex(ff);
snd_ff_transaction_unregister(ff);
}
@@ -56,9 +57,11 @@ static void do_registration(struct work_struct *work)
name_card(ff);
- err = snd_ff_stream_init_duplex(ff);
- if (err < 0)
- goto error;
+ if (ff->spec->protocol->begin_session) {
+ err = snd_ff_stream_init_duplex(ff);
+ if (err < 0)
+ goto error;
+ }
snd_ff_proc_init(ff);
@@ -66,13 +69,15 @@ static void do_registration(struct work_struct *work)
if (err < 0)
goto error;
- err = snd_ff_create_pcm_devices(ff);
- if (err < 0)
- goto error;
+ if (ff->spec->protocol->begin_session) {
+ err = snd_ff_create_pcm_devices(ff);
+ if (err < 0)
+ goto error;
- err = snd_ff_create_hwdep_devices(ff);
- if (err < 0)
- goto error;
+ err = snd_ff_create_hwdep_devices(ff);
+ if (err < 0)
+ goto error;
+ }
err = snd_card_register(ff->card);
if (err < 0)
@@ -121,7 +126,7 @@ static void snd_ff_update(struct fw_unit *unit)
snd_ff_transaction_reregister(ff);
- if (ff->registered)
+ if (ff->registered && ff->spec->protocol->begin_session)
snd_ff_stream_update_duplex(ff);
}
@@ -145,6 +150,16 @@ static void snd_ff_remove(struct fw_unit *unit)
fw_unit_put(ff->unit);
}
+static const struct snd_ff_spec spec_ff800 = {
+ .name = "Fireface800",
+ .midi_in_ports = 1,
+ .midi_out_ports = 1,
+ .protocol = &snd_ff_protocol_ff800,
+ .regs = {
+ [SND_FF_REG_TYPE_MIDI_HIGH_ADDR] = 0x000200000320ull,
+ },
+};
+
static const struct snd_ff_spec spec_ff400 = {
.name = "Fireface400",
.pcm_capture_channels = {18, 14, 10},
@@ -158,6 +173,18 @@ static const struct snd_ff_spec spec_ff400 = {
};
static const struct ieee1394_device_id snd_ff_id_table[] = {
+ /* Fireface 800 */
+ {
+ .match_flags = IEEE1394_MATCH_VENDOR_ID |
+ IEEE1394_MATCH_SPECIFIER_ID |
+ IEEE1394_MATCH_VERSION |
+ IEEE1394_MATCH_MODEL_ID,
+ .vendor_id = OUI_RME,
+ .specifier_id = OUI_RME,
+ .version = 0x000001,
+ .model_id = 0x101800,
+ .driver_data = (kernel_ulong_t)&spec_ff800,
+ },
/* Fireface 400 */
{
.match_flags = IEEE1394_MATCH_VENDOR_ID |
@@ -165,7 +192,7 @@ static const struct ieee1394_device_id snd_ff_id_table[] = {
IEEE1394_MATCH_VERSION |
IEEE1394_MATCH_MODEL_ID,
.vendor_id = OUI_RME,
- .specifier_id = 0x000a35,
+ .specifier_id = OUI_RME,
.version = 0x000002,
.model_id = 0x101800,
.driver_data = (kernel_ulong_t)&spec_ff400,
diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h
index 178a96cb6e2a..6e4a8197d3ca 100644
--- a/sound/firewire/fireface/ff.h
+++ b/sound/firewire/fireface/ff.h
@@ -114,6 +114,7 @@ struct snd_ff_protocol {
int (*switch_fetching_mode)(struct snd_ff *ff, bool enable);
};
+extern const struct snd_ff_protocol snd_ff_protocol_ff800;
extern const struct snd_ff_protocol snd_ff_protocol_ff400;
int snd_ff_transaction_get_clock(struct snd_ff *ff, unsigned int *rate,