root/sound/usb/caiaq/midi.c

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

DEFINITIONS

This source file includes following definitions.
  1. snd_usb_caiaq_midi_input_open
  2. snd_usb_caiaq_midi_input_close
  3. snd_usb_caiaq_midi_input_trigger
  4. snd_usb_caiaq_midi_output_open
  5. snd_usb_caiaq_midi_output_close
  6. snd_usb_caiaq_midi_send
  7. snd_usb_caiaq_midi_output_trigger
  8. snd_usb_caiaq_midi_handle_input
  9. snd_usb_caiaq_midi_init
  10. snd_usb_caiaq_midi_output_done

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *   Copyright (c) 2006,2007 Daniel Mack
   4 */
   5 
   6 #include <linux/device.h>
   7 #include <linux/usb.h>
   8 #include <linux/gfp.h>
   9 #include <sound/rawmidi.h>
  10 #include <sound/core.h>
  11 #include <sound/pcm.h>
  12 
  13 #include "device.h"
  14 #include "midi.h"
  15 
  16 static int snd_usb_caiaq_midi_input_open(struct snd_rawmidi_substream *substream)
  17 {
  18         return 0;
  19 }
  20 
  21 static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substream)
  22 {
  23         return 0;
  24 }
  25 
  26 static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
  27 {
  28         struct snd_usb_caiaqdev *cdev = substream->rmidi->private_data;
  29 
  30         if (!cdev)
  31                 return;
  32 
  33         cdev->midi_receive_substream = up ? substream : NULL;
  34 }
  35 
  36 
  37 static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substream)
  38 {
  39         return 0;
  40 }
  41 
  42 static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream)
  43 {
  44         struct snd_usb_caiaqdev *cdev = substream->rmidi->private_data;
  45         if (cdev->midi_out_active) {
  46                 usb_kill_urb(&cdev->midi_out_urb);
  47                 cdev->midi_out_active = 0;
  48         }
  49         return 0;
  50 }
  51 
  52 static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *cdev,
  53                                     struct snd_rawmidi_substream *substream)
  54 {
  55         int len, ret;
  56         struct device *dev = caiaqdev_to_dev(cdev);
  57 
  58         cdev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE;
  59         cdev->midi_out_buf[1] = 0; /* port */
  60         len = snd_rawmidi_transmit(substream, cdev->midi_out_buf + 3,
  61                                    EP1_BUFSIZE - 3);
  62 
  63         if (len <= 0)
  64                 return;
  65 
  66         cdev->midi_out_buf[2] = len;
  67         cdev->midi_out_urb.transfer_buffer_length = len+3;
  68 
  69         ret = usb_submit_urb(&cdev->midi_out_urb, GFP_ATOMIC);
  70         if (ret < 0)
  71                 dev_err(dev,
  72                         "snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed,"
  73                         "ret=%d, len=%d\n", substream, ret, len);
  74         else
  75                 cdev->midi_out_active = 1;
  76 }
  77 
  78 static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
  79 {
  80         struct snd_usb_caiaqdev *cdev = substream->rmidi->private_data;
  81 
  82         if (up) {
  83                 cdev->midi_out_substream = substream;
  84                 if (!cdev->midi_out_active)
  85                         snd_usb_caiaq_midi_send(cdev, substream);
  86         } else {
  87                 cdev->midi_out_substream = NULL;
  88         }
  89 }
  90 
  91 
  92 static const struct snd_rawmidi_ops snd_usb_caiaq_midi_output =
  93 {
  94         .open =         snd_usb_caiaq_midi_output_open,
  95         .close =        snd_usb_caiaq_midi_output_close,
  96         .trigger =      snd_usb_caiaq_midi_output_trigger,
  97 };
  98 
  99 static const struct snd_rawmidi_ops snd_usb_caiaq_midi_input =
 100 {
 101         .open =         snd_usb_caiaq_midi_input_open,
 102         .close =        snd_usb_caiaq_midi_input_close,
 103         .trigger =      snd_usb_caiaq_midi_input_trigger,
 104 };
 105 
 106 void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *cdev,
 107                                      int port, const char *buf, int len)
 108 {
 109         if (!cdev->midi_receive_substream)
 110                 return;
 111 
 112         snd_rawmidi_receive(cdev->midi_receive_substream, buf, len);
 113 }
 114 
 115 int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device)
 116 {
 117         int ret;
 118         struct snd_rawmidi *rmidi;
 119 
 120         ret = snd_rawmidi_new(device->chip.card, device->product_name, 0,
 121                                         device->spec.num_midi_out,
 122                                         device->spec.num_midi_in,
 123                                         &rmidi);
 124 
 125         if (ret < 0)
 126                 return ret;
 127 
 128         strlcpy(rmidi->name, device->product_name, sizeof(rmidi->name));
 129 
 130         rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX;
 131         rmidi->private_data = device;
 132 
 133         if (device->spec.num_midi_out > 0) {
 134                 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
 135                 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
 136                                     &snd_usb_caiaq_midi_output);
 137         }
 138 
 139         if (device->spec.num_midi_in > 0) {
 140                 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
 141                 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
 142                                     &snd_usb_caiaq_midi_input);
 143         }
 144 
 145         device->rmidi = rmidi;
 146 
 147         return 0;
 148 }
 149 
 150 void snd_usb_caiaq_midi_output_done(struct urb* urb)
 151 {
 152         struct snd_usb_caiaqdev *cdev = urb->context;
 153 
 154         cdev->midi_out_active = 0;
 155         if (urb->status != 0)
 156                 return;
 157 
 158         if (!cdev->midi_out_substream)
 159                 return;
 160 
 161         snd_usb_caiaq_midi_send(cdev, cdev->midi_out_substream);
 162 }

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