~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/firewire/digi00x/digi00x-midi.c

Version: ~ [ linux-5.15-rc1 ] ~ [ linux-5.14.5 ] ~ [ linux-5.13.18 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.66 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.147 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.206 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.246 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.282 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.283 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * digi00x-midi.h - a part of driver for Digidesign Digi 002/003 family
  3  *
  4  * Copyright (c) 2014-2015 Takashi Sakamoto
  5  *
  6  * Licensed under the terms of the GNU General Public License, version 2.
  7  */
  8 
  9 #include "digi00x.h"
 10 
 11 static int midi_open(struct snd_rawmidi_substream *substream)
 12 {
 13         struct snd_dg00x *dg00x = substream->rmidi->private_data;
 14         int err;
 15 
 16         err = snd_dg00x_stream_lock_try(dg00x);
 17         if (err < 0)
 18                 return err;
 19 
 20         mutex_lock(&dg00x->mutex);
 21         dg00x->substreams_counter++;
 22         err = snd_dg00x_stream_start_duplex(dg00x, 0);
 23         mutex_unlock(&dg00x->mutex);
 24         if (err < 0)
 25                 snd_dg00x_stream_lock_release(dg00x);
 26 
 27         return err;
 28 }
 29 
 30 static int midi_close(struct snd_rawmidi_substream *substream)
 31 {
 32         struct snd_dg00x *dg00x = substream->rmidi->private_data;
 33 
 34         mutex_lock(&dg00x->mutex);
 35         dg00x->substreams_counter--;
 36         snd_dg00x_stream_stop_duplex(dg00x);
 37         mutex_unlock(&dg00x->mutex);
 38 
 39         snd_dg00x_stream_lock_release(dg00x);
 40         return 0;
 41 }
 42 
 43 static void midi_capture_trigger(struct snd_rawmidi_substream *substream,
 44                                  int up)
 45 {
 46         struct snd_dg00x *dg00x = substream->rmidi->private_data;
 47         unsigned int port;
 48         unsigned long flags;
 49 
 50         if (substream->rmidi->device == 0)
 51                 port = substream->number;
 52         else
 53                 port = 2;
 54 
 55         spin_lock_irqsave(&dg00x->lock, flags);
 56 
 57         if (up)
 58                 amdtp_dot_midi_trigger(&dg00x->tx_stream, port, substream);
 59         else
 60                 amdtp_dot_midi_trigger(&dg00x->tx_stream, port, NULL);
 61 
 62         spin_unlock_irqrestore(&dg00x->lock, flags);
 63 }
 64 
 65 static void midi_playback_trigger(struct snd_rawmidi_substream *substream,
 66                                   int up)
 67 {
 68         struct snd_dg00x *dg00x = substream->rmidi->private_data;
 69         unsigned int port;
 70         unsigned long flags;
 71 
 72         if (substream->rmidi->device == 0)
 73                 port = substream->number;
 74         else
 75                 port = 2;
 76 
 77         spin_lock_irqsave(&dg00x->lock, flags);
 78 
 79         if (up)
 80                 amdtp_dot_midi_trigger(&dg00x->rx_stream, port, substream);
 81         else
 82                 amdtp_dot_midi_trigger(&dg00x->rx_stream, port, NULL);
 83 
 84         spin_unlock_irqrestore(&dg00x->lock, flags);
 85 }
 86 
 87 static void set_substream_names(struct snd_dg00x *dg00x,
 88                                 struct snd_rawmidi *rmidi, bool is_console)
 89 {
 90         struct snd_rawmidi_substream *subs;
 91         struct snd_rawmidi_str *str;
 92         int i;
 93 
 94         for (i = 0; i < 2; ++i) {
 95                 str = &rmidi->streams[i];
 96 
 97                 list_for_each_entry(subs, &str->substreams, list) {
 98                         if (!is_console) {
 99                                 snprintf(subs->name, sizeof(subs->name),
100                                          "%s MIDI %d",
101                                          dg00x->card->shortname,
102                                          subs->number + 1);
103                         } else {
104                                 snprintf(subs->name, sizeof(subs->name),
105                                          "%s control",
106                                          dg00x->card->shortname);
107                         }
108                 }
109         }
110 }
111 
112 static int add_substream_pair(struct snd_dg00x *dg00x, unsigned int out_ports,
113                               unsigned int in_ports, bool is_console)
114 {
115         static const struct snd_rawmidi_ops capture_ops = {
116                 .open = midi_open,
117                 .close = midi_close,
118                 .trigger = midi_capture_trigger,
119         };
120         static const struct snd_rawmidi_ops playback_ops = {
121                 .open = midi_open,
122                 .close = midi_close,
123                 .trigger = midi_playback_trigger,
124         };
125         const char *label;
126         struct snd_rawmidi *rmidi;
127         int err;
128 
129         /* Add physical midi ports. */
130         err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, is_console,
131                               out_ports, in_ports, &rmidi);
132         if (err < 0)
133                 return err;
134         rmidi->private_data = dg00x;
135 
136         if (!is_console)
137                 label = "%s control";
138         else
139                 label = "%s MIDI";
140         snprintf(rmidi->name, sizeof(rmidi->name), label,
141                  dg00x->card->shortname);
142 
143         snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &playback_ops);
144         snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &capture_ops);
145 
146         rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT |
147                              SNDRV_RAWMIDI_INFO_OUTPUT |
148                              SNDRV_RAWMIDI_INFO_DUPLEX;
149 
150         set_substream_names(dg00x, rmidi, is_console);
151 
152         return 0;
153 }
154 
155 int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x)
156 {
157         int err;
158 
159         /* Add physical midi ports. */
160         err = add_substream_pair(dg00x, DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS,
161                                  false);
162         if (err < 0)
163                 return err;
164 
165         if (dg00x->is_console)
166                 err = add_substream_pair(dg00x, 1, 1, true);
167 
168         return err;
169 }
170 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp