Path: blob/master/sound/firewire/digi00x/digi00x-midi.c
26451 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* digi00x-midi.h - a part of driver for Digidesign Digi 002/003 family3*4* Copyright (c) 2014-2015 Takashi Sakamoto5*/67#include "digi00x.h"89static int midi_open(struct snd_rawmidi_substream *substream)10{11struct snd_dg00x *dg00x = substream->rmidi->private_data;12int err;1314err = snd_dg00x_stream_lock_try(dg00x);15if (err < 0)16return err;1718mutex_lock(&dg00x->mutex);19err = snd_dg00x_stream_reserve_duplex(dg00x, 0, 0, 0);20if (err >= 0) {21++dg00x->substreams_counter;22err = snd_dg00x_stream_start_duplex(dg00x);23if (err < 0)24--dg00x->substreams_counter;25}26mutex_unlock(&dg00x->mutex);27if (err < 0)28snd_dg00x_stream_lock_release(dg00x);2930return err;31}3233static int midi_close(struct snd_rawmidi_substream *substream)34{35struct snd_dg00x *dg00x = substream->rmidi->private_data;3637mutex_lock(&dg00x->mutex);38--dg00x->substreams_counter;39snd_dg00x_stream_stop_duplex(dg00x);40mutex_unlock(&dg00x->mutex);4142snd_dg00x_stream_lock_release(dg00x);43return 0;44}4546static void midi_capture_trigger(struct snd_rawmidi_substream *substream,47int up)48{49struct snd_dg00x *dg00x = substream->rmidi->private_data;50unsigned int port;51unsigned long flags;5253if (substream->rmidi->device == 0)54port = substream->number;55else56port = 2;5758spin_lock_irqsave(&dg00x->lock, flags);5960if (up)61amdtp_dot_midi_trigger(&dg00x->tx_stream, port, substream);62else63amdtp_dot_midi_trigger(&dg00x->tx_stream, port, NULL);6465spin_unlock_irqrestore(&dg00x->lock, flags);66}6768static void midi_playback_trigger(struct snd_rawmidi_substream *substream,69int up)70{71struct snd_dg00x *dg00x = substream->rmidi->private_data;72unsigned int port;73unsigned long flags;7475if (substream->rmidi->device == 0)76port = substream->number;77else78port = 2;7980spin_lock_irqsave(&dg00x->lock, flags);8182if (up)83amdtp_dot_midi_trigger(&dg00x->rx_stream, port, substream);84else85amdtp_dot_midi_trigger(&dg00x->rx_stream, port, NULL);8687spin_unlock_irqrestore(&dg00x->lock, flags);88}8990static void set_substream_names(struct snd_dg00x *dg00x,91struct snd_rawmidi *rmidi, bool is_console)92{93struct snd_rawmidi_substream *subs;94struct snd_rawmidi_str *str;95int i;9697for (i = 0; i < 2; ++i) {98str = &rmidi->streams[i];99100list_for_each_entry(subs, &str->substreams, list) {101if (!is_console) {102scnprintf(subs->name, sizeof(subs->name),103"%s MIDI %d",104dg00x->card->shortname,105subs->number + 1);106} else {107scnprintf(subs->name, sizeof(subs->name),108"%s control",109dg00x->card->shortname);110}111}112}113}114115static int add_substream_pair(struct snd_dg00x *dg00x, unsigned int out_ports,116unsigned int in_ports, bool is_console)117{118static const struct snd_rawmidi_ops capture_ops = {119.open = midi_open,120.close = midi_close,121.trigger = midi_capture_trigger,122};123static const struct snd_rawmidi_ops playback_ops = {124.open = midi_open,125.close = midi_close,126.trigger = midi_playback_trigger,127};128const char *label;129struct snd_rawmidi *rmidi;130int err;131132/* Add physical midi ports. */133err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, is_console,134out_ports, in_ports, &rmidi);135if (err < 0)136return err;137rmidi->private_data = dg00x;138139if (!is_console)140label = "%s control";141else142label = "%s MIDI";143snprintf(rmidi->name, sizeof(rmidi->name), label,144dg00x->card->shortname);145146snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &playback_ops);147snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &capture_ops);148149rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT |150SNDRV_RAWMIDI_INFO_OUTPUT |151SNDRV_RAWMIDI_INFO_DUPLEX;152153set_substream_names(dg00x, rmidi, is_console);154155return 0;156}157158int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x)159{160int err;161162/* Add physical midi ports. */163err = add_substream_pair(dg00x, DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS,164false);165if (err < 0)166return err;167168if (dg00x->is_console)169err = add_substream_pair(dg00x, 1, 1, true);170171return err;172}173174175