diff options
-rw-r--r-- | sound/firewire/Kconfig | 1 | ||||
-rw-r--r-- | sound/firewire/fireface/Makefile | 3 | ||||
-rw-r--r-- | sound/firewire/fireface/ff-protocol-ff800.c | 27 | ||||
-rw-r--r-- | sound/firewire/fireface/ff.c | 51 | ||||
-rw-r--r-- | sound/firewire/fireface/ff.h | 1 |
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, |