// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) by Paul Barton-Davis 1998-1999 */ /* The low level driver for the WaveFront ICS2115 MIDI interface(s) * * Note that there is also an MPU-401 emulation (actually, a UART-401 * emulation) on the CS4232 on the Tropez and Tropez Plus. This code * has nothing to do with that interface at all. * * The interface is essentially just a UART-401, but is has the * interesting property of supporting what Turtle Beach called * "Virtual MIDI" mode. In this mode, there are effectively *two* * MIDI buses accessible via the interface, one that is routed * solely to/from the external WaveFront synthesizer and the other * corresponding to the pin/socket connector used to link external * MIDI devices to the board. * * This driver fully supports this mode, allowing two distinct MIDI * busses to be used completely independently, giving 32 channels of * MIDI routing, 16 to the WaveFront synth and 16 to the external MIDI * bus. The devices are named /dev/snd/midiCnD0 and /dev/snd/midiCnD1, * where `n' is the card number. Note that the device numbers may be * something other than 0 and 1 if the CS4232 UART/MPU-401 interface * is enabled. * * Switching between the two is accomplished externally by the driver * using the two otherwise unused MIDI bytes. See the code for more details. * * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see lowlevel/isa/wavefront.c) * * The main reason to turn off Virtual MIDI mode is when you want to * tightly couple the WaveFront synth with an external MIDI * device. You won't be able to distinguish the source of any MIDI * data except via SysEx ID, but thats probably OK, since for the most * part, the WaveFront won't be sending any MIDI data at all. * * The main reason to turn on Virtual MIDI Mode is to provide two * completely independent 16-channel MIDI buses, one to the * WaveFront and one to any external MIDI devices. Given the 32 * voice nature of the WaveFront, its pretty easy to find a use * for all 16 channels driving just that synth. * */ #include <linux/io.h> #include <linux/init.h> #include <linux/time.h> #include <linux/wait.h> #include <sound/core.h> #include <sound/snd_wavefront.h> static inline int wf_mpu_status (snd_wavefront_midi_t *midi) { … } static inline int input_avail (snd_wavefront_midi_t *midi) { … } static inline int output_ready (snd_wavefront_midi_t *midi) { … } static inline int read_data (snd_wavefront_midi_t *midi) { … } static inline void write_data (snd_wavefront_midi_t *midi, unsigned char byte) { … } static snd_wavefront_midi_t * get_wavefront_midi (struct snd_rawmidi_substream *substream) { … } static void snd_wavefront_midi_output_write(snd_wavefront_card_t *card) { … } static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream) { … } static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substream) { … } static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substream) { … } static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substream) { … } static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) { … } static void snd_wavefront_midi_output_timer(struct timer_list *t) { … } static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) { … } void snd_wavefront_midi_interrupt (snd_wavefront_card_t *card) { … } void snd_wavefront_midi_enable_virtual (snd_wavefront_card_t *card) { … } void snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *card) { … } int snd_wavefront_midi_start (snd_wavefront_card_t *card) { … } const struct snd_rawmidi_ops snd_wavefront_midi_output = …; const struct snd_rawmidi_ops snd_wavefront_midi_input = …;