root/sound/firewire/oxfw/oxfw-midi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. midi_capture_open
  2. midi_playback_open
  3. midi_capture_close
  4. midi_playback_close
  5. midi_capture_trigger
  6. midi_playback_trigger
  7. set_midi_substream_names
  8. snd_oxfw_create_midi

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * oxfw_midi.c - a part of driver for OXFW970/971 based devices
   4  *
   5  * Copyright (c) 2014 Takashi Sakamoto
   6  */
   7 
   8 #include "oxfw.h"
   9 
  10 static int midi_capture_open(struct snd_rawmidi_substream *substream)
  11 {
  12         struct snd_oxfw *oxfw = substream->rmidi->private_data;
  13         int err;
  14 
  15         err = snd_oxfw_stream_lock_try(oxfw);
  16         if (err < 0)
  17                 return err;
  18 
  19         mutex_lock(&oxfw->mutex);
  20 
  21         err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream, 0, 0);
  22         if (err >= 0) {
  23                 ++oxfw->substreams_count;
  24                 err = snd_oxfw_stream_start_duplex(oxfw);
  25                 if (err < 0)
  26                         --oxfw->substreams_count;
  27         }
  28 
  29         mutex_unlock(&oxfw->mutex);
  30 
  31         if (err < 0)
  32                 snd_oxfw_stream_lock_release(oxfw);
  33 
  34         return err;
  35 }
  36 
  37 static int midi_playback_open(struct snd_rawmidi_substream *substream)
  38 {
  39         struct snd_oxfw *oxfw = substream->rmidi->private_data;
  40         int err;
  41 
  42         err = snd_oxfw_stream_lock_try(oxfw);
  43         if (err < 0)
  44                 return err;
  45 
  46         mutex_lock(&oxfw->mutex);
  47 
  48         err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream, 0, 0);
  49         if (err >= 0) {
  50                 ++oxfw->substreams_count;
  51                 err = snd_oxfw_stream_start_duplex(oxfw);
  52         }
  53 
  54         mutex_unlock(&oxfw->mutex);
  55 
  56         if (err < 0)
  57                 snd_oxfw_stream_lock_release(oxfw);
  58 
  59         return err;
  60 }
  61 
  62 static int midi_capture_close(struct snd_rawmidi_substream *substream)
  63 {
  64         struct snd_oxfw *oxfw = substream->rmidi->private_data;
  65 
  66         mutex_lock(&oxfw->mutex);
  67 
  68         --oxfw->substreams_count;
  69         snd_oxfw_stream_stop_duplex(oxfw);
  70 
  71         mutex_unlock(&oxfw->mutex);
  72 
  73         snd_oxfw_stream_lock_release(oxfw);
  74         return 0;
  75 }
  76 
  77 static int midi_playback_close(struct snd_rawmidi_substream *substream)
  78 {
  79         struct snd_oxfw *oxfw = substream->rmidi->private_data;
  80 
  81         mutex_lock(&oxfw->mutex);
  82 
  83         --oxfw->substreams_count;
  84         snd_oxfw_stream_stop_duplex(oxfw);
  85 
  86         mutex_unlock(&oxfw->mutex);
  87 
  88         snd_oxfw_stream_lock_release(oxfw);
  89         return 0;
  90 }
  91 
  92 static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
  93 {
  94         struct snd_oxfw *oxfw = substrm->rmidi->private_data;
  95         unsigned long flags;
  96 
  97         spin_lock_irqsave(&oxfw->lock, flags);
  98 
  99         if (up)
 100                 amdtp_am824_midi_trigger(&oxfw->tx_stream,
 101                                          substrm->number, substrm);
 102         else
 103                 amdtp_am824_midi_trigger(&oxfw->tx_stream,
 104                                          substrm->number, NULL);
 105 
 106         spin_unlock_irqrestore(&oxfw->lock, flags);
 107 }
 108 
 109 static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
 110 {
 111         struct snd_oxfw *oxfw = substrm->rmidi->private_data;
 112         unsigned long flags;
 113 
 114         spin_lock_irqsave(&oxfw->lock, flags);
 115 
 116         if (up)
 117                 amdtp_am824_midi_trigger(&oxfw->rx_stream,
 118                                          substrm->number, substrm);
 119         else
 120                 amdtp_am824_midi_trigger(&oxfw->rx_stream,
 121                                          substrm->number, NULL);
 122 
 123         spin_unlock_irqrestore(&oxfw->lock, flags);
 124 }
 125 
 126 static void set_midi_substream_names(struct snd_oxfw *oxfw,
 127                                      struct snd_rawmidi_str *str)
 128 {
 129         struct snd_rawmidi_substream *subs;
 130 
 131         list_for_each_entry(subs, &str->substreams, list) {
 132                 snprintf(subs->name, sizeof(subs->name),
 133                          "%s MIDI %d",
 134                          oxfw->card->shortname, subs->number + 1);
 135         }
 136 }
 137 
 138 int snd_oxfw_create_midi(struct snd_oxfw *oxfw)
 139 {
 140         static const struct snd_rawmidi_ops capture_ops = {
 141                 .open           = midi_capture_open,
 142                 .close          = midi_capture_close,
 143                 .trigger        = midi_capture_trigger,
 144         };
 145         static const struct snd_rawmidi_ops playback_ops = {
 146                 .open           = midi_playback_open,
 147                 .close          = midi_playback_close,
 148                 .trigger        = midi_playback_trigger,
 149         };
 150         struct snd_rawmidi *rmidi;
 151         struct snd_rawmidi_str *str;
 152         int err;
 153 
 154         if (oxfw->midi_input_ports == 0 && oxfw->midi_output_ports == 0)
 155                 return 0;
 156 
 157         /* create midi ports */
 158         err = snd_rawmidi_new(oxfw->card, oxfw->card->driver, 0,
 159                               oxfw->midi_output_ports, oxfw->midi_input_ports,
 160                               &rmidi);
 161         if (err < 0)
 162                 return err;
 163 
 164         snprintf(rmidi->name, sizeof(rmidi->name),
 165                  "%s MIDI", oxfw->card->shortname);
 166         rmidi->private_data = oxfw;
 167 
 168         if (oxfw->midi_input_ports > 0) {
 169                 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
 170 
 171                 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
 172                                     &capture_ops);
 173 
 174                 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
 175 
 176                 set_midi_substream_names(oxfw, str);
 177         }
 178 
 179         if (oxfw->midi_output_ports > 0) {
 180                 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
 181 
 182                 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
 183                                     &playback_ops);
 184 
 185                 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
 186 
 187                 set_midi_substream_names(oxfw, str);
 188         }
 189 
 190         if ((oxfw->midi_output_ports > 0) && (oxfw->midi_input_ports > 0))
 191                 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
 192 
 193         return 0;
 194 }

/* [<][>][^][v][top][bottom][index][help] */